1 /*
2   Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
3 
4   Permission is hereby granted, free of charge, to any person obtaining a copy
5   of this software and associated documentation files (the "Software"), to deal
6   in the Software without restriction, including without limitation the rights
7   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8   copies of the Software, and to permit persons to whom the Software is
9   furnished to do so, subject to the following conditions:
10 
11   The above copyright notice and this permission notice shall be included in
12   all copies or substantial portions of the Software.
13 
14   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20   THE SOFTWARE.
21 */
22 
23 #include "unity/examples/unity_config.h"
24 #include "unity/src/unity.h"
25 #include "common.h"
26 
compare_from_string(const char * const a,const char * const b,const cJSON_bool case_sensitive)27 static cJSON_bool compare_from_string(const char * const a, const char * const b, const cJSON_bool case_sensitive)
28 {
29     cJSON *a_json = NULL;
30     cJSON *b_json = NULL;
31     cJSON_bool result = false;
32 
33     a_json = cJSON_Parse(a);
34     TEST_ASSERT_NOT_NULL_MESSAGE(a_json, "Failed to parse a.");
35     b_json = cJSON_Parse(b);
36     TEST_ASSERT_NOT_NULL_MESSAGE(b_json, "Failed to parse b.");
37 
38     result = cJSON_Compare(a_json, b_json, case_sensitive);
39 
40     cJSON_Delete(a_json);
41     cJSON_Delete(b_json);
42 
43     return result;
44 }
45 
cjson_compare_should_compare_null_pointer_as_not_equal(void)46 static void cjson_compare_should_compare_null_pointer_as_not_equal(void)
47 {
48     TEST_ASSERT_FALSE(cJSON_Compare(NULL, NULL, true));
49     TEST_ASSERT_FALSE(cJSON_Compare(NULL, NULL, false));
50 }
51 
cjson_compare_should_compare_invalid_as_not_equal(void)52 static void cjson_compare_should_compare_invalid_as_not_equal(void)
53 {
54     cJSON invalid[1];
55     memset(invalid, '\0', sizeof(invalid));
56 
57     TEST_ASSERT_FALSE(cJSON_Compare(invalid, invalid, false));
58     TEST_ASSERT_FALSE(cJSON_Compare(invalid, invalid, true));
59 }
60 
cjson_compare_should_compare_numbers(void)61 static void cjson_compare_should_compare_numbers(void)
62 {
63     TEST_ASSERT_TRUE(compare_from_string("1", "1", true));
64     TEST_ASSERT_TRUE(compare_from_string("1", "1", false));
65     TEST_ASSERT_TRUE(compare_from_string("0.0001", "0.0001", true));
66     TEST_ASSERT_TRUE(compare_from_string("0.0001", "0.0001", false));
67     TEST_ASSERT_TRUE(compare_from_string("1E100", "10E99", false));
68 
69     TEST_ASSERT_FALSE(compare_from_string("0.5E-100", "0.5E-101", false));
70 
71     TEST_ASSERT_FALSE(compare_from_string("1", "2", true));
72     TEST_ASSERT_FALSE(compare_from_string("1", "2", false));
73 }
74 
cjson_compare_should_compare_booleans(void)75 static void cjson_compare_should_compare_booleans(void)
76 {
77     /* true */
78     TEST_ASSERT_TRUE(compare_from_string("true", "true", true));
79     TEST_ASSERT_TRUE(compare_from_string("true", "true", false));
80 
81     /* false */
82     TEST_ASSERT_TRUE(compare_from_string("false", "false", true));
83     TEST_ASSERT_TRUE(compare_from_string("false", "false", false));
84 
85     /* mixed */
86     TEST_ASSERT_FALSE(compare_from_string("true", "false", true));
87     TEST_ASSERT_FALSE(compare_from_string("true", "false", false));
88     TEST_ASSERT_FALSE(compare_from_string("false", "true", true));
89     TEST_ASSERT_FALSE(compare_from_string("false", "true", false));
90 }
91 
cjson_compare_should_compare_null(void)92 static void cjson_compare_should_compare_null(void)
93 {
94     TEST_ASSERT_TRUE(compare_from_string("null", "null", true));
95     TEST_ASSERT_TRUE(compare_from_string("null", "null", false));
96 
97     TEST_ASSERT_FALSE(compare_from_string("null", "true", true));
98     TEST_ASSERT_FALSE(compare_from_string("null", "true", false));
99 }
100 
cjson_compare_should_not_accept_invalid_types(void)101 static void cjson_compare_should_not_accept_invalid_types(void)
102 {
103     cJSON invalid[1];
104     memset(invalid, '\0', sizeof(invalid));
105 
106     invalid->type = cJSON_Number | cJSON_String;
107 
108     TEST_ASSERT_FALSE(cJSON_Compare(invalid, invalid, true));
109     TEST_ASSERT_FALSE(cJSON_Compare(invalid, invalid, false));
110 }
111 
cjson_compare_should_compare_strings(void)112 static void cjson_compare_should_compare_strings(void)
113 {
114     TEST_ASSERT_TRUE(compare_from_string("\"abcdefg\"", "\"abcdefg\"", true));
115     TEST_ASSERT_TRUE(compare_from_string("\"abcdefg\"", "\"abcdefg\"", false));
116 
117     TEST_ASSERT_FALSE(compare_from_string("\"ABCDEFG\"", "\"abcdefg\"", true));
118     TEST_ASSERT_FALSE(compare_from_string("\"ABCDEFG\"", "\"abcdefg\"", false));
119 }
120 
cjson_compare_should_compare_raw(void)121 static void cjson_compare_should_compare_raw(void)
122 {
123     cJSON *raw1 = NULL;
124     cJSON *raw2 = NULL;
125 
126     raw1 = cJSON_Parse("\"[true, false]\"");
127     TEST_ASSERT_NOT_NULL(raw1);
128     raw2 = cJSON_Parse("\"[true, false]\"");
129     TEST_ASSERT_NOT_NULL(raw2);
130 
131     raw1->type = cJSON_Raw;
132     raw2->type = cJSON_Raw;
133 
134     TEST_ASSERT_TRUE(cJSON_Compare(raw1, raw2, true));
135     TEST_ASSERT_TRUE(cJSON_Compare(raw1, raw2, false));
136 
137     cJSON_Delete(raw1);
138     cJSON_Delete(raw2);
139 }
140 
cjson_compare_should_compare_arrays(void)141 static void cjson_compare_should_compare_arrays(void)
142 {
143     TEST_ASSERT_TRUE(compare_from_string("[]", "[]", true));
144     TEST_ASSERT_TRUE(compare_from_string("[]", "[]", false));
145 
146     TEST_ASSERT_TRUE(compare_from_string("[false,true,null,42,\"string\",[],{}]", "[false, true, null, 42, \"string\", [], {}]", true));
147     TEST_ASSERT_TRUE(compare_from_string("[false,true,null,42,\"string\",[],{}]", "[false, true, null, 42, \"string\", [], {}]", false));
148 
149     TEST_ASSERT_TRUE(compare_from_string("[[[1], 2]]", "[[[1], 2]]", true));
150     TEST_ASSERT_TRUE(compare_from_string("[[[1], 2]]", "[[[1], 2]]", false));
151 
152     TEST_ASSERT_FALSE(compare_from_string("[true,null,42,\"string\",[],{}]", "[false, true, null, 42, \"string\", [], {}]", true));
153     TEST_ASSERT_FALSE(compare_from_string("[true,null,42,\"string\",[],{}]", "[false, true, null, 42, \"string\", [], {}]", false));
154 
155     /* Arrays that are a prefix of another array */
156     TEST_ASSERT_FALSE(compare_from_string("[1,2,3]", "[1,2]", true));
157     TEST_ASSERT_FALSE(compare_from_string("[1,2,3]", "[1,2]", false));
158 }
159 
cjson_compare_should_compare_objects(void)160 static void cjson_compare_should_compare_objects(void)
161 {
162     TEST_ASSERT_TRUE(compare_from_string("{}", "{}", true));
163     TEST_ASSERT_TRUE(compare_from_string("{}", "{}", false));
164 
165     TEST_ASSERT_TRUE(compare_from_string(
166                 "{\"false\": false, \"true\": true, \"null\": null, \"number\": 42, \"string\": \"string\", \"array\": [], \"object\": {}}",
167                 "{\"true\": true, \"false\": false, \"null\": null, \"number\": 42, \"string\": \"string\", \"array\": [], \"object\": {}}",
168                 true));
169     TEST_ASSERT_FALSE(compare_from_string(
170                 "{\"False\": false, \"true\": true, \"null\": null, \"number\": 42, \"string\": \"string\", \"array\": [], \"object\": {}}",
171                 "{\"true\": true, \"false\": false, \"null\": null, \"number\": 42, \"string\": \"string\", \"array\": [], \"object\": {}}",
172                 true));
173     TEST_ASSERT_TRUE(compare_from_string(
174                 "{\"False\": false, \"true\": true, \"null\": null, \"number\": 42, \"string\": \"string\", \"array\": [], \"object\": {}}",
175                 "{\"true\": true, \"false\": false, \"null\": null, \"number\": 42, \"string\": \"string\", \"array\": [], \"object\": {}}",
176                 false));
177     TEST_ASSERT_FALSE(compare_from_string(
178                 "{\"Flse\": false, \"true\": true, \"null\": null, \"number\": 42, \"string\": \"string\", \"array\": [], \"object\": {}}",
179                 "{\"true\": true, \"false\": false, \"null\": null, \"number\": 42, \"string\": \"string\", \"array\": [], \"object\": {}}",
180                 false));
181     /* test objects that are a subset of each other */
182     TEST_ASSERT_FALSE(compare_from_string(
183                 "{\"one\": 1, \"two\": 2}",
184                 "{\"one\": 1, \"two\": 2, \"three\": 3}",
185                 true))
186     TEST_ASSERT_FALSE(compare_from_string(
187                 "{\"one\": 1, \"two\": 2}",
188                 "{\"one\": 1, \"two\": 2, \"three\": 3}",
189                 false))
190 }
191 
main(void)192 int CJSON_CDECL main(void)
193 {
194     UNITY_BEGIN();
195 
196     RUN_TEST(cjson_compare_should_compare_null_pointer_as_not_equal);
197     RUN_TEST(cjson_compare_should_compare_invalid_as_not_equal);
198     RUN_TEST(cjson_compare_should_compare_numbers);
199     RUN_TEST(cjson_compare_should_compare_booleans);
200     RUN_TEST(cjson_compare_should_compare_null);
201     RUN_TEST(cjson_compare_should_not_accept_invalid_types);
202     RUN_TEST(cjson_compare_should_compare_strings);
203     RUN_TEST(cjson_compare_should_compare_raw);
204     RUN_TEST(cjson_compare_should_compare_arrays);
205     RUN_TEST(cjson_compare_should_compare_objects);
206 
207     return UNITY_END();
208 }
209