| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367 |
- #include "testBase.h"
- #define DoubleList \
- /* 零值测试 */ \
- X(0.0) \
- X(-0.0) \
- /* 正负整数边界 */ \
- X(1.0) \
- X(-1.0) \
- X(2.0) \
- X(-2.0) \
- X(10.0) \
- X(-10.0) \
- X(100.0) \
- X(1000.0) \
- X(10000.0) \
- X(100000.0) \
- /* 简单小数(二进制精确表示) */ \
- X(0.5) \
- X(-0.5) \
- X(0.25) \
- X(-0.25) \
- X(0.125) \
- X(0.0625) \
- X(0.03125) \
- X(0.015625) \
- /* 常见小数 */ \
- X(16.89) \
- X(-16.89) \
- X(123.456) \
- X(-123.456) \
- X(99.99) \
- X(-99.99) \
- X(1.5) \
- X(2.5) \
- X(3.5) \
- /* 小于1的小数 */ \
- X(0.001) \
- X(-0.001) \
- X(0.0001) \
- X(0.00001) \
- X(0.000001) \
- X(0.123456789) \
- X(0.987654321) \
- X(0.111111111111111) \
- /* 大数测试 */ \
- X(999999.999999) \
- X(-999999.999999) \
- X(12345678.9) \
- X(99999999.0) \
- X(123456789.123456) \
- X(9876543210.12345) \
- /* 科学计数法 - 大数 */ \
- X(1.5e10) \
- X(-1.5e10) \
- X(1.23e8) \
- X(9.99e12) \
- X(1.0e15) \
- X(1.0e18) \
- X(1.0e20) \
- X(5.55e15) \
- /* 科学计数法 - 小数 */ \
- X(1.5e-10) \
- X(-1.5e-10) \
- X(9.87e-5) \
- X(1.0e-15) \
- X(5.5e-8) \
- X(1.0e-18) \
- X(1.0e-20) \
- X(1.23e-3) \
- X(-9.87e-7) \
- /* 数学常量 */ \
- X(3.14159265358979) \
- X(2.71828182845904) \
- X(1.41421356237309) \
- X(1.73205080756888) \
- X(1.61803398874989) \
- X(0.69314718055994) \
- /* 浮点精度经典测试 */ \
- X(0.1) \
- X(0.2) \
- X(0.3) \
- X(0.6) \
- X(0.7) \
- X(0.9) \
- X(0.123456) \
- /* 整数边界值 */ \
- X(2147483647.0) \
- X(-2147483648.0) \
- X(4294967295.0) \
- X(9007199254740991.0) \
- X(-9007199254740991.0) \
- /* 极端小值 */ \
- X(1.0e-100) \
- X(-1.0e-100) \
- X(1.0e-200) \
- X(1.0e-300) \
- X(2.225073858507201e-308) \
- /* 极端大值 */ \
- X(1.0e100) \
- X(-1.0e100) \
- X(1.0e200) \
- X(1.0e300) \
- X(1.797693134862315e308) \
- /* 特殊精度值 */ \
- X(1.0000000000001) \
- X(0.9999999999999) \
- X(1.23456789012345) \
- X(9.87654321098765) \
- /* 重复数字模式 */ \
- X(1.1111111111111) \
- X(2.2222222222222) \
- X(9.9999999999999) \
- /* 混合符号和指数 */ \
- X(-1.23e-45) \
- X(-9.87e67) \
- X(1.11e-11) \
- X(-2.22e22)
- static const double DoubleValueTable[] = {
- #define X(a) a,
- DoubleList
- #undef X
- };
- static const char *DoubleStringTable[] = {
- #define X(a) "{\"double\":" #a "}",
- DoubleList
- #undef X
- };
- static const char *DoubleStringTable2[] = {
- #define X(a) #a,
- DoubleList
- #undef X
- };
- static const char *DoubleStringTable3[] = {
- #define X(a) "[" #a "]",
- DoubleList
- #undef X
- };
- static RyanJsonBool_e shouldSkipLargeDoubleWhenNoScientific(double value)
- {
- #if false == RyanJsonSnprintfSupportScientific
- /* 不支持科学计数法的平台上,跳过超大值序列化往返校验。 */
- return RyanJsonMakeBool(fabs(value) >= 1.0e100);
- #else
- (void)value;
- return RyanJsonFalse;
- #endif
- }
- /**
- * @brief 浮点类型边界与一致性测试
- */
- void testEqualityDoubleEdgeCases(void)
- {
- // NULL 输入
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonIsDouble(NULL), "RyanJsonIsDouble(NULL) 应返回 false");
- // 类型混淆测试
- RyanJson_t num = RyanJsonCreateInt("num", 123);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsNumber(num), "RyanJsonIsNumber(Int) 应返回 true");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonIsDouble(num), "RyanJsonIsDouble(Int) 应返回 false");
- RyanJsonDelete(num);
- RyanJson_t str = RyanJsonCreateString("str", "123.456");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonIsDouble(str), "RyanJsonIsDouble(String) 应返回 false");
- RyanJsonDelete(str);
- RyanJson_t obj = RyanJsonCreateObject();
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonIsDouble(obj), "RyanJsonIsDouble(Object) 应返回 false");
- RyanJsonDelete(obj);
- RyanJson_t boolNode = RyanJsonCreateBool("bool", RyanJsonTrue);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonIsDouble(boolNode), "RyanJsonIsDouble(Bool) 应返回 false");
- RyanJsonDelete(boolNode);
- }
- static void testEqualityDoubleTypeIdentity(void)
- {
- // 指数形式即使数值是整数,也应保持 double 类型
- RyanJson_t expNode = RyanJsonParse("1e0");
- TEST_ASSERT_NOT_NULL(expNode);
- TEST_ASSERT_TRUE(RyanJsonIsDouble(expNode));
- TEST_ASSERT_TRUE(RyanJsonCompareDouble(1.0, RyanJsonGetDoubleValue(expNode)));
- char *expPrinted = RyanJsonPrint(expNode, 64, RyanJsonFalse, NULL);
- TEST_ASSERT_NOT_NULL(expPrinted);
- RyanJson_t expRoundtrip = RyanJsonParse(expPrinted);
- RyanJsonFree(expPrinted);
- TEST_ASSERT_NOT_NULL(expRoundtrip);
- TEST_ASSERT_TRUE(RyanJsonIsDouble(expRoundtrip));
- TEST_ASSERT_TRUE(RyanJsonCompareDouble(1.0, RyanJsonGetDoubleValue(expRoundtrip)));
- RyanJsonDelete(expRoundtrip);
- RyanJsonDelete(expNode);
- // 小数形式应保持 double
- RyanJson_t fracNode = RyanJsonParse("-2.5000");
- TEST_ASSERT_NOT_NULL(fracNode);
- TEST_ASSERT_TRUE(RyanJsonIsDouble(fracNode));
- TEST_ASSERT_TRUE(RyanJsonCompareDouble(-2.5, RyanJsonGetDoubleValue(fracNode)));
- RyanJsonDelete(fracNode);
- // 超出 int32_t 范围的纯数字,应归类为 double
- RyanJson_t overInt = RyanJsonParse("2147483648");
- TEST_ASSERT_NOT_NULL(overInt);
- TEST_ASSERT_TRUE(RyanJsonIsDouble(overInt));
- TEST_ASSERT_FALSE(RyanJsonIsInt(overInt));
- TEST_ASSERT_TRUE(RyanJsonCompareDouble(2147483648.0, RyanJsonGetDoubleValue(overInt)));
- RyanJsonDelete(overInt);
- RyanJson_t belowInt = RyanJsonParse("-2147483649");
- TEST_ASSERT_NOT_NULL(belowInt);
- TEST_ASSERT_TRUE(RyanJsonIsDouble(belowInt));
- TEST_ASSERT_FALSE(RyanJsonIsInt(belowInt));
- TEST_ASSERT_TRUE(RyanJsonCompareDouble(-2147483649.0, RyanJsonGetDoubleValue(belowInt)));
- RyanJsonDelete(belowInt);
- }
- static void testEqualityDoubleTableCommon(const char *const *stringTable, RyanJsonBool_e withKey)
- {
- for (uint32_t i = 0; i < sizeof(DoubleValueTable) / sizeof(DoubleValueTable[0]); i++)
- {
- double expectValue = DoubleValueTable[i];
- if (shouldSkipLargeDoubleWhenNoScientific(expectValue)) { continue; }
- const char *jsondoubleStr = stringTable[i];
- RyanJson_t jsonRoot = RyanJsonParse(jsondoubleStr);
- TEST_ASSERT_NOT_NULL_MESSAGE(jsonRoot, jsondoubleStr);
- RyanJson_t valueNode = withKey ? RyanJsonGetObjectToKey(jsonRoot, "double") : jsonRoot;
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsDouble(valueNode), withKey ? "字段 'double' 类型错误" : "Root node not double");
- // 验证解析后的数值是否正确
- double doubleValue = RyanJsonGetDoubleValue(valueNode);
- if (!RyanJsonCompareDouble(expectValue, doubleValue))
- {
- TEST_PRINTF("字符串: %s, 期望: %g, 实际: %g", jsondoubleStr, expectValue, doubleValue);
- TEST_FAIL();
- }
- // 往返校验:序列化后再次解析,数值应保持一致
- char *serializedStr = RyanJsonPrint(jsonRoot, 128, RyanJsonFalse, NULL);
- if (NULL == serializedStr)
- {
- TEST_PRINTF("序列化失败样本: %s", jsondoubleStr);
- RyanJsonDelete(jsonRoot);
- TEST_FAIL_MESSAGE("序列化失败");
- }
- RyanJsonDelete(jsonRoot);
- RyanJson_t roundtripJson = RyanJsonParse(serializedStr);
- RyanJsonFree(serializedStr);
- if (NULL == roundtripJson)
- {
- TEST_PRINTF("往返解析失败样本: %s", jsondoubleStr);
- TEST_FAIL_MESSAGE("往返测试:重新解析失败");
- }
- RyanJson_t roundtripValueNode = withKey ? RyanJsonGetObjectToKey(roundtripJson, "double") : roundtripJson;
- if (RyanJsonFalse == RyanJsonIsDouble(roundtripValueNode))
- {
- RyanJsonDelete(roundtripJson);
- TEST_FAIL_MESSAGE(withKey ? "往返测试:字段 'double' 类型错误" : "往返测试:Root node not double");
- }
- double roundtripValue = RyanJsonGetDoubleValue(roundtripValueNode);
- if (!RyanJsonCompareDouble(expectValue, roundtripValue))
- {
- TEST_PRINTF("往返测试失败:期望: %g, 实际: %g", expectValue, roundtripValue);
- TEST_FAIL();
- }
- RyanJsonDelete(roundtripJson);
- }
- }
- static void testEqualityDoubleTable(void)
- {
- testEqualityDoubleTableCommon(DoubleStringTable, RyanJsonTrue);
- }
- static void testEqualityDoubleTable2(void)
- {
- testEqualityDoubleTableCommon(DoubleStringTable2, RyanJsonFalse);
- }
- static void testEqualityDoubleTable3(void)
- {
- for (uint32_t i = 0; i < sizeof(DoubleValueTable) / sizeof(DoubleValueTable[0]); i++)
- {
- double expectValue = DoubleValueTable[i];
- if (shouldSkipLargeDoubleWhenNoScientific(expectValue)) { continue; }
- const char *jsondoubleStr = DoubleStringTable3[i];
- RyanJson_t jsonRoot = RyanJsonParse(jsondoubleStr);
- TEST_ASSERT_NOT_NULL_MESSAGE(jsonRoot, jsondoubleStr);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsArray(jsonRoot), "Root node not array");
- TEST_ASSERT_EQUAL_INT_MESSAGE(1, RyanJsonGetSize(jsonRoot), "Array size not 1");
- RyanJson_t valueNode = RyanJsonGetObjectByIndex(jsonRoot, 0);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsDouble(valueNode), "Array[0] not double");
- double doubleValue = RyanJsonGetDoubleValue(valueNode);
- if (!RyanJsonCompareDouble(expectValue, doubleValue))
- {
- TEST_PRINTF("字符串: %s, 期望: %g, 实际: %g", jsondoubleStr, expectValue, doubleValue);
- TEST_FAIL();
- }
- // 往返校验:序列化后再次解析,数值应保持一致
- char *serializedStr = RyanJsonPrint(jsonRoot, 128, RyanJsonFalse, NULL);
- if (NULL == serializedStr)
- {
- TEST_PRINTF("序列化失败样本: %s", jsondoubleStr);
- RyanJsonDelete(jsonRoot);
- TEST_FAIL_MESSAGE("序列化失败");
- }
- RyanJsonDelete(jsonRoot);
- RyanJson_t roundtripJson = RyanJsonParse(serializedStr);
- RyanJsonFree(serializedStr);
- if (NULL == roundtripJson)
- {
- TEST_PRINTF("往返解析失败样本: %s", jsondoubleStr);
- TEST_FAIL_MESSAGE("往返测试:重新解析失败");
- }
- if (RyanJsonFalse == RyanJsonIsArray(roundtripJson))
- {
- RyanJsonDelete(roundtripJson);
- TEST_FAIL_MESSAGE("往返测试:Root node not array");
- }
- if (1 != RyanJsonGetSize(roundtripJson))
- {
- RyanJsonDelete(roundtripJson);
- TEST_FAIL_MESSAGE("往返测试:Array size not 1");
- }
- RyanJson_t roundtripValueNode = RyanJsonGetObjectByIndex(roundtripJson, 0);
- if (RyanJsonFalse == RyanJsonIsDouble(roundtripValueNode))
- {
- RyanJsonDelete(roundtripJson);
- TEST_FAIL_MESSAGE("往返测试:Array[0] not double");
- }
- double roundtripValue = RyanJsonGetDoubleValue(roundtripValueNode);
- if (!RyanJsonCompareDouble(expectValue, roundtripValue))
- {
- TEST_PRINTF("往返测试失败:期望: %g, 实际: %g", expectValue, roundtripValue);
- TEST_FAIL();
- }
- RyanJsonDelete(roundtripJson);
- }
- }
- void testEqualityDoubleRunner(void)
- {
- UnitySetTestFile(__FILE__);
- RUN_TEST(testEqualityDoubleEdgeCases);
- RUN_TEST(testEqualityDoubleTypeIdentity);
- RUN_TEST(testEqualityDoubleTable);
- RUN_TEST(testEqualityDoubleTable2);
- RUN_TEST(testEqualityDoubleTable3);
- }
|