Skip to content

Instantly share code, notes, and snippets.

@kmajetic
Created September 9, 2015 20:02
Show Gist options
  • Save kmajetic/cd4b14e772dc4007e6f4 to your computer and use it in GitHub Desktop.
Save kmajetic/cd4b14e772dc4007e6f4 to your computer and use it in GitHub Desktop.
package org.kata.util.matchers;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.hamcrest.Description;
import org.json.JSONException;
import org.mockito.ArgumentMatcher;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import static org.mockito.Matchers.argThat;
/**
* Created by kmajetic on 14.05.15..
*/
public class JsonStringSkipMatcher extends ArgumentMatcher<String> {
public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
private final String expected;
private final String[] skipNames;
public JsonStringSkipMatcher(String expected, String[] skipNames) {
this.expected = expected;
this.skipNames = skipNames;
}
public static String jsonLike(String expected, String... skipNames) {
return argThat(new JsonStringSkipMatcher(expected, skipNames));
}
@Override
public boolean matches(Object argument) {
if (expected == null)
return argument == null;
if (!(argument instanceof String))
return false;
if (expected.equals(argument))
return true;
try {
return compare(expected, (String) argument);
} catch (JSONException | IOException e) {
return false;
}
}
private boolean compare(String expected, String actual) throws JSONException, IOException {
final ObjectNode expectedNode = OBJECT_MAPPER.readValue(expected, ObjectNode.class);
final ObjectNode actualNode = OBJECT_MAPPER.readValue(actual, ObjectNode.class);
Iterator<Map.Entry<String, JsonNode>> fields = expectedNode.fields();
while (fields.hasNext()) {
Map.Entry<String, JsonNode> entry = fields.next();
if (shouldSkip(entry.getKey())) {
continue;
}
JsonNode otherValue = actualNode.get(entry.getKey());
if (entry.getValue() == null && otherValue == null) {
continue;
}
if (otherValue == null || !otherValue.equals(entry.getValue())) {
return false;
}
}
return true;
}
private boolean shouldSkip(String key) {
for (String name : skipNames) {
if (name.equals(key)) {
return true;
}
}
return false;
}
@Override
public void describeTo(Description description) {
description.appendText(expected.toString());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment