• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include "unity/examples/unity_config.h"
28 #include "unity/src/unity.h"
29 #include "common.h"
30 #include "../cJSON_Utils.h"
31 
32 /* JSON Apply Merge tests: */
33 static const char *merges[15][3] =
34 {
35     {"{\"a\":\"b\"}", "{\"a\":\"c\"}", "{\"a\":\"c\"}"},
36     {"{\"a\":\"b\"}", "{\"b\":\"c\"}", "{\"a\":\"b\",\"b\":\"c\"}"},
37     {"{\"a\":\"b\"}", "{\"a\":null}", "{}"},
38     {"{\"a\":\"b\",\"b\":\"c\"}", "{\"a\":null}", "{\"b\":\"c\"}"},
39     {"{\"a\":[\"b\"]}", "{\"a\":\"c\"}", "{\"a\":\"c\"}"},
40     {"{\"a\":\"c\"}", "{\"a\":[\"b\"]}", "{\"a\":[\"b\"]}"},
41     {"{\"a\":{\"b\":\"c\"}}", "{\"a\":{\"b\":\"d\",\"c\":null}}", "{\"a\":{\"b\":\"d\"}}"},
42     {"{\"a\":[{\"b\":\"c\"}]}", "{\"a\":[1]}", "{\"a\":[1]}"},
43     {"[\"a\",\"b\"]", "[\"c\",\"d\"]", "[\"c\",\"d\"]"},
44     {"{\"a\":\"b\"}", "[\"c\"]", "[\"c\"]"},
45     {"{\"a\":\"foo\"}", "null", "null"},
46     {"{\"a\":\"foo\"}", "\"bar\"", "\"bar\""},
47     {"{\"e\":null}", "{\"a\":1}", "{\"e\":null,\"a\":1}"},
48     {"[1,2]", "{\"a\":\"b\",\"c\":null}", "{\"a\":\"b\"}"},
49     {"{}","{\"a\":{\"bb\":{\"ccc\":null}}}", "{\"a\":{\"bb\":{}}}"}
50 };
51 
json_pointer_tests(void)52 static void json_pointer_tests(void)
53 {
54     cJSON *root = NULL;
55     const char *json=
56         "{"
57         "\"foo\": [\"bar\", \"baz\"],"
58         "\"\": 0,"
59         "\"a/b\": 1,"
60         "\"c%d\": 2,"
61         "\"e^f\": 3,"
62         "\"g|h\": 4,"
63         "\"i\\\\j\": 5,"
64         "\"k\\\"l\": 6,"
65         "\" \": 7,"
66         "\"m~n\": 8"
67         "}";
68 
69     root = cJSON_Parse(json);
70 
71     TEST_ASSERT_EQUAL_PTR(cJSONUtils_GetPointer(root, ""), root);
72     TEST_ASSERT_EQUAL_PTR(cJSONUtils_GetPointer(root, "/foo"), cJSON_GetObjectItem(root, "foo"));
73     TEST_ASSERT_EQUAL_PTR(cJSONUtils_GetPointer(root, "/foo/0"), cJSON_GetObjectItem(root, "foo")->child);
74     TEST_ASSERT_EQUAL_PTR(cJSONUtils_GetPointer(root, "/foo/0"), cJSON_GetObjectItem(root, "foo")->child);
75     TEST_ASSERT_EQUAL_PTR(cJSONUtils_GetPointer(root, "/"), cJSON_GetObjectItem(root, ""));
76     TEST_ASSERT_EQUAL_PTR(cJSONUtils_GetPointer(root, "/a~1b"), cJSON_GetObjectItem(root, "a/b"));
77     TEST_ASSERT_EQUAL_PTR(cJSONUtils_GetPointer(root, "/c%d"), cJSON_GetObjectItem(root, "c%d"));
78     TEST_ASSERT_EQUAL_PTR(cJSONUtils_GetPointer(root, "/c^f"), cJSON_GetObjectItem(root, "c^f"));
79     TEST_ASSERT_EQUAL_PTR(cJSONUtils_GetPointer(root, "/c|f"), cJSON_GetObjectItem(root, "c|f"));
80     TEST_ASSERT_EQUAL_PTR(cJSONUtils_GetPointer(root, "/i\\j"), cJSON_GetObjectItem(root, "i\\j"));
81     TEST_ASSERT_EQUAL_PTR(cJSONUtils_GetPointer(root, "/k\"l"), cJSON_GetObjectItem(root, "k\"l"));
82     TEST_ASSERT_EQUAL_PTR(cJSONUtils_GetPointer(root, "/ "), cJSON_GetObjectItem(root, " "));
83     TEST_ASSERT_EQUAL_PTR(cJSONUtils_GetPointer(root, "/m~0n"), cJSON_GetObjectItem(root, "m~n"));
84 
85     cJSON_Delete(root);
86 }
87 
misc_tests(void)88 static void misc_tests(void)
89 {
90     /* Misc tests */
91     int numbers[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
92     cJSON *object = NULL;
93     cJSON *object1 = NULL;
94     cJSON *object2 = NULL;
95     cJSON *object3 = NULL;
96     cJSON *object4 = NULL;
97     cJSON *nums = NULL;
98     cJSON *num6 = NULL;
99     char *pointer = NULL;
100 
101     printf("JSON Pointer construct\n");
102     object = cJSON_CreateObject();
103     nums = cJSON_CreateIntArray(numbers, 10);
104     num6 = cJSON_GetArrayItem(nums, 6);
105     cJSON_AddItemToObject(object, "numbers", nums);
106 
107     pointer = cJSONUtils_FindPointerFromObjectTo(object, num6);
108     TEST_ASSERT_EQUAL_STRING("/numbers/6", pointer);
109     free(pointer);
110 
111     pointer = cJSONUtils_FindPointerFromObjectTo(object, nums);
112     TEST_ASSERT_EQUAL_STRING("/numbers", pointer);
113     free(pointer);
114 
115     pointer = cJSONUtils_FindPointerFromObjectTo(object, object);
116     TEST_ASSERT_EQUAL_STRING("", pointer);
117     free(pointer);
118 
119     object1 = cJSON_CreateObject();
120     object2 = cJSON_CreateString("m~n");
121     cJSON_AddItemToObject(object1, "m~n", object2);
122     pointer = cJSONUtils_FindPointerFromObjectTo(object1, object2);
123     TEST_ASSERT_EQUAL_STRING("/m~0n",pointer);
124     free(pointer);
125 
126     object3 = cJSON_CreateObject();
127     object4 = cJSON_CreateString("m/n");
128     cJSON_AddItemToObject(object3, "m/n", object4);
129     pointer = cJSONUtils_FindPointerFromObjectTo(object3, object4);
130     TEST_ASSERT_EQUAL_STRING("/m~1n",pointer);
131     free(pointer);
132 
133     cJSON_Delete(object);
134     cJSON_Delete(object1);
135     cJSON_Delete(object3);
136 }
137 
sort_tests(void)138 static void sort_tests(void)
139 {
140     /* Misc tests */
141     const char *random = "QWERTYUIOPASDFGHJKLZXCVBNM";
142     char buf[2] = {'\0', '\0'};
143     cJSON *sortme = NULL;
144     size_t i = 0;
145     cJSON *current_element = NULL;
146 
147     /* JSON Sort test: */
148     sortme = cJSON_CreateObject();
149     for (i = 0; i < 26; i++)
150     {
151         buf[0] = random[i];
152         cJSON_AddItemToObject(sortme, buf, cJSON_CreateNumber(1));
153     }
154 
155     cJSONUtils_SortObject(sortme);
156 
157     /* check sorting */
158     current_element = sortme->child->next;
159     for (i = 1; (i < 26) && (current_element != NULL) && (current_element->prev != NULL); i++)
160     {
161         TEST_ASSERT_TRUE(current_element->string[0] >= current_element->prev->string[0]);
162         current_element = current_element->next;
163     }
164 
165     cJSON_Delete(sortme);
166 }
167 
merge_tests(void)168 static void merge_tests(void)
169 {
170     size_t i = 0;
171     char *patchtext = NULL;
172     char *after = NULL;
173 
174     /* Merge tests: */
175     printf("JSON Merge Patch tests\n");
176     for (i = 0; i < 15; i++)
177     {
178         cJSON *object_to_be_merged = cJSON_Parse(merges[i][0]);
179         cJSON *patch = cJSON_Parse(merges[i][1]);
180         patchtext = cJSON_PrintUnformatted(patch);
181         object_to_be_merged = cJSONUtils_MergePatch(object_to_be_merged, patch);
182         after = cJSON_PrintUnformatted(object_to_be_merged);
183         TEST_ASSERT_EQUAL_STRING(merges[i][2], after);
184 
185         free(patchtext);
186         free(after);
187         cJSON_Delete(object_to_be_merged);
188         cJSON_Delete(patch);
189     }
190 }
191 
generate_merge_tests(void)192 static void generate_merge_tests(void)
193 {
194     size_t i = 0;
195     char *patchedtext = NULL;
196 
197     /* Generate Merge tests: */
198     for (i = 0; i < 15; i++)
199     {
200         cJSON *from = cJSON_Parse(merges[i][0]);
201         cJSON *to = cJSON_Parse(merges[i][2]);
202         cJSON *patch = cJSONUtils_GenerateMergePatch(from,to);
203         from = cJSONUtils_MergePatch(from,patch);
204         patchedtext = cJSON_PrintUnformatted(from);
205         TEST_ASSERT_EQUAL_STRING(merges[i][2], patchedtext);
206 
207         cJSON_Delete(from);
208         cJSON_Delete(to);
209         cJSON_Delete(patch);
210         free(patchedtext);
211     }
212 }
213 
main(void)214 int main(void)
215 {
216     UNITY_BEGIN();
217 
218     RUN_TEST(json_pointer_tests);
219     RUN_TEST(misc_tests);
220     RUN_TEST(sort_tests);
221     RUN_TEST(merge_tests);
222     RUN_TEST(generate_merge_tests);
223 
224     return UNITY_END();
225 }
226