mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-10-23 07:51:04 +00:00
Merge pull request #2198 from ebean-orm/sebastian-mrozek-feature/json-assert-compare-arrays
Feature/json assert compare arrays
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
package io.ebean.test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
final class CompareResult {
|
||||
|
||||
private final boolean applicable;
|
||||
private final List<String> errors;
|
||||
|
||||
static final CompareResult NO_ERRORS = new CompareResult(true, Collections.emptyList());
|
||||
static final CompareResult NOT_APPLICABLE = new CompareResult(false, Collections.emptyList());
|
||||
|
||||
static CompareResult error(String error) {
|
||||
return new CompareResult(true, Collections.singletonList(error));
|
||||
}
|
||||
|
||||
static CompareResult errors(List<String> errors) {
|
||||
return new CompareResult(true, errors);
|
||||
}
|
||||
|
||||
private CompareResult(boolean applicable, List<String> errors) {
|
||||
this.applicable = applicable;
|
||||
this.errors = new ArrayList<>(errors);
|
||||
}
|
||||
|
||||
boolean isApplicable() {
|
||||
return applicable;
|
||||
}
|
||||
|
||||
boolean hasErrors() {
|
||||
return !errors.isEmpty();
|
||||
}
|
||||
|
||||
List<String> getErrors() {
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,7 @@ 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;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Perform traversal of JsonNodes comparing against an expected JsonNode that
|
||||
@@ -16,15 +13,15 @@ import java.util.Stack;
|
||||
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()) {
|
||||
CompareResult result = checkRecursive(null, actualJsonNode, expectedJsonNode);
|
||||
if (result.hasErrors()) {
|
||||
List<String> errors = result.getErrors();
|
||||
String errorsString = String.join("\n", errors);
|
||||
errorsString += "\nExpected JSON fields: " + expectedJsonNode;
|
||||
errorsString += "\nActual JSON: " + actualJsonNode;
|
||||
@@ -32,55 +29,72 @@ class JsonAssertContains {
|
||||
}
|
||||
}
|
||||
|
||||
private void checkRecursive(String name, JsonNode actualJsonNode, JsonNode expectedJsonNode) {
|
||||
private CompareResult 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CompareResult result = checkNull(actualJsonNode, expectedJsonNode);
|
||||
if (result.isApplicable()) {
|
||||
return pop(name, result);
|
||||
}
|
||||
|
||||
result = checkType(actualJsonNode, expectedJsonNode);
|
||||
if (result.isApplicable()) {
|
||||
return pop(name, result);
|
||||
}
|
||||
|
||||
result = checkArray(actualJsonNode, expectedJsonNode);
|
||||
if (result.isApplicable()) {
|
||||
return pop(name, result);
|
||||
}
|
||||
|
||||
result = checkObject(actualJsonNode, expectedJsonNode);
|
||||
if (result.isApplicable()) {
|
||||
return pop(name, result);
|
||||
}
|
||||
|
||||
result = checkValue(actualJsonNode, expectedJsonNode);
|
||||
if (result.isApplicable()) {
|
||||
return pop(name, result);
|
||||
}
|
||||
|
||||
return CompareResult.NOT_APPLICABLE;
|
||||
}
|
||||
|
||||
private CompareResult pop(String name, CompareResult result) {
|
||||
if (name != null) {
|
||||
path.pop();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean checkNull(JsonNode actualJsonNode, JsonNode expectedJsonNode) {
|
||||
private CompareResult 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 CompareResult.error(String.format("Expected field '%s' to be '%s' but was null", path(), expectedJsonNode));
|
||||
}
|
||||
return true;
|
||||
return CompareResult.NOT_APPLICABLE;
|
||||
}
|
||||
|
||||
private boolean checkType(JsonNode actualJsonNode, JsonNode expectedJsonNode) {
|
||||
private CompareResult 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 CompareResult.error(String.format("Expected field '%s' to be of type '%s' but was '%s'", path(), expectedJsonNode.getNodeType(), actualJsonNode.getNodeType()));
|
||||
}
|
||||
return true;
|
||||
return CompareResult.NOT_APPLICABLE;
|
||||
}
|
||||
|
||||
private boolean checkArray(JsonNode actualJsonNode, JsonNode expectedJsonNode) {
|
||||
private CompareResult checkArray(JsonNode actualJsonNode, JsonNode expectedJsonNode) {
|
||||
if (!expectedJsonNode.isArray()) {
|
||||
return true;
|
||||
return CompareResult.NOT_APPLICABLE;
|
||||
}
|
||||
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;
|
||||
return new MatchArrayElements(actualJsonNode, expectedJsonNode).match();
|
||||
}
|
||||
|
||||
private boolean checkObject(JsonNode actualJsonNode, JsonNode expectedJsonNode) {
|
||||
private CompareResult checkObject(JsonNode actualJsonNode, JsonNode expectedJsonNode) {
|
||||
if (!expectedJsonNode.isObject()) {
|
||||
return true;
|
||||
return CompareResult.NOT_APPLICABLE;
|
||||
}
|
||||
List<String> errors = new LinkedList<>();
|
||||
Iterator<Map.Entry<String, JsonNode>> expectedFields = expectedJsonNode.fields();
|
||||
while (expectedFields.hasNext()) {
|
||||
Map.Entry<String, JsonNode> expectedField = expectedFields.next();
|
||||
@@ -89,17 +103,18 @@ class JsonAssertContains {
|
||||
if (actualNode == null) {
|
||||
errors.add(String.format("Expected field '%s' to be present", path(expectedKey)));
|
||||
} else {
|
||||
checkRecursive(expectedKey, actualNode, expectedField.getValue());
|
||||
CompareResult result = checkRecursive(expectedKey, actualNode, expectedField.getValue());
|
||||
errors.addAll(result.getErrors());
|
||||
}
|
||||
}
|
||||
// do not continue (scalar type check)
|
||||
return false;
|
||||
return CompareResult.errors(errors);
|
||||
}
|
||||
|
||||
private void checkValue(JsonNode actualJsonNode, JsonNode expectedJsonNode) {
|
||||
private CompareResult 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));
|
||||
return CompareResult.error(String.format("Expected field '%s' to be equal to '%s' but was '%s'", path(), expectedJsonNode, actualJsonNode));
|
||||
}
|
||||
return CompareResult.NO_ERRORS;
|
||||
}
|
||||
|
||||
String path(String expectedKey) {
|
||||
@@ -115,4 +130,64 @@ class JsonAssertContains {
|
||||
}
|
||||
return String.join(".", path).replace(".[", "[");
|
||||
}
|
||||
|
||||
/**
|
||||
* Match two arrays allowing elements to be in a different order.
|
||||
*/
|
||||
private class MatchArrayElements {
|
||||
private final JsonNode actualJsonNode;
|
||||
private final JsonNode expectedJsonNode;
|
||||
private final Map<Integer, JsonNode> expectedMap = new LinkedHashMap<>();
|
||||
private final Map<Integer, JsonNode> actualMap = new LinkedHashMap<>();
|
||||
|
||||
MatchArrayElements(JsonNode actualJsonNode, JsonNode expectedJsonNode) {
|
||||
this.actualJsonNode = actualJsonNode;
|
||||
this.expectedJsonNode = expectedJsonNode;
|
||||
for (int e = 0; e < expectedJsonNode.size(); e++) {
|
||||
expectedMap.put(e, expectedJsonNode.get(e));
|
||||
}
|
||||
for (int a = 0; a < actualJsonNode.size(); a++) {
|
||||
actualMap.put(a, actualJsonNode.get(a));
|
||||
}
|
||||
}
|
||||
|
||||
CompareResult match() {
|
||||
Iterator<Map.Entry<Integer, JsonNode>> iterator = expectedMap.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<Integer, JsonNode> expectedEntry = iterator.next();
|
||||
int matchPos = findFirstMatch(expectedEntry.getKey(), expectedEntry.getValue());
|
||||
if (matchPos > -1) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
List<String> errors = new ArrayList<>();
|
||||
if (actualJsonNode.size() != expectedJsonNode.size()) {
|
||||
errors.add(String.format("Unmatched array size for '%s', expected %d but got %d elements", path(), expectedJsonNode.size(), actualJsonNode.size()));
|
||||
}
|
||||
// unmatched expected -> actual
|
||||
for (Map.Entry<Integer, JsonNode> entry : expectedMap.entrySet()) {
|
||||
errors.add(String.format("Expected array element '%s[%d]' was not matched to an element in the actual array - element: %s", path(), entry.getKey(), entry.getValue()));
|
||||
}
|
||||
// unmatched actual -> expected
|
||||
for (Map.Entry<Integer, JsonNode> entry : actualMap.entrySet()) {
|
||||
errors.add(String.format("Actual array element '%s[%d]' was not matched to an element in the expected array - element: %s", path(), entry.getKey(), entry.getValue()));
|
||||
}
|
||||
return CompareResult.errors(errors);
|
||||
}
|
||||
|
||||
private int findFirstMatch(int e, JsonNode expectedNode) {
|
||||
Iterator<Map.Entry<Integer, JsonNode>> iterator = actualMap.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<Integer, JsonNode> entry = iterator.next();
|
||||
CompareResult result = checkRecursive("[" + e + "]", entry.getValue(), expectedNode);
|
||||
if (result.isApplicable() && !result.hasErrors()) {
|
||||
iterator.remove();
|
||||
return entry.getKey();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package io.ebean.test;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static io.ebean.test.Json.readNode;
|
||||
import static io.ebean.test.Json.readNodeFromResource;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -33,18 +35,21 @@ public class JsonAssertContainsTest {
|
||||
JsonAssertContains.assertContains(original, expected);
|
||||
} catch (AssertionError e) {
|
||||
String exceptionMessage = e.getMessage();
|
||||
System.out.println(exceptionMessage);
|
||||
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'")
|
||||
"Expected field 'someObject1.value1' to be of type 'ARRAY' but was 'NUMBER'",
|
||||
"Expected field 'someObject1.value2' to be of type 'OBJECT' but was 'STRING'",
|
||||
"Expected array element 'someObject1.array1[0]' was not matched to an element in the actual array - element: 101",
|
||||
"Actual array element 'someObject1.array1[0]' was not matched to an element in the expected array - element: 99",
|
||||
"Expected field 'someObject1.object1.val5' to be present",
|
||||
"Expected field 'someObject1.object1.val6' to be present",
|
||||
"Expected field 'someObject1.object2' to be of type 'NULL' but was 'OBJECT'",
|
||||
"Expected field 'someObject1.objectNull' to be of type 'OBJECT' but was 'NULL'")
|
||||
.forEach(assertionError -> assertThat(exceptionMessage).contains(assertionError));
|
||||
return;
|
||||
}
|
||||
Assertions.fail("Expected an exception to be thrown");
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +64,9 @@ public class JsonAssertContainsTest {
|
||||
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));
|
||||
return;
|
||||
}
|
||||
Assertions.fail("Expected an exception to be thrown");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -72,7 +79,9 @@ public class JsonAssertContainsTest {
|
||||
String exceptionMessage = e.getMessage();
|
||||
Stream.of("Expected field 'some' to be of type 'NUMBER' but was 'STRING'")
|
||||
.forEach(assertionError -> assertThat(exceptionMessage).contains(assertionError));
|
||||
return;
|
||||
}
|
||||
Assertions.fail("Expected an exception to be thrown");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -83,4 +92,103 @@ public class JsonAssertContainsTest {
|
||||
assertThat(contains.path("a")).isEqualTo("a");
|
||||
assertThat(contains.path("b")).isEqualTo("b");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void assertContainsNumbersArrayShuffled() {
|
||||
JsonNode array = readNode("[2, 54, 13, 10]");
|
||||
JsonNode arrayShuffled = readNode("[2, 13, 10, 54]");
|
||||
|
||||
JsonAssertContains.assertContains(arrayShuffled, array);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertContainsObjectsArrayShuffled() {
|
||||
JsonNode array = readNodeFromResource("/contains/array-objects.json");
|
||||
JsonNode arrayShuffled = readNodeFromResource("/contains/array-objects-shuffled.json");
|
||||
|
||||
JsonAssertContains.assertContains(arrayShuffled, array);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertArrayElementsNotFound() {
|
||||
JsonNode original = readNodeFromResource("/contains/array-multi-match.json");
|
||||
JsonNode actual = readNodeFromResource("/contains/array-multi-match-duplicate-props.json");
|
||||
|
||||
try {
|
||||
JsonAssertContains.assertContains(actual, original);
|
||||
} catch (AssertionError e) {
|
||||
String exceptionMessage = e.getMessage();
|
||||
Stream.of("Unmatched array size for '', expected 6 but got 4 elements",
|
||||
"Expected array element '[2]' was not matched to an element in the actual array - element: {\"c\":3}",
|
||||
"Expected array element '[4]' was not matched to an element in the actual array - element: {\"e\":5}",
|
||||
"Expected array element '[5]' was not matched to an element in the actual array - element: {\"f\":6}",
|
||||
"Actual array element '[3]' was not matched to an element in the expected array - element: {\"b\":2}")
|
||||
.forEach(assertionError -> assertThat(exceptionMessage).contains(assertionError));
|
||||
return;
|
||||
}
|
||||
|
||||
Assertions.fail("Expected an exception to be thrown");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertNestedArray_ordering() {
|
||||
JsonNode original = readNodeFromResource("/contains/nested-array.json");
|
||||
JsonNode actual = readNodeFromResource("/contains/nested-array-ordering.json");
|
||||
JsonAssertContains.assertContains(actual, original);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertNestedArray_both() {
|
||||
try {
|
||||
JsonNode original = readNodeFromResource("/contains/nested-array.json");
|
||||
JsonNode actual = readNodeFromResource("/contains/nested-array-both.json");
|
||||
JsonAssertContains.assertContains(actual, original);
|
||||
} catch (AssertionError e) {
|
||||
String exceptionMessage = e.getMessage();
|
||||
Stream.of(
|
||||
"Expected array element 'someArray1[1]' was not matched to an element in the actual array - element: {\"name\":\"b\"}",
|
||||
"Actual array element 'someArray1[0]' was not matched to an element in the expected array - element: {\"name\":\"z\"}")
|
||||
.forEach(assertionError -> assertThat(exceptionMessage).contains(assertionError));
|
||||
return;
|
||||
}
|
||||
|
||||
Assertions.fail("Expected an exception to be thrown");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertNestedArray_extraExpected() {
|
||||
try {
|
||||
JsonNode original = readNodeFromResource("/contains/nested-array.json");
|
||||
JsonNode actual = readNodeFromResource("/contains/nested-array-extraExpected.json");
|
||||
JsonAssertContains.assertContains(actual, original);
|
||||
} catch (AssertionError e) {
|
||||
String exceptionMessage = e.getMessage();
|
||||
Stream.of(
|
||||
"Unmatched array size for 'someArray1', expected 3 but got 4 elements",
|
||||
"Actual array element 'someArray1[2]' was not matched to an element in the expected array - element: {\"name\":\"d\"}")
|
||||
.forEach(assertionError -> assertThat(exceptionMessage).contains(assertionError));
|
||||
return;
|
||||
}
|
||||
|
||||
Assertions.fail("Expected an exception to be thrown");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertNestedArray_missExpected() {
|
||||
try {
|
||||
JsonNode original = readNodeFromResource("/contains/nested-array.json");
|
||||
JsonNode actual = readNodeFromResource("/contains/nested-array-missExpected.json");
|
||||
JsonAssertContains.assertContains(actual, original);
|
||||
} catch (AssertionError e) {
|
||||
String exceptionMessage = e.getMessage();
|
||||
Stream.of(
|
||||
"Unmatched array size for 'someArray1', expected 3 but got 2 elements",
|
||||
"Expected array element 'someArray1[1]' was not matched to an element in the actual array - element: {\"name\":\"b\"}")
|
||||
.forEach(assertionError -> assertThat(exceptionMessage).contains(assertionError));
|
||||
return;
|
||||
}
|
||||
|
||||
Assertions.fail("Expected an exception to be thrown");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
[
|
||||
{
|
||||
"b": 2,
|
||||
"c": 3
|
||||
},
|
||||
{
|
||||
"d": 4,
|
||||
"e": 5
|
||||
},
|
||||
{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
"c": 3
|
||||
},
|
||||
{
|
||||
"b": 2
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,20 @@
|
||||
[
|
||||
{
|
||||
"a": 1
|
||||
},
|
||||
{
|
||||
"b": 2
|
||||
},
|
||||
{
|
||||
"c": 3
|
||||
},
|
||||
{
|
||||
"d": 4
|
||||
},
|
||||
{
|
||||
"e": 5
|
||||
},
|
||||
{
|
||||
"f": 6
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,14 @@
|
||||
[
|
||||
{
|
||||
"id": "tyu",
|
||||
"c": 3
|
||||
},
|
||||
{
|
||||
"id": "zxy",
|
||||
"a": 1
|
||||
},
|
||||
{
|
||||
"id": "123",
|
||||
"b": 2
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,11 @@
|
||||
[
|
||||
{
|
||||
"a": 1
|
||||
},
|
||||
{
|
||||
"b": 2
|
||||
},
|
||||
{
|
||||
"c": 3
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"someString1": "string1",
|
||||
"someArray1": [
|
||||
{"name":"z"},
|
||||
{"name":"c"},
|
||||
{"name":"a"}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"someString1": "string1",
|
||||
"someArray1": [
|
||||
{"name":"c"},
|
||||
{"name":"a"},
|
||||
{"name":"d"},
|
||||
{"name":"b"}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"someString1": "string1",
|
||||
"someArray1": [
|
||||
{"name":"c"},
|
||||
{"name":"a"}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"someString1": "string1",
|
||||
"someArray1": [
|
||||
{"name":"c"},
|
||||
{"name":"a"},
|
||||
{"name":"b"}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"someString1": "string1",
|
||||
"someArray1": [
|
||||
{"name":"a"},
|
||||
{"name":"b"},
|
||||
{"name":"c"}
|
||||
]
|
||||
}
|
||||
@@ -3,6 +3,22 @@
|
||||
"someString2": "string2",
|
||||
"someValue1": 99,
|
||||
"someValue2": 2,
|
||||
"someObject1": {
|
||||
"value1": [],
|
||||
"value2": {
|
||||
|
||||
},
|
||||
"array1": [
|
||||
101
|
||||
],
|
||||
"object1": {
|
||||
"val5": "val5",
|
||||
"val6": "val6"
|
||||
},
|
||||
"object2": null,
|
||||
"objectNull": {
|
||||
}
|
||||
},
|
||||
"someArray1": [
|
||||
"a"
|
||||
],
|
||||
|
||||
@@ -3,6 +3,19 @@
|
||||
"someString2": "string2",
|
||||
"someValue1": 1,
|
||||
"someValue2": 2,
|
||||
"someObject1": {
|
||||
"value1": 42,
|
||||
"value2": "string3",
|
||||
"array1": [
|
||||
99
|
||||
],
|
||||
"object1": {
|
||||
},
|
||||
"object2": {
|
||||
|
||||
},
|
||||
"objectNull": null
|
||||
},
|
||||
"someArray1": [
|
||||
1,
|
||||
2,
|
||||
|
||||
Reference in New Issue
Block a user