Skip to content

Commit 9f078c8

Browse files
committed
Added async addon test
1 parent 6f01473 commit 9f078c8

File tree

8 files changed

+463
-2
lines changed

8 files changed

+463
-2
lines changed

apps/test-app/App.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ function loadTests() {
1414
for (const [suiteName, examples] of Object.entries(nodeAddonExamples)) {
1515
describe(suiteName, () => {
1616
for (const [exampleName, requireExample] of Object.entries(examples)) {
17-
it(exampleName, () => {
18-
requireExample();
17+
it(exampleName, async () => {
18+
const test = requireExample();
19+
if (test instanceof Function) {
20+
await test();
21+
}
1922
});
2023
}
2124
});

packages/node-addon-examples/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@ module.exports = {
1717
},
1818
"tests": {
1919
"buffers": () => require("./tests/buffers/addon.js"),
20+
"async": () => require("./tests/async/addon.js"),
2021
},
2122
};
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#pragma once
2+
3+
#define NODE_API_RETVAL_NOTHING // Intentionally blank #define
4+
5+
#define GET_AND_THROW_LAST_ERROR(env) \
6+
do { \
7+
const napi_extended_error_info* error_info; \
8+
napi_get_last_error_info((env), &error_info); \
9+
bool is_pending; \
10+
const char* err_message = error_info->error_message; \
11+
napi_is_exception_pending((env), &is_pending); \
12+
/* If an exception is already pending, don't rethrow it */ \
13+
if (!is_pending) { \
14+
const char* error_message = \
15+
err_message != NULL ? err_message : "empty error message"; \
16+
napi_throw_error((env), NULL, error_message); \
17+
} \
18+
} while (0)
19+
20+
// The basic version of GET_AND_THROW_LAST_ERROR. We cannot access any
21+
// exceptions and we cannot fail by way of JS exception, so we abort.
22+
#define FATALLY_FAIL_WITH_LAST_ERROR(env) \
23+
do { \
24+
const napi_extended_error_info* error_info; \
25+
napi_get_last_error_info((env), &error_info); \
26+
const char* err_message = error_info->error_message; \
27+
const char* error_message = \
28+
err_message != NULL ? err_message : "empty error message"; \
29+
fprintf(stderr, "%s\n", error_message); \
30+
abort(); \
31+
} while (0)
32+
33+
#define NODE_API_ASSERT_BASE(env, assertion, message, ret_val) \
34+
do { \
35+
if (!(assertion)) { \
36+
napi_throw_error( \
37+
(env), NULL, "assertion (" #assertion ") failed: " message); \
38+
return ret_val; \
39+
} \
40+
} while (0)
41+
42+
#define NODE_API_BASIC_ASSERT_BASE(assertion, message, ret_val) \
43+
do { \
44+
if (!(assertion)) { \
45+
fprintf(stderr, "assertion (" #assertion ") failed: " message); \
46+
abort(); \
47+
return ret_val; \
48+
} \
49+
} while (0)
50+
51+
// Returns NULL on failed assertion.
52+
// This is meant to be used inside napi_callback methods.
53+
#define NODE_API_ASSERT(env, assertion, message) \
54+
NODE_API_ASSERT_BASE(env, assertion, message, NULL)
55+
56+
// Returns empty on failed assertion.
57+
// This is meant to be used inside functions with void return type.
58+
#define NODE_API_ASSERT_RETURN_VOID(env, assertion, message) \
59+
NODE_API_ASSERT_BASE(env, assertion, message, NODE_API_RETVAL_NOTHING)
60+
61+
#define NODE_API_BASIC_ASSERT_RETURN_VOID(assertion, message) \
62+
NODE_API_BASIC_ASSERT_BASE(assertion, message, NODE_API_RETVAL_NOTHING)
63+
64+
#define NODE_API_CALL_BASE(env, the_call, ret_val) \
65+
do { \
66+
if ((the_call) != napi_ok) { \
67+
GET_AND_THROW_LAST_ERROR((env)); \
68+
return ret_val; \
69+
} \
70+
} while (0)
71+
72+
#define NODE_API_BASIC_CALL_BASE(env, the_call, ret_val) \
73+
do { \
74+
if ((the_call) != napi_ok) { \
75+
FATALLY_FAIL_WITH_LAST_ERROR((env)); \
76+
return ret_val; \
77+
} \
78+
} while (0)
79+
80+
// Returns NULL if the_call doesn't return napi_ok.
81+
#define NODE_API_CALL(env, the_call) NODE_API_CALL_BASE(env, the_call, NULL)
82+
83+
// Returns empty if the_call doesn't return napi_ok.
84+
#define NODE_API_CALL_RETURN_VOID(env, the_call) \
85+
NODE_API_CALL_BASE(env, the_call, NODE_API_RETVAL_NOTHING)
86+
87+
#define NODE_API_BASIC_CALL_RETURN_VOID(env, the_call) \
88+
NODE_API_BASIC_CALL_BASE(env, the_call, NODE_API_RETVAL_NOTHING)
89+
90+
#define NODE_API_CHECK_STATUS(the_call) \
91+
do { \
92+
napi_status status = (the_call); \
93+
if (status != napi_ok) { \
94+
return status; \
95+
} \
96+
} while (0)
97+
98+
#define NODE_API_ASSERT_STATUS(env, assertion, message) \
99+
NODE_API_ASSERT_BASE(env, assertion, message, napi_generic_failure)
100+
101+
#define DECLARE_NODE_API_PROPERTY(name, func) \
102+
{(name), NULL, (func), NULL, NULL, NULL, napi_default, NULL}
103+
104+
#define DECLARE_NODE_API_GETTER(name, func) \
105+
{(name), NULL, NULL, (func), NULL, NULL, napi_default, NULL}
106+
107+
#define DECLARE_NODE_API_PROPERTY_VALUE(name, value) \
108+
{(name), NULL, NULL, NULL, NULL, (value), napi_default, NULL}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
cmake_minimum_required(VERSION 3.15)
2+
project(tests-async)
3+
4+
add_compile_definitions(NAPI_VERSION=8)
5+
6+
add_library(addon SHARED addon.c ${CMAKE_JS_SRC})
7+
set_target_properties(addon PROPERTIES PREFIX "" SUFFIX ".node")
8+
target_include_directories(addon PRIVATE ${CMAKE_JS_INC})
9+
target_link_libraries(addon PRIVATE ${CMAKE_JS_LIB})
10+
target_compile_features(addon PRIVATE cxx_std_17)
11+
12+
if(MSVC AND CMAKE_JS_NODELIB_DEF AND CMAKE_JS_NODELIB_TARGET)
13+
# Generate node.lib
14+
execute_process(COMMAND ${CMAKE_AR} /def:${CMAKE_JS_NODELIB_DEF} /out:${CMAKE_JS_NODELIB_TARGET} ${CMAKE_STATIC_LINKER_FLAGS})
15+
endif()

0 commit comments

Comments
 (0)