1#include <js_native_api.h>
2
3#include "../common.h"
4#include "test_null.h"
5
6static napi_value SetProperty(napi_env env, napi_callback_info info) {
7  napi_value return_value, object, key;
8
9  NODE_API_CALL(env, napi_create_object(env, &return_value));
10  NODE_API_CALL(env, napi_create_object(env, &object));
11  NODE_API_CALL(env,
12      napi_create_string_utf8(env, "someString", NAPI_AUTO_LENGTH, &key));
13
14  add_returned_status(env,
15                      "envIsNull",
16                      return_value,
17                      "Invalid argument",
18                      napi_invalid_arg,
19                      napi_set_property(NULL, object, key, object));
20
21  napi_set_property(env, NULL, key, object);
22  add_last_status(env, "objectIsNull", return_value);
23
24  napi_set_property(env, object, NULL, object);
25  add_last_status(env, "keyIsNull", return_value);
26
27  napi_set_property(env, object, key, NULL);
28  add_last_status(env, "valueIsNull", return_value);
29
30  return return_value;
31}
32
33static napi_value GetProperty(napi_env env, napi_callback_info info) {
34  napi_value return_value, object, key, prop;
35
36  NODE_API_CALL(env, napi_create_object(env, &return_value));
37  NODE_API_CALL(env, napi_create_object(env, &object));
38  NODE_API_CALL(env,
39      napi_create_string_utf8(env, "someString", NAPI_AUTO_LENGTH, &key));
40
41  add_returned_status(env,
42                      "envIsNull",
43                      return_value,
44                      "Invalid argument",
45                      napi_invalid_arg,
46                      napi_get_property(NULL, object, key, &prop));
47
48  napi_get_property(env, NULL, key, &prop);
49  add_last_status(env, "objectIsNull", return_value);
50
51  napi_get_property(env, object, NULL, &prop);
52  add_last_status(env, "keyIsNull", return_value);
53
54  napi_get_property(env, object, key, NULL);
55  add_last_status(env, "valueIsNull", return_value);
56
57  return return_value;
58}
59
60static napi_value TestBoolValuedPropApi(napi_env env,
61    napi_status (*api)(napi_env, napi_value, napi_value, bool*)) {
62  napi_value return_value, object, key;
63  bool result;
64
65  NODE_API_CALL(env, napi_create_object(env, &return_value));
66  NODE_API_CALL(env, napi_create_object(env, &object));
67  NODE_API_CALL(env,
68      napi_create_string_utf8(env, "someString", NAPI_AUTO_LENGTH, &key));
69
70  add_returned_status(env,
71                      "envIsNull",
72                      return_value,
73                      "Invalid argument",
74                      napi_invalid_arg,
75                      api(NULL, object, key, &result));
76
77  api(env, NULL, key, &result);
78  add_last_status(env, "objectIsNull", return_value);
79
80  api(env, object, NULL, &result);
81  add_last_status(env, "keyIsNull", return_value);
82
83  api(env, object, key, NULL);
84  add_last_status(env, "valueIsNull", return_value);
85
86  return return_value;
87}
88
89static napi_value HasProperty(napi_env env, napi_callback_info info) {
90  return TestBoolValuedPropApi(env, napi_has_property);
91}
92
93static napi_value HasOwnProperty(napi_env env, napi_callback_info info) {
94  return TestBoolValuedPropApi(env, napi_has_own_property);
95}
96
97static napi_value DeleteProperty(napi_env env, napi_callback_info info) {
98  return TestBoolValuedPropApi(env, napi_delete_property);
99}
100
101static napi_value SetNamedProperty(napi_env env, napi_callback_info info) {
102  napi_value return_value, object;
103
104  NODE_API_CALL(env, napi_create_object(env, &return_value));
105  NODE_API_CALL(env, napi_create_object(env, &object));
106
107  add_returned_status(env,
108                      "envIsNull",
109                      return_value,
110                      "Invalid argument",
111                      napi_invalid_arg,
112                      napi_set_named_property(NULL, object, "key", object));
113
114  napi_set_named_property(env, NULL, "key", object);
115  add_last_status(env, "objectIsNull", return_value);
116
117  napi_set_named_property(env, object, NULL, object);
118  add_last_status(env, "keyIsNull", return_value);
119
120  napi_set_named_property(env, object, "key", NULL);
121  add_last_status(env, "valueIsNull", return_value);
122
123  return return_value;
124}
125
126static napi_value GetNamedProperty(napi_env env, napi_callback_info info) {
127  napi_value return_value, object, prop;
128
129  NODE_API_CALL(env, napi_create_object(env, &return_value));
130  NODE_API_CALL(env, napi_create_object(env, &object));
131
132  add_returned_status(env,
133                      "envIsNull",
134                      return_value,
135                      "Invalid argument",
136                      napi_invalid_arg,
137                      napi_get_named_property(NULL, object, "key", &prop));
138
139  napi_get_named_property(env, NULL, "key", &prop);
140  add_last_status(env, "objectIsNull", return_value);
141
142  napi_get_named_property(env, object, NULL, &prop);
143  add_last_status(env, "keyIsNull", return_value);
144
145  napi_get_named_property(env, object, "key", NULL);
146  add_last_status(env, "valueIsNull", return_value);
147
148  return return_value;
149}
150
151static napi_value HasNamedProperty(napi_env env, napi_callback_info info) {
152  napi_value return_value, object;
153  bool result;
154
155  NODE_API_CALL(env, napi_create_object(env, &return_value));
156  NODE_API_CALL(env, napi_create_object(env, &object));
157
158  add_returned_status(env,
159                      "envIsNull",
160                      return_value,
161                      "Invalid argument",
162                      napi_invalid_arg,
163                      napi_has_named_property(NULL, object, "key", &result));
164
165  napi_has_named_property(env, NULL, "key", &result);
166  add_last_status(env, "objectIsNull", return_value);
167
168  napi_has_named_property(env, object, NULL, &result);
169  add_last_status(env, "keyIsNull", return_value);
170
171  napi_has_named_property(env, object, "key", NULL);
172  add_last_status(env, "valueIsNull", return_value);
173
174  return return_value;
175}
176
177static napi_value SetElement(napi_env env, napi_callback_info info) {
178  napi_value return_value, object;
179
180  NODE_API_CALL(env, napi_create_object(env, &return_value));
181  NODE_API_CALL(env, napi_create_object(env, &object));
182
183  add_returned_status(env,
184                      "envIsNull",
185                      return_value,
186                      "Invalid argument",
187                      napi_invalid_arg,
188                      napi_set_element(NULL, object, 0, object));
189
190  napi_set_element(env, NULL, 0, object);
191  add_last_status(env, "objectIsNull", return_value);
192
193  napi_set_property(env, object, 0, NULL);
194  add_last_status(env, "valueIsNull", return_value);
195
196  return return_value;
197}
198
199static napi_value GetElement(napi_env env, napi_callback_info info) {
200  napi_value return_value, object, prop;
201
202  NODE_API_CALL(env, napi_create_object(env, &return_value));
203  NODE_API_CALL(env, napi_create_object(env, &object));
204
205  add_returned_status(env,
206                      "envIsNull",
207                      return_value,
208                      "Invalid argument",
209                      napi_invalid_arg,
210                      napi_get_element(NULL, object, 0, &prop));
211
212  napi_get_property(env, NULL, 0, &prop);
213  add_last_status(env, "objectIsNull", return_value);
214
215  napi_get_property(env, object, 0, NULL);
216  add_last_status(env, "valueIsNull", return_value);
217
218  return return_value;
219}
220
221static napi_value TestBoolValuedElementApi(napi_env env,
222    napi_status (*api)(napi_env, napi_value, uint32_t, bool*)) {
223  napi_value return_value, object;
224  bool result;
225
226  NODE_API_CALL(env, napi_create_object(env, &return_value));
227  NODE_API_CALL(env, napi_create_object(env, &object));
228
229  add_returned_status(env,
230                      "envIsNull",
231                      return_value,
232                      "Invalid argument",
233                      napi_invalid_arg,
234                      api(NULL, object, 0, &result));
235
236  api(env, NULL, 0, &result);
237  add_last_status(env, "objectIsNull", return_value);
238
239  api(env, object, 0, NULL);
240  add_last_status(env, "valueIsNull", return_value);
241
242  return return_value;
243}
244
245static napi_value HasElement(napi_env env, napi_callback_info info) {
246  return TestBoolValuedElementApi(env, napi_has_element);
247}
248
249static napi_value DeleteElement(napi_env env, napi_callback_info info) {
250  return TestBoolValuedElementApi(env, napi_delete_element);
251}
252
253static napi_value DefineProperties(napi_env env, napi_callback_info info) {
254  napi_value object, return_value;
255
256  napi_property_descriptor desc = {
257    "prop", NULL, DefineProperties, NULL, NULL, NULL, napi_enumerable, NULL
258  };
259
260  NODE_API_CALL(env, napi_create_object(env, &object));
261  NODE_API_CALL(env, napi_create_object(env, &return_value));
262
263  add_returned_status(env,
264                      "envIsNull",
265                      return_value,
266                      "Invalid argument",
267                      napi_invalid_arg,
268                      napi_define_properties(NULL, object, 1, &desc));
269
270  napi_define_properties(env, NULL, 1, &desc);
271  add_last_status(env, "objectIsNull", return_value);
272
273  napi_define_properties(env, object, 1, NULL);
274  add_last_status(env, "descriptorListIsNull", return_value);
275
276  desc.utf8name = NULL;
277  napi_define_properties(env, object, 1, NULL);
278  add_last_status(env, "utf8nameIsNull", return_value);
279  desc.utf8name = "prop";
280
281  desc.method = NULL;
282  napi_define_properties(env, object, 1, NULL);
283  add_last_status(env, "methodIsNull", return_value);
284  desc.method = DefineProperties;
285
286  return return_value;
287}
288
289static napi_value GetPropertyNames(napi_env env, napi_callback_info info) {
290  napi_value return_value, props;
291
292  NODE_API_CALL(env, napi_create_object(env, &return_value));
293
294  add_returned_status(env,
295                      "envIsNull",
296                      return_value,
297                      "Invalid argument",
298                      napi_invalid_arg,
299                      napi_get_property_names(NULL, return_value, &props));
300
301  napi_get_property_names(env, NULL, &props);
302  add_last_status(env, "objectIsNull", return_value);
303
304  napi_get_property_names(env, return_value, NULL);
305  add_last_status(env, "valueIsNull", return_value);
306
307  return return_value;
308}
309
310static napi_value GetAllPropertyNames(napi_env env, napi_callback_info info) {
311  napi_value return_value, props;
312
313  NODE_API_CALL(env, napi_create_object(env, &return_value));
314
315  add_returned_status(env,
316                      "envIsNull",
317                      return_value,
318                      "Invalid argument",
319                      napi_invalid_arg,
320                      napi_get_all_property_names(NULL,
321                                                  return_value,
322                                                  napi_key_own_only,
323                                                  napi_key_writable,
324                                                  napi_key_keep_numbers,
325                                                  &props));
326
327  napi_get_all_property_names(env,
328                              NULL,
329                              napi_key_own_only,
330                              napi_key_writable,
331                              napi_key_keep_numbers,
332                              &props);
333  add_last_status(env, "objectIsNull", return_value);
334
335  napi_get_all_property_names(env,
336                              return_value,
337                              napi_key_own_only,
338                              napi_key_writable,
339                              napi_key_keep_numbers,
340                              NULL);
341  add_last_status(env, "valueIsNull", return_value);
342
343  return return_value;
344}
345
346static napi_value GetPrototype(napi_env env, napi_callback_info info) {
347  napi_value return_value, proto;
348
349  NODE_API_CALL(env, napi_create_object(env, &return_value));
350
351  add_returned_status(env,
352                      "envIsNull",
353                      return_value,
354                      "Invalid argument",
355                      napi_invalid_arg,
356                      napi_get_prototype(NULL, return_value, &proto));
357
358  napi_get_prototype(env, NULL, &proto);
359  add_last_status(env, "objectIsNull", return_value);
360
361  napi_get_prototype(env, return_value, NULL);
362  add_last_status(env, "valueIsNull", return_value);
363
364  return return_value;
365}
366
367void init_test_null(napi_env env, napi_value exports) {
368  napi_value test_null;
369
370  const napi_property_descriptor test_null_props[] = {
371    DECLARE_NODE_API_PROPERTY("setProperty", SetProperty),
372    DECLARE_NODE_API_PROPERTY("getProperty", GetProperty),
373    DECLARE_NODE_API_PROPERTY("hasProperty", HasProperty),
374    DECLARE_NODE_API_PROPERTY("hasOwnProperty", HasOwnProperty),
375    DECLARE_NODE_API_PROPERTY("deleteProperty", DeleteProperty),
376    DECLARE_NODE_API_PROPERTY("setNamedProperty", SetNamedProperty),
377    DECLARE_NODE_API_PROPERTY("getNamedProperty", GetNamedProperty),
378    DECLARE_NODE_API_PROPERTY("hasNamedProperty", HasNamedProperty),
379    DECLARE_NODE_API_PROPERTY("setElement", SetElement),
380    DECLARE_NODE_API_PROPERTY("getElement", GetElement),
381    DECLARE_NODE_API_PROPERTY("hasElement", HasElement),
382    DECLARE_NODE_API_PROPERTY("deleteElement", DeleteElement),
383    DECLARE_NODE_API_PROPERTY("defineProperties", DefineProperties),
384    DECLARE_NODE_API_PROPERTY("getPropertyNames", GetPropertyNames),
385    DECLARE_NODE_API_PROPERTY("getAllPropertyNames", GetAllPropertyNames),
386    DECLARE_NODE_API_PROPERTY("getPrototype", GetPrototype),
387  };
388
389  NODE_API_CALL_RETURN_VOID(env, napi_create_object(env, &test_null));
390  NODE_API_CALL_RETURN_VOID(env, napi_define_properties(
391      env, test_null, sizeof(test_null_props) / sizeof(*test_null_props),
392      test_null_props));
393
394  const napi_property_descriptor test_null_set = {
395    "testNull", NULL, NULL, NULL, NULL, test_null, napi_enumerable, NULL
396  };
397
398  NODE_API_CALL_RETURN_VOID(env,
399      napi_define_properties(env, exports, 1, &test_null_set));
400}
401