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 
31 static cJSON item[1];
32 
assert_is_array(cJSON * array_item)33 static void assert_is_array(cJSON *array_item)
34 {
35     TEST_ASSERT_NOT_NULL_MESSAGE(array_item, "Item is NULL.");
36 
37     assert_not_in_list(array_item);
38     assert_has_type(array_item, cJSON_Array);
39     assert_has_no_reference(array_item);
40     assert_has_no_const_string(array_item);
41     assert_has_no_valuestring(array_item);
42     assert_has_no_string(array_item);
43 }
44 
assert_not_array(const char * json)45 static void assert_not_array(const char *json)
46 {
47     parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
48     buffer.content = (const unsigned char*)json;
49     buffer.length = strlen(json) + sizeof("");
50     buffer.hooks = global_hooks;
51 
52     TEST_ASSERT_FALSE(parse_array(item, &buffer));
53     assert_is_invalid(item);
54 }
55 
assert_parse_array(const char * json)56 static void assert_parse_array(const char *json)
57 {
58     parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } };
59     buffer.content = (const unsigned char*)json;
60     buffer.length = strlen(json) + sizeof("");
61     buffer.hooks = global_hooks;
62 
63     TEST_ASSERT_TRUE(parse_array(item, &buffer));
64     assert_is_array(item);
65 }
66 
parse_array_should_parse_empty_arrays(void)67 static void parse_array_should_parse_empty_arrays(void)
68 {
69     assert_parse_array("[]");
70     assert_has_no_child(item);
71 
72     assert_parse_array("[\n\t]");
73     assert_has_no_child(item);
74 }
75 
76 
parse_array_should_parse_arrays_with_one_element(void)77 static void parse_array_should_parse_arrays_with_one_element(void)
78 {
79 
80     assert_parse_array("[1]");
81     assert_has_child(item);
82     assert_has_type(item->child, cJSON_Number);
83     reset(item);
84 
85     assert_parse_array("[\"hello!\"]");
86     assert_has_child(item);
87     assert_has_type(item->child, cJSON_String);
88     TEST_ASSERT_EQUAL_STRING("hello!", item->child->valuestring);
89     reset(item);
90 
91     assert_parse_array("[[]]");
92     assert_has_child(item);
93     TEST_ASSERT_NOT_NULL(item->child);
94     assert_has_type(item->child, cJSON_Array);
95     assert_has_no_child(item->child);
96     reset(item);
97 
98     assert_parse_array("[null]");
99     assert_has_child(item);
100     assert_has_type(item->child, cJSON_NULL);
101     reset(item);
102 }
103 
parse_array_should_parse_arrays_with_multiple_elements(void)104 static void parse_array_should_parse_arrays_with_multiple_elements(void)
105 {
106     assert_parse_array("[1\t,\n2, 3]");
107     assert_has_child(item);
108     TEST_ASSERT_NOT_NULL(item->child->next);
109     TEST_ASSERT_NOT_NULL(item->child->next->next);
110     TEST_ASSERT_NULL(item->child->next->next->next);
111     assert_has_type(item->child, cJSON_Number);
112     assert_has_type(item->child->next, cJSON_Number);
113     assert_has_type(item->child->next->next, cJSON_Number);
114     reset(item);
115 
116     {
117         size_t i = 0;
118         cJSON *node = NULL;
119         int expected_types[7] =
120         {
121             cJSON_Number,
122             cJSON_NULL,
123             cJSON_True,
124             cJSON_False,
125             cJSON_Array,
126             cJSON_String,
127             cJSON_Object
128         };
129         assert_parse_array("[1, null, true, false, [], \"hello\", {}]");
130 
131         node = item->child;
132         for (
133                 i = 0;
134                 (i < (sizeof(expected_types)/sizeof(int)))
135                 && (node != NULL);
136                 (void)i++, node = node->next)
137         {
138             TEST_ASSERT_BITS(0xFF, expected_types[i], node->type);
139         }
140         TEST_ASSERT_EQUAL_INT(i, 7);
141         reset(item);
142     }
143 }
144 
parse_array_should_not_parse_non_arrays(void)145 static void parse_array_should_not_parse_non_arrays(void)
146 {
147     assert_not_array("");
148     assert_not_array("[");
149     assert_not_array("]");
150     assert_not_array("{\"hello\":[]}");
151     assert_not_array("42");
152     assert_not_array("3.14");
153     assert_not_array("\"[]hello world!\n\"");
154 }
155 
main(void)156 int CJSON_CDECL main(void)
157 {
158     /* initialize cJSON item */
159     memset(item, 0, sizeof(cJSON));
160 
161     UNITY_BEGIN();
162     RUN_TEST(parse_array_should_parse_empty_arrays);
163     RUN_TEST(parse_array_should_parse_arrays_with_one_element);
164     RUN_TEST(parse_array_should_parse_arrays_with_multiple_elements);
165     RUN_TEST(parse_array_should_not_parse_non_arrays);
166     return UNITY_END();
167 }
168