154 lines
5.3 KiB
Kotlin

package solutions.bitbadger.documents.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.AutoId
import solutions.bitbadger.documents.Configuration
import solutions.bitbadger.documents.DocumentException
import solutions.bitbadger.documents.support.ForceDialect
import solutions.bitbadger.documents.support.TEST_TABLE
import kotlin.test.assertEquals
import kotlin.test.assertTrue
/**
* Unit tests for the `Document` object
*/
@DisplayName("JVM | Kotlin | Query | DocumentQuery")
class DocumentQueryTest {
/**
* Clear the connection string (resets Dialect)
*/
@AfterEach
fun cleanUp() {
ForceDialect.none()
}
@Test
@DisplayName("insert generates no auto ID | PostgreSQL")
fun insertNoAutoPostgres() {
ForceDialect.postgres()
assertEquals("INSERT INTO $TEST_TABLE VALUES (:data)", DocumentQuery.insert(TEST_TABLE))
}
@Test
@DisplayName("insert generates no auto ID | SQLite")
fun insertNoAutoSQLite() {
ForceDialect.sqlite()
assertEquals("INSERT INTO $TEST_TABLE VALUES (:data)", DocumentQuery.insert(TEST_TABLE))
}
@Test
@DisplayName("insert generates auto number | PostgreSQL")
fun insertAutoNumberPostgres() {
ForceDialect.postgres()
assertEquals(
"INSERT INTO $TEST_TABLE VALUES (:data::jsonb || ('{\"id\":' " +
"|| (SELECT COALESCE(MAX((data->>'id')::numeric), 0) + 1 FROM $TEST_TABLE) || '}')::jsonb)",
DocumentQuery.insert(TEST_TABLE, AutoId.NUMBER)
)
}
@Test
@DisplayName("insert generates auto number | SQLite")
fun insertAutoNumberSQLite() {
ForceDialect.sqlite()
assertEquals(
"INSERT INTO $TEST_TABLE VALUES (json_set(:data, '$.id', " +
"(SELECT coalesce(max(data->>'id'), 0) + 1 FROM $TEST_TABLE)))",
DocumentQuery.insert(TEST_TABLE, AutoId.NUMBER)
)
}
@Test
@DisplayName("insert generates auto UUID | PostgreSQL")
fun insertAutoUUIDPostgres() {
ForceDialect.postgres()
val query = DocumentQuery.insert(TEST_TABLE, AutoId.UUID)
assertTrue(
query.startsWith("INSERT INTO $TEST_TABLE 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() {
ForceDialect.sqlite()
val query = DocumentQuery.insert(TEST_TABLE, AutoId.UUID)
assertTrue(
query.startsWith("INSERT INTO $TEST_TABLE 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 {
ForceDialect.postgres()
Configuration.idStringLength = 8
val query = DocumentQuery.insert(TEST_TABLE, AutoId.RANDOM_STRING)
assertTrue(
query.startsWith("INSERT INTO $TEST_TABLE VALUES (:data::jsonb || '{\"id\":\""),
"Query start not correct (actual: $query)"
)
assertTrue(query.endsWith("\"}')"), "Query end not correct")
assertEquals(
8,
query.replace("INSERT INTO $TEST_TABLE VALUES (:data::jsonb || '{\"id\":\"", "")
.replace("\"}')", "").length,
"Random string length incorrect"
)
} finally {
Configuration.idStringLength = 16
}
}
@Test
@DisplayName("insert generates auto random string | SQLite")
fun insertAutoRandomSQLite() {
ForceDialect.sqlite()
val query = DocumentQuery.insert(TEST_TABLE, AutoId.RANDOM_STRING)
assertTrue(
query.startsWith("INSERT INTO $TEST_TABLE 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 $TEST_TABLE VALUES (json_set(:data, '$.id', '", "").replace("'))", "").length,
"Random string length incorrect"
)
}
@Test
@DisplayName("insert fails when no dialect is set")
fun insertFailsUnknown() {
assertThrows<DocumentException> { DocumentQuery.insert(TEST_TABLE) }
}
@Test
@DisplayName("save generates correctly")
fun save() {
ForceDialect.postgres()
assertEquals(
"INSERT INTO $TEST_TABLE VALUES (:data) ON CONFLICT ((data->>'id')) DO UPDATE SET data = EXCLUDED.data",
DocumentQuery.save(TEST_TABLE), "INSERT ON CONFLICT UPDATE statement not constructed correctly"
)
}
@Test
@DisplayName("update generates successfully")
fun update() =
assertEquals(
"UPDATE $TEST_TABLE SET data = :data",
DocumentQuery.update(TEST_TABLE),
"Update query not constructed correctly"
)
}