Skip to content

Commit 01f3a65

Browse files
committed
Build, load and test function arguments addon
1 parent 25a8cae commit 01f3a65

File tree

14 files changed

+1245
-9
lines changed

14 files changed

+1245
-9
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,8 @@
11
node_modules/
2+
3+
# Shallow checkout for agents to reference
4+
/node/
5+
6+
# Artifacts from building addons
7+
/build/
8+
/tests/**/*.node

CMakeLists.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
cmake_minimum_required(VERSION 3.15...3.31)
2+
project(node-api-cts)
3+
4+
function(add_node_api_cts_addon ADDON_NAME SRC)
5+
add_library(${ADDON_NAME} SHARED ${SRC} ${CMAKE_JS_SRC})
6+
set_target_properties(${ADDON_NAME} PROPERTIES PREFIX "" SUFFIX ".node")
7+
target_include_directories(${ADDON_NAME} PRIVATE ${CMAKE_JS_INC})
8+
target_link_libraries(${ADDON_NAME} PRIVATE ${CMAKE_JS_LIB})
9+
target_compile_features(${ADDON_NAME} PRIVATE cxx_std_17)
10+
target_compile_definitions(${ADDON_NAME} PRIVATE ADDON_NAME=${ADDON_NAME})
11+
set_target_properties(${ADDON_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
12+
endfunction()
13+
14+
file(GLOB_RECURSE cmake_dirs RELATIVE ${CMAKE_SOURCE_DIR} tests/*/CMakeLists.txt)
15+
16+
foreach(cmake_file ${cmake_dirs})
17+
get_filename_component(subdir ${cmake_file} DIRECTORY)
18+
add_subdirectory(${subdir})
19+
endforeach()
20+
21+
if(MSVC AND CMAKE_JS_NODELIB_DEF AND CMAKE_JS_NODELIB_TARGET)
22+
# Generate node.lib
23+
execute_process(COMMAND ${CMAKE_AR} /def:${CMAKE_JS_NODELIB_DEF} /out:${CMAKE_JS_NODELIB_TARGET} ${CMAKE_STATIC_LINKER_FLAGS})
24+
endif()

implementors/node/load-addon.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import assert from "node:assert/strict";
2+
import { dlopen } from "node:process";
3+
import { constants } from "node:os";
4+
import path from "node:path";
5+
import fs from "node:fs";
6+
7+
const loadAddon = (addonFileName) => {
8+
assert(typeof addonFileName === "string", "Expected a string as addon filename");
9+
assert(!addonFileName.endsWith(".node"), "Expected addon filename without the .node extension");
10+
const addonPath = path.join(process.cwd(), addonFileName + ".node");
11+
assert(fs.existsSync(addonPath), `Expected ${addonPath} to exist - did you build the addons?`);
12+
const addon = { exports: {} };
13+
dlopen(addon, addonPath, constants.dlopen.RTLD_NOW);
14+
return addon.exports;
15+
};
16+
17+
Object.assign(globalThis, { loadAddon });

implementors/node/run-tests.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,19 @@ import { test, type TestContext } from "node:test";
55

66
const ROOT_PATH = path.resolve(import.meta.dirname, "..", "..");
77
const TESTS_ROOT_PATH = path.join(ROOT_PATH, "tests");
8+
89
const ASSERT_MODULE_PATH = path.join(
910
ROOT_PATH,
1011
"implementors",
1112
"node",
1213
"assert.js"
1314
);
15+
const LOAD_ADDON_MODULE_PATH = path.join(
16+
ROOT_PATH,
17+
"implementors",
18+
"node",
19+
"load-addon.js"
20+
);
1421

1522
async function listDirectoryEntries(dir: string) {
1623
const entries = await fs.readdir(dir, { withFileTypes: true });
@@ -31,13 +38,19 @@ async function listDirectoryEntries(dir: string) {
3138
return { directories, files };
3239
}
3340

34-
function runFileInSubprocess(filePath: string): Promise<void> {
41+
function runFileInSubprocess(cwd: string, filePath: string): Promise<void> {
3542
return new Promise((resolve, reject) => {
36-
const child = spawn(process.execPath, [
37-
"--import",
38-
ASSERT_MODULE_PATH,
39-
filePath,
40-
]);
43+
const child = spawn(
44+
process.execPath,
45+
[
46+
"--import",
47+
ASSERT_MODULE_PATH,
48+
"--import",
49+
LOAD_ADDON_MODULE_PATH,
50+
filePath,
51+
],
52+
{ cwd }
53+
);
4154

4255
let stderrOutput = "";
4356
child.stderr.setEncoding("utf8");
@@ -80,8 +93,7 @@ async function populateSuite(
8093
const { directories, files } = await listDirectoryEntries(dir);
8194

8295
for (const file of files) {
83-
const filePath = path.join(dir, file);
84-
await testContext.test(file, () => runFileInSubprocess(filePath));
96+
await testContext.test(file, () => runFileInSubprocess(dir, file));
8597
}
8698

8799
for (const directory of directories) {

0 commit comments

Comments
 (0)