Skip to content
This repository was archived by the owner on Jul 5, 2025. It is now read-only.

Commit 2ef4610

Browse files
committed
feat: handle return error
1 parent 8fe7783 commit 2ef4610

File tree

9 files changed

+109
-63
lines changed

9 files changed

+109
-63
lines changed

crates/sweet_rsx/src/sweet_loader/sweet_loader.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ mod test {
1111
use sweet::prelude::*;
1212

1313
#[test]
14-
fn works() { expect(true).to_be_false(); }
14+
fn works() {}
1515
}

crates/sweet_test/src/wasm/js_runtime_extern.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ pub mod js_runtime {
1212
#[wasm_bindgen(catch)]
1313
/// Just run the function outside of the wasm boundary
1414
/// ie `const panic_to_error = (f)=>f()`
15-
pub fn panic_to_error(f: &mut dyn FnMut()) -> Result<(), JsValue>;
15+
pub fn panic_to_error(
16+
f: &mut dyn FnMut() -> Result<(), String>,
17+
) -> Result<(), JsValue>;
1618
#[wasm_bindgen]
1719
/// Read a file from the filesystem, ie `Deno.read_file()`
1820
pub fn read_file(path: &str) -> Option<String>;
@@ -29,9 +31,24 @@ mod test {
2931
use crate::prelude::*;
3032

3133
#[test]
32-
fn works() {
34+
fn cwd() { expect(js_runtime::cwd()).to_contain("sweet"); }
35+
36+
#[test]
37+
#[ignore = "take hook shenanigans"]
38+
// #[should_panic]
39+
fn panic_to_error() {
40+
let result = js_runtime::panic_to_error(&mut || panic!("it panicked"));
41+
expect(&format!("{:?}", result))
42+
.to_start_with("Err(JsValue(RuntimeError: unreachable");
43+
}
44+
#[test]
45+
fn read_file() {
3346
expect(js_runtime::read_file("foobar")).to_be_none();
3447
expect(js_runtime::read_file("Cargo.toml")).to_be_some();
3548
// expect(js_runtime::read_file("Cargo.lock")).to_be_some();
3649
}
50+
#[test]
51+
fn sweet_root() {
52+
expect(js_runtime::sweet_root().unwrap()).to_end_with("sweet/");
53+
}
3754
}

crates/sweet_test/src/wasm/panic_store.rs

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,67 @@
11
use crate::prelude::*;
2+
use core::fmt;
3+
use flume::Sender;
24
use std::cell::RefCell;
35
use std::panic::PanicHookInfo;
46
use std::rc::Rc;
57
use test::TestDesc;
8+
use wasm_bindgen::JsValue;
69

10+
11+
/// A completed test that maybe panicked
712
pub enum PanicStoreOut<T> {
813
Panicked(TestDescAndResult),
9-
Ok(T),
14+
/// maybe returned error
15+
NoPanic(T),
16+
}
17+
18+
impl<T> PanicStoreOut<T> {
19+
pub fn panicked(&self) -> bool {
20+
match self {
21+
PanicStoreOut::Panicked(_) => true,
22+
PanicStoreOut::NoPanic(_) => false,
23+
}
24+
}
25+
}
26+
27+
impl<T: fmt::Debug> fmt::Debug for PanicStoreOut<T> {
28+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29+
match self {
30+
PanicStoreOut::Panicked(result) => {
31+
write!(f, "Panicked({:?})", result)
32+
}
33+
PanicStoreOut::NoPanic(result) => {
34+
write!(f, "NoPanic({:?})", result)
35+
}
36+
}
37+
}
38+
}
39+
40+
impl<T> PanicStoreOut<Result<T, JsValue>> {
41+
pub fn send(self, result_tx: &Sender<TestDescAndResult>, desc: &TestDesc) {
42+
match self {
43+
PanicStoreOut::Panicked(result) => {
44+
result_tx.send(result).expect("channel was dropped");
45+
}
46+
PanicStoreOut::NoPanic(Err(err)) => {
47+
let test_result = TestResult::from_test_result(
48+
Err(err
49+
.as_string()
50+
.expect("all test errors should be strings")),
51+
desc,
52+
);
53+
result_tx
54+
.send(TestDescAndResult::new(desc.clone(), test_result))
55+
.expect("channel was dropped");
56+
}
57+
PanicStoreOut::NoPanic(Ok(_)) => {
58+
let test_result = TestResult::from_test_result(Ok(()), desc);
59+
result_tx
60+
.send(TestDescAndResult::new(desc.clone(), test_result))
61+
.expect("channel was dropped");
62+
}
63+
}
64+
}
1065
}
1166

1267

@@ -58,7 +113,7 @@ impl PanicStore {
58113
(Some(panic_result), _) => PanicStoreOut::Panicked(
59114
TestDescAndResult::new(desc.clone(), panic_result),
60115
),
61-
(None, result) => PanicStoreOut::Ok(result),
116+
(None, result) => PanicStoreOut::NoPanic(result),
62117
}
63118
})
64119
}

crates/sweet_test/src/wasm/run_libtest_wasm.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,7 @@ pub async fn run_with_pending() -> Result<(), JsValue> {
7272

7373
let futs = futures.into_iter().map(|fut| async {
7474
TestFuture::new(fut.desc, result_tx.clone(), async move {
75-
(fut.fut)().await.ok();
76-
Ok(JsValue::NULL)
75+
(fut.fut)().await
7776
})
7877
.await;
7978
});
Lines changed: 6 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,31 @@
11
use crate::prelude::*;
22
use flume::Sender;
3-
use forky::web::ClosureFnMutT2Ext;
43
use test::TestDescAndFn;
5-
use wasm_bindgen::prelude::Closure;
6-
use wasm_bindgen::JsCast;
7-
use wasm_bindgen::JsValue;
84

5+
6+
/// Run sync tests, and return async tests
97
pub fn run_wasm_tests_sync(
108
tests: Vec<TestDescAndFn>,
119
result_tx: &Sender<TestDescAndResult>,
1210
) -> Vec<TestDescAndFuture> {
1311
tests
1412
.into_iter()
1513
.filter_map(|test| {
16-
let func = TestDescAndFnExt::func(&test);
14+
let mut func = TestDescAndFnExt::func(&test);
1715

1816
let result = SweetTestCollector::with_scope(&test.desc, || {
1917
PanicStore::with_scope(&test.desc, || {
20-
// dont worry if it returned error, we will catch the panic
21-
run_no_abort(func)
18+
js_runtime::panic_to_error(&mut func)
2219
})
2320
});
2421

2522
match result {
26-
Ok(PanicStoreOut::Panicked(result)) => {
27-
result_tx.send(result).expect("channel was dropped");
28-
None
29-
}
30-
Ok(PanicStoreOut::Ok(_)) => {
31-
let test_result =
32-
TestResult::from_test_result(Ok(()), &test.desc);
33-
result_tx
34-
.send(TestDescAndResult::new(
35-
test.desc.clone(),
36-
test_result,
37-
))
38-
.expect("channel was dropped");
23+
Ok(panic_out) => {
24+
panic_out.send(result_tx, &test.desc);
3925
None
4026
}
4127
Err(val) => Some(val),
4228
}
4329
})
4430
.collect()
4531
}
46-
47-
/// this function may panic. In js that will abort execution
48-
/// so we send it out of the wasm boundary
49-
/// TODO try the wb_test func might be cheaper than closure
50-
fn run_no_abort(func: fn() -> Result<(), String>) {
51-
// fn run_no_abort(func: fn() -> Result<(), String>) -> Result<(), String> {
52-
let closure = Closure::from_func_no_args(move || {
53-
TestDescExt::result_to_panic(func());
54-
});
55-
let func: &js_sys::Function = closure.as_ref().unchecked_ref();
56-
func.call0(&JsValue::NULL).ok();
57-
// match func.call0(&JsValue::NULL) {
58-
// Ok(_) => Ok(()),
59-
// Err(err) => Err(format!("{:?}", err)),
60-
// }
61-
}

crates/sweet_test/src/wasm/test_future.rs

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ impl<F> TestFuture<F> {
2929
}
3030
}
3131

32-
impl<F: Future<Output = Result<JsValue, JsValue>>> Future for TestFuture<F> {
32+
impl<F: Future<Output = Result<(), String>>> Future for TestFuture<F> {
3333
type Output = ();
3434

3535
fn poll(
@@ -46,37 +46,36 @@ impl<F: Future<Output = Result<JsValue, JsValue>>> Future for TestFuture<F> {
4646
let result_tx = &self_mut.result_tx;
4747
let mut future_poll_output = None;
4848

49-
// did it panic during this poll
49+
// this should only be used if poll::ready!
5050
let panic_output = PanicStore::with_scope(desc, || {
5151
let mut test = Some(test);
5252
js_runtime::panic_to_error(&mut || {
5353
let test = test.take().unwrap_throw();
54-
future_poll_output = Some(test.poll(cx))
54+
let out = test.poll(cx);
55+
future_poll_output = Some(match &out {
56+
Poll::Ready(_) => Poll::Ready(()),
57+
Poll::Pending => Poll::Pending,
58+
});
59+
match out {
60+
Poll::Ready(Err(err)) => Err(err),
61+
_ => Ok(()),
62+
}
5563
})
5664
});
5765

58-
match panic_output {
59-
PanicStoreOut::Panicked(test_desc_and_result) => {
60-
result_tx
61-
.send(test_desc_and_result)
62-
.expect("channel was dropped");
63-
return Poll::Ready(());
64-
}
65-
PanicStoreOut::Ok(_) => {
66-
// could be pending
67-
}
66+
// panicked futures will never be ready
67+
if panic_output.panicked() {
68+
panic_output.send(result_tx, desc);
69+
return Poll::Ready(());
6870
}
6971

7072
match future_poll_output {
7173
Some(Poll::Pending) => Poll::Pending,
72-
_ => {
73-
let test_result = TestResult::from_test_result(Ok(()), &desc);
74-
result_tx
75-
.send(TestDescAndResult::new(desc.clone(), test_result))
76-
.expect("channel was dropped");
77-
74+
Some(Poll::Ready(())) => {
75+
panic_output.send(result_tx, desc);
7876
Poll::Ready(())
7977
}
78+
None => Poll::Pending,
8079
}
8180
}
8281
}

crates/sweet_test/tests/macros.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,13 @@ fn it_panics_sync() { panic!("foo") }
1616
async fn it_passes() {}
1717
#[sweet::test]
1818
async fn it_returns_ok() -> Result<(), String> { Ok(()) }
19+
#[test]
20+
#[ignore = "it returns error"]
21+
fn it_returns_err() -> Result<(), String> { Err("foo".to_string()) }
22+
1923
#[sweet::test]
2024
#[ignore = "it returns error"]
21-
async fn it_returns_err() -> Result<(), String> { Err("foo".to_string()) }
25+
async fn it_returns_err_async() -> Result<(), String> { Err("foo".to_string()) }
2226

2327
#[sweet::test]
2428
#[should_panic]

crates/sweet_test/tests/sweet_macro.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//! used for cargo expand
12
#![cfg_attr(test, feature(test, custom_test_frameworks))]
23
#![cfg_attr(test, test_runner(sweet::test_runner))]
34

justfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ test-all *args:
4545
cargo test --workspace -- {{args}}
4646
cargo test -p sweet_rsx --lib --target wasm32-unknown-unknown -- {{args}}
4747
cargo test -p sweet_test --lib --target wasm32-unknown-unknown -- {{args}}
48+
cargo test -p sweet_test --test macros --target wasm32-unknown-unknown -- {{args}}
4849

4950
expand-wasm test *args:
5051
just watch 'cargo expand --test {{test}} --target wasm32-unknown-unknown {{args}}'

0 commit comments

Comments
 (0)