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 add diffToArray and compareToArray
imflyfish committed Feb 26, 2024
commit e38a939be1ebcfbecb46be98deb91cade3e80112
25 changes: 20 additions & 5 deletions core/src/main/java/com/alibaba/fastjson2/util/CompareUtils.java
Original file line number Diff line number Diff line change
@@ -27,6 +27,7 @@ public class CompareUtils {

public static final String FIELD_NAME_OF_VALUE_EQUAL = "valueEqual";
public static final String FIELD_NAME_OF_TYPE_EQUAL = "typeEqual";
public static final String FIELD_NAME_OF_DIFF_TYPE = "diffType";

/**
* 比较json是否相同
@@ -40,6 +41,13 @@ public static boolean equals(JSONObject json1, JSONObject json2) {
return result.isEmpty();
}

public static JSONArray diffToArray(JSONObject json1, JSONObject json2) {
JSONObject diffJson = diff(json1, json2);
JSONArray array = new JSONArray(diffJson.size());
array.addAll(diffJson.values());
return array;
}

/**
* 比较json,只保留差异部分
*
@@ -56,6 +64,13 @@ public static JSONObject diff(JSONObject json1, JSONObject json2) {
return result;
}

public static JSONArray compareToArray(JSONObject json1, JSONObject json2) {
JSONObject diffJson = compare(json1, json2);
JSONArray array = new JSONArray(diffJson.size());
array.addAll(diffJson.values());
return array;
}

/**
* 比较json
*
@@ -85,13 +100,13 @@ public static JSONObject compare(JSONObject json1, JSONObject json2) {
pathResult.put("path", path);

if (json1Contain && !json2Contain) {
pathResult.put("equal", false);
pathResult.put("type", DIFF_TYPE_OF_REMOVE);
pathResult.put(FIELD_NAME_OF_VALUE_EQUAL, false);
pathResult.put(FIELD_NAME_OF_DIFF_TYPE, DIFF_TYPE_OF_REMOVE);
Object value1 = json1.getByPath(path);
pathResult.put("value1", value1);
} else if (!json1Contain && json2Contain) {
pathResult.put("equal", false);
pathResult.put("type", DIFF_TYPE_OF_ADD);
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);
} else if (json1Contain && json2Contain) {
@@ -101,7 +116,6 @@ public static JSONObject compare(JSONObject json1, JSONObject json2) {
if (Boolean.FALSE.equals(pathResult.get(FIELD_NAME_OF_VALUE_EQUAL))) {
pathResult.put("value1", value1);
pathResult.put("value2", value2);
pathResult.put("type", DIFF_TYPE_OF_MODIFY);
}
}

@@ -174,6 +188,7 @@ private static JSONObject compareValue(Object value1, Object value2) {
result.put(FIELD_NAME_OF_VALUE_EQUAL, equal);

if (!equal) {
result.put(FIELD_NAME_OF_DIFF_TYPE, DIFF_TYPE_OF_MODIFY);
if (value1 != null && value2 != null) {
boolean typeEqual = (value1.getClass().equals(value2.getClass()));
result.put(FIELD_NAME_OF_TYPE_EQUAL, typeEqual);
Original file line number Diff line number Diff line change
@@ -1,11 +1,52 @@
package com.alibaba.fastjson2.util;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter;
import org.junit.Assert;
import org.junit.jupiter.api.Test;

class CompareUtilsTest {
@Test
public void diffToArray() {
JSONObject json1 = JSONObject.parseObject("{" +
"'number':1," +
"'string':'abc'," +
"'object': {'number':1,'string':'abc',}," +
"'array': [{'number':1,'string':'abc',}]," +
"}");
JSONObject json2 = JSONObject.parseObject("{" +
"'number':1," +
"'string':'abc'," +
"'object': {'number':1,'string':'abc',}," +
"'array': [{'number':1,'string':'abc',}]," +
"}");
JSONArray result = CompareUtils.diffToArray(json1, json2);
System.out.println(result.toJSONString(JSONWriter.Feature.PrettyFormat));
String expected = "[]";
Assert.assertEquals(expected, result.toString());
}

@Test
public void diffToArray3() {
JSONObject json1 = JSONObject.parseObject("{" +
// "'number':'abc'," +
"'string':123," +
"'object': {'number':'abc','string':123,}," +
"'array': [{'number':'abc','string':123,}]," +
"}");
JSONObject json2 = JSONObject.parseObject("{" +
"'number':1," +
// "'string':'abc'," +
// "'object': {'number':123,'string':'abc',}," +
"'array': [{'number':123,'string':'abc',}]," +
"}");
JSONArray result = CompareUtils.diffToArray(json1, json2);
System.out.println(result.toJSONString(JSONWriter.Feature.PrettyFormat));
String expected = "[{\"path\":\"string\",\"valueEqual\":false,\"diffType\":\"REMOVE\",\"value1\":123},{\"path\":\"object.number\",\"valueEqual\":false,\"diffType\":\"REMOVE\",\"value1\":\"abc\"},{\"path\":\"object.string\",\"valueEqual\":false,\"diffType\":\"REMOVE\",\"value1\":123},{\"path\":\"array[0].number\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":false,\"value1\":\"abc\",\"value2\":123},{\"path\":\"array[0].string\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":false,\"value1\":123,\"value2\":\"abc\"},{\"path\":\"number\",\"valueEqual\":false,\"diffType\":\"ADD\",\"value2\":1}]";
Assert.assertEquals(expected, result.toString());
}

@Test
public void testDiff() {
JSONObject json1 = JSONObject.parseObject("{" +
@@ -62,7 +103,7 @@ public void testDiff2() {
"}");
JSONObject result = CompareUtils.diff(json1, json2);
System.out.println(result.toJSONString(JSONWriter.Feature.PrettyFormat));
String expected = "{\"number\":{\"path\":\"number\",\"valueEqual\":false,\"typeEqual\":false,\"value1\":\"abc\",\"value2\":1,\"type\":\"MODIFY\"},\"string\":{\"path\":\"string\",\"valueEqual\":false,\"typeEqual\":false,\"value1\":123,\"value2\":\"abc\",\"type\":\"MODIFY\"},\"object.number\":{\"path\":\"object.number\",\"valueEqual\":false,\"typeEqual\":false,\"value1\":\"abc\",\"value2\":123,\"type\":\"MODIFY\"},\"object.string\":{\"path\":\"object.string\",\"valueEqual\":false,\"typeEqual\":false,\"value1\":123,\"value2\":\"abc\",\"type\":\"MODIFY\"},\"array[0].number\":{\"path\":\"array[0].number\",\"valueEqual\":false,\"typeEqual\":false,\"value1\":\"abc\",\"value2\":123,\"type\":\"MODIFY\"},\"array[0].string\":{\"path\":\"array[0].string\",\"valueEqual\":false,\"typeEqual\":false,\"value1\":123,\"value2\":\"abc\",\"type\":\"MODIFY\"}}";
String expected = "{\"number\":{\"path\":\"number\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":false,\"value1\":\"abc\",\"value2\":1},\"string\":{\"path\":\"string\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":false,\"value1\":123,\"value2\":\"abc\"},\"object.number\":{\"path\":\"object.number\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":false,\"value1\":\"abc\",\"value2\":123},\"object.string\":{\"path\":\"object.string\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":false,\"value1\":123,\"value2\":\"abc\"},\"array[0].number\":{\"path\":\"array[0].number\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":false,\"value1\":\"abc\",\"value2\":123},\"array[0].string\":{\"path\":\"array[0].string\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":false,\"value1\":123,\"value2\":\"abc\"}}";
Assert.assertEquals(expected, result.toString());
}

@@ -82,7 +123,7 @@ public void testDiff3() {
"}");
JSONObject result = CompareUtils.diff(json1, json2);
System.out.println(result.toJSONString(JSONWriter.Feature.PrettyFormat));
String expected = "{\"string\":{\"path\":\"string\",\"equal\":false,\"type\":\"REMOVE\",\"value1\":123},\"object.number\":{\"path\":\"object.number\",\"equal\":false,\"type\":\"REMOVE\",\"value1\":\"abc\"},\"object.string\":{\"path\":\"object.string\",\"equal\":false,\"type\":\"REMOVE\",\"value1\":123},\"array[0].number\":{\"path\":\"array[0].number\",\"valueEqual\":false,\"typeEqual\":false,\"value1\":\"abc\",\"value2\":123,\"type\":\"MODIFY\"},\"array[0].string\":{\"path\":\"array[0].string\",\"valueEqual\":false,\"typeEqual\":false,\"value1\":123,\"value2\":\"abc\",\"type\":\"MODIFY\"},\"number\":{\"path\":\"number\",\"equal\":false,\"type\":\"ADD\",\"value2\":1}}";
String expected = "{\"string\":{\"path\":\"string\",\"valueEqual\":false,\"diffType\":\"REMOVE\",\"value1\":123},\"object.number\":{\"path\":\"object.number\",\"valueEqual\":false,\"diffType\":\"REMOVE\",\"value1\":\"abc\"},\"object.string\":{\"path\":\"object.string\",\"valueEqual\":false,\"diffType\":\"REMOVE\",\"value1\":123},\"array[0].number\":{\"path\":\"array[0].number\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":false,\"value1\":\"abc\",\"value2\":123},\"array[0].string\":{\"path\":\"array[0].string\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":false,\"value1\":123,\"value2\":\"abc\"},\"number\":{\"path\":\"number\",\"valueEqual\":false,\"diffType\":\"ADD\",\"value2\":1}}";
Assert.assertEquals(expected, result.toString());
}

@@ -124,7 +165,7 @@ public void testCompare1() {
System.out.println(json2);
JSONObject result = CompareUtils.compare(json1, json2);
System.out.println(result.toJSONString(JSONWriter.Feature.PrettyFormat));
String expected = "{\"number\":{\"path\":\"number\",\"valueEqual\":false,\"typeEqual\":true,\"value1\":11,\"value2\":1,\"type\":\"MODIFY\"},\"string\":{\"path\":\"string\",\"valueEqual\":false,\"typeEqual\":true,\"value1\":\"abcd\",\"value2\":\"abc\",\"type\":\"MODIFY\"},\"object.number\":{\"path\":\"object.number\",\"valueEqual\":false,\"typeEqual\":true,\"value1\":11,\"value2\":1,\"type\":\"MODIFY\"},\"object.string\":{\"path\":\"object.string\",\"valueEqual\":false,\"typeEqual\":true,\"value1\":\"abcd\",\"value2\":\"abc\",\"type\":\"MODIFY\"},\"array[0].number\":{\"path\":\"array[0].number\",\"valueEqual\":false,\"typeEqual\":true,\"value1\":11,\"value2\":1,\"type\":\"MODIFY\"},\"array[0].string\":{\"path\":\"array[0].string\",\"valueEqual\":false,\"typeEqual\":true,\"value1\":\"abcd\",\"value2\":\"abc\",\"type\":\"MODIFY\"}}";
String expected = "{\"number\":{\"path\":\"number\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":true,\"value1\":11,\"value2\":1},\"string\":{\"path\":\"string\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":true,\"value1\":\"abcd\",\"value2\":\"abc\"},\"object.number\":{\"path\":\"object.number\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":true,\"value1\":11,\"value2\":1},\"object.string\":{\"path\":\"object.string\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":true,\"value1\":\"abcd\",\"value2\":\"abc\"},\"array[0].number\":{\"path\":\"array[0].number\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":true,\"value1\":11,\"value2\":1},\"array[0].string\":{\"path\":\"array[0].string\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":true,\"value1\":\"abcd\",\"value2\":\"abc\"}}";
Assert.assertEquals(expected, result.toString());
}

@@ -146,7 +187,7 @@ public void testCompare2() {
System.out.println(json2);
JSONObject result = CompareUtils.compare(json1, json2);
System.out.println(result.toJSONString(JSONWriter.Feature.PrettyFormat));
String expected = "{\"number\":{\"path\":\"number\",\"valueEqual\":false,\"typeEqual\":false,\"value1\":\"abc\",\"value2\":1,\"type\":\"MODIFY\"},\"string\":{\"path\":\"string\",\"valueEqual\":false,\"typeEqual\":false,\"value1\":123,\"value2\":\"abc\",\"type\":\"MODIFY\"},\"object.number\":{\"path\":\"object.number\",\"valueEqual\":false,\"typeEqual\":false,\"value1\":\"abc\",\"value2\":123,\"type\":\"MODIFY\"},\"object.string\":{\"path\":\"object.string\",\"valueEqual\":false,\"typeEqual\":false,\"value1\":123,\"value2\":\"abc\",\"type\":\"MODIFY\"},\"array[0].number\":{\"path\":\"array[0].number\",\"valueEqual\":false,\"typeEqual\":false,\"value1\":\"abc\",\"value2\":123,\"type\":\"MODIFY\"},\"array[0].string\":{\"path\":\"array[0].string\",\"valueEqual\":false,\"typeEqual\":false,\"value1\":123,\"value2\":\"abc\",\"type\":\"MODIFY\"}}";
String expected = "{\"number\":{\"path\":\"number\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":false,\"value1\":\"abc\",\"value2\":1},\"string\":{\"path\":\"string\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":false,\"value1\":123,\"value2\":\"abc\"},\"object.number\":{\"path\":\"object.number\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":false,\"value1\":\"abc\",\"value2\":123},\"object.string\":{\"path\":\"object.string\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":false,\"value1\":123,\"value2\":\"abc\"},\"array[0].number\":{\"path\":\"array[0].number\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":false,\"value1\":\"abc\",\"value2\":123},\"array[0].string\":{\"path\":\"array[0].string\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":false,\"value1\":123,\"value2\":\"abc\"}}";
Assert.assertEquals(expected, result.toString());
}

@@ -168,7 +209,29 @@ public void testCompare3() {
System.out.println(json2);
JSONObject result = CompareUtils.compare(json1, json2);
System.out.println(result.toJSONString(JSONWriter.Feature.PrettyFormat));
String expected = "{\"string\":{\"path\":\"string\",\"equal\":false,\"type\":\"REMOVE\",\"value1\":123},\"object.number\":{\"path\":\"object.number\",\"equal\":false,\"type\":\"REMOVE\",\"value1\":\"abc\"},\"object.string\":{\"path\":\"object.string\",\"equal\":false,\"type\":\"REMOVE\",\"value1\":123},\"array[0].number\":{\"path\":\"array[0].number\",\"valueEqual\":false,\"typeEqual\":false,\"value1\":\"abc\",\"value2\":123,\"type\":\"MODIFY\"},\"array[0].string\":{\"path\":\"array[0].string\",\"valueEqual\":false,\"typeEqual\":false,\"value1\":123,\"value2\":\"abc\",\"type\":\"MODIFY\"},\"number\":{\"path\":\"number\",\"equal\":false,\"type\":\"ADD\",\"value2\":1}}";
String expected = "{\"string\":{\"path\":\"string\",\"valueEqual\":false,\"diffType\":\"REMOVE\",\"value1\":123},\"object.number\":{\"path\":\"object.number\",\"valueEqual\":false,\"diffType\":\"REMOVE\",\"value1\":\"abc\"},\"object.string\":{\"path\":\"object.string\",\"valueEqual\":false,\"diffType\":\"REMOVE\",\"value1\":123},\"array[0].number\":{\"path\":\"array[0].number\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":false,\"value1\":\"abc\",\"value2\":123},\"array[0].string\":{\"path\":\"array[0].string\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":false,\"value1\":123,\"value2\":\"abc\"},\"number\":{\"path\":\"number\",\"valueEqual\":false,\"diffType\":\"ADD\",\"value2\":1}}";
Assert.assertEquals(expected, result.toString());
}

@Test
public void testCompareToArray3() {
JSONObject json1 = JSONObject.parseObject("{" +
// "'number':'abc'," +
"'string':123," +
"'object': {'number':'abc','string':123,}," +
"'array': [{'number':'abc','string':123,}]," +
"}");
JSONObject json2 = JSONObject.parseObject("{" +
"'number':1," +
// "'string':'abc'," +
// "'object': {'number':123,'string':'abc',}," +
"'array': [{'number':123,'string':'abc',}]," +
"}");
System.out.println(json1);
System.out.println(json2);
JSONArray result = CompareUtils.compareToArray(json1, json2);
System.out.println(result.toJSONString(JSONWriter.Feature.PrettyFormat));
String expected = "[{\"path\":\"string\",\"valueEqual\":false,\"diffType\":\"REMOVE\",\"value1\":123},{\"path\":\"object.number\",\"valueEqual\":false,\"diffType\":\"REMOVE\",\"value1\":\"abc\"},{\"path\":\"object.string\",\"valueEqual\":false,\"diffType\":\"REMOVE\",\"value1\":123},{\"path\":\"array[0].number\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":false,\"value1\":\"abc\",\"value2\":123},{\"path\":\"array[0].string\",\"valueEqual\":false,\"diffType\":\"MODIFY\",\"typeEqual\":false,\"value1\":123,\"value2\":\"abc\"},{\"path\":\"number\",\"valueEqual\":false,\"diffType\":\"ADD\",\"value2\":1}]";
Assert.assertEquals(expected, result.toString());
}