Skip to content

Commit f79a30b

Browse files
committed
Implement a test to show the use
1 parent 7d40f34 commit f79a30b

File tree

2 files changed

+172
-0
lines changed

2 files changed

+172
-0
lines changed

packages/weak-node-api/tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ FetchContent_MakeAvailable(Catch2)
1010

1111
add_executable(weak-node-api-tests
1212
test_inject.cpp
13+
test_multi_host.cpp
1314
)
1415
target_link_libraries(weak-node-api-tests
1516
PRIVATE
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
#include "js_native_api_types.h"
2+
#include "node_api.h"
3+
#include "node_api_types.h"
4+
#include <catch2/catch_test_macros.hpp>
5+
#include <cstddef>
6+
#include <memory>
7+
#include <weak_node_api.hpp>
8+
#include <weak_node_api_multi_host.hpp>
9+
10+
TEST_CASE("WeakNodeApiMultiHost") {
11+
SECTION("is injectable") {
12+
WeakNodeApiMultiHost host{nullptr, nullptr};
13+
inject_weak_node_api_host(host);
14+
}
15+
16+
SECTION("propagates calls to the right napi_create_object") {
17+
// Setup two hosts
18+
static size_t foo_calls = 0;
19+
auto host_foo = std::shared_ptr<WeakNodeApiHost>(new WeakNodeApiHost{
20+
.napi_create_object = [](napi_env env,
21+
napi_value *result) -> napi_status {
22+
foo_calls++;
23+
return napi_status::napi_ok;
24+
}});
25+
26+
static size_t bar_calls = 0;
27+
auto host_bar = std::shared_ptr<WeakNodeApiHost>(new WeakNodeApiHost{
28+
.napi_create_object = [](napi_env env,
29+
napi_value *result) -> napi_status {
30+
bar_calls++;
31+
return napi_status::napi_ok;
32+
}});
33+
34+
// Create and inject a multi host and wrap two envs
35+
WeakNodeApiMultiHost multi_host{nullptr, nullptr};
36+
inject_weak_node_api_host(multi_host);
37+
38+
auto foo_env = multi_host.wrap(napi_env{}, host_foo);
39+
auto bar_env = multi_host.wrap(napi_env{}, host_bar);
40+
41+
napi_value result;
42+
43+
REQUIRE(foo_calls == 0);
44+
REQUIRE(bar_calls == 0);
45+
46+
REQUIRE(napi_create_object(foo_env, &result) == napi_ok);
47+
REQUIRE(foo_calls == 1);
48+
REQUIRE(bar_calls == 0);
49+
50+
REQUIRE(napi_create_object(bar_env, &result) == napi_ok);
51+
REQUIRE(foo_calls == 1);
52+
REQUIRE(bar_calls == 1);
53+
}
54+
55+
SECTION("handles multi-host resetting") {
56+
// Setup two hosts
57+
static size_t called = 0;
58+
auto host = std::shared_ptr<WeakNodeApiHost>(new WeakNodeApiHost{
59+
.napi_create_object = [](napi_env env,
60+
napi_value *result) -> napi_status {
61+
called++;
62+
return napi_status::napi_ok;
63+
}});
64+
65+
// Create and inject a multi host and wrap two envs
66+
WeakNodeApiMultiHost multi_host{nullptr, nullptr};
67+
inject_weak_node_api_host(multi_host);
68+
69+
auto env = multi_host.wrap(napi_env{}, host);
70+
71+
napi_value result;
72+
REQUIRE(called == 0);
73+
74+
REQUIRE(napi_create_object(env, &result) == napi_ok);
75+
REQUIRE(called == 1);
76+
77+
host.reset();
78+
REQUIRE(napi_create_object(env, &result) == napi_generic_failure);
79+
REQUIRE(called == 1);
80+
}
81+
82+
SECTION("wraps threadsafe functions") {
83+
// Setup two hosts
84+
static size_t calls = 0;
85+
auto host_foo = std::shared_ptr<WeakNodeApiHost>(new WeakNodeApiHost{
86+
.napi_create_object = [](napi_env env,
87+
napi_value *result) -> napi_status {
88+
calls++;
89+
return napi_status::napi_ok;
90+
},
91+
.napi_create_threadsafe_function =
92+
[](napi_env, napi_value, napi_value, napi_value, size_t, size_t,
93+
void *, napi_finalize, void *, napi_threadsafe_function_call_js,
94+
napi_threadsafe_function *out) -> napi_status {
95+
calls++;
96+
(*out) = {};
97+
return napi_status::napi_ok;
98+
},
99+
.napi_release_threadsafe_function =
100+
[](napi_threadsafe_function,
101+
napi_threadsafe_function_release_mode) -> napi_status {
102+
calls++;
103+
return napi_status::napi_ok;
104+
}});
105+
106+
// Create and inject a multi host and wrap two envs
107+
WeakNodeApiMultiHost multi_host{nullptr, nullptr};
108+
inject_weak_node_api_host(multi_host);
109+
110+
auto foo_env = multi_host.wrap(napi_env{}, host_foo);
111+
112+
{
113+
napi_threadsafe_function result;
114+
115+
REQUIRE(calls == 0);
116+
117+
REQUIRE(napi_create_threadsafe_function(
118+
foo_env, nullptr, nullptr, nullptr, 0, 0, nullptr, nullptr,
119+
nullptr, nullptr, &result) == napi_ok);
120+
REQUIRE(calls == 1);
121+
122+
REQUIRE(napi_release_threadsafe_function(
123+
result,
124+
napi_threadsafe_function_release_mode::napi_tsfn_release) ==
125+
napi_ok);
126+
REQUIRE(calls == 2);
127+
}
128+
}
129+
130+
SECTION("wraps async cleanup hook handles") {
131+
// Setup two hosts
132+
static size_t calls = 0;
133+
auto host_foo = std::shared_ptr<WeakNodeApiHost>(new WeakNodeApiHost{
134+
.napi_create_object = [](napi_env env,
135+
napi_value *result) -> napi_status {
136+
calls++;
137+
return napi_status::napi_ok;
138+
},
139+
.napi_add_async_cleanup_hook =
140+
[](node_api_basic_env env, napi_async_cleanup_hook hook, void *arg,
141+
napi_async_cleanup_hook_handle *remove_handle) -> napi_status {
142+
calls++;
143+
(*remove_handle) = {};
144+
return napi_status::napi_ok;
145+
},
146+
.napi_remove_async_cleanup_hook =
147+
[](napi_async_cleanup_hook_handle remove_handle) -> napi_status {
148+
calls++;
149+
return napi_status::napi_ok;
150+
}});
151+
152+
// Create and inject a multi host and wrap two envs
153+
WeakNodeApiMultiHost multi_host{nullptr, nullptr};
154+
inject_weak_node_api_host(multi_host);
155+
156+
auto foo_env = multi_host.wrap(napi_env{}, host_foo);
157+
158+
{
159+
napi_async_cleanup_hook_handle result;
160+
161+
REQUIRE(calls == 0);
162+
163+
REQUIRE(napi_add_async_cleanup_hook(foo_env, nullptr, nullptr, &result) ==
164+
napi_ok);
165+
REQUIRE(calls == 1);
166+
167+
REQUIRE(napi_remove_async_cleanup_hook(result) == napi_ok);
168+
REQUIRE(calls == 2);
169+
}
170+
}
171+
}

0 commit comments

Comments
 (0)