Reorg complete, jvm tests pass
This commit is contained in:
@@ -23,7 +23,8 @@ fun <TDoc> Connection.customList(
|
||||
parameters: Collection<Parameter<*>> = listOf(),
|
||||
clazz: Class<TDoc>,
|
||||
mapFunc: (ResultSet, Class<TDoc>) -> TDoc
|
||||
) = Custom.list(query, parameters, clazz, this, mapFunc)
|
||||
) =
|
||||
solutions.bitbadger.documents.jvm.Custom.list(query, parameters, clazz, this, mapFunc)
|
||||
|
||||
/**
|
||||
* Execute a query that returns one or no results
|
||||
@@ -39,7 +40,8 @@ fun <TDoc> Connection.customSingle(
|
||||
parameters: Collection<Parameter<*>> = listOf(),
|
||||
clazz: Class<TDoc>,
|
||||
mapFunc: (ResultSet, Class<TDoc>) -> TDoc
|
||||
) = Custom.single(query, parameters, clazz, this, mapFunc)
|
||||
) =
|
||||
solutions.bitbadger.documents.jvm.Custom.single(query, parameters, clazz, this, mapFunc)
|
||||
|
||||
/**
|
||||
* Execute a query that returns no results
|
||||
@@ -48,7 +50,7 @@ fun <TDoc> Connection.customSingle(
|
||||
* @param parameters Parameters to use for the query
|
||||
*/
|
||||
fun Connection.customNonQuery(query: String, parameters: Collection<Parameter<*>> = listOf()) =
|
||||
Custom.nonQuery(query, parameters, this)
|
||||
solutions.bitbadger.documents.jvm.Custom.nonQuery(query, parameters, this)
|
||||
|
||||
/**
|
||||
* Execute a query that returns a scalar result
|
||||
@@ -64,7 +66,8 @@ fun <T : Any> Connection.customScalar(
|
||||
parameters: Collection<Parameter<*>> = listOf(),
|
||||
clazz: Class<T>,
|
||||
mapFunc: (ResultSet, Class<T>) -> T
|
||||
) = Custom.scalar(query, parameters, clazz, this, mapFunc)
|
||||
) =
|
||||
solutions.bitbadger.documents.jvm.Custom.scalar(query, parameters, clazz, this, mapFunc)
|
||||
|
||||
// ~~~ DEFINITION QUERIES ~~~
|
||||
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
package solutions.bitbadger.documents.java;
|
||||
|
||||
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.java.support.*;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Unit tests for the `AutoId` enum
|
||||
*/
|
||||
@DisplayName("Java | Common | AutoId")
|
||||
final public class AutoIdTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Generates a UUID string")
|
||||
public 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")
|
||||
public void generateRandomStringEven() {
|
||||
final String 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")
|
||||
public void generateRandomStringOdd() {
|
||||
final String result = AutoId.generateRandomString(11);
|
||||
assertEquals(11, result.length(), "There should have been 11 characters in " + result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Generates different random hex character strings")
|
||||
public void generateRandomStringIsRandom() {
|
||||
final String result1 = AutoId.generateRandomString(16);
|
||||
final String result2 = AutoId.generateRandomString(16);
|
||||
assertNotEquals(result1, result2, "There should have been 2 different strings generated");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId fails for null document")
|
||||
public void needsAutoIdFailsForNullDocument() {
|
||||
assertThrows(DocumentException.class, () -> AutoId.needsAutoId(AutoId.DISABLED, null, "id"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId fails for missing ID property")
|
||||
public void needsAutoIdFailsForMissingId() {
|
||||
assertThrows(DocumentException.class, () -> AutoId.needsAutoId(AutoId.UUID, new IntIdClass(0), "Id"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns false if disabled")
|
||||
public void needsAutoIdFalseIfDisabled() {
|
||||
try {
|
||||
assertFalse(AutoId.needsAutoId(AutoId.DISABLED, "", ""), "Disabled Auto ID should always return false");
|
||||
} catch (DocumentException ex) {
|
||||
fail(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns true for Number strategy and byte ID of 0")
|
||||
public void needsAutoIdTrueForByteWithZero() {
|
||||
try {
|
||||
assertTrue(AutoId.needsAutoId(AutoId.NUMBER, new ByteIdClass((byte) 0), "id"),
|
||||
"Number Auto ID with 0 should return true");
|
||||
} catch (DocumentException ex) {
|
||||
fail(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns false for Number strategy and byte ID of non-0")
|
||||
public void needsAutoIdFalseForByteWithNonZero() {
|
||||
try {
|
||||
assertFalse(AutoId.needsAutoId(AutoId.NUMBER, new ByteIdClass((byte) 77), "id"),
|
||||
"Number Auto ID with 77 should return false");
|
||||
} catch (DocumentException ex) {
|
||||
fail(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns true for Number strategy and short ID of 0")
|
||||
public void needsAutoIdTrueForShortWithZero() {
|
||||
try {
|
||||
assertTrue(AutoId.needsAutoId(AutoId.NUMBER, new ShortIdClass((short) 0), "id"),
|
||||
"Number Auto ID with 0 should return true");
|
||||
} catch (DocumentException ex) {
|
||||
fail(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns false for Number strategy and short ID of non-0")
|
||||
public void needsAutoIdFalseForShortWithNonZero() {
|
||||
try {
|
||||
assertFalse(AutoId.needsAutoId(AutoId.NUMBER, new ShortIdClass((short) 31), "id"),
|
||||
"Number Auto ID with 31 should return false");
|
||||
} catch (DocumentException ex) {
|
||||
fail(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns true for Number strategy and int ID of 0")
|
||||
public void needsAutoIdTrueForIntWithZero() {
|
||||
try {
|
||||
assertTrue(AutoId.needsAutoId(AutoId.NUMBER, new IntIdClass(0), "id"),
|
||||
"Number Auto ID with 0 should return true");
|
||||
} catch (DocumentException ex) {
|
||||
fail(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns false for Number strategy and int ID of non-0")
|
||||
public void needsAutoIdFalseForIntWithNonZero() {
|
||||
try {
|
||||
assertFalse(AutoId.needsAutoId(AutoId.NUMBER, new IntIdClass(6), "id"),
|
||||
"Number Auto ID with 6 should return false");
|
||||
} catch (DocumentException ex) {
|
||||
fail(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns true for Number strategy and long ID of 0")
|
||||
public void needsAutoIdTrueForLongWithZero() {
|
||||
try {
|
||||
assertTrue(AutoId.needsAutoId(AutoId.NUMBER, new LongIdClass(0L), "id"),
|
||||
"Number Auto ID with 0 should return true");
|
||||
} catch (DocumentException ex) {
|
||||
fail(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns false for Number strategy and long ID of non-0")
|
||||
public void needsAutoIdFalseForLongWithNonZero() {
|
||||
try {
|
||||
assertFalse(AutoId.needsAutoId(AutoId.NUMBER, new LongIdClass(2L), "id"),
|
||||
"Number Auto ID with 2 should return false");
|
||||
} catch (DocumentException ex) {
|
||||
fail(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId fails for Number strategy and non-number ID")
|
||||
public void needsAutoIdFailsForNumberWithStringId() {
|
||||
assertThrows(DocumentException.class, () -> AutoId.needsAutoId(AutoId.NUMBER, new StringIdClass(""), "id"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns true for UUID strategy and blank ID")
|
||||
public void needsAutoIdTrueForUUIDWithBlank() {
|
||||
try {
|
||||
assertTrue(AutoId.needsAutoId(AutoId.UUID, new StringIdClass(""), "id"),
|
||||
"UUID Auto ID with blank should return true");
|
||||
} catch (DocumentException ex) {
|
||||
fail(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns false for UUID strategy and non-blank ID")
|
||||
public void needsAutoIdFalseForUUIDNotBlank() {
|
||||
try {
|
||||
assertFalse(AutoId.needsAutoId(AutoId.UUID, new StringIdClass("howdy"), "id"),
|
||||
"UUID Auto ID with non-blank should return false");
|
||||
} catch (DocumentException ex) {
|
||||
fail(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId fails for UUID strategy and non-string ID")
|
||||
public 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")
|
||||
public void needsAutoIdTrueForRandomWithBlank() {
|
||||
try {
|
||||
assertTrue(AutoId.needsAutoId(AutoId.RANDOM_STRING, new StringIdClass(""), "id"),
|
||||
"Random String Auto ID with blank should return true");
|
||||
} catch (DocumentException ex) {
|
||||
fail(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns false for Random String strategy and non-blank ID")
|
||||
public void needsAutoIdFalseForRandomNotBlank() {
|
||||
try {
|
||||
assertFalse(AutoId.needsAutoId(AutoId.RANDOM_STRING, new StringIdClass("full"), "id"),
|
||||
"Random String Auto ID with non-blank should return false");
|
||||
} catch (DocumentException ex) {
|
||||
fail(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId fails for Random String strategy and non-string ID")
|
||||
public void needsAutoIdFailsForRandomNonString() {
|
||||
assertThrows(DocumentException.class,
|
||||
() -> AutoId.needsAutoId(AutoId.RANDOM_STRING, new ShortIdClass((short) 55), "id"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package solutions.bitbadger.documents.java;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import solutions.bitbadger.documents.DocumentIndex;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* Unit tests for the `DocumentIndex` enum
|
||||
*/
|
||||
@DisplayName("Java | Common | DocumentIndex")
|
||||
final public class DocumentIndexTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("FULL uses proper SQL")
|
||||
public void fullSQL() {
|
||||
assertEquals("", DocumentIndex.FULL.getSql(), "The SQL for Full is incorrect");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("OPTIMIZED uses proper SQL")
|
||||
public void optimizedSQL() {
|
||||
assertEquals(" jsonb_path_ops", DocumentIndex.OPTIMIZED.getSql(), "The SQL for Optimized is incorrect");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package solutions.bitbadger.documents.java;
|
||||
|
||||
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("Java | Common | FieldMatch")
|
||||
final public class FieldMatchTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("ANY uses proper SQL")
|
||||
public void any() {
|
||||
assertEquals("OR", FieldMatch.ANY.getSql(), "ANY should use OR");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("ALL uses proper SQL")
|
||||
public void all() {
|
||||
assertEquals("AND", FieldMatch.ALL.getSql(), "ALL should use AND");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,629 @@
|
||||
package solutions.bitbadger.documents.java;
|
||||
|
||||
import kotlin.Pair;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import solutions.bitbadger.documents.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Unit tests for the `Field` class
|
||||
*/
|
||||
@DisplayName("Java | Common | Field")
|
||||
final public class FieldTest {
|
||||
|
||||
/**
|
||||
* Clear the connection string (resets Dialect)
|
||||
*/
|
||||
@AfterEach
|
||||
public void cleanUp() {
|
||||
Configuration.setConnectionString(null);
|
||||
}
|
||||
|
||||
// ~~~ INSTANCE METHODS ~~~
|
||||
|
||||
@Test
|
||||
@DisplayName("withParameterName fails for invalid name")
|
||||
public void withParamNameFails() {
|
||||
assertThrows(DocumentException.class, () -> Field.equal("it", "").withParameterName("2424"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("withParameterName works with colon prefix")
|
||||
public void withParamNameColon() {
|
||||
Field<String> field = Field.equal("abc", "22").withQualifier("me");
|
||||
Field<String> withParam = field.withParameterName(":test");
|
||||
assertNotSame(field, withParam, "A new Field instance should have been created");
|
||||
assertEquals(field.getName(), withParam.getName(), "Name should have been preserved");
|
||||
assertEquals(field.getComparison(), withParam.getComparison(), "Comparison should have been preserved");
|
||||
assertEquals(":test", withParam.getParameterName(), "Parameter name not set correctly");
|
||||
assertEquals(field.getQualifier(), withParam.getQualifier(), "Qualifier should have been preserved");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("withParameterName works with at-sign prefix")
|
||||
public void withParamNameAtSign() {
|
||||
Field<String> field = Field.equal("def", "44");
|
||||
Field<String> withParam = field.withParameterName("@unit");
|
||||
assertNotSame(field, withParam, "A new Field instance should have been created");
|
||||
assertEquals(field.getName(), withParam.getName(), "Name should have been preserved");
|
||||
assertEquals(field.getComparison(), withParam.getComparison(), "Comparison should have been preserved");
|
||||
assertEquals("@unit", withParam.getParameterName(), "Parameter name not set correctly");
|
||||
assertEquals(field.getQualifier(), withParam.getQualifier(), "Qualifier should have been preserved");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("withQualifier sets qualifier correctly")
|
||||
public void withQualifier() {
|
||||
Field<String> field = Field.equal("j", "k");
|
||||
Field<String> withQual = field.withQualifier("test");
|
||||
assertNotSame(field, withQual, "A new Field instance should have been created");
|
||||
assertEquals(field.getName(), withQual.getName(), "Name should have been preserved");
|
||||
assertEquals(field.getComparison(), withQual.getComparison(), "Comparison should have been preserved");
|
||||
assertEquals(field.getParameterName(), withQual.getParameterName(),
|
||||
"Parameter Name should have been preserved");
|
||||
assertEquals("test", withQual.getQualifier(), "Qualifier not set correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for simple unqualified PostgreSQL field")
|
||||
public void pathPostgresSimpleUnqualified() {
|
||||
assertEquals("data->>'SomethingCool'",
|
||||
Field.greaterOrEqual("SomethingCool", 18).path(Dialect.POSTGRESQL, FieldFormat.SQL),
|
||||
"Path not correct");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for simple qualified PostgreSQL field")
|
||||
public void pathPostgresSimpleQualified() {
|
||||
assertEquals("this.data->>'SomethingElse'",
|
||||
Field.less("SomethingElse", 9).withQualifier("this").path(Dialect.POSTGRESQL, FieldFormat.SQL),
|
||||
"Path not correct");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for nested unqualified PostgreSQL field")
|
||||
public void pathPostgresNestedUnqualified() {
|
||||
assertEquals("data#>>'{My,Nested,Field}'",
|
||||
Field.equal("My.Nested.Field", "howdy").path(Dialect.POSTGRESQL, FieldFormat.SQL), "Path not correct");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for nested qualified PostgreSQL field")
|
||||
public void pathPostgresNestedQualified() {
|
||||
assertEquals("bird.data#>>'{Nest,Away}'",
|
||||
Field.equal("Nest.Away", "doc").withQualifier("bird").path(Dialect.POSTGRESQL, FieldFormat.SQL),
|
||||
"Path not correct");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for simple unqualified SQLite field")
|
||||
public void pathSQLiteSimpleUnqualified() {
|
||||
assertEquals("data->>'SomethingCool'",
|
||||
Field.greaterOrEqual("SomethingCool", 18).path(Dialect.SQLITE, FieldFormat.SQL), "Path not correct");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for simple qualified SQLite field")
|
||||
public void pathSQLiteSimpleQualified() {
|
||||
assertEquals("this.data->>'SomethingElse'",
|
||||
Field.less("SomethingElse", 9).withQualifier("this").path(Dialect.SQLITE, FieldFormat.SQL),
|
||||
"Path not correct");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for nested unqualified SQLite field")
|
||||
public void pathSQLiteNestedUnqualified() {
|
||||
assertEquals("data->'My'->'Nested'->>'Field'",
|
||||
Field.equal("My.Nested.Field", "howdy").path(Dialect.SQLITE, FieldFormat.SQL), "Path not correct");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for nested qualified SQLite field")
|
||||
public void pathSQLiteNestedQualified() {
|
||||
assertEquals("bird.data->'Nest'->>'Away'",
|
||||
Field.equal("Nest.Away", "doc").withQualifier("bird").path(Dialect.SQLITE, FieldFormat.SQL),
|
||||
"Path not correct");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for exists w/o qualifier (PostgreSQL)")
|
||||
public void toWhereExistsNoQualPostgres() {
|
||||
Configuration.setConnectionString(":postgresql:");
|
||||
assertEquals("data->>'that_field' IS NOT NULL", Field.exists("that_field").toWhere(),
|
||||
"Field WHERE clause not generated correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for exists w/o qualifier (SQLite)")
|
||||
public void toWhereExistsNoQualSQLite() {
|
||||
Configuration.setConnectionString(":sqlite:");
|
||||
assertEquals("data->>'that_field' IS NOT NULL", Field.exists("that_field").toWhere(),
|
||||
"Field WHERE clause not generated correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for not-exists w/o qualifier (PostgreSQL)")
|
||||
public void toWhereNotExistsNoQualPostgres() {
|
||||
Configuration.setConnectionString(":postgresql:");
|
||||
assertEquals("data->>'a_field' IS NULL", Field.notExists("a_field").toWhere(),
|
||||
"Field WHERE clause not generated correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for not-exists w/o qualifier (SQLite)")
|
||||
public void toWhereNotExistsNoQualSQLite() {
|
||||
Configuration.setConnectionString(":sqlite:");
|
||||
assertEquals("data->>'a_field' IS NULL", Field.notExists("a_field").toWhere(),
|
||||
"Field WHERE clause not generated correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for BETWEEN w/o qualifier, numeric range (PostgreSQL)")
|
||||
public void toWhereBetweenNoQualNumericPostgres() {
|
||||
Configuration.setConnectionString(":postgresql:");
|
||||
assertEquals("(data->>'age')::numeric BETWEEN @agemin AND @agemax",
|
||||
Field.between("age", 13, 17, "@age").toWhere(), "Field WHERE clause not generated correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for BETWEEN w/o qualifier, alphanumeric range (PostgreSQL)")
|
||||
public void toWhereBetweenNoQualAlphaPostgres() {
|
||||
Configuration.setConnectionString(":postgresql:");
|
||||
assertEquals("data->>'city' BETWEEN :citymin AND :citymax",
|
||||
Field.between("city", "Atlanta", "Chicago", ":city").toWhere(),
|
||||
"Field WHERE clause not generated correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for BETWEEN w/o qualifier (SQLite)")
|
||||
public void toWhereBetweenNoQualSQLite() {
|
||||
Configuration.setConnectionString(":sqlite:");
|
||||
assertEquals("data->>'age' BETWEEN @agemin AND @agemax", Field.between("age", 13, 17, "@age").toWhere(),
|
||||
"Field WHERE clause not generated correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for BETWEEN w/ qualifier, numeric range (PostgreSQL)")
|
||||
public void toWhereBetweenQualNumericPostgres() {
|
||||
Configuration.setConnectionString(":postgresql:");
|
||||
assertEquals("(test.data->>'age')::numeric BETWEEN @agemin AND @agemax",
|
||||
Field.between("age", 13, 17, "@age").withQualifier("test").toWhere(),
|
||||
"Field WHERE clause not generated correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for BETWEEN w/ qualifier, alphanumeric range (PostgreSQL)")
|
||||
public void toWhereBetweenQualAlphaPostgres() {
|
||||
Configuration.setConnectionString(":postgresql:");
|
||||
assertEquals("unit.data->>'city' BETWEEN :citymin AND :citymax",
|
||||
Field.between("city", "Atlanta", "Chicago", ":city").withQualifier("unit").toWhere(),
|
||||
"Field WHERE clause not generated correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for BETWEEN w/ qualifier (SQLite)")
|
||||
public void toWhereBetweenQualSQLite() {
|
||||
Configuration.setConnectionString(":sqlite:");
|
||||
assertEquals("my.data->>'age' BETWEEN @agemin AND @agemax",
|
||||
Field.between("age", 13, 17, "@age").withQualifier("my").toWhere(),
|
||||
"Field WHERE clause not generated correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for IN/any, numeric values (PostgreSQL)")
|
||||
public void toWhereAnyNumericPostgres() {
|
||||
Configuration.setConnectionString(":postgresql:");
|
||||
assertEquals("(data->>'even')::numeric IN (:nbr_0, :nbr_1, :nbr_2)",
|
||||
Field.any("even", List.of(2, 4, 6), ":nbr").toWhere(),
|
||||
"Field WHERE clause not generated correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for IN/any, alphanumeric values (PostgreSQL)")
|
||||
public void toWhereAnyAlphaPostgres() {
|
||||
Configuration.setConnectionString(":postgresql:");
|
||||
assertEquals("data->>'test' IN (:city_0, :city_1)",
|
||||
Field.any("test", List.of("Atlanta", "Chicago"), ":city").toWhere(),
|
||||
"Field WHERE clause not generated correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for IN/any (SQLite)")
|
||||
public void toWhereAnySQLite() {
|
||||
Configuration.setConnectionString(":sqlite:");
|
||||
assertEquals("data->>'test' IN (:city_0, :city_1)",
|
||||
Field.any("test", List.of("Atlanta", "Chicago"), ":city").toWhere(),
|
||||
"Field WHERE clause not generated correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for inArray (PostgreSQL)")
|
||||
public void toWhereInArrayPostgres() {
|
||||
Configuration.setConnectionString(":postgresql:");
|
||||
assertEquals("data->'even' ??| ARRAY[:it_0, :it_1, :it_2, :it_3]",
|
||||
Field.inArray("even", "tbl", List.of(2, 4, 6, 8), ":it").toWhere(),
|
||||
"Field WHERE clause not generated correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for inArray (SQLite)")
|
||||
public void toWhereInArraySQLite() {
|
||||
Configuration.setConnectionString(":sqlite:");
|
||||
assertEquals("EXISTS (SELECT 1 FROM json_each(tbl.data, '$.test') WHERE value IN (:city_0, :city_1))",
|
||||
Field.inArray("test", "tbl", List.of("Atlanta", "Chicago"), ":city").toWhere(),
|
||||
"Field WHERE clause not generated correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for others w/o qualifier (PostgreSQL)")
|
||||
public void toWhereOtherNoQualPostgres() {
|
||||
Configuration.setConnectionString(":postgresql:");
|
||||
assertEquals("data->>'some_field' = :value", Field.equal("some_field", "", ":value").toWhere(),
|
||||
"Field WHERE clause not generated correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for others w/o qualifier (SQLite)")
|
||||
public void toWhereOtherNoQualSQLite() {
|
||||
Configuration.setConnectionString(":sqlite:");
|
||||
assertEquals("data->>'some_field' = :value", Field.equal("some_field", "", ":value").toWhere(),
|
||||
"Field WHERE clause not generated correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates no-parameter w/ qualifier (PostgreSQL)")
|
||||
public void toWhereNoParamWithQualPostgres() {
|
||||
Configuration.setConnectionString(":postgresql:");
|
||||
assertEquals("test.data->>'no_field' IS NOT NULL", Field.exists("no_field").withQualifier("test").toWhere(),
|
||||
"Field WHERE clause not generated correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates no-parameter w/ qualifier (SQLite)")
|
||||
public void toWhereNoParamWithQualSQLite() {
|
||||
Configuration.setConnectionString(":sqlite:");
|
||||
assertEquals("test.data->>'no_field' IS NOT NULL", Field.exists("no_field").withQualifier("test").toWhere(),
|
||||
"Field WHERE clause not generated correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates parameter w/ qualifier (PostgreSQL)")
|
||||
public void toWhereParamWithQualPostgres() {
|
||||
Configuration.setConnectionString(":postgresql:");
|
||||
assertEquals("(q.data->>'le_field')::numeric <= :it",
|
||||
Field.lessOrEqual("le_field", 18, ":it").withQualifier("q").toWhere(),
|
||||
"Field WHERE clause not generated correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates parameter w/ qualifier (SQLite)")
|
||||
public void toWhereParamWithQualSQLite() {
|
||||
Configuration.setConnectionString(":sqlite:");
|
||||
assertEquals("q.data->>'le_field' <= :it",
|
||||
Field.lessOrEqual("le_field", 18, ":it").withQualifier("q").toWhere(),
|
||||
"Field WHERE clause not generated correctly");
|
||||
}
|
||||
|
||||
// ~~~ STATIC TESTS ~~~
|
||||
|
||||
@Test
|
||||
@DisplayName("equal constructs a field w/o parameter name")
|
||||
public void equalCtor() {
|
||||
Field<Integer> field = Field.equal("Test", 14);
|
||||
assertEquals("Test", field.getName(), "Field name not filled correctly");
|
||||
assertEquals(Op.EQUAL, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||
assertEquals(14, field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||
assertNull(field.getParameterName(), "The parameter name should have been null");
|
||||
assertNull(field.getQualifier(), "The qualifier should have been null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("equal constructs a field w/ parameter name")
|
||||
public void equalParameterCtor() {
|
||||
Field<Integer> field = Field.equal("Test", 14, ":w");
|
||||
assertEquals("Test", field.getName(), "Field name not filled correctly");
|
||||
assertEquals(Op.EQUAL, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||
assertEquals(14, field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||
assertEquals(":w", field.getParameterName(), "Field parameter name not filled correctly");
|
||||
assertNull(field.getQualifier(), "The qualifier should have been null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("greater constructs a field w/o parameter name")
|
||||
public void greaterCtor() {
|
||||
Field<String> field = Field.greater("Great", "night");
|
||||
assertEquals("Great", field.getName(), "Field name not filled correctly");
|
||||
assertEquals(Op.GREATER, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||
assertEquals("night", field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||
assertNull(field.getParameterName(), "The parameter name should have been null");
|
||||
assertNull(field.getQualifier(), "The qualifier should have been null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("greater constructs a field w/ parameter name")
|
||||
public void greaterParameterCtor() {
|
||||
Field<String> field = Field.greater("Great", "night", ":yeah");
|
||||
assertEquals("Great", field.getName(), "Field name not filled correctly");
|
||||
assertEquals(Op.GREATER, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||
assertEquals("night", field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||
assertEquals(":yeah", field.getParameterName(), "Field parameter name not filled correctly");
|
||||
assertNull(field.getQualifier(), "The qualifier should have been null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("greaterOrEqual constructs a field w/o parameter name")
|
||||
public void greaterOrEqualCtor() {
|
||||
Field<Long> field = Field.greaterOrEqual("Nice", 88L);
|
||||
assertEquals("Nice", field.getName(), "Field name not filled correctly");
|
||||
assertEquals(Op.GREATER_OR_EQUAL, field.getComparison().getOp(),
|
||||
"Field comparison operation not filled correctly");
|
||||
assertEquals(88L, field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||
assertNull(field.getParameterName(), "The parameter name should have been null");
|
||||
assertNull(field.getQualifier(), "The qualifier should have been null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("greaterOrEqual constructs a field w/ parameter name")
|
||||
public void greaterOrEqualParameterCtor() {
|
||||
Field<Long> field = Field.greaterOrEqual("Nice", 88L, ":nice");
|
||||
assertEquals("Nice", field.getName(), "Field name not filled correctly");
|
||||
assertEquals(Op.GREATER_OR_EQUAL, field.getComparison().getOp(),
|
||||
"Field comparison operation not filled correctly");
|
||||
assertEquals(88L, field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||
assertEquals(":nice", field.getParameterName(), "Field parameter name not filled correctly");
|
||||
assertNull(field.getQualifier(), "The qualifier should have been null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("less constructs a field w/o parameter name")
|
||||
public void lessCtor() {
|
||||
Field<String> field = Field.less("Lesser", "seven");
|
||||
assertEquals("Lesser", field.getName(), "Field name not filled correctly");
|
||||
assertEquals(Op.LESS, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||
assertEquals("seven", field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||
assertNull(field.getParameterName(), "The parameter name should have been null");
|
||||
assertNull(field.getQualifier(), "The qualifier should have been null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("less constructs a field w/ parameter name")
|
||||
public void lessParameterCtor() {
|
||||
Field<String> field = Field.less("Lesser", "seven", ":max");
|
||||
assertEquals("Lesser", field.getName(), "Field name not filled correctly");
|
||||
assertEquals(Op.LESS, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||
assertEquals("seven", field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||
assertEquals(":max", field.getParameterName(), "Field parameter name not filled correctly");
|
||||
assertNull(field.getQualifier(), "The qualifier should have been null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("lessOrEqual constructs a field w/o parameter name")
|
||||
public void lessOrEqualCtor() {
|
||||
Field<String> field = Field.lessOrEqual("Nobody", "KNOWS");
|
||||
assertEquals("Nobody", field.getName(), "Field name not filled correctly");
|
||||
assertEquals(Op.LESS_OR_EQUAL, field.getComparison().getOp(),
|
||||
"Field comparison operation not filled correctly");
|
||||
assertEquals("KNOWS", field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||
assertNull(field.getParameterName(), "The parameter name should have been null");
|
||||
assertNull(field.getQualifier(), "The qualifier should have been null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("lessOrEqual constructs a field w/ parameter name")
|
||||
public void lessOrEqualParameterCtor() {
|
||||
Field<String> field = Field.lessOrEqual("Nobody", "KNOWS", ":nope");
|
||||
assertEquals("Nobody", field.getName(), "Field name not filled correctly");
|
||||
assertEquals(Op.LESS_OR_EQUAL, field.getComparison().getOp(),
|
||||
"Field comparison operation not filled correctly");
|
||||
assertEquals("KNOWS", field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||
assertEquals(":nope", field.getParameterName(), "Field parameter name not filled correctly");
|
||||
assertNull(field.getQualifier(), "The qualifier should have been null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("notEqual constructs a field w/o parameter name")
|
||||
public void notEqualCtor() {
|
||||
Field<String> field = Field.notEqual("Park", "here");
|
||||
assertEquals("Park", field.getName(), "Field name not filled correctly");
|
||||
assertEquals(Op.NOT_EQUAL, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||
assertEquals("here", field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||
assertNull(field.getParameterName(), "The parameter name should have been null");
|
||||
assertNull(field.getQualifier(), "The qualifier should have been null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("notEqual constructs a field w/ parameter name")
|
||||
public void notEqualParameterCtor() {
|
||||
Field<String> field = Field.notEqual("Park", "here", ":now");
|
||||
assertEquals("Park", field.getName(), "Field name not filled correctly");
|
||||
assertEquals(Op.NOT_EQUAL, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||
assertEquals("here", field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||
assertEquals(":now", field.getParameterName(), "Field parameter name not filled correctly");
|
||||
assertNull(field.getQualifier(), "The qualifier should have been null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("between constructs a field w/o parameter name")
|
||||
public void betweenCtor() {
|
||||
Field<Pair<Integer, Integer>> field = Field.between("Age", 18, 49);
|
||||
assertEquals("Age", field.getName(), "Field name not filled correctly");
|
||||
assertEquals(Op.BETWEEN, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||
assertEquals(18, field.getComparison().getValue().getFirst(),
|
||||
"Field comparison min value not filled correctly");
|
||||
assertEquals(49, field.getComparison().getValue().getSecond(),
|
||||
"Field comparison max value not filled correctly");
|
||||
assertNull(field.getParameterName(), "The parameter name should have been null");
|
||||
assertNull(field.getQualifier(), "The qualifier should have been null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("between constructs a field w/ parameter name")
|
||||
public void betweenParameterCtor() {
|
||||
Field<Pair<Integer, Integer>> field = Field.between("Age", 18, 49, ":limit");
|
||||
assertEquals("Age", field.getName(), "Field name not filled correctly");
|
||||
assertEquals(Op.BETWEEN, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||
assertEquals(18, field.getComparison().getValue().getFirst(),
|
||||
"Field comparison min value not filled correctly");
|
||||
assertEquals(49, field.getComparison().getValue().getSecond(),
|
||||
"Field comparison max value not filled correctly");
|
||||
assertEquals(":limit", field.getParameterName(), "The parameter name should have been null");
|
||||
assertNull(field.getQualifier(), "The qualifier should have been null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("any constructs a field w/o parameter name")
|
||||
public void anyCtor() {
|
||||
Field<Collection<Integer>> field = Field.any("Here", List.of(8, 16, 32));
|
||||
assertEquals("Here", field.getName(), "Field name not filled correctly");
|
||||
assertEquals(Op.IN, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||
assertEquals(List.of(8, 16, 32), field.getComparison().getValue(),
|
||||
"Field comparison value not filled correctly");
|
||||
assertNull(field.getParameterName(), "The parameter name should have been null");
|
||||
assertNull(field.getQualifier(), "The qualifier should have been null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("any constructs a field w/ parameter name")
|
||||
public void anyParameterCtor() {
|
||||
Field<Collection<Integer>> field = Field.any("Here", List.of(8, 16, 32), ":list");
|
||||
assertEquals("Here", field.getName(), "Field name not filled correctly");
|
||||
assertEquals(Op.IN, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||
assertEquals(List.of(8, 16, 32), field.getComparison().getValue(),
|
||||
"Field comparison value not filled correctly");
|
||||
assertEquals(":list", field.getParameterName(), "Field parameter name not filled correctly");
|
||||
assertNull(field.getQualifier(), "The qualifier should have been null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("inArray constructs a field w/o parameter name")
|
||||
public void inArrayCtor() {
|
||||
Field<Pair<String, Collection<String>>> field = Field.inArray("ArrayField", "table", List.of("z"));
|
||||
assertEquals("ArrayField", field.getName(), "Field name not filled correctly");
|
||||
assertEquals(Op.IN_ARRAY, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||
assertEquals("table", field.getComparison().getValue().getFirst(),
|
||||
"Field comparison table not filled correctly");
|
||||
assertEquals(List.of("z"), field.getComparison().getValue().getSecond(),
|
||||
"Field comparison values not filled correctly");
|
||||
assertNull(field.getParameterName(), "The parameter name should have been null");
|
||||
assertNull(field.getQualifier(), "The qualifier should have been null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("inArray constructs a field w/ parameter name")
|
||||
public void inArrayParameterCtor() {
|
||||
Field<Pair<String, Collection<String>>> field = Field.inArray("ArrayField", "table", List.of("z"), ":a");
|
||||
assertEquals("ArrayField", field.getName(), "Field name not filled correctly");
|
||||
assertEquals(Op.IN_ARRAY, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||
assertEquals("table", field.getComparison().getValue().getFirst(),
|
||||
"Field comparison table not filled correctly");
|
||||
assertEquals(List.of("z"), field.getComparison().getValue().getSecond(),
|
||||
"Field comparison values not filled correctly");
|
||||
assertEquals(":a", field.getParameterName(), "Field parameter name not filled correctly");
|
||||
assertNull(field.getQualifier(), "The qualifier should have been null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("exists constructs a field")
|
||||
public void existsCtor() {
|
||||
Field<String> field = Field.exists("Groovy");
|
||||
assertEquals("Groovy", field.getName(), "Field name not filled correctly");
|
||||
assertEquals(Op.EXISTS, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||
assertEquals("", field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||
assertNull(field.getParameterName(), "The parameter name should have been null");
|
||||
assertNull(field.getQualifier(), "The qualifier should have been null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("notExists constructs a field")
|
||||
public void notExistsCtor() {
|
||||
Field<String> field = Field.notExists("Groovy");
|
||||
assertEquals("Groovy", field.getName(), "Field name not filled correctly");
|
||||
assertEquals(Op.NOT_EXISTS, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||
assertEquals("", field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||
assertNull(field.getParameterName(), "The parameter name should have been null");
|
||||
assertNull(field.getQualifier(), "The qualifier should have been null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("named constructs a field")
|
||||
public void namedCtor() {
|
||||
Field<String> field = Field.named("Tacos");
|
||||
assertEquals("Tacos", field.getName(), "Field name not filled correctly");
|
||||
assertEquals(Op.EQUAL, field.getComparison().getOp(), "Field comparison operation not filled correctly");
|
||||
assertEquals("", field.getComparison().getValue(), "Field comparison value not filled correctly");
|
||||
assertNull(field.getParameterName(), "The parameter name should have been null");
|
||||
assertNull(field.getQualifier(), "The qualifier should have been null");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("static constructors fail for invalid parameter name")
|
||||
public void staticCtorsFailOnParamName() {
|
||||
assertThrows(DocumentException.class, () -> Field.equal("a", "b", "that ain't it, Jack..."));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a simple PostgreSQL SQL name")
|
||||
public void nameToPathPostgresSimpleSQL() {
|
||||
assertEquals("data->>'Simple'", Field.nameToPath("Simple", Dialect.POSTGRESQL, FieldFormat.SQL),
|
||||
"Path not constructed correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a simple SQLite SQL name")
|
||||
public void nameToPathSQLiteSimpleSQL() {
|
||||
assertEquals("data->>'Simple'", Field.nameToPath("Simple", Dialect.SQLITE, FieldFormat.SQL),
|
||||
"Path not constructed correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a nested PostgreSQL SQL name")
|
||||
public void nameToPathPostgresNestedSQL() {
|
||||
assertEquals("data#>>'{A,Long,Path,to,the,Property}'",
|
||||
Field.nameToPath("A.Long.Path.to.the.Property", Dialect.POSTGRESQL, FieldFormat.SQL),
|
||||
"Path not constructed correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a nested SQLite SQL name")
|
||||
public void nameToPathSQLiteNestedSQL() {
|
||||
assertEquals("data->'A'->'Long'->'Path'->'to'->'the'->>'Property'",
|
||||
Field.nameToPath("A.Long.Path.to.the.Property", Dialect.SQLITE, FieldFormat.SQL),
|
||||
"Path not constructed correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a simple PostgreSQL JSON name")
|
||||
public void nameToPathPostgresSimpleJSON() {
|
||||
assertEquals("data->'Simple'", Field.nameToPath("Simple", Dialect.POSTGRESQL, FieldFormat.JSON),
|
||||
"Path not constructed correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a simple SQLite JSON name")
|
||||
public void nameToPathSQLiteSimpleJSON() {
|
||||
assertEquals("data->'Simple'", Field.nameToPath("Simple", Dialect.SQLITE, FieldFormat.JSON),
|
||||
"Path not constructed correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a nested PostgreSQL JSON name")
|
||||
public void nameToPathPostgresNestedJSON() {
|
||||
assertEquals("data#>'{A,Long,Path,to,the,Property}'",
|
||||
Field.nameToPath("A.Long.Path.to.the.Property", Dialect.POSTGRESQL, FieldFormat.JSON),
|
||||
"Path not constructed correctly");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a nested SQLite JSON name")
|
||||
public void nameToPathSQLiteNestedJSON() {
|
||||
assertEquals("data->'A'->'Long'->'Path'->'to'->'the'->'Property'",
|
||||
Field.nameToPath("A.Long.Path.to.the.Property", Dialect.SQLITE, FieldFormat.JSON),
|
||||
"Path not constructed correctly");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package solutions.bitbadger.documents.java;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import solutions.bitbadger.documents.Op;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* Unit tests for the `Op` enum
|
||||
*/
|
||||
@DisplayName("Java | Common | Op")
|
||||
final public class OpTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("EQUAL uses proper SQL")
|
||||
public void equalSQL() {
|
||||
assertEquals("=", Op.EQUAL.getSql(), "The SQL for equal is incorrect");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("GREATER uses proper SQL")
|
||||
public void greaterSQL() {
|
||||
assertEquals(">", Op.GREATER.getSql(), "The SQL for greater is incorrect");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("GREATER_OR_EQUAL uses proper SQL")
|
||||
public void greaterOrEqualSQL() {
|
||||
assertEquals(">=", Op.GREATER_OR_EQUAL.getSql(), "The SQL for greater-or-equal is incorrect");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("LESS uses proper SQL")
|
||||
public void lessSQL() {
|
||||
assertEquals("<", Op.LESS.getSql(), "The SQL for less is incorrect");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("LESS_OR_EQUAL uses proper SQL")
|
||||
public void lessOrEqualSQL() {
|
||||
assertEquals("<=", Op.LESS_OR_EQUAL.getSql(), "The SQL for less-or-equal is incorrect");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("NOT_EQUAL uses proper SQL")
|
||||
public void notEqualSQL() {
|
||||
assertEquals("<>", Op.NOT_EQUAL.getSql(), "The SQL for not-equal is incorrect");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("BETWEEN uses proper SQL")
|
||||
public void betweenSQL() {
|
||||
assertEquals("BETWEEN", Op.BETWEEN.getSql(), "The SQL for between is incorrect");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("IN uses proper SQL")
|
||||
public void inSQL() {
|
||||
assertEquals("IN", Op.IN.getSql(), "The SQL for in is incorrect");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("IN_ARRAY uses proper SQL")
|
||||
public void inArraySQL() {
|
||||
assertEquals("??|", Op.IN_ARRAY.getSql(), "The SQL for in-array is incorrect");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("EXISTS uses proper SQL")
|
||||
public void existsSQL() {
|
||||
assertEquals("IS NOT NULL", Op.EXISTS.getSql(), "The SQL for exists is incorrect");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("NOT_EXISTS uses proper SQL")
|
||||
public void notExistsSQL() {
|
||||
assertEquals("IS NULL", Op.NOT_EXISTS.getSql(), "The SQL for not-exists is incorrect");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package solutions.bitbadger.documents.java;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import solutions.bitbadger.documents.ParameterName;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* Unit tests for the `ParameterName` class
|
||||
*/
|
||||
@DisplayName("Java | Common | ParameterName")
|
||||
final public class ParameterNameTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("derive works when given existing names")
|
||||
public void withExisting() {
|
||||
ParameterName names = new ParameterName();
|
||||
assertEquals(":taco", names.derive(":taco"), "Name should have been :taco");
|
||||
assertEquals(":field0", names.derive(null), "Counter should not have advanced for named field");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("derive works when given all anonymous fields")
|
||||
public void allAnonymous() {
|
||||
ParameterName names = new ParameterName();
|
||||
assertEquals(":field0", names.derive(null), "Anonymous field name should have been returned");
|
||||
assertEquals(":field1", names.derive(null), "Counter should have advanced from previous call");
|
||||
assertEquals(":field2", names.derive(null), "Counter should have advanced from previous call");
|
||||
assertEquals(":field3", names.derive(null), "Counter should have advanced from previous call");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package solutions.bitbadger.documents.java;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import solutions.bitbadger.documents.DocumentException;
|
||||
import solutions.bitbadger.documents.Parameter;
|
||||
import solutions.bitbadger.documents.ParameterType;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Unit tests for the `Parameter` class
|
||||
*/
|
||||
@DisplayName("Java | Common | Parameter")
|
||||
final public class ParameterTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Construction with colon-prefixed name")
|
||||
public void ctorWithColon() {
|
||||
Parameter<String> p = new Parameter<>(":test", ParameterType.STRING, "ABC");
|
||||
assertEquals(":test", p.getName(), "Parameter name was incorrect");
|
||||
assertEquals(ParameterType.STRING, p.getType(), "Parameter type was incorrect");
|
||||
assertEquals("ABC", p.getValue(), "Parameter value was incorrect");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Construction with at-sign-prefixed name")
|
||||
public void ctorWithAtSign() {
|
||||
Parameter<String> p = new Parameter<>("@yo", ParameterType.NUMBER, null);
|
||||
assertEquals("@yo", p.getName(), "Parameter name was incorrect");
|
||||
assertEquals(ParameterType.NUMBER, p.getType(), "Parameter type was incorrect");
|
||||
assertNull(p.getValue(), "Parameter value was incorrect");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Construction fails with incorrect prefix")
|
||||
public void ctorFailsForPrefix() {
|
||||
assertThrows(DocumentException.class, () -> new Parameter<>("it", ParameterType.JSON, ""));
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
package solutions.bitbadger.documents.java.java;
|
||||
package solutions.bitbadger.documents.java.jvm;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import solutions.bitbadger.documents.*;
|
||||
import solutions.bitbadger.documents.java.jvm.Parameters;
|
||||
import solutions.bitbadger.documents.jvm.Parameters;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package solutions.bitbadger.documents.java.java.integration.common;
|
||||
package solutions.bitbadger.documents.java.jvm.integration.common;
|
||||
|
||||
import solutions.bitbadger.documents.Field;
|
||||
import solutions.bitbadger.documents.java.jvm.Count;
|
||||
import solutions.bitbadger.documents.java.integration.ThrowawayDatabase;
|
||||
import solutions.bitbadger.documents.java.java.testDocs.JsonDocument;
|
||||
import solutions.bitbadger.documents.jvm.Count;
|
||||
import solutions.bitbadger.documents.support.ThrowawayDatabase;
|
||||
import solutions.bitbadger.documents.java.support.JsonDocument;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static solutions.bitbadger.documents.java.integration.TypesKt.TEST_TABLE;
|
||||
import static solutions.bitbadger.documents.support.TypesKt.TEST_TABLE;
|
||||
|
||||
/**
|
||||
* Integration tests for the `Count` object
|
||||
@@ -1,9 +1,9 @@
|
||||
package solutions.bitbadger.documents.java.java.integration.postgresql;
|
||||
package solutions.bitbadger.documents.java.jvm.integration.postgresql;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import solutions.bitbadger.documents.java.integration.postgresql.PgDB;
|
||||
import solutions.bitbadger.documents.java.java.integration.common.CountFunctions;
|
||||
import solutions.bitbadger.documents.java.jvm.integration.common.CountFunctions;
|
||||
import solutions.bitbadger.documents.jvm.integration.postgresql.PgDB;
|
||||
|
||||
/**
|
||||
* PostgreSQL integration tests for the `Count` object / `count*` connection extension functions
|
||||
@@ -1,10 +1,10 @@
|
||||
package solutions.bitbadger.documents.java.java.integration.sqlite;
|
||||
package solutions.bitbadger.documents.java.jvm.integration.sqlite;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import solutions.bitbadger.documents.DocumentException;
|
||||
import solutions.bitbadger.documents.java.integration.sqlite.SQLiteDB;
|
||||
import solutions.bitbadger.documents.java.java.integration.common.CountFunctions;
|
||||
import solutions.bitbadger.documents.java.jvm.integration.common.CountFunctions;
|
||||
import solutions.bitbadger.documents.jvm.integration.sqlite.SQLiteDB;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package solutions.bitbadger.documents.java.java.testDocs;
|
||||
package solutions.bitbadger.documents.java.support;
|
||||
|
||||
public class ByteIdClass {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package solutions.bitbadger.documents.java.java.testDocs;
|
||||
package solutions.bitbadger.documents.java.support;
|
||||
|
||||
public class IntIdClass {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package solutions.bitbadger.documents.java.java.testDocs;
|
||||
package solutions.bitbadger.documents.java.support;
|
||||
|
||||
import kotlinx.serialization.Serializable;
|
||||
import solutions.bitbadger.documents.java.jvm.Document;
|
||||
import solutions.bitbadger.documents.java.integration.ThrowawayDatabase;
|
||||
import solutions.bitbadger.documents.jvm.Document;
|
||||
import solutions.bitbadger.documents.support.ThrowawayDatabase;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static solutions.bitbadger.documents.java.integration.TypesKt.TEST_TABLE;
|
||||
import static solutions.bitbadger.documents.support.TypesKt.TEST_TABLE;
|
||||
|
||||
@Serializable
|
||||
public class JsonDocument {
|
||||
@@ -1,4 +1,4 @@
|
||||
package solutions.bitbadger.documents.java.java.testDocs;
|
||||
package solutions.bitbadger.documents.java.support;
|
||||
|
||||
public class LongIdClass {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package solutions.bitbadger.documents.java.java.testDocs;
|
||||
package solutions.bitbadger.documents.java.support;
|
||||
|
||||
public class ShortIdClass {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package solutions.bitbadger.documents.java.java.testDocs;
|
||||
package solutions.bitbadger.documents.java.support;
|
||||
|
||||
public class StringIdClass {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package solutions.bitbadger.documents.java.java.testDocs;
|
||||
package solutions.bitbadger.documents.java.support;
|
||||
|
||||
public class SubDocument {
|
||||
|
||||
165
src/jvm/src/test/kotlin/AutoIdTest.kt
Normal file
165
src/jvm/src/test/kotlin/AutoIdTest.kt
Normal file
@@ -0,0 +1,165 @@
|
||||
package solutions.bitbadger.documents
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertNotEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
/**
|
||||
* Unit tests for the `AutoId` enum
|
||||
*/
|
||||
@DisplayName("Kotlin | Common | AutoId")
|
||||
class AutoIdTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Generates a UUID string")
|
||||
fun 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")
|
||||
fun generateRandomStringEven() {
|
||||
val 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")
|
||||
fun generateRandomStringOdd() {
|
||||
val result = AutoId.generateRandomString(11)
|
||||
assertEquals(11, result.length, "There should have been 11 characters in $result")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Generates different random hex character strings")
|
||||
fun generateRandomStringIsRandom() {
|
||||
val result1 = AutoId.generateRandomString(16)
|
||||
val result2 = AutoId.generateRandomString(16)
|
||||
assertNotEquals(result1, result2, "There should have been 2 different strings generated")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId fails for null document")
|
||||
fun needsAutoIdFailsForNullDocument() {
|
||||
assertThrows<DocumentException> { AutoId.needsAutoId(AutoId.DISABLED, null, "id") }
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId fails for missing ID property")
|
||||
fun needsAutoIdFailsForMissingId() {
|
||||
assertThrows<DocumentException> { AutoId.needsAutoId(AutoId.UUID, IntIdClass(0), "Id") }
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns false if disabled")
|
||||
fun 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")
|
||||
fun needsAutoIdTrueForByteWithZero() =
|
||||
assertTrue(AutoId.needsAutoId(AutoId.NUMBER, ByteIdClass(0), "id"), "Number Auto ID with 0 should return true")
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns false for Number strategy and byte ID of non-0")
|
||||
fun needsAutoIdFalseForByteWithNonZero() =
|
||||
assertFalse(
|
||||
AutoId.needsAutoId(AutoId.NUMBER, ByteIdClass(77), "id"),
|
||||
"Number Auto ID with 77 should return false"
|
||||
)
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns true for Number strategy and short ID of 0")
|
||||
fun needsAutoIdTrueForShortWithZero() =
|
||||
assertTrue(AutoId.needsAutoId(AutoId.NUMBER, ShortIdClass(0), "id"), "Number Auto ID with 0 should return true")
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns false for Number strategy and short ID of non-0")
|
||||
fun needsAutoIdFalseForShortWithNonZero() =
|
||||
assertFalse(
|
||||
AutoId.needsAutoId(AutoId.NUMBER, ShortIdClass(31), "id"),
|
||||
"Number Auto ID with 31 should return false"
|
||||
)
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns true for Number strategy and int ID of 0")
|
||||
fun needsAutoIdTrueForIntWithZero() =
|
||||
assertTrue(AutoId.needsAutoId(AutoId.NUMBER, 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")
|
||||
fun needsAutoIdFalseForIntWithNonZero() =
|
||||
assertFalse(AutoId.needsAutoId(AutoId.NUMBER, IntIdClass(6), "id"), "Number Auto ID with 6 should return false")
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns true for Number strategy and long ID of 0")
|
||||
fun needsAutoIdTrueForLongWithZero() =
|
||||
assertTrue(AutoId.needsAutoId(AutoId.NUMBER, LongIdClass(0), "id"), "Number Auto ID with 0 should return true")
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns false for Number strategy and long ID of non-0")
|
||||
fun needsAutoIdFalseForLongWithNonZero() =
|
||||
assertFalse(
|
||||
AutoId.needsAutoId(AutoId.NUMBER, LongIdClass(2), "id"),
|
||||
"Number Auto ID with 2 should return false"
|
||||
)
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId fails for Number strategy and non-number ID")
|
||||
fun needsAutoIdFailsForNumberWithStringId() {
|
||||
assertThrows<DocumentException> { AutoId.needsAutoId(AutoId.NUMBER, StringIdClass(""), "id") }
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns true for UUID strategy and blank ID")
|
||||
fun needsAutoIdTrueForUUIDWithBlank() =
|
||||
assertTrue(
|
||||
AutoId.needsAutoId(AutoId.UUID, StringIdClass(""), "id"),
|
||||
"UUID Auto ID with blank should return true"
|
||||
)
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns false for UUID strategy and non-blank ID")
|
||||
fun needsAutoIdFalseForUUIDNotBlank() =
|
||||
assertFalse(
|
||||
AutoId.needsAutoId(AutoId.UUID, StringIdClass("howdy"), "id"),
|
||||
"UUID Auto ID with non-blank should return false"
|
||||
)
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId fails for UUID strategy and non-string ID")
|
||||
fun needsAutoIdFailsForUUIDNonString() {
|
||||
assertThrows<DocumentException> { AutoId.needsAutoId(AutoId.UUID, IntIdClass(5), "id") }
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns true for Random String strategy and blank ID")
|
||||
fun needsAutoIdTrueForRandomWithBlank() =
|
||||
assertTrue(
|
||||
AutoId.needsAutoId(AutoId.RANDOM_STRING, StringIdClass(""), "id"),
|
||||
"Random String Auto ID with blank should return true"
|
||||
)
|
||||
|
||||
@Test
|
||||
@DisplayName("needsAutoId returns false for Random String strategy and non-blank ID")
|
||||
fun needsAutoIdFalseForRandomNotBlank() =
|
||||
assertFalse(
|
||||
AutoId.needsAutoId(AutoId.RANDOM_STRING, 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")
|
||||
fun needsAutoIdFailsForRandomNonString() {
|
||||
assertThrows<DocumentException> { AutoId.needsAutoId(AutoId.RANDOM_STRING, ShortIdClass(55), "id") }
|
||||
}
|
||||
}
|
||||
|
||||
data class ByteIdClass(val id: Byte)
|
||||
data class ShortIdClass(val id: Short)
|
||||
data class IntIdClass(val id: Int)
|
||||
data class LongIdClass(val id: Long)
|
||||
data class StringIdClass(val id: String)
|
||||
168
src/jvm/src/test/kotlin/ComparisonTest.kt
Normal file
168
src/jvm/src/test/kotlin/ComparisonTest.kt
Normal file
@@ -0,0 +1,168 @@
|
||||
package solutions.bitbadger.documents
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
/**
|
||||
* Unit tests for the `ComparisonBetween` class
|
||||
*/
|
||||
@DisplayName("ComparisonBetween")
|
||||
class ComparisonBetweenTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("op is set to BETWEEN")
|
||||
fun op() =
|
||||
assertEquals(Op.BETWEEN, ComparisonBetween(Pair(0, 0)).op, "Between comparison should have BETWEEN op")
|
||||
|
||||
@Test
|
||||
@DisplayName("isNumeric is false with strings")
|
||||
fun isNumericFalseForStringsAndBetween() =
|
||||
assertFalse(
|
||||
ComparisonBetween(Pair("eh", "zed")).isNumeric,
|
||||
"A BETWEEN with strings should not be numeric")
|
||||
|
||||
@Test
|
||||
@DisplayName("isNumeric is true with bytes")
|
||||
fun isNumericTrueForByteAndBetween() =
|
||||
assertTrue(ComparisonBetween(Pair<Byte, Byte>(7, 11)).isNumeric, "A BETWEEN with bytes should be numeric")
|
||||
|
||||
@Test
|
||||
@DisplayName("isNumeric is true with shorts")
|
||||
fun isNumericTrueForShortAndBetween() =
|
||||
assertTrue(
|
||||
ComparisonBetween(Pair<Short, Short>(0, 9)).isNumeric,
|
||||
"A BETWEEN with shorts should be numeric")
|
||||
|
||||
@Test
|
||||
@DisplayName("isNumeric is true with ints")
|
||||
fun isNumericTrueForIntAndBetween() =
|
||||
assertTrue(ComparisonBetween(Pair(15, 44)).isNumeric, "A BETWEEN with ints should be numeric")
|
||||
|
||||
@Test
|
||||
@DisplayName("isNumeric is true with longs")
|
||||
fun isNumericTrueForLongAndBetween() =
|
||||
assertTrue(ComparisonBetween(Pair(9L, 12L)).isNumeric, "A BETWEEN with longs should be numeric")
|
||||
}
|
||||
|
||||
/**
|
||||
* Unit tests for the `ComparisonIn` class
|
||||
*/
|
||||
@DisplayName("ComparisonIn")
|
||||
class ComparisonInTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("op is set to IN")
|
||||
fun op() =
|
||||
assertEquals(Op.IN, ComparisonIn(listOf<String>()).op, "In comparison should have IN op")
|
||||
|
||||
@Test
|
||||
@DisplayName("isNumeric is false for empty list of values")
|
||||
fun isNumericFalseForEmptyList() =
|
||||
assertFalse(ComparisonIn(listOf<Int>()).isNumeric, "An IN with empty list should not be numeric")
|
||||
|
||||
@Test
|
||||
@DisplayName("isNumeric is false with strings")
|
||||
fun isNumericFalseForStringsAndIn() =
|
||||
assertFalse(ComparisonIn(listOf("a", "b", "c")).isNumeric, "An IN with strings should not be numeric")
|
||||
|
||||
@Test
|
||||
@DisplayName("isNumeric is true with bytes")
|
||||
fun isNumericTrueForByteAndIn() =
|
||||
assertTrue(ComparisonIn(listOf<Byte>(4, 8)).isNumeric, "An IN with bytes should be numeric")
|
||||
|
||||
@Test
|
||||
@DisplayName("isNumeric is true with shorts")
|
||||
fun isNumericTrueForShortAndIn() =
|
||||
assertTrue(ComparisonIn(listOf<Short>(18, 22)).isNumeric, "An IN with shorts should be numeric")
|
||||
|
||||
@Test
|
||||
@DisplayName("isNumeric is true with ints")
|
||||
fun isNumericTrueForIntAndIn() =
|
||||
assertTrue(ComparisonIn(listOf(7, 8, 9)).isNumeric, "An IN with ints should be numeric")
|
||||
|
||||
@Test
|
||||
@DisplayName("isNumeric is true with longs")
|
||||
fun isNumericTrueForLongAndIn() =
|
||||
assertTrue(ComparisonIn(listOf(3L)).isNumeric, "An IN with longs should be numeric")
|
||||
}
|
||||
|
||||
/**
|
||||
* Unit tests for the `ComparisonInArray` class
|
||||
*/
|
||||
@DisplayName("ComparisonInArray")
|
||||
class ComparisonInArrayTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("op is set to IN_ARRAY")
|
||||
fun op() =
|
||||
assertEquals(
|
||||
Op.IN_ARRAY,
|
||||
ComparisonInArray(Pair("tbl", listOf<String>())).op,
|
||||
"InArray comparison should have IN_ARRAY op"
|
||||
)
|
||||
|
||||
@Test
|
||||
@DisplayName("isNumeric is false for empty list of values")
|
||||
fun isNumericFalseForEmptyList() =
|
||||
assertFalse(ComparisonIn(listOf<Int>()).isNumeric, "An IN_ARRAY with empty list should not be numeric")
|
||||
|
||||
@Test
|
||||
@DisplayName("isNumeric is false with strings")
|
||||
fun isNumericFalseForStringsAndIn() =
|
||||
assertFalse(ComparisonIn(listOf("a", "b", "c")).isNumeric, "An IN_ARRAY with strings should not be numeric")
|
||||
|
||||
@Test
|
||||
@DisplayName("isNumeric is false with bytes")
|
||||
fun isNumericTrueForByteAndIn() =
|
||||
assertTrue(ComparisonIn(listOf<Byte>(4, 8)).isNumeric, "An IN_ARRAY with bytes should not be numeric")
|
||||
|
||||
@Test
|
||||
@DisplayName("isNumeric is false with shorts")
|
||||
fun isNumericTrueForShortAndIn() =
|
||||
assertTrue(ComparisonIn(listOf<Short>(18, 22)).isNumeric, "An IN_ARRAY with shorts should not be numeric")
|
||||
|
||||
@Test
|
||||
@DisplayName("isNumeric is false with ints")
|
||||
fun isNumericTrueForIntAndIn() =
|
||||
assertTrue(ComparisonIn(listOf(7, 8, 9)).isNumeric, "An IN_ARRAY with ints should not be numeric")
|
||||
|
||||
@Test
|
||||
@DisplayName("isNumeric is false with longs")
|
||||
fun isNumericTrueForLongAndIn() =
|
||||
assertTrue(ComparisonIn(listOf(3L)).isNumeric, "An IN_ARRAY with longs should not be numeric")
|
||||
}
|
||||
|
||||
/**
|
||||
* Unit tests for the `ComparisonSingle` class
|
||||
*/
|
||||
@DisplayName("ComparisonSingle")
|
||||
class ComparisonSingleTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("isNumeric is false for string value")
|
||||
fun isNumericFalseForString() =
|
||||
assertFalse(ComparisonSingle(Op.EQUAL, "80").isNumeric, "A string should not be numeric")
|
||||
|
||||
@Test
|
||||
@DisplayName("isNumeric is true for byte value")
|
||||
fun isNumericTrueForByte() =
|
||||
assertTrue(ComparisonSingle(Op.EQUAL, 47.toByte()).isNumeric, "A byte should be numeric")
|
||||
|
||||
@Test
|
||||
@DisplayName("isNumeric is true for short value")
|
||||
fun isNumericTrueForShort() =
|
||||
assertTrue(ComparisonSingle(Op.EQUAL, 2.toShort()).isNumeric, "A short should be numeric")
|
||||
|
||||
@Test
|
||||
@DisplayName("isNumeric is true for int value")
|
||||
fun isNumericTrueForInt() =
|
||||
assertTrue(ComparisonSingle(Op.EQUAL, 555).isNumeric, "An int should be numeric")
|
||||
|
||||
@Test
|
||||
@DisplayName("isNumeric is true for long value")
|
||||
fun isNumericTrueForLong() =
|
||||
assertTrue(ComparisonSingle(Op.EQUAL, 82L).isNumeric, "A long should be numeric")
|
||||
}
|
||||
43
src/jvm/src/test/kotlin/ConfigurationTest.kt
Normal file
43
src/jvm/src/test/kotlin/ConfigurationTest.kt
Normal file
@@ -0,0 +1,43 @@
|
||||
package solutions.bitbadger.documents
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
/**
|
||||
* Unit tests for the `Configuration` object
|
||||
*/
|
||||
@DisplayName("Kotlin | Common | Configuration")
|
||||
class ConfigurationTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Default ID field is `id`")
|
||||
fun defaultIdField() {
|
||||
assertEquals("id", Configuration.idField, "Default ID field incorrect")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Default Auto ID strategy is `DISABLED`")
|
||||
fun defaultAutoId() {
|
||||
assertEquals(AutoId.DISABLED, Configuration.autoIdStrategy, "Default Auto ID strategy should be `disabled`")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Default ID string length should be 16")
|
||||
fun defaultIdStringLength() {
|
||||
assertEquals(16, Configuration.idStringLength, "Default ID string length should be 16")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Dialect is derived from connection string")
|
||||
fun dialectIsDerived() {
|
||||
try {
|
||||
assertThrows<DocumentException> { Configuration.dialect() }
|
||||
Configuration.connectionString = "jdbc:postgresql:db"
|
||||
assertEquals(Dialect.POSTGRESQL, Configuration.dialect())
|
||||
} finally {
|
||||
Configuration.connectionString = null
|
||||
}
|
||||
}
|
||||
}
|
||||
40
src/jvm/src/test/kotlin/DialectTest.kt
Normal file
40
src/jvm/src/test/kotlin/DialectTest.kt
Normal file
@@ -0,0 +1,40 @@
|
||||
package solutions.bitbadger.documents
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
/**
|
||||
* Unit tests for the `Dialect` enum
|
||||
*/
|
||||
@DisplayName("Kotlin | Common | Dialect")
|
||||
class DialectTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("deriveFromConnectionString derives PostgreSQL correctly")
|
||||
fun derivesPostgres() =
|
||||
assertEquals(
|
||||
Dialect.POSTGRESQL, Dialect.deriveFromConnectionString("jdbc:postgresql:db"),
|
||||
"Dialect should have been PostgreSQL")
|
||||
|
||||
@Test
|
||||
@DisplayName("deriveFromConnectionString derives PostgreSQL correctly")
|
||||
fun derivesSQLite() =
|
||||
assertEquals(
|
||||
Dialect.SQLITE, Dialect.deriveFromConnectionString("jdbc:sqlite:memory"),
|
||||
"Dialect should have been SQLite")
|
||||
|
||||
@Test
|
||||
@DisplayName("deriveFromConnectionString fails when the connection string is unknown")
|
||||
fun deriveFailsWhenUnknown() {
|
||||
try {
|
||||
Dialect.deriveFromConnectionString("SQL Server")
|
||||
} catch (ex: DocumentException) {
|
||||
assertNotNull(ex.message, "The exception message should not have been null")
|
||||
assertTrue(ex.message!!.contains("[SQL Server]"),
|
||||
"The connection string should have been in the exception message")
|
||||
}
|
||||
}
|
||||
}
|
||||
24
src/jvm/src/test/kotlin/DocumentIndexTest.kt
Normal file
24
src/jvm/src/test/kotlin/DocumentIndexTest.kt
Normal file
@@ -0,0 +1,24 @@
|
||||
package solutions.bitbadger.documents
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
/**
|
||||
* Unit tests for the `DocumentIndex` enum
|
||||
*/
|
||||
@DisplayName("Kotlin | Common | DocumentIndex")
|
||||
class DocumentIndexTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("FULL uses proper SQL")
|
||||
fun fullSQL() {
|
||||
assertEquals("", DocumentIndex.FULL.sql, "The SQL for Full is incorrect")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("OPTIMIZED uses proper SQL")
|
||||
fun optimizedSQL() {
|
||||
assertEquals(" jsonb_path_ops", DocumentIndex.OPTIMIZED.sql, "The SQL for Optimized is incorrect")
|
||||
}
|
||||
}
|
||||
24
src/jvm/src/test/kotlin/FieldMatchTest.kt
Normal file
24
src/jvm/src/test/kotlin/FieldMatchTest.kt
Normal file
@@ -0,0 +1,24 @@
|
||||
package solutions.bitbadger.documents
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
/**
|
||||
* Unit tests for the `FieldMatch` enum
|
||||
*/
|
||||
@DisplayName("Kotlin | Common | FieldMatch")
|
||||
class FieldMatchTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("ANY uses proper SQL")
|
||||
fun any() {
|
||||
assertEquals("OR", FieldMatch.ANY.sql, "ANY should use OR")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("ALL uses proper SQL")
|
||||
fun all() {
|
||||
assertEquals("AND", FieldMatch.ALL.sql, "ALL should use AND")
|
||||
}
|
||||
}
|
||||
594
src/jvm/src/test/kotlin/FieldTest.kt
Normal file
594
src/jvm/src/test/kotlin/FieldTest.kt
Normal file
@@ -0,0 +1,594 @@
|
||||
package solutions.bitbadger.documents
|
||||
|
||||
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 kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotSame
|
||||
import kotlin.test.assertNull
|
||||
|
||||
/**
|
||||
* Unit tests for the `Field` class
|
||||
*/
|
||||
@DisplayName("Kotlin | Common | Field")
|
||||
class FieldTest {
|
||||
|
||||
/**
|
||||
* Clear the connection string (resets Dialect)
|
||||
*/
|
||||
@AfterEach
|
||||
fun cleanUp() {
|
||||
Configuration.dialectValue = null
|
||||
}
|
||||
|
||||
// ~~~ INSTANCE METHODS ~~~
|
||||
|
||||
@Test
|
||||
@DisplayName("withParameterName fails for invalid name")
|
||||
fun withParamNameFails() {
|
||||
assertThrows<DocumentException> { Field.equal("it", "").withParameterName("2424") }
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("withParameterName works with colon prefix")
|
||||
fun withParamNameColon() {
|
||||
val field = Field.equal("abc", "22").withQualifier("me")
|
||||
val withParam = field.withParameterName(":test")
|
||||
assertNotSame(field, withParam, "A new Field instance should have been created")
|
||||
assertEquals(field.name, withParam.name, "Name should have been preserved")
|
||||
assertEquals(field.comparison, withParam.comparison, "Comparison should have been preserved")
|
||||
assertEquals(":test", withParam.parameterName, "Parameter name not set correctly")
|
||||
assertEquals(field.qualifier, withParam.qualifier, "Qualifier should have been preserved")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("withParameterName works with at-sign prefix")
|
||||
fun withParamNameAtSign() {
|
||||
val field = Field.equal("def", "44")
|
||||
val withParam = field.withParameterName("@unit")
|
||||
assertNotSame(field, withParam, "A new Field instance should have been created")
|
||||
assertEquals(field.name, withParam.name, "Name should have been preserved")
|
||||
assertEquals(field.comparison, withParam.comparison, "Comparison should have been preserved")
|
||||
assertEquals("@unit", withParam.parameterName, "Parameter name not set correctly")
|
||||
assertEquals(field.qualifier, withParam.qualifier, "Qualifier should have been preserved")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("withQualifier sets qualifier correctly")
|
||||
fun withQualifier() {
|
||||
val field = Field.equal("j", "k")
|
||||
val withQual = field.withQualifier("test")
|
||||
assertNotSame(field, withQual, "A new Field instance should have been created")
|
||||
assertEquals(field.name, withQual.name, "Name should have been preserved")
|
||||
assertEquals(field.comparison, withQual.comparison, "Comparison should have been preserved")
|
||||
assertEquals(field.parameterName, withQual.parameterName, "Parameter Name should have been preserved")
|
||||
assertEquals("test", withQual.qualifier, "Qualifier not set correctly")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for simple unqualified PostgreSQL field")
|
||||
fun pathPostgresSimpleUnqualified() =
|
||||
assertEquals("data->>'SomethingCool'",
|
||||
Field.greaterOrEqual("SomethingCool", 18).path(Dialect.POSTGRESQL, FieldFormat.SQL), "Path not correct")
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for simple qualified PostgreSQL field")
|
||||
fun pathPostgresSimpleQualified() =
|
||||
assertEquals("this.data->>'SomethingElse'",
|
||||
Field.less("SomethingElse", 9).withQualifier("this").path(Dialect.POSTGRESQL, FieldFormat.SQL),
|
||||
"Path not correct")
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for nested unqualified PostgreSQL field")
|
||||
fun pathPostgresNestedUnqualified() {
|
||||
assertEquals("data#>>'{My,Nested,Field}'",
|
||||
Field.equal("My.Nested.Field", "howdy").path(Dialect.POSTGRESQL, FieldFormat.SQL), "Path not correct")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for nested qualified PostgreSQL field")
|
||||
fun pathPostgresNestedQualified() =
|
||||
assertEquals("bird.data#>>'{Nest,Away}'",
|
||||
Field.equal("Nest.Away", "doc").withQualifier("bird").path(Dialect.POSTGRESQL, FieldFormat.SQL),
|
||||
"Path not correct")
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for simple unqualified SQLite field")
|
||||
fun pathSQLiteSimpleUnqualified() =
|
||||
assertEquals("data->>'SomethingCool'",
|
||||
Field.greaterOrEqual("SomethingCool", 18).path(Dialect.SQLITE, FieldFormat.SQL), "Path not correct")
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for simple qualified SQLite field")
|
||||
fun pathSQLiteSimpleQualified() =
|
||||
assertEquals("this.data->>'SomethingElse'",
|
||||
Field.less("SomethingElse", 9).withQualifier("this").path(Dialect.SQLITE, FieldFormat.SQL),
|
||||
"Path not correct")
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for nested unqualified SQLite field")
|
||||
fun pathSQLiteNestedUnqualified() =
|
||||
assertEquals("data->'My'->'Nested'->>'Field'",
|
||||
Field.equal("My.Nested.Field", "howdy").path(Dialect.SQLITE, FieldFormat.SQL), "Path not correct")
|
||||
|
||||
@Test
|
||||
@DisplayName("path generates for nested qualified SQLite field")
|
||||
fun pathSQLiteNestedQualified() =
|
||||
assertEquals("bird.data->'Nest'->>'Away'",
|
||||
Field.equal("Nest.Away", "doc").withQualifier("bird").path(Dialect.SQLITE, FieldFormat.SQL),
|
||||
"Path not correct")
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for exists w/o qualifier (PostgreSQL)")
|
||||
fun toWhereExistsNoQualPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("data->>'that_field' IS NOT NULL", Field.exists("that_field").toWhere(),
|
||||
"Field WHERE clause not generated correctly")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for exists w/o qualifier (SQLite)")
|
||||
fun toWhereExistsNoQualSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals("data->>'that_field' IS NOT NULL", Field.exists("that_field").toWhere(),
|
||||
"Field WHERE clause not generated correctly")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for not-exists w/o qualifier (PostgreSQL)")
|
||||
fun toWhereNotExistsNoQualPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("data->>'a_field' IS NULL", Field.notExists("a_field").toWhere(),
|
||||
"Field WHERE clause not generated correctly")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for not-exists w/o qualifier (SQLite)")
|
||||
fun toWhereNotExistsNoQualSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals("data->>'a_field' IS NULL", Field.notExists("a_field").toWhere(),
|
||||
"Field WHERE clause not generated correctly")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for BETWEEN w/o qualifier, numeric range (PostgreSQL)")
|
||||
fun toWhereBetweenNoQualNumericPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("(data->>'age')::numeric BETWEEN @agemin AND @agemax",
|
||||
Field.between("age", 13, 17, "@age").toWhere(), "Field WHERE clause not generated correctly")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for BETWEEN w/o qualifier, alphanumeric range (PostgreSQL)")
|
||||
fun toWhereBetweenNoQualAlphaPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("data->>'city' BETWEEN :citymin AND :citymax",
|
||||
Field.between("city", "Atlanta", "Chicago", ":city").toWhere(),
|
||||
"Field WHERE clause not generated correctly")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for BETWEEN w/o qualifier (SQLite)")
|
||||
fun toWhereBetweenNoQualSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals("data->>'age' BETWEEN @agemin AND @agemax", Field.between("age", 13, 17, "@age").toWhere(),
|
||||
"Field WHERE clause not generated correctly")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for BETWEEN w/ qualifier, numeric range (PostgreSQL)")
|
||||
fun toWhereBetweenQualNumericPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("(test.data->>'age')::numeric BETWEEN @agemin AND @agemax",
|
||||
Field.between("age", 13, 17, "@age").withQualifier("test").toWhere(),
|
||||
"Field WHERE clause not generated correctly")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for BETWEEN w/ qualifier, alphanumeric range (PostgreSQL)")
|
||||
fun toWhereBetweenQualAlphaPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("unit.data->>'city' BETWEEN :citymin AND :citymax",
|
||||
Field.between("city", "Atlanta", "Chicago", ":city").withQualifier("unit").toWhere(),
|
||||
"Field WHERE clause not generated correctly")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for BETWEEN w/ qualifier (SQLite)")
|
||||
fun toWhereBetweenQualSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals("my.data->>'age' BETWEEN @agemin AND @agemax",
|
||||
Field.between("age", 13, 17, "@age").withQualifier("my").toWhere(),
|
||||
"Field WHERE clause not generated correctly")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for IN/any, numeric values (PostgreSQL)")
|
||||
fun toWhereAnyNumericPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("(data->>'even')::numeric IN (:nbr_0, :nbr_1, :nbr_2)",
|
||||
Field.any("even", listOf(2, 4, 6), ":nbr").toWhere(), "Field WHERE clause not generated correctly")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for IN/any, alphanumeric values (PostgreSQL)")
|
||||
fun toWhereAnyAlphaPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("data->>'test' IN (:city_0, :city_1)",
|
||||
Field.any("test", listOf("Atlanta", "Chicago"), ":city").toWhere(),
|
||||
"Field WHERE clause not generated correctly")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for IN/any (SQLite)")
|
||||
fun toWhereAnySQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals("data->>'test' IN (:city_0, :city_1)",
|
||||
Field.any("test", listOf("Atlanta", "Chicago"), ":city").toWhere(),
|
||||
"Field WHERE clause not generated correctly")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for inArray (PostgreSQL)")
|
||||
fun toWhereInArrayPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("data->'even' ??| ARRAY[:it_0, :it_1, :it_2, :it_3]",
|
||||
Field.inArray("even", "tbl", listOf(2, 4, 6, 8), ":it").toWhere(),
|
||||
"Field WHERE clause not generated correctly")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for inArray (SQLite)")
|
||||
fun toWhereInArraySQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals("EXISTS (SELECT 1 FROM json_each(tbl.data, '$.test') WHERE value IN (:city_0, :city_1))",
|
||||
Field.inArray("test", "tbl", listOf("Atlanta", "Chicago"), ":city").toWhere(),
|
||||
"Field WHERE clause not generated correctly")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for others w/o qualifier (PostgreSQL)")
|
||||
fun toWhereOtherNoQualPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("data->>'some_field' = :value", Field.equal("some_field", "", ":value").toWhere(),
|
||||
"Field WHERE clause not generated correctly")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates for others w/o qualifier (SQLite)")
|
||||
fun toWhereOtherNoQualSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals("data->>'some_field' = :value", Field.equal("some_field", "", ":value").toWhere(),
|
||||
"Field WHERE clause not generated correctly")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates no-parameter w/ qualifier (PostgreSQL)")
|
||||
fun toWhereNoParamWithQualPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("test.data->>'no_field' IS NOT NULL", Field.exists("no_field").withQualifier("test").toWhere(),
|
||||
"Field WHERE clause not generated correctly")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates no-parameter w/ qualifier (SQLite)")
|
||||
fun toWhereNoParamWithQualSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals("test.data->>'no_field' IS NOT NULL", Field.exists("no_field").withQualifier("test").toWhere(),
|
||||
"Field WHERE clause not generated correctly")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates parameter w/ qualifier (PostgreSQL)")
|
||||
fun toWhereParamWithQualPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("(q.data->>'le_field')::numeric <= :it",
|
||||
Field.lessOrEqual("le_field", 18, ":it").withQualifier("q").toWhere(),
|
||||
"Field WHERE clause not generated correctly")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("toWhere generates parameter w/ qualifier (SQLite)")
|
||||
fun toWhereParamWithQualSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals("q.data->>'le_field' <= :it",
|
||||
Field.lessOrEqual("le_field", 18, ":it").withQualifier("q").toWhere(),
|
||||
"Field WHERE clause not generated correctly")
|
||||
}
|
||||
|
||||
// ~~~ COMPANION OBJECT TESTS ~~~
|
||||
|
||||
@Test
|
||||
@DisplayName("equal constructs a field w/o parameter name")
|
||||
fun equalCtor() {
|
||||
val field = Field.equal("Test", 14)
|
||||
assertEquals("Test", field.name, "Field name not filled correctly")
|
||||
assertEquals(Op.EQUAL, field.comparison.op, "Field comparison operation not filled correctly")
|
||||
assertEquals(14, field.comparison.value, "Field comparison value not filled correctly")
|
||||
assertNull(field.parameterName, "The parameter name should have been null")
|
||||
assertNull(field.qualifier, "The qualifier should have been null")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("equal constructs a field w/ parameter name")
|
||||
fun equalParameterCtor() {
|
||||
val field = Field.equal("Test", 14, ":w")
|
||||
assertEquals("Test", field.name, "Field name not filled correctly")
|
||||
assertEquals(Op.EQUAL, field.comparison.op, "Field comparison operation not filled correctly")
|
||||
assertEquals(14, field.comparison.value, "Field comparison value not filled correctly")
|
||||
assertEquals(":w", field.parameterName, "Field parameter name not filled correctly")
|
||||
assertNull(field.qualifier, "The qualifier should have been null")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("greater constructs a field w/o parameter name")
|
||||
fun greaterCtor() {
|
||||
val field = Field.greater("Great", "night")
|
||||
assertEquals("Great", field.name, "Field name not filled correctly")
|
||||
assertEquals(Op.GREATER, field.comparison.op, "Field comparison operation not filled correctly")
|
||||
assertEquals("night", field.comparison.value, "Field comparison value not filled correctly")
|
||||
assertNull(field.parameterName, "The parameter name should have been null")
|
||||
assertNull(field.qualifier, "The qualifier should have been null")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("greater constructs a field w/ parameter name")
|
||||
fun greaterParameterCtor() {
|
||||
val field = Field.greater("Great", "night", ":yeah")
|
||||
assertEquals("Great", field.name, "Field name not filled correctly")
|
||||
assertEquals(Op.GREATER, field.comparison.op, "Field comparison operation not filled correctly")
|
||||
assertEquals("night", field.comparison.value, "Field comparison value not filled correctly")
|
||||
assertEquals(":yeah", field.parameterName, "Field parameter name not filled correctly")
|
||||
assertNull(field.qualifier, "The qualifier should have been null")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("greaterOrEqual constructs a field w/o parameter name")
|
||||
fun greaterOrEqualCtor() {
|
||||
val field = Field.greaterOrEqual("Nice", 88L)
|
||||
assertEquals("Nice", field.name, "Field name not filled correctly")
|
||||
assertEquals(Op.GREATER_OR_EQUAL, field.comparison.op, "Field comparison operation not filled correctly")
|
||||
assertEquals(88L, field.comparison.value, "Field comparison value not filled correctly")
|
||||
assertNull(field.parameterName, "The parameter name should have been null")
|
||||
assertNull(field.qualifier, "The qualifier should have been null")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("greaterOrEqual constructs a field w/ parameter name")
|
||||
fun greaterOrEqualParameterCtor() {
|
||||
val field = Field.greaterOrEqual("Nice", 88L, ":nice")
|
||||
assertEquals("Nice", field.name, "Field name not filled correctly")
|
||||
assertEquals(Op.GREATER_OR_EQUAL, field.comparison.op, "Field comparison operation not filled correctly")
|
||||
assertEquals(88L, field.comparison.value, "Field comparison value not filled correctly")
|
||||
assertEquals(":nice", field.parameterName, "Field parameter name not filled correctly")
|
||||
assertNull(field.qualifier, "The qualifier should have been null")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("less constructs a field w/o parameter name")
|
||||
fun lessCtor() {
|
||||
val field = Field.less("Lesser", "seven")
|
||||
assertEquals("Lesser", field.name, "Field name not filled correctly")
|
||||
assertEquals(Op.LESS, field.comparison.op, "Field comparison operation not filled correctly")
|
||||
assertEquals("seven", field.comparison.value, "Field comparison value not filled correctly")
|
||||
assertNull(field.parameterName, "The parameter name should have been null")
|
||||
assertNull(field.qualifier, "The qualifier should have been null")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("less constructs a field w/ parameter name")
|
||||
fun lessParameterCtor() {
|
||||
val field = Field.less("Lesser", "seven", ":max")
|
||||
assertEquals("Lesser", field.name, "Field name not filled correctly")
|
||||
assertEquals(Op.LESS, field.comparison.op, "Field comparison operation not filled correctly")
|
||||
assertEquals("seven", field.comparison.value, "Field comparison value not filled correctly")
|
||||
assertEquals(":max", field.parameterName, "Field parameter name not filled correctly")
|
||||
assertNull(field.qualifier, "The qualifier should have been null")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("lessOrEqual constructs a field w/o parameter name")
|
||||
fun lessOrEqualCtor() {
|
||||
val field = Field.lessOrEqual("Nobody", "KNOWS")
|
||||
assertEquals("Nobody", field.name, "Field name not filled correctly")
|
||||
assertEquals(Op.LESS_OR_EQUAL, field.comparison.op, "Field comparison operation not filled correctly")
|
||||
assertEquals("KNOWS", field.comparison.value, "Field comparison value not filled correctly")
|
||||
assertNull(field.parameterName, "The parameter name should have been null")
|
||||
assertNull(field.qualifier, "The qualifier should have been null")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("lessOrEqual constructs a field w/ parameter name")
|
||||
fun lessOrEqualParameterCtor() {
|
||||
val field = Field.lessOrEqual("Nobody", "KNOWS", ":nope")
|
||||
assertEquals("Nobody", field.name, "Field name not filled correctly")
|
||||
assertEquals(Op.LESS_OR_EQUAL, field.comparison.op, "Field comparison operation not filled correctly")
|
||||
assertEquals("KNOWS", field.comparison.value, "Field comparison value not filled correctly")
|
||||
assertEquals(":nope", field.parameterName, "Field parameter name not filled correctly")
|
||||
assertNull(field.qualifier, "The qualifier should have been null")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("notEqual constructs a field w/o parameter name")
|
||||
fun notEqualCtor() {
|
||||
val field = Field.notEqual("Park", "here")
|
||||
assertEquals("Park", field.name, "Field name not filled correctly")
|
||||
assertEquals(Op.NOT_EQUAL, field.comparison.op, "Field comparison operation not filled correctly")
|
||||
assertEquals("here", field.comparison.value, "Field comparison value not filled correctly")
|
||||
assertNull(field.parameterName, "The parameter name should have been null")
|
||||
assertNull(field.qualifier, "The qualifier should have been null")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("notEqual constructs a field w/ parameter name")
|
||||
fun notEqualParameterCtor() {
|
||||
val field = Field.notEqual("Park", "here", ":now")
|
||||
assertEquals("Park", field.name, "Field name not filled correctly")
|
||||
assertEquals(Op.NOT_EQUAL, field.comparison.op, "Field comparison operation not filled correctly")
|
||||
assertEquals("here", field.comparison.value, "Field comparison value not filled correctly")
|
||||
assertEquals(":now", field.parameterName, "Field parameter name not filled correctly")
|
||||
assertNull(field.qualifier, "The qualifier should have been null")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("between constructs a field w/o parameter name")
|
||||
fun betweenCtor() {
|
||||
val field = Field.between("Age", 18, 49)
|
||||
assertEquals("Age", field.name, "Field name not filled correctly")
|
||||
assertEquals(Op.BETWEEN, field.comparison.op, "Field comparison operation not filled correctly")
|
||||
assertEquals(18, field.comparison.value.first, "Field comparison min value not filled correctly")
|
||||
assertEquals(49, field.comparison.value.second, "Field comparison max value not filled correctly")
|
||||
assertNull(field.parameterName, "The parameter name should have been null")
|
||||
assertNull(field.qualifier, "The qualifier should have been null")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("between constructs a field w/ parameter name")
|
||||
fun betweenParameterCtor() {
|
||||
val field = Field.between("Age", 18, 49, ":limit")
|
||||
assertEquals("Age", field.name, "Field name not filled correctly")
|
||||
assertEquals(Op.BETWEEN, field.comparison.op, "Field comparison operation not filled correctly")
|
||||
assertEquals(18, field.comparison.value.first, "Field comparison min value not filled correctly")
|
||||
assertEquals(49, field.comparison.value.second, "Field comparison max value not filled correctly")
|
||||
assertEquals(":limit", field.parameterName, "The parameter name should have been null")
|
||||
assertNull(field.qualifier, "The qualifier should have been null")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("any constructs a field w/o parameter name")
|
||||
fun anyCtor() {
|
||||
val field = Field.any("Here", listOf(8, 16, 32))
|
||||
assertEquals("Here", field.name, "Field name not filled correctly")
|
||||
assertEquals(Op.IN, field.comparison.op, "Field comparison operation not filled correctly")
|
||||
assertEquals(listOf(8, 16, 32), field.comparison.value, "Field comparison value not filled correctly")
|
||||
assertNull(field.parameterName, "The parameter name should have been null")
|
||||
assertNull(field.qualifier, "The qualifier should have been null")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("any constructs a field w/ parameter name")
|
||||
fun anyParameterCtor() {
|
||||
val field = Field.any("Here", listOf(8, 16, 32), ":list")
|
||||
assertEquals("Here", field.name, "Field name not filled correctly")
|
||||
assertEquals(Op.IN, field.comparison.op, "Field comparison operation not filled correctly")
|
||||
assertEquals(listOf(8, 16, 32), field.comparison.value, "Field comparison value not filled correctly")
|
||||
assertEquals(":list", field.parameterName, "Field parameter name not filled correctly")
|
||||
assertNull(field.qualifier, "The qualifier should have been null")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("inArray constructs a field w/o parameter name")
|
||||
fun inArrayCtor() {
|
||||
val field = Field.inArray("ArrayField", "table", listOf("z"))
|
||||
assertEquals("ArrayField", field.name, "Field name not filled correctly")
|
||||
assertEquals(Op.IN_ARRAY, field.comparison.op, "Field comparison operation not filled correctly")
|
||||
assertEquals("table", field.comparison.value.first, "Field comparison table not filled correctly")
|
||||
assertEquals(listOf("z"), field.comparison.value.second, "Field comparison values not filled correctly")
|
||||
assertNull(field.parameterName, "The parameter name should have been null")
|
||||
assertNull(field.qualifier, "The qualifier should have been null")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("inArray constructs a field w/ parameter name")
|
||||
fun inArrayParameterCtor() {
|
||||
val field = Field.inArray("ArrayField", "table", listOf("z"), ":a")
|
||||
assertEquals("ArrayField", field.name, "Field name not filled correctly")
|
||||
assertEquals(Op.IN_ARRAY, field.comparison.op, "Field comparison operation not filled correctly")
|
||||
assertEquals("table", field.comparison.value.first, "Field comparison table not filled correctly")
|
||||
assertEquals(listOf("z"), field.comparison.value.second, "Field comparison values not filled correctly")
|
||||
assertEquals(":a", field.parameterName, "Field parameter name not filled correctly")
|
||||
assertNull(field.qualifier, "The qualifier should have been null")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("exists constructs a field")
|
||||
fun existsCtor() {
|
||||
val field = Field.exists("Groovy")
|
||||
assertEquals("Groovy", field.name, "Field name not filled correctly")
|
||||
assertEquals(Op.EXISTS, field.comparison.op, "Field comparison operation not filled correctly")
|
||||
assertEquals("", field.comparison.value, "Field comparison value not filled correctly")
|
||||
assertNull(field.parameterName, "The parameter name should have been null")
|
||||
assertNull(field.qualifier, "The qualifier should have been null")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("notExists constructs a field")
|
||||
fun notExistsCtor() {
|
||||
val field = Field.notExists("Groovy")
|
||||
assertEquals("Groovy", field.name, "Field name not filled correctly")
|
||||
assertEquals(Op.NOT_EXISTS, field.comparison.op, "Field comparison operation not filled correctly")
|
||||
assertEquals("", field.comparison.value, "Field comparison value not filled correctly")
|
||||
assertNull(field.parameterName, "The parameter name should have been null")
|
||||
assertNull(field.qualifier, "The qualifier should have been null")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("named constructs a field")
|
||||
fun namedCtor() {
|
||||
val field = Field.named("Tacos")
|
||||
assertEquals("Tacos", field.name, "Field name not filled correctly")
|
||||
assertEquals(Op.EQUAL, field.comparison.op, "Field comparison operation not filled correctly")
|
||||
assertEquals("", field.comparison.value, "Field comparison value not filled correctly")
|
||||
assertNull(field.parameterName, "The parameter name should have been null")
|
||||
assertNull(field.qualifier, "The qualifier should have been null")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("static constructors fail for invalid parameter name")
|
||||
fun staticCtorsFailOnParamName() {
|
||||
assertThrows<DocumentException> { Field.equal("a", "b", "that ain't it, Jack...") }
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a simple PostgreSQL SQL name")
|
||||
fun nameToPathPostgresSimpleSQL() =
|
||||
assertEquals("data->>'Simple'", Field.nameToPath("Simple", Dialect.POSTGRESQL, FieldFormat.SQL),
|
||||
"Path not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a simple SQLite SQL name")
|
||||
fun nameToPathSQLiteSimpleSQL() =
|
||||
assertEquals("data->>'Simple'", Field.nameToPath("Simple", Dialect.SQLITE, FieldFormat.SQL),
|
||||
"Path not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a nested PostgreSQL SQL name")
|
||||
fun nameToPathPostgresNestedSQL() =
|
||||
assertEquals("data#>>'{A,Long,Path,to,the,Property}'",
|
||||
Field.nameToPath("A.Long.Path.to.the.Property", Dialect.POSTGRESQL, FieldFormat.SQL),
|
||||
"Path not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a nested SQLite SQL name")
|
||||
fun nameToPathSQLiteNestedSQL() =
|
||||
assertEquals("data->'A'->'Long'->'Path'->'to'->'the'->>'Property'",
|
||||
Field.nameToPath("A.Long.Path.to.the.Property", Dialect.SQLITE, FieldFormat.SQL),
|
||||
"Path not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a simple PostgreSQL JSON name")
|
||||
fun nameToPathPostgresSimpleJSON() =
|
||||
assertEquals("data->'Simple'", Field.nameToPath("Simple", Dialect.POSTGRESQL, FieldFormat.JSON),
|
||||
"Path not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a simple SQLite JSON name")
|
||||
fun nameToPathSQLiteSimpleJSON() =
|
||||
assertEquals("data->'Simple'", Field.nameToPath("Simple", Dialect.SQLITE, FieldFormat.JSON),
|
||||
"Path not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a nested PostgreSQL JSON name")
|
||||
fun nameToPathPostgresNestedJSON() =
|
||||
assertEquals("data#>'{A,Long,Path,to,the,Property}'",
|
||||
Field.nameToPath("A.Long.Path.to.the.Property", Dialect.POSTGRESQL, FieldFormat.JSON),
|
||||
"Path not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("nameToPath creates a nested SQLite JSON name")
|
||||
fun nameToPathSQLiteNestedJSON() =
|
||||
assertEquals("data->'A'->'Long'->'Path'->'to'->'the'->'Property'",
|
||||
Field.nameToPath("A.Long.Path.to.the.Property", Dialect.SQLITE, FieldFormat.JSON),
|
||||
"Path not constructed correctly")
|
||||
}
|
||||
78
src/jvm/src/test/kotlin/OpTest.kt
Normal file
78
src/jvm/src/test/kotlin/OpTest.kt
Normal file
@@ -0,0 +1,78 @@
|
||||
package solutions.bitbadger.documents
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
/**
|
||||
* Unit tests for the `Op` enum
|
||||
*/
|
||||
@DisplayName("Kotlin | Common | Op")
|
||||
class OpTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("EQUAL uses proper SQL")
|
||||
fun equalSQL() {
|
||||
assertEquals("=", Op.EQUAL.sql, "The SQL for equal is incorrect")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("GREATER uses proper SQL")
|
||||
fun greaterSQL() {
|
||||
assertEquals(">", Op.GREATER.sql, "The SQL for greater is incorrect")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("GREATER_OR_EQUAL uses proper SQL")
|
||||
fun greaterOrEqualSQL() {
|
||||
assertEquals(">=", Op.GREATER_OR_EQUAL.sql, "The SQL for greater-or-equal is incorrect")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("LESS uses proper SQL")
|
||||
fun lessSQL() {
|
||||
assertEquals("<", Op.LESS.sql, "The SQL for less is incorrect")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("LESS_OR_EQUAL uses proper SQL")
|
||||
fun lessOrEqualSQL() {
|
||||
assertEquals("<=", Op.LESS_OR_EQUAL.sql, "The SQL for less-or-equal is incorrect")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("NOT_EQUAL uses proper SQL")
|
||||
fun notEqualSQL() {
|
||||
assertEquals("<>", Op.NOT_EQUAL.sql, "The SQL for not-equal is incorrect")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("BETWEEN uses proper SQL")
|
||||
fun betweenSQL() {
|
||||
assertEquals("BETWEEN", Op.BETWEEN.sql, "The SQL for between is incorrect")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("IN uses proper SQL")
|
||||
fun inSQL() {
|
||||
assertEquals("IN", Op.IN.sql, "The SQL for in is incorrect")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("IN_ARRAY uses proper SQL")
|
||||
fun inArraySQL() {
|
||||
assertEquals("??|", Op.IN_ARRAY.sql, "The SQL for in-array is incorrect")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("EXISTS uses proper SQL")
|
||||
fun existsSQL() {
|
||||
assertEquals("IS NOT NULL", Op.EXISTS.sql, "The SQL for exists is incorrect")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("NOT_EXISTS uses proper SQL")
|
||||
fun notExistsSQL() {
|
||||
assertEquals("IS NULL", Op.NOT_EXISTS.sql, "The SQL for not-exists is incorrect")
|
||||
}
|
||||
}
|
||||
30
src/jvm/src/test/kotlin/ParameterNameTest.kt
Normal file
30
src/jvm/src/test/kotlin/ParameterNameTest.kt
Normal file
@@ -0,0 +1,30 @@
|
||||
package solutions.bitbadger.documents
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
/**
|
||||
* Unit tests for the `ParameterName` class
|
||||
*/
|
||||
@DisplayName("Kotlin | Common | ParameterName")
|
||||
class ParameterNameTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("derive works when given existing names")
|
||||
fun withExisting() {
|
||||
val names = ParameterName()
|
||||
assertEquals(":taco", names.derive(":taco"), "Name should have been :taco")
|
||||
assertEquals(":field0", names.derive(null), "Counter should not have advanced for named field")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("derive works when given all anonymous fields")
|
||||
fun allAnonymous() {
|
||||
val names = ParameterName()
|
||||
assertEquals(":field0", names.derive(null), "Anonymous field name should have been returned")
|
||||
assertEquals(":field1", names.derive(null), "Counter should have advanced from previous call")
|
||||
assertEquals(":field2", names.derive(null), "Counter should have advanced from previous call")
|
||||
assertEquals(":field3", names.derive(null), "Counter should have advanced from previous call")
|
||||
}
|
||||
}
|
||||
38
src/jvm/src/test/kotlin/ParameterTest.kt
Normal file
38
src/jvm/src/test/kotlin/ParameterTest.kt
Normal file
@@ -0,0 +1,38 @@
|
||||
package solutions.bitbadger.documents
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNull
|
||||
|
||||
/**
|
||||
* Unit tests for the `Parameter` class
|
||||
*/
|
||||
@DisplayName("Kotlin | Common | Parameter")
|
||||
class ParameterTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Construction with colon-prefixed name")
|
||||
fun ctorWithColon() {
|
||||
val p = Parameter(":test", ParameterType.STRING, "ABC")
|
||||
assertEquals(":test", p.name, "Parameter name was incorrect")
|
||||
assertEquals(ParameterType.STRING, p.type, "Parameter type was incorrect")
|
||||
assertEquals("ABC", p.value, "Parameter value was incorrect")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Construction with at-sign-prefixed name")
|
||||
fun ctorWithAtSign() {
|
||||
val p = Parameter("@yo", ParameterType.NUMBER, null)
|
||||
assertEquals("@yo", p.name, "Parameter name was incorrect")
|
||||
assertEquals(ParameterType.NUMBER, p.type, "Parameter type was incorrect")
|
||||
assertNull(p.value, "Parameter value was incorrect")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Construction fails with incorrect prefix")
|
||||
fun ctorFailsForPrefix() {
|
||||
assertThrows<DocumentException> { Parameter("it", ParameterType.JSON, "") }
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package solutions.bitbadger.documents.java
|
||||
package solutions.bitbadger.documents.jvm
|
||||
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
@@ -38,7 +38,8 @@ class ParametersTest {
|
||||
@DisplayName("nameFields works when changing fields")
|
||||
fun nameFieldsChange() {
|
||||
val fields = listOf(
|
||||
Field.equal("a", ""), Field.equal("e", "", ":hi"), Field.equal("b", ""), Field.notExists("z"))
|
||||
Field.equal("a", ""), Field.equal("e", "", ":hi"), Field.equal("b", ""), Field.notExists("z")
|
||||
)
|
||||
val named = Parameters.nameFields(fields)
|
||||
assertEquals(fields.size, named.size, "There should have been 4 fields in the list")
|
||||
assertNotSame(fields.elementAt(0), named.elementAt(0), "The first field should not be the same")
|
||||
@@ -1,13 +1,8 @@
|
||||
package solutions.bitbadger.documents.java.integration.common
|
||||
package solutions.bitbadger.documents.jvm.integration.common
|
||||
|
||||
import solutions.bitbadger.documents.Field
|
||||
import solutions.bitbadger.documents.java.extensions.countAll
|
||||
import solutions.bitbadger.documents.java.extensions.countByContains
|
||||
import solutions.bitbadger.documents.java.extensions.countByFields
|
||||
import solutions.bitbadger.documents.java.extensions.countByJsonPath
|
||||
import solutions.bitbadger.documents.java.integration.JsonDocument
|
||||
import solutions.bitbadger.documents.java.integration.TEST_TABLE
|
||||
import solutions.bitbadger.documents.java.integration.ThrowawayDatabase
|
||||
import solutions.bitbadger.documents.extensions.*
|
||||
import solutions.bitbadger.documents.support.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
/**
|
||||
@@ -1,16 +1,12 @@
|
||||
package solutions.bitbadger.documents.java.integration.common
|
||||
package solutions.bitbadger.documents.jvm.integration.common
|
||||
|
||||
import solutions.bitbadger.documents.Configuration
|
||||
import solutions.bitbadger.documents.Field
|
||||
import solutions.bitbadger.documents.Parameter
|
||||
import solutions.bitbadger.documents.ParameterType
|
||||
import solutions.bitbadger.documents.common.*
|
||||
import solutions.bitbadger.documents.java.*
|
||||
import solutions.bitbadger.documents.java.extensions.*
|
||||
import solutions.bitbadger.documents.java.integration.JsonDocument
|
||||
import solutions.bitbadger.documents.java.integration.TEST_TABLE
|
||||
import solutions.bitbadger.documents.java.integration.ThrowawayDatabase
|
||||
import solutions.bitbadger.documents.java.jvm.Results
|
||||
import solutions.bitbadger.documents.*
|
||||
import solutions.bitbadger.documents.extensions.*
|
||||
import solutions.bitbadger.documents.jvm.Results
|
||||
import solutions.bitbadger.documents.query.Count
|
||||
import solutions.bitbadger.documents.query.Delete
|
||||
import solutions.bitbadger.documents.query.Find
|
||||
import solutions.bitbadger.documents.support.*
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertNull
|
||||
@@ -1,11 +1,11 @@
|
||||
package solutions.bitbadger.documents.java.integration.common
|
||||
package solutions.bitbadger.documents.jvm.integration.common
|
||||
|
||||
import solutions.bitbadger.documents.DocumentIndex
|
||||
import solutions.bitbadger.documents.java.extensions.ensureDocumentIndex
|
||||
import solutions.bitbadger.documents.java.extensions.ensureFieldIndex
|
||||
import solutions.bitbadger.documents.java.extensions.ensureTable
|
||||
import solutions.bitbadger.documents.java.integration.TEST_TABLE
|
||||
import solutions.bitbadger.documents.java.integration.ThrowawayDatabase
|
||||
import solutions.bitbadger.documents.extensions.ensureDocumentIndex
|
||||
import solutions.bitbadger.documents.extensions.ensureFieldIndex
|
||||
import solutions.bitbadger.documents.extensions.ensureTable
|
||||
import solutions.bitbadger.documents.support.TEST_TABLE
|
||||
import solutions.bitbadger.documents.support.ThrowawayDatabase
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package solutions.bitbadger.documents.java.integration.common
|
||||
package solutions.bitbadger.documents.jvm.integration.common
|
||||
|
||||
import solutions.bitbadger.documents.Field
|
||||
import solutions.bitbadger.documents.java.extensions.*
|
||||
import solutions.bitbadger.documents.java.integration.JsonDocument
|
||||
import solutions.bitbadger.documents.java.integration.TEST_TABLE
|
||||
import solutions.bitbadger.documents.java.integration.ThrowawayDatabase
|
||||
import solutions.bitbadger.documents.extensions.*
|
||||
import solutions.bitbadger.documents.support.JsonDocument
|
||||
import solutions.bitbadger.documents.support.TEST_TABLE
|
||||
import solutions.bitbadger.documents.support.ThrowawayDatabase
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
/**
|
||||
@@ -1,11 +1,10 @@
|
||||
package solutions.bitbadger.documents.java.integration.common
|
||||
package solutions.bitbadger.documents.jvm.integration.common
|
||||
|
||||
import AutoId
|
||||
import solutions.bitbadger.documents.AutoId
|
||||
import solutions.bitbadger.documents.Configuration
|
||||
import solutions.bitbadger.documents.Field
|
||||
import solutions.bitbadger.documents.common.*
|
||||
import solutions.bitbadger.documents.java.extensions.*
|
||||
import solutions.bitbadger.documents.java.integration.*
|
||||
import solutions.bitbadger.documents.extensions.*
|
||||
import solutions.bitbadger.documents.support.*
|
||||
import kotlin.test.*
|
||||
|
||||
/**
|
||||
@@ -1,13 +1,8 @@
|
||||
package solutions.bitbadger.documents.java.integration.common
|
||||
package solutions.bitbadger.documents.jvm.integration.common
|
||||
|
||||
import solutions.bitbadger.documents.Field
|
||||
import solutions.bitbadger.documents.java.extensions.existsByContains
|
||||
import solutions.bitbadger.documents.java.extensions.existsByFields
|
||||
import solutions.bitbadger.documents.java.extensions.existsById
|
||||
import solutions.bitbadger.documents.java.extensions.existsByJsonPath
|
||||
import solutions.bitbadger.documents.java.integration.JsonDocument
|
||||
import solutions.bitbadger.documents.java.integration.TEST_TABLE
|
||||
import solutions.bitbadger.documents.java.integration.ThrowawayDatabase
|
||||
import solutions.bitbadger.documents.extensions.*
|
||||
import solutions.bitbadger.documents.support.*
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package solutions.bitbadger.documents.java.integration.common
|
||||
package solutions.bitbadger.documents.jvm.integration.common
|
||||
|
||||
import solutions.bitbadger.documents.Configuration
|
||||
import solutions.bitbadger.documents.Field
|
||||
import solutions.bitbadger.documents.FieldMatch
|
||||
import solutions.bitbadger.documents.common.*
|
||||
import solutions.bitbadger.documents.java.extensions.*
|
||||
import solutions.bitbadger.documents.java.integration.*
|
||||
import solutions.bitbadger.documents.extensions.*
|
||||
import solutions.bitbadger.documents.support.*
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertNull
|
||||
@@ -1,10 +1,8 @@
|
||||
package solutions.bitbadger.documents.java.integration.common
|
||||
package solutions.bitbadger.documents.jvm.integration.common
|
||||
|
||||
import solutions.bitbadger.documents.Field
|
||||
import solutions.bitbadger.documents.java.extensions.*
|
||||
import solutions.bitbadger.documents.java.integration.JsonDocument
|
||||
import solutions.bitbadger.documents.java.integration.TEST_TABLE
|
||||
import solutions.bitbadger.documents.java.integration.ThrowawayDatabase
|
||||
import solutions.bitbadger.documents.extensions.*
|
||||
import solutions.bitbadger.documents.support.*
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertNotNull
|
||||
@@ -1,10 +1,8 @@
|
||||
package solutions.bitbadger.documents.java.integration.common
|
||||
package solutions.bitbadger.documents.jvm.integration.common
|
||||
|
||||
import solutions.bitbadger.documents.Field
|
||||
import solutions.bitbadger.documents.java.extensions.*
|
||||
import solutions.bitbadger.documents.java.integration.JsonDocument
|
||||
import solutions.bitbadger.documents.java.integration.TEST_TABLE
|
||||
import solutions.bitbadger.documents.java.integration.ThrowawayDatabase
|
||||
import solutions.bitbadger.documents.extensions.*
|
||||
import solutions.bitbadger.documents.support.*
|
||||
import kotlin.test.*
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package solutions.bitbadger.documents.java.integration.postgresql
|
||||
package solutions.bitbadger.documents.jvm.integration.postgresql
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import solutions.bitbadger.documents.java.integration.common.Count
|
||||
import solutions.bitbadger.documents.jvm.integration.common.Count
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
@@ -1,7 +1,7 @@
|
||||
package solutions.bitbadger.documents.java.integration.postgresql
|
||||
package solutions.bitbadger.documents.jvm.integration.postgresql
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import solutions.bitbadger.documents.java.integration.common.Custom
|
||||
import solutions.bitbadger.documents.jvm.integration.common.Custom
|
||||
|
||||
import kotlin.test.Test
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package solutions.bitbadger.documents.java.integration.postgresql
|
||||
package solutions.bitbadger.documents.jvm.integration.postgresql
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import solutions.bitbadger.documents.java.integration.common.Definition
|
||||
import solutions.bitbadger.documents.jvm.integration.common.Definition
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
@@ -1,7 +1,7 @@
|
||||
package solutions.bitbadger.documents.java.integration.postgresql
|
||||
package solutions.bitbadger.documents.jvm.integration.postgresql
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import solutions.bitbadger.documents.java.integration.common.Delete
|
||||
import solutions.bitbadger.documents.jvm.integration.common.Delete
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
@@ -1,7 +1,7 @@
|
||||
package solutions.bitbadger.documents.java.integration.postgresql
|
||||
package solutions.bitbadger.documents.jvm.integration.postgresql
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import solutions.bitbadger.documents.java.integration.common.Document
|
||||
import solutions.bitbadger.documents.jvm.integration.common.Document
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
@@ -1,7 +1,7 @@
|
||||
package solutions.bitbadger.documents.java.integration.postgresql
|
||||
package solutions.bitbadger.documents.jvm.integration.postgresql
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import solutions.bitbadger.documents.java.integration.common.Exists
|
||||
import solutions.bitbadger.documents.jvm.integration.common.Exists
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
@@ -1,7 +1,7 @@
|
||||
package solutions.bitbadger.documents.java.integration.postgresql
|
||||
package solutions.bitbadger.documents.jvm.integration.postgresql
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import solutions.bitbadger.documents.java.integration.common.Find
|
||||
import solutions.bitbadger.documents.jvm.integration.common.Find
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
@@ -1,7 +1,7 @@
|
||||
package solutions.bitbadger.documents.java.integration.postgresql
|
||||
package solutions.bitbadger.documents.jvm.integration.postgresql
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import solutions.bitbadger.documents.java.integration.common.Patch
|
||||
import solutions.bitbadger.documents.jvm.integration.common.Patch
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
@@ -1,18 +1,11 @@
|
||||
package solutions.bitbadger.documents.java.integration.postgresql
|
||||
package solutions.bitbadger.documents.jvm.integration.postgresql
|
||||
|
||||
import AutoId
|
||||
import solutions.bitbadger.documents.Configuration
|
||||
import solutions.bitbadger.documents.Parameter
|
||||
import solutions.bitbadger.documents.ParameterType
|
||||
import solutions.bitbadger.documents.common.*
|
||||
import solutions.bitbadger.documents.java.*
|
||||
import solutions.bitbadger.documents.java.extensions.customNonQuery
|
||||
import solutions.bitbadger.documents.java.extensions.customScalar
|
||||
import solutions.bitbadger.documents.java.extensions.ensureTable
|
||||
import solutions.bitbadger.documents.java.integration.TEST_TABLE
|
||||
import solutions.bitbadger.documents.java.integration.ThrowawayDatabase
|
||||
import solutions.bitbadger.documents.java.jvm.DocumentConfig
|
||||
import solutions.bitbadger.documents.java.jvm.Results
|
||||
import solutions.bitbadger.documents.*
|
||||
import solutions.bitbadger.documents.extensions.customNonQuery
|
||||
import solutions.bitbadger.documents.extensions.customScalar
|
||||
import solutions.bitbadger.documents.extensions.ensureTable
|
||||
import solutions.bitbadger.documents.jvm.*
|
||||
import solutions.bitbadger.documents.support.*
|
||||
|
||||
/**
|
||||
* A wrapper for a throwaway PostgreSQL database
|
||||
@@ -1,7 +1,7 @@
|
||||
package solutions.bitbadger.documents.java.integration.postgresql
|
||||
package solutions.bitbadger.documents.jvm.integration.postgresql
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import solutions.bitbadger.documents.java.integration.common.RemoveFields
|
||||
import solutions.bitbadger.documents.jvm.integration.common.RemoveFields
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
@@ -1,9 +1,9 @@
|
||||
package solutions.bitbadger.documents.java.integration.sqlite
|
||||
package solutions.bitbadger.documents.jvm.integration.sqlite
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
import solutions.bitbadger.documents.java.integration.common.Count
|
||||
import solutions.bitbadger.documents.jvm.integration.common.Count
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
@@ -1,7 +1,7 @@
|
||||
package solutions.bitbadger.documents.java.integration.sqlite
|
||||
package solutions.bitbadger.documents.jvm.integration.sqlite
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import solutions.bitbadger.documents.java.integration.common.Custom
|
||||
import solutions.bitbadger.documents.jvm.integration.common.Custom
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
@@ -1,9 +1,9 @@
|
||||
package solutions.bitbadger.documents.java.integration.sqlite
|
||||
package solutions.bitbadger.documents.jvm.integration.sqlite
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
import solutions.bitbadger.documents.java.integration.common.Definition
|
||||
import solutions.bitbadger.documents.jvm.integration.common.Definition
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
@@ -1,9 +1,9 @@
|
||||
package solutions.bitbadger.documents.java.integration.sqlite
|
||||
package solutions.bitbadger.documents.jvm.integration.sqlite
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
import solutions.bitbadger.documents.java.integration.common.Delete
|
||||
import solutions.bitbadger.documents.jvm.integration.common.Delete
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
@@ -1,7 +1,7 @@
|
||||
package solutions.bitbadger.documents.java.integration.sqlite
|
||||
package solutions.bitbadger.documents.jvm.integration.sqlite
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import solutions.bitbadger.documents.java.integration.common.Document
|
||||
import solutions.bitbadger.documents.jvm.integration.common.Document
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
@@ -1,9 +1,9 @@
|
||||
package solutions.bitbadger.documents.java.integration.sqlite
|
||||
package solutions.bitbadger.documents.jvm.integration.sqlite
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
import solutions.bitbadger.documents.java.integration.common.Exists
|
||||
import solutions.bitbadger.documents.jvm.integration.common.Exists
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
@@ -1,9 +1,9 @@
|
||||
package solutions.bitbadger.documents.java.integration.sqlite
|
||||
package solutions.bitbadger.documents.jvm.integration.sqlite
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
import solutions.bitbadger.documents.java.integration.common.Find
|
||||
import solutions.bitbadger.documents.jvm.integration.common.Find
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
@@ -1,9 +1,9 @@
|
||||
package solutions.bitbadger.documents.java.integration.sqlite
|
||||
package solutions.bitbadger.documents.jvm.integration.sqlite
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
import solutions.bitbadger.documents.java.integration.common.Patch
|
||||
import solutions.bitbadger.documents.jvm.integration.common.Patch
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
@@ -1,9 +1,9 @@
|
||||
package solutions.bitbadger.documents.java.integration.sqlite
|
||||
package solutions.bitbadger.documents.jvm.integration.sqlite
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
import solutions.bitbadger.documents.java.integration.common.RemoveFields
|
||||
import solutions.bitbadger.documents.jvm.integration.common.RemoveFields
|
||||
import kotlin.test.Test
|
||||
|
||||
/**
|
||||
@@ -1,17 +1,10 @@
|
||||
package solutions.bitbadger.documents.java.integration.sqlite
|
||||
package solutions.bitbadger.documents.jvm.integration.sqlite
|
||||
|
||||
import AutoId
|
||||
import solutions.bitbadger.documents.Configuration
|
||||
import solutions.bitbadger.documents.Parameter
|
||||
import solutions.bitbadger.documents.ParameterType
|
||||
import solutions.bitbadger.documents.common.*
|
||||
import solutions.bitbadger.documents.java.*
|
||||
import solutions.bitbadger.documents.java.extensions.customScalar
|
||||
import solutions.bitbadger.documents.java.extensions.ensureTable
|
||||
import solutions.bitbadger.documents.java.integration.TEST_TABLE
|
||||
import solutions.bitbadger.documents.java.integration.ThrowawayDatabase
|
||||
import solutions.bitbadger.documents.java.jvm.DocumentConfig
|
||||
import solutions.bitbadger.documents.java.jvm.Results
|
||||
import solutions.bitbadger.documents.*
|
||||
import solutions.bitbadger.documents.extensions.customScalar
|
||||
import solutions.bitbadger.documents.extensions.ensureTable
|
||||
import solutions.bitbadger.documents.jvm.*
|
||||
import solutions.bitbadger.documents.support.*
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
90
src/jvm/src/test/kotlin/query/CountTest.kt
Normal file
90
src/jvm/src/test/kotlin/query/CountTest.kt
Normal file
@@ -0,0 +1,90 @@
|
||||
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.Configuration
|
||||
import solutions.bitbadger.documents.Dialect
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
import solutions.bitbadger.documents.Field
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
/**
|
||||
* Unit tests for the `Count` object
|
||||
*/
|
||||
@DisplayName("Kotlin | Common | Query: Count")
|
||||
class CountTest {
|
||||
|
||||
/** Test table name */
|
||||
private val tbl = "test_table"
|
||||
|
||||
/**
|
||||
* Clear the connection string (resets Dialect)
|
||||
*/
|
||||
@AfterEach
|
||||
fun cleanUp() {
|
||||
Configuration.dialectValue = null
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("all generates correctly")
|
||||
fun all() =
|
||||
assertEquals("SELECT COUNT(*) AS it FROM $tbl", Count.all(tbl), "Count query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly (PostgreSQL)")
|
||||
fun byFieldsPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"SELECT COUNT(*) AS it FROM $tbl WHERE data->>'test' = :field0",
|
||||
Count.byFields(tbl, listOf(Field.equal("test", "", ":field0"))),
|
||||
"Count query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly (PostgreSQL)")
|
||||
fun byFieldsSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals(
|
||||
"SELECT COUNT(*) AS it FROM $tbl WHERE data->>'test' = :field0",
|
||||
Count.byFields(tbl, listOf(Field.equal("test", "", ":field0"))),
|
||||
"Count query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains generates correctly (PostgreSQL)")
|
||||
fun byContainsPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"SELECT COUNT(*) AS it FROM $tbl WHERE data @> :criteria", Count.byContains(tbl),
|
||||
"Count query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains fails (SQLite)")
|
||||
fun byContainsSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertThrows<DocumentException> { Count.byContains(tbl) }
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath generates correctly (PostgreSQL)")
|
||||
fun byJsonPathPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"SELECT COUNT(*) AS it FROM $tbl WHERE jsonb_path_exists(data, :path::jsonpath)",
|
||||
Count.byJsonPath(tbl), "Count query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath fails (SQLite)")
|
||||
fun byJsonPathSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertThrows<DocumentException> { Count.byJsonPath(tbl) }
|
||||
}
|
||||
}
|
||||
134
src/jvm/src/test/kotlin/query/DefinitionTest.kt
Normal file
134
src/jvm/src/test/kotlin/query/DefinitionTest.kt
Normal file
@@ -0,0 +1,134 @@
|
||||
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.Configuration
|
||||
import solutions.bitbadger.documents.Dialect
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
import solutions.bitbadger.documents.DocumentIndex
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
/**
|
||||
* Unit tests for the `Definition` object
|
||||
*/
|
||||
@DisplayName("Kotlin | Common | Query: Definition")
|
||||
class DefinitionTest {
|
||||
|
||||
/** Test table name */
|
||||
private val tbl = "test_table"
|
||||
|
||||
/**
|
||||
* Clear the connection string (resets Dialect)
|
||||
*/
|
||||
@AfterEach
|
||||
fun cleanUp() {
|
||||
Configuration.dialectValue = null
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureTableFor generates correctly")
|
||||
fun ensureTableFor() =
|
||||
assertEquals(
|
||||
"CREATE TABLE IF NOT EXISTS my.table (data JSONB NOT NULL)",
|
||||
Definition.ensureTableFor("my.table", "JSONB"), "CREATE TABLE statement not constructed correctly"
|
||||
)
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureTable generates correctly (PostgreSQL)")
|
||||
fun ensureTablePostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("CREATE TABLE IF NOT EXISTS $tbl (data JSONB NOT NULL)", Definition.ensureTable(tbl))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureTable generates correctly (SQLite)")
|
||||
fun ensureTableSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals("CREATE TABLE IF NOT EXISTS $tbl (data TEXT NOT NULL)", Definition.ensureTable(tbl))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureTable fails when no dialect is set")
|
||||
fun ensureTableFailsUnknown() {
|
||||
assertThrows<DocumentException> { Definition.ensureTable(tbl) }
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureKey generates correctly with schema")
|
||||
fun ensureKeyWithSchema() =
|
||||
assertEquals(
|
||||
"CREATE UNIQUE INDEX IF NOT EXISTS idx_table_key ON test.table ((data->>'id'))",
|
||||
Definition.ensureKey("test.table", Dialect.POSTGRESQL),
|
||||
"CREATE INDEX for key statement with schema not constructed correctly"
|
||||
)
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureKey generates correctly without schema")
|
||||
fun ensureKeyWithoutSchema() =
|
||||
assertEquals(
|
||||
"CREATE UNIQUE INDEX IF NOT EXISTS idx_${tbl}_key ON $tbl ((data->>'id'))",
|
||||
Definition.ensureKey(tbl, Dialect.SQLITE),
|
||||
"CREATE INDEX for key statement without schema not constructed correctly"
|
||||
)
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureIndexOn generates multiple fields and directions")
|
||||
fun ensureIndexOnMultipleFields() =
|
||||
assertEquals(
|
||||
"CREATE INDEX IF NOT EXISTS idx_table_gibberish ON test.table ((data->>'taco'), (data->>'guac') DESC, (data->>'salsa') ASC)",
|
||||
Definition.ensureIndexOn(
|
||||
"test.table", "gibberish", listOf("taco", "guac DESC", "salsa ASC"),
|
||||
Dialect.POSTGRESQL
|
||||
),
|
||||
"CREATE INDEX for multiple field statement not constructed correctly"
|
||||
)
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureIndexOn generates nested PostgreSQL field")
|
||||
fun ensureIndexOnNestedPostgres() =
|
||||
assertEquals(
|
||||
"CREATE INDEX IF NOT EXISTS idx_${tbl}_nest ON $tbl ((data#>>'{a,b,c}'))",
|
||||
Definition.ensureIndexOn(tbl, "nest", listOf("a.b.c"), Dialect.POSTGRESQL),
|
||||
"CREATE INDEX for nested PostgreSQL field incorrect"
|
||||
)
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureIndexOn generates nested SQLite field")
|
||||
fun ensureIndexOnNestedSQLite() =
|
||||
assertEquals(
|
||||
"CREATE INDEX IF NOT EXISTS idx_${tbl}_nest ON $tbl ((data->'a'->'b'->>'c'))",
|
||||
Definition.ensureIndexOn(tbl, "nest", listOf("a.b.c"), Dialect.SQLITE),
|
||||
"CREATE INDEX for nested SQLite field incorrect"
|
||||
)
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureDocumentIndexOn generates Full for PostgreSQL")
|
||||
fun ensureDocumentIndexOnFullPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"CREATE INDEX IF NOT EXISTS idx_${tbl}_document ON $tbl USING GIN (data)",
|
||||
Definition.ensureDocumentIndexOn(tbl, DocumentIndex.FULL),
|
||||
"CREATE INDEX for full document index incorrect"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureDocumentIndexOn generates Optimized for PostgreSQL")
|
||||
fun ensureDocumentIndexOnOptimizedPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"CREATE INDEX IF NOT EXISTS idx_${tbl}_document ON $tbl USING GIN (data jsonb_path_ops)",
|
||||
Definition.ensureDocumentIndexOn(tbl, DocumentIndex.OPTIMIZED),
|
||||
"CREATE INDEX for optimized document index incorrect"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("ensureDocumentIndexOn fails for SQLite")
|
||||
fun ensureDocumentIndexOnFailsSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertThrows<DocumentException> { Definition.ensureDocumentIndexOn(tbl, DocumentIndex.FULL) }
|
||||
}
|
||||
}
|
||||
102
src/jvm/src/test/kotlin/query/DeleteTest.kt
Normal file
102
src/jvm/src/test/kotlin/query/DeleteTest.kt
Normal file
@@ -0,0 +1,102 @@
|
||||
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.Configuration
|
||||
import solutions.bitbadger.documents.Dialect
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
import solutions.bitbadger.documents.Field
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
/**
|
||||
* Unit tests for the `Delete` object
|
||||
*/
|
||||
@DisplayName("Kotlin | Common | Query: Delete")
|
||||
class DeleteTest {
|
||||
|
||||
/** Test table name */
|
||||
private val tbl = "test_table"
|
||||
|
||||
/**
|
||||
* Clear the connection string (resets Dialect)
|
||||
*/
|
||||
@AfterEach
|
||||
fun cleanUp() {
|
||||
Configuration.dialectValue = null
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates correctly (PostgreSQL)")
|
||||
fun byIdPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"DELETE FROM $tbl WHERE data->>'id' = :id",
|
||||
Delete.byId<String>(tbl), "Delete query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates correctly (SQLite)")
|
||||
fun byIdSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals(
|
||||
"DELETE FROM $tbl WHERE data->>'id' = :id",
|
||||
Delete.byId<String>(tbl), "Delete query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly (PostgreSQL)")
|
||||
fun byFieldsPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"DELETE FROM $tbl WHERE data->>'a' = :b", Delete.byFields(tbl, listOf(Field.equal("a", "", ":b"))),
|
||||
"Delete query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly (SQLite)")
|
||||
fun byFieldsSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals(
|
||||
"DELETE FROM $tbl WHERE data->>'a' = :b", Delete.byFields(tbl, listOf(Field.equal("a", "", ":b"))),
|
||||
"Delete query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains generates correctly (PostgreSQL)")
|
||||
fun byContainsPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"DELETE FROM $tbl WHERE data @> :criteria", Delete.byContains(tbl), "Delete query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains fails (SQLite)")
|
||||
fun byContainsSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertThrows<DocumentException> { Delete.byContains(tbl) }
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath generates correctly (PostgreSQL)")
|
||||
fun byJsonPathPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"DELETE FROM $tbl WHERE jsonb_path_exists(data, :path::jsonpath)", Delete.byJsonPath(tbl),
|
||||
"Delete query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath fails (SQLite)")
|
||||
fun byJsonPathSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertThrows<DocumentException> { Delete.byJsonPath(tbl) }
|
||||
}
|
||||
}
|
||||
150
src/jvm/src/test/kotlin/query/DocumentTest.kt
Normal file
150
src/jvm/src/test/kotlin/query/DocumentTest.kt
Normal file
@@ -0,0 +1,150 @@
|
||||
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.Dialect
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
/**
|
||||
* Unit tests for the `Document` object
|
||||
*/
|
||||
@DisplayName("Kotlin | Common | Query: Document")
|
||||
class DocumentTest {
|
||||
|
||||
/** Test table name */
|
||||
private val tbl = "test_table"
|
||||
|
||||
/**
|
||||
* Clear the connection string (resets Dialect)
|
||||
*/
|
||||
@AfterEach
|
||||
fun cleanUp() {
|
||||
Configuration.dialectValue = null
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("insert generates no auto ID (PostgreSQL)")
|
||||
fun insertNoAutoPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("INSERT INTO $tbl VALUES (:data)", Document.insert(tbl))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("insert generates no auto ID (SQLite)")
|
||||
fun insertNoAutoSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals("INSERT INTO $tbl VALUES (:data)", Document.insert(tbl))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("insert generates auto number (PostgreSQL)")
|
||||
fun insertAutoNumberPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"INSERT INTO $tbl VALUES (:data::jsonb || ('{\"id\":' " +
|
||||
"|| (SELECT COALESCE(MAX((data->>'id')::numeric), 0) + 1 FROM $tbl) || '}')::jsonb)",
|
||||
Document.insert(tbl, AutoId.NUMBER)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("insert generates auto number (SQLite)")
|
||||
fun insertAutoNumberSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals(
|
||||
"INSERT INTO $tbl VALUES (json_set(:data, '$.id', " +
|
||||
"(SELECT coalesce(max(data->>'id'), 0) + 1 FROM $tbl)))",
|
||||
Document.insert(tbl, AutoId.NUMBER)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("insert generates auto UUID (PostgreSQL)")
|
||||
fun insertAutoUUIDPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
val query = Document.insert(tbl, AutoId.UUID)
|
||||
assertTrue(
|
||||
query.startsWith("INSERT INTO $tbl 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() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
val query = Document.insert(tbl, AutoId.UUID)
|
||||
assertTrue(
|
||||
query.startsWith("INSERT INTO $tbl 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 {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
Configuration.idStringLength = 8
|
||||
val query = Document.insert(tbl, AutoId.RANDOM_STRING)
|
||||
assertTrue(
|
||||
query.startsWith("INSERT INTO $tbl VALUES (:data::jsonb || '{\"id\":\""),
|
||||
"Query start not correct (actual: $query)"
|
||||
)
|
||||
assertTrue(query.endsWith("\"}')"), "Query end not correct")
|
||||
assertEquals(
|
||||
8,
|
||||
query.replace("INSERT INTO $tbl VALUES (:data::jsonb || '{\"id\":\"", "").replace("\"}')", "").length,
|
||||
"Random string length incorrect"
|
||||
)
|
||||
} finally {
|
||||
Configuration.idStringLength = 16
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("insert generates auto random string (SQLite)")
|
||||
fun insertAutoRandomSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
val query = Document.insert(tbl, AutoId.RANDOM_STRING)
|
||||
assertTrue(
|
||||
query.startsWith("INSERT INTO $tbl 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 $tbl VALUES (json_set(:data, '$.id', '", "").replace("'))", "").length,
|
||||
"Random string length incorrect"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("insert fails when no dialect is set")
|
||||
fun insertFailsUnknown() {
|
||||
assertThrows<DocumentException> { Document.insert(tbl) }
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("save generates correctly")
|
||||
fun save() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"INSERT INTO $tbl VALUES (:data) ON CONFLICT ((data->>'id')) DO UPDATE SET data = EXCLUDED.data",
|
||||
Document.save(tbl), "INSERT ON CONFLICT UPDATE statement not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("update generates successfully")
|
||||
fun update() =
|
||||
assertEquals("UPDATE $tbl SET data = :data", Document.update(tbl), "Update query not constructed correctly")
|
||||
}
|
||||
105
src/jvm/src/test/kotlin/query/ExistsTest.kt
Normal file
105
src/jvm/src/test/kotlin/query/ExistsTest.kt
Normal file
@@ -0,0 +1,105 @@
|
||||
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.Configuration
|
||||
import solutions.bitbadger.documents.Dialect
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
import solutions.bitbadger.documents.Field
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
/**
|
||||
* Unit tests for the `Exists` object
|
||||
*/
|
||||
@DisplayName("Kotlin | Common | Query: Exists")
|
||||
class ExistsTest {
|
||||
|
||||
/** Test table name */
|
||||
private val tbl = "test_table"
|
||||
|
||||
/**
|
||||
* Clear the connection string (resets Dialect)
|
||||
*/
|
||||
@AfterEach
|
||||
fun cleanUp() {
|
||||
Configuration.dialectValue = null
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates correctly (PostgreSQL)")
|
||||
fun byIdPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE data->>'id' = :id) AS it",
|
||||
Exists.byId<String>(tbl), "Exists query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates correctly (SQLite)")
|
||||
fun byIdSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals(
|
||||
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE data->>'id' = :id) AS it",
|
||||
Exists.byId<String>(tbl), "Exists query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly (PostgreSQL)")
|
||||
fun byFieldsPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE (data->>'it')::numeric = :test) AS it",
|
||||
Exists.byFields(tbl, listOf(Field.equal("it", 7, ":test"))),
|
||||
"Exists query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly (SQLite)")
|
||||
fun byFieldsSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals(
|
||||
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE data->>'it' = :test) AS it",
|
||||
Exists.byFields(tbl, listOf(Field.equal("it", 7, ":test"))),
|
||||
"Exists query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains generates correctly (PostgreSQL)")
|
||||
fun byContainsPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE data @> :criteria) AS it", Exists.byContains(tbl),
|
||||
"Exists query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains fails (SQLite)")
|
||||
fun byContainsSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertThrows<DocumentException> { Exists.byContains(tbl) }
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath generates correctly (PostgreSQL)")
|
||||
fun byJsonPathPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"SELECT EXISTS (SELECT 1 FROM $tbl WHERE jsonb_path_exists(data, :path::jsonpath)) AS it",
|
||||
Exists.byJsonPath(tbl), "Exists query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath fails (SQLite)")
|
||||
fun byJsonPathSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertThrows<DocumentException> { Exists.byJsonPath(tbl) }
|
||||
}
|
||||
}
|
||||
110
src/jvm/src/test/kotlin/query/FindTest.kt
Normal file
110
src/jvm/src/test/kotlin/query/FindTest.kt
Normal file
@@ -0,0 +1,110 @@
|
||||
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.Configuration
|
||||
import solutions.bitbadger.documents.Dialect
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
import solutions.bitbadger.documents.Field
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
/**
|
||||
* Unit tests for the `Find` object
|
||||
*/
|
||||
@DisplayName("Kotlin | Common | Query: Find")
|
||||
class FindTest {
|
||||
|
||||
/** Test table name */
|
||||
private val tbl = "test_table"
|
||||
|
||||
/**
|
||||
* Clear the connection string (resets Dialect)
|
||||
*/
|
||||
@AfterEach
|
||||
fun cleanUp() {
|
||||
Configuration.dialectValue = null
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("all generates correctly")
|
||||
fun all() =
|
||||
assertEquals("SELECT data FROM $tbl", Find.all(tbl), "Find query not constructed correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates correctly (PostgreSQL)")
|
||||
fun byIdPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"SELECT data FROM $tbl WHERE data->>'id' = :id",
|
||||
Find.byId<String>(tbl), "Find query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates correctly (SQLite)")
|
||||
fun byIdSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals(
|
||||
"SELECT data FROM $tbl WHERE data->>'id' = :id",
|
||||
Find.byId<String>(tbl), "Find query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly (PostgreSQL)")
|
||||
fun byFieldsPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"SELECT data FROM $tbl WHERE data->>'a' = :b AND (data->>'c')::numeric < :d",
|
||||
Find.byFields(tbl, listOf(Field.equal("a", "", ":b"), Field.less("c", 14, ":d"))),
|
||||
"Find query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly (SQLite)")
|
||||
fun byFieldsSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals(
|
||||
"SELECT data FROM $tbl WHERE data->>'a' = :b AND data->>'c' < :d",
|
||||
Find.byFields(tbl, listOf(Field.equal("a", "", ":b"), Field.less("c", 14, ":d"))),
|
||||
"Find query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains generates correctly (PostgreSQL)")
|
||||
fun byContainsPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"SELECT data FROM $tbl WHERE data @> :criteria", Find.byContains(tbl),
|
||||
"Find query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains fails (SQLite)")
|
||||
fun byContainsSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertThrows<DocumentException> { Find.byContains(tbl) }
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath generates correctly (PostgreSQL)")
|
||||
fun byJsonPathPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"SELECT data FROM $tbl WHERE jsonb_path_exists(data, :path::jsonpath)", Find.byJsonPath(tbl),
|
||||
"Find query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath fails (SQLite)")
|
||||
fun byJsonPathSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertThrows<DocumentException> { Find.byJsonPath(tbl) }
|
||||
}
|
||||
}
|
||||
105
src/jvm/src/test/kotlin/query/PatchTest.kt
Normal file
105
src/jvm/src/test/kotlin/query/PatchTest.kt
Normal file
@@ -0,0 +1,105 @@
|
||||
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.Configuration
|
||||
import solutions.bitbadger.documents.Dialect
|
||||
import solutions.bitbadger.documents.DocumentException
|
||||
import solutions.bitbadger.documents.Field
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
/**
|
||||
* Unit tests for the `Patch` object
|
||||
*/
|
||||
@DisplayName("Kotlin | Common | Query: Patch")
|
||||
class PatchTest {
|
||||
|
||||
/** Test table name */
|
||||
private val tbl = "test_table"
|
||||
|
||||
/**
|
||||
* Reset the dialect
|
||||
*/
|
||||
@AfterEach
|
||||
fun cleanUp() {
|
||||
Configuration.dialectValue = null
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates correctly (PostgreSQL)")
|
||||
fun byIdPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"UPDATE $tbl SET data = data || :data WHERE data->>'id' = :id",
|
||||
Patch.byId<String>(tbl), "Patch query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates correctly (SQLite)")
|
||||
fun byIdSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals(
|
||||
"UPDATE $tbl SET data = json_patch(data, json(:data)) WHERE data->>'id' = :id",
|
||||
Patch.byId<String>(tbl), "Patch query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly (PostgreSQL)")
|
||||
fun byFieldsPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"UPDATE $tbl SET data = data || :data WHERE data->>'z' = :y",
|
||||
Patch.byFields(tbl, listOf(Field.equal("z", "", ":y"))),
|
||||
"Patch query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly (SQLite)")
|
||||
fun byFieldsSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals(
|
||||
"UPDATE $tbl SET data = json_patch(data, json(:data)) WHERE data->>'z' = :y",
|
||||
Patch.byFields(tbl, listOf(Field.equal("z", "", ":y"))),
|
||||
"Patch query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains generates correctly (PostgreSQL)")
|
||||
fun byContainsPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"UPDATE $tbl SET data = data || :data WHERE data @> :criteria", Patch.byContains(tbl),
|
||||
"Patch query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains fails (SQLite)")
|
||||
fun byContainsSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertThrows<DocumentException> { Patch.byContains(tbl) }
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath generates correctly (PostgreSQL)")
|
||||
fun byJsonPathPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"UPDATE $tbl SET data = data || :data WHERE jsonb_path_exists(data, :path::jsonpath)",
|
||||
Patch.byJsonPath(tbl), "Patch query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath fails (SQLite)")
|
||||
fun byJsonPathSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertThrows<DocumentException> { Patch.byJsonPath(tbl) }
|
||||
}
|
||||
}
|
||||
178
src/jvm/src/test/kotlin/query/QueryTest.kt
Normal file
178
src/jvm/src/test/kotlin/query/QueryTest.kt
Normal file
@@ -0,0 +1,178 @@
|
||||
package solutions.bitbadger.documents.query
|
||||
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
import solutions.bitbadger.documents.Configuration
|
||||
import solutions.bitbadger.documents.Dialect
|
||||
import solutions.bitbadger.documents.Field
|
||||
import solutions.bitbadger.documents.FieldMatch
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
/**
|
||||
* Unit tests for the top-level query functions
|
||||
*/
|
||||
@DisplayName("Kotlin | Common | Query")
|
||||
class QueryTest {
|
||||
|
||||
/**
|
||||
* Clear the connection string (resets Dialect)
|
||||
*/
|
||||
@AfterEach
|
||||
fun cleanUp() {
|
||||
Configuration.dialectValue = null
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("statementWhere generates correctly")
|
||||
fun statementWhere() =
|
||||
assertEquals("x WHERE y", statementWhere("x", "y"), "Statements not combined correctly")
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates a numeric ID query (PostgreSQL)")
|
||||
fun byIdNumericPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("test WHERE (data->>'id')::numeric = :id", byId("test", 9))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates an alphanumeric ID query (PostgreSQL)")
|
||||
fun byIdAlphaPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("unit WHERE data->>'id' = :id", byId("unit", "18"))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates ID query (SQLite)")
|
||||
fun byIdSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals("yo WHERE data->>'id' = :id", byId("yo", 27))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates default field query (PostgreSQL)")
|
||||
fun byFieldsMultipleDefaultPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"this WHERE data->>'a' = :the_a AND (data->>'b')::numeric = :b_value",
|
||||
byFields("this", listOf(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value")))
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates default field query (SQLite)")
|
||||
fun byFieldsMultipleDefaultSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals(
|
||||
"this WHERE data->>'a' = :the_a AND data->>'b' = :b_value",
|
||||
byFields("this", listOf(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value")))
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates ANY field query (PostgreSQL)")
|
||||
fun byFieldsMultipleAnyPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"that WHERE data->>'a' = :the_a OR (data->>'b')::numeric = :b_value",
|
||||
byFields(
|
||||
"that", listOf(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value")),
|
||||
FieldMatch.ANY
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates ANY field query (SQLite)")
|
||||
fun byFieldsMultipleAnySQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals(
|
||||
"that WHERE data->>'a' = :the_a OR data->>'b' = :b_value",
|
||||
byFields(
|
||||
"that", listOf(Field.equal("a", "", ":the_a"), Field.equal("b", 0, ":b_value")),
|
||||
FieldMatch.ANY
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("orderBy generates for no fields")
|
||||
fun orderByNone() {
|
||||
assertEquals("", orderBy(listOf(), Dialect.POSTGRESQL), "ORDER BY should have been blank (PostgreSQL)")
|
||||
assertEquals("", orderBy(listOf(), Dialect.SQLITE), "ORDER BY should have been blank (SQLite)")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("orderBy generates single, no direction for PostgreSQL")
|
||||
fun orderBySinglePostgres() =
|
||||
assertEquals(
|
||||
" ORDER BY data->>'TestField'",
|
||||
orderBy(listOf(Field.named("TestField")), Dialect.POSTGRESQL), "ORDER BY not constructed correctly"
|
||||
)
|
||||
|
||||
@Test
|
||||
@DisplayName("orderBy generates single, no direction for SQLite")
|
||||
fun orderBySingleSQLite() =
|
||||
assertEquals(
|
||||
" ORDER BY data->>'TestField'", orderBy(listOf(Field.named("TestField")), Dialect.SQLITE),
|
||||
"ORDER BY not constructed correctly"
|
||||
)
|
||||
|
||||
@Test
|
||||
@DisplayName("orderBy generates multiple with direction for PostgreSQL")
|
||||
fun orderByMultiplePostgres() =
|
||||
assertEquals(
|
||||
" ORDER BY data#>>'{Nested,Test,Field}' DESC, data->>'AnotherField', data->>'It' DESC",
|
||||
orderBy(
|
||||
listOf(Field.named("Nested.Test.Field DESC"), Field.named("AnotherField"), Field.named("It DESC")),
|
||||
Dialect.POSTGRESQL
|
||||
),
|
||||
"ORDER BY not constructed correctly"
|
||||
)
|
||||
|
||||
@Test
|
||||
@DisplayName("orderBy generates multiple with direction for SQLite")
|
||||
fun orderByMultipleSQLite() =
|
||||
assertEquals(
|
||||
" ORDER BY data->'Nested'->'Test'->>'Field' DESC, data->>'AnotherField', data->>'It' DESC",
|
||||
orderBy(
|
||||
listOf(Field.named("Nested.Test.Field DESC"), Field.named("AnotherField"), Field.named("It DESC")),
|
||||
Dialect.SQLITE
|
||||
),
|
||||
"ORDER BY not constructed correctly"
|
||||
)
|
||||
|
||||
@Test
|
||||
@DisplayName("orderBy generates numeric ordering PostgreSQL")
|
||||
fun orderByNumericPostgres() =
|
||||
assertEquals(
|
||||
" ORDER BY (data->>'Test')::numeric",
|
||||
orderBy(listOf(Field.named("n:Test")), Dialect.POSTGRESQL), "ORDER BY not constructed correctly"
|
||||
)
|
||||
|
||||
@Test
|
||||
@DisplayName("orderBy generates numeric ordering for SQLite")
|
||||
fun orderByNumericSQLite() =
|
||||
assertEquals(
|
||||
" ORDER BY data->>'Test'", orderBy(listOf(Field.named("n:Test")), Dialect.SQLITE),
|
||||
"ORDER BY not constructed correctly"
|
||||
)
|
||||
|
||||
@Test
|
||||
@DisplayName("orderBy generates case-insensitive ordering for PostgreSQL")
|
||||
fun orderByCIPostgres() =
|
||||
assertEquals(
|
||||
" ORDER BY LOWER(data#>>'{Test,Field}') DESC NULLS FIRST",
|
||||
orderBy(listOf(Field.named("i:Test.Field DESC NULLS FIRST")), Dialect.POSTGRESQL),
|
||||
"ORDER BY not constructed correctly"
|
||||
)
|
||||
|
||||
@Test
|
||||
@DisplayName("orderBy generates case-insensitive ordering for SQLite")
|
||||
fun orderByCISQLite() =
|
||||
assertEquals(
|
||||
" ORDER BY data->'Test'->>'Field' COLLATE NOCASE ASC NULLS LAST",
|
||||
orderBy(listOf(Field.named("i:Test.Field ASC NULLS LAST")), Dialect.SQLITE),
|
||||
"ORDER BY not constructed correctly"
|
||||
)
|
||||
}
|
||||
120
src/jvm/src/test/kotlin/query/RemoveFieldsTest.kt
Normal file
120
src/jvm/src/test/kotlin/query/RemoveFieldsTest.kt
Normal file
@@ -0,0 +1,120 @@
|
||||
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.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
/**
|
||||
* Unit tests for the `RemoveFields` object
|
||||
*/
|
||||
@DisplayName("Kotlin | Common | Query: RemoveFields")
|
||||
class RemoveFieldsTest {
|
||||
|
||||
/** Test table name */
|
||||
private val tbl = "test_table"
|
||||
|
||||
/**
|
||||
* Reset the dialect
|
||||
*/
|
||||
@AfterEach
|
||||
fun cleanUp() {
|
||||
Configuration.dialectValue = null
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates correctly (PostgreSQL)")
|
||||
fun byIdPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"UPDATE $tbl SET data = data - :name::text[] WHERE data->>'id' = :id",
|
||||
RemoveFields.byId<String>(tbl, listOf(Parameter(":name", ParameterType.STRING, "{a,z}"))),
|
||||
"Remove Fields query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates correctly (SQLite)")
|
||||
fun byIdSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals(
|
||||
"UPDATE $tbl SET data = json_remove(data, :name0, :name1) WHERE data->>'id' = :id",
|
||||
RemoveFields.byId<String>(
|
||||
tbl,
|
||||
listOf(
|
||||
Parameter(":name0", ParameterType.STRING, "a"),
|
||||
Parameter(":name1", ParameterType.STRING, "z")
|
||||
)
|
||||
),
|
||||
"Remove Field query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly (PostgreSQL)")
|
||||
fun byFieldsPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"UPDATE $tbl SET data = data - :name::text[] WHERE data->>'f' > :g",
|
||||
RemoveFields.byFields(
|
||||
tbl,
|
||||
listOf(Parameter(":name", ParameterType.STRING, "{b,c}")),
|
||||
listOf(Field.greater("f", "", ":g"))
|
||||
),
|
||||
"Remove Field query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates correctly (SQLite)")
|
||||
fun byFieldsSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals(
|
||||
"UPDATE $tbl SET data = json_remove(data, :name0, :name1) WHERE data->>'f' > :g",
|
||||
RemoveFields.byFields(
|
||||
tbl,
|
||||
listOf(Parameter(":name0", ParameterType.STRING, "b"), Parameter(":name1", ParameterType.STRING, "c")),
|
||||
listOf(Field.greater("f", "", ":g"))
|
||||
),
|
||||
"Remove Field query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains generates correctly (PostgreSQL)")
|
||||
fun byContainsPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"UPDATE $tbl SET data = data - :name::text[] WHERE data @> :criteria",
|
||||
RemoveFields.byContains(tbl, listOf(Parameter(":name", ParameterType.STRING, "{m,n}"))),
|
||||
"Remove Field query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byContains fails (SQLite)")
|
||||
fun byContainsSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertThrows<DocumentException> { RemoveFields.byContains(tbl, listOf()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath generates correctly (PostgreSQL)")
|
||||
fun byJsonPathPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"UPDATE $tbl SET data = data - :name::text[] WHERE jsonb_path_exists(data, :path::jsonpath)",
|
||||
RemoveFields.byJsonPath(tbl, listOf(Parameter(":name", ParameterType.STRING, "{o,p}"))),
|
||||
"Remove Field query not constructed correctly"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byJsonPath fails (SQLite)")
|
||||
fun byJsonPathSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertThrows<DocumentException> { RemoveFields.byJsonPath(tbl, listOf()) }
|
||||
}
|
||||
}
|
||||
176
src/jvm/src/test/kotlin/query/WhereTest.kt
Normal file
176
src/jvm/src/test/kotlin/query/WhereTest.kt
Normal file
@@ -0,0 +1,176 @@
|
||||
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.*
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
/**
|
||||
* Unit tests for the `Where` object
|
||||
*/
|
||||
@DisplayName("Kotlin | Common | Query: Where")
|
||||
class WhereTest {
|
||||
|
||||
/**
|
||||
* Clear the connection string (resets Dialect)
|
||||
*/
|
||||
@AfterEach
|
||||
fun cleanUp() {
|
||||
Configuration.dialectValue = null
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields is blank when given no fields")
|
||||
fun byFieldsBlankIfEmpty() =
|
||||
assertEquals("", Where.byFields(listOf()))
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates one numeric field (PostgreSQL)")
|
||||
fun byFieldsOneFieldPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("(data->>'it')::numeric = :that", Where.byFields(listOf(Field.equal("it", 9, ":that"))))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates one alphanumeric field (PostgreSQL)")
|
||||
fun byFieldsOneAlphaFieldPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("data->>'it' = :that", Where.byFields(listOf(Field.equal("it", "", ":that"))))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates one field (SQLite)")
|
||||
fun byFieldsOneFieldSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals("data->>'it' = :that", Where.byFields(listOf(Field.equal("it", "", ":that"))))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates multiple fields w/ default match (PostgreSQL)")
|
||||
fun byFieldsMultipleDefaultPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"data->>'1' = :one AND (data->>'2')::numeric = :two AND data->>'3' = :three",
|
||||
Where.byFields(
|
||||
listOf(Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three"))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates multiple fields w/ default match (SQLite)")
|
||||
fun byFieldsMultipleDefaultSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals(
|
||||
"data->>'1' = :one AND data->>'2' = :two AND data->>'3' = :three",
|
||||
Where.byFields(
|
||||
listOf(Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three"))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates multiple fields w/ ANY match (PostgreSQL)")
|
||||
fun byFieldsMultipleAnyPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals(
|
||||
"data->>'1' = :one OR (data->>'2')::numeric = :two OR data->>'3' = :three",
|
||||
Where.byFields(
|
||||
listOf(Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three")),
|
||||
FieldMatch.ANY
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byFields generates multiple fields w/ ANY match (SQLite)")
|
||||
fun byFieldsMultipleAnySQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals(
|
||||
"data->>'1' = :one OR data->>'2' = :two OR data->>'3' = :three",
|
||||
Where.byFields(
|
||||
listOf(Field.equal("1", "", ":one"), Field.equal("2", 0L, ":two"), Field.equal("3", "", ":three")),
|
||||
FieldMatch.ANY
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates defaults for alphanumeric key (PostgreSQL)")
|
||||
fun byIdDefaultAlphaPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("data->>'id' = :id", Where.byId(docId = ""))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates defaults for numeric key (PostgreSQL)")
|
||||
fun byIdDefaultNumericPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("(data->>'id')::numeric = :id", Where.byId(docId = 5))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates defaults (SQLite)")
|
||||
fun byIdDefaultSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals("data->>'id' = :id", Where.byId(docId = ""))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates named ID (PostgreSQL)")
|
||||
fun byIdDefaultNamedPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("data->>'id' = :key", Where.byId<String>(":key"))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("byId generates named ID (SQLite)")
|
||||
fun byIdDefaultNamedSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertEquals("data->>'id' = :key", Where.byId<String>(":key"))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("jsonContains generates defaults (PostgreSQL)")
|
||||
fun jsonContainsDefaultPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("data @> :criteria", Where.jsonContains())
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("jsonContains generates named parameter (PostgreSQL)")
|
||||
fun jsonContainsNamedPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("data @> :it", Where.jsonContains(":it"))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("jsonContains fails (SQLite)")
|
||||
fun jsonContainsFailsSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertThrows<DocumentException> { Where.jsonContains() }
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("jsonPathMatches generates defaults (PostgreSQL)")
|
||||
fun jsonPathMatchDefaultPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("jsonb_path_exists(data, :path::jsonpath)", Where.jsonPathMatches())
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("jsonPathMatches generates named parameter (PostgreSQL)")
|
||||
fun jsonPathMatchNamedPostgres() {
|
||||
Configuration.dialectValue = Dialect.POSTGRESQL
|
||||
assertEquals("jsonb_path_exists(data, :jp::jsonpath)", Where.jsonPathMatches(":jp"))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("jsonPathMatches fails (SQLite)")
|
||||
fun jsonPathFailsSQLite() {
|
||||
Configuration.dialectValue = Dialect.SQLITE
|
||||
assertThrows<DocumentException> { Where.jsonPathMatches() }
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package solutions.bitbadger.documents.java
|
||||
package solutions.bitbadger.documents.support
|
||||
|
||||
import solutions.bitbadger.documents.DocumentSerializer
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
@@ -1,4 +1,4 @@
|
||||
package solutions.bitbadger.documents.java.integration
|
||||
package solutions.bitbadger.documents.support
|
||||
|
||||
import java.sql.Connection
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package solutions.bitbadger.documents.java.integration
|
||||
package solutions.bitbadger.documents.support
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import solutions.bitbadger.documents.java.extensions.insert
|
||||
import solutions.bitbadger.documents.extensions.insert
|
||||
|
||||
/** The test table name to use for integration tests */
|
||||
const val TEST_TABLE = "test_table"
|
||||
Reference in New Issue
Block a user