Skip to content

Commit a24e302

Browse files
committed
regression test only first
1 parent 42edbf4 commit a24e302

1 file changed

Lines changed: 77 additions & 0 deletions

File tree

source/tests/metacall_node_async_test/source/metacall_node_async_test.cpp

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@
2828

2929
std::atomic<int> success_callbacks{};
3030

31+
struct trampoline_regression_ctx_type
32+
{
33+
std::atomic<unsigned int> resolve_callbacks{ 0 };
34+
std::atomic<unsigned int> reject_callbacks{ 0 };
35+
} trampoline_ctx;
36+
3137
class metacall_node_async_test : public testing::Test
3238
{
3339
public:
@@ -151,6 +157,71 @@ TEST_F(metacall_node_async_test, DefaultConstructor)
151157

152158
metacall_value_destroy(args[0]);
153159

160+
/* Regression #578: trampoline ownership. test */
161+
{
162+
const char trampoline_buffer[] =
163+
"function f_reg(x) { return new Promise(r => r(x)); }\n"
164+
"function g_reg(x) { return new Promise((_, r) => r(x)); }\n"
165+
"async function i_reg() { throw Error('Hi there!'); }\n"
166+
"module.exports = { f_reg, g_reg, i_reg };\n";
167+
168+
EXPECT_EQ((int)0, (int)metacall_load_from_memory("node", trampoline_buffer, sizeof(trampoline_buffer), NULL));
169+
170+
auto trampoline_resolve_cb = [](void *result, void *data) -> void * {
171+
EXPECT_NE((void *)NULL, (void *)result);
172+
173+
trampoline_regression_ctx_type *ctx = static_cast<trampoline_regression_ctx_type *>(data);
174+
EXPECT_NE((void *)NULL, (void *)ctx);
175+
176+
++ctx->resolve_callbacks;
177+
178+
return NULL;
179+
};
180+
181+
auto trampoline_reject_cb = [](void *result, void *data) -> void * {
182+
EXPECT_NE((void *)NULL, (void *)result);
183+
184+
trampoline_regression_ctx_type *ctx = static_cast<trampoline_regression_ctx_type *>(data);
185+
EXPECT_NE((void *)NULL, (void *)ctx);
186+
187+
++ctx->reject_callbacks;
188+
189+
return NULL;
190+
};
191+
192+
/* Await #1: resolve path — exercises node_loader_trampoline_resolve ownership */
193+
void *args_f_reg[] = { metacall_value_create_double(10.0) };
194+
195+
void *future_f_reg = metacall_await("f_reg", args_f_reg, trampoline_resolve_cb, trampoline_reject_cb, static_cast<void *>(&trampoline_ctx));
196+
197+
metacall_value_destroy(args_f_reg[0]);
198+
199+
EXPECT_NE((void *)NULL, (void *)future_f_reg);
200+
EXPECT_EQ((enum metacall_value_id)METACALL_FUTURE, (enum metacall_value_id)metacall_value_id(future_f_reg));
201+
202+
metacall_value_destroy(future_f_reg);
203+
204+
/* Await #2: reject path — exercises node_loader_trampoline_reject ownership */
205+
void *args_g_reg[] = { metacall_value_create_double(20.0) };
206+
207+
void *future_g_reg = metacall_await("g_reg", args_g_reg, trampoline_resolve_cb, trampoline_reject_cb, static_cast<void *>(&trampoline_ctx));
208+
209+
metacall_value_destroy(args_g_reg[0]);
210+
211+
EXPECT_NE((void *)NULL, (void *)future_g_reg);
212+
EXPECT_EQ((enum metacall_value_id)METACALL_FUTURE, (enum metacall_value_id)metacall_value_id(future_g_reg));
213+
214+
metacall_value_destroy(future_g_reg);
215+
216+
/* Await #3: async throw — exception surfaces as reject path */
217+
void *future_i_reg = metacall_await("i_reg", metacall_null_args, trampoline_resolve_cb, trampoline_reject_cb, static_cast<void *>(&trampoline_ctx));
218+
219+
EXPECT_NE((void *)NULL, (void *)future_i_reg);
220+
EXPECT_EQ((enum metacall_value_id)METACALL_FUTURE, (enum metacall_value_id)metacall_value_id(future_i_reg));
221+
222+
metacall_value_destroy(future_i_reg);
223+
}
224+
154225
/* Test future */
155226
future = metacall("h");
156227

@@ -259,6 +330,12 @@ TEST_F(metacall_node_async_test, DefaultConstructor)
259330
{
260331
/* Total amount of successful callbacks must be 4 */
261332
EXPECT_EQ((int)success_callbacks, (int)4);
333+
334+
/* Regression #578: exactly 1 resolve and 2 rejects must have fired.
335+
* Under ASAN (detect_leaks=1) this also confirms zero heap leaks from
336+
* the trampoline unique_ptr fix in node_loader_trampoline.cpp. */
337+
EXPECT_EQ((unsigned int)1, (unsigned int)trampoline_ctx.resolve_callbacks);
338+
EXPECT_EQ((unsigned int)2, (unsigned int)trampoline_ctx.reject_callbacks);
262339
}
263340
#endif /* OPTION_BUILD_LOADERS_NODE */
264341
}

0 commit comments

Comments
 (0)