mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
90 lines
2.6 KiB
TypeScript
90 lines
2.6 KiB
TypeScript
import { spawnSync } from "bun";
|
|
import { cc, dlopen } from "bun:ffi";
|
|
import { beforeAll, describe, expect, it } from "bun:test";
|
|
import { bunEnv, bunExe, isWindows } from "harness";
|
|
import { join } from "path";
|
|
|
|
import source from "./napi-app/ffi_addon_1.c" with { type: "file" };
|
|
|
|
const symbols = {
|
|
set_instance_data: {
|
|
args: ["napi_env", "int"],
|
|
returns: "void",
|
|
},
|
|
get_instance_data: {
|
|
args: ["napi_env"],
|
|
returns: "int",
|
|
},
|
|
get_type: {
|
|
args: ["napi_env", "napi_value"],
|
|
returns: "cstring",
|
|
},
|
|
};
|
|
|
|
let addon1, addon2, cc1, cc2;
|
|
|
|
beforeAll(() => {
|
|
// build gyp
|
|
const install = spawnSync({
|
|
cmd: [bunExe(), "install", "--verbose"],
|
|
cwd: join(__dirname, "napi-app"),
|
|
stderr: "inherit",
|
|
env: bunEnv,
|
|
stdout: "inherit",
|
|
stdin: "inherit",
|
|
});
|
|
if (!install.success) {
|
|
throw new Error("build failed");
|
|
}
|
|
addon1 = dlopen(join(__dirname, `napi-app/build/Debug/ffi_addon_1.node`), symbols).symbols;
|
|
addon2 = dlopen(join(__dirname, `napi-app/build/Debug/ffi_addon_2.node`), symbols).symbols;
|
|
try {
|
|
cc1 = cc({
|
|
source,
|
|
symbols,
|
|
flags: `-I${join(__dirname, "napi-app/node_modules/node-api-headers/include")}`,
|
|
}).symbols;
|
|
cc2 = cc({
|
|
source,
|
|
symbols,
|
|
flags: `-I${join(__dirname, "napi-app/node_modules/node-api-headers/include")}`,
|
|
}).symbols;
|
|
} catch (e) {
|
|
// ignore compilation failure on Windows
|
|
if (!isWindows) throw e;
|
|
}
|
|
});
|
|
|
|
describe("ffi napi integration", () => {
|
|
it("has a different napi_env for each ffi library", () => {
|
|
addon1.set_instance_data(undefined, 5);
|
|
addon2.set_instance_data(undefined, 6);
|
|
expect(addon1.get_instance_data()).toBe(5);
|
|
expect(addon2.get_instance_data()).toBe(6);
|
|
});
|
|
|
|
// broken
|
|
it.todo("passes values correctly", () => {
|
|
expect(addon1.get_type(undefined, 123).toString()).toBe("number");
|
|
expect(addon1.get_type(undefined, "hello").toString()).toBe("string");
|
|
expect(addon1.get_type(undefined, 190n).toString()).toBe("bigint");
|
|
});
|
|
});
|
|
|
|
describe("cc napi integration", () => {
|
|
// fails on windows as TCC can't link the napi_ functions
|
|
it.todoIf(isWindows)("has a different napi_env for each cc invocation", () => {
|
|
cc1.set_instance_data(undefined, 5);
|
|
cc2.set_instance_data(undefined, 6);
|
|
expect(cc1.get_instance_data()).toBe(5);
|
|
expect(cc2.get_instance_data()).toBe(6);
|
|
});
|
|
|
|
// broken
|
|
it.todo("passes values correctly", () => {
|
|
expect(cc1.get_type(undefined, 123).toString()).toBe("number");
|
|
expect(cc1.get_type(undefined, "hello").toString()).toBe("string");
|
|
expect(cc1.get_type(undefined, 190n).toString()).toBe("bigint");
|
|
});
|
|
});
|