Compare commits

..

No commits in common. "3e1683dfe596bbc4f36a19af07ea3dd4ace53a6c" and "ea110d51d34df0c0c760ce0d880329ac05309aeb" have entirely different histories.

7 changed files with 26 additions and 95 deletions

View File

@ -14,6 +14,6 @@ dependencies {
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.31") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.31")
implementation("org.jetbrains.kotlin:kotlin-serialization:1.4.31") implementation("org.jetbrains.kotlin:kotlin-serialization:1.4.31")
implementation("com.github.jengelman.gradle.plugins:shadow:6.1.0") implementation("com.github.jengelman.gradle.plugins:shadow:6.1.0")
implementation("org.jlleitschuh.gradle:ktlint-gradle:10.0.0") implementation("org.jlleitschuh.gradle:ktlint-gradle:9.4.1")
implementation("com.github.ben-manes:gradle-versions-plugin:0.28.0") implementation("com.github.ben-manes:gradle-versions-plugin:0.28.0")
} }

View File

@ -5,9 +5,7 @@ plugins {
} }
tasks.withType<Test> { tasks.withType<Test> {
useJUnitPlatform { useJUnitPlatform()
excludeTags("slow")
}
} }
dependencies { dependencies {

View File

@ -1,91 +1,38 @@
package be.simplenotes.domain.usecases.search package be.simplenotes.domain.usecases.search
import be.simplenotes.search.SearchTerms import be.simplenotes.search.SearchTerms
import java.util.*
private enum class Quote { SingleQuote, DoubleQuote, } private fun innerRegex(name: String) =
"""$name:['"](.*?)['"]""".toRegex()
private fun outerRegex(name: String) =
"""($name:['"].*?['"])""".toRegex()
data class ParsedSearchInput(val global: List<String>, val entries: Map<String, String>) private val titleRe = innerRegex("title")
private val outerTitleRe = outerRegex("title")
object SearchInputParser { private val tagRe = innerRegex("tag")
fun parseInput(input: String): ParsedSearchInput { private val outerTagRe = outerRegex("tag")
val tokenizer = StringTokenizer(input, ":\"' ", true)
val tokens = ArrayList<String>() private val contentRe = innerRegex("content")
val current = StringBuilder() private val outerContentRe = outerRegex("content")
var quoteOpen: Quote? = null
fun push() {
if (current.isNotEmpty()) {
tokens.add(current.toString())
}
current.setLength(0)
quoteOpen = null
}
while (tokenizer.hasMoreTokens()) {
when (val token = tokenizer.nextToken()) {
"\"" -> when {
Quote.DoubleQuote == quoteOpen -> push()
quoteOpen == null -> quoteOpen = Quote.DoubleQuote
else -> current.append(token)
}
"'" -> when {
Quote.SingleQuote == quoteOpen -> push()
quoteOpen == null -> quoteOpen = Quote.SingleQuote
else -> current.append(token)
}
" " -> {
if (quoteOpen != null) current.append(" ")
else push()
}
":" -> {
push()
tokens.add(token)
}
else -> {
current.append(token)
}
}
}
push()
val entries = HashMap<String, String>()
val colonIndexes = ArrayList<Int>()
tokens.forEachIndexed { index, token ->
if (token == ":") colonIndexes += index
}
var changes = 0
for (colonIndex in colonIndexes) {
val offset = changes * 3
val key = tokens.getOrNull(colonIndex - 1 - offset)
val value = tokens.getOrNull(colonIndex + 1 - offset)
if (key != null && value != null) {
entries[key] = value
tokens.removeAt(colonIndex - 1 - offset) // remove key
tokens.removeAt(colonIndex - 1 - offset) // remove :
tokens.removeAt(colonIndex - 1 - offset) // remove value
changes++
}
}
return ParsedSearchInput(global = tokens, entries = entries)
}
}
internal fun parseSearchTerms(input: String): SearchTerms { internal fun parseSearchTerms(input: String): SearchTerms {
val parsedInput = SearchInputParser.parseInput(input) var c: String = input
val title: String? = parsedInput.entries["title"] fun extract(innerRegex: Regex, outerRegex: Regex): String? {
val tag: String? = parsedInput.entries["tag"] val match = innerRegex.find(input)?.groups?.get(1)?.value
val content: String? = parsedInput.entries["content"] if (match != null) {
val group = outerRegex.find(input)?.groups?.get(1)?.value
group?.let { c = c.replace(it, "") }
}
return match
}
val all = parsedInput.global.takeIf { it.isNotEmpty() }?.joinToString(" ") 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( return SearchTerms(
title = title, title = title,

View File

@ -35,14 +35,6 @@ internal class SearchTermsParserKtTest {
tag = "example abc", tag = "example abc",
all = "this is the end" all = "this is the end"
), ),
createResult("tag:blah", tag = "blah"),
createResult("tag:'some words'", tag = "some words"),
createResult("tag:'some words ' global", tag = "some words ", all = "global"),
createResult(
"tag:'double quote inside single \" ' global",
tag = "double quote inside single \" ",
all = "global"
),
) )
@ParameterizedTest @ParameterizedTest

View File

@ -2,7 +2,6 @@ package be.simplenotes.persistence
import be.simplenotes.config.DataSourceConfig import be.simplenotes.config.DataSourceConfig
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.parallel.ResourceLock import org.junit.jupiter.api.parallel.ResourceLock
@ -16,7 +15,6 @@ class H2DbHealthCheckImplTest : DbTest() {
} }
} }
@Tag("slow")
@ResourceLock("mariadb") @ResourceLock("mariadb")
class MariaDbHealthCheckImplTest : DbTest() { class MariaDbHealthCheckImplTest : DbTest() {
lateinit var mariaDB: KMariadbContainer lateinit var mariaDB: KMariadbContainer

View File

@ -5,7 +5,6 @@ import be.simplenotes.persistence.KMariadbContainer
import be.simplenotes.persistence.h2dataSourceConfig import be.simplenotes.persistence.h2dataSourceConfig
import be.simplenotes.persistence.mariadbDataSourceConfig import be.simplenotes.persistence.mariadbDataSourceConfig
import org.junit.jupiter.api.AfterAll import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.parallel.ResourceLock import org.junit.jupiter.api.parallel.ResourceLock
@ResourceLock("h2") @ResourceLock("h2")
@ -13,7 +12,6 @@ internal class H2NoteRepositoryImplTests : BaseNoteRepositoryImplTest() {
override fun dataSourceConfig() = h2dataSourceConfig() override fun dataSourceConfig() = h2dataSourceConfig()
} }
@Tag("slow")
@ResourceLock("mariadb") @ResourceLock("mariadb")
internal class MariaDbNoteRepositoryImplTests : BaseNoteRepositoryImplTest() { internal class MariaDbNoteRepositoryImplTests : BaseNoteRepositoryImplTest() {
lateinit var mariaDB: KMariadbContainer lateinit var mariaDB: KMariadbContainer

View File

@ -5,7 +5,6 @@ import be.simplenotes.persistence.KMariadbContainer
import be.simplenotes.persistence.h2dataSourceConfig import be.simplenotes.persistence.h2dataSourceConfig
import be.simplenotes.persistence.mariadbDataSourceConfig import be.simplenotes.persistence.mariadbDataSourceConfig
import org.junit.jupiter.api.AfterAll import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.Tag
import org.junit.jupiter.api.parallel.ResourceLock import org.junit.jupiter.api.parallel.ResourceLock
@ResourceLock("h2") @ResourceLock("h2")
@ -13,7 +12,6 @@ internal class UserRepositoryImplTest : BaseUserRepositoryImplTest() {
override fun dataSourceConfig() = h2dataSourceConfig() override fun dataSourceConfig() = h2dataSourceConfig()
} }
@Tag("slow")
@ResourceLock("mariadb") @ResourceLock("mariadb")
internal class MariaDbUserRepositoryImplTest : BaseUserRepositoryImplTest() { internal class MariaDbUserRepositoryImplTest : BaseUserRepositoryImplTest() {
lateinit var mariaDB: KMariadbContainer lateinit var mariaDB: KMariadbContainer