Move search parsing to domain layer

This commit is contained in:
2020-11-05 14:55:54 +01:00
parent c39a20cf96
commit 568a2c6831
6 changed files with 11 additions and 15 deletions
@@ -4,11 +4,11 @@ import arrow.core.computations.either
import be.simplenotes.domain.security.HtmlSanitizer
import be.simplenotes.domain.usecases.markdown.MarkdownConverter
import be.simplenotes.domain.usecases.markdown.MarkdownParsingError
import be.simplenotes.domain.usecases.search.parseSearchTerms
import be.simplenotes.persistance.repositories.NoteRepository
import be.simplenotes.persistance.repositories.UserRepository
import be.simplenotes.persistance.transactions.TransactionService
import be.simplenotes.search.NoteSearcher
import be.simplenotes.search.SearchTerms
import be.simplenotes.types.LoggedInUser
import be.simplenotes.types.Note
import be.simplenotes.types.PersistedNote
@@ -102,7 +102,7 @@ class NoteService(
}
}
fun search(userId: Int, searchTerms: SearchTerms) = searcher.search(userId, searchTerms)
fun search(userId: Int, searchInput: String) = searcher.search(userId, parseSearchTerms(searchInput))
@PreDestroy
fun dropAllIndexes() = searcher.dropAll()
@@ -0,0 +1,43 @@
package be.simplenotes.domain.usecases.search
import be.simplenotes.search.SearchTerms
private fun innerRegex(name: String) =
"""$name:['"](.*?)['"]""".toRegex()
private fun outerRegex(name: String) =
"""($name:['"].*?['"])""".toRegex()
private val titleRe = innerRegex("title")
private val outerTitleRe = outerRegex("title")
private val tagRe = innerRegex("tag")
private val outerTagRe = outerRegex("tag")
private val contentRe = innerRegex("content")
private val outerContentRe = outerRegex("content")
internal fun parseSearchTerms(input: String): SearchTerms {
var c: String = input
fun extract(innerRegex: Regex, outerRegex: Regex): String? {
val match = innerRegex.find(input)?.groups?.get(1)?.value
if (match != null) {
val group = outerRegex.find(input)?.groups?.get(1)?.value
group?.let { c = c.replace(it, "") }
}
return match
}
val title: String? = extract(titleRe, outerTitleRe)
val tag: String? = extract(tagRe, outerTagRe)
val content: String? = extract(contentRe, outerContentRe)
val all = c.trim().ifEmpty { null }
return SearchTerms(
title = title,
tag = tag,
content = content,
all = all
)
}
@@ -0,0 +1,45 @@
package be.simplenotes.domain.usecases.search
import be.simplenotes.search.SearchTerms
import com.natpryce.hamkrest.assertion.assertThat
import com.natpryce.hamkrest.equalTo
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.MethodSource
import java.util.stream.Stream
internal class SearchTermsParserKtTest {
private fun createResult(
input: String,
title: String? = null,
tag: String? = null,
content: String? = null,
all: String? = null,
): Pair<String, SearchTerms> = input to SearchTerms(title, tag, content, all)
@Suppress("Unused")
private fun results() = Stream.of(
createResult("title:'example'", title = "example"),
createResult("title:'example with words'", title = "example with words"),
createResult("title:'example with words'", title = "example with words"),
createResult("""title:"double quotes"""", title = "double quotes"),
createResult("title:'example' something else", title = "example", all = "something else"),
createResult("tag:'example'", tag = "example"),
createResult("tag:'example' title:'other'", title = "other", tag = "example"),
createResult("blah blah tag:'example' title:'other'", title = "other", tag = "example", all = "blah blah"),
createResult("tag:'example' middle title:'other'", title = "other", tag = "example", all = "middle"),
createResult("tag:'example' title:'other' end", title = "other", tag = "example", all = "end"),
createResult(
"tag:'example abc' title:'other with words' this is the end ",
title = "other with words",
tag = "example abc",
all = "this is the end"
),
)
@ParameterizedTest
@MethodSource("results")
fun `valid search parser`(case: Pair<String, SearchTerms>) {
assertThat(parseSearchTerms(case.first), equalTo(case.second))
}
}