-
-
Notifications
You must be signed in to change notification settings - Fork 9
Add function arguments test #18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| #include <js_native_api.h> | ||
| #include "../common.h" | ||
| #include "../entry_point.h" | ||
|
|
||
| static napi_value Add(napi_env env, napi_callback_info info) { | ||
| size_t argc = 2; | ||
| napi_value args[2]; | ||
| NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL)); | ||
|
|
||
| NODE_API_ASSERT(env, argc >= 2, "Wrong number of arguments"); | ||
|
|
||
| napi_valuetype valuetype0; | ||
| NODE_API_CALL(env, napi_typeof(env, args[0], &valuetype0)); | ||
|
|
||
| napi_valuetype valuetype1; | ||
| NODE_API_CALL(env, napi_typeof(env, args[1], &valuetype1)); | ||
|
|
||
| NODE_API_ASSERT(env, valuetype0 == napi_number && valuetype1 == napi_number, | ||
| "Wrong argument type. Numbers expected."); | ||
|
|
||
| double value0; | ||
| NODE_API_CALL(env, napi_get_value_double(env, args[0], &value0)); | ||
|
|
||
| double value1; | ||
| NODE_API_CALL(env, napi_get_value_double(env, args[1], &value1)); | ||
|
|
||
| napi_value sum; | ||
| NODE_API_CALL(env, napi_create_double(env, value0 + value1, &sum)); | ||
|
|
||
| return sum; | ||
| } | ||
|
|
||
| EXTERN_C_START | ||
| napi_value Init(napi_env env, napi_value exports) { | ||
| napi_property_descriptor desc = DECLARE_NODE_API_PROPERTY("add", Add); | ||
| NODE_API_CALL(env, napi_define_properties(env, exports, 1, &desc)); | ||
| return exports; | ||
| } | ||
| EXTERN_C_END |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| #ifndef JS_NATIVE_API_COMMON_INL_H_ | ||
| #define JS_NATIVE_API_COMMON_INL_H_ | ||
|
|
||
| #include <js_native_api.h> | ||
| #include "common.h" | ||
|
|
||
| #include <stdio.h> | ||
|
|
||
| inline void add_returned_status(napi_env env, | ||
| const char* key, | ||
| napi_value object, | ||
| char* expected_message, | ||
| napi_status expected_status, | ||
| napi_status actual_status) { | ||
| char napi_message_string[100] = ""; | ||
| napi_value prop_value; | ||
|
|
||
| if (actual_status != expected_status) { | ||
| snprintf(napi_message_string, | ||
| sizeof(napi_message_string), | ||
| "Invalid status [%d]", | ||
| actual_status); | ||
| } | ||
|
|
||
| NODE_API_CALL_RETURN_VOID( | ||
| env, | ||
| napi_create_string_utf8( | ||
| env, | ||
| (actual_status == expected_status ? expected_message | ||
| : napi_message_string), | ||
| NAPI_AUTO_LENGTH, | ||
| &prop_value)); | ||
| NODE_API_CALL_RETURN_VOID( | ||
| env, napi_set_named_property(env, object, key, prop_value)); | ||
| } | ||
|
|
||
| inline void add_last_status(napi_env env, | ||
| const char* key, | ||
| napi_value return_value) { | ||
| napi_value prop_value; | ||
| napi_value exception; | ||
| const napi_extended_error_info* p_last_error; | ||
| NODE_API_CALL_RETURN_VOID(env, napi_get_last_error_info(env, &p_last_error)); | ||
| // Content of p_last_error can be updated in subsequent node-api calls. | ||
| // Retrieve it immediately. | ||
| const char* error_message = p_last_error->error_message == NULL | ||
| ? "napi_ok" | ||
| : p_last_error->error_message; | ||
|
|
||
| bool is_exception_pending; | ||
| NODE_API_CALL_RETURN_VOID( | ||
| env, napi_is_exception_pending(env, &is_exception_pending)); | ||
| if (is_exception_pending) { | ||
| NODE_API_CALL_RETURN_VOID( | ||
| env, napi_get_and_clear_last_exception(env, &exception)); | ||
| char exception_key[50]; | ||
| snprintf(exception_key, sizeof(exception_key), "%s%s", key, "Exception"); | ||
| NODE_API_CALL_RETURN_VOID( | ||
| env, | ||
| napi_set_named_property(env, return_value, exception_key, exception)); | ||
| } | ||
|
|
||
| NODE_API_CALL_RETURN_VOID( | ||
| env, | ||
| napi_create_string_utf8( | ||
| env, error_message, NAPI_AUTO_LENGTH, &prop_value)); | ||
| NODE_API_CALL_RETURN_VOID( | ||
| env, napi_set_named_property(env, return_value, key, prop_value)); | ||
| } | ||
|
|
||
| #endif // JS_NATIVE_API_COMMON_INL_H_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copied as-is from nodejs/node/test/js-native-api/common-inl.h
| #ifndef JS_NATIVE_API_COMMON_H_ | ||
| #define JS_NATIVE_API_COMMON_H_ | ||
|
|
||
| #include <js_native_api.h> | ||
| #include <stdlib.h> // abort() | ||
|
|
||
| // Empty value so that macros here are able to return NULL or void | ||
| #define NODE_API_RETVAL_NOTHING // Intentionally blank #define | ||
|
|
||
| #define GET_AND_THROW_LAST_ERROR(env) \ | ||
| do { \ | ||
| const napi_extended_error_info *error_info; \ | ||
| napi_get_last_error_info((env), &error_info); \ | ||
| bool is_pending; \ | ||
| const char* err_message = error_info->error_message; \ | ||
| napi_is_exception_pending((env), &is_pending); \ | ||
| /* If an exception is already pending, don't rethrow it */ \ | ||
| if (!is_pending) { \ | ||
| const char* error_message = err_message != NULL ? \ | ||
| err_message : \ | ||
| "empty error message"; \ | ||
| napi_throw_error((env), NULL, error_message); \ | ||
| } \ | ||
| } while (0) | ||
|
|
||
| // The basic version of GET_AND_THROW_LAST_ERROR. We cannot access any | ||
| // exceptions and we cannot fail by way of JS exception, so we abort. | ||
| #define FATALLY_FAIL_WITH_LAST_ERROR(env) \ | ||
| do { \ | ||
| const napi_extended_error_info* error_info; \ | ||
| napi_get_last_error_info((env), &error_info); \ | ||
| const char* err_message = error_info->error_message; \ | ||
| const char* error_message = \ | ||
| err_message != NULL ? err_message : "empty error message"; \ | ||
| fprintf(stderr, "%s\n", error_message); \ | ||
| abort(); \ | ||
| } while (0) | ||
|
|
||
| #define NODE_API_ASSERT_BASE(env, assertion, message, ret_val) \ | ||
| do { \ | ||
| if (!(assertion)) { \ | ||
| napi_throw_error( \ | ||
| (env), \ | ||
| NULL, \ | ||
| "assertion (" #assertion ") failed: " message); \ | ||
| return ret_val; \ | ||
| } \ | ||
| } while (0) | ||
|
|
||
| #define NODE_API_BASIC_ASSERT_BASE(assertion, message, ret_val) \ | ||
| do { \ | ||
| if (!(assertion)) { \ | ||
| fprintf(stderr, "assertion (" #assertion ") failed: " message); \ | ||
| abort(); \ | ||
| return ret_val; \ | ||
| } \ | ||
| } while (0) | ||
|
|
||
| // Returns NULL on failed assertion. | ||
| // This is meant to be used inside napi_callback methods. | ||
| #define NODE_API_ASSERT(env, assertion, message) \ | ||
| NODE_API_ASSERT_BASE(env, assertion, message, NULL) | ||
|
|
||
| // Returns empty on failed assertion. | ||
| // This is meant to be used inside functions with void return type. | ||
| #define NODE_API_ASSERT_RETURN_VOID(env, assertion, message) \ | ||
| NODE_API_ASSERT_BASE(env, assertion, message, NODE_API_RETVAL_NOTHING) | ||
|
|
||
| #define NODE_API_BASIC_ASSERT_RETURN_VOID(assertion, message) \ | ||
| NODE_API_BASIC_ASSERT_BASE(assertion, message, NODE_API_RETVAL_NOTHING) | ||
|
|
||
| #define NODE_API_CALL_BASE(env, the_call, ret_val) \ | ||
| do { \ | ||
| if ((the_call) != napi_ok) { \ | ||
| GET_AND_THROW_LAST_ERROR((env)); \ | ||
| return ret_val; \ | ||
| } \ | ||
| } while (0) | ||
|
|
||
| #define NODE_API_BASIC_CALL_BASE(env, the_call, ret_val) \ | ||
| do { \ | ||
| if ((the_call) != napi_ok) { \ | ||
| FATALLY_FAIL_WITH_LAST_ERROR((env)); \ | ||
| return ret_val; \ | ||
| } \ | ||
| } while (0) | ||
|
|
||
| // Returns NULL if the_call doesn't return napi_ok. | ||
| #define NODE_API_CALL(env, the_call) \ | ||
| NODE_API_CALL_BASE(env, the_call, NULL) | ||
|
|
||
| // Returns empty if the_call doesn't return napi_ok. | ||
| #define NODE_API_CALL_RETURN_VOID(env, the_call) \ | ||
| NODE_API_CALL_BASE(env, the_call, NODE_API_RETVAL_NOTHING) | ||
|
|
||
| #define NODE_API_BASIC_CALL_RETURN_VOID(env, the_call) \ | ||
| NODE_API_BASIC_CALL_BASE(env, the_call, NODE_API_RETVAL_NOTHING) | ||
|
|
||
| #define NODE_API_CHECK_STATUS(the_call) \ | ||
| do { \ | ||
| napi_status status = (the_call); \ | ||
| if (status != napi_ok) { \ | ||
| return status; \ | ||
| } \ | ||
| } while (0) | ||
|
|
||
| #define NODE_API_ASSERT_STATUS(env, assertion, message) \ | ||
| NODE_API_ASSERT_BASE(env, assertion, message, napi_generic_failure) | ||
|
|
||
| #define DECLARE_NODE_API_PROPERTY(name, func) \ | ||
| { (name), NULL, (func), NULL, NULL, NULL, napi_default, NULL } | ||
|
|
||
| #define DECLARE_NODE_API_GETTER(name, func) \ | ||
| { (name), NULL, NULL, (func), NULL, NULL, napi_default, NULL } | ||
|
|
||
| #define DECLARE_NODE_API_PROPERTY_VALUE(name, value) \ | ||
| { (name), NULL, NULL, NULL, NULL, (value), napi_default, NULL } | ||
|
|
||
| static inline void add_returned_status(napi_env env, | ||
| const char* key, | ||
| napi_value object, | ||
| char* expected_message, | ||
| napi_status expected_status, | ||
| napi_status actual_status); | ||
|
|
||
| static inline void add_last_status(napi_env env, | ||
| const char* key, | ||
| napi_value return_value); | ||
|
|
||
| #include "common-inl.h" | ||
|
|
||
| #endif // JS_NATIVE_API_COMMON_H_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copied as-is from nodejs/node/test/js-native-api/common.h
| napi_value Init(napi_env env, napi_value exports); | ||
| EXTERN_C_END | ||
|
|
||
| NAPI_MODULE(ADDON_NAME, Init) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed this from
NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)Since we're not using Node GYP.
| #ifndef JS_NATIVE_API_ENTRY_POINT_H_ | ||
| #define JS_NATIVE_API_ENTRY_POINT_H_ | ||
|
|
||
| #include <node_api.h> | ||
|
|
||
| EXTERN_C_START | ||
| napi_value Init(napi_env env, napi_value exports); | ||
| EXTERN_C_END | ||
|
|
||
| NAPI_MODULE(ADDON_NAME, Init) | ||
|
|
||
| #endif // JS_NATIVE_API_ENTRY_POINT_H_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copied with a single line changed from nodejs/node/test/js-native-api/entry_point.h
| const addon = loadAddon('2_function_arguments'); | ||
|
|
||
| const { add } = addon; | ||
|
|
||
| assert(typeof add === "function"); | ||
| assert(add(3, 5) === 8); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actual test, based off nodejs/node/test/js-native-api/2_function_arguments/test.js
This comment was marked as outdated.
This comment was marked as outdated.
168d39e to
14a2fbe
Compare
|
Instead of getting the test directory using the call-sites, I changed the implementation to spawn the test file with the file's parent directory as current working directory and updated the |
8b56135 to
255abb8
Compare
.github/workflows/test.yml
Outdated
| run: npm run node:test | ||
| env: | ||
| NODE_OPTIONS: --import=${{ github.workspace }}/tools/strip.js |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
255abb8 to
bc89a1e
Compare
Merging this PR will:
loadAddonfunction into tests, based on theprocess.dlopenfunction.loadAddonfunction.cmake-jsand a rootCMakeLists.txtdeclaring aadd_node_api_cts_addonhelper called from the test directory setup a target for the test's addon.2_function_arguments.c,common-inl.handentry_point.has is (with the exception of one change in the latter).