Skip to content

Commit

Permalink
Fail fast when comparing arrays
Browse files Browse the repository at this point in the history
When comparing arrays, we want to find if the array items are equal,
not so much how they differ.
  • Loading branch information
lukas-krecan committed Jun 26, 2024
1 parent a8648b2 commit 567c5ce
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@
import static java.lang.Math.min;
import static java.util.Collections.unmodifiableList;
import static java.util.stream.Collectors.toList;
import static net.javacrumbs.jsonunit.core.Configuration.dummyDifferenceListener;
import static net.javacrumbs.jsonunit.core.internal.Diff.DEFAULT_DIFFERENCE_STRING;
import static net.javacrumbs.jsonunit.core.internal.JsonUnitLogger.NULL_LOGGER;

import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
import net.javacrumbs.jsonunit.core.Configuration;
import net.javacrumbs.jsonunit.core.listener.DifferenceListener;

/**
* Stores comparison result when comparing two arrays.
Expand Down Expand Up @@ -81,15 +81,8 @@ private static List<List<Integer>> generateEqualElements(

for (int j = 0; j < expectedElements.size(); j++) {
Node expected = expectedElements.get(j);
Diff diff = new Diff(
expected,
actual,
Path.create("", path.toElement(i).getFullPath()),
configuration.withDifferenceListener(dummyDifferenceListener()),
NULL_LOGGER,
NULL_LOGGER,
DEFAULT_DIFFERENCE_STRING);
if (diff.similar()) {
boolean similar = isSimilar(path, configuration, expected, actual, i);
if (similar) {
actualIsEqualTo.add(j);
}
}
Expand All @@ -100,6 +93,22 @@ private static List<List<Integer>> generateEqualElements(
return equalElements;
}

private static boolean isSimilar(Path path, Configuration configuration, Node expected, Node actual, int i) {
Diff diff = new Diff(
expected,
actual,
Path.create("", path.toElement(i).getFullPath()),
configuration.withDifferenceListener(failFastDifferenceListener),
NULL_LOGGER,
NULL_LOGGER,
DEFAULT_DIFFERENCE_STRING);
try {
return diff.similar();
} catch (DifferenceFoundException e) {
return false;
}
}

ComparisonMatrix compare() {
doSimpleMatching();

Expand Down Expand Up @@ -178,15 +187,15 @@ private List<Integer> getEqualToUsedOnlyInEquivalentElements(
}

private List<Integer> getEquivalentElements(List<Integer> equalTo) {
List<Integer> equivalentElments = new ArrayList<>();
List<Integer> equivalentElements = new ArrayList<>();
for (int i = 0; i < equalElements.size(); i++) {
if (!alreadyMatched.get(i)) {
if (equalTo.equals(equalElements.get(i))) {
equivalentElments.add(i);
equivalentElements.add(i);
}
}
}
return equivalentElments;
return equivalentElements;
}

private void addExtra(int index) {
Expand Down Expand Up @@ -240,4 +249,15 @@ List<Integer> getMissing() {
List<Integer> getExtra() {
return extra;
}

private static final DifferenceListener failFastDifferenceListener = (difference, context) -> {
throw new DifferenceFoundException();
};

private static final class DifferenceFoundException extends RuntimeException {
@Override
public synchronized Throwable fillInStackTrace() {
return this;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import static java.math.BigDecimal.valueOf;
import static java.util.Collections.singletonMap;
import static net.javacrumbs.jsonunit.core.util.ResourceUtils.resource;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
Expand All @@ -26,11 +27,8 @@
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import net.javacrumbs.jsonunit.core.Configuration;
import net.javacrumbs.jsonunit.core.NumberComparator;
import net.javacrumbs.jsonunit.core.Option;
Expand Down Expand Up @@ -249,23 +247,14 @@ void shouldMatchWithLineSeparatorCustomMatcher() {
@Timeout(1)
void shouldRunDiffBeforeTimeout() throws URISyntaxException, IOException {
//noinspection DataFlowIssue
var actual = Files.readString(
Paths.get(this.getClass().getResource("/big-json-with-common-keys-actual.json").toURI())
);
var actual = resource("big-json-with-common-keys-actual.json");
//noinspection DataFlowIssue
var expected = Files.readString(
Paths.get(this.getClass().getResource("/big-json-with-common-keys-expected.json").toURI())
);
var expected = resource("big-json-with-common-keys-expected.json");
var cfg = commonConfig()
.withNumberComparator(new NormalisedNumberComparator())
.withOptions(Option.IGNORING_ARRAY_ORDER, Option.IGNORING_EXTRA_ARRAY_ITEMS, Option.IGNORING_EXTRA_FIELDS);
Diff diff = Diff.create(
expected,
actual,
"",
"",
cfg
);
.withNumberComparator(new NormalisedNumberComparator())
.withOptions(
Option.IGNORING_ARRAY_ORDER, Option.IGNORING_EXTRA_ARRAY_ITEMS, Option.IGNORING_EXTRA_FIELDS);
Diff diff = Diff.create(expected, actual, "", "", cfg);
diff.similar();
}

Expand Down Expand Up @@ -323,7 +312,8 @@ public boolean compare(BigDecimal expectedValue, BigDecimal actualValue, BigDeci
var normalisedExpectedValue = expectedValue.stripTrailingZeros();
var normalisedActualValue = actualValue.stripTrailingZeros();
if (tolerance != null) {
var diff = normalisedExpectedValue.subtract(normalisedActualValue).abs();
var diff =
normalisedExpectedValue.subtract(normalisedActualValue).abs();
return diff.compareTo(tolerance) <= 0;
} else {
return normalisedExpectedValue.equals(normalisedActualValue);
Expand Down

0 comments on commit 567c5ce

Please sign in to comment.