Skip to content

Commit d271b3b

Browse files
wip: working but failing test
1 parent 3587760 commit d271b3b

File tree

5 files changed

+100
-90
lines changed

5 files changed

+100
-90
lines changed

crates/js-component-bindgen/src/transpile_bindgen.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2562,23 +2562,19 @@ impl<'a> Instantiator<'a, '_> {
25622562
// Figure out the function name and callee (e.g. class for a given resource) to use
25632563
let (import_name, binding_name) = match func.kind {
25642564
FunctionKind::Freestanding | FunctionKind::AsyncFreestanding => (
2565-
// TODO: if we want to avoid async<some fn> for imports,
2566-
// we need to use the code below:
2565+
// TODO: if we want to avoid the naming of 'async<fn name>' (e.g. 'asyncSleepMillis'
2566+
// vs 'sleepMillis' which just *is* an imported async function)....
2567+
//
2568+
// We need to use the code below:
25672569
//
25682570
// func_name
25692571
// .strip_prefix("[async]")
25702572
// .unwrap_or(func_name)
25712573
// .to_lower_camel_case(),
25722574
//
2573-
// This would break *a lot* of downstream though.
2574-
2575-
// func_name.to_lower_camel_case(),
2576-
2577-
func_name
2578-
.strip_prefix("[async]")
2579-
.unwrap_or(func_name)
2580-
.to_lower_camel_case(),
2581-
2575+
// This has the potential to break a lot of downstream consumers who are expecting to
2576+
// provide 'async<fn name>`, so it must be done before a breaking change.
2577+
func_name.to_lower_camel_case(),
25822578
callee_name,
25832579
),
25842580

packages/jco/test/p3/ported/wasmtime/component-async/backpressure.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { join } from 'node:path';
22

33
import { suite, test } from 'vitest';
44

5-
import { testComponent, composeCallerCallee, COMPONENT_FIXTURES_DIR } from "./common.js";
5+
import { buildAndTranspile, composeCallerCallee, COMPONENT_FIXTURES_DIR } from "./common.js";
66

77
// These tests are ported from upstream wasmtime's component-async-tests
88
//
@@ -23,6 +23,15 @@ suite('backpressure scenario', () => {
2323
callerPath,
2424
calleePath,
2525
});
26-
await testComponent({ componentPath });
26+
27+
let cleanup;
28+
try {
29+
const res = await buildAndTranspile({ componentPath });
30+
const instance = res.instance;
31+
cleanup = res.cleanup;
32+
await instance['local:local/run'].asyncRun();
33+
} finally {
34+
if (cleanup) { await cleanup(); }
35+
}
2736
});
2837
});

packages/jco/test/p3/ported/wasmtime/component-async/common.js

Lines changed: 7 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,7 @@ async function ensureFile(filePath) {
2727
}
2828

2929
/**
30-
* Run a single component test for a component that
31-
* exports `local:local/run` (normally async) in the style of
32-
* wasmtime component-async-tests
33-
*
34-
* This test will generally transpile the component and then run its' 'local:local/run' export
35-
*
36-
* @see https://github.com/bytecodealliance/wasmtime/blob/main/crates/misc/component-async-tests/tests/scenario/util.rs
30+
* Build and transpile a component for use in a test
3731
*
3832
* @param {object} args
3933
* @param {string} args.componentPath - path to the wasm binary that should be tested
@@ -42,7 +36,7 @@ async function ensureFile(filePath) {
4236
* @param {object} args.transpile.extraArgs - extra arguments that should be used during transpilation (ex. `{minify: false}`)
4337
* @returns {Promise<void>} A Promise that resolves when the test completes
4438
*/
45-
export async function testComponent(args) {
39+
export async function buildAndTranspile(args) {
4640
const componentPath = await ensureFile(args.componentPath);
4741
const { esModule, cleanup } = await setupAsyncTest({
4842
asyncMode: 'jspi',
@@ -72,45 +66,11 @@ export async function testComponent(args) {
7266
}
7367
);
7468

75-
let runFn;
76-
let result;
77-
if ('local:local/run' in instance) {
78-
runFn = instance['local:local/run'].asyncRun;
79-
assert.strictEqual(
80-
runFn instanceof AsyncFunction,
81-
true,
82-
'local:local/run should be async'
83-
);
84-
} else if ('wasi:cli/[email protected]' in instance) {
85-
runFn = instance['wasi:cli/[email protected]'].run;
86-
}
87-
88-
if (runFn) {
89-
if (runFn instanceof AsyncFunction) {
90-
result = await runFn();
91-
} else {
92-
result = runFn();
93-
}
94-
}
95-
96-
// Ensure our test does *something* via a detected export or if testing
97-
// will happen outside, due to noCleanup
98-
if (!runFn && !args.noCleanup) {
99-
throw new Error("no detected function was run, and cleanup is specified");
100-
}
101-
102-
if (args.noCleanup) {
103-
return {
104-
result,
105-
instance,
106-
esModule,
107-
cleanup,
108-
};
109-
}
110-
111-
await cleanup();
112-
113-
return { result };
69+
return {
70+
instance,
71+
esModule,
72+
cleanup,
73+
};
11474
}
11575

11676
/**

packages/jco/test/p3/ported/wasmtime/component-async/error-context.js

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { join } from 'node:path';
22

33
import { suite, test } from 'vitest';
44

5-
import { testComponent, composeCallerCallee, COMPONENT_FIXTURES_DIR } from "./common.js";
5+
import { buildAndTranspile, composeCallerCallee, COMPONENT_FIXTURES_DIR } from "./common.js";
66

77
// These tests are ported from upstream wasmtime's component-async-tests
88
//
@@ -15,7 +15,16 @@ suite('error-context scenario', () => {
1515
COMPONENT_FIXTURES_DIR,
1616
'p3/error-context/async-error-context.wasm'
1717
);
18-
await testComponent({ componentPath });
18+
19+
let cleanup;
20+
try {
21+
const res = await buildAndTranspile({ componentPath });
22+
const instance = res.instance;
23+
cleanup = res.cleanup;
24+
await instance['local:local/run'].asyncRun();
25+
} finally {
26+
if (cleanup) { await cleanup(); }
27+
}
1928
});
2029

2130
test('caller & callee', async () => {
@@ -31,6 +40,15 @@ suite('error-context scenario', () => {
3140
callerPath,
3241
calleePath,
3342
});
34-
await testComponent({ componentPath });
43+
44+
let cleanup;
45+
try {
46+
const res = await buildAndTranspile({ componentPath });
47+
cleanup = res.cleanup;
48+
const instance = res.instance;
49+
await instance['local:local/run'].asyncRun();
50+
} finally {
51+
if (cleanup) { await cleanup(); }
52+
}
3553
});
3654
});

packages/jco/test/p3/ported/wasmtime/component-async/post-return.js

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { join } from 'node:path';
22

3-
import { suite, test } from 'vitest';
3+
import { suite, test, expect, vi } from 'vitest';
44

5-
import { testComponent, composeCallerCallee, COMPONENT_FIXTURES_DIR } from "./common.js";
5+
import { buildAndTranspile, composeCallerCallee, COMPONENT_FIXTURES_DIR } from "./common.js";
66

77
// These tests are ported from upstream wasmtime's component-async-tests
88
//
@@ -23,7 +23,16 @@ suite.skip('post-return scenario', () => {
2323
callerPath,
2424
calleePath,
2525
});
26-
await testComponent({ componentPath });
26+
27+
let cleanup;
28+
try {
29+
const res = await buildAndTranspile({ componentPath });
30+
const instance = res.instance;
31+
cleanup = res.cleanup;
32+
await instance['local:local/run'].asyncRun();
33+
} finally {
34+
if (cleanup) { await cleanup(); }
35+
}
2736
});
2837
});
2938

@@ -46,31 +55,49 @@ suite('post-return async sleep scenario', () => {
4655
callerPath,
4756
calleePath,
4857
});
49-
await testComponent({
50-
componentPath,
51-
instantiation: {
52-
imports: {
53-
'local:local/sleep': {
54-
// WIT:
55-
// ```
56-
// sleep-millis: async func(time-in-millis: u64);
57-
// ```
58-
// see: wasmtime/crates/misc/component-async-tests/wit/test.wit
5958

60-
// sleepMillis: async (ms) => {
61-
// await new Promise((resolve) => setTimeout(resolve, ms));
62-
// },
63-
// asyncSleepMillis: async (ms) => {
64-
// await new Promise((resolve) => setTimeout(resolve, ms));
65-
// },
66-
}
67-
}
68-
},
69-
transpile: {
70-
extraArgs: {
71-
minify: false,
72-
}
73-
},
59+
const waitTimeMs = 300;
60+
const asyncSleepMillis = vi.fn(async (ms) => {
61+
expect(ms).toStrictEqual(waitTimeMs);
62+
await new Promise((resolve) => setTimeout(resolve, ms));
7463
});
64+
65+
let cleanup;
66+
try {
67+
const res = await buildAndTranspile({
68+
componentPath,
69+
noCleanup: true,
70+
instantiation: {
71+
imports: {
72+
'local:local/sleep': {
73+
// WIT:
74+
//
75+
// ```
76+
// sleep-millis: async func(time-in-millis: u64);
77+
// ```
78+
// see: wasmtime/crates/misc/component-async-tests/wit/test.wit
79+
asyncSleepMillis,
80+
}
81+
}
82+
},
83+
transpile: {
84+
extraArgs: {
85+
minify: false,
86+
}
87+
},
88+
});
89+
const instance = res.instance;
90+
cleanup = res.cleanup;
91+
92+
await instance['local:local/sleep-post-return'].asyncRun(waitTimeMs);
93+
94+
// TODO: fix: sleep-post-return is running but *does not* call the import properly,
95+
// likely because the task is not actually the thing being returned -- the promise is
96+
// returning early?
97+
98+
expect(asyncSleepMillis).toHaveBeenCalled();
99+
} finally {
100+
if (cleanup) { await cleanup(); }
101+
}
75102
});
76103
});

0 commit comments

Comments
 (0)