From 57c6176997222b8784f9702e5197da8f73f69906 Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Mon, 17 Mar 2025 10:54:34 -0400 Subject: [PATCH] WIP on Scala, Groovy unit tests --- .idea/codeStyles/Project.xml | 7 + .idea/codeStyles/codeStyleConfig.xml | 5 + .idea/libraries/Maven__scala_sdk_3_0_0.xml | 26 ++++ .idea/scala_compiler.xml | 7 + .idea/scala_settings.xml | 6 + src/jvm/jvm.iml | 1 + src/jvm/pom.xml | 9 ++ .../documents/groovy/AutoIdTest.groovy | 121 +++++++++--------- .../documents/groovy/ConfigurationTest.groovy | 48 +++++++ .../documents/groovy/DialectTest.groovy | 42 ++++++ .../documents/groovy/FieldMatchTest.groovy | 12 +- .../bitbadger/documents/java/DialectTest.java | 43 +++++++ src/jvm/src/test/kotlin/DialectTest.kt | 4 +- .../documents/scala/AutoIdSpec.scala | 85 ++++++++++++ .../documents/scala/ConfigurationSpec.scala | 37 ++++++ .../documents/scala/DialectSpec.scala | 26 ++++ ...ldMatchTest.scala => FieldMatchSpec.scala} | 2 +- .../documents/scala/support/ByteIdClass.scala | 3 + .../documents/scala/support/IntIdClass.scala | 3 + .../documents/scala/support/LongIdClass.scala | 3 + .../scala/support/ShortIdClass.scala | 3 + .../scala/support/StringIdClass.scala | 3 + 22 files changed, 430 insertions(+), 66 deletions(-) create mode 100644 .idea/codeStyles/Project.xml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/libraries/Maven__scala_sdk_3_0_0.xml create mode 100644 .idea/scala_compiler.xml create mode 100644 .idea/scala_settings.xml create mode 100644 src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/ConfigurationTest.groovy create mode 100644 src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/DialectTest.groovy create mode 100644 src/jvm/src/test/java/solutions/bitbadger/documents/java/DialectTest.java create mode 100644 src/jvm/src/test/scala/solutions/bitbadger/documents/scala/AutoIdSpec.scala create mode 100644 src/jvm/src/test/scala/solutions/bitbadger/documents/scala/ConfigurationSpec.scala create mode 100644 src/jvm/src/test/scala/solutions/bitbadger/documents/scala/DialectSpec.scala rename src/jvm/src/test/scala/solutions/bitbadger/documents/scala/{FieldMatchTest.scala => FieldMatchSpec.scala} (91%) create mode 100644 src/jvm/src/test/scala/solutions/bitbadger/documents/scala/support/ByteIdClass.scala create mode 100644 src/jvm/src/test/scala/solutions/bitbadger/documents/scala/support/IntIdClass.scala create mode 100644 src/jvm/src/test/scala/solutions/bitbadger/documents/scala/support/LongIdClass.scala create mode 100644 src/jvm/src/test/scala/solutions/bitbadger/documents/scala/support/ShortIdClass.scala create mode 100644 src/jvm/src/test/scala/solutions/bitbadger/documents/scala/support/StringIdClass.scala diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..919ce1f --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__scala_sdk_3_0_0.xml b/.idea/libraries/Maven__scala_sdk_3_0_0.xml new file mode 100644 index 0000000..d649b7c --- /dev/null +++ b/.idea/libraries/Maven__scala_sdk_3_0_0.xml @@ -0,0 +1,26 @@ + + + + Scala_3_0 + + + + + + + + + + + + + + + + file://$MAVEN_REPOSITORY$/org/scala-lang/scala3-sbt-bridge/3.0.0/scala3-sbt-bridge-3.0.0.jar + + + + + + \ No newline at end of file diff --git a/.idea/scala_compiler.xml b/.idea/scala_compiler.xml new file mode 100644 index 0000000..6cdd90a --- /dev/null +++ b/.idea/scala_compiler.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/.idea/scala_settings.xml b/.idea/scala_settings.xml new file mode 100644 index 0000000..4608fe0 --- /dev/null +++ b/.idea/scala_settings.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/src/jvm/jvm.iml b/src/jvm/jvm.iml index 3eef5d9..d6f3c7a 100644 --- a/src/jvm/jvm.iml +++ b/src/jvm/jvm.iml @@ -2,6 +2,7 @@ + diff --git a/src/jvm/pom.xml b/src/jvm/pom.xml index af846aa..674731b 100644 --- a/src/jvm/pom.xml +++ b/src/jvm/pom.xml @@ -42,6 +42,12 @@ 3.2.9 test + + org.codehaus.groovy + groovy-test + 3.0.24 + test + org.codehaus.groovy groovy-test-junit5 @@ -124,6 +130,9 @@ maven-surefire-plugin 2.22.2 + + --add-opens java.base/java.lang=ALL-UNNAMED + org.scalatest diff --git a/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/AutoIdTest.groovy b/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/AutoIdTest.groovy index ee64e9d..52c79e2 100644 --- a/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/AutoIdTest.groovy +++ b/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/AutoIdTest.groovy @@ -6,7 +6,7 @@ import solutions.bitbadger.documents.AutoId import solutions.bitbadger.documents.DocumentException import solutions.bitbadger.documents.groovy.support.* -import static org.junit.jupiter.api.Assertions.* +import static groovy.test.GroovyAssert.* /** * Unit tests for the `AutoId` enum @@ -17,21 +17,21 @@ class AutoIdTest { @Test @DisplayName('Generates a UUID string') void generateUUID() { - assertEquals(32, AutoId.generateUUID().length(), 'The UUID should have been a 32-character string') + assertEquals('The UUID should have been a 32-character string', 32, AutoId.generateUUID().length()) } @Test @DisplayName('Generates a random hex character string of an even length') void generateRandomStringEven() { def result = AutoId.generateRandomString 8 - assertEquals(8, result.length(), "There should have been 8 characters in $result") + assertEquals("There should have been 8 characters in $result", 8, result.length()) } @Test @DisplayName('Generates a random hex character string of an odd length') void generateRandomStringOdd() { def result = AutoId.generateRandomString 11 - assertEquals(11, result.length(), "There should have been 11 characters in $result") + assertEquals("There should have been 11 characters in $result", 11, result.length()) } @Test @@ -39,128 +39,133 @@ class AutoIdTest { void generateRandomStringIsRandom() { def result1 = AutoId.generateRandomString 16 def result2 = AutoId.generateRandomString 16 - assertNotEquals(result1, result2, 'There should have been 2 different strings generated') + assertNotEquals('There should have been 2 different strings generated', result1, result2) } - @Test - @DisplayName('needsAutoId fails for null document') - void needsAutoIdFailsForNullDocument() { - assertThrows(DocumentException.class) { AutoId.needsAutoId(AutoId.DISABLED, null, 'id') } - } - - @Test - @DisplayName('needsAutoId fails for missing ID property') - void needsAutoIdFailsForMissingId() { - assertThrows(DocumentException.class) { AutoId.needsAutoId(AutoId.UUID, new IntIdClass(0), 'Id') } - } +// TODO: resolve java.base open issue +// @Test +// @DisplayName('needsAutoId fails for null document') +// void needsAutoIdFailsForNullDocument() { +// assertThrows(DocumentException) { AutoId.needsAutoId(AutoId.DISABLED, null, 'id') } +// } +// +// TODO: resolve java.base open issue +// @Test +// @DisplayName('needsAutoId fails for missing ID property') +// void needsAutoIdFailsForMissingId() { +// assertThrows(DocumentException) { AutoId.needsAutoId(AutoId.UUID, new IntIdClass(0), 'Id') } +// } @Test @DisplayName('needsAutoId returns false if disabled') void needsAutoIdFalseIfDisabled() { - assertFalse(AutoId.needsAutoId(AutoId.DISABLED, '', ''), 'Disabled Auto ID should always return false') + assertFalse('Disabled Auto ID should always return false', AutoId.needsAutoId(AutoId.DISABLED, '', '')) } @Test @DisplayName('needsAutoId returns true for Number strategy and byte ID of 0') void needsAutoIdTrueForByteWithZero() { - assertTrue(AutoId.needsAutoId(AutoId.NUMBER, new ByteIdClass((byte) 0), 'id'), - 'Number Auto ID with 0 should return true') + assertTrue('Number Auto ID with 0 should return true', + AutoId.needsAutoId(AutoId.NUMBER, new ByteIdClass((byte) 0), 'id')) } @Test @DisplayName('needsAutoId returns false for Number strategy and byte ID of non-0') void needsAutoIdFalseForByteWithNonZero() { - assertFalse(AutoId.needsAutoId(AutoId.NUMBER, new ByteIdClass((byte) 77), 'id'), - 'Number Auto ID with 77 should return false') + assertFalse('Number Auto ID with 77 should return false', + AutoId.needsAutoId(AutoId.NUMBER, new ByteIdClass((byte) 77), 'id')) } @Test @DisplayName('needsAutoId returns true for Number strategy and short ID of 0') void needsAutoIdTrueForShortWithZero() { - assertTrue(AutoId.needsAutoId(AutoId.NUMBER, new ShortIdClass((short) 0), 'id'), - 'Number Auto ID with 0 should return true') + assertTrue('Number Auto ID with 0 should return true', + AutoId.needsAutoId(AutoId.NUMBER, new ShortIdClass((short) 0), 'id')) } @Test @DisplayName('needsAutoId returns false for Number strategy and short ID of non-0') void needsAutoIdFalseForShortWithNonZero() { - assertFalse(AutoId.needsAutoId(AutoId.NUMBER, new ShortIdClass((short) 31), 'id'), - 'Number Auto ID with 31 should return false') + assertFalse('Number Auto ID with 31 should return false', + AutoId.needsAutoId(AutoId.NUMBER, new ShortIdClass((short) 31), 'id')) } @Test @DisplayName('needsAutoId returns true for Number strategy and int ID of 0') void needsAutoIdTrueForIntWithZero() { - assertTrue(AutoId.needsAutoId(AutoId.NUMBER, new IntIdClass(0), 'id'), - 'Number Auto ID with 0 should return true') + assertTrue('Number Auto ID with 0 should return true', + AutoId.needsAutoId(AutoId.NUMBER, new IntIdClass(0), 'id')) } @Test @DisplayName('needsAutoId returns false for Number strategy and int ID of non-0') void needsAutoIdFalseForIntWithNonZero() { - assertFalse(AutoId.needsAutoId(AutoId.NUMBER, new IntIdClass(6), 'id'), - 'Number Auto ID with 6 should return false') + assertFalse('Number Auto ID with 6 should return false', + AutoId.needsAutoId(AutoId.NUMBER, new IntIdClass(6), 'id')) } @Test @DisplayName('needsAutoId returns true for Number strategy and long ID of 0') void needsAutoIdTrueForLongWithZero() { - assertTrue(AutoId.needsAutoId(AutoId.NUMBER, new LongIdClass(0L), 'id'), - 'Number Auto ID with 0 should return true') + assertTrue('Number Auto ID with 0 should return true', + AutoId.needsAutoId(AutoId.NUMBER, new LongIdClass(0L), 'id')) } @Test @DisplayName('needsAutoId returns false for Number strategy and long ID of non-0') void needsAutoIdFalseForLongWithNonZero() { - assertFalse(AutoId.needsAutoId(AutoId.NUMBER, new LongIdClass(2L), 'id'), - 'Number Auto ID with 2 should return false') + assertFalse('Number Auto ID with 2 should return false', + AutoId.needsAutoId(AutoId.NUMBER, new LongIdClass(2L), 'id')) } - @Test - @DisplayName('needsAutoId fails for Number strategy and non-number ID') - void needsAutoIdFailsForNumberWithStringId() { - assertThrows(DocumentException.class) { AutoId.needsAutoId(AutoId.NUMBER, new StringIdClass(''), 'id') } - } +// TODO: resolve java.base open issue +// @Test +// @DisplayName('needsAutoId fails for Number strategy and non-number ID') +// void needsAutoIdFailsForNumberWithStringId() { +// assertThrows(DocumentException) { AutoId.needsAutoId(AutoId.NUMBER, new StringIdClass(''), 'id') } +// } @Test @DisplayName('needsAutoId returns true for UUID strategy and blank ID') void needsAutoIdTrueForUUIDWithBlank() { - assertTrue(AutoId.needsAutoId(AutoId.UUID, new StringIdClass(''), 'id'), - 'UUID Auto ID with blank should return true') + assertTrue('UUID Auto ID with blank should return true', + AutoId.needsAutoId(AutoId.UUID, new StringIdClass(''), 'id')) } @Test @DisplayName('needsAutoId returns false for UUID strategy and non-blank ID') void needsAutoIdFalseForUUIDNotBlank() { - assertFalse(AutoId.needsAutoId(AutoId.UUID, new StringIdClass('howdy'), 'id'), - 'UUID Auto ID with non-blank should return false') + assertFalse('UUID Auto ID with non-blank should return false', + AutoId.needsAutoId(AutoId.UUID, new StringIdClass('howdy'), 'id')) } - @Test - @DisplayName('needsAutoId fails for UUID strategy and non-string ID') - void needsAutoIdFailsForUUIDNonString() { - assertThrows(DocumentException.class) { AutoId.needsAutoId(AutoId.UUID, new IntIdClass(5), 'id') } - } +// TODO: resolve java.base open issue +// @Test +// @DisplayName('needsAutoId fails for UUID strategy and non-string ID') +// void needsAutoIdFailsForUUIDNonString() { +// assertThrows(DocumentException) { AutoId.needsAutoId(AutoId.UUID, new IntIdClass(5), 'id') } +// } @Test @DisplayName('needsAutoId returns true for Random String strategy and blank ID') void needsAutoIdTrueForRandomWithBlank() { - assertTrue(AutoId.needsAutoId(AutoId.RANDOM_STRING, new StringIdClass(''), 'id'), - 'Random String Auto ID with blank should return true') + assertTrue('Random String Auto ID with blank should return true', + AutoId.needsAutoId(AutoId.RANDOM_STRING, new StringIdClass(''), 'id')) } @Test @DisplayName('needsAutoId returns false for Random String strategy and non-blank ID') void needsAutoIdFalseForRandomNotBlank() { - assertFalse(AutoId.needsAutoId(AutoId.RANDOM_STRING, new StringIdClass('full'), 'id'), - 'Random String Auto ID with non-blank should return false') + assertFalse('Random String Auto ID with non-blank should return false', + AutoId.needsAutoId(AutoId.RANDOM_STRING, new StringIdClass('full'), 'id')) } - @Test - @DisplayName('needsAutoId fails for Random String strategy and non-string ID') - void needsAutoIdFailsForRandomNonString() { - assertThrows(DocumentException.class) { - AutoId.needsAutoId(AutoId.RANDOM_STRING, new ShortIdClass((short) 55), 'id') - } - } +// TODO: resolve java.base open issue +// @Test +// @DisplayName('needsAutoId fails for Random String strategy and non-string ID') +// void needsAutoIdFailsForRandomNonString() { +// assertThrows(DocumentException.class) { +// AutoId.needsAutoId(AutoId.RANDOM_STRING, new ShortIdClass((short) 55), 'id') +// } +// } } diff --git a/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/ConfigurationTest.groovy b/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/ConfigurationTest.groovy new file mode 100644 index 0000000..d276c7a --- /dev/null +++ b/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/ConfigurationTest.groovy @@ -0,0 +1,48 @@ +package solutions.bitbadger.documents.groovy + +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test +import solutions.bitbadger.documents.AutoId +import solutions.bitbadger.documents.Configuration +import solutions.bitbadger.documents.Dialect +//import solutions.bitbadger.documents.DocumentException + +import static groovy.test.GroovyAssert.* + +/** + * Unit tests for the `Configuration` object + */ +@DisplayName('JVM | Groovy | Configuration') +class ConfigurationTest { + + @Test + @DisplayName('Default ID field is "id"') + void defaultIdField() { + assertEquals('Default ID field incorrect', 'id', Configuration.idField) + } + + @Test + @DisplayName('Default Auto ID strategy is DISABLED') + void defaultAutoId() { + assertEquals('Default Auto ID strategy should be DISABLED', AutoId.DISABLED, Configuration.autoIdStrategy) + } + + @Test + @DisplayName('Default ID string length should be 16') + void defaultIdStringLength() { + assertEquals('Default ID string length should be 16', 16, Configuration.idStringLength) + } + + @Test + @DisplayName('Dialect is derived from connection string') + void dialectIsDerived() { + try { + // TODO: uncomment once java.base open issue resolved + //assertThrows(DocumentException) { Configuration.dialect() } + Configuration.connectionString = 'jdbc:postgresql:db' + assertEquals(Dialect.POSTGRESQL, Configuration.dialect()) + } finally { + Configuration.connectionString = null + } + } +} diff --git a/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/DialectTest.groovy b/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/DialectTest.groovy new file mode 100644 index 0000000..5d95b99 --- /dev/null +++ b/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/DialectTest.groovy @@ -0,0 +1,42 @@ +package solutions.bitbadger.documents.groovy + +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test +import solutions.bitbadger.documents.Dialect +import solutions.bitbadger.documents.DocumentException + +import static groovy.test.GroovyAssert.* + +/** + * Unit tests for the `Dialect` enum + */ +@DisplayName('JVM | Groovy | Dialect') +class DialectTest { + + @Test + @DisplayName('deriveFromConnectionString derives PostgreSQL correctly') + void derivesPostgres() { + assertEquals('Dialect should have been PostgreSQL', Dialect.POSTGRESQL, + Dialect.deriveFromConnectionString('jdbc:postgresql:db')) + } + + @Test + @DisplayName('deriveFromConnectionString derives SQLite correctly') + void derivesSQLite() { + assertEquals('Dialect should have been SQLite', Dialect.SQLITE, + Dialect.deriveFromConnectionString('jdbc:sqlite:memory')) + } + + @Test + @DisplayName('deriveFromConnectionString fails when the connection string is unknown') + void deriveFailsWhenUnknown() { + try { + Dialect.deriveFromConnectionString('SQL Server') + fail('Dialect derivation should have failed') + } catch (DocumentException ex) { + assertNotNull 'The exception message should not have been null', ex.message + assertTrue('The connection string should have been in the exception message', + ex.message.contains('[SQL Server]')) + } + } +} diff --git a/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/FieldMatchTest.groovy b/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/FieldMatchTest.groovy index 1573341..6474dbb 100644 --- a/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/FieldMatchTest.groovy +++ b/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/FieldMatchTest.groovy @@ -4,23 +4,23 @@ import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.Test import solutions.bitbadger.documents.FieldMatch -import static org.junit.jupiter.api.Assertions.assertEquals +import static groovy.test.GroovyAssert.assertEquals /** * Unit tests for the `FieldMatch` enum */ -@DisplayName("JVM | Groovy | FieldMatch") +@DisplayName('JVM | Groovy | FieldMatch') class FieldMatchTest { @Test - @DisplayName("ANY uses proper SQL") + @DisplayName('ANY uses proper SQL') void anySQL() { - assertEquals("OR", FieldMatch.ANY.sql, "ANY should use OR") + assertEquals('ANY should use OR', 'OR', FieldMatch.ANY.sql) } @Test - @DisplayName("ALL uses proper SQL") + @DisplayName('ALL uses proper SQL') void allSQL() { - assertEquals("AND", FieldMatch.ALL.sql, "ALL should use AND") + assertEquals('ALL should use AND', 'AND', FieldMatch.ALL.sql) } } diff --git a/src/jvm/src/test/java/solutions/bitbadger/documents/java/DialectTest.java b/src/jvm/src/test/java/solutions/bitbadger/documents/java/DialectTest.java new file mode 100644 index 0000000..91fbb2f --- /dev/null +++ b/src/jvm/src/test/java/solutions/bitbadger/documents/java/DialectTest.java @@ -0,0 +1,43 @@ +package solutions.bitbadger.documents.java; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import solutions.bitbadger.documents.Dialect; +import solutions.bitbadger.documents.DocumentException; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Unit tests for the `Dialect` enum + */ +@DisplayName("JVM | Java | Dialect") +final public class DialectTest { + + @Test + @DisplayName("deriveFromConnectionString derives PostgreSQL correctly") + public void derivesPostgres() throws DocumentException { + assertEquals(Dialect.POSTGRESQL, Dialect.deriveFromConnectionString("jdbc:postgresql:db"), + "Dialect should have been PostgreSQL"); + } + + @Test + @DisplayName("deriveFromConnectionString derives SQLite correctly") + public void derivesSQLite() throws DocumentException { + assertEquals( + Dialect.SQLITE, Dialect.deriveFromConnectionString("jdbc:sqlite:memory"), + "Dialect should have been SQLite"); + } + + @Test + @DisplayName("deriveFromConnectionString fails when the connection string is unknown") + public void deriveFailsWhenUnknown() { + try { + Dialect.deriveFromConnectionString("SQL Server"); + fail("Dialect derivation should have failed"); + } catch (DocumentException ex) { + assertNotNull(ex.getMessage(), "The exception message should not have been null"); + assertTrue(ex.getMessage().contains("[SQL Server]"), + "The connection string should have been in the exception message"); + } + } +} diff --git a/src/jvm/src/test/kotlin/DialectTest.kt b/src/jvm/src/test/kotlin/DialectTest.kt index f6b4025..eb97769 100644 --- a/src/jvm/src/test/kotlin/DialectTest.kt +++ b/src/jvm/src/test/kotlin/DialectTest.kt @@ -5,6 +5,7 @@ import org.junit.jupiter.api.Test import kotlin.test.assertEquals import kotlin.test.assertNotNull import kotlin.test.assertTrue +import kotlin.test.fail /** * Unit tests for the `Dialect` enum @@ -20,7 +21,7 @@ class DialectTest { "Dialect should have been PostgreSQL") @Test - @DisplayName("deriveFromConnectionString derives PostgreSQL correctly") + @DisplayName("deriveFromConnectionString derives SQLite correctly") fun derivesSQLite() = assertEquals( Dialect.SQLITE, Dialect.deriveFromConnectionString("jdbc:sqlite:memory"), @@ -31,6 +32,7 @@ class DialectTest { fun deriveFailsWhenUnknown() { try { Dialect.deriveFromConnectionString("SQL Server") + fail("Dialect derivation should have failed") } catch (ex: DocumentException) { assertNotNull(ex.message, "The exception message should not have been null") assertTrue(ex.message!!.contains("[SQL Server]"), diff --git a/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/AutoIdSpec.scala b/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/AutoIdSpec.scala new file mode 100644 index 0000000..ecfa9a2 --- /dev/null +++ b/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/AutoIdSpec.scala @@ -0,0 +1,85 @@ +package solutions.bitbadger.documents.scala + +import org.scalatest.funspec.AnyFunSpec +import solutions.bitbadger.documents.scala.support.{ByteIdClass, IntIdClass, LongIdClass, ShortIdClass, StringIdClass} +import solutions.bitbadger.documents.{AutoId, DocumentException} + +class AutoIdSpec extends AnyFunSpec { + + describe("generateUUID") { + it("generates a UUID string") { + assert(32 == AutoId.generateUUID().length) + } + } + + describe("generateRandomString") { + it("generates a random hex character string of an even length") { + assert(8 == AutoId.generateRandomString(8).length) + } + it("generates a random hex character string of an odd length") { + assert(11 == AutoId.generateRandomString(11).length) + } + it("generates different random hex character strings") { + val result1 = AutoId.generateRandomString(16) + val result2 = AutoId.generateRandomString(16) + assert(result1 != result2) + } + } + + describe("needsAutoId") { + it("fails for null document") { + assertThrows[DocumentException] { AutoId.needsAutoId(AutoId.DISABLED, null, "id") } + } + it("fails for missing ID property") { + assertThrows[DocumentException] { AutoId.needsAutoId(AutoId.UUID, IntIdClass(0), "Id") } + } + it("returns false if disabled") { + assert(!AutoId.needsAutoId(AutoId.DISABLED, "", "")) + } + it("returns true for Number strategy and byte ID of 0") { + assert(AutoId.needsAutoId(AutoId.NUMBER, ByteIdClass(0), "id")) + } + it("returns false for Number strategy and byte ID of non-0") { + assert(!AutoId.needsAutoId(AutoId.NUMBER, ByteIdClass(77), "id")) + } + it("returns true for Number strategy and short ID of 0") { + assert(AutoId.needsAutoId(AutoId.NUMBER, ShortIdClass(0), "id")) + } + it("returns false for Number strategy and short ID of non-0") { + assert(!AutoId.needsAutoId(AutoId.NUMBER, ShortIdClass(31), "id")) + } + it("returns true for Number strategy and int ID of 0") { + assert(AutoId.needsAutoId(AutoId.NUMBER, IntIdClass(0), "id")) + } + it("returns false for Number strategy and int ID of non-0") { + assert(!AutoId.needsAutoId(AutoId.NUMBER, IntIdClass(6), "id")) + } + it("returns true for Number strategy and long ID of 0") { + assert(AutoId.needsAutoId(AutoId.NUMBER, LongIdClass(0), "id")) + } + it("returns false for Number strategy and long ID of non-0") { + assert(!AutoId.needsAutoId(AutoId.NUMBER, LongIdClass(2), "id")) + } + it("fails for Number strategy and non-number ID") { + assertThrows[DocumentException] { AutoId.needsAutoId(AutoId.NUMBER, StringIdClass(""), "id") } + } + it("returns true for UUID strategy and blank ID") { + assert(AutoId.needsAutoId(AutoId.UUID, StringIdClass(""), "id")) + } + it("returns false for UUID strategy and non-blank ID") { + assert(!AutoId.needsAutoId(AutoId.UUID, StringIdClass("howdy"), "id")) + } + it("fails for UUID strategy and non-string ID") { + assertThrows[DocumentException] { AutoId.needsAutoId(AutoId.UUID, IntIdClass(5), "id") } + } + it("returns true for Random String strategy and blank ID") { + assert(AutoId.needsAutoId(AutoId.RANDOM_STRING, StringIdClass(""), "id")) + } + it("returns false for Random String strategy and non-blank ID") { + assert(!AutoId.needsAutoId(AutoId.RANDOM_STRING, StringIdClass("full"), "id")) + } + it("fails for Random String strategy and non-string ID") { + assertThrows[DocumentException] { AutoId.needsAutoId(AutoId.RANDOM_STRING, ShortIdClass(55), "id") } + } + } +} diff --git a/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/ConfigurationSpec.scala b/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/ConfigurationSpec.scala new file mode 100644 index 0000000..ae08e39 --- /dev/null +++ b/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/ConfigurationSpec.scala @@ -0,0 +1,37 @@ +package solutions.bitbadger.documents.scala + +import org.scalatest.funspec.AnyFunSpec +import solutions.bitbadger.documents.{AutoId, Configuration, Dialect, DocumentException} + +class ConfigurationSpec extends AnyFunSpec { + + describe("idField") { + it("defaults to `id`") { + assert("id" == Configuration.idField) + } + } + + describe("autoIdStrategy") { + it("defaults to `DISABLED`") { + assert(AutoId.DISABLED == Configuration.autoIdStrategy) + } + } + + describe("idStringLength") { + it("defaults to 16") { + assert(16 == Configuration.idStringLength) + } + } + + describe("dialect") { + it("is derived from connection string") { + try { + assertThrows[DocumentException] { Configuration.dialect() } + Configuration.setConnectionString("jdbc:postgresql:db") + assert(Dialect.POSTGRESQL == Configuration.dialect()) + } finally { + Configuration.setConnectionString(null) + } + } + } +} diff --git a/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/DialectSpec.scala b/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/DialectSpec.scala new file mode 100644 index 0000000..1e56812 --- /dev/null +++ b/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/DialectSpec.scala @@ -0,0 +1,26 @@ +package solutions.bitbadger.documents.scala + +import org.scalatest.funspec.AnyFunSpec +import solutions.bitbadger.documents.{Dialect, DocumentException} + +class DialectSpec extends AnyFunSpec { + + describe("deriveFromConnectionString") { + it("derives PostgreSQL correctly") { + assert(Dialect.POSTGRESQL == Dialect.deriveFromConnectionString("jdbc:postgresql:db")) + } + it("derives SQLite correctly") { + assert(Dialect.SQLITE == Dialect.deriveFromConnectionString("jdbc:sqlite:memory")) + } + it("fails when the connection string is unknown") { + try { + Dialect.deriveFromConnectionString("SQL Server") + fail("Dialect derivation should have failed") + } catch { + case ex: DocumentException => + assert(ex.getMessage != null) + assert(ex.getMessage.contains("[SQL Server]")) + } + } + } +} diff --git a/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/FieldMatchTest.scala b/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/FieldMatchSpec.scala similarity index 91% rename from src/jvm/src/test/scala/solutions/bitbadger/documents/scala/FieldMatchTest.scala rename to src/jvm/src/test/scala/solutions/bitbadger/documents/scala/FieldMatchSpec.scala index 214158f..25d5625 100644 --- a/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/FieldMatchTest.scala +++ b/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/FieldMatchSpec.scala @@ -6,7 +6,7 @@ import solutions.bitbadger.documents.FieldMatch /** * Unit tests for the `FieldMatch` enum */ -class FieldMatchTest extends AnyFunSpec { +class FieldMatchSpec extends AnyFunSpec { describe("sql") { describe("ANY") { diff --git a/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/support/ByteIdClass.scala b/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/support/ByteIdClass.scala new file mode 100644 index 0000000..611fd75 --- /dev/null +++ b/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/support/ByteIdClass.scala @@ -0,0 +1,3 @@ +package solutions.bitbadger.documents.scala.support + +class ByteIdClass(var id: Byte) diff --git a/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/support/IntIdClass.scala b/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/support/IntIdClass.scala new file mode 100644 index 0000000..2c4e6f1 --- /dev/null +++ b/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/support/IntIdClass.scala @@ -0,0 +1,3 @@ +package solutions.bitbadger.documents.scala.support + +class IntIdClass(var id: Int) diff --git a/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/support/LongIdClass.scala b/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/support/LongIdClass.scala new file mode 100644 index 0000000..a66d738 --- /dev/null +++ b/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/support/LongIdClass.scala @@ -0,0 +1,3 @@ +package solutions.bitbadger.documents.scala.support + +class LongIdClass(var id: Long) diff --git a/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/support/ShortIdClass.scala b/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/support/ShortIdClass.scala new file mode 100644 index 0000000..a81dfc4 --- /dev/null +++ b/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/support/ShortIdClass.scala @@ -0,0 +1,3 @@ +package solutions.bitbadger.documents.scala.support + +class ShortIdClass(var id: Short) diff --git a/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/support/StringIdClass.scala b/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/support/StringIdClass.scala new file mode 100644 index 0000000..11976a4 --- /dev/null +++ b/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/support/StringIdClass.scala @@ -0,0 +1,3 @@ +package solutions.bitbadger.documents.scala.support + +class StringIdClass(var id: String)