WIP on query tests

This commit is contained in:
2025-02-18 22:57:06 -05:00
parent 2b6dff9fd3
commit cefd2daa52
2 changed files with 218 additions and 13 deletions

View File

@@ -3,7 +3,9 @@ package solutions.bitbadger.documents
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class QueryTest {
@@ -130,6 +132,105 @@ class QueryTest {
assertEquals("data->>'id' = :key", Query.Where.byId<String>(":key"))
}
@Test
@DisplayName("Where.jsonContains generates defaults (PostgreSQL)")
fun whereJsonContainsDefaultPostgres() {
Configuration.connectionString = pg
assertEquals("data @> :criteria", Query.Where.jsonContains())
}
@Test
@DisplayName("Where.jsonContains generates named parameter (PostgreSQL)")
fun whereJsonContainsNamedPostgres() {
Configuration.connectionString = pg
assertEquals("data @> :it", Query.Where.jsonContains(":it"))
}
@Test
@DisplayName("Where.jsonContains fails (SQLite)")
fun whereJsonContainsFailsSQLite() {
Configuration.connectionString = lite
assertThrows<DocumentException> { Query.Where.jsonContains() }
}
@Test
@DisplayName("Where.jsonPathMatch generates defaults (PostgreSQL)")
fun whereJsonPathMatchDefaultPostgres() {
Configuration.connectionString = pg
assertEquals("jsonb_path_exists(data, :path::jsonpath)", Query.Where.jsonPathMatches())
}
@Test
@DisplayName("Where.jsonPathMatch generates named parameter (PostgreSQL)")
fun whereJsonPathMatchNamedPostgres() {
Configuration.connectionString = pg
assertEquals("jsonb_path_exists(data, :jp::jsonpath)", Query.Where.jsonPathMatches(":jp"))
}
@Test
@DisplayName("Where.jsonPathMatch fails (SQLite)")
fun whereJsonPathFailsSQLite() {
Configuration.connectionString = lite
assertThrows<DocumentException> { Query.Where.jsonPathMatches() }
}
// ~~~ root functions ~~~
@Test
@DisplayName("byId generates a numeric ID query (PostgreSQL)")
fun byIdNumericPostgres() {
Configuration.connectionString = pg
assertEquals("test WHERE (data->>'id')::numeric = :id", Query.byId("test", 9))
}
@Test
@DisplayName("byId generates an alphanumeric ID query (PostgreSQL)")
fun byIdAlphaPostgres() {
Configuration.connectionString = pg
assertEquals("unit WHERE data->>'id' = :id", Query.byId("unit", "18"))
}
@Test
@DisplayName("byId generates ID query (SQLite)")
fun byIdSQLite() {
Configuration.connectionString = lite
assertEquals("yo WHERE data->>'id' = :id", Query.byId("yo", 27))
}
@Test
@DisplayName("byFields generates default field query (PostgreSQL)")
fun byFieldsMultipleDefaultPostgres() {
Configuration.connectionString = pg
assertEquals("this WHERE data->>'a' = :the_a AND (data->>'b')::numeric = :b_value",
Query.byFields("this", listOf(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value"))))
}
@Test
@DisplayName("byFields generates default field query (SQLite)")
fun byFieldsMultipleDefaultSQLite() {
Configuration.connectionString = lite
assertEquals("this WHERE data->>'a' = :the_a AND data->>'b' = :b_value",
Query.byFields("this", listOf(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value"))))
}
@Test
@DisplayName("byFields generates ANY field query (PostgreSQL)")
fun byFieldsMultipleAnyPostgres() {
Configuration.connectionString = pg
assertEquals("that WHERE data->>'a' = :the_a OR (data->>'b')::numeric = :b_value",
Query.byFields("that", listOf(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value")),
FieldMatch.ANY))
}
@Test
@DisplayName("byFields generates ANY field query (SQLite)")
fun byFieldsMultipleAnySQLite() {
Configuration.connectionString = lite
assertEquals("that WHERE data->>'a' = :the_a OR data->>'b' = :b_value",
Query.byFields("that", listOf(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value")),
FieldMatch.ANY))
}
// ~~~ Definition ~~~
@Test
@@ -138,6 +239,26 @@ class QueryTest {
assertEquals("CREATE TABLE IF NOT EXISTS my.table (data JSONB NOT NULL)",
Query.Definition.ensureTableFor("my.table", "JSONB"), "CREATE TABLE statement not constructed correctly")
@Test
@DisplayName("Definition.ensureTable generates correctly (PostgreSQL)")
fun ensureTablePostgres() {
Configuration.connectionString = pg
assertEquals("CREATE TABLE IF NOT EXISTS $tbl (data JSONB NOT NULL)", Query.Definition.ensureTable(tbl))
}
@Test
@DisplayName("Definition.ensureTable generates correctly (SQLite)")
fun ensureTableSQLite() {
Configuration.connectionString = lite
assertEquals("CREATE TABLE IF NOT EXISTS $tbl (data TEXT NOT NULL)", Query.Definition.ensureTable(tbl))
}
@Test
@DisplayName("Definition.ensureTable fails when no dialect is set")
fun ensureTableFailsUnknown() {
assertThrows<DocumentException> { Query.Definition.ensureTable(tbl) }
}
@Test
@DisplayName("Definition.ensureKey generates correctly with schema")
fun ensureKeyWithSchema() =
@@ -175,11 +296,97 @@ class QueryTest {
Query.Definition.ensureIndexOn(tbl, "nest", listOf("a.b.c"), Dialect.SQLITE),
"CREATE INDEX for nested SQLite field incorrect")
// ~~~ root functions ~~~
@Test
@DisplayName("insert generates correctly")
fun insert() {
@DisplayName("insert generates no auto ID (PostgreSQL)")
fun insertNoAutoPostgres() {
Configuration.connectionString = pg
assertEquals("INSERT INTO $tbl VALUES (:data)", Query.insert(tbl), "INSERT statement not constructed correctly")
assertEquals("INSERT INTO $tbl VALUES (:data)", Query.insert(tbl))
}
@Test
@DisplayName("insert generates no auto ID (SQLite)")
fun insertNoAutoSQLite() {
Configuration.connectionString = lite
assertEquals("INSERT INTO $tbl VALUES (:data)", Query.insert(tbl))
}
@Test
@DisplayName("insert generates auto number (PostgreSQL)")
fun insertAutoNumberPostgres() {
Configuration.connectionString = pg
assertEquals(
"INSERT INTO $tbl VALUES (:data::jsonb || ('{\"id\":' " +
"|| (SELECT COALESCE(MAX((data->>'id')::numeric), 0) + 1 FROM $tbl) || '}')::jsonb)",
Query.insert(tbl, AutoId.NUMBER))
}
@Test
@DisplayName("insert generates auto number (SQLite)")
fun insertAutoNumberSQLite() {
Configuration.connectionString = lite
assertEquals(
"INSERT INTO $tbl VALUES (json_set(:data, '$.id', " +
"(SELECT coalesce(max(data->>'id'), 0) + 1 FROM $tbl)))",
Query.insert(tbl, AutoId.NUMBER))
}
@Test
@DisplayName("insert generates auto UUID (PostgreSQL)")
fun insertAutoUUIDPostgres() {
Configuration.connectionString = pg
val query = Query.insert(tbl, AutoId.UUID)
assertTrue(query.startsWith("INSERT INTO $tbl VALUES (:data::jsonb || '{\"id\":\""),
"Query start not correct (actual: $query)")
assertTrue(query.endsWith("\"}')"), "Query end not correct")
}
@Test
@DisplayName("insert generates auto UUID (SQLite)")
fun insertAutoUUIDSQLite() {
Configuration.connectionString = lite
val query = Query.insert(tbl, AutoId.UUID)
assertTrue(query.startsWith("INSERT INTO $tbl VALUES (json_set(:data, '$.id', '"),
"Query start not correct (actual: $query)")
assertTrue(query.endsWith("'))"), "Query end not correct")
}
@Test
@DisplayName("insert generates auto random string (PostgreSQL)")
fun insertAutoRandomPostgres() {
try {
Configuration.connectionString = pg
Configuration.idStringLength = 8
val query = Query.insert(tbl, AutoId.RANDOM_STRING)
assertTrue(query.startsWith("INSERT INTO $tbl VALUES (:data::jsonb || '{\"id\":\""),
"Query start not correct (actual: $query)")
assertTrue(query.endsWith("\"}')"), "Query end not correct")
assertEquals(8,
query.replace("INSERT INTO $tbl VALUES (:data::jsonb || '{\"id\":\"", "").replace("\"}')", "").length,
"Random string length incorrect")
} finally {
Configuration.idStringLength = 16
}
}
@Test
@DisplayName("insert generates auto random string (SQLite)")
fun insertAutoRandomSQLite() {
Configuration.connectionString = lite
val query = Query.insert(tbl, AutoId.RANDOM_STRING)
assertTrue(query.startsWith("INSERT INTO $tbl VALUES (json_set(:data, '$.id', '"),
"Query start not correct (actual: $query)")
assertTrue(query.endsWith("'))"), "Query end not correct")
assertEquals(Configuration.idStringLength,
query.replace("INSERT INTO $tbl VALUES (json_set(:data, '$.id', '", "").replace("'))", "").length,
"Random string length incorrect")
}
@Test
@DisplayName("insert fails when no dialect is set")
fun insertFailsUnknown() {
assertThrows<DocumentException> { Query.insert(tbl) }
}
@Test