Skip to content

Commit

Permalink
#493 Support for comparing tuples
Browse files Browse the repository at this point in the history
  • Loading branch information
lukas-krecan committed Apr 2, 2022
1 parent b199fb9 commit 8ab810c
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
import net.javacrumbs.jsonunit.core.internal.Diff;
import net.javacrumbs.jsonunit.core.internal.Node;
import net.javacrumbs.jsonunit.core.internal.Path;
import org.assertj.core.groups.Tuple;

import java.util.Comparator;
import java.util.List;

import static net.javacrumbs.jsonunit.core.internal.JsonUtils.wrapDeserializedObject;

Expand All @@ -37,6 +39,10 @@ class JsonComparator implements Comparator<Object> {

@Override
public int compare(Object actual, Object expected) {
if (actual instanceof Tuple && expected instanceof Tuple) {
return compareTuples((Tuple) actual, (Tuple) expected);
}

// this comparator is not transitive, `expected` is usually a Node and `actual` is usually a Map, or primitive
if (
(actualParsed && !(actual instanceof Node) && (expected instanceof Node) && !(expected instanceof ExpectedNode)) ||
Expand All @@ -57,4 +63,16 @@ public int compare(Object actual, Object expected) {
return -1;
}
}

private int compareTuples(Tuple actual, Tuple expected) {
List<Object> actualList = actual.toList();
List<Object> expectedList = expected.toList();
if (actualList.size() != expectedList.size()) return -1;

for (int i = 0; i < actualList.size(); i++) {
int result = compare(actualList.get(i), expectedList.get(i));
if (result != 0) return result;
}
return 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,9 @@
import net.javacrumbs.jsonunit.core.internal.Diff;
import net.javacrumbs.jsonunit.core.internal.Path;
import org.assertj.core.api.AbstractAssert;
import org.assertj.core.api.AbstractListAssert;
import org.assertj.core.api.FactoryBasedNavigableListAssert;
import org.assertj.core.api.InstanceOfAssertFactory;
import org.assertj.core.api.ListAssert;
import org.assertj.core.api.ObjectAssert;
import org.assertj.core.error.BasicErrorMessageFactory;
import org.assertj.core.groups.Tuple;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -117,16 +113,4 @@ protected JsonListAssert newAbstractIterableAssert(Iterable<?> iterable) {
private Diff createDiff(Object other) {
return Diff.create(other, wrapDeserializedObject(actual), "fullJson", path, configuration);
}

@Override
public AbstractListAssert<?, List<? extends Tuple>, Tuple, ObjectAssert<Tuple>> extracting(String... propertiesOrFields) {
return toPureAssertJ().extracting(propertiesOrFields);
}

/**
* Drops all Json related comparators and switches to pure AssertJ assert.
*/
private ListAssert<Object> toPureAssertJ() {
return new ListAssert<>(actual);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -771,16 +771,57 @@ protected void shouldFailOnTrainingToken() {
}

@Test
void arrayExtracting() {
void arrayExtractingShouldPass() {
assertThatJson("[\n" +
" {\"id\": 1, \"name\":\"Aaron\"},\n" +
" {\"id\": 2, \"name\":\"Paul\"}\n" +
" {\"id\": 1, \"name\":{\"first\":\"Aaron\"}},\n" +
" {\"id\": 2, \"name\":{\"first\":\"Paul\"}}\n" +
" ]")
.isArray()
.extracting("id", "name")
.contains(tuple(valueOf(1), "Aaron"), tuple(valueOf(2), "Paul"));
.contains(tuple(valueOf(1), "{\"first\":\"Aaron\"}"), tuple(valueOf(2), "{\"first\":\"Paul\"}"));
}

@Test
void arrayExtractingShouldFail() {
assertThatThrownBy(() ->
assertThatJson("[\n" +
" {\"id\": 1, \"name\":{\"first\":\"Aaron\"}},\n" +
" {\"id\": 2, \"name\":{\"first\":\"John\"}}\n" +
" ]")
.isArray()
.extracting("id", "name")
.contains(tuple(valueOf(1), "{\"first\":\"Aaron\"}"), tuple(valueOf(2), "{\"first\":\"Paul\"}"))
).hasMessage("[Different value found in node \"\"] \n" +
"Expecting ArrayList:\n" +
" [(1, {\"first\":\"Aaron\"}), (2, {\"first\":\"John\"})]\n" +
"to contain:\n" +
" [(1, \"{\"first\":\"Aaron\"}\"), (2, \"{\"first\":\"Paul\"}\")]\n" +
"but could not find the following element(s):\n" +
" [(2, \"{\"first\":\"Paul\"}\")]\n" +
"when comparing values using JsonComparator");
}

@Test
void arrayExtractingShouldFailOnDifferentLengthTuple() {
assertThatThrownBy(() ->
assertThatJson("[\n" +
" {\"id\": 1, \"name\":{\"first\":\"Aaron\"}},\n" +
" {\"id\": 2, \"name\":{\"first\":\"John\"}}\n" +
" ]")
.isArray()
.extracting("id", "name")
.contains(tuple(valueOf(1), "{\"first\":\"Aaron\"}", 3), tuple(valueOf(2), "{\"first\":\"John\"}"))
).hasMessage("[Different value found in node \"\"] \n" +
"Expecting ArrayList:\n" +
" [(1, {\"first\":\"Aaron\"}), (2, {\"first\":\"John\"})]\n" +
"to contain:\n" +
" [(1, \"{\"first\":\"Aaron\"}\", 3), (2, \"{\"first\":\"John\"}\")]\n" +
"but could not find the following element(s):\n" +
" [(1, \"{\"first\":\"Aaron\"}\", 3)]\n" +
"when comparing values using JsonComparator");
}


@Test
void shouldAssertStringNumber() {
assertThatJson("{\"a\":\"1\"}").node("a").asNumber().isEqualByComparingTo("1");
Expand Down

0 comments on commit 8ab810c

Please sign in to comment.