Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.archyoshi</groupId>
<artifactId>assertj-json</artifactId>
<version>0.1.2</version>
<version>0.1.3-SNAPSHOT</version>
<packaging>jar</packaging>

<name>AssertJ JSON</name>
Expand Down
119 changes: 110 additions & 9 deletions src/main/java/com/archyoshi/assertj/json/JsonAssertions.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@
import com.archyoshi.assertj.json.api.JsonComparisonAssert;
import com.archyoshi.assertj.json.api.JsonIterableAssert;
import com.archyoshi.assertj.json.api.JsonNodeAssert;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.archyoshi.assertj.json.api.JsonNodeLoader;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.nio.file.Path;

/**
Expand Down Expand Up @@ -83,7 +84,7 @@ public static JsonNodeAssert assertThat(final String json) {
* @return a new {@link JsonNodeAssert} instance
*/
public static JsonNodeAssert assertThat(final String json, final ObjectMapper mapper) {
return new JsonNodeAssert(parseJson(json, mapper), mapper);
return new JsonNodeAssert(JsonNodeLoader.toNode(json, mapper), mapper);
}

/**
Expand All @@ -92,7 +93,7 @@ public static JsonNodeAssert assertThat(final String json, final ObjectMapper ma
* <p>The file is read and parsed as JSON content. The default {@code ObjectMapper} is used.
*
* @param jsonFile the path to the JSON file to assert on
* @return a new {@link JsonNodeAssert} instance
* @return a new {@link JsonComparisonAssert} instance
* @throws AssertionError if the file cannot be read or contains invalid JSON
* @since 0.1.0
*/
Expand All @@ -111,6 +112,35 @@ public static JsonComparisonAssert assertThat(final Path jsonFile, final ObjectM
return new JsonComparisonAssert(jsonFile, mapper);
}

/**
* Creates a new assertion object for the given JSON file.
*
* <p>The file is read and parsed as JSON content. The default {@code ObjectMapper} is used.
*
* @param jsonFile the JSON file to assert on
* @return a new {@link JsonComparisonAssert} instance
* @throws AssertionError if the file cannot be read or contains invalid JSON
* @since 0.1.3
*/
public static JsonComparisonAssert assertThat(final File jsonFile) {
return assertThat(jsonFile, MAPPER);
}

/**
* Creates an assertion object for a JSON file parsed with the supplied mapper.
*
* @param jsonFile the JSON file to assert on
* @param mapper the mapper used to parse JSON
* @return a new {@link JsonComparisonAssert} instance
* @since 0.1.3
*/
public static JsonComparisonAssert assertThat(final File jsonFile, final ObjectMapper mapper) {
if (jsonFile == null) {
throw new AssertionError("Expected JSON file not to be null");
}
return assertThat(jsonFile.toPath(), mapper);
}

/**
* Creates iterable assertions for a JSON array node.
*
Expand All @@ -123,11 +153,82 @@ public static JsonIterableAssert assertThatArray(final JsonNode actual) {
return JsonIterableAssert.assertThat(actual);
}

private static JsonNode parseJson(final String json, final ObjectMapper mapper) {
try {
return mapper.readTree(json);
} catch (JsonProcessingException e) {
throw new AssertionError("Invalid JSON content: " + e.getOriginalMessage(), e);
}
/**
* Creates iterable assertions for a JSON array string.
*
* @param jsonArray the JSON array string
* @return an assertion object for the array elements
* @throws AssertionError if the string cannot be parsed or is not a JSON array
* @since 0.1.3
*/
public static JsonIterableAssert assertThatArray(final String jsonArray) {
return assertThatArray(jsonArray, MAPPER);
}

/**
* Creates iterable assertions for a JSON array string parsed with the supplied mapper.
*
* @param jsonArray the JSON array string
* @param mapper the mapper used to parse the string
* @return an assertion object for the array elements
* @throws AssertionError if the string cannot be parsed or is not a JSON array
* @since 0.1.3
*/
public static JsonIterableAssert assertThatArray(
final String jsonArray, final ObjectMapper mapper) {
return assertThatArray(JsonNodeLoader.toNode(jsonArray, mapper));
}

/**
* Creates iterable assertions for a JSON array file at the given path.
*
* @param jsonArrayPath the path to the JSON array file
* @return an assertion object for the array elements
* @throws AssertionError if the file cannot be read or is not a JSON array
* @since 0.1.3
*/
public static JsonIterableAssert assertThatArray(final Path jsonArrayPath) {
return assertThatArray(jsonArrayPath, MAPPER);
}

/**
* Creates iterable assertions for a JSON array file at the given path using the supplied
* mapper.
*
* @param jsonArrayPath the path to the JSON array file
* @param mapper the mapper used to parse JSON
* @return an assertion object for the array elements
* @throws AssertionError if the file cannot be read or is not a JSON array
* @since 0.1.3
*/
public static JsonIterableAssert assertThatArray(
final Path jsonArrayPath, final ObjectMapper mapper) {
return assertThatArray(JsonNodeLoader.toNode(jsonArrayPath, mapper));
}

/**
* Creates iterable assertions for a JSON array file.
*
* @param jsonArrayFile the JSON array file
* @return an assertion object for the array elements
* @throws AssertionError if the file cannot be read or is not a JSON array
* @since 0.1.3
*/
public static JsonIterableAssert assertThatArray(final File jsonArrayFile) {
return assertThatArray(jsonArrayFile, MAPPER);
}

/**
* Creates iterable assertions for a JSON array file using the supplied mapper.
*
* @param jsonArrayFile the JSON array file
* @param mapper the mapper used to parse JSON
* @return an assertion object for the array elements
* @throws AssertionError if the file cannot be read or is not a JSON array
* @since 0.1.3
*/
public static JsonIterableAssert assertThatArray(
final File jsonArrayFile, final ObjectMapper mapper) {
return assertThatArray(JsonNodeLoader.toNode(jsonArrayFile, mapper));
}
}
118 changes: 95 additions & 23 deletions src/main/java/com/archyoshi/assertj/json/api/JsonComparisonAssert.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -61,6 +62,23 @@ public JsonComparisonAssert(final Path actual, final ObjectMapper mapper) {
this.mapper = mapper;
}

/**
* Verifies that the actual JSON file has the same field names as the expected JSON node. Values
* are ignored, while nested object structure and array positions are preserved.
*
* @param expected the expected JSON node
* @return this assertion object
* @since 0.1.3
*/
public JsonComparisonAssert hasSameFieldsAs(final JsonNode expected) {
final JsonNode actualNode = actualJson();
if (!sameFields(actualNode, expected)) {
failWithActualExpectedAndMessage(
actualNode, expected, "Expected JSON files to have the same fields");
}
return this;
}

/**
* Verifies that the actual JSON file and expected JSON file contain the same field names.
* Values are ignored, while nested object structure and array positions are preserved.
Expand All @@ -69,7 +87,18 @@ public JsonComparisonAssert(final Path actual, final ObjectMapper mapper) {
* @return this assertion object
*/
public JsonComparisonAssert hasSameFieldsAs(final Path expectedFile) {
return hasSameFieldsAs(readJson(expectedFile));
return hasSameFieldsAs(JsonNodeLoader.toNode(expectedFile, mapper));
}

/**
* Verifies that the actual JSON file and expected JSON file contain the same field names.
*
* @param expectedFile the expected JSON file
* @return this assertion object
* @since 0.1.3
*/
public JsonComparisonAssert hasSameFieldsAs(final File expectedFile) {
return hasSameFieldsAs(JsonNodeLoader.toNode(expectedFile, mapper));
}

/**
Expand All @@ -79,15 +108,20 @@ public JsonComparisonAssert hasSameFieldsAs(final Path expectedFile) {
* @return this assertion object
*/
public JsonComparisonAssert hasSameFieldsAs(final String expectedJson) {
return hasSameFieldsAs(parseJson(expectedJson));
return hasSameFieldsAs(JsonNodeLoader.toNode(expectedJson, mapper));
}

private JsonComparisonAssert hasSameFieldsAs(final JsonNode expected) {
JsonNode actualNode = actualJson();
if (!sameFields(actualNode, expected)) {
failWithActualExpectedAndMessage(
actualNode, expected, "Expected JSON files to have the same fields");
}
/**
* Verifies that the actual JSON file has the same parsed content as the expected JSON node.
* Formatting and object field ordering are ignored.
*
* @param expected the expected JSON node
* @return this assertion object
* @since 0.1.3
*/
public JsonComparisonAssert hasSameContentAs(final JsonNode expected) {
final JsonNode actualNode = actualJson();
assertThat(actualNode).as("JSON content from %s", actual).isEqualTo(expected);
return this;
}

Expand All @@ -99,7 +133,18 @@ private JsonComparisonAssert hasSameFieldsAs(final JsonNode expected) {
* @return this assertion object
*/
public JsonComparisonAssert hasSameContentAs(final Path expectedFile) {
return hasSameContentAs(readJson(expectedFile));
return hasSameContentAs(JsonNodeLoader.toNode(expectedFile, mapper));
}

/**
* Verifies that the actual JSON file and expected JSON file have the same parsed content.
*
* @param expectedFile the expected JSON file
* @return this assertion object
* @since 0.1.3
*/
public JsonComparisonAssert hasSameContentAs(final File expectedFile) {
return hasSameContentAs(JsonNodeLoader.toNode(expectedFile, mapper));
}

/**
Expand All @@ -109,33 +154,60 @@ public JsonComparisonAssert hasSameContentAs(final Path expectedFile) {
* @return this assertion object
*/
public JsonComparisonAssert hasSameContentAs(final String expectedJson) {
return hasSameContentAs(parseJson(expectedJson));
}

private JsonComparisonAssert hasSameContentAs(final JsonNode expected) {
JsonNode actualNode = actualJson();
assertThat(actualNode).as("JSON content from %s", actual).isEqualTo(expected);
return this;
return hasSameContentAs(JsonNodeLoader.toNode(expectedJson, mapper));
}

/**
* Verifies that the JSON document in the actual file contains the supplied JSON fragment.
* Object fragments may omit fields; nested fragments are checked recursively. Arrays are
* matched by position for the elements supplied in the fragment.
* Verifies that the JSON document in the actual file contains the supplied JSON node. Object
* fragments may omit fields; nested fragments are checked recursively. Arrays are matched by
* position for the elements supplied in the fragment.
*
* @param expectedFragment the JSON fragment to find
* @param expectedNode the JSON node to find
* @return this assertion object
* @since 0.1.3
*/
public JsonComparisonAssert partiallyContains(final String expectedFragment) {
JsonNode actualNode = actualJson();
JsonNode expectedNode = parseJson(expectedFragment);
public JsonComparisonAssert partiallyContains(final JsonNode expectedNode) {
final JsonNode actualNode = actualJson();
if (!contains(actualNode, expectedNode)) {
failWithActualExpectedAndMessage(
actualNode, expectedNode, "Expected JSON to partially contain");
}
return this;
}

/**
* Verifies that the JSON document in the actual file contains the supplied JSON fragment
* string.
*
* @param expectedFragment the JSON fragment to find
* @return this assertion object
*/
public JsonComparisonAssert partiallyContains(final String expectedFragment) {
return partiallyContains(JsonNodeLoader.toNode(expectedFragment, mapper));
}

/**
* Verifies that the JSON document in the actual file contains the supplied JSON file content.
*
* @param expectedFile the JSON file to find
* @return this assertion object
* @since 0.1.3
*/
public JsonComparisonAssert partiallyContains(final Path expectedFile) {
return partiallyContains(JsonNodeLoader.toNode(expectedFile, mapper));
}

/**
* Verifies that the JSON document in the actual file contains the supplied JSON file content.
*
* @param expectedFile the JSON file to find
* @return this assertion object
* @since 0.1.3
*/
public JsonComparisonAssert partiallyContains(final File expectedFile) {
return partiallyContains(JsonNodeLoader.toNode(expectedFile, mapper));
}

private boolean sameFields(final JsonNode actualNode, final JsonNode expectedNode) {
if (actualNode.isObject() && expectedNode.isObject()) {
if (actualNode.size() != expectedNode.size()) {
Expand Down
Loading
Loading