Skip to content

Commit

Permalink
Adding FAIL_FAST option (#785)
Browse files Browse the repository at this point in the history
  • Loading branch information
lukas-krecan authored Jul 3, 2024
1 parent 3ed8176 commit 8480045
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 21 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ ij_java_for_statement_wrap = off
ij_java_generate_final_locals = false
ij_java_generate_final_parameters = false
ij_java_if_brace_force = never
ij_java_imports_layout = *,|,javax.**,java.**,|,$*
ij_java_imports_layout = $*,|,*
ij_java_indent_case_from_switch = true
ij_java_insert_inner_class_imports = false
ij_java_insert_override_annotation = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,10 @@ public enum Option {
* Ignores values but fails if value types are different.
* When using within {@link ConfigurationWhen#then(Option, Option...)}, path to the node with ignored value should be passed.
*/
IGNORING_VALUES
IGNORING_VALUES,

/**
* Stops comparison at the first difference. Can bring performance boots to use-cases that do not need the full list of all differences.
*/
FAIL_FAST
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@
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.Option.FAIL_FAST;
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 @@ -98,15 +99,12 @@ private static boolean isSimilar(Path path, Configuration configuration, Node ex
expected,
actual,
Path.create("", path.toElement(i).getFullPath()),
configuration.withDifferenceListener(failFastDifferenceListener),
configuration.withDifferenceListener(dummyDifferenceListener()).withOptions(FAIL_FAST),
NULL_LOGGER,
NULL_LOGGER,
DEFAULT_DIFFERENCE_STRING);
try {
return diff.similar();
} catch (DifferenceFoundException e) {
return false;
}

return diff.similar();
}

ComparisonMatrix compare() {
Expand Down Expand Up @@ -249,15 +247,4 @@ 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 @@ -16,6 +16,7 @@
package net.javacrumbs.jsonunit.core.internal;

import static java.util.Collections.emptySet;
import static net.javacrumbs.jsonunit.core.Option.FAIL_FAST;
import static net.javacrumbs.jsonunit.core.Option.IGNORING_ARRAY_ORDER;
import static net.javacrumbs.jsonunit.core.Option.IGNORING_EXTRA_ARRAY_ITEMS;
import static net.javacrumbs.jsonunit.core.Option.IGNORING_EXTRA_FIELDS;
Expand Down Expand Up @@ -152,7 +153,11 @@ private void compare() {
if (part.isMissingNode()) {
structureDifferenceFound(context, "Missing node in path \"%s\".", startPath);
} else {
compareNodes(context);
try {
compareNodes(context);
} catch (FailedFastException e) {
// ignore, the difference is already in the `differences` list.
}
}
compared = true;

Expand Down Expand Up @@ -634,15 +639,24 @@ private List<Node> asList(Iterator<Node> elements) {

private void structureDifferenceFound(Context context, String message, Object... arguments) {
differences.add(new JsonDifference(context, message, arguments));
possiblyFailFast(context);
}

private void valueDifferenceFound(Context context, String message, Object... arguments) {
differences.add(new JsonDifference(context, message, arguments));
possiblyFailFast(context);
}

private void reportValueDifference(Context context, String message, Object... arguments) {
reportDifference(DifferenceImpl.different(context));
valueDifferenceFound(context, message, arguments);
possiblyFailFast(context);
}

private void possiblyFailFast(Context context) {
if (hasOption(context.actualPath(), FAIL_FAST)) {
throw new FailedFastException();
}
}

private Set<String> commonFields(Map<String, Node> expectedFields, Map<String, Node> actualFields) {
Expand Down Expand Up @@ -719,4 +733,14 @@ private static JsonUnitLogger createLogger(String name) {
return NULL_LOGGER;
}
}

/**
* Exception throw on the first difference when FAIL_FAST option is on.
*/
private static final class FailedFastException extends RuntimeException {
@Override
public synchronized Throwable fillInStackTrace() {
return this;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2281,6 +2281,18 @@ void shouldIgnoreMultiplePathsWrittenSeparately() {
.isEqualTo("{\"c\":3}");
}

@Test
void shouldFailFast() {
assertThatThrownBy(() -> assertThatJson("{\"a\":{\"a1\": 1},\"b\":{\"b1\": 1}}")
.withOptions(Option.FAIL_FAST)
.isEqualTo("{\"a\":{\"a1\": 2},\"b\":{\"b1\": 2}}"))
.hasMessage(
"""
JSON documents are different:
Different value found in node "a.a1", expected: <2> but was: <1>.
""");
}

private static final String json =
"""
{
Expand Down

0 comments on commit 8480045

Please sign in to comment.