Skip to content

Commit ebd91a5

Browse files
kraenhansenclaudelegendecas
authored
doc: add porting plan with difficulty ratings (#23)
* doc: add porting plan with difficulty ratings Enumerates all 58 test directories from Node.js's test/js-native-api and test/node-api, rates each by porting difficulty (Easy/Medium/Hard), and documents special considerations for tests with deep runtime dependencies (libuv, worker threads, SEA, node_api_post_finalizer, etc.). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * doc: clarify napi_ vs node_api_ prefix convention and fix function names Add an "API Naming Convention" section explaining that the napi_/node_api_ prefix difference is historical (rename from "napi" to "Node API"), not an indicator of Node.js-specificity. What matters is the declaring header: js_native_api.h (engine-agnostic) vs node_api.h (runtime-specific). Also fix two function name errors in the Special Considerations section: - node_api_get_prototype → napi_get_prototype (actual name in source) - napi_is_sharedarraybuffer → node_api_is_sharedarraybuffer (correct prefix) - napi_get_typedarray_info → node_api_create_sharedarraybuffer (wrong function referenced; the real concern is backing-store allocation) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Update PORTING.md Co-authored-by: Chengzhong Wu <legendecas@gmail.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Chengzhong Wu <legendecas@gmail.com>
1 parent 186ab0e commit ebd91a5

File tree

1 file changed

+185
-0
lines changed

1 file changed

+185
-0
lines changed

PORTING.md

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
# Porting Plan
2+
3+
This document tracks the progress of porting tests from Node.js's test suite into the CTS.
4+
The source directories are [`test/js-native-api`](https://github.com/nodejs/node/tree/main/test/js-native-api)
5+
and [`test/node-api`](https://github.com/nodejs/node/tree/main/test/node-api) in the Node.js repository.
6+
7+
## API Naming Convention
8+
9+
Node-API uses two function prefixes that are sometimes confused:
10+
11+
- **`napi_`** — the original prefix, retained for backwards compatibility
12+
- **`node_api_`** — the newer prefix, adopted after the project was renamed from "napi" to "Node API"
13+
14+
The prefix alone does **not** indicate whether a function is Node.js-specific or runtime-agnostic.
15+
What matters is which header the function is declared in:
16+
17+
- `js_native_api.h` — engine-agnostic APIs, available across all Node-API runtimes
18+
- `node_api.h` — runtime-specific APIs, providing features beyond pure JavaScript value operations.
19+
20+
For example, `node_api_is_sharedarraybuffer` carries the newer `node_api_` prefix but is declared
21+
in `js_native_api.h` and is therefore engine-agnostic.
22+
23+
## Difficulty Ratings
24+
25+
Difficulty is assessed on two axes:
26+
- **Size/complexity** — total lines of C/C++ and JS across all source files
27+
- **Runtime-API dependence** — pure `js_native_api.h` is cheapest; Node.js extensions and direct
28+
libuv calls require harness work or Node-only scoping
29+
30+
| Rating | Meaning |
31+
|---|---|
32+
| Easy | Small test, pure `js_native_api.h` or trivial runtime API, straightforward 1:1 port |
33+
| Medium | Moderate size or uses a Node.js extension API that the harness will need to abstract |
34+
| Hard | Large test and/or deep libuv/worker/SEA dependency; may need new harness primitives or Node-only scoping |
35+
36+
## Engine-specific (`js-native-api`)
37+
38+
Tests covering the engine-specific part of Node-API, defined in `js_native_api.h`.
39+
40+
| Directory | Status | Difficulty |
41+
|---|---|---|
42+
| `2_function_arguments` | Ported ||
43+
| `3_callbacks` | Not ported | Easy |
44+
| `4_object_factory` | Not ported | Easy |
45+
| `5_function_factory` | Not ported | Easy |
46+
| `6_object_wrap` | Not ported | Medium |
47+
| `7_factory_wrap` | Not ported | Easy |
48+
| `8_passing_wrapped` | Not ported | Easy |
49+
| `test_array` | Not ported | Easy |
50+
| `test_bigint` | Not ported | Easy |
51+
| `test_cannot_run_js` | Not ported | Medium |
52+
| `test_constructor` | Not ported | Medium |
53+
| `test_conversions` | Not ported | Medium |
54+
| `test_dataview` | Not ported | Easy |
55+
| `test_date` | Not ported | Easy |
56+
| `test_error` | Not ported | Medium |
57+
| `test_exception` | Not ported | Medium |
58+
| `test_finalizer` | Not ported | Medium |
59+
| `test_function` | Not ported | Medium |
60+
| `test_general` | Not ported | Hard |
61+
| `test_handle_scope` | Not ported | Easy |
62+
| `test_instance_data` | Not ported | Easy |
63+
| `test_new_target` | Not ported | Easy |
64+
| `test_number` | Not ported | Easy |
65+
| `test_object` | Not ported | Hard |
66+
| `test_promise` | Not ported | Easy |
67+
| `test_properties` | Not ported | Easy |
68+
| `test_reference` | Not ported | Medium |
69+
| `test_reference_double_free` | Not ported | Easy |
70+
| `test_sharedarraybuffer` | Not ported | Medium |
71+
| `test_string` | Not ported | Medium |
72+
| `test_symbol` | Not ported | Easy |
73+
| `test_typedarray` | Not ported | Medium |
74+
75+
## Runtime-specific (`node-api`)
76+
77+
Tests covering the runtime-specific part of Node-API, defined in `node_api.h`.
78+
79+
| Directory | Status | Difficulty |
80+
|---|---|---|
81+
| `1_hello_world` | Not ported | Easy |
82+
| `test_async` | Not ported | Hard |
83+
| `test_async_cleanup_hook` | Not ported | Hard |
84+
| `test_async_context` | Not ported | Hard |
85+
| `test_buffer` | Not ported | Medium |
86+
| `test_callback_scope` | Not ported | Hard |
87+
| `test_cleanup_hook` | Not ported | Medium |
88+
| `test_env_teardown_gc` | Not ported | Easy |
89+
| `test_exception` | Not ported | Easy |
90+
| `test_fatal` | Not ported | Hard |
91+
| `test_fatal_exception` | Not ported | Easy |
92+
| `test_general` | Not ported | Medium |
93+
| `test_init_order` | Not ported | Medium |
94+
| `test_instance_data` | Not ported | Hard |
95+
| `test_make_callback` | Not ported | Hard |
96+
| `test_make_callback_recurse` | Not ported | Hard |
97+
| `test_null_init` | Not ported | Medium |
98+
| `test_reference_by_node_api_version` | Not ported | Medium |
99+
| `test_sea_addon` | Not ported | Hard |
100+
| `test_threadsafe_function` | Not ported | Hard |
101+
| `test_threadsafe_function_shutdown` | Not ported | Hard |
102+
| `test_uv_loop` | Not ported | Hard |
103+
| `test_uv_threadpool_size` | Not ported | Hard |
104+
| `test_worker_buffer_callback` | Not ported | Hard |
105+
| `test_worker_terminate` | Not ported | Hard |
106+
| `test_worker_terminate_finalization` | Not ported | Hard |
107+
108+
## Special Considerations
109+
110+
### `node_api_post_finalizer` (`6_object_wrap`, `test_finalizer`)
111+
112+
Both tests call `node_api_post_finalizer` to defer JS-touching work out of the GC finalizer and
113+
onto the main thread. The function is declared in `js_native_api.h` but is gated behind
114+
`NAPI_EXPERIMENTAL`, so not all runtimes may implement it yet. The CTS harness will need a
115+
platform-agnostic post-finalizer primitive that implementors can map to their own
116+
deferred-callback mechanism, or the tests need to isolate the post-finalizer cases behind a
117+
runtime capability check.
118+
119+
### `node_api_set_prototype` / `napi_get_prototype` (`test_general`, js-native-api)
120+
121+
The general test suite mixes `js_native_api.h` assertions with calls to `node_api_set_prototype`
122+
(gated behind `NAPI_EXPERIMENTAL`) and `napi_get_prototype` (standard). The experimental function
123+
may not be implemented by all runtimes yet. The CTS port should split the affected test cases into
124+
a stable core and an experimental annex, or guard the `node_api_set_prototype` cases with a
125+
runtime capability check.
126+
127+
### SharedArrayBuffer backing-store creation (`test_sharedarraybuffer`)
128+
129+
`node_api_is_sharedarraybuffer` and `node_api_create_sharedarraybuffer` are both declared in
130+
`js_native_api.h` and are engine-agnostic. However, the test also exercises creating a
131+
SharedArrayBuffer from the C side via `node_api_create_sharedarraybuffer`, which allocates
132+
backing store memory. The CTS version will need a harness-provided factory (something like
133+
`create_shared_array_buffer(size)`) that each runtime can implement using its own path.
134+
135+
### libuv dependency (multiple `node-api` tests)
136+
137+
The following tests call into libuv directly — `napi_get_uv_event_loop`, `uv_thread_t`,
138+
`uv_mutex_t`, `uv_async_t`, `uv_check_t`, `uv_idle_t`, `uv_queue_work`, and related APIs:
139+
140+
- `test_async`, `test_async_cleanup_hook`, `test_async_context`
141+
- `test_callback_scope`
142+
- `test_fatal` (uses `uv_thread_t` to test cross-thread fatal errors)
143+
- `test_instance_data` (async work + threadsafe functions + `uv_thread_t`)
144+
- `test_uv_loop`, `test_uv_threadpool_size`
145+
146+
Porting options:
147+
1. **Node-only scope** — mark these tests as Node.js-only and skip on other runtimes.
148+
2. **Harness abstraction** — introduce a minimal platform-agnostic threading/async API in the
149+
harness (e.g., `cts_thread_create`, `cts_async_schedule`) that implementors back with their
150+
own event loop primitives (libuv, tokio, etc.).
151+
152+
### Threadsafe functions (`test_threadsafe_function`, `test_threadsafe_function_shutdown`)
153+
154+
`test_threadsafe_function` is the largest single test (~700 total lines across C and JS), covering
155+
blocking/non-blocking queue modes, queue-full handling, multiple concurrent threads, finalization
156+
ordering, uncaught exception propagation, and high-precision timing via `uv_hrtime`. The threading
157+
primitives are libuv-specific (same concern as the section above). Porting this test likely depends
158+
on resolving the libuv abstraction question first.
159+
160+
### Worker threads (`test_worker_buffer_callback`, `test_worker_terminate`, `test_worker_terminate_finalization`)
161+
162+
These three tests exercise addon behavior inside Node.js worker threads: buffer finalizer delivery
163+
in worker contexts, function-call behavior under pending exceptions during worker shutdown, and
164+
wrapped-object finalization on forced worker termination. Node.js worker threads have no direct
165+
equivalent in most other Node-API runtimes. These tests are likely Node.js-only and should be
166+
scoped accordingly.
167+
168+
### SEA — Single Executable Applications (`test_sea_addon`)
169+
170+
`test_sea_addon` verifies that a native addon can be loaded inside a Node.js Single Executable
171+
Application. SEA is a Node.js-specific packaging feature with no equivalent in other runtimes.
172+
This test should be excluded from the CTS scope or placed in a Node-only annex.
173+
174+
### `napi_get_node_version` (`test_general`, node-api)
175+
176+
`test_general` calls `napi_get_node_version`, which returns the Node.js major/minor/patch version.
177+
No equivalent exists in other runtimes. The CTS port should either omit that assertion or expose a
178+
harness helper (e.g., `cts_get_runtime_version`) that runtimes can optionally implement.
179+
180+
### Legacy module registration (`test_null_init`)
181+
182+
`test_null_init` exercises the deprecated `NAPI_MODULE` macro with a NULL init function, calling
183+
`napi_module_register` directly. Some newer runtimes that implement Node-API may not support this
184+
legacy registration path. If so, this test should be scoped as Node-only or skipped on runtimes
185+
that only support `NAPI_MODULE_INIT`.

0 commit comments

Comments
 (0)