Repository: nodejs/node
Pull request: node-api: test passing NULL to number APIs

<!--
Before submitting a pull request, please read
https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md.

Commit message formatting guidelines:
https://github.com/nodejs/node/blob/HEAD/doc/contributing/pull-requests.md#commit-message-guidelines

For code changes:
1. Include tests for any bug fixes or new features.
2. Update documentation if relevant.
3. Ensure that `make -j4 test` (UNIX), or `vcbuild test` (Windows) passes.

Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.
-->


Changed files:
filename: test/js-native-api/test_number/binding.gyp
patch: @@ -3,8 +3,10 @@
     {
       "target_name": "test_number",
       "sources": [
+        "../common.c",
         "../entry_point.c",
-        "test_number.c"
+        "test_number.c",
+        "test_null.c",
       ]
     }
   ]

filename: test/js-native-api/test_number/test_null.c
patch: @@ -0,0 +1,77 @@
+#include <js_native_api.h>
+
+#include "../common.h"
+
+// Unifies the way the macros declare values.
+typedef double double_t;
+
+#define BINDING_FOR_CREATE(initial_capital, lowercase)                         \
+  static napi_value Create##initial_capital(napi_env env,                      \
+                                            napi_callback_info info) {         \
+    napi_value return_value, call_result;                                      \
+    lowercase##_t value = 42;                                                  \
+    NODE_API_CALL(env, napi_create_object(env, &return_value));                \
+    add_returned_status(env,                                                   \
+                        "envIsNull",                                           \
+                        return_value,                                          \
+                        "Invalid argument",                                    \
+                        napi_invalid_arg,                                      \
+                        napi_create_##lowercase(NULL, value, &call_result));   \
+    napi_create_##lowercase(env, value, NULL);                                 \
+    add_last_status(env, "resultIsNull", return_value);                        \
+    return return_value;                                                       \
+  }
+
+#define BINDING_FOR_GET_VALUE(initial_capital, lowercase)                      \
+  static napi_value GetValue##initial_capital(napi_env env,                    \
+                                              napi_callback_info info) {       \
+    napi_value return_value, call_result;                                      \
+    lowercase##_t value = 42;                                                  \
+    NODE_API_CALL(env, napi_create_object(env, &return_value));                \
+    NODE_API_CALL(env, napi_create_##lowercase(env, value, &call_result));     \
+    add_returned_status(                                                       \
+        env,                                                                   \
+        "envIsNull",                                                           \
+        return_value,                                                          \
+        "Invalid argument",                                                    \
+        napi_invalid_arg,                                                      \
+        napi_get_value_##lowercase(NULL, call_result, &value));                \
+    napi_get_value_##lowercase(env, NULL, &value);                             \
+    add_last_status(env, "valueIsNull", return_value);                         \
+    napi_get_value_##lowercase(env, call_result, NULL);                        \
+    add_last_status(env, "resultIsNull", return_value);                        \
+    return return_value;                                                       \
+  }
+
+BINDING_FOR_CREATE(Double, double)
+BINDING_FOR_CREATE(Int32, int32)
+BINDING_FOR_CREATE(Uint32, uint32)
+BINDING_FOR_CREATE(Int64, int64)
+BINDING_FOR_GET_VALUE(Double, double)
+BINDING_FOR_GET_VALUE(Int32, int32)
+BINDING_FOR_GET_VALUE(Uint32, uint32)
+BINDING_FOR_GET_VALUE(Int64, int64)
+
+void init_test_null(napi_env env, napi_value exports) {
+  const napi_property_descriptor test_null_props[] = {
+      DECLARE_NODE_API_PROPERTY("createDouble", CreateDouble),
+      DECLARE_NODE_API_PROPERTY("createInt32", CreateInt32),
+      DECLARE_NODE_API_PROPERTY("createUint32", CreateUint32),
+      DECLARE_NODE_API_PROPERTY("createInt64", CreateInt64),
+      DECLARE_NODE_API_PROPERTY("getValueDouble", GetValueDouble),
+      DECLARE_NODE_API_PROPERTY("getValueInt32", GetValueInt32),
+      DECLARE_NODE_API_PROPERTY("getValueUint32", GetValueUint32),
+      DECLARE_NODE_API_PROPERTY("getValueInt64", GetValueInt64),
+  };
+  napi_value test_null;
+
+  NODE_API_CALL_RETURN_VOID(env, napi_create_object(env, &test_null));
+  NODE_API_CALL_RETURN_VOID(
+      env,
+      napi_define_properties(env,
+                             test_null,
+                             sizeof(test_null_props) / sizeof(*test_null_props),
+                             test_null_props));
+  NODE_API_CALL_RETURN_VOID(
+      env, napi_set_named_property(env, exports, "testNull", test_null));
+}

filename: test/js-native-api/test_number/test_null.h
patch: @@ -0,0 +1,8 @@
+#ifndef TEST_JS_NATIVE_API_TEST_NUMBER_TEST_NULL_H_
+#define TEST_JS_NATIVE_API_TEST_NUMBER_TEST_NULL_H_
+
+#include <js_native_api.h>
+
+void init_test_null(napi_env env, napi_value exports);
+
+#endif  // TEST_JS_NATIVE_API_TEST_NUMBER_TEST_NULL_H_

filename: test/js-native-api/test_number/test_null.js
patch: @@ -0,0 +1,18 @@
+'use strict';
+const common = require('../../common');
+const assert = require('assert');
+const { testNull } = require(`./build/${common.buildType}/test_number`);
+
+const expectedCreateResult = {
+  envIsNull: 'Invalid argument',
+  resultIsNull: 'Invalid argument',
+};
+const expectedGetValueResult = {
+  envIsNull: 'Invalid argument',
+  resultIsNull: 'Invalid argument',
+  valueIsNull: 'Invalid argument',
+};
+[ 'Double', 'Int32', 'Uint32', 'Int64' ].forEach((typeName) => {
+  assert.deepStrictEqual(testNull['create' + typeName](), expectedCreateResult);
+  assert.deepStrictEqual(testNull['getValue' + typeName](), expectedGetValueResult);
+});

filename: test/js-native-api/test_number/test_number.c
patch: @@ -1,5 +1,6 @@
 #include <js_native_api.h>
 #include "../common.h"
+#include "test_null.h"
 
 static napi_value Test(napi_env env, napi_callback_info info) {
   size_t argc = 1;
@@ -101,6 +102,8 @@ napi_value Init(napi_env env, napi_value exports) {
   NODE_API_CALL(env, napi_define_properties(
       env, exports, sizeof(descriptors) / sizeof(*descriptors), descriptors));
 
+  init_test_null(env, exports);
+
   return exports;
 }
 EXTERN_C_END