diff --git a/.idea/encodings.xml b/.idea/encodings.xml
index 2afc1f9..3a6db4a 100644
--- a/.idea/encodings.xml
+++ b/.idea/encodings.xml
@@ -5,6 +5,7 @@
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..46a3f3f
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 6871788..b32d087 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
solutions.bitbadger
documents
4.0.0-alpha1-SNAPSHOT
- jar
+ pom
${project.groupId}:${project.artifactId}
Expose a document store interface for PostgreSQL and SQLite
diff --git a/src/jvm/jvm.iml b/src/jvm/jvm.iml
new file mode 100644
index 0000000..3eef5d9
--- /dev/null
+++ b/src/jvm/jvm.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/jvm/pom.xml b/src/jvm/pom.xml
index 33c4d65..af846aa 100644
--- a/src/jvm/pom.xml
+++ b/src/jvm/pom.xml
@@ -36,6 +36,18 @@
${jackson.version}
test
+
+ org.scalatest
+ scalatest_3
+ 3.2.9
+ test
+
+
+ org.codehaus.groovy
+ groovy-test-junit5
+ 3.0.24
+ test
+
@@ -68,15 +80,69 @@
${project.basedir}/src/test/kotlin
${project.basedir}/src/test/java
+ ${project.basedir}/src/test/scala
+
+ net.alchim31.maven
+ scala-maven-plugin
+ 4.9.2
+
+
+
+ testCompile
+
+
+
+
+ ${java.version}
+ ${java.version}
+
+
+
+ org.codehaus.gmaven
+ gmaven-plugin
+ 1.5
+
+ ${java.version}
+
+
+
+
+ 2.0
+
+
+ generateTestStubs
+ testCompile
+
+
+
+
maven-surefire-plugin
2.22.2
+
+ org.scalatest
+ scalatest-maven-plugin
+ 2.2.0
+
+ ${project.build.directory}/surefire-reports
+ .
+ WDF TestSuite.txt
+
+
+
+ test
+
+ test
+
+
+
+
maven-failsafe-plugin
2.22.2
@@ -92,6 +158,7 @@
org.apache.maven.plugins
maven-compiler-plugin
+ 3.13.0
${java.version}
${java.version}
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
new file mode 100644
index 0000000..ee64e9d
--- /dev/null
+++ b/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/AutoIdTest.groovy
@@ -0,0 +1,166 @@
+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.DocumentException
+import solutions.bitbadger.documents.groovy.support.*
+
+import static org.junit.jupiter.api.Assertions.*
+
+/**
+ * Unit tests for the `AutoId` enum
+ */
+@DisplayName('JVM | Groovy | AutoId')
+class AutoIdTest {
+
+ @Test
+ @DisplayName('Generates a UUID string')
+ void generateUUID() {
+ assertEquals(32, AutoId.generateUUID().length(), 'The UUID should have been a 32-character string')
+ }
+
+ @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")
+ }
+
+ @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")
+ }
+
+ @Test
+ @DisplayName('Generates different random hex character strings')
+ void generateRandomStringIsRandom() {
+ def result1 = AutoId.generateRandomString 16
+ def result2 = AutoId.generateRandomString 16
+ assertNotEquals(result1, result2, 'There should have been 2 different strings generated')
+ }
+
+ @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') }
+ }
+
+ @Test
+ @DisplayName('needsAutoId returns false if disabled')
+ void needsAutoIdFalseIfDisabled() {
+ assertFalse(AutoId.needsAutoId(AutoId.DISABLED, '', ''), 'Disabled Auto ID should always return false')
+ }
+
+ @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')
+ }
+
+ @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')
+ }
+
+ @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')
+ }
+
+ @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')
+ }
+
+ @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')
+ }
+
+ @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')
+ }
+
+ @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')
+ }
+
+ @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')
+ }
+
+ @Test
+ @DisplayName('needsAutoId fails for Number strategy and non-number ID')
+ void needsAutoIdFailsForNumberWithStringId() {
+ assertThrows(DocumentException.class) { 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')
+ }
+
+ @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')
+ }
+
+ @Test
+ @DisplayName('needsAutoId fails for UUID strategy and non-string ID')
+ void needsAutoIdFailsForUUIDNonString() {
+ assertThrows(DocumentException.class) { 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')
+ }
+
+ @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')
+ }
+
+ @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/FieldMatchTest.groovy b/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/FieldMatchTest.groovy
new file mode 100644
index 0000000..1573341
--- /dev/null
+++ b/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/FieldMatchTest.groovy
@@ -0,0 +1,26 @@
+package solutions.bitbadger.documents.groovy
+
+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
+
+/**
+ * Unit tests for the `FieldMatch` enum
+ */
+@DisplayName("JVM | Groovy | FieldMatch")
+class FieldMatchTest {
+
+ @Test
+ @DisplayName("ANY uses proper SQL")
+ void anySQL() {
+ assertEquals("OR", FieldMatch.ANY.sql, "ANY should use OR")
+ }
+
+ @Test
+ @DisplayName("ALL uses proper SQL")
+ void allSQL() {
+ assertEquals("AND", FieldMatch.ALL.sql, "ALL should use AND")
+ }
+}
diff --git a/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/support/ByteIdClass.groovy b/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/support/ByteIdClass.groovy
new file mode 100644
index 0000000..62442f6
--- /dev/null
+++ b/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/support/ByteIdClass.groovy
@@ -0,0 +1,9 @@
+package solutions.bitbadger.documents.groovy.support
+
+class ByteIdClass {
+ byte id
+
+ ByteIdClass(byte id) {
+ this.id = id
+ }
+}
diff --git a/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/support/IntIdClass.groovy b/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/support/IntIdClass.groovy
new file mode 100644
index 0000000..63d7f75
--- /dev/null
+++ b/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/support/IntIdClass.groovy
@@ -0,0 +1,9 @@
+package solutions.bitbadger.documents.groovy.support
+
+class IntIdClass {
+ int id
+
+ IntIdClass(int id) {
+ this.id = id
+ }
+}
diff --git a/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/support/LongIdClass.groovy b/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/support/LongIdClass.groovy
new file mode 100644
index 0000000..377fa1d
--- /dev/null
+++ b/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/support/LongIdClass.groovy
@@ -0,0 +1,9 @@
+package solutions.bitbadger.documents.groovy.support
+
+class LongIdClass {
+ long id
+
+ LongIdClass(long id) {
+ this.id = id
+ }
+}
diff --git a/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/support/ShortIdClass.groovy b/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/support/ShortIdClass.groovy
new file mode 100644
index 0000000..fca6ea0
--- /dev/null
+++ b/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/support/ShortIdClass.groovy
@@ -0,0 +1,9 @@
+package solutions.bitbadger.documents.groovy.support
+
+class ShortIdClass {
+ short id
+
+ ShortIdClass(short id) {
+ this.id = id
+ }
+}
diff --git a/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/support/StringIdClass.groovy b/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/support/StringIdClass.groovy
new file mode 100644
index 0000000..90e68e9
--- /dev/null
+++ b/src/jvm/src/test/groovy/solutions/bitbadger/documents/groovy/support/StringIdClass.groovy
@@ -0,0 +1,9 @@
+package solutions.bitbadger.documents.groovy.support
+
+class StringIdClass {
+ String id
+
+ StringIdClass(String id) {
+ this.id = id
+ }
+}
diff --git a/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/FieldMatchTest.scala b/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/FieldMatchTest.scala
new file mode 100644
index 0000000..214158f
--- /dev/null
+++ b/src/jvm/src/test/scala/solutions/bitbadger/documents/scala/FieldMatchTest.scala
@@ -0,0 +1,23 @@
+package solutions.bitbadger.documents.scala
+
+import org.scalatest.funspec.AnyFunSpec
+import solutions.bitbadger.documents.FieldMatch
+
+/**
+ * Unit tests for the `FieldMatch` enum
+ */
+class FieldMatchTest extends AnyFunSpec {
+
+ describe("sql") {
+ describe("ANY") {
+ it("should use OR") {
+ assert("OR" == FieldMatch.ANY.getSql)
+ }
+ }
+ describe("ALL") {
+ it("should use AND") {
+ assert("AND" == FieldMatch.ALL.getSql)
+ }
+ }
+ }
+}