Add utility function for comparing json_objectstags/json-c-0.13-20171207
| @@ -45,6 +45,7 @@ | |||||
| /tests/test_null | /tests/test_null | ||||
| /tests/test_printbuf | /tests/test_printbuf | ||||
| /tests/test_set_serializer | /tests/test_set_serializer | ||||
| /tests/test_compare | |||||
| /tests/*.vg.out | /tests/*.vg.out | ||||
| /tests/*.log | /tests/*.log | ||||
| /tests/*.trs | /tests/*.trs | ||||
| @@ -992,3 +992,84 @@ struct json_object* json_object_array_get_idx(const struct json_object *jso, | |||||
| return (struct json_object*)array_list_get_idx(jso->o.c_array, idx); | return (struct json_object*)array_list_get_idx(jso->o.c_array, idx); | ||||
| } | } | ||||
| static int json_array_equal(struct json_object* jso1, | |||||
| struct json_object* jso2) | |||||
| { | |||||
| int len, i; | |||||
| len = json_object_array_length(jso1); | |||||
| if (len != json_object_array_length(jso2)) | |||||
| return 0; | |||||
| for (i = 0; i < len; i++) { | |||||
| if (!json_object_equal(json_object_array_get_idx(jso1, i), | |||||
| json_object_array_get_idx(jso2, i))) | |||||
| return 0; | |||||
| } | |||||
| return 1; | |||||
| } | |||||
| static int json_object_all_values_equal(struct json_object* jso1, | |||||
| struct json_object* jso2) | |||||
| { | |||||
| struct json_object_iter iter; | |||||
| struct json_object *sub; | |||||
| /* Iterate over jso1 keys and see if they exist and are equal in jso2 */ | |||||
| json_object_object_foreachC(jso1, iter) { | |||||
| if (!lh_table_lookup_ex(jso1->o.c_object, (void*)iter.key, | |||||
| (void**)&sub)) | |||||
| return 0; | |||||
| if (!json_object_equal(iter.val, sub)) | |||||
| return 0; | |||||
| } | |||||
| /* Iterate over jso2 keys to see if any exist that are not in jso1 */ | |||||
| json_object_object_foreachC(jso2, iter) { | |||||
| if (!lh_table_lookup_ex(jso1->o.c_object, (void*)iter.key, | |||||
| (void**)&sub)) | |||||
| return 0; | |||||
| } | |||||
| return 1; | |||||
| } | |||||
| int json_object_equal(struct json_object* jso1, struct json_object* jso2) | |||||
| { | |||||
| if (jso1 == jso2) | |||||
| return 1; | |||||
| if (!jso1 || !jso2) | |||||
| return 0; | |||||
| if (jso1->o_type != jso2->o_type) | |||||
| return 0; | |||||
| switch(jso1->o_type) { | |||||
| case json_type_boolean: | |||||
| return (jso1->o.c_boolean == jso2->o.c_boolean); | |||||
| case json_type_double: | |||||
| return (jso1->o.c_double == jso2->o.c_double); | |||||
| case json_type_int: | |||||
| return (jso1->o.c_int64 == jso2->o.c_int64); | |||||
| case json_type_string: | |||||
| return (jso1->o.c_string.len == jso2->o.c_string.len && | |||||
| memcmp(get_string_component(jso1), | |||||
| get_string_component(jso2), | |||||
| jso1->o.c_string.len) == 0); | |||||
| case json_type_object: | |||||
| return json_object_all_values_equal(jso1, jso2); | |||||
| case json_type_array: | |||||
| return json_array_equal(jso1, jso2); | |||||
| case json_type_null: | |||||
| return 1; | |||||
| }; | |||||
| return 0; | |||||
| } | |||||
| @@ -696,6 +696,26 @@ extern const char* json_object_get_string(struct json_object *obj); | |||||
| */ | */ | ||||
| extern int json_object_get_string_len(const struct json_object *obj); | extern int json_object_get_string_len(const struct json_object *obj); | ||||
| /** Check if two json_object's are equal | |||||
| * | |||||
| * If the passed objects are equal 1 will be returned. | |||||
| * Equality is defined as follows: | |||||
| * - json_objects of different types are never equal | |||||
| * - json_objects of the same primitive type are equal if the | |||||
| * c-representation of their value is equal | |||||
| * - json-arrays are considered equal if all values at the same | |||||
| * indices are equal (same order) | |||||
| * - Complex json_objects are considered equal if all | |||||
| * contained objects referenced by their key are equal, | |||||
| * regardless their order. | |||||
| * | |||||
| * @param obj1 the first json_object instance | |||||
| * @param obj2 the second json_object instance | |||||
| * @returns whether both objects are equal or not | |||||
| */ | |||||
| extern int json_object_equal(struct json_object *obj1, | |||||
| struct json_object *obj2); | |||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||
| } | } | ||||
| #endif | #endif | ||||
| @@ -16,6 +16,7 @@ TESTS+= test_locale.test | |||||
| TESTS+= test_charcase.test | TESTS+= test_charcase.test | ||||
| TESTS+= test_printbuf.test | TESTS+= test_printbuf.test | ||||
| TESTS+= test_set_serializer.test | TESTS+= test_set_serializer.test | ||||
| TESTS+= test_compare.test | |||||
| check_PROGRAMS= | check_PROGRAMS= | ||||
| check_PROGRAMS += $(TESTS:.test=) | check_PROGRAMS += $(TESTS:.test=) | ||||
| @@ -0,0 +1,145 @@ | |||||
| /* | |||||
| * Tests if json_object_equal behaves correct. | |||||
| */ | |||||
| #include <stdio.h> | |||||
| #include <string.h> | |||||
| #include "config.h" | |||||
| #include "json_inttypes.h" | |||||
| #include "json_object.h" | |||||
| #include "json_tokener.h" | |||||
| int main() | |||||
| { | |||||
| /* integer tests */ | |||||
| struct json_object *int1 = json_object_new_int(0); | |||||
| struct json_object *int2 = json_object_new_int(1); | |||||
| struct json_object *int3 = json_object_new_int(1); | |||||
| if (!json_object_equal(int1, int2)) | |||||
| printf("JSON integer comparision is correct\n"); | |||||
| else | |||||
| printf("JSON integer comparision failed\n"); | |||||
| if (json_object_equal(int1, int1)) | |||||
| printf("JSON same object comparision is correct\n"); | |||||
| else | |||||
| printf("JSON same object comparision failed\n"); | |||||
| if (json_object_equal(int2, int3)) | |||||
| printf("JSON same integer comparision is correct\n"); | |||||
| else | |||||
| printf("JSON same integer comparision failed\n"); | |||||
| json_object_put(int1); | |||||
| json_object_put(int2); | |||||
| json_object_put(int3); | |||||
| /* string tests */ | |||||
| struct json_object *str1 = json_object_new_string("TESTSTRING"); | |||||
| struct json_object *str2 = json_object_new_string("TESTSTRING"); | |||||
| struct json_object *str3 = json_object_new_string("DIFFERENT"); | |||||
| if (json_object_equal(str1, str2)) | |||||
| printf("Comparing equal strings is correct\n"); | |||||
| else | |||||
| printf("Comparing equal strings failed\n"); | |||||
| if (!json_object_equal(str1, str3)) | |||||
| printf("Comparing different strings is correct\n"); | |||||
| else | |||||
| printf("Comparing different strings failed\n"); | |||||
| json_object_put(str1); | |||||
| json_object_put(str2); | |||||
| json_object_put(str3); | |||||
| /* double tests */ | |||||
| struct json_object *dbl1 = json_object_new_double(3.14159); | |||||
| struct json_object *dbl2 = json_object_new_double(3.14159); | |||||
| struct json_object *dbl3 = json_object_new_double(3.0); | |||||
| if (json_object_equal(dbl1, dbl2)) | |||||
| printf("Comparing equal doubles is correct\n"); | |||||
| else | |||||
| printf("Comparing equal doubles failed\n"); | |||||
| if (!json_object_equal(dbl1, dbl3)) | |||||
| printf("Comparing different doubles is correct\n"); | |||||
| else | |||||
| printf("Comparing different doubles failed\n"); | |||||
| json_object_put(dbl1); | |||||
| json_object_put(dbl2); | |||||
| json_object_put(dbl3); | |||||
| /* array tests */ | |||||
| struct json_object *ar1 = json_object_new_array(); | |||||
| struct json_object *ar2 = json_object_new_array(); | |||||
| struct json_object *ar3 = json_object_new_array(); | |||||
| struct json_object *ar4 = json_object_new_array(); | |||||
| json_object_array_add(ar1, json_object_new_int(1)); | |||||
| json_object_array_add(ar1, json_object_new_int(2)); | |||||
| json_object_array_add(ar2, json_object_new_int(1)); | |||||
| json_object_array_add(ar2, json_object_new_int(2)); | |||||
| json_object_array_add(ar3, json_object_new_int(1)); | |||||
| json_object_array_add(ar3, json_object_new_int(1)); | |||||
| if (json_object_equal(ar1, ar2)) | |||||
| printf("Comparing equal arrays is correct\n"); | |||||
| else | |||||
| printf("Comparing equal arrays failed\n"); | |||||
| json_object_array_add(ar2, json_object_new_int(1)); | |||||
| if (!json_object_equal(ar1, ar2)) | |||||
| printf("Comparing arrays of different len is correct\n"); | |||||
| else | |||||
| printf("Comparing arrays of different len failed\n"); | |||||
| if (!json_object_equal(ar1, ar3)) | |||||
| printf("Comparing different arrays is correct\n"); | |||||
| else | |||||
| printf("Comparing different arrays failed\n"); | |||||
| if (!json_object_equal(ar1, ar4)) | |||||
| printf("Comparing different arrays (one empty) is correct\n"); | |||||
| else | |||||
| printf("Comparing different arrays (one empty) failed\n"); | |||||
| json_object_put(ar1); | |||||
| json_object_put(ar2); | |||||
| json_object_put(ar3); | |||||
| json_object_put(ar4); | |||||
| /* object tests */ | |||||
| struct json_object *obj1 = json_object_new_object(); | |||||
| struct json_object *obj2 = json_object_new_object(); | |||||
| json_object_object_add(obj1, "test1", json_object_new_int(123)); | |||||
| json_object_object_add(obj1, "test2", json_object_new_int(321)); | |||||
| json_object_object_add(obj2, "test2", json_object_new_int(123)); | |||||
| json_object_object_add(obj2, "test1", json_object_new_int(321)); | |||||
| /* key-order is different between obj1 and obj2, should still be equal */ | |||||
| if (json_object_equal(obj1, obj2)) | |||||
| printf("Comparing JSON object with different key order is correct\n"); | |||||
| else | |||||
| printf("Comparing JSON object with different key order is incorrect\n"); | |||||
| /* make obj2 look different to obj1 */ | |||||
| json_object_object_add(obj2, "test3", json_object_new_int(234)); | |||||
| if (!json_object_equal(obj1, obj2)) | |||||
| printf("Comparing different objects is correct\n"); | |||||
| else | |||||
| printf("Comparing different objects is incorrect\n"); | |||||
| json_object_put(obj1); | |||||
| json_object_put(obj2); | |||||
| return 0; | |||||
| } | |||||
| @@ -0,0 +1,13 @@ | |||||
| JSON integer comparision is correct | |||||
| JSON same object comparision is correct | |||||
| JSON same integer comparision is correct | |||||
| Comparing equal strings is correct | |||||
| Comparing different strings is correct | |||||
| Comparing equal doubles is correct | |||||
| Comparing different doubles is correct | |||||
| Comparing equal arrays is correct | |||||
| Comparing arrays of different len is correct | |||||
| Comparing different arrays is correct | |||||
| Comparing different arrays (one empty) is correct | |||||
| Comparing JSON object with different key order is correct | |||||
| Comparing different objects is correct | |||||
| @@ -0,0 +1,12 @@ | |||||
| #!/bin/sh | |||||
| # Common definitions | |||||
| if test -z "$srcdir"; then | |||||
| srcdir="${0%/*}" | |||||
| test "$srcdir" = "$0" && srcdir=. | |||||
| test -z "$srcdir" && srcdir=. | |||||
| fi | |||||
| . "$srcdir/test-defs.sh" | |||||
| run_output_test test_compare | |||||
| exit $? | |||||