tests/test_json.c

changeset 1586
7f1cadc3ebc1
parent 1582
32b82c424252
child 1588
5c4ee11417c1
--- a/tests/test_json.c	Sat Dec 13 13:55:27 2025 +0100
+++ b/tests/test_json.c	Sat Dec 13 15:16:25 2025 +0100
@@ -32,6 +32,8 @@
 #include "cx/json.h"
 #include "cx/compare.h"
 
+#include <math.h>
+
 CX_TEST(test_json_init_default) {
     CxJson json;
     CX_TEST_DO {
@@ -1249,6 +1251,132 @@
     cx_testing_allocator_destroy(&talloc);
 }
 
+CX_TEST(test_json_compare_primitives) {
+    CxJsonValue *a[14];
+    a[0] = cxJsonCreateLiteral(NULL, CX_JSON_NULL);
+    a[1] = cxJsonCreateLiteral(NULL, CX_JSON_TRUE);
+    a[2] = cxJsonCreateLiteral(NULL, CX_JSON_FALSE);
+    a[3] = cxJsonCreateInteger(NULL, 1234);
+    a[4] = cxJsonCreateInteger(NULL, 5432);
+    a[5] = cxJsonCreateInteger(NULL, -10);
+    a[6] = cxJsonCreateInteger(NULL, 0);
+    a[7] = cxJsonCreateNumber(NULL, 0.0f);
+    a[8] = cxJsonCreateNumber(NULL, 13.37f);
+    a[9] = cxJsonCreateNumber(NULL, -123.456f);
+    a[10] = cxJsonCreateNumber(NULL, 1234.0f);
+    a[11] = cxJsonCreateNumber(NULL, -10.3f);
+    a[12] = cxJsonCreateString(NULL, "hello");
+    a[13] = cxJsonCreateString(NULL, "world");
+    
+    CxJsonValue *b[14];
+    b[0] = cxJsonCreateLiteral(NULL, CX_JSON_NULL);
+    b[1] = cxJsonCreateLiteral(NULL, CX_JSON_TRUE);
+    b[2] = cxJsonCreateLiteral(NULL, CX_JSON_FALSE);
+    b[3] = cxJsonCreateInteger(NULL, 1234);
+    b[4] = cxJsonCreateInteger(NULL, 5432);
+    b[5] = cxJsonCreateInteger(NULL, -10);
+    b[6] = cxJsonCreateInteger(NULL, 0);
+    b[7] = cxJsonCreateNumber(NULL, 0.0f);
+    b[8] = cxJsonCreateNumber(NULL, 13.37f);
+    b[9] = cxJsonCreateNumber(NULL, -123.456f);
+    b[10] = cxJsonCreateNumber(NULL, 1234.0f);
+    b[11] = cxJsonCreateNumber(NULL, -10.3f);
+    b[12] = cxJsonCreateString(NULL, "hello");
+    b[13] = cxJsonCreateString(NULL, "world");
+    
+    CX_TEST_DO {
+        for(int i=0;i<12;i++) {
+            for(int j=0;j<12;j++) {
+                int ret = cxJsonCompare(a[i], b[j]);
+                if(i == j) {
+                    CX_TEST_ASSERT(ret == 0);
+                } else {
+                    if(cxJsonIsNumber(a[i]) && cxJsonIsNumber(b[j])) {
+                        double diff = fabs(cxJsonAsDouble(a[i]) - cxJsonAsDouble(b[j]));
+                        if(diff < 0.001) {
+                            CX_TEST_ASSERT(ret == 0);
+                        } else {
+                            CX_TEST_ASSERT(ret != 0);
+                        }
+                    } else {
+                        CX_TEST_ASSERT(ret != 0);
+                    }
+                }
+            }
+        }
+        
+    }
+    for(int i=0;i<14;i++) {
+        cxJsonValueFree(a[i]);
+        cxJsonValueFree(b[i]);
+    }
+}
+
+CX_TEST(test_json_compare_objects) {
+    CxJsonValue *json[7];
+    cxJsonFromString(NULL, "{ }", &json[0]);
+    cxJsonFromString(NULL, "{ }", &json[1]);
+    cxJsonFromString(NULL, "{ \"name\": \"value\" }", &json[2]);
+    cxJsonFromString(NULL, "{ \"key0\": \"value0\", \"key1\": \"value1\", \"key2\":null }", &json[3]);
+    cxJsonFromString(NULL, "{ \"key1\": \"value1\", \"key2\":null, \"key0\": \"value0\" }", &json[4]);
+    
+    const char *json_complex_object = 
+        "{\n"
+        "  \"bool\": false,\n"
+        "  \"int\": 47,\n"
+        "  \"strings\": [ \"hello\", \"world\" ],\n"
+        "  \"nested\": {\n"
+        "        \"string\": \"test\",\n"
+        "        \"floats\": [ 3.1415, 47.11, 8.15 ],\n"
+        "        \"ints\": [ 4, 8, 15, 16, 23, 42 ],\n"
+        "        \"literals\": [ true, null, false ],\n"
+        "        \"objects\": [\n"
+        "          {},\n"
+        "          { \"unicode\": \"\\u03a3\\u29b0\" },\n"
+        "          { \"array\": [ 1,2,3] }\n"
+        "        ]\n"
+        "  }\n"
+        "}\n";
+    cxJsonFromString(NULL, json_complex_object, &json[5]);
+    cxJsonFromString(NULL, json_complex_object, &json[6]);
+    
+    CX_TEST_DO {
+        for(int i=0;i<7;i++) {
+            CX_TEST_ASSERT(cxJsonIsObject(json[i]));
+        }
+        
+        CX_TEST_ASSERT(cxJsonCompare(json[0], json[0]) == 0);
+        CX_TEST_ASSERT(cxJsonCompare(json[0], json[1]) == 0);
+        CX_TEST_ASSERT(cxJsonCompare(json[2], json[2]) == 0); // <-- fail
+        
+        // compare empty object with all other objects
+        for(int i=2;i<6;i++) {
+            CX_TEST_ASSERT(cxJsonCompare(json[0], json[i]) != 0);
+        }
+        
+        // compare different objects
+        CX_TEST_ASSERT(cxJsonCompare(json[2], json[3]) != 0);
+        CX_TEST_ASSERT(cxJsonCompare(json[2], json[5]) != 0);
+        
+        // compare equal objects with different orders
+        CX_TEST_ASSERT(cxJsonCompare(json[3], json[4]) == 0); // <-- fail
+        
+        // test the same complex object
+        CX_TEST_ASSERT(cxJsonCompare(json[6], json[7])); // <-- fail, even with hashmap
+    }
+    
+    for(int i=0;i<7;i++) {
+        cxJsonValueFree(json[i]);
+    }
+}
+
+CX_TEST(test_json_compare_arrays) {
+    CX_TEST_DO {
+        
+    }
+}
+
+
 static CxJsonValue *test_json_write_create_test_object(const CxAllocator *allocator) {
     CxJsonValue *obj = cxJsonCreateObj(allocator);
     cxJsonObjPutLiteral(obj, "bool", CX_JSON_FALSE);
@@ -1681,6 +1809,9 @@
     cx_test_register(suite, test_json_allocator_parse_error);
     cx_test_register(suite, test_json_create_value);
     cx_test_register(suite, test_json_overwrite_value);
+    cx_test_register(suite, test_json_compare_primitives);
+    cx_test_register(suite, test_json_compare_objects);
+    cx_test_register(suite, test_json_compare_arrays);
     cx_test_register(suite, test_json_write_default_format);
     cx_test_register(suite, test_json_write_pretty_default_spaces);
     cx_test_register(suite, test_json_write_pretty_default_tabs);

mercurial