diff --git a/src/integration-test/kotlin/Types.kt b/src/integration-test/kotlin/Types.kt index c698ad5..b655427 100644 --- a/src/integration-test/kotlin/Types.kt +++ b/src/integration-test/kotlin/Types.kt @@ -23,13 +23,10 @@ data class ArrayDocument(val id: String, val values: List) { } @Serializable -data class JsonDocument(val id: String, val value: String, val numValue: Int, val sub: SubDocument?) { +data class JsonDocument(val id: String, val value: String = "", val numValue: Int = 0, val sub: SubDocument? = null) { companion object { - /** An empty JsonDocument */ - val emptyDoc = JsonDocument("", "", 0, null) - /** Documents to use for testing */ - val testDocuments = listOf( + private val testDocuments = listOf( JsonDocument("one", "FIRST!", 0, null), JsonDocument("two", "another", 10, SubDocument("green", "blue")), JsonDocument("three", "", 4, null), diff --git a/src/integration-test/kotlin/common/Document.kt b/src/integration-test/kotlin/common/Document.kt index 88a0f50..e17a091 100644 --- a/src/integration-test/kotlin/common/Document.kt +++ b/src/integration-test/kotlin/common/Document.kt @@ -56,7 +56,7 @@ object Document { Configuration.autoIdStrategy = AutoId.UUID assertEquals(0L, db.conn.countAll(TEST_TABLE), "There should be no documents in the table") - db.conn.insert(TEST_TABLE, JsonDocument.emptyDoc) + db.conn.insert(TEST_TABLE, JsonDocument("")) val after = db.conn.findAll(TEST_TABLE) assertEquals(1, after.size, "There should have been 1 document returned") @@ -71,10 +71,10 @@ object Document { Configuration.autoIdStrategy = AutoId.RANDOM_STRING assertEquals(0L, db.conn.countAll(TEST_TABLE), "There should be no documents in the table") - db.conn.insert(TEST_TABLE, JsonDocument.emptyDoc) + db.conn.insert(TEST_TABLE, JsonDocument("")) Configuration.idStringLength = 21 - db.conn.insert(TEST_TABLE, JsonDocument.emptyDoc) + db.conn.insert(TEST_TABLE, JsonDocument("")) val after = db.conn.findAll(TEST_TABLE) assertEquals(2, after.size, "There should have been 2 documents returned") diff --git a/src/integration-test/kotlin/common/Patch.kt b/src/integration-test/kotlin/common/Patch.kt index bbacc48..888054f 100644 --- a/src/integration-test/kotlin/common/Patch.kt +++ b/src/integration-test/kotlin/common/Patch.kt @@ -7,7 +7,7 @@ import kotlin.test.assertNotNull import kotlin.test.assertTrue /** - * Integration tests for the `Find` object + * Integration tests for the `Patch` object */ object Patch { diff --git a/src/integration-test/kotlin/common/RemoveFields.kt b/src/integration-test/kotlin/common/RemoveFields.kt new file mode 100644 index 0000000..20fb33f --- /dev/null +++ b/src/integration-test/kotlin/common/RemoveFields.kt @@ -0,0 +1,106 @@ +package solutions.bitbadger.documents.common + +import solutions.bitbadger.documents.* +import kotlin.test.* + + +/** + * Integration tests for the `RemoveFields` object + */ +object RemoveFields { + + fun byIdMatchFields(db: ThrowawayDatabase) { + JsonDocument.load(db) + db.conn.removeFieldsById(TEST_TABLE, "two", listOf("sub", "value")) + val doc = db.conn.findById(TEST_TABLE, "two") + assertNotNull(doc, "There should have been a document returned") + assertEquals("", doc.value, "The value should have been empty") + assertNull(doc.sub, "The sub-document should have been removed") + } + + fun byIdMatchNoFields(db: ThrowawayDatabase) { + JsonDocument.load(db) + assertFalse { db.conn.existsByFields(TEST_TABLE, listOf(Field.exists("a_field_that_does_not_exist"))) } + db.conn.removeFieldsById(TEST_TABLE, "one", listOf("a_field_that_does_not_exist")) // no exception = pass + } + + fun byIdNoMatch(db: ThrowawayDatabase) { + JsonDocument.load(db) + assertFalse { db.conn.existsById(TEST_TABLE, "fifty") } + db.conn.removeFieldsById(TEST_TABLE, "fifty", listOf("sub")) // no exception = pass + } + + fun byFieldsMatchFields(db: ThrowawayDatabase) { + JsonDocument.load(db) + val fields = listOf(Field.equal("numValue", 17)) + db.conn.removeFieldsByFields(TEST_TABLE, fields, listOf("sub")) + val doc = db.conn.findFirstByFields(TEST_TABLE, fields) + assertNotNull(doc, "The document should have been returned") + assertEquals("four", doc.id, "An incorrect document was returned") + assertNull(doc.sub, "The sub-document should have been removed") + } + + fun byFieldsMatchNoFields(db: ThrowawayDatabase) { + JsonDocument.load(db) + assertFalse { db.conn.existsByFields(TEST_TABLE, listOf(Field.exists("nada"))) } + db.conn.removeFieldsByFields(TEST_TABLE, listOf(Field.equal("numValue", 17)), listOf("nada")) // no exn = pass + } + + fun byFieldsNoMatch(db: ThrowawayDatabase) { + JsonDocument.load(db) + val fields = listOf(Field.notEqual("missing", "nope")) + assertFalse { db.conn.existsByFields(TEST_TABLE, fields) } + db.conn.removeFieldsByFields(TEST_TABLE, fields, listOf("value")) // no exception = pass + } + + fun byContainsMatchFields(db: ThrowawayDatabase) { + JsonDocument.load(db) + val criteria = mapOf("sub" to mapOf("foo" to "green")) + db.conn.removeFieldsByContains(TEST_TABLE, criteria, listOf("value")) + val docs = db.conn.findByContains>>(TEST_TABLE, criteria) + assertEquals(2, docs.size, "There should have been 2 documents returned") + docs.forEach { + assertTrue(listOf("two", "four").contains(it.id), "An incorrect document was returned (${it.id})") + assertEquals("", it.value, "The value should have been empty") + } + } + + fun byContainsMatchNoFields(db: ThrowawayDatabase) { + JsonDocument.load(db) + assertFalse { db.conn.existsByFields(TEST_TABLE, listOf(Field.exists("invalid_field"))) } + db.conn.removeFieldsByContains(TEST_TABLE, mapOf("sub" to mapOf("foo" to "green")), listOf("invalid_field")) + // no exception = pass + } + + fun byContainsNoMatch(db: ThrowawayDatabase) { + JsonDocument.load(db) + val contains = mapOf("value" to "substantial") + assertFalse { db.conn.existsByContains(TEST_TABLE, contains) } + db.conn.removeFieldsByContains(TEST_TABLE, contains, listOf("numValue")) + } + + fun byJsonPathMatchFields(db: ThrowawayDatabase) { + JsonDocument.load(db) + val path = "$.value ? (@ == \"purple\")" + db.conn.removeFieldsByJsonPath(TEST_TABLE, path, listOf("sub")) + val docs = db.conn.findByJsonPath(TEST_TABLE, path) + assertEquals(2, docs.size, "There should have been 2 documents returned") + docs.forEach { + assertTrue(listOf("four", "five").contains(it.id), "An incorrect document was returned (${it.id})") + assertNull(it.sub, "The sub-document should have been removed") + } + } + + fun byJsonPathMatchNoFields(db: ThrowawayDatabase) { + JsonDocument.load(db) + assertFalse { db.conn.existsByFields(TEST_TABLE, listOf(Field.exists("submarine"))) } + db.conn.removeFieldsByJsonPath(TEST_TABLE, "$.value ? (@ == \"purple\")", listOf("submarine")) // no exn = pass + } + + fun byJsonPathNoMatch(db: ThrowawayDatabase) { + JsonDocument.load(db) + val path = "$.value ? (@ == \"mauve\")" + assertFalse { db.conn.existsByJsonPath(TEST_TABLE, path) } + db.conn.removeFieldsByJsonPath(TEST_TABLE, path, listOf("value")) // no exception = pass + } +} diff --git a/src/integration-test/kotlin/postgresql/RemoveFieldsIT.kt b/src/integration-test/kotlin/postgresql/RemoveFieldsIT.kt new file mode 100644 index 0000000..d7beb63 --- /dev/null +++ b/src/integration-test/kotlin/postgresql/RemoveFieldsIT.kt @@ -0,0 +1,72 @@ +package solutions.bitbadger.documents.postgresql + +import org.junit.jupiter.api.DisplayName +import solutions.bitbadger.documents.common.RemoveFields +import kotlin.test.Test + +/** + * PostgreSQL integration tests for the `RemoveFields` object / `removeFieldsBy*` connection extension functions + */ +@DisplayName("PostgreSQL - RemoveFields") +class RemoveFieldsIT { + + @Test + @DisplayName("byId removes fields from an existing document") + fun byIdMatchFields() = + PgDB().use(RemoveFields::byIdMatchFields) + + @Test + @DisplayName("byId succeeds when fields do not exist on an existing document") + fun byIdMatchNoFields() = + PgDB().use(RemoveFields::byIdMatchNoFields) + + @Test + @DisplayName("byId succeeds when no document exists") + fun byIdNoMatch() = + PgDB().use(RemoveFields::byIdNoMatch) + + @Test + @DisplayName("byFields removes fields from matching documents") + fun byFieldsMatchFields() = + PgDB().use(RemoveFields::byFieldsMatchFields) + + @Test + @DisplayName("byFields succeeds when fields do not exist on matching documents") + fun byFieldsMatchNoFields() = + PgDB().use(RemoveFields::byFieldsMatchNoFields) + + @Test + @DisplayName("byFields succeeds when no matching documents exist") + fun byFieldsNoMatch() = + PgDB().use(RemoveFields::byFieldsNoMatch) + + @Test + @DisplayName("byContains removes fields from matching documents") + fun byContainsMatchFields() = + PgDB().use(RemoveFields::byContainsMatchFields) + + @Test + @DisplayName("byContains succeeds when fields do not exist on matching documents") + fun byContainsMatchNoFields() = + PgDB().use(RemoveFields::byContainsMatchNoFields) + + @Test + @DisplayName("byContains succeeds when no matching documents exist") + fun byContainsNoMatch() = + PgDB().use(RemoveFields::byContainsNoMatch) + + @Test + @DisplayName("byJsonPath removes fields from matching documents") + fun byJsonPathMatchFields() = + PgDB().use(RemoveFields::byJsonPathMatchFields) + + @Test + @DisplayName("byJsonPath succeeds when fields do not exist on matching documents") + fun byJsonPathMatchNoFields() = + PgDB().use(RemoveFields::byJsonPathMatchNoFields) + + @Test + @DisplayName("byJsonPath succeeds when no matching documents exist") + fun byJsonPathNoMatch() = + PgDB().use(RemoveFields::byJsonPathNoMatch) +} diff --git a/src/integration-test/kotlin/sqlite/RemoveFieldsIT.kt b/src/integration-test/kotlin/sqlite/RemoveFieldsIT.kt new file mode 100644 index 0000000..149b66d --- /dev/null +++ b/src/integration-test/kotlin/sqlite/RemoveFieldsIT.kt @@ -0,0 +1,56 @@ +package solutions.bitbadger.documents.sqlite + +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.assertThrows +import solutions.bitbadger.documents.DocumentException +import solutions.bitbadger.documents.common.RemoveFields +import kotlin.test.Test + +/** + * SQLite integration tests for the `RemoveFields` object / `removeFieldsBy*` connection extension functions + */ +@DisplayName("SQLite - RemoveFields") +class RemoveFieldsIT { + + @Test + @DisplayName("byId removes fields from an existing document") + fun byIdMatchFields() = + SQLiteDB().use(RemoveFields::byIdMatchFields) + + @Test + @DisplayName("byId succeeds when fields do not exist on an existing document") + fun byIdMatchNoFields() = + SQLiteDB().use(RemoveFields::byIdMatchNoFields) + + @Test + @DisplayName("byId succeeds when no document exists") + fun byIdNoMatch() = + SQLiteDB().use(RemoveFields::byIdNoMatch) + + @Test + @DisplayName("byFields removes fields from matching documents") + fun byFieldsMatchFields() = + SQLiteDB().use(RemoveFields::byFieldsMatchFields) + + @Test + @DisplayName("byFields succeeds when fields do not exist on matching documents") + fun byFieldsMatchNoFields() = + SQLiteDB().use(RemoveFields::byFieldsMatchNoFields) + + @Test + @DisplayName("byFields succeeds when no matching documents exist") + fun byFieldsNoMatch() = + SQLiteDB().use(RemoveFields::byFieldsNoMatch) + + @Test + @DisplayName("byContains fails") + fun byContainsFails() { + assertThrows { SQLiteDB().use(RemoveFields::byContainsMatchFields) } + } + + @Test + @DisplayName("byJsonPath fails") + fun byJsonPathFails() { + assertThrows { SQLiteDB().use(RemoveFields::byJsonPathMatchFields) } + } +} diff --git a/src/main/kotlin/Configuration.kt b/src/main/kotlin/Configuration.kt index fa473c4..8c2b484 100644 --- a/src/main/kotlin/Configuration.kt +++ b/src/main/kotlin/Configuration.kt @@ -13,8 +13,9 @@ object Configuration { * https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/json.md for all configuration options */ var json = Json { - encodeDefaults = true - explicitNulls = false + encodeDefaults = true + explicitNulls = false + coerceInputValues = true } /** The field in which a document's ID is stored */ diff --git a/src/main/kotlin/ConnectionExtensions.kt b/src/main/kotlin/ConnectionExtensions.kt index 9b7476d..9db989c 100644 --- a/src/main/kotlin/ConnectionExtensions.kt +++ b/src/main/kotlin/ConnectionExtensions.kt @@ -356,6 +356,60 @@ inline fun Connection.patchByContains( inline fun Connection.patchByJsonPath(tableName: String, path: String, patch: TPatch) = Patch.byJsonPath(tableName, path, patch, this) +// ~~~ DOCUMENT FIELD REMOVAL QUERIES ~~~ + +/** + * Remove fields from a document by its ID + * + * @param tableName The name of the table in which the document's fields should be removed + * @param docId The ID of the document to have fields removed + * @param toRemove The names of the fields to be removed + */ +fun Connection.removeFieldsById(tableName: String, docId: TKey, toRemove: Collection) = + RemoveFields.byId(tableName, docId, toRemove, this) + +/** + * Remove fields from documents using a field comparison + * + * @param tableName The name of the table in which document fields should be removed + * @param fields The fields which should be compared + * @param toRemove The names of the fields to be removed + * @param howMatched How the fields should be matched + */ +fun Connection.removeFieldsByFields( + tableName: String, + fields: Collection>, + toRemove: Collection, + howMatched: FieldMatch? = null +) = + RemoveFields.byFields(tableName, fields, toRemove, howMatched, this) + +/** + * Remove fields from documents using a JSON containment query (PostgreSQL only) + * + * @param tableName The name of the table in which document fields should be removed + * @param criteria The object against which JSON containment should be checked + * @param toRemove The names of the fields to be removed + * @throws DocumentException If called on a SQLite connection + */ +inline fun Connection.removeFieldsByContains( + tableName: String, + criteria: TContains, + toRemove: Collection +) = + RemoveFields.byContains(tableName, criteria, toRemove, this) + +/** + * Remove fields from documents using a JSON Path match query (PostgreSQL only) + * + * @param tableName The name of the table in which document fields should be removed + * @param path The JSON path comparison to match + * @param toRemove The names of the fields to be removed + * @throws DocumentException If called on a SQLite connection + */ +fun Connection.removeFieldsByJsonPath(tableName: String, path: String, toRemove: Collection) = + RemoveFields.byJsonPath(tableName, path, toRemove, this) + // ~~~ DOCUMENT DELETION QUERIES ~~~ /** diff --git a/src/main/kotlin/Parameters.kt b/src/main/kotlin/Parameters.kt index 3467ea2..4da353b 100644 --- a/src/main/kotlin/Parameters.kt +++ b/src/main/kotlin/Parameters.kt @@ -105,14 +105,14 @@ object Parameters { * @param parameterName The parameter name to use for the query * @return A list of parameters to use for building the query */ - fun fieldNames(names: Collection, parameterName: String = ":name") = + fun fieldNames(names: Collection, parameterName: String = ":name"): MutableCollection> = when (Configuration.dialect("generate field name parameters")) { - Dialect.POSTGRESQL -> listOf( + Dialect.POSTGRESQL -> mutableListOf( Parameter(parameterName, ParameterType.STRING, names.joinToString(",").let { "{$it}" }) ) Dialect.SQLITE -> names.mapIndexed { index, name -> Parameter("$parameterName$index", ParameterType.STRING, name) - } + }.toMutableList() } } diff --git a/src/main/kotlin/RemoveFields.kt b/src/main/kotlin/RemoveFields.kt new file mode 100644 index 0000000..7ce2c21 --- /dev/null +++ b/src/main/kotlin/RemoveFields.kt @@ -0,0 +1,154 @@ +package solutions.bitbadger.documents + +import solutions.bitbadger.documents.query.RemoveFields +import java.sql.Connection + +/** + * Functions to remove fields from documents + */ +object RemoveFields { + + /** + * Translate field paths to JSON paths for SQLite queries + * + * @param parameters The parameters for the specified fields + * @return The parameters for the specified fields, translated if used for SQLite + */ + private fun translatePath(parameters: MutableCollection>): MutableCollection> { + val dialect = Configuration.dialect("remove fields") + return when (dialect) { + Dialect.POSTGRESQL -> parameters + Dialect.SQLITE -> parameters.map { Parameter(it.name, it.type, "$.${it.value}") }.toMutableList() + } + } + + /** + * Remove fields from a document by its ID + * + * @param tableName The name of the table in which the document's fields should be removed + * @param docId The ID of the document to have fields removed + * @param toRemove The names of the fields to be removed + * @param conn The connection on which the update should be executed + */ + fun byId(tableName: String, docId: TKey, toRemove: Collection, conn: Connection) { + val nameParams = Parameters.fieldNames(toRemove) + conn.customNonQuery( + RemoveFields.byId(tableName, nameParams, docId), + Parameters.addFields( + listOf(Field.equal(Configuration.idField, docId, ":id")), + translatePath(nameParams) + ) + ) + } + + /** + * Remove fields from a document by its ID + * + * @param tableName The name of the table in which the document's fields should be removed + * @param docId The ID of the document to have fields removed + * @param toRemove The names of the fields to be removed + */ + fun byId(tableName: String, docId: TKey, toRemove: Collection) = + Configuration.dbConn().use { byId(tableName, docId, toRemove, it) } + + /** + * Remove fields from documents using a field comparison + * + * @param tableName The name of the table in which document fields should be removed + * @param fields The fields which should be compared + * @param toRemove The names of the fields to be removed + * @param howMatched How the fields should be matched + * @param conn The connection on which the update should be executed + */ + fun byFields( + tableName: String, + fields: Collection>, + toRemove: Collection, + howMatched: FieldMatch? = null, + conn: Connection + ) { + val named = Parameters.nameFields(fields) + val nameParams = Parameters.fieldNames(toRemove) + conn.customNonQuery( + RemoveFields.byFields(tableName, nameParams, named, howMatched), + Parameters.addFields(named, translatePath(nameParams)) + ) + } + + /** + * Remove fields from documents using a field comparison + * + * @param tableName The name of the table in which document fields should be removed + * @param fields The fields which should be compared + * @param toRemove The names of the fields to be removed + * @param howMatched How the fields should be matched + */ + fun byFields( + tableName: String, + fields: Collection>, + toRemove: Collection, + howMatched: FieldMatch? = null + ) = + Configuration.dbConn().use { byFields(tableName, fields, toRemove, howMatched, it) } + + /** + * Remove fields from documents using a JSON containment query (PostgreSQL only) + * + * @param tableName The name of the table in which document fields should be removed + * @param criteria The object against which JSON containment should be checked + * @param toRemove The names of the fields to be removed + * @param conn The connection on which the update should be executed + * @throws DocumentException If called on a SQLite connection + */ + inline fun byContains( + tableName: String, + criteria: TContains, + toRemove: Collection, + conn: Connection + ) { + val nameParams = Parameters.fieldNames(toRemove) + conn.customNonQuery( + RemoveFields.byContains(tableName, nameParams), + listOf(Parameters.json(":criteria", criteria), *nameParams.toTypedArray()) + ) + } + + /** + * Remove fields from documents using a JSON containment query (PostgreSQL only) + * + * @param tableName The name of the table in which document fields should be removed + * @param criteria The object against which JSON containment should be checked + * @param toRemove The names of the fields to be removed + * @throws DocumentException If called on a SQLite connection + */ + inline fun byContains(tableName: String, criteria: TContains, toRemove: Collection) = + Configuration.dbConn().use { byContains(tableName, criteria, toRemove, it) } + + /** + * Remove fields from documents using a JSON Path match query (PostgreSQL only) + * + * @param tableName The name of the table in which document fields should be removed + * @param path The JSON path comparison to match + * @param toRemove The names of the fields to be removed + * @param conn The connection on which the update should be executed + * @throws DocumentException If called on a SQLite connection + */ + fun byJsonPath(tableName: String, path: String, toRemove: Collection, conn: Connection) { + val nameParams = Parameters.fieldNames(toRemove) + conn.customNonQuery( + RemoveFields.byJsonPath(tableName, nameParams), + listOf(Parameter(":path", ParameterType.STRING, path), *nameParams.toTypedArray()) + ) + } + + /** + * Remove fields from documents using a JSON Path match query (PostgreSQL only) + * + * @param tableName The name of the table in which document fields should be removed + * @param path The JSON path comparison to match + * @param toRemove The names of the fields to be removed + * @throws DocumentException If called on a SQLite connection + */ + fun byJsonPath(tableName: String, path: String, toRemove: Collection) = + Configuration.dbConn().use { byJsonPath(tableName, path, toRemove, it) } +} diff --git a/src/main/kotlin/query/RemoveFields.kt b/src/main/kotlin/query/RemoveFields.kt index 1077e78..b3842c4 100644 --- a/src/main/kotlin/query/RemoveFields.kt +++ b/src/main/kotlin/query/RemoveFields.kt @@ -16,9 +16,9 @@ object RemoveFields { * @param toRemove The parameters for the fields to be removed * @return A query to remove fields from documents in the given table */ - private fun removeFields(tableName: String, toRemove: List>) = + private fun removeFields(tableName: String, toRemove: Collection>) = when (Configuration.dialect("generate field removal query")) { - Dialect.POSTGRESQL -> "UPDATE $tableName SET data = data - ${toRemove[0].name}::text[]" + Dialect.POSTGRESQL -> "UPDATE $tableName SET data = data - ${toRemove.elementAt(0).name}::text[]" Dialect.SQLITE -> toRemove.joinToString(", ") { it.name }.let { "UPDATE $tableName SET data = json_remove(data, $it)" } @@ -32,7 +32,7 @@ object RemoveFields { * @param docId The ID of the document to be updated (optional, used for type checking) * @return A query to patch a JSON document by its ID */ - fun byId(tableName: String, toRemove: List>, docId: TKey? = null) = + fun byId(tableName: String, toRemove: Collection>, docId: TKey? = null) = byIdBase(removeFields(tableName, toRemove), docId) /** @@ -46,7 +46,7 @@ object RemoveFields { */ fun byFields( tableName: String, - toRemove: List>, + toRemove: Collection>, fields: Collection>, howMatched: FieldMatch? = null ) = @@ -59,7 +59,7 @@ object RemoveFields { * @param toRemove The parameters for the fields to be removed * @return A query to patch JSON documents by JSON containment */ - fun byContains(tableName: String, toRemove: List>) = + fun byContains(tableName: String, toRemove: Collection>) = statementWhere(removeFields(tableName, toRemove), Where.jsonContains()) /** @@ -69,6 +69,6 @@ object RemoveFields { * @param toRemove The parameters for the fields to be removed * @return A query to patch JSON documents by JSON path match */ - fun byJsonPath(tableName: String, toRemove: List>) = + fun byJsonPath(tableName: String, toRemove: Collection>) = statementWhere(removeFields(tableName, toRemove), Where.jsonPathMatches()) } diff --git a/src/test/kotlin/ConfigurationTest.kt b/src/test/kotlin/ConfigurationTest.kt index acb8981..9e83235 100644 --- a/src/test/kotlin/ConfigurationTest.kt +++ b/src/test/kotlin/ConfigurationTest.kt @@ -18,6 +18,7 @@ class ConfigurationTest { fun defaultJsonOptions() { assertTrue(Configuration.json.configuration.encodeDefaults, "Encode Defaults should have been set") assertFalse(Configuration.json.configuration.explicitNulls, "Explicit Nulls should not have been set") + assertTrue(Configuration.json.configuration.coerceInputValues, "Coerce Input Values should have been set") } @Test diff --git a/src/test/kotlin/ParametersTest.kt b/src/test/kotlin/ParametersTest.kt index 154f872..e3d64a2 100644 --- a/src/test/kotlin/ParametersTest.kt +++ b/src/test/kotlin/ParametersTest.kt @@ -62,7 +62,7 @@ class ParametersTest { @DisplayName("fieldNames generates a single parameter (PostgreSQL)") fun fieldNamesSinglePostgres() { Configuration.dialectValue = Dialect.POSTGRESQL - val nameParams = Parameters.fieldNames(listOf("test")) + val nameParams = Parameters.fieldNames(listOf("test")).toList() assertEquals(1, nameParams.size, "There should be one name parameter") assertEquals(":name", nameParams[0].name, "The parameter name is incorrect") assertEquals(ParameterType.STRING, nameParams[0].type, "The parameter type is incorrect") @@ -73,7 +73,7 @@ class ParametersTest { @DisplayName("fieldNames generates multiple parameters (PostgreSQL)") fun fieldNamesMultiplePostgres() { Configuration.dialectValue = Dialect.POSTGRESQL - val nameParams = Parameters.fieldNames(listOf("test", "this", "today")) + val nameParams = Parameters.fieldNames(listOf("test", "this", "today")).toList() assertEquals(1, nameParams.size, "There should be one name parameter") assertEquals(":name", nameParams[0].name, "The parameter name is incorrect") assertEquals(ParameterType.STRING, nameParams[0].type, "The parameter type is incorrect") @@ -84,7 +84,7 @@ class ParametersTest { @DisplayName("fieldNames generates a single parameter (SQLite)") fun fieldNamesSingleSQLite() { Configuration.dialectValue = Dialect.SQLITE - val nameParams = Parameters.fieldNames(listOf("test")) + val nameParams = Parameters.fieldNames(listOf("test")).toList() assertEquals(1, nameParams.size, "There should be one name parameter") assertEquals(":name0", nameParams[0].name, "The parameter name is incorrect") assertEquals(ParameterType.STRING, nameParams[0].type, "The parameter type is incorrect") @@ -95,7 +95,7 @@ class ParametersTest { @DisplayName("fieldNames generates multiple parameters (SQLite)") fun fieldNamesMultipleSQLite() { Configuration.dialectValue = Dialect.SQLITE - val nameParams = Parameters.fieldNames(listOf("test", "this", "today")) + val nameParams = Parameters.fieldNames(listOf("test", "this", "today")).toList() assertEquals(3, nameParams.size, "There should be one name parameter") assertEquals(":name0", nameParams[0].name, "The first parameter name is incorrect") assertEquals(ParameterType.STRING, nameParams[0].type, "The first parameter type is incorrect")