mirror of
https://github.com/json-c/json-c.git
synced 2026-03-23 06:59:06 +08:00
Merge pull request #220 from hschaa/master
Add utility function for comparing json_objects
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -45,6 +45,7 @@
|
||||
/tests/test_null
|
||||
/tests/test_printbuf
|
||||
/tests/test_set_serializer
|
||||
/tests/test_compare
|
||||
/tests/*.vg.out
|
||||
/tests/*.log
|
||||
/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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
/** 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
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -16,6 +16,7 @@ TESTS+= test_locale.test
|
||||
TESTS+= test_charcase.test
|
||||
TESTS+= test_printbuf.test
|
||||
TESTS+= test_set_serializer.test
|
||||
TESTS+= test_compare.test
|
||||
|
||||
check_PROGRAMS=
|
||||
check_PROGRAMS += $(TESTS:.test=)
|
||||
|
||||
145
tests/test_compare.c
Normal file
145
tests/test_compare.c
Normal file
@@ -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;
|
||||
}
|
||||
13
tests/test_compare.expected
Normal file
13
tests/test_compare.expected
Normal file
@@ -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
|
||||
12
tests/test_compare.test
Executable file
12
tests/test_compare.test
Executable file
@@ -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 $?
|
||||
Reference in New Issue
Block a user