| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593 |
- #include "testBase.h"
- static void testCompareEdgeCases(void)
- {
- // 测试对象键值对顺序对比较的影响
- // RyanJson 的对象比较是无序的:键值对顺序不同也应视为相同
- RyanJson_t json1 = RyanJsonCreateObject();
- RyanJsonAddIntToObject(json1, "a", 1);
- RyanJsonAddIntToObject(json1, "b", 2);
- RyanJson_t json2 = RyanJsonCreateObject();
- RyanJsonAddIntToObject(json2, "b", 2);
- RyanJsonAddIntToObject(json2, "a", 1); // 顺序不同
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(json1, json2), "顺序不同的对象比较应返回 True (RyanJson 是无序比较)");
- RyanJsonDelete(json1);
- RyanJsonDelete(json2);
- }
- static void testCompareObjectOrderPaths(void)
- {
- RyanJson_t left = RyanJsonCreateObject();
- RyanJson_t rightOrdered = RyanJsonCreateObject();
- RyanJson_t rightUnordered = RyanJsonCreateObject();
- TEST_ASSERT_NOT_NULL(left);
- TEST_ASSERT_NOT_NULL(rightOrdered);
- TEST_ASSERT_NOT_NULL(rightUnordered);
- // 同序构造:覆盖对象比较同序快路径
- for (int32_t i = 0; i < 64; i++)
- {
- char key[16];
- RyanJsonSnprintf(key, sizeof(key), "k%" PRId32, i);
- TEST_ASSERT_TRUE(RyanJsonAddIntToObject(left, key, i));
- TEST_ASSERT_TRUE(RyanJsonAddIntToObject(rightOrdered, key, i));
- }
- // 逆序构造:覆盖对象比较按 key 回退查找路径
- for (int32_t i = 63; i >= 0; i--)
- {
- char key[16];
- RyanJsonSnprintf(key, sizeof(key), "k%" PRId32, i);
- TEST_ASSERT_TRUE(RyanJsonAddIntToObject(rightUnordered, key, i));
- }
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(left, rightOrdered), "同序对象比较应返回 True");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(left, rightUnordered), "乱序对象比较应返回 True");
- RyanJsonDelete(left);
- RyanJsonDelete(rightOrdered);
- RyanJsonDelete(rightUnordered);
- }
- static void testCompareScalarAndTypeMatrix(void)
- {
- RyanJson_t intLeft = RyanJsonCreateInt(NULL, 10);
- RyanJson_t intRight = RyanJsonCreateInt(NULL, 11);
- RyanJson_t doubleCloseLeft = RyanJsonCreateDouble(NULL, 1.0);
- RyanJson_t doubleCloseRight = RyanJsonCreateDouble(NULL, 1.0 + (RyanJsonAbsTolerance / 2.0));
- RyanJson_t doubleFarLeft = RyanJsonCreateDouble(NULL, 1.0);
- RyanJson_t doubleFarRight = RyanJsonCreateDouble(NULL, 1.0 + (RyanJsonAbsTolerance * 100.0));
- RyanJson_t strLeft = RyanJsonCreateString(NULL, "alpha");
- RyanJson_t strRight = RyanJsonCreateString(NULL, "beta");
- RyanJson_t typeInt = RyanJsonCreateInt(NULL, 1);
- RyanJson_t typeDouble = RyanJsonCreateDouble(NULL, 1.0);
- RyanJson_t typeString = RyanJsonCreateString(NULL, "1");
- TEST_ASSERT_NOT_NULL(intLeft);
- TEST_ASSERT_NOT_NULL(intRight);
- TEST_ASSERT_NOT_NULL(doubleCloseLeft);
- TEST_ASSERT_NOT_NULL(doubleCloseRight);
- TEST_ASSERT_NOT_NULL(doubleFarLeft);
- TEST_ASSERT_NOT_NULL(doubleFarRight);
- TEST_ASSERT_NOT_NULL(strLeft);
- TEST_ASSERT_NOT_NULL(strRight);
- TEST_ASSERT_NOT_NULL(typeInt);
- TEST_ASSERT_NOT_NULL(typeDouble);
- TEST_ASSERT_NOT_NULL(typeString);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(intLeft, intRight), "int 值不同时 Compare 应返回 False");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(intLeft, intRight), "int 值不同时 CompareOnlyKey 应返回 True");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(doubleCloseLeft, doubleCloseRight), "double 在容差内应判等");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(doubleFarLeft, doubleFarRight), "double 超过容差应不相等");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(doubleFarLeft, doubleFarRight), "double 值不同时 CompareOnlyKey 应返回 True");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(strLeft, strRight), "string 值不同时 Compare 应返回 False");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(strLeft, strRight), "string 值不同时 CompareOnlyKey 应返回 True");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(typeInt, typeString), "类型不同时 Compare 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(typeInt, typeString), "类型不同时 CompareOnlyKey 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(typeInt, typeDouble), "int/double 即使数值相同,类型不同也应不相等");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(typeInt, typeDouble),
- "CompareOnlyKey 忽略 number 具体子类型,int/double 应视为相等");
- RyanJsonDelete(intLeft);
- RyanJsonDelete(intRight);
- RyanJsonDelete(doubleCloseLeft);
- RyanJsonDelete(doubleCloseRight);
- RyanJsonDelete(doubleFarLeft);
- RyanJsonDelete(doubleFarRight);
- RyanJsonDelete(strLeft);
- RyanJsonDelete(strRight);
- RyanJsonDelete(typeInt);
- RyanJsonDelete(typeDouble);
- RyanJsonDelete(typeString);
- }
- static void testCompareNumberSubtypeInContainers(void)
- {
- RyanJson_t left = RyanJsonParse("{\"n\":1,\"arr\":[1,2.0],\"obj\":{\"x\":3,\"y\":4.0}}");
- RyanJson_t right = RyanJsonParse("{\"obj\":{\"y\":4,\"x\":3.0},\"arr\":[1.0,2],\"n\":1.0}");
- RyanJson_t rightTypeMismatch = RyanJsonParse("{\"obj\":{\"y\":4,\"x\":\"3\"},\"arr\":[1.0,2],\"n\":1.0}");
- TEST_ASSERT_NOT_NULL(left);
- TEST_ASSERT_NOT_NULL(right);
- TEST_ASSERT_NOT_NULL(rightTypeMismatch);
- // 全量比较要求数值子类型一致;仅比较 key 时允许 int/double 混用
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(left, right), "容器中 int/double 子类型不同,Compare 应返回 False");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(left, right),
- "容器中 int/double 子类型不同,但结构一致时 CompareOnlyKey 应返回 True");
- // 数值与字符串类型不同,即使在 CompareOnlyKey 下也必须失败
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(left, rightTypeMismatch), "number/string 类型不同,Compare 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(left, rightTypeMismatch), "number/string 类型不同,CompareOnlyKey 也应返回 False");
- RyanJsonDelete(left);
- RyanJsonDelete(right);
- RyanJsonDelete(rightTypeMismatch);
- }
- static void testCompareEmptyContainerAndTypeMismatch(void)
- {
- RyanJson_t emptyObjA = RyanJsonCreateObject();
- RyanJson_t emptyObjB = RyanJsonCreateObject();
- RyanJson_t emptyArrA = RyanJsonCreateArray();
- RyanJson_t emptyArrB = RyanJsonCreateArray();
- TEST_ASSERT_NOT_NULL(emptyObjA);
- TEST_ASSERT_NOT_NULL(emptyObjB);
- TEST_ASSERT_NOT_NULL(emptyArrA);
- TEST_ASSERT_NOT_NULL(emptyArrB);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(emptyObjA, emptyObjB), "空对象之间应相等");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(emptyObjA, emptyObjB), "空对象 CompareOnlyKey 应相等");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(emptyArrA, emptyArrB), "空数组之间应相等");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(emptyArrA, emptyArrB), "空数组 CompareOnlyKey 应相等");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(emptyObjA, emptyArrA), "对象与数组类型不同应不相等");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(emptyObjA, emptyArrA), "对象与数组 CompareOnlyKey 也应不相等");
- RyanJsonDelete(emptyObjA);
- RyanJsonDelete(emptyObjB);
- RyanJsonDelete(emptyArrA);
- RyanJsonDelete(emptyArrB);
- }
- static void testCompareArraySemantics(void)
- {
- RyanJson_t arrIntA = RyanJsonCreateArray();
- RyanJson_t arrIntB = RyanJsonCreateArray();
- RyanJson_t arrIntReverse = RyanJsonCreateArray();
- RyanJson_t arrMixedA = RyanJsonCreateArray();
- RyanJson_t arrMixedB = RyanJsonCreateArray();
- RyanJson_t arrShort = RyanJsonCreateArray();
- TEST_ASSERT_NOT_NULL(arrIntA);
- TEST_ASSERT_NOT_NULL(arrIntB);
- TEST_ASSERT_NOT_NULL(arrIntReverse);
- TEST_ASSERT_NOT_NULL(arrMixedA);
- TEST_ASSERT_NOT_NULL(arrMixedB);
- TEST_ASSERT_NOT_NULL(arrShort);
- TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arrIntA, 1));
- TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arrIntA, 2));
- TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arrIntA, 3));
- TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arrIntB, 1));
- TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arrIntB, 2));
- TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arrIntB, 3));
- TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arrIntReverse, 3));
- TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arrIntReverse, 2));
- TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arrIntReverse, 1));
- TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arrMixedA, 1));
- TEST_ASSERT_TRUE(RyanJsonAddStringToArray(arrMixedA, "2"));
- TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arrMixedA, 3));
- TEST_ASSERT_TRUE(RyanJsonAddStringToArray(arrMixedB, "1"));
- TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arrMixedB, 2));
- TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arrMixedB, 3));
- TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arrShort, 1));
- TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arrShort, 2));
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(arrIntA, arrIntB), "相同数组 Compare 应返回 True");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(arrIntA, arrIntReverse), "数组顺序不同 Compare 应返回 False");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(arrIntA, arrIntReverse), "数组顺序不同但类型一致,CompareOnlyKey 应返回 True");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(arrMixedA, arrMixedB), "数组元素类型顺序不同 Compare 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(arrMixedA, arrMixedB), "数组元素类型顺序不同 CompareOnlyKey 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(arrIntA, arrShort), "数组长度不同 Compare 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(arrIntA, arrShort), "数组长度不同 CompareOnlyKey 应返回 False");
- RyanJsonDelete(arrIntA);
- RyanJsonDelete(arrIntB);
- RyanJsonDelete(arrIntReverse);
- RyanJsonDelete(arrMixedA);
- RyanJsonDelete(arrMixedB);
- RyanJsonDelete(arrShort);
- }
- static void testCompareNestedObjectScenarios(void)
- {
- RyanJson_t left = RyanJsonParse("{\"meta\":{\"id\":1,\"name\":\"m\"},\"list\":[1,2,3],\"flag\":true}");
- RyanJson_t rightOrderedDiff = RyanJsonParse("{\"flag\":true,\"list\":[1,2,3],\"meta\":{\"name\":\"m\",\"id\":1}}");
- RyanJson_t rightValueDiff = RyanJsonParse("{\"flag\":true,\"list\":[1,2,3],\"meta\":{\"name\":\"m\",\"id\":2}}");
- RyanJson_t rightMissingKey = RyanJsonParse("{\"flag\":true,\"list\":[1,2,3],\"meta\":{\"name\":\"m\",\"idx\":1}}");
- RyanJson_t leftSingleKey = RyanJsonParse("{\"a\":1}");
- RyanJson_t rightSingleKey = RyanJsonParse("{\"b\":1}");
- RyanJson_t leftPrefixMatch = RyanJsonParse("{\"a\":1,\"b\":2}");
- RyanJson_t rightPrefixMismatch = RyanJsonParse("{\"a\":1,\"c\":2}");
- RyanJson_t leftTailMatch = RyanJsonParse("{\"a\":1,\"b\":2,\"c\":3}");
- RyanJson_t rightTailMatch = RyanJsonParse("{\"b\":2,\"c\":3,\"a\":1}");
- RyanJson_t rightTailMismatch = RyanJsonParse("{\"c\":3,\"d\":4,\"a\":1}");
- TEST_ASSERT_NOT_NULL(left);
- TEST_ASSERT_NOT_NULL(rightOrderedDiff);
- TEST_ASSERT_NOT_NULL(rightValueDiff);
- TEST_ASSERT_NOT_NULL(rightMissingKey);
- TEST_ASSERT_NOT_NULL(leftSingleKey);
- TEST_ASSERT_NOT_NULL(rightSingleKey);
- TEST_ASSERT_NOT_NULL(leftPrefixMatch);
- TEST_ASSERT_NOT_NULL(rightPrefixMismatch);
- TEST_ASSERT_NOT_NULL(leftTailMatch);
- TEST_ASSERT_NOT_NULL(rightTailMatch);
- TEST_ASSERT_NOT_NULL(rightTailMismatch);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(left, rightOrderedDiff), "嵌套对象乱序但值一致应返回 True");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(left, rightOrderedDiff), "嵌套对象乱序 CompareOnlyKey 应返回 True");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(left, rightValueDiff), "嵌套对象值不同 Compare 应返回 False");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(left, rightValueDiff), "嵌套对象值不同 CompareOnlyKey 应返回 True");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(left, rightMissingKey), "嵌套对象 key 不匹配 Compare 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(left, rightMissingKey), "嵌套对象 key 不匹配 CompareOnlyKey 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(leftSingleKey, rightSingleKey), "同尺寸对象但 key 不同 Compare 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(leftSingleKey, rightSingleKey),
- "同尺寸对象但 key 不同 CompareOnlyKey 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(leftPrefixMatch, rightPrefixMismatch),
- "前缀 key 相同但后续 key 不同 Compare 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(leftPrefixMatch, rightPrefixMismatch),
- "前缀 key 相同但后续 key 不同 CompareOnlyKey 应返回 False");
- // 覆盖同层遍历中 rightCandidate == NULL 的回退查找成功分支
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(leftTailMatch, rightTailMatch), "尾节点命中回退查找后 Compare 应返回 True");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(leftTailMatch, rightTailMatch), "尾节点命中回退查找后 CompareOnlyKey 应返回 True");
- // 覆盖同层遍历中 rightCandidate == NULL 的回退查找失败分支
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(leftTailMatch, rightTailMismatch), "尾节点回退查找失败 Compare 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(leftTailMatch, rightTailMismatch),
- "尾节点回退查找失败 CompareOnlyKey 应返回 False");
- RyanJsonDelete(left);
- RyanJsonDelete(rightOrderedDiff);
- RyanJsonDelete(rightValueDiff);
- RyanJsonDelete(rightMissingKey);
- RyanJsonDelete(leftSingleKey);
- RyanJsonDelete(rightSingleKey);
- RyanJsonDelete(leftPrefixMatch);
- RyanJsonDelete(rightPrefixMismatch);
- RyanJsonDelete(leftTailMatch);
- RyanJsonDelete(rightTailMatch);
- RyanJsonDelete(rightTailMismatch);
- }
- static void testCompareArrayWithObjects(void)
- {
- RyanJson_t arrLeft = RyanJsonParse("[{\"a\":1,\"b\":2},{\"x\":3,\"y\":4}]");
- RyanJson_t arrObjectUnordered = RyanJsonParse("[{\"b\":2,\"a\":1},{\"y\":4,\"x\":3}]");
- RyanJson_t arrOrderSwapped = RyanJsonParse("[{\"y\":4,\"x\":3},{\"b\":2,\"a\":1}]");
- RyanJson_t arrValueDiff = RyanJsonParse("[{\"a\":9,\"b\":2},{\"x\":3,\"y\":4}]");
- TEST_ASSERT_NOT_NULL(arrLeft);
- TEST_ASSERT_NOT_NULL(arrObjectUnordered);
- TEST_ASSERT_NOT_NULL(arrOrderSwapped);
- TEST_ASSERT_NOT_NULL(arrValueDiff);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(arrLeft, arrObjectUnordered), "数组内对象乱序键应比较为 True");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(arrLeft, arrObjectUnordered), "数组内对象乱序键 CompareOnlyKey 应返回 True");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(arrLeft, arrOrderSwapped), "数组元素顺序变化 Compare 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(arrLeft, arrOrderSwapped), "数组元素顺序变化 CompareOnlyKey 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(arrLeft, arrValueDiff), "数组内对象值变化 Compare 应返回 False");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(arrLeft, arrValueDiff), "数组内对象值变化但键结构一致 CompareOnlyKey 应返回 True");
- RyanJsonDelete(arrLeft);
- RyanJsonDelete(arrObjectUnordered);
- RyanJsonDelete(arrOrderSwapped);
- RyanJsonDelete(arrValueDiff);
- }
- static void testCompareDeepNestAndLargeArray(void)
- {
- // 深度嵌套比较(检测栈溢出或递归限制)
- // 之前 200 层出现疑似内存不足或其他问题,降至 50 层验证核心逻辑
- int32_t depth = 50;
- RyanJson_t root1 = RyanJsonCreateObject();
- RyanJson_t root2 = RyanJsonCreateObject();
- RyanJson_t curr1 = root1;
- RyanJson_t curr2 = root2;
- for (int32_t i = 0; i < depth; i++)
- {
- RyanJson_t child1 = RyanJsonCreateObject();
- RyanJson_t child2 = RyanJsonCreateObject();
- TEST_ASSERT_NOT_NULL_MESSAGE(child1, "创建 child1 失败");
- TEST_ASSERT_NOT_NULL_MESSAGE(child2, "创建 child2 失败");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonAddItemToObject(curr1, "nest", child1), "添加到 curr1 失败");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonAddItemToObject(curr2, "nest", child2), "添加到 curr2 失败");
- // RyanJsonAddItemToObject 会“吞掉” child1(若其为容器),把其内容转移到新节点并释放 child1
- // 因此 child1 指针已失效,必须通过 key 获取新创建的节点
- curr1 = RyanJsonGetObjectByKey(curr1, "nest");
- curr2 = RyanJsonGetObjectByKey(curr2, "nest");
- TEST_ASSERT_NOT_NULL_MESSAGE(curr1, "获取 curr1 下一级 nest 失败");
- TEST_ASSERT_NOT_NULL_MESSAGE(curr2, "获取 curr2 下一级 nest 失败");
- }
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(root1, root2), "初始深度比较失败");
- // 修改末端
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonAddIntToObject(curr1, "diff", 1), "添加 diff 失败");
- TEST_ASSERT_EQUAL_INT_MESSAGE(1, RyanJsonGetSize(curr1), "添加 diff 后 Size 应为 1");
- TEST_ASSERT_EQUAL_INT_MESSAGE(0, RyanJsonGetSize(curr2), "curr2 Size 应仍为 0");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(root1, root2), "修改后深度比较应失败");
- RyanJsonDelete(root1);
- RyanJsonDelete(root2);
- // 大数组比较
- int32_t count = 2000;
- RyanJson_t arr1 = RyanJsonCreateArray();
- RyanJson_t arr2 = RyanJsonCreateArray();
- for (int32_t i = 0; i < count; i++)
- {
- RyanJsonAddIntToArray(arr1, i);
- RyanJsonAddIntToArray(arr2, i);
- }
- TEST_ASSERT_TRUE(RyanJsonCompare(arr1, arr2));
- // 修改中间一个元素
- RyanJsonDeleteByIndex(arr2, count / 2); // 删除中间项
- RyanJson_t insert = RyanJsonCreateInt("new", 99999);
- RyanJsonInsert(arr2, count / 2, insert);
- TEST_ASSERT_FALSE(RyanJsonCompare(arr1, arr2));
- RyanJsonDelete(arr1);
- RyanJsonDelete(arr2);
- }
- static void testCompareEqualityAndStructuralDiff(void)
- {
- char jsonstr[] = "{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null,\"item\":"
- "{\"inter\":16,\"double\":16."
- "89,\"string\":\"hello\","
- "\"boolTrue\":true,\"boolFalse\":false,\"null\":null},\"arrayInt\":[16,16,16,16,16],\"arrayDouble\":[16.89,16.89,"
- "16.89,16.89,16.89],"
- "\"arrayString\":[\"hello\",\"hello\","
- "\"hello\",\"hello\",\"hello\"],\"array\":[16,16.89,\"hello\",true,false,null],\"arrayItem\":[{\"inter\":16,"
- "\"double\":16.89,\"string\":"
- "\"hello\",\"boolTrue\":true,"
- "\"boolFalse\":false,\"null\":null},{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,"
- "\"boolFalse\":false,\"null\":null}]}";
- RyanJson_t json = RyanJsonParse(jsonstr);
- TEST_ASSERT_NOT_NULL_MESSAGE(json, "解析 Json 1 失败");
- RyanJson_t json2 = RyanJsonParse(jsonstr);
- TEST_ASSERT_NOT_NULL_MESSAGE(json2, "解析 Json 2 失败");
- // 边界情况测试
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, NULL), "与 NULL 比较应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(NULL, json2), "NULL 与对象比较应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(NULL, NULL), "NULL 与 NULL 比较应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(json, NULL), "仅比较 Key:与 NULL 比较应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(NULL, json2), "仅比较 Key:NULL 与对象比较应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(NULL, NULL), "仅比较 Key:NULL 与 NULL 比较应返回 False");
- // 完整对象比较
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(json, json2), "两个相同内容的对象比较应返回 True");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(json, json), "对象与自身比较应返回 True");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "仅比较 Key:两个相同内容的对象比较应返回 True");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(json, json), "仅比较 Key:对象与自身比较应返回 True");
- // 修改对象 2 并比较
- // 添加字符串
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonAddStringToObject(json2, "test", "hello");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "多出一个字段后比较应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "多出一个字段后仅比较 Key 应返回 False");
- // 添加整数
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonAddIntToObject(json2, "test", 1);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "多出一个整数后比较应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "多出一个整数后仅比较 Key 应返回 False");
- // 添加浮点数
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonAddDoubleToObject(json2, "test", 2.0);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "多出一个浮点数后比较应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "多出一个浮点数后仅比较 Key 应返回 False");
- // 添加 boolValue
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonAddBoolToObject(json2, "test", RyanJsonTrue);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "多出一个布尔值后比较应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "多出一个布尔值后仅比较 Key 应返回 False");
- // 添加 null
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonAddNullToObject(json2, "test");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "多出一个 Null 后比较应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "多出一个 Null 后仅比较 Key 应返回 False");
- // 数组修改测试
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonAddIntToArray(RyanJsonGetObjectToKey(json2, "arrayInt"), 2);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "数组长度变化后比较应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "数组长度变化后仅比较 Key 应返回 False");
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonAddDoubleToArray(RyanJsonGetObjectToKey(json2, "arrayDouble"), 2.0);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "数组长度变化(浮点)后比较应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "数组长度变化(浮点)后仅比较 Key 应返回 False");
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonAddStringToArray(RyanJsonGetObjectToKey(json2, "arrayString"), "hello");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "数组长度变化(字符串)后比较应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "数组长度变化(字符串)后仅比较 Key 应返回 False");
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonAddStringToArray(RyanJsonGetObjectToKey(json2, "arrayItem"), "hello");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "数组长度变化(项)后比较应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "数组长度变化(项)后仅比较 Key 应返回 False");
- // 修改 key 名称
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonChangeKey(RyanJsonGetObjectToKey(json2, "inter"), "int2");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "Key 修改后比较应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "Key 修改后仅比较 Key 应返回 False");
- // 修改值但 key 相同
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonChangeIntValue(RyanJsonGetObjectToKey(json2, "inter"), 17);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "Value 修改后比较应返回 False");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "Value 修改但 Key 相同,仅比较 Key 应返回 True");
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonChangeDoubleValue(RyanJsonGetObjectToKey(json2, "double"), 20.89);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "浮点 Value 修改但 Key 相同,仅比较 Key 应返回 True");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "浮点 Value 修改后比较应返回 False");
- // 类型修改测试(从 double 改为 int32_t)
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonDeleteByKey(json2, "double");
- RyanJsonAddIntToObject(json2, "double", 20); // 改为 int
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "类型修改后比较应返回 False");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "类型修改但 Key 相同,仅比较 Key 应返回 True");
- // 修改 strValue
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonChangeStringValue(RyanJsonGetObjectToKey(json2, "string"), "49");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "字符串 Value 修改后比较应返回 False");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "字符串 Value 修改但 Key 相同,仅比较 Key 应返回 True");
- // 修改对象 1 的 boolValue
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonChangeBoolValue(RyanJsonGetObjectToKey(json2, "boolTrue"), RyanJsonFalse);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "布尔 Value 修改后比较应返回 False");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "布尔 Value 修改但 Key 相同,仅比较 Key 应返回 True");
- // 修改嵌套对象的 boolValue
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonChangeBoolValue(RyanJsonGetObjectToKey(json2, "item", "boolTrue"), RyanJsonFalse);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "嵌套布尔 Value 修改后比较应返回 False");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "嵌套布尔 Value 修改但结构相同,仅比较 Key 应返回 True");
- // 修改数组中的整数
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonChangeIntValue(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json2, "arrayInt"), 0), 17);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "数组元素修改后比较应返回 False");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "数组元素修改但长度相同,仅比较 Key 应返回 True");
- // 修改数组中的浮点数
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonChangeDoubleValue(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json2, "arrayDouble"), 0), 20.89);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "数组浮点元素修改后比较应返回 False");
- // 修改数组中的字符串
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonChangeStringValue(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json2, "arrayString"), 0), "20.89");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "数组字符串元素修改后比较应返回 False");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "数组字符串元素修改但长度相同,仅比较 Key 应返回 True");
- // 修改混合数组
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonChangeIntValue(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json2, "array"), 0), 17);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "混合数组修改后比较应返回 False");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "混合数组修改但长度相同,仅比较 Key 应返回 True");
- // 修改数组项中的对象
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonChangeIntValue(RyanJsonGetObjectToKey(RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json2, "arrayItem"), 0), "inter"),
- 17);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "数组项对象修改后比较应返回 False");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "数组项对象修改但结构相同,仅比较 Key 应返回 True");
- // 删除整个 key 节点
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonDeleteByKey(json2, "arrayItem");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "删除 Key 后比较应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "删除 Key 后仅比较 Key 应返回 False");
- // 删除数组索引项
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonDeleteByIndex(RyanJsonGetObjectToKey(json2, "arrayInt"), 2);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "删除数组索引后比较应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "删除数组索引后仅比较 Key 应返回 False");
- // 删除数组项中的对象项
- RyanJsonDelete(json2);
- json2 = RyanJsonParse(jsonstr);
- RyanJsonDeleteByIndex(RyanJsonGetObjectToKey(json2, "arrayItem"), 0);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(json, json2), "删除数组对象项后比较应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(json, json2), "删除数组对象项后仅比较 Key 应返回 False");
- RyanJsonDelete(json);
- RyanJsonDelete(json2);
- }
- void testCompareRunner(void)
- {
- UnitySetTestFile(__FILE__);
- RUN_TEST(testCompareEdgeCases);
- RUN_TEST(testCompareObjectOrderPaths);
- RUN_TEST(testCompareScalarAndTypeMatrix);
- RUN_TEST(testCompareNumberSubtypeInContainers);
- RUN_TEST(testCompareEmptyContainerAndTypeMismatch);
- RUN_TEST(testCompareArraySemantics);
- RUN_TEST(testCompareNestedObjectScenarios);
- RUN_TEST(testCompareArrayWithObjects);
- RUN_TEST(testCompareDeepNestAndLargeArray);
- RUN_TEST(testCompareEqualityAndStructuralDiff);
- }
|