mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#2173 - ebean-test: Add assertContains - DbJson.of(entityBean).assertContains(...)
This commit is contained in:
+9
-11
@@ -1,21 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>12.7.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<!-- <parent>-->
|
||||
<!-- <groupId>org.avaje</groupId>-->
|
||||
<!-- <artifactId>java8-oss</artifactId>-->
|
||||
<!-- <version>2.2</version>-->
|
||||
<!-- </parent>-->
|
||||
|
||||
<scm>
|
||||
<developerConnection>scm:git:git@github.com:ebean-orm/ebean.git</developerConnection>
|
||||
<tag>ebean-parent-12.6.5</tag>
|
||||
</scm>
|
||||
|
||||
<name>ebean test</name>
|
||||
<description>Testing support for Ebean</description>
|
||||
@@ -60,6 +51,13 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
<version>${jackson-databind.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean-test-docker</artifactId>
|
||||
|
||||
@@ -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.
|
||||
* <p>
|
||||
* 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.
|
||||
* </p>
|
||||
*
|
||||
* <h3>Assert contains</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* DbJson.of(order)
|
||||
* .assertContains("/order-partial.json");
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
*
|
||||
* <h3>Assert content matches</h3>
|
||||
* <p>
|
||||
* 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.
|
||||
* </p>
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* DbJson.of(timedEntries)
|
||||
* .replace("id", "eventTime")
|
||||
* .assertContentMatches("/assertJson/full-1-timed.json");
|
||||
* DbJson.of(order)
|
||||
* .replace("id", "whenCreated", "whenModified)
|
||||
* .assertContentMatches("/order-full.json");
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* <h3>Assert contains</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* DbJson.of(timedEntries)
|
||||
* .replace("id", "eventTime")
|
||||
* .assertContentMatches("/assertJson/full-1-timed.json");
|
||||
* DbJson.of(order)
|
||||
* .assertContains("/order-partial.json");
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <h3>Assert content matches</h3>
|
||||
* <pre>{@code
|
||||
*
|
||||
* DbJson.of(order)
|
||||
* .replace("id", "whenCreated", "whenModified)
|
||||
* .assertContentMatches("/order-full.json");
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
@@ -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.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
@@ -103,7 +127,44 @@ public class DbJson {
|
||||
* }</pre>
|
||||
*/
|
||||
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.
|
||||
* <p>
|
||||
* 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.
|
||||
* </p>
|
||||
*
|
||||
* @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.
|
||||
* <p>
|
||||
* 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.
|
||||
* </p>
|
||||
*
|
||||
* @param resourcePath The resource path of the JSON content we are checking against.
|
||||
*/
|
||||
public void assertContainsResource(String resourcePath) {
|
||||
assertContains(readResource(resourcePath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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> T asBean(Class<T> cls) {
|
||||
return Json.read(cls, readResource(resourcePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return as a list of beans.
|
||||
*/
|
||||
<T> List<T> asList(Class<T> 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.
|
||||
* <pre>{@code
|
||||
*
|
||||
* PlainBean bean =
|
||||
* Json.resource("/example/plain-list.json").asBean(PlainBean.class);
|
||||
*
|
||||
* List<PlainBean> list =
|
||||
* Json.resource("/example/plain-list.json").asList(PlainBean.class);
|
||||
*
|
||||
* JsonNode jsonNode =
|
||||
* Json.resource("/example/plain-list.json").asJsonNode();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @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> T readFromResource(Class<T> type, String resourcePath) {
|
||||
return read(type, readResource(resourcePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a typed object from json content.
|
||||
*/
|
||||
public static <T> T read(Class<T> 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 <T> List<T> readList(Class<T> 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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<String> path = new Stack<>();
|
||||
private final LinkedList<String> 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<Map.Entry<String, JsonNode>> expectedFields = expectedJsonNode.fields();
|
||||
while (expectedFields.hasNext()) {
|
||||
Map.Entry<String, JsonNode> 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(".[", "[");
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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<PlainBean> 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<PlainBean> list = Json.resource("/example/plain-list.json").asList(PlainBean.class);
|
||||
|
||||
// traditional style
|
||||
List<PlainBean> list2 = Json.readList(PlainBean.class, readResource("/example/plain-list.json"));
|
||||
assertThat(list).isEqualTo(list2);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,6 +18,8 @@ public class BSimpleWithGen {
|
||||
|
||||
private String name;
|
||||
|
||||
private String other;
|
||||
|
||||
@Transient
|
||||
private Map<String, List<String>> 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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "something-contains-me",
|
||||
"version": 1
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "something-contains-me",
|
||||
"other": "YeahNah",
|
||||
"version": 1
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"id": _,
|
||||
"name": "something",
|
||||
"other": null,
|
||||
"whenModified": _,
|
||||
"version": 1
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
[ {
|
||||
"id": "*",
|
||||
"name": "something",
|
||||
"other": null,
|
||||
"whenModified": "*",
|
||||
"version": 1
|
||||
}, {
|
||||
"id": "*",
|
||||
"name": "other",
|
||||
"other": null,
|
||||
"whenModified": "*",
|
||||
"version": 1
|
||||
} ]
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"some": "val",
|
||||
"someNull": "actualNotNull",
|
||||
"matchNull": null,
|
||||
"nullObject": {
|
||||
"id": 42
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"some": "val",
|
||||
"someNull": null,
|
||||
"extra": "notThere",
|
||||
"matchNull": null,
|
||||
"nullObject": null
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"some": "val"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"some": 42
|
||||
}
|
||||
@@ -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": []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"someString1": "string1",
|
||||
"someValue1": 1,
|
||||
"someArray2": [
|
||||
{
|
||||
"value1": 11,
|
||||
"array1": [],
|
||||
"object2": {
|
||||
"v1": "v1",
|
||||
"v4": []
|
||||
},
|
||||
"objectNull": null
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
[
|
||||
{
|
||||
"id": 42,
|
||||
"name": "foo"
|
||||
},
|
||||
{
|
||||
"id": 55,
|
||||
"name": "bar"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"id": 42,
|
||||
"name": "foo"
|
||||
}
|
||||
Reference in New Issue
Block a user