diff --git a/src/main/kotlin/fr/postgresjson/connexion/Connection.kt b/src/main/kotlin/fr/postgresjson/connexion/Connection.kt index 0407224..dd9fc77 100644 --- a/src/main/kotlin/fr/postgresjson/connexion/Connection.kt +++ b/src/main/kotlin/fr/postgresjson/connexion/Connection.kt @@ -228,7 +228,7 @@ class Connection( logger?.info( """ |Query Error: - |${sql}, + |$sql, |Arguments (${values.length}): |${values.joinToString(", ").ifBlank { "No arguments" }.prependIndent()} """.trimMargin().prependIndent(" > "), diff --git a/src/main/kotlin/fr/postgresjson/migration/MigrationExecutor.kt b/src/main/kotlin/fr/postgresjson/migration/MigrationExecutor.kt index 754b093..1f6d4bf 100644 --- a/src/main/kotlin/fr/postgresjson/migration/MigrationExecutor.kt +++ b/src/main/kotlin/fr/postgresjson/migration/MigrationExecutor.kt @@ -306,8 +306,4 @@ class MigrationExecutor private constructor( return MigrationExecutor(connection, queriesCopy, functionsCopy) } - - fun status(): Map { - TODO("not implemented") - } } diff --git a/src/test/kotlin/fr/postgresjson/ConnectionTest.kt b/src/test/kotlin/fr/postgresjson/ConnectionTest.kt index 738520e..c861691 100644 --- a/src/test/kotlin/fr/postgresjson/ConnectionTest.kt +++ b/src/test/kotlin/fr/postgresjson/ConnectionTest.kt @@ -6,130 +6,169 @@ import fr.postgresjson.connexion.SqlSerializable import fr.postgresjson.connexion.execute import fr.postgresjson.serializer.deserialize import fr.postgresjson.serializer.toTypeReference -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.TestInstance +import io.kotest.core.spec.style.StringSpec +import io.kotest.matchers.nulls.shouldBeNull +import io.kotest.matchers.nulls.shouldNotBeNull +import org.amshove.kluent.`should be equal to` import org.junit.jupiter.api.assertThrows import java.util.UUID import kotlin.reflect.full.hasAnnotation import kotlin.test.assertEquals import kotlin.test.assertFalse import kotlin.test.assertNotNull -import kotlin.test.assertNull import kotlin.test.assertTrue -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -class ConnectionTest : TestAbstract() { - @SqlSerializable - private class ObjTest(val name: String, val id: UUID = UUID.fromString("2c0243ed-ff4d-4b9f-a52b-e38c71b0ed00")) - @SqlSerializable - private class ObjTest2(val id: UUID, val title: String, var test: ObjTest?) - @SqlSerializable - private class ObjTest3(val id: UUID, val first: String, var second: String, var third: Int) - @SqlSerializable - private class ObjTestWithParameterObject(val id: UUID, var first: ParameterObject, var second: ParameterObject) - @SqlSerializable - private class ParameterObject(var third: String) - private class ObjTest4 +class ConnectionTest : StringSpec({ + val connection = TestConnection() - @Test - fun serializable() { + @SqlSerializable + class ObjTest(val name: String, val id: UUID = UUID.fromString("2c0243ed-ff4d-4b9f-a52b-e38c71b0ed00")) + @SqlSerializable + class ObjTest2(val id: UUID, val title: String, var test: ObjTest?) + @SqlSerializable + class ObjTest3(val id: UUID, val first: String, var second: String, var third: Int) + @SqlSerializable + class ParameterObject(var third: String) + @SqlSerializable + class ObjTestWithParameterObject(val id: UUID, var first: ParameterObject, var second: ParameterObject) + class ObjTest4 + + "serializable" { assertTrue(ObjTest("plop")::class.hasAnnotation()) assertFalse(ObjTest4()::class.hasAnnotation()) } - @Test - fun getObject() { - val obj: ObjTest? = connection.execute("select to_json(a) from test a limit 1") + "getObject" { + val obj: ObjTest? = connection.rollbackAfter { + sendQuery( + """ + create table test( + id UUID primary key, + name text + ); + INSERT INTO test (id, name) VALUES ('1e5f5d41-6d14-4007-897b-0ed2616bec96', 'one'); + INSERT INTO test (id, name) VALUES ('26fa76cf-7688-4a1d-b611-e3060b38bf58', 'two'); + """.trimIndent() + ) + + execute("select to_json(a) from test a limit 1") + } + assertNotNull(obj) assertEquals(UUID.fromString("1e5f5d41-6d14-4007-897b-0ed2616bec96"), obj.id) } - @Test - fun getExistingObject() { - val objs: List? = connection.execute>( - """ - select - json_agg(j) - FROM ( - SELECT - t.id, - t.title, - t2 as test - from test2 t - JOIN test t2 ON t.test_id = t2.id - ) j; - """.trimIndent() - ) - assertNotNull(objs) - assertEquals(objs.size, 2) - assertEquals(objs[0].id, UUID.fromString("1e5f5d41-6d14-4007-897b-0ed2616bec96")) - assertEquals(objs[0].title, "plop") - assertEquals(objs[0].test!!.id, UUID.fromString("1e5f5d41-6d14-4007-897b-0ed2616bec96")) + "getExistingObject" { + val objs: List? = connection.rollbackAfter { + sendQuery( + """ + create table test( + id uuid primary key, + name text + ); + create table test2( + id uuid primary key, + title text, + test_id uuid + ); + INSERT INTO test VALUES ('1e5f5d41-6d14-4007-897b-0ed2616bec96', 'one'); + INSERT INTO test2 VALUES ('a0214677-7332-4eec-8e9b-af0658ea72a6', 'two', '1e5f5d41-6d14-4007-897b-0ed2616bec96'); + INSERT INTO test2 VALUES ('8545577e-2785-421f-bb7e-1ec3faa1d79a', 'three', null); + """.trimIndent() + ) + + execute>( + """ + select json_agg(j) + from ( + select + t.id, + t.title, + t2 as test + from test2 t + join test t2 ON t.test_id = t2.id + ) j; + """.trimIndent() + ) + } + + objs.shouldNotBeNull() + objs.size `should be equal to` 1 + objs.first().id `should be equal to` UUID.fromString("a0214677-7332-4eec-8e9b-af0658ea72a6") + objs.first().title `should be equal to` "two" + objs.first().test!!.id `should be equal to` UUID.fromString("1e5f5d41-6d14-4007-897b-0ed2616bec96") + objs.first().test!!.name `should be equal to` "one" } - @Test - fun `test call request with args`() { + "test call request with args" { val result: ObjTest? = connection.execute( "select json_build_object('id', '2c0243ed-ff4d-4b9f-a52b-e38c71b0ed00', 'name', ?::text)", listOf("myName") ) - assertNotNull(result) - assertEquals("myName", result.name) + result.shouldNotBeNull() + result.name `should be equal to` "myName" } - @Test - fun `test call request without args`() { + "test call request without args" { val result: ObjTest? = connection.execute( "select json_build_object('id', '2c0243ed-ff4d-4b9f-a52b-e38c71b0ed00', 'name', 'myName')", object : TypeReference() {} ) { assertEquals("myName", this.deserialize()?.name) } - assertNotNull(result) - assertEquals("myName", result.name) + result.shouldNotBeNull() + result.name `should be equal to` "myName" } - @Test - fun `test call request return null`() { + "test call request return null" { val result: ObjTest? = connection.execute("select null;", object : TypeReference() {}) - assertNull(result) + result.shouldBeNull() } - @Test - fun `test call request return nothing`() { - val e = assertThrows { - connection.execute("select * from test where false;", object : TypeReference() {}) + "test call request return nothing" { + val e = connection.rollbackAfter { + sendQuery( + """ + create table test( + id UUID primary key, + name text + ); + """.trimIndent() + ) + + assertThrows { + execute("select * from test where false;", object : TypeReference() {}) + } } - assertEquals("No data return for the query", e.message) - assertEquals("select * from test where false;", e.queryExecuted) + + e.shouldNotBeNull() + e.message `should be equal to` "No data return for the query" + e.queryExecuted `should be equal to` "select * from test where false;" } - @Test - fun callRequestWithArgsEntity() { + "callRequestWithArgsEntity" { val o = ObjTest("myName", id = UUID.fromString("2c0243ed-ff4d-4b9f-a52b-e38c71b0ed00")) val obj: ObjTest? = connection.execute( "select json_build_object('id', id, 'name', name) FROM json_to_record(?::json) as o(id uuid, name text);", listOf(o) ) - assertNotNull(obj) - assertEquals(UUID.fromString("2c0243ed-ff4d-4b9f-a52b-e38c71b0ed00"), obj.id) - assertEquals("myName", obj.name) + obj.shouldNotBeNull() + obj.id `should be equal to` UUID.fromString("2c0243ed-ff4d-4b9f-a52b-e38c71b0ed00") + obj.name `should be equal to` "myName" } - @Test - fun `test update Entity`() { + "test update Entity" { val obj = ObjTest("before", id = UUID.fromString("1e5f5d41-6d14-4007-897b-0ed2616bec96")) val objUpdated: ObjTest? = connection.execute( "select ?::jsonb || jsonb_build_object('name', 'after');", obj.toTypeReference(), listOf(obj) ) - assertNotNull(objUpdated) - assertEquals(UUID.fromString("1e5f5d41-6d14-4007-897b-0ed2616bec96"), objUpdated.id) - assertEquals("after", objUpdated.name) + objUpdated.shouldNotBeNull() + objUpdated.id `should be equal to` UUID.fromString("1e5f5d41-6d14-4007-897b-0ed2616bec96") + objUpdated.name `should be equal to` "after" } - @Test - fun `test update Entity with vararg`() { + "test update Entity with vararg" { val obj = ObjTest("before", id = UUID.fromString("1e5f5d41-6d14-4007-897b-0ed2616bec96")) val objUpdated: ObjTest? = connection.execute( "select :obj::jsonb || jsonb_build_object('name', 'after');", @@ -141,8 +180,7 @@ class ConnectionTest : TestAbstract() { assertEquals("after", objUpdated.name) } - @Test - fun callExec() { + "callExec" { val o = ObjTest("myName") val result = connection.exec( "select json_build_object('id', '2c0243ed-ff4d-4b9f-a52b-e38c71b0ed00', 'name', ?::json->>'name')", @@ -151,8 +189,7 @@ class ConnectionTest : TestAbstract() { assertEquals(1, result.rowsAffected) } - @Test - fun `select one with named parameters`() { + "select one with named parameters" { val result: ObjTest3? = connection.execute( """ SELECT json_build_object( @@ -174,8 +211,7 @@ class ConnectionTest : TestAbstract() { assertEquals(123, result.third) } - @Test - fun `select one with named parameters object`() { + "select one with named parameters object" { val result: ObjTestWithParameterObject? = connection.execute( """ SELECT json_build_object( @@ -195,8 +231,7 @@ class ConnectionTest : TestAbstract() { assertEquals("two", result.second.third) } - @Test - fun `select with named parameters`() { + "select with named parameters" { val result: List? = connection.execute( """ SELECT json_build_array( @@ -227,8 +262,7 @@ class ConnectionTest : TestAbstract() { assertEquals(123, result[0].third) } - @Test - fun `select with named parameters as vararg of Pair`() { + "select with named parameters as vararg of Pair" { val result: List? = connection.execute( """ SELECT json_build_array( @@ -247,8 +281,7 @@ class ConnectionTest : TestAbstract() { assertEquals(123, result[0].third) } - @Test - fun `execute with extra parameters`() { + "execute with extra parameters" { val params: Map = mapOf( "first" to "ff", "third" to 123, @@ -276,24 +309,21 @@ class ConnectionTest : TestAbstract() { assertEquals(123, result.third) } - @Test - fun `test exec without parameters`() { + "test exec without parameters" { connection.exec("select 42, 'hello';").run { assertEquals(42, rows[0].getInt(0)) assertEquals("hello", rows[0].getString(1)) } } - @Test - fun `test exec with one object as parameter`() { + "test exec with one object as parameter" { val obj = ObjTest("myName", UUID.fromString("c606e216-53b3-43c8-a900-e727cb4a017c")) connection.exec("select ?::jsonb->>'name'", obj).run { assertEquals("myName", rows[0].getString(0)) } } - @Test - fun `select one in transaction`() { + "select one in transaction" { connection.inTransaction { execute( """ @@ -314,4 +344,4 @@ class ConnectionTest : TestAbstract() { } } } -} +}) diff --git a/src/test/kotlin/fr/postgresjson/SqlFixtureListener.kt b/src/test/kotlin/fr/postgresjson/SqlFixtureListener.kt new file mode 100644 index 0000000..d15da5d --- /dev/null +++ b/src/test/kotlin/fr/postgresjson/SqlFixtureListener.kt @@ -0,0 +1,26 @@ +package fr.postgresjson + +import fr.postgresjson.connexion.Connection +import io.kotest.core.listeners.AfterSpecListener +import io.kotest.core.listeners.BeforeSpecListener +import io.kotest.core.spec.Spec +import java.io.File + +open class SqlFixtureListener : BeforeSpecListener, AfterSpecListener { + private val connection = Connection(database = "json_test", username = "test", password = "test", port = 35555) + + override suspend fun beforeSpec(spec: Spec) { + val initSQL = File(this::class.java.getResource("/fixtures/init.sql")!!.toURI()) + connection + .connect() + .sendQuery(initSQL.readText()) + .join() + } + + override suspend fun afterSpec(spec: Spec) { + val downSQL = File(this::class.java.getResource("/fixtures/down.sql")!!.toURI()) + connection + .apply { connect().sendQuery(downSQL.readText()).join() } + .disconnect() + } +} diff --git a/src/test/kotlin/fr/postgresjson/TestConnection.kt b/src/test/kotlin/fr/postgresjson/TestConnection.kt new file mode 100644 index 0000000..fa8aa27 --- /dev/null +++ b/src/test/kotlin/fr/postgresjson/TestConnection.kt @@ -0,0 +1,16 @@ +package fr.postgresjson + +import fr.postgresjson.connexion.Connection + +fun TestConnection(): Connection = + Connection(database = "json_test", username = "test", password = "test", port = 35555) + +fun Connection.rollbackAfter(block: Connection.() -> A?) = connect().run { + sendQuery("BEGIN") + try { + block().apply { sendQuery("ROLLBACK") } + } catch (e: Throwable) { + sendQuery("ROLLBACK") + throw e + } +}