Skip to content

Commit 45d6e7d

Browse files
test(jco): enable resource test, start fixing owned stream lift test
1 parent cbaf7e7 commit 45d6e7d

3 files changed

Lines changed: 104 additions & 68 deletions

File tree

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

Lines changed: 61 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,62 @@
1+
use std::sync::atomic::AtomicU32;
2+
13
mod bindings {
24
use super::Component;
35
wit_bindgen::generate!({
46
world: "stream-tx",
7+
with: {
8+
"jco:test-components/get-stream-async/example-guest-resource": generate,
9+
}
510
});
611
export!(Component);
712
}
813

9-
use bindings::wit_stream;
1014
use wit_bindgen::StreamReader;
1115

12-
use crate::bindings::exports::jco::test_components::get_stream_async;
13-
use crate::bindings::wit_stream::StreamPayload;
16+
use bindings::exports::jco::test_components::get_stream_async;
17+
use bindings::exports::jco::test_components::get_stream_async::GuestExampleGuestResource;
18+
use bindings::jco::test_components::resources::ExampleResource;
19+
use bindings::wit_stream;
20+
use bindings::wit_stream::StreamPayload;
1421

1522
struct Component;
1623

17-
// /// Guest-local implementation of `example-resource`
18-
// ///
19-
// /// This resource is returned by component exported fucntions, but note
20-
// /// that is is *distinct* from the resource that is provided by the host
21-
// /// and passed in.
22-
// ///
23-
// /// This component can look and behave and be linked to the external resource
24-
// /// implementation (forwarding calls to it), but it is *not* the same.
25-
// struct ExR(u32);
26-
27-
// impl get_stream_async::GuestExampleResource for ExR {
28-
// fn new(id: u32) -> Self {
29-
// Self(id)
30-
// }
31-
32-
// fn get_id(&self) -> u32 {
33-
// return self.0;
34-
// }
35-
// }
24+
static RESOURCE_DISPOSE_COUNT: AtomicU32 = AtomicU32::new(0);
25+
26+
/// Guest-local implementation of `example-resource`
27+
///
28+
/// This resource is returned by component exported fucntions, but note
29+
/// that is is *distinct* from the resource that is provided by the host
30+
/// and passed in.
31+
///
32+
/// This component can look and behave and be linked to the external resource
33+
/// implementation (forwarding calls to it), but it is *not* the same.
34+
///
35+
pub struct ExR(u32);
36+
37+
impl get_stream_async::GuestExampleGuestResource for ExR {
38+
fn new(id: u32) -> Self {
39+
ExR(id)
40+
}
41+
42+
fn get_id(&self) -> u32 {
43+
self.0
44+
}
45+
46+
async fn get_id_async(&self) -> u32 {
47+
self.0
48+
}
49+
}
50+
51+
impl Drop for ExR {
52+
fn drop(&mut self) {
53+
RESOURCE_DISPOSE_COUNT.fetch_add(1, std::sync::atomic::Ordering::Release);
54+
}
55+
}
3656

3757
impl get_stream_async::Guest for Component {
58+
type ExampleGuestResource = ExR;
59+
3860
async fn get_stream_u32(vals: Vec<u32>) -> Result<StreamReader<u32>, String> {
3961
stream_values_async(vals)
4062
}
@@ -152,18 +174,27 @@ impl get_stream_async::Guest for Component {
152174
stream_values_async(vals)
153175
}
154176

155-
// async fn get_stream_example_resource_own(
156-
// vals: Vec<u32>,
157-
// ) -> Result<StreamReader<Self::ExampleResource>, String> {
158-
// let resources: Vec<ExR> = vals
159-
// .iter()
160-
// .map(|v| <ExR as get_stream_async::GuestExampleResource>::new(*v))
161-
// .collect();
177+
// async fn get_stream_example_resource_own(vals: Vec<u32>) -> Result<StreamReader<ExR>, String> {
178+
// let resources: Vec<ExR> = vals.iter().map(|v| ExR::new(*v)).collect();
162179
// stream_values_async(resources)
163180
// }
164181

182+
async fn get_stream_example_resource_own(
183+
vals: Vec<u32>,
184+
) -> Result<StreamReader<get_stream_async::ExampleGuestResource>, String> {
185+
let resources = vals
186+
.iter()
187+
.map(|v| get_stream_async::ExampleGuestResource::new(ExR::new(*v)))
188+
.collect::<Vec<_>>();
189+
stream_values_async(resources)
190+
}
191+
192+
fn get_example_resource_own_disposes() -> u32 {
193+
RESOURCE_DISPOSE_COUNT.load(std::sync::atomic::Ordering::Acquire)
194+
}
195+
165196
async fn get_stream_example_resource_own_attr(
166-
vals: Vec<get_stream_async::ExampleResource>,
197+
vals: Vec<ExampleResource>,
167198
) -> Result<StreamReader<u32>, String> {
168199
let (mut tx, rx) = wit_stream::new();
169200
wit_bindgen::spawn(async move {

crates/test-components/wit/all.wit

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ interface resources {
2626
interface get-stream-async {
2727
use resources.{example-resource};
2828

29+
resource example-guest-resource {
30+
constructor(id: u32);
31+
get-id: func() -> u32;
32+
get-id-async: async func() -> u32;
33+
}
34+
2935
variant example-variant {
3036
num(u32),
3137
str(string),
@@ -99,12 +105,9 @@ interface get-stream-async {
99105
// vals: list<borrow<example-resource>>
100106
// ) -> result<stream<borrow<example-resource>>, string>;
101107

102-
// // NOTE: the resource exported by a component is *not* the same as the one
103-
// // that has been provided by the host. They can be linked/have a linking managed by the component,
104-
// // but are not exactly the same.
105-
// get-stream-example-resource-own: async func(vals: list<u32>) -> result<stream<example-resource>, string>;
108+
get-stream-example-resource-own: async func(vals: list<u32>) -> result<stream<example-guest-resource>, string>;
109+
get-example-resource-own-disposes: func() -> u32;
106110

107-
// NOTE: the test below is a special case to ensure that the host resource alone is usable.
108111
get-stream-example-resource-own-attr: async func(vals: list<example-resource>) -> result<stream<u32>, string>;
109112

110113
//get-stream-stream-string: async func(vals: list<stream<string>>) -> result<stream<stream<string>>, string>;
@@ -134,7 +137,6 @@ world async-simple-return {
134137

135138
world stream-tx {
136139
import resources;
137-
// export resources;
138140
export get-stream-async;
139141
}
140142

packages/jco/test/p3/stream.js

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ suite("stream<T> lifts", () => {
2828
path: join(LOCAL_TEST_COMPONENTS_DIR, `${name}.wasm`),
2929
skipInstantiation: true,
3030
},
31-
// jco: {
32-
// transpile: {
33-
// extraArgs: {
34-
// minify: false,
35-
// },
36-
// },
37-
// },
31+
jco: {
32+
transpile: {
33+
extraArgs: {
34+
minify: false,
35+
},
36+
},
37+
},
3838
});
3939

4040
esModule = setupRes.esModule;
@@ -50,7 +50,7 @@ suite("stream<T> lifts", () => {
5050
...new WASIShim().getImportObject(),
5151
"jco:test-components/resources": {
5252
ExampleResource,
53-
}
53+
},
5454
});
5555
});
5656

@@ -295,40 +295,43 @@ suite("stream<T> lifts", () => {
295295
await checkStreamValues({ stream, vals, typeName: "result<string>", assertEqFn: assert.deepEqual });
296296
});
297297

298-
// test.only("example-resource", async () => {
299-
// assert.instanceOf(instance["jco:test-components/get-stream-async"].getStreamExampleResourceOwn, AsyncFunction);
300-
// let vals = [
301-
// 2,
302-
// 1,
303-
// 0,
304-
// ];
305-
// let stream = await instance["jco:test-components/get-stream-async"].getStreamExampleResourceOwn(vals);
306-
// for (const v of vals) {
307-
// const exportedResource = await stream.next();
308-
// assert.isNotNull(exportedResource);
309-
// assert.instanceOf(instance["jco:test-components/get-stream-async"].ExampleResource);
310-
// test.assert(exportedResource.getId(), v);
311-
// }
312-
// });
298+
test("example-resource", async () => {
299+
assert.instanceOf(instance["jco:test-components/get-stream-async"].getStreamExampleResourceOwn, AsyncFunction);
300+
let vals = [2, 1, 0];
301+
let stream = await instance["jco:test-components/get-stream-async"].getStreamExampleResourceOwn(vals);
302+
const disposeSymbol = Symbol.dispose || Symbol.for("dispose");
303+
let numDisposed = 0;
304+
for (const expectedResourceId of vals) {
305+
const resource = await stream.next();
306+
assert.isNotNull(resource);
307+
assert.instanceOf(resource, instance["jco:test-components/get-stream-async"].ExampleGuestResource);
308+
assert.strictEqual(resource.getId(), expectedResourceId);
309+
assert.strictEqual(resource.getId(), await resource.getIdAsync());
310+
311+
assert.doesNotThrow(() => resource[disposeSymbol]());
312+
numDisposed += 1;
313+
assert.strictEqual(
314+
instance["jco:test-components/get-stream-async"].getExampleResourceOwnDisposes(),
315+
numDisposed,
316+
);
317+
}
318+
});
313319

314320
test("example-resource#get-id", async () => {
315-
assert.instanceOf(instance["jco:test-components/get-stream-async"].getStreamExampleResourceOwnAttr, AsyncFunction);
316-
let vals = [
317-
new ExampleResource(2),
318-
new ExampleResource(1),
319-
new ExampleResource(0),
320-
];
321+
assert.instanceOf(
322+
instance["jco:test-components/get-stream-async"].getStreamExampleResourceOwnAttr,
323+
AsyncFunction,
324+
);
325+
let vals = [new ExampleResource(2), new ExampleResource(1), new ExampleResource(0)];
321326
let stream = await instance["jco:test-components/get-stream-async"].getStreamExampleResourceOwnAttr(vals);
322327

323328
await checkStreamValues({
324329
stream,
325330
vals,
326331
typeName: "example-resource#get-id (output)",
327-
expectedValues: [2,1,0],
332+
expectedValues: [2, 1, 0],
328333
});
329334
});
330-
331-
// TODO: test resources which contain async functions
332335
});
333336

334337
async function checkStreamValues(args) {

0 commit comments

Comments
 (0)