| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- #include "testBase.h"
- static void testCompareDuplicateKeyPolicyBasic(void)
- {
- // 该用例在 strict/non-strict 两种编译模式都执行:
- // - strict 模式:重复 key 应在解析阶段被拒绝;
- // - non-strict 模式:重复 key 允许存在,Compare/CompareOnlyKey 需按“同 key 出现序号”一一对齐。
- RyanJson_t dupLeft = RyanJsonParse("{\"a\":1,\"a\":1}");
- RyanJson_t diffKeyRight = RyanJsonParse("{\"a\":1,\"b\":1}");
- TEST_ASSERT_NOT_NULL(diffKeyRight);
- #if true == RyanJsonStrictObjectKeyCheck
- TEST_ASSERT_NULL_MESSAGE(dupLeft, "strict 模式下重复 key 应解析失败");
- // 控制组:普通 Object 乱序比较在 strict 模式下仍应正常。
- {
- RyanJson_t ordered = RyanJsonParse("{\"a\":1,\"b\":1}");
- RyanJson_t unordered = RyanJsonParse("{\"b\":1,\"a\":1}");
- TEST_ASSERT_NOT_NULL(ordered);
- TEST_ASSERT_NOT_NULL(unordered);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(ordered, unordered), "strict 模式下普通 Object 乱序 Compare 应返回 True");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(ordered, unordered),
- "strict 模式下普通 Object 乱序 CompareOnlyKey 应返回 True");
- RyanJsonDelete(ordered);
- RyanJsonDelete(unordered);
- }
- #else
- // non-strict 模式允许重复 key,本分支验证 Compare/CompareOnlyKey 不会把右侧同一节点重复匹配。
- RyanJson_t sameLeft = RyanJsonParse("{\"a\":1,\"a\":2}");
- RyanJson_t sameRight = RyanJsonParse("{\"a\":1,\"a\":2}");
- // 第二次出现位置的类型不一致(String vs Number)时,CompareOnlyKey 也必须失败。
- RyanJson_t typeLeft = RyanJsonParse("{\"a\":1,\"a\":\"2\"}");
- RyanJson_t typeRight = RyanJsonParse("{\"a\":1,\"a\":2}");
- TEST_ASSERT_NOT_NULL(dupLeft);
- TEST_ASSERT_NOT_NULL(sameLeft);
- TEST_ASSERT_NOT_NULL(sameRight);
- TEST_ASSERT_NOT_NULL(typeLeft);
- TEST_ASSERT_NOT_NULL(typeRight);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(dupLeft, diffKeyRight), "重复 key 与不同 key 混合时 Compare 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(dupLeft, diffKeyRight), "重复 key 与不同 key 混合时 CompareOnlyKey 应返回 False");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(sameLeft, sameRight), "重复 key 的同序号节点完全一致时 Compare 应返回 True");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(sameLeft, sameRight), "重复 key 的同序号节点完全一致时 CompareOnlyKey 应返回 True");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(typeLeft, typeRight), "重复 key 的同序号节点类型不同,Compare 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(typeLeft, typeRight),
- "重复 key 的同序号节点类型不同,CompareOnlyKey 应返回 False");
- RyanJsonDelete(sameLeft);
- RyanJsonDelete(sameRight);
- RyanJsonDelete(typeLeft);
- RyanJsonDelete(typeRight);
- #endif
- RyanJsonDelete(dupLeft);
- RyanJsonDelete(diffKeyRight);
- }
- static void testCompareDuplicateKeyCountAndOrder(void)
- {
- RyanJson_t left = RyanJsonParse("{\"a\":1,\"a\":2,\"a\":3}");
- RyanJson_t rightCountMismatch = RyanJsonParse("{\"a\":1,\"a\":2,\"b\":3}");
- RyanJson_t rightOrderSwapped = RyanJsonParse("{\"a\":3,\"a\":2,\"a\":1}");
- RyanJson_t rightSame = RyanJsonParse("{\"a\":1,\"a\":2,\"a\":3}");
- RyanJson_t rightTypeChanged = RyanJsonParse("{\"a\":1,\"a\":\"2\",\"a\":3}");
- #if true == RyanJsonStrictObjectKeyCheck
- TEST_ASSERT_NULL_MESSAGE(left, "strict 模式下重复 key 应解析失败");
- TEST_ASSERT_NULL_MESSAGE(rightCountMismatch, "strict 模式下重复 key 应解析失败");
- TEST_ASSERT_NULL_MESSAGE(rightOrderSwapped, "strict 模式下重复 key 应解析失败");
- TEST_ASSERT_NULL_MESSAGE(rightSame, "strict 模式下重复 key 应解析失败");
- TEST_ASSERT_NULL_MESSAGE(rightTypeChanged, "strict 模式下重复 key 应解析失败");
- // 控制组:无重复 key 时,key 不一致应判 False。
- {
- RyanJson_t normalLeft = RyanJsonParse("{\"a\":1,\"b\":2,\"c\":3}");
- RyanJson_t normalRight = RyanJsonParse("{\"a\":1,\"b\":2,\"x\":3}");
- TEST_ASSERT_NOT_NULL(normalLeft);
- TEST_ASSERT_NOT_NULL(normalRight);
- TEST_ASSERT_FALSE(RyanJsonCompare(normalLeft, normalRight));
- TEST_ASSERT_FALSE(RyanJsonCompareOnlyKey(normalLeft, normalRight));
- RyanJsonDelete(normalLeft);
- RyanJsonDelete(normalRight);
- }
- #else
- TEST_ASSERT_NOT_NULL(left);
- TEST_ASSERT_NOT_NULL(rightCountMismatch);
- TEST_ASSERT_NOT_NULL(rightOrderSwapped);
- TEST_ASSERT_NOT_NULL(rightSame);
- TEST_ASSERT_NOT_NULL(rightTypeChanged);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(left, rightCountMismatch), "重复 key 个数不一致时 Compare 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(left, rightCountMismatch), "重复 key 个数不一致时 CompareOnlyKey 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(left, rightOrderSwapped), "重复 key 同序号值不同,Compare 应返回 False");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(left, rightOrderSwapped), "重复 key 同序号类型一致,CompareOnlyKey 应返回 True");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(left, rightSame), "重复 key 完全一致时 Compare 应返回 True");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(left, rightSame), "重复 key 完全一致时 CompareOnlyKey 应返回 True");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(left, rightTypeChanged), "重复 key 同序号类型变化,Compare 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(left, rightTypeChanged), "重复 key 同序号类型变化,CompareOnlyKey 应返回 False");
- #endif
- RyanJsonDelete(left);
- RyanJsonDelete(rightCountMismatch);
- RyanJsonDelete(rightOrderSwapped);
- RyanJsonDelete(rightSame);
- RyanJsonDelete(rightTypeChanged);
- }
- static void testCompareDuplicateKeyNestedObject(void)
- {
- RyanJson_t left = RyanJsonParse("{\"outer\":{\"k\":1,\"k\":2},\"stable\":1}");
- RyanJson_t rightSame = RyanJsonParse("{\"stable\":1,\"outer\":{\"k\":1,\"k\":2}}");
- RyanJson_t rightKeyMismatch = RyanJsonParse("{\"stable\":1,\"outer\":{\"k\":1,\"x\":2}}");
- RyanJson_t rightTypeMismatch = RyanJsonParse("{\"stable\":1,\"outer\":{\"k\":1,\"k\":\"2\"}}");
- RyanJson_t rightValueMismatch = RyanJsonParse("{\"stable\":1,\"outer\":{\"k\":1,\"k\":9}}");
- #if true == RyanJsonStrictObjectKeyCheck
- TEST_ASSERT_NULL_MESSAGE(left, "strict 模式下嵌套重复 key 应解析失败");
- TEST_ASSERT_NULL_MESSAGE(rightSame, "strict 模式下嵌套重复 key 应解析失败");
- TEST_ASSERT_NULL_MESSAGE(rightTypeMismatch, "strict 模式下嵌套重复 key 应解析失败");
- TEST_ASSERT_NULL_MESSAGE(rightValueMismatch, "strict 模式下嵌套重复 key 应解析失败");
- TEST_ASSERT_NOT_NULL(rightKeyMismatch);
- // 控制组:无重复 key 的嵌套 Object 可以正常比较。
- {
- RyanJson_t normalLeft = RyanJsonParse("{\"outer\":{\"k\":1,\"m\":2},\"stable\":1}");
- TEST_ASSERT_NOT_NULL(normalLeft);
- TEST_ASSERT_FALSE(RyanJsonCompare(normalLeft, rightKeyMismatch));
- TEST_ASSERT_FALSE(RyanJsonCompareOnlyKey(normalLeft, rightKeyMismatch));
- RyanJsonDelete(normalLeft);
- }
- #else
- TEST_ASSERT_NOT_NULL(left);
- TEST_ASSERT_NOT_NULL(rightSame);
- TEST_ASSERT_NOT_NULL(rightKeyMismatch);
- TEST_ASSERT_NOT_NULL(rightTypeMismatch);
- TEST_ASSERT_NOT_NULL(rightValueMismatch);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(left, rightSame), "嵌套重复 key 完全一致时 Compare 应返回 True");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(left, rightSame), "嵌套重复 key 完全一致时 CompareOnlyKey 应返回 True");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(left, rightKeyMismatch), "嵌套重复 key 与普通 key 混合时 Compare 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(left, rightKeyMismatch),
- "嵌套重复 key 与普通 key 混合时 CompareOnlyKey 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(left, rightTypeMismatch), "嵌套重复 key 同序号类型变化,Compare 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(left, rightTypeMismatch),
- "嵌套重复 key 同序号类型变化,CompareOnlyKey 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(left, rightValueMismatch), "嵌套重复 key 同序号值变化,Compare 应返回 False");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(left, rightValueMismatch),
- "嵌套重复 key 同序号类型一致时 CompareOnlyKey 应返回 True");
- #endif
- RyanJsonDelete(left);
- RyanJsonDelete(rightSame);
- RyanJsonDelete(rightKeyMismatch);
- RyanJsonDelete(rightTypeMismatch);
- RyanJsonDelete(rightValueMismatch);
- }
- static void testCompareDuplicateKeyArrayObject(void)
- {
- RyanJson_t left = RyanJsonParse("[{\"a\":1,\"a\":2},{\"b\":1}]");
- RyanJson_t rightSame = RyanJsonParse("[{\"a\":1,\"a\":2},{\"b\":1}]");
- RyanJson_t rightArraySwap = RyanJsonParse("[{\"b\":1},{\"a\":1,\"a\":2}]");
- RyanJson_t rightInnerMismatch = RyanJsonParse("[{\"a\":1,\"b\":2},{\"b\":1}]");
- RyanJson_t rightInnerValueDiff = RyanJsonParse("[{\"a\":9,\"a\":8},{\"b\":1}]");
- #if true == RyanJsonStrictObjectKeyCheck
- TEST_ASSERT_NULL_MESSAGE(left, "strict 模式下 Array 元素中的重复 key 应解析失败");
- TEST_ASSERT_NULL_MESSAGE(rightSame, "strict 模式下 Array 元素中的重复 key 应解析失败");
- TEST_ASSERT_NULL_MESSAGE(rightArraySwap, "strict 模式下 Array 元素中的重复 key 应解析失败");
- TEST_ASSERT_NULL_MESSAGE(rightInnerValueDiff, "strict 模式下 Array 元素中的重复 key 应解析失败");
- TEST_ASSERT_NOT_NULL(rightInnerMismatch);
- // 控制组:无重复 key 的 Array 中 Object 语义正常。
- {
- RyanJson_t normalLeft = RyanJsonParse("[{\"a\":1,\"b\":2},{\"b\":1}]");
- TEST_ASSERT_NOT_NULL(normalLeft);
- TEST_ASSERT_TRUE(RyanJsonCompare(normalLeft, rightInnerMismatch));
- TEST_ASSERT_TRUE(RyanJsonCompareOnlyKey(normalLeft, rightInnerMismatch));
- RyanJsonDelete(normalLeft);
- }
- #else
- TEST_ASSERT_NOT_NULL(left);
- TEST_ASSERT_NOT_NULL(rightSame);
- TEST_ASSERT_NOT_NULL(rightArraySwap);
- TEST_ASSERT_NOT_NULL(rightInnerMismatch);
- TEST_ASSERT_NOT_NULL(rightInnerValueDiff);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(left, rightSame), "Array 内重复 key Object 完全一致时 Compare 应返回 True");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(left, rightSame), "Array 内重复 key Object 完全一致时 CompareOnlyKey 应返回 True");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(left, rightArraySwap), "Array 顺序改变后 Compare 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(left, rightArraySwap), "Array 顺序改变后 CompareOnlyKey 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(left, rightInnerMismatch), "Array 内重复 key 与普通 key 混合时 Compare 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(left, rightInnerMismatch),
- "Array 内重复 key 与普通 key 混合时 CompareOnlyKey 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(left, rightInnerValueDiff), "Array 内重复 key 同序号值变化,Compare 应返回 False");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(left, rightInnerValueDiff),
- "Array 内重复 key 同序号类型一致时 CompareOnlyKey 应返回 True");
- #endif
- RyanJsonDelete(left);
- RyanJsonDelete(rightSame);
- RyanJsonDelete(rightArraySwap);
- RyanJsonDelete(rightInnerMismatch);
- RyanJsonDelete(rightInnerValueDiff);
- }
- static void testCompareDuplicateKeyDeepOccurrenceAlign(void)
- {
- RyanJson_t left = RyanJsonParse("{\"a\":{\"v\":1},\"a\":{\"v\":2}}");
- RyanJson_t rightSame = RyanJsonParse("{\"a\":{\"v\":1},\"a\":{\"v\":2}}");
- RyanJson_t rightSwap = RyanJsonParse("{\"a\":{\"v\":2},\"a\":{\"v\":1}}");
- RyanJson_t rightTypeChanged = RyanJsonParse("{\"a\":{\"v\":1},\"a\":{\"v\":\"2\"}}");
- #if true == RyanJsonStrictObjectKeyCheck
- TEST_ASSERT_NULL_MESSAGE(left, "strict 模式下深层重复 key 应解析失败");
- TEST_ASSERT_NULL_MESSAGE(rightSame, "strict 模式下深层重复 key 应解析失败");
- TEST_ASSERT_NULL_MESSAGE(rightSwap, "strict 模式下深层重复 key 应解析失败");
- TEST_ASSERT_NULL_MESSAGE(rightTypeChanged, "strict 模式下深层重复 key 应解析失败");
- // 控制组:无重复 key 的深层 Object 比较应正常。
- {
- RyanJson_t normalLeft = RyanJsonParse("{\"a1\":{\"v\":1},\"a2\":{\"v\":2}}");
- RyanJson_t normalRight = RyanJsonParse("{\"a2\":{\"v\":2},\"a1\":{\"v\":1}}");
- TEST_ASSERT_NOT_NULL(normalLeft);
- TEST_ASSERT_NOT_NULL(normalRight);
- TEST_ASSERT_TRUE(RyanJsonCompare(normalLeft, normalRight));
- TEST_ASSERT_TRUE(RyanJsonCompareOnlyKey(normalLeft, normalRight));
- RyanJsonDelete(normalLeft);
- RyanJsonDelete(normalRight);
- }
- #else
- TEST_ASSERT_NOT_NULL(left);
- TEST_ASSERT_NOT_NULL(rightSame);
- TEST_ASSERT_NOT_NULL(rightSwap);
- TEST_ASSERT_NOT_NULL(rightTypeChanged);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(left, rightSame), "深层重复 key 同序号完全一致时 Compare 应返回 True");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(left, rightSame), "深层重复 key 同序号完全一致时 CompareOnlyKey 应返回 True");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(left, rightSwap), "深层重复 key 同序号值错位时 Compare 应返回 False");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareOnlyKey(left, rightSwap), "深层重复 key 同序号类型一致时 CompareOnlyKey 应返回 True");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompare(left, rightTypeChanged), "深层重复 key 同序号类型变化时 Compare 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonCompareOnlyKey(left, rightTypeChanged),
- "深层重复 key 同序号类型变化时 CompareOnlyKey 应返回 False");
- #endif
- RyanJsonDelete(left);
- RyanJsonDelete(rightSame);
- RyanJsonDelete(rightSwap);
- RyanJsonDelete(rightTypeChanged);
- }
- void testCompareDuplicateKeyRunner(void)
- {
- UnitySetTestFile(__FILE__);
- RUN_TEST(testCompareDuplicateKeyPolicyBasic);
- RUN_TEST(testCompareDuplicateKeyCountAndOrder);
- RUN_TEST(testCompareDuplicateKeyNestedObject);
- RUN_TEST(testCompareDuplicateKeyArrayObject);
- RUN_TEST(testCompareDuplicateKeyDeepOccurrenceAlign);
- }
|