Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 18 additions & 18 deletions PORTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,37 +40,37 @@ Tests covering the engine-specific part of Node-API, defined in `js_native_api.h

| Directory | Status | Difficulty |
| ---------------------------- | ---------- | ---------- |
| `2_function_arguments` | Ported | — |
| `3_callbacks` | Not ported | Easy |
| `4_object_factory` | Not ported | Easy |
| `5_function_factory` | Not ported | Easy |
| `2_function_arguments` | Ported | — |
| `3_callbacks` | Ported ✅ | Easy |
| `4_object_factory` | Ported ✅ | Easy |
| `5_function_factory` | Ported ✅ | Easy |
| `6_object_wrap` | Not ported | Medium |
| `7_factory_wrap` | Not ported | Easy |
| `8_passing_wrapped` | Not ported | Easy |
| `test_array` | Not ported | Easy |
| `test_bigint` | Not ported | Easy |
| `7_factory_wrap` | Ported ✅ | Easy |
| `8_passing_wrapped` | Ported ✅ | Easy |
| `test_array` | Ported ✅ | Easy |
| `test_bigint` | Ported ✅ | Easy |
| `test_cannot_run_js` | Not ported | Medium |
| `test_constructor` | Not ported | Medium |
| `test_conversions` | Not ported | Medium |
| `test_dataview` | Not ported | Easy |
| `test_date` | Not ported | Easy |
| `test_dataview` | Not ported | Medium |
| `test_date` | Ported ✅ | Easy |
| `test_error` | Not ported | Medium |
| `test_exception` | Not ported | Medium |
| `test_finalizer` | Not ported | Medium |
| `test_function` | Not ported | Medium |
| `test_general` | Not ported | Hard |
| `test_handle_scope` | Not ported | Easy |
| `test_instance_data` | Not ported | Easy |
| `test_new_target` | Not ported | Easy |
| `test_number` | Not ported | Easy |
| `test_handle_scope` | Ported ✅ | Easy |
| `test_instance_data` | Not ported | Medium |
| `test_new_target` | Ported ✅ | Easy |
| `test_number` | Ported ✅ | Easy |
| `test_object` | Not ported | Hard |
| `test_promise` | Not ported | Easy |
| `test_properties` | Not ported | Easy |
| `test_promise` | Ported ✅ | Easy |
| `test_properties` | Ported ✅ | Easy |
| `test_reference` | Not ported | Medium |
| `test_reference_double_free` | Not ported | Easy |
| `test_reference_double_free` | Ported ✅ | Easy |
| `test_sharedarraybuffer` | Not ported | Medium |
| `test_string` | Not ported | Medium |
| `test_symbol` | Not ported | Easy |
| `test_symbol` | Ported ✅ | Easy |
| `test_typedarray` | Not ported | Medium |

## Runtime-specific (`node-api`)
Expand Down
46 changes: 46 additions & 0 deletions implementors/node/must-call.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const pendingCalls = [];

/**
* Wraps a function and asserts it is called exactly `exact` times before the
* process exits. If `fn` is omitted, a no-op function is used.
*
* Usage:
* promise.then(mustCall((result) => {
* assert.strictEqual(result, 42);
* }));
*/
const mustCall = (fn, exact = 1) => {
const entry = {
exact,
actual: 0,
name: fn?.name || "<anonymous>",
error: new Error(), // capture call-site stack
};
pendingCalls.push(entry);
return function(...args) {
entry.actual++;
if (fn) return fn.apply(this, args);
};
};

/**
* Returns a function that throws immediately if called.
*/
const mustNotCall = (msg) => {
return () => {
throw new Error(msg || "mustNotCall function was called");
};
};

process.on("exit", () => {
for (const entry of pendingCalls) {
if (entry.actual !== entry.exact) {
entry.error.message =
`mustCall "${entry.name}" expected ${entry.exact} call(s) ` +
`but got ${entry.actual}`;
throw entry.error;
}
}
});

Object.assign(globalThis, { mustCall, mustNotCall });
8 changes: 8 additions & 0 deletions implementors/node/tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ const GC_MODULE_PATH = path.join(
"node",
"gc.js"
);
const MUST_CALL_MODULE_PATH = path.join(
ROOT_PATH,
"implementors",
"node",
"must-call.js"
);

export function listDirectoryEntries(dir: string) {
const entries = fs.readdirSync(dir, { withFileTypes: true });
Expand Down Expand Up @@ -72,6 +78,8 @@ export function runFileInSubprocess(
"file://" + LOAD_ADDON_MODULE_PATH,
"--import",
"file://" + GC_MODULE_PATH,
"--import",
"file://" + MUST_CALL_MODULE_PATH,
filePath,
],
{ cwd }
Expand Down
Loading
Loading