package solutions.bitbadger.documents.common.query 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 solutions.bitbadger.documents.common.* import kotlin.test.assertEquals /** * Unit tests for the `Where` object */ @DisplayName("Kotlin | Common | Query: Where") class WhereTest { /** * Clear the connection string (resets Dialect) */ @AfterEach fun cleanUp() { Configuration.dialectValue = null } @Test @DisplayName("byFields is blank when given no fields") fun byFieldsBlankIfEmpty() = assertEquals("", Where.byFields(listOf())) @Test @DisplayName("byFields generates one numeric field (PostgreSQL)") fun byFieldsOneFieldPostgres() { Configuration.dialectValue = Dialect.POSTGRESQL assertEquals("(data->>'it')::numeric = :that", Where.byFields(listOf(Field.equal("it", 9, ":that")))) } @Test @DisplayName("byFields generates one alphanumeric field (PostgreSQL)") fun byFieldsOneAlphaFieldPostgres() { Configuration.dialectValue = Dialect.POSTGRESQL assertEquals("data->>'it' = :that", Where.byFields(listOf(Field.equal("it", "", ":that")))) } @Test @DisplayName("byFields generates one field (SQLite)") fun byFieldsOneFieldSQLite() { Configuration.dialectValue = Dialect.SQLITE assertEquals("data->>'it' = :that", Where.byFields(listOf(Field.equal("it", "", ":that")))) } @Test @DisplayName("byFields generates multiple fields w/ default match (PostgreSQL)") fun byFieldsMultipleDefaultPostgres() { Configuration.dialectValue = Dialect.POSTGRESQL assertEquals( "data->>'1' = :one AND (data->>'2')::numeric = :two AND data->>'3' = :three", Where.byFields( listOf(Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three")) ) ) } @Test @DisplayName("byFields generates multiple fields w/ default match (SQLite)") fun byFieldsMultipleDefaultSQLite() { Configuration.dialectValue = Dialect.SQLITE assertEquals( "data->>'1' = :one AND data->>'2' = :two AND data->>'3' = :three", Where.byFields( listOf(Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three")) ) ) } @Test @DisplayName("byFields generates multiple fields w/ ANY match (PostgreSQL)") fun byFieldsMultipleAnyPostgres() { Configuration.dialectValue = Dialect.POSTGRESQL assertEquals( "data->>'1' = :one OR (data->>'2')::numeric = :two OR data->>'3' = :three", Where.byFields( listOf(Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three")), FieldMatch.ANY ) ) } @Test @DisplayName("byFields generates multiple fields w/ ANY match (SQLite)") fun byFieldsMultipleAnySQLite() { Configuration.dialectValue = Dialect.SQLITE assertEquals( "data->>'1' = :one OR data->>'2' = :two OR data->>'3' = :three", Where.byFields( listOf(Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three")), FieldMatch.ANY ) ) } @Test @DisplayName("byId generates defaults for alphanumeric key (PostgreSQL)") fun byIdDefaultAlphaPostgres() { Configuration.dialectValue = Dialect.POSTGRESQL assertEquals("data->>'id' = :id", Where.byId(docId = "")) } @Test @DisplayName("byId generates defaults for numeric key (PostgreSQL)") fun byIdDefaultNumericPostgres() { Configuration.dialectValue = Dialect.POSTGRESQL assertEquals("(data->>'id')::numeric = :id", Where.byId(docId = 5)) } @Test @DisplayName("byId generates defaults (SQLite)") fun byIdDefaultSQLite() { Configuration.dialectValue = Dialect.SQLITE assertEquals("data->>'id' = :id", Where.byId(docId = "")) } @Test @DisplayName("byId generates named ID (PostgreSQL)") fun byIdDefaultNamedPostgres() { Configuration.dialectValue = Dialect.POSTGRESQL assertEquals("data->>'id' = :key", Where.byId(":key")) } @Test @DisplayName("byId generates named ID (SQLite)") fun byIdDefaultNamedSQLite() { Configuration.dialectValue = Dialect.SQLITE assertEquals("data->>'id' = :key", Where.byId(":key")) } @Test @DisplayName("jsonContains generates defaults (PostgreSQL)") fun jsonContainsDefaultPostgres() { Configuration.dialectValue = Dialect.POSTGRESQL assertEquals("data @> :criteria", Where.jsonContains()) } @Test @DisplayName("jsonContains generates named parameter (PostgreSQL)") fun jsonContainsNamedPostgres() { Configuration.dialectValue = Dialect.POSTGRESQL assertEquals("data @> :it", Where.jsonContains(":it")) } @Test @DisplayName("jsonContains fails (SQLite)") fun jsonContainsFailsSQLite() { Configuration.dialectValue = Dialect.SQLITE assertThrows { Where.jsonContains() } } @Test @DisplayName("jsonPathMatches generates defaults (PostgreSQL)") fun jsonPathMatchDefaultPostgres() { Configuration.dialectValue = Dialect.POSTGRESQL assertEquals("jsonb_path_exists(data, :path::jsonpath)", Where.jsonPathMatches()) } @Test @DisplayName("jsonPathMatches generates named parameter (PostgreSQL)") fun jsonPathMatchNamedPostgres() { Configuration.dialectValue = Dialect.POSTGRESQL assertEquals("jsonb_path_exists(data, :jp::jsonpath)", Where.jsonPathMatches(":jp")) } @Test @DisplayName("jsonPathMatches fails (SQLite)") fun jsonPathFailsSQLite() { Configuration.dialectValue = Dialect.SQLITE assertThrows { Where.jsonPathMatches() } } }