Skip to content

Commit 95c4954

Browse files
test(jco): add regression test for bare export initialize
1 parent e000213 commit 95c4954

5 files changed

Lines changed: 143 additions & 5 deletions

File tree

crates/test-components/src/bin/async_error_context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use wit_bindgen::rt::async_support::ErrorContext;
1010

1111
struct Component;
1212

13-
impl bindings::exports::jco::test_components::local_run::Guest for Component {
13+
impl bindings::exports::jco::test_components::local_run_async::Guest for Component {
1414
async fn run() {
1515
let err_ctx = ErrorContext::new("error");
1616
assert_eq!("error", err_ctx.debug_message());
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
mod bindings {
2+
use super::Component;
3+
wit_bindgen::generate!({
4+
world: "basic-run-string",
5+
});
6+
export!(Component);
7+
}
8+
9+
use crate::bindings::exports::jco::test_components::get_string;
10+
use crate::bindings::exports::jco::test_components::local_run_string;
11+
12+
use std::sync::OnceLock;
13+
14+
struct Component;
15+
16+
static INIT_DATA: OnceLock<Option<String>> = OnceLock::new();
17+
18+
/// Initialization takes the ENV value of "TEST" (if present)
19+
#[unsafe(no_mangle)]
20+
pub extern "C" fn _initialize() {
21+
INIT_DATA.get_or_init(|| std::env::var("TEST").ok());
22+
}
23+
24+
/// This version relies on the initialized data
25+
impl local_run_string::Guest for Component {
26+
fn run() -> String {
27+
INIT_DATA
28+
.get()
29+
.expect("failed to get init data")
30+
.clone()
31+
.expect("missing string in init data")
32+
}
33+
}
34+
35+
/// This version relies on the imported interface
36+
impl get_string::Guest for Component {
37+
fn get_string() -> String {
38+
bindings::jco::test_components::get_string::get_string()
39+
}
40+
}
41+
42+
// Stub only to ensure this works as a binary
43+
fn main() {}

crates/test-components/wit/all.wit

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
package jco:test-components;
22

3-
interface local-run {
3+
interface local-run-async {
44
run: async func();
55
}
66

7+
interface local-run-string {
8+
run: func() -> string;
9+
}
10+
11+
interface get-string {
12+
get-string: func() -> string;
13+
}
14+
715
interface async-add-s32 {
816
add: async func(a: s32, b: s32) -> result<s32, string>;
917
}
@@ -97,7 +105,7 @@ world async-simple-import {
97105
}
98106

99107
world async-error-context {
100-
export local-run;
108+
export local-run-async;
101109
}
102110

103111
world async-flat-param-adder {
@@ -138,4 +146,10 @@ interface fixed-length-lists-fn {
138146

139147
world fixed-length-lists {
140148
export fixed-length-lists-fn;
141-
}
149+
}
150+
151+
world basic-run-string {
152+
import get-string;
153+
export get-string;
154+
export local-run-string;
155+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { join } from "node:path";
2+
3+
import { suite, test, assert } from "vitest";
4+
5+
import { WASIShim } from "@bytecodealliance/preview2-shim/instantiation";
6+
7+
import { setupAsyncTest } from "./helpers.js";
8+
import { LOCAL_TEST_COMPONENTS_DIR } from "./common.js";
9+
10+
suite("non-wizered raw initialize export", () => {
11+
test("sync", async () => {
12+
const name = "non-wizered-init";
13+
// NOTE: simply importing the instance will run the initialization function,
14+
// and it should not fail
15+
const { instance, cleanup } = await setupAsyncTest({
16+
component: {
17+
name,
18+
path: join(LOCAL_TEST_COMPONENTS_DIR, `${name}.wasm`),
19+
imports: {
20+
...new WASIShim({ sandbox: { env: { TEST: "YES" } } }).getImportObject(),
21+
"jco:test-components/get-string": {
22+
getString() {
23+
return "FROM IMPORT";
24+
},
25+
},
26+
},
27+
},
28+
jco: {
29+
transpile: {
30+
extraArgs: {
31+
minify: false,
32+
},
33+
},
34+
},
35+
});
36+
37+
assert.strictEqual(instance["jco:test-components/local-run-string"].run(), "YES");
38+
assert.strictEqual(instance["jco:test-components/get-string"].getString(), "FROM IMPORT");
39+
40+
await cleanup();
41+
});
42+
43+
// TODO(breaking): remove this once manually specified async is removed
44+
test("legacy async", async () => {
45+
if (typeof WebAssembly?.Suspending !== "function") {
46+
return;
47+
}
48+
49+
const name = "non-wizered-init";
50+
// NOTE: simply importing the instance will run the initialization function,
51+
// and it should not fail
52+
const { instance, cleanup } = await setupAsyncTest({
53+
component: {
54+
name,
55+
path: join(LOCAL_TEST_COMPONENTS_DIR, `${name}.wasm`),
56+
imports: {
57+
...new WASIShim({ sandbox: { env: { TEST: "YES" } } }).getImportObject(),
58+
"jco:test-components/get-string": {
59+
async getString() {
60+
return "FROM IMPORT";
61+
},
62+
},
63+
},
64+
},
65+
jco: {
66+
transpile: {
67+
extraArgs: {
68+
minify: false,
69+
asyncMode: "jspi",
70+
asyncImports: ["jco:test-components/get-string#get-string"],
71+
asyncExports: ["jco:test-components/get-string#get-string"],
72+
},
73+
},
74+
},
75+
});
76+
77+
assert.strictEqual(await instance["jco:test-components/get-string"].getString(), "FROM IMPORT");
78+
79+
await cleanup();
80+
});
81+
});

packages/jco/test/p3/error-context.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ suite("Error Context (WASI P3)", () => {
2727
const { WASIShim } = await import("@bytecodealliance/preview2-shim/instantiation");
2828
const instance = await esModule.instantiate(undefined, new WASIShim().getImportObject());
2929

30-
const runFn = instance["jco:test-components/local-run"].run;
30+
const runFn = instance["jco:test-components/local-run-async"].run;
3131
assert.strictEqual(runFn instanceof AsyncFunction, true, "run function should be async");
3232

3333
await runFn();

0 commit comments

Comments
 (0)