diff --git a/ebean-test/pom.xml b/ebean-test/pom.xml index 92f4c590f..caef82218 100644 --- a/ebean-test/pom.xml +++ b/ebean-test/pom.xml @@ -1,21 +1,12 @@ - + 4.0.0 ebean-parent io.ebean 12.7.1-SNAPSHOT - - - - - - - - scm:git:git@github.com:ebean-orm/ebean.git - ebean-parent-12.6.5 - ebean test Testing support for Ebean @@ -60,6 +51,13 @@ true + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson-databind.version} + true + + io.ebean ebean-test-docker diff --git a/ebean-test/src/main/java/io/ebean/test/DbJson.java b/ebean-test/src/main/java/io/ebean/test/DbJson.java index 79de39099..3675063c1 100644 --- a/ebean-test/src/main/java/io/ebean/test/DbJson.java +++ b/ebean-test/src/main/java/io/ebean/test/DbJson.java @@ -2,34 +2,63 @@ package io.ebean.test; import io.ebean.DB; -import java.io.IOException; -import java.io.InputStream; - import static org.assertj.core.api.Assertions.assertThat; /** * Helper for testing to assert that the JSON form of an entity - * or list of entities match a String / typically test resource. + * or list of entities is as expected. + *

+ * Using assertContains() we can match the JSON form of an entity + * against a subset of JSON content. Typically the subset of JSON + * excludes generated properties like id, when created and + * when modified properties. + *

+ * + *

Assert contains

+ *
{@code
+ *
+ *    DbJson.of(order)
+ *      .assertContains("/order-partial.json");
+ *
+ * }
+ * + * + *

Assert content matches

+ *

+ * Using assertContentMatches() we are doing an exact content match. + * We typically need to replace generated property values. This assert + * will start to fail if the model changes like adding a property to + * the entity so we should use it less widely due to the maintenance + * burden we have with it. + *

* *
{@code
  *
- *    DbJson.of(timedEntries)
- *      .replace("id", "eventTime")
- *      .assertContentMatches("/assertJson/full-1-timed.json");
+ *    DbJson.of(order)
+ *      .replace("id", "whenCreated", "whenModified)
+ *      .assertContentMatches("/order-full.json");
  *
  * }
*/ public class DbJson { /** - * Create a PrettyJson object that has the JSON form of the - * entity bean or beans. + * Create a PrettyJson object that has the JSON form of the entity bean or beans. * + *

Assert contains

*
{@code
    *
-   *    DbJson.of(timedEntries)
-   *      .replace("id", "eventTime")
-   *      .assertContentMatches("/assertJson/full-1-timed.json");
+   *    DbJson.of(order)
+   *      .assertContains("/order-partial.json");
+   *
+   * }
+ * + *

Assert content matches

+ *
{@code
+   *
+   *    DbJson.of(order)
+   *      .replace("id", "whenCreated", "whenModified)
+   *      .assertContentMatches("/order-full.json");
    *
    * }
*/ @@ -41,12 +70,7 @@ public class DbJson { * Read the content for the given resource path. */ public static String readResource(String resourcePath) { - InputStream is = DbJson.class.getResourceAsStream(resourcePath); - try { - return IOUtils.readUtf8(is).trim(); - } catch (IOException e) { - throw new IllegalArgumentException(e); - } + return IOUtils.readResource(resourcePath); } /** @@ -92,7 +116,7 @@ public class DbJson { } /** - * Assert the json matches the content at the given resource path. + * Assert the json exactly matches the content at the given resource path. * *
{@code
      *
@@ -103,7 +127,44 @@ public class DbJson {
      * }
*/ public void assertContentMatches(String resourcePath) { - assertThat(rawJson).isEqualTo(readResource(resourcePath)); + assertThat(lineEnd(rawJson)).isEqualTo(lineEnd(readResource(resourcePath))); + } + + /** + * Normalise line ending characters to just use new line. + */ + private String lineEnd(String content) { + return content.replace("\r\n", "\n"); + } + + /** + * Assert the DB json contains the given json content. + *

+ * With this "contains" check the DB Json can contain more content than what + * it is checked against. Typically the DB json can contain generated properties + * like id values, when created, when modified etc and we leave these out of the + * json content we are checking against. + *

+ * + * @param json The subset json content that should be contained by the DB json. + */ + public void assertContains(String json) { + Json.assertContains(rawJson, json); + } + + /** + * Assert the DB Json contains the Json at the given resource path. + *

+ * With this "contains" check the DB Json can contain more content than what + * it is checked against. Typically the DB json can contain generated properties + * like id values, when created, when modified etc and we leave these out of the + * json content we are checking against. + *

+ * + * @param resourcePath The resource path of the JSON content we are checking against. + */ + public void assertContainsResource(String resourcePath) { + assertContains(readResource(resourcePath)); } } } diff --git a/ebean-test/src/main/java/io/ebean/test/IOUtils.java b/ebean-test/src/main/java/io/ebean/test/IOUtils.java index 79b706706..a9b98086b 100644 --- a/ebean-test/src/main/java/io/ebean/test/IOUtils.java +++ b/ebean-test/src/main/java/io/ebean/test/IOUtils.java @@ -11,6 +11,18 @@ import java.nio.charset.StandardCharsets; */ class IOUtils { + /** + * Read the content for the given resource path. + */ + static String readResource(String resourcePath) { + try { + InputStream is = IOUtils.class.getResourceAsStream(resourcePath); + return IOUtils.readUtf8(is).trim(); + } catch (IOException e) { + throw new IllegalArgumentException("Error reading resource " + resourcePath, e); + } + } + /** * Reads the entire contents of the specified input stream and return them as UTF-8 string. */ diff --git a/ebean-test/src/main/java/io/ebean/test/Json.java b/ebean-test/src/main/java/io/ebean/test/Json.java new file mode 100644 index 000000000..7612757e3 --- /dev/null +++ b/ebean-test/src/main/java/io/ebean/test/Json.java @@ -0,0 +1,168 @@ +package io.ebean.test; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.type.CollectionType; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; + +import java.io.IOException; +import java.util.List; + +/** + * Helper to convert to and from json using Jackson object mapper and + * perform some useful asserts based on json content. + */ +public class Json { + + /** + * For reading resource json content into a bean, list or jsonNode in a fluid style. + */ + public static class Resource { + private final String resourcePath; + + private Resource(String resourcePath) { + this.resourcePath = resourcePath; + } + + /** + * Return as a plain bean. + */ + T asBean(Class cls) { + return Json.read(cls, readResource(resourcePath)); + } + + /** + * Return as a list of beans. + */ + List asList(Class cls) { + return Json.readList(cls, readResource(resourcePath)); + } + + /** + * Return as a JsonNode. + */ + JsonNode asNode() { + return Json.readNodeFromResource(resourcePath); + } + } + + private static final ObjectMapper MAPPER = initMapper(); + + /** + * For fluid style reading resource json content and return as a + * bean, list of bean or JsonNode. + *
{@code
+   *
+   *   PlainBean bean =
+   *     Json.resource("/example/plain-list.json").asBean(PlainBean.class);
+   *
+   *   List list =
+   *     Json.resource("/example/plain-list.json").asList(PlainBean.class);
+   *
+   *   JsonNode jsonNode =
+   *     Json.resource("/example/plain-list.json").asJsonNode();
+   *
+   * }
+ * + * @param resourcePath The resource path where the json content is read from + * @return The resource to convert to a bean or jsonNode etc + */ + public static Resource resource(String resourcePath) { + return new Resource(resourcePath); + } + + /** + * Assert all the fields in the expectedJson are present in actualJson and values match. + */ + public static void assertContains(String actualJson, String expectedJson) { + assertContains(readNode(actualJson), readNode(expectedJson)); + } + + /** + * Assert all the fields in the expectedJson are present in actualJson and values match. + */ + public static void assertContains(JsonNode actualJsonNode, JsonNode expectedJsonNode) { + JsonAssertContains.assertContains(actualJsonNode, expectedJsonNode); + } + + /** + * Read the content for the given resource path. + */ + public static String readResource(String resourcePath) { + return IOUtils.readResource(resourcePath); + } + + /** + * Return a bean from json content of a resource path. + */ + public static T readFromResource(Class type, String resourcePath) { + return read(type, readResource(resourcePath)); + } + + /** + * Return a typed object from json content. + */ + public static T read(Class type, String json) { + try { + return MAPPER.readValue(json, type); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * Return a list of a given type from json content. + */ + public static List readList(Class type, String json) { + final CollectionType collectionType = MAPPER.getTypeFactory().constructCollectionType(List.class, type); + try { + return MAPPER.readValue(json, collectionType); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * Parse json into a generic JsonNode structure from resource. + */ + public static JsonNode readNodeFromResource(String resourcePath) { + return readNode(IOUtils.readResource(resourcePath)); + } + + /** + * Parse json into a generic JsonNode structure. + */ + public static JsonNode readNode(String json) { + try { + return MAPPER.readTree(json); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * Serialize object to string + */ + public static String toJsonString(Object bean) { + try { + return MAPPER.writeValueAsString(bean); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static ObjectMapper initMapper() { + return new ObjectMapper() + .registerModule(new JavaTimeModule()) + .configure(SerializationFeature.INDENT_OUTPUT, true) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false) + .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false) + .configure(SerializationFeature.INDENT_OUTPUT, true) + .setSerializationInclusion(JsonInclude.Include.NON_NULL); + } + +} diff --git a/ebean-test/src/main/java/io/ebean/test/JsonAssertContains.java b/ebean-test/src/main/java/io/ebean/test/JsonAssertContains.java new file mode 100644 index 000000000..25e1e065a --- /dev/null +++ b/ebean-test/src/main/java/io/ebean/test/JsonAssertContains.java @@ -0,0 +1,118 @@ +package io.ebean.test; + +import com.fasterxml.jackson.databind.JsonNode; +import org.assertj.core.api.Assertions; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; +import java.util.Stack; + +/** + * Perform traversal of JsonNodes comparing against an expected JsonNode that + * typically contains a subset of the data (typically excludes any generated properties + * like when modified timestamps etc). + */ +class JsonAssertContains { + + private final Stack path = new Stack<>(); + private final LinkedList errors = new LinkedList<>(); + + static void assertContains(JsonNode actualJsonNode, JsonNode expectedJsonNode) { + new JsonAssertContains().contains(actualJsonNode, expectedJsonNode); + } + + private void contains(JsonNode actualJsonNode, JsonNode expectedJsonNode) { + checkRecursive(null, actualJsonNode, expectedJsonNode); + if (!errors.isEmpty()) { + String errorsString = String.join("\n", errors); + errorsString += "\nExpected JSON fields: " + expectedJsonNode; + errorsString += "\nActual JSON: " + actualJsonNode; + Assertions.fail(errorsString); + } + } + + private void checkRecursive(String name, JsonNode actualJsonNode, JsonNode expectedJsonNode) { + if (name != null) { + path.push(name); + } + if (checkNull(actualJsonNode, expectedJsonNode)) { + if (checkType(actualJsonNode, expectedJsonNode)) { + if (checkArray(actualJsonNode, expectedJsonNode)) { + if (checkObject(actualJsonNode, expectedJsonNode)) { + checkValue(actualJsonNode, expectedJsonNode); + } + } + } + } + if (name != null) { + path.pop(); + } + } + + private boolean checkNull(JsonNode actualJsonNode, JsonNode expectedJsonNode) { + if (actualJsonNode == null) { + errors.add(String.format("Expected field '%s' to be '%s' but was null", path(), expectedJsonNode)); + return false; + } + return true; + } + + private boolean checkType(JsonNode actualJsonNode, JsonNode expectedJsonNode) { + if (!expectedJsonNode.getNodeType().equals(actualJsonNode.getNodeType())) { + errors.add(String.format("Expected field '%s' to be of type '%s' but was '%s'", path(), expectedJsonNode.getNodeType(), actualJsonNode.getNodeType())); + return false; + } + return true; + } + + private boolean checkArray(JsonNode actualJsonNode, JsonNode expectedJsonNode) { + if (!expectedJsonNode.isArray()) { + return true; + } + for (int i = 0; i < expectedJsonNode.size(); i++) { + checkRecursive("[" + i + "]", actualJsonNode.get(i), expectedJsonNode.get(i)); + } + // do not continue (object or scalar type check) + return false; + } + + private boolean checkObject(JsonNode actualJsonNode, JsonNode expectedJsonNode) { + if (!expectedJsonNode.isObject()) { + return true; + } + Iterator> expectedFields = expectedJsonNode.fields(); + while (expectedFields.hasNext()) { + Map.Entry expectedField = expectedFields.next(); + String expectedKey = expectedField.getKey(); + JsonNode actualNode = actualJsonNode.get(expectedKey); + if (actualNode == null) { + errors.add(String.format("Expected field '%s' to be present", path(expectedKey))); + } else { + checkRecursive(expectedKey, actualNode, expectedField.getValue()); + } + } + // do not continue (scalar type check) + return false; + } + + private void checkValue(JsonNode actualJsonNode, JsonNode expectedJsonNode) { + if (!expectedJsonNode.equals(actualJsonNode)) { + errors.add(String.format("Expected field '%s' to be equal to '%s' but was '%s'", path(), expectedJsonNode, actualJsonNode)); + } + } + + String path(String expectedKey) { + if (path.isEmpty()) { + return expectedKey; + } + return path() + "." + expectedKey; + } + + String path() { + if (path.isEmpty()) { + return ""; + } + return String.join(".", path).replace(".[", "["); + } +} diff --git a/ebean-test/src/test/java/io/ebean/test/DbJsonTest.java b/ebean-test/src/test/java/io/ebean/test/DbJsonTest.java index dc841c88f..365c019cd 100644 --- a/ebean-test/src/test/java/io/ebean/test/DbJsonTest.java +++ b/ebean-test/src/test/java/io/ebean/test/DbJsonTest.java @@ -1,11 +1,13 @@ package io.ebean.test; +import com.fasterxml.jackson.databind.JsonNode; import io.ebean.DB; import org.junit.Test; import org.test.BSimpleWithGen; import java.util.List; +import static io.ebean.test.DbJson.readResource; import static org.assertj.core.api.Assertions.assertThat; @@ -36,6 +38,37 @@ public class DbJsonTest { //.withPlaceholder("_") .replace("id", "whenModified") .assertContentMatches("/bean/example-list.json"); + } + @Test + public void assertContains_pass() { + + BSimpleWithGen bean = new BSimpleWithGen("something-contains-me", "YeahNah"); + DB.save(bean); + + BSimpleWithGen found = DB.find(BSimpleWithGen.class, bean.getId()); + + DbJson.of(found).assertContainsResource("/bean/contains-minimal.json"); + DbJson.of(found).assertContains(readResource("/bean/contains-with-version.json")); + + DB.delete(bean); + } + + @Test + public void asJson() { + + BSimpleWithGen bean = new BSimpleWithGen("other"); + DB.save(bean); + + String asJson = DbJson.of(bean) + .withPlaceholder("\"*Replaced*\"") + .replace("id") + .asJson(); + + JsonNode node = Json.readNode(asJson); + assertThat(node.get("id").asText()).isEqualTo("*Replaced*"); + assertThat(node.get("name").asText()).isEqualTo("other"); + + DB.delete(bean); } } diff --git a/ebean-test/src/test/java/io/ebean/test/JsonAssertContainsTest.java b/ebean-test/src/test/java/io/ebean/test/JsonAssertContainsTest.java new file mode 100644 index 000000000..2c25776f9 --- /dev/null +++ b/ebean-test/src/test/java/io/ebean/test/JsonAssertContainsTest.java @@ -0,0 +1,86 @@ +package io.ebean.test; + +import com.fasterxml.jackson.databind.JsonNode; +import org.junit.Test; + +import java.util.stream.Stream; + +import static io.ebean.test.Json.readNodeFromResource; +import static org.assertj.core.api.Assertions.assertThat; + + +public class JsonAssertContainsTest { + + @Test + public void assertContains_itself() { + JsonNode original = readNodeFromResource("/contains/original.json"); + JsonAssertContains.assertContains(original, original); + } + + @Test + public void assertContains_subset() { + JsonNode original = readNodeFromResource("/contains/original.json"); + JsonNode expected = readNodeFromResource("/contains/original-subset.json"); + JsonAssertContains.assertContains(original, expected); + } + + + @Test + public void testContainsFails() { + JsonNode original = readNodeFromResource("/contains/original.json"); + JsonNode expected = readNodeFromResource("/contains/original-subset-modified.json"); + try { + JsonAssertContains.assertContains(original, expected); + } catch (AssertionError e) { + String exceptionMessage = e.getMessage(); + Stream.of("Expected field 'someString1' to be equal to '\"aaaa\"' but was '\"string1\"", + "Expected field 'someValue1' to be equal to '99' but was '1'", + "Expected field 'someArray1[0]' to be of type 'STRING' but was 'NUMBER", + "Expected field 'someArray2[0].value1' to be of type 'ARRAY' but was 'NUMBER'", + "Expected field 'someArray2[0].value2' to be of type 'OBJECT' but was 'STRING'", + "Expected field 'someArray2[0].array1[0]' to be '\"1\"' but was null", + "Expected field 'someArray2[0].object1.val5' to be present", + "Expected field 'someArray2[0].object1.val6' to be present", + "Expected field 'someArray2[0].object2' to be of type 'NULL' but was 'OBJECT'", + "Expected field 'someArray2[0].objectNull' to be of type 'OBJECT' but was 'NULL'") + .forEach(assertionError -> assertThat(exceptionMessage).contains(assertionError)); + } + } + + + @Test + public void assertContains_checkNull() { + JsonNode original = readNodeFromResource("/contains/check-null-actual.json"); + JsonNode expected = readNodeFromResource("/contains/check-null-expected.json"); + try { + JsonAssertContains.assertContains(original, expected); + } catch (AssertionError e) { + String exceptionMessage = e.getMessage(); + Stream.of("Expected field 'someNull' to be of type 'NULL' but was 'STRING'", + "Expected field 'extra' to be present") + .forEach(assertionError -> assertThat(exceptionMessage).contains(assertionError)); + } + } + + @Test + public void assertContains_checkType() { + JsonNode original = readNodeFromResource("/contains/check-type-actual.json"); + JsonNode expected = readNodeFromResource("/contains/check-type-expected.json"); + try { + JsonAssertContains.assertContains(original, expected); + } catch (AssertionError e) { + String exceptionMessage = e.getMessage(); + Stream.of("Expected field 'some' to be of type 'NUMBER' but was 'STRING'") + .forEach(assertionError -> assertThat(exceptionMessage).contains(assertionError)); + } + } + + @Test + public void path_when_empty() { + JsonAssertContains contains = new JsonAssertContains(); + + assertThat(contains.path()).isEqualTo(""); + assertThat(contains.path("a")).isEqualTo("a"); + assertThat(contains.path("b")).isEqualTo("b"); + } +} diff --git a/ebean-test/src/test/java/io/ebean/test/JsonTest.java b/ebean-test/src/test/java/io/ebean/test/JsonTest.java new file mode 100644 index 000000000..baf7a1563 --- /dev/null +++ b/ebean-test/src/test/java/io/ebean/test/JsonTest.java @@ -0,0 +1,75 @@ +package io.ebean.test; + +import com.fasterxml.jackson.databind.JsonNode; +import org.junit.Test; +import org.test.PlainBean; + +import java.util.List; + +import static io.ebean.test.Json.readNodeFromResource; +import static io.ebean.test.Json.readResource; +import static org.assertj.core.api.Assertions.assertThat; + +public class JsonTest { + + @Test + public void assertContains_subset() { + JsonNode original = readNodeFromResource("/contains/original.json"); + JsonNode expected = readNodeFromResource("/contains/original-subset.json"); + Json.assertContains(original, expected); + } + + @Test + public void readNode() { + JsonNode original = Json.readNode(readResource("/contains/original.json")); + Json.assertContains(original, original); + } + + @Test + public void resource_asNode() { + JsonNode original = Json.resource("/contains/original.json").asNode(); + JsonNode nonFluid = Json.readNode(readResource("/contains/original.json")); + assertThat(original).isEqualTo(nonFluid); + } + + @Test + public void readBean_resource_asBean() { + // traditional style from resource + PlainBean bean1 = Json.readFromResource(PlainBean.class, "/example/plain.json"); + assertThat(bean1.id).isEqualTo(42); + assertThat(bean1.name).isEqualTo("foo"); + + // traditional style given json content + PlainBean bean2 = Json.read(PlainBean.class, readResource("/example/plain.json")); + assertThat(bean2.id).isEqualTo(42); + assertThat(bean2.name).isEqualTo("foo"); + + // fluid style - resource asBean() + PlainBean bean3 = Json.resource("/example/plain.json").asBean(PlainBean.class); + assertThat(bean3.id).isEqualTo(42); + assertThat(bean3.name).isEqualTo("foo"); + } + + @Test + public void readList() { + List list = Json.readList(PlainBean.class, readResource("/example/plain-list.json")); + + String asJson = Json.toJsonString(list); + assertThat(list).hasSize(2); + assertThat(list.get(0).name).isEqualTo("foo"); + assertThat(list.get(1).name).isEqualTo("bar"); + + assertThat(asJson).contains("\"name\" : \"foo\""); + } + + @Test + public void resourceAsList() { + // fluid style - resource asList() + List list = Json.resource("/example/plain-list.json").asList(PlainBean.class); + + // traditional style + List list2 = Json.readList(PlainBean.class, readResource("/example/plain-list.json")); + assertThat(list).isEqualTo(list2); + } + +} diff --git a/ebean-test/src/test/java/org/test/BSimpleWithGen.java b/ebean-test/src/test/java/org/test/BSimpleWithGen.java index cf3c7f2f6..5ee189229 100644 --- a/ebean-test/src/test/java/org/test/BSimpleWithGen.java +++ b/ebean-test/src/test/java/org/test/BSimpleWithGen.java @@ -18,6 +18,8 @@ public class BSimpleWithGen { private String name; + private String other; + @Transient private Map> someMap; @@ -31,6 +33,11 @@ public class BSimpleWithGen { this.name = name; } + public BSimpleWithGen(String name, String other) { + this.name = name; + this.other = other; + } + public Integer getId() { return id; } diff --git a/ebean-test/src/test/java/org/test/PlainBean.java b/ebean-test/src/test/java/org/test/PlainBean.java new file mode 100644 index 000000000..103e67425 --- /dev/null +++ b/ebean-test/src/test/java/org/test/PlainBean.java @@ -0,0 +1,22 @@ +package org.test; + +import java.util.Objects; + +public class PlainBean { + + public int id; + public String name; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PlainBean plainBean = (PlainBean) o; + return id == plainBean.id && name.equals(plainBean.name); + } + + @Override + public int hashCode() { + return Objects.hash(id, name); + } +} diff --git a/ebean-test/src/test/resources/bean/contains-minimal.json b/ebean-test/src/test/resources/bean/contains-minimal.json new file mode 100644 index 000000000..564060eec --- /dev/null +++ b/ebean-test/src/test/resources/bean/contains-minimal.json @@ -0,0 +1,4 @@ +{ + "name": "something-contains-me", + "version": 1 +} diff --git a/ebean-test/src/test/resources/bean/contains-with-version.json b/ebean-test/src/test/resources/bean/contains-with-version.json new file mode 100644 index 000000000..894b0bf14 --- /dev/null +++ b/ebean-test/src/test/resources/bean/contains-with-version.json @@ -0,0 +1,5 @@ +{ + "name": "something-contains-me", + "other": "YeahNah", + "version": 1 +} diff --git a/ebean-test/src/test/resources/bean/example-bean.json b/ebean-test/src/test/resources/bean/example-bean.json index 593babff3..e9a935767 100644 --- a/ebean-test/src/test/resources/bean/example-bean.json +++ b/ebean-test/src/test/resources/bean/example-bean.json @@ -1,6 +1,7 @@ { "id": _, "name": "something", + "other": null, "whenModified": _, "version": 1 } diff --git a/ebean-test/src/test/resources/bean/example-list.json b/ebean-test/src/test/resources/bean/example-list.json index 21264b0a7..8c7b8b681 100644 --- a/ebean-test/src/test/resources/bean/example-list.json +++ b/ebean-test/src/test/resources/bean/example-list.json @@ -1,11 +1,13 @@ [ { "id": "*", "name": "something", + "other": null, "whenModified": "*", "version": 1 }, { "id": "*", "name": "other", + "other": null, "whenModified": "*", "version": 1 } ] diff --git a/ebean-test/src/test/resources/contains/check-null-actual.json b/ebean-test/src/test/resources/contains/check-null-actual.json new file mode 100644 index 000000000..992d2aef4 --- /dev/null +++ b/ebean-test/src/test/resources/contains/check-null-actual.json @@ -0,0 +1,9 @@ +{ + "some": "val", + "someNull": "actualNotNull", + "matchNull": null, + "nullObject": { + "id": 42 + } + +} diff --git a/ebean-test/src/test/resources/contains/check-null-expected.json b/ebean-test/src/test/resources/contains/check-null-expected.json new file mode 100644 index 000000000..ce4163032 --- /dev/null +++ b/ebean-test/src/test/resources/contains/check-null-expected.json @@ -0,0 +1,7 @@ +{ + "some": "val", + "someNull": null, + "extra": "notThere", + "matchNull": null, + "nullObject": null +} diff --git a/ebean-test/src/test/resources/contains/check-type-actual.json b/ebean-test/src/test/resources/contains/check-type-actual.json new file mode 100644 index 000000000..6b240843c --- /dev/null +++ b/ebean-test/src/test/resources/contains/check-type-actual.json @@ -0,0 +1,3 @@ +{ + "some": "val" +} diff --git a/ebean-test/src/test/resources/contains/check-type-expected.json b/ebean-test/src/test/resources/contains/check-type-expected.json new file mode 100644 index 000000000..5b0cf6957 --- /dev/null +++ b/ebean-test/src/test/resources/contains/check-type-expected.json @@ -0,0 +1,3 @@ +{ + "some": 42 +} diff --git a/ebean-test/src/test/resources/contains/original-subset-modified.json b/ebean-test/src/test/resources/contains/original-subset-modified.json new file mode 100644 index 000000000..107d557d2 --- /dev/null +++ b/ebean-test/src/test/resources/contains/original-subset-modified.json @@ -0,0 +1,26 @@ +{ + "someString1": "aaaa", + "someString2": "string2", + "someValue1": 99, + "someValue2": 2, + "someArray1": [ + "a" + ], + "someArray2": [ + { + "value1": [], + "value2": {}, + "array1": [ + "1" + ], + "object1": { + "val5": "a", + "val6": 1 + }, + "object2": null, + "objectNull": { + "val": [] + } + } + ] +} diff --git a/ebean-test/src/test/resources/contains/original-subset.json b/ebean-test/src/test/resources/contains/original-subset.json new file mode 100644 index 000000000..e5823e2a4 --- /dev/null +++ b/ebean-test/src/test/resources/contains/original-subset.json @@ -0,0 +1,15 @@ +{ + "someString1": "string1", + "someValue1": 1, + "someArray2": [ + { + "value1": 11, + "array1": [], + "object2": { + "v1": "v1", + "v4": [] + }, + "objectNull": null + } + ] +} diff --git a/ebean-test/src/test/resources/contains/original.json b/ebean-test/src/test/resources/contains/original.json new file mode 100644 index 000000000..063affac4 --- /dev/null +++ b/ebean-test/src/test/resources/contains/original.json @@ -0,0 +1,27 @@ +{ + "someString1": "string1", + "someString2": "string2", + "someValue1": 1, + "someValue2": 2, + "someArray1": [ + 1, + 2, + 3, + 4 + ], + "someArray2": [ + { + "value1": 11, + "value2": "22", + "array1": [], + "object1": {}, + "object2": { + "v1": "v1", + "v2": 1, + "v3": {}, + "v4": [] + }, + "objectNull": null + } + ] +} diff --git a/ebean-test/src/test/resources/example/plain-list.json b/ebean-test/src/test/resources/example/plain-list.json new file mode 100644 index 000000000..49bc4c34d --- /dev/null +++ b/ebean-test/src/test/resources/example/plain-list.json @@ -0,0 +1,10 @@ +[ + { + "id": 42, + "name": "foo" + }, + { + "id": 55, + "name": "bar" + } +] diff --git a/ebean-test/src/test/resources/example/plain.json b/ebean-test/src/test/resources/example/plain.json new file mode 100644 index 000000000..63632de85 --- /dev/null +++ b/ebean-test/src/test/resources/example/plain.json @@ -0,0 +1,4 @@ +{ + "id": 42, + "name": "foo" +}