Skip to content
Open
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
9 changes: 9 additions & 0 deletions src/main/java/org/skyscreamer/jsonassert/JSONCompare.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.json.JSONObject;
import org.json.JSONString;
import org.skyscreamer.jsonassert.comparator.DefaultComparator;
import org.skyscreamer.jsonassert.comparator.ExtendNullComparator;
import org.skyscreamer.jsonassert.comparator.JSONComparator;

/**
Expand All @@ -30,7 +31,15 @@ public final class JSONCompare {
private JSONCompare() {
}

/**
* Get the corresponding comparator according to the compare mode
* @param mode, the compare mode
* @return a instance of ExtendNullComparator if the mode is EXTEND_WITH_NULL
*/
private static JSONComparator getComparatorForMode(JSONCompareMode mode) {
if(mode.isNullExtensible()){
return new ExtendNullComparator(mode);
}
return new DefaultComparator(mode);
}

Expand Down
23 changes: 22 additions & 1 deletion src/main/java/org/skyscreamer/jsonassert/JSONCompareMode.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,28 @@ public enum JSONCompareMode {
/**
* Strict order checking. Extensible, and strict array ordering.
*/
STRICT_ORDER(true, true);
STRICT_ORDER(true, true),

/**
* Extensible checking, and only null values can be extended
*/
EXTEND_WITH_NULL(true, false,true);

private final boolean _extensible;
private final boolean _strictOrder;
private boolean _isNullExtensible=false;

JSONCompareMode(boolean extensible, boolean strictOrder) {
_extensible = extensible;
_strictOrder = strictOrder;
}


JSONCompareMode(boolean extensible, boolean strictOrder,boolean isNullExtensible){
_extensible = extensible;
_strictOrder = strictOrder;
_isNullExtensible=isNullExtensible;
}

/**
* Is extensible
Expand Down Expand Up @@ -114,4 +127,12 @@ public JSONCompareMode withExtensible(boolean extensible) {
return hasStrictOrder() ? STRICT : NON_EXTENSIBLE;
}
}

/**
* Get whether the mode allow extend with null values
* @return true if the mode allow extend with null values
*/
public boolean isNullExtensible(){
return _isNullExtensible;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package org.skyscreamer.jsonassert.comparator;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.skyscreamer.jsonassert.JSONCompareMode;
import org.skyscreamer.jsonassert.JSONCompareResult;
import java.util.HashSet;
import java.util.Set;

import static org.skyscreamer.jsonassert.comparator.JSONCompareUtil.getKeys;

/*
实现的思路是,原先的代码根据不同的mode使用不同的比较器,于是我新建一个类继承原先的比较器,然后重写里面的比较方法。
当使用extend_with_null这种mode时,修改代码使用我新建的比较器。
*/
public class ExtendNullComparator extends DefaultComparator {

public ExtendNullComparator(JSONCompareMode mode){
super(mode);
}

// CS304 Issue link: https://github.com/skyscreamer/JSONassert/issues/120
/**
* Compare two JSON Object with mode EXTEND_WITH_NULL, only null values can be extended
* in actual JSON Object.
* The compare is implemented in a recursive way and if non-match happens the compare will end
* @param prefix
* @param expected
* @param actual
* @param result
* @throws JSONException
*/
public void compareJSON(String prefix, JSONObject expected, JSONObject actual, JSONCompareResult result) throws JSONException {
Set<String> expectedKeys = getKeys(expected);
for (String key : expectedKeys) {
Object expectedValue = expected.get(key);
if (actual.has(key)) {
Object actualValue = actual.get(key);
compareValues(key, expectedValue, actualValue, result);
} else {
result.missing("", key);
}
}

Set<String> actualKeys=getKeys(actual);
for(String key : actualKeys){
Object actualValue =actual.get(key);
if(!expected.has(key) && (!actualValue.toString().equals("null"))){
result.fail("Extended actual value from key \""+key+"\" is Not Null");
break;
}
}
}


// CS304 Issue link: https://github.com/skyscreamer/JSONassert/issues/120
/**
* Compare two JSON Array with mode EXTEND_WITH_NULL, only null values can be extended
* in actual JSON Array.
* The compare is implemented in a recursive way and if non-match happens the compare will end
* @param prefix
* @param expected
* @param actual
* @param result
* @throws JSONException
*/
public void compareJSONArray(String prefix, JSONArray expected, JSONArray actual, JSONCompareResult result) throws JSONException {
Set<Integer> matched = new HashSet<Integer>();
for (int i = 0; i < expected.length(); ++i) {
Object expectedElement = JSONCompareUtil.getObjectOrNull(expected, i);
boolean matchFound = false;
for (int j = 0; j < actual.length(); ++j) {
Object actualElement = JSONCompareUtil.getObjectOrNull(actual, j);
if ((expectedElement == null && actualElement != null) || (expectedElement != null && actualElement == null)) {
continue;
}
if (matched.contains(j) || !actualElement.getClass().equals(expectedElement.getClass())) {
continue;
}
if (expectedElement instanceof JSONObject) {
if (compareJSON((JSONObject) expectedElement, (JSONObject) actualElement).passed()) {
matched.add(j);
matchFound = true;
break;
}
} else if (expectedElement instanceof JSONArray) {
if (compareJSON((JSONArray) expectedElement, (JSONArray) actualElement).passed()) {
matched.add(j);
matchFound = true;
break;
}
} else if (expectedElement.equals(actualElement)) {
matched.add(j);
matchFound = true;
break;
}
}
if (!matchFound) {
result.fail("[" + i + "] Could not find match for element " + expectedElement);
return;
}
}

for(int i = 0; i < actual.length(); ++i){
if(!matched.contains(i) && (!actual.get(i).toString().equals("null"))){
result.fail("Extended actual value "+actual.get(i).toString()+" is Not Null");
break;
}
}
}

}