Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] JSON 比对 #1946 #2267

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
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
Prev Previous commit
Next Next commit
compare util optimize object or array is null, optimize compare objec…
…t type and array type
  • Loading branch information
imflyfish committed Mar 2, 2024
commit 0ad9fa87e64137deecfc0dcda4271b2564baf39b
33 changes: 30 additions & 3 deletions core/src/main/java/com/alibaba/fastjson2/util/CompareUtils.java
Original file line number Diff line number Diff line change
@@ -76,7 +76,7 @@ public static JSONObject sum(JSONArray list) {
}
}
result.put("equal", equal);
result.put("total", list.size());
result.put("total", addCount + removeCount + modifyCount + valueEqualCount);
result.put("valueEqualCount", valueEqualCount);
result.put("typeEqualCount", typeEqualCount);
result.put("diffCount", addCount + removeCount + modifyCount);
@@ -149,30 +149,55 @@ public static JSONObject compare(JSONObject json1, JSONObject json2) {
}
}

List<String> ignorePathPrefixList = new ArrayList<>();
outer:
for (String path : jsonPathList) {
boolean json1Contain = jsonPath1.containsKey(path);
boolean json2Contain = jsonPath2.containsKey(path);

JSONObject pathResult = new JSONObject();
pathResult.put("path", path);

for (String ignorePathPrefix : ignorePathPrefixList) {
if (path.startsWith(ignorePathPrefix)) {
continue outer;
}
}
if (json1Contain && !json2Contain) {
pathResult.put(FIELD_NAME_OF_VALUE_EQUAL, false);
pathResult.put(FIELD_NAME_OF_DIFF_TYPE, DIFF_TYPE_OF_REMOVE);
Object value1 = json1.getByPath(path);
if (value1 instanceof JSONObject || value1 instanceof JSONArray) {
ignorePathPrefixList.add(path);
}
pathResult.put("value1", value1);
} else if (!json1Contain && json2Contain) {
pathResult.put(FIELD_NAME_OF_VALUE_EQUAL, false);
pathResult.put(FIELD_NAME_OF_DIFF_TYPE, DIFF_TYPE_OF_ADD);
Object value2 = json2.getByPath(path);
pathResult.put("value2", value2);
if (value2 instanceof JSONObject || value2 instanceof JSONArray) {
ignorePathPrefixList.add(path);
}
} else if (json1Contain) {
Object value1 = json1.getByPath(path);
Object value2 = json2.getByPath(path);
pathResult.putAll(compareValue(value1, value2));
if (Boolean.FALSE.equals(pathResult.get(FIELD_NAME_OF_VALUE_EQUAL))) {
if ((value1 instanceof JSONObject && value2 instanceof JSONObject) || (value2 instanceof JSONArray && value1 instanceof JSONArray)) {
continue;
}
if ((value1 instanceof JSONObject && value2 instanceof JSONArray) || (value2 instanceof JSONObject && value1 instanceof JSONArray)) {
pathResult.put(FIELD_NAME_OF_VALUE_EQUAL, false);
pathResult.put(FIELD_NAME_OF_TYPE_EQUAL, false);
pathResult.put(FIELD_NAME_OF_DIFF_TYPE, DIFF_TYPE_OF_MODIFY);
pathResult.put("value1", value1);
pathResult.put("value2", value2);
ignorePathPrefixList.add(path);
} else {
pathResult.putAll(compareValue(value1, value2));
if (Boolean.FALSE.equals(pathResult.get(FIELD_NAME_OF_VALUE_EQUAL))) {
pathResult.put("value1", value1);
pathResult.put("value2", value2);
}
}
}

@@ -206,6 +231,8 @@ public static JSONObject convertWithJsonPath(JSONObject json) {
} else {
array = (JSONArray) value;
}
newMap.put((fieldName), value);

int index = 0;
for (Object item : array) {
String arrayFieldName = fieldName.concat("[".concat(index + "").concat("]"));
114 changes: 60 additions & 54 deletions core/src/test/java/com/alibaba/fastjson2/util/CompareUtilsTest.java
Original file line number Diff line number Diff line change
@@ -61,16 +61,13 @@ public void diffToArray3() {
"\t\t\"value2\":1\n" +
"\t},\n" +
"\t{\n" +
"\t\t\"path\":\"object.number\",\n" +
"\t\t\"path\":\"object\",\n" +
"\t\t\"valueEqual\":false,\n" +
"\t\t\"diffType\":\"REMOVE\",\n" +
"\t\t\"value1\":\"abc\"\n" +
"\t},\n" +
"\t{\n" +
"\t\t\"path\":\"object.string\",\n" +
"\t\t\"valueEqual\":false,\n" +
"\t\t\"diffType\":\"REMOVE\",\n" +
"\t\t\"value1\":123\n" +
"\t\t\"value1\":{\n" +
"\t\t\t\"number\":\"abc\",\n" +
"\t\t\t\"string\":123\n" +
"\t\t}\n" +
"\t},\n" +
"\t{\n" +
"\t\t\"path\":\"array[0].number\",\n" +
@@ -231,17 +228,14 @@ public void testDiff3() {
"\t\t\"diffType\":\"REMOVE\",\n" +
"\t\t\"value1\":123\n" +
"\t},\n" +
"\t\"object.number\":{\n" +
"\t\t\"path\":\"object.number\",\n" +
"\t\t\"valueEqual\":false,\n" +
"\t\t\"diffType\":\"REMOVE\",\n" +
"\t\t\"value1\":\"abc\"\n" +
"\t},\n" +
"\t\"object.string\":{\n" +
"\t\t\"path\":\"object.string\",\n" +
"\t\"object\":{\n" +
"\t\t\"path\":\"object\",\n" +
"\t\t\"valueEqual\":false,\n" +
"\t\t\"diffType\":\"REMOVE\",\n" +
"\t\t\"value1\":123\n" +
"\t\t\"value1\":{\n" +
"\t\t\t\"number\":\"abc\",\n" +
"\t\t\t\"string\":123\n" +
"\t\t}\n" +
"\t},\n" +
"\t\"array[0].number\":{\n" +
"\t\t\"path\":\"array[0].number\",\n" +
@@ -478,17 +472,14 @@ public void testCompare3() {
"\t\t\"diffType\":\"REMOVE\",\n" +
"\t\t\"value1\":123\n" +
"\t},\n" +
"\t\"object.number\":{\n" +
"\t\t\"path\":\"object.number\",\n" +
"\t\"object\":{\n" +
"\t\t\"path\":\"object\",\n" +
"\t\t\"valueEqual\":false,\n" +
"\t\t\"diffType\":\"REMOVE\",\n" +
"\t\t\"value1\":\"abc\"\n" +
"\t},\n" +
"\t\"object.string\":{\n" +
"\t\t\"path\":\"object.string\",\n" +
"\t\t\"valueEqual\":false,\n" +
"\t\t\"diffType\":\"REMOVE\",\n" +
"\t\t\"value1\":123\n" +
"\t\t\"value1\":{\n" +
"\t\t\t\"number\":\"abc\",\n" +
"\t\t\t\"string\":123\n" +
"\t\t}\n" +
"\t},\n" +
"\t\"array[0].number\":{\n" +
"\t\t\"path\":\"array[0].number\",\n" +
@@ -522,10 +513,12 @@ public void testCompareToArray3() {
"'string':123," +
"'object': {'number':'abc','string':123,}," +
"'array': [{'number':'abc','string':123,}]," +
"'field': [{'number':'abc','string':123,}]," +
"}");
JSONObject json2 = JSONObject.parseObject("{" +
"'number':1," +
"'array': [{'number':123,'string':'abc',}]," +
"'field': {'number':'abc','string':123,}," +
"}");
System.out.println(json1);
System.out.println(json2);
@@ -539,16 +532,13 @@ public void testCompareToArray3() {
"\t\t\"value1\":123\n" +
"\t},\n" +
"\t{\n" +
"\t\t\"path\":\"object.number\",\n" +
"\t\t\"path\":\"object\",\n" +
"\t\t\"valueEqual\":false,\n" +
"\t\t\"diffType\":\"REMOVE\",\n" +
"\t\t\"value1\":\"abc\"\n" +
"\t},\n" +
"\t{\n" +
"\t\t\"path\":\"object.string\",\n" +
"\t\t\"valueEqual\":false,\n" +
"\t\t\"diffType\":\"REMOVE\",\n" +
"\t\t\"value1\":123\n" +
"\t\t\"value1\":{\n" +
"\t\t\t\"number\":\"abc\",\n" +
"\t\t\t\"string\":123\n" +
"\t\t}\n" +
"\t},\n" +
"\t{\n" +
"\t\t\"path\":\"array[0].number\",\n" +
@@ -567,6 +557,22 @@ public void testCompareToArray3() {
"\t\t\"value2\":\"abc\"\n" +
"\t},\n" +
"\t{\n" +
"\t\t\"path\":\"field\",\n" +
"\t\t\"valueEqual\":false,\n" +
"\t\t\"typeEqual\":false,\n" +
"\t\t\"diffType\":\"MODIFY\",\n" +
"\t\t\"value1\":[\n" +
"\t\t\t{\n" +
"\t\t\t\t\"number\":\"abc\",\n" +
"\t\t\t\t\"string\":123\n" +
"\t\t\t}\n" +
"\t\t],\n" +
"\t\t\"value2\":{\n" +
"\t\t\t\"number\":\"abc\",\n" +
"\t\t\t\"string\":123\n" +
"\t\t}\n" +
"\t},\n" +
"\t{\n" +
"\t\t\"path\":\"number\",\n" +
"\t\t\"valueEqual\":false,\n" +
"\t\t\"diffType\":\"ADD\",\n" +
@@ -593,22 +599,21 @@ public void testCompareNull() {
System.out.println(result.toJSONString(JSONWriter.Feature.PrettyFormat));
String expected = "[\n" +
"\t{\n" +
"\t\t\"path\":\"array1[0]\",\n" +
"\t\t\"path\":\"array1\",\n" +
"\t\t\"valueEqual\":false,\n" +
"\t\t\"diffType\":\"REMOVE\",\n" +
"\t\t\"value1\":123\n" +
"\t\t\"value1\":[\n" +
"\t\t\t123\n" +
"\t\t]\n" +
"\t},\n" +
"\t{\n" +
"\t\t\"path\":\"object.number\",\n" +
"\t\t\"path\":\"object\",\n" +
"\t\t\"valueEqual\":false,\n" +
"\t\t\"diffType\":\"REMOVE\",\n" +
"\t\t\"value1\":\"abc\"\n" +
"\t},\n" +
"\t{\n" +
"\t\t\"path\":\"object.string\",\n" +
"\t\t\"valueEqual\":false,\n" +
"\t\t\"diffType\":\"REMOVE\",\n" +
"\t\t\"value1\":123\n" +
"\t\t\"value1\":{\n" +
"\t\t\t\"number\":\"abc\",\n" +
"\t\t\t\"string\":123\n" +
"\t\t}\n" +
"\t},\n" +
"\t{\n" +
"\t\t\"path\":\"array[0].number\",\n" +
@@ -655,16 +660,15 @@ public void testCompareArray() {
"\t\t\"value2\":1\n" +
"\t},\n" +
"\t{\n" +
"\t\t\"path\":\"array[0].number\",\n" +
"\t\t\"valueEqual\":false,\n" +
"\t\t\"diffType\":\"ADD\",\n" +
"\t\t\"value2\":123\n" +
"\t},\n" +
"\t{\n" +
"\t\t\"path\":\"array[0].string\",\n" +
"\t\t\"path\":\"array\",\n" +
"\t\t\"valueEqual\":false,\n" +
"\t\t\"diffType\":\"ADD\",\n" +
"\t\t\"value2\":\"abc\"\n" +
"\t\t\"value2\":[\n" +
"\t\t\t{\n" +
"\t\t\t\t\"number\":123,\n" +
"\t\t\t\t\"string\":\"abc\"\n" +
"\t\t\t}\n" +
"\t\t]\n" +
"\t}\n" +
"]";
assertEquals(expected, result.toString(JSONWriter.Feature.PrettyFormat));
@@ -715,12 +719,14 @@ public void testSum() {
"'remove':'abc'," +
"'object': {'number':'abc','string':123,}," +
"'array': [{'number':'abc','string':123,}]," +
"'field': [{'number':'abc','string':123,}]," +
"}");
JSONObject json2 = JSONObject.parseObject("{" +
"'number':1," +
"'new':'abc'," +
"'string':'abc'," +
"'array': [{'number':123,'string':'abc',}]," +
"'field': {'number':'abc','string':123,}," +
"}");
JSONArray list = CompareUtils.compareToArray(json1, json2);
System.out.println(list.toString(JSONWriter.Feature.PrettyFormat));
@@ -733,8 +739,8 @@ public void testSum() {
"\t\"typeEqualCount\":1,\n" +
"\t\"diffCount\":7,\n" +
"\t\"addCount\":1,\n" +
"\t\"removeCount\":3,\n" +
"\t\"modifyCount\":3\n" +
"\t\"removeCount\":2,\n" +
"\t\"modifyCount\":4\n" +
"}";
assertEquals(expected, result.toString(JSONWriter.Feature.PrettyFormat));
}
Loading