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

Commit abdfb74

Browse files
test(tinywasm): add AssertMalformed to spec test harness
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
1 parent f203c4a commit abdfb74

File tree

2 files changed

+92
-37
lines changed

2 files changed

+92
-37
lines changed

crates/parser/src/conversion.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,16 @@ pub(crate) fn convert_module_code(
3131
) -> Result<CodeSection> {
3232
let locals_reader = func.get_locals_reader()?;
3333
let count = locals_reader.get_count();
34+
3435
let mut locals = Vec::with_capacity(count as usize);
3536

3637
for (i, local) in locals_reader.into_iter().enumerate() {
3738
let local = local?;
39+
validator.define_locals(i, local.0, local.1)?;
40+
3841
for _ in 0..local.0 {
3942
locals.push(convert_valtype(&local.1));
4043
}
41-
validator.define_locals(i, local.0, local.1)?;
4244
}
4345

4446
if locals.len() != count as usize {

crates/tinywasm/tests/mvp.rs

Lines changed: 89 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::{
2-
collections::HashMap,
2+
collections::BTreeMap,
33
fmt::{Debug, Formatter},
44
};
55

@@ -21,48 +21,85 @@ fn parse_module(mut module: wast::core::Module) -> Result<TinyWasmModule, Error>
2121
fn test_mvp() {
2222
let mut test_suite = TestSuite::new();
2323

24-
wasm_testsuite::MVP_TESTS.iter().for_each(|name| {
25-
println!("test: {}", name);
24+
wasm_testsuite::MVP_TESTS.iter().for_each(|group| {
25+
println!("test: {}", group);
2626

27-
let test_group = test_suite.test_group("mvp");
27+
let test_group = test_suite.test_group(group);
2828

29-
let wast = wasm_testsuite::get_test_wast(name).expect("failed to get test wast");
29+
let wast = wasm_testsuite::get_test_wast(group).expect("failed to get test wast");
3030
let wast = std::str::from_utf8(&wast).expect("failed to convert wast to utf8");
3131

3232
let mut lexer = Lexer::new(&wast);
33+
// we need to allow confusing unicode characters since they are technically valid wasm
3334
lexer.allow_confusing_unicode(true);
3435

3536
let buf = ParseBuffer::new_with_lexer(lexer).expect("failed to create parse buffer");
3637
let wast_data = parser::parse::<Wast>(&buf).expect("failed to parse wat");
3738

38-
for directive in wast_data.directives {
39+
for (i, directive) in wast_data.directives.into_iter().enumerate() {
3940
let span = directive.span();
4041

4142
use wast::WastDirective::*;
43+
let name = format!("{}-{}", group, i);
4244
match directive {
45+
// TODO: needs to support more binary sections
4346
Wat(QuoteWat::Wat(wast::Wat::Module(module))) => {
44-
let module = parse_module(module).map(|_| ());
45-
test_group.module_compiles(name, span, module);
47+
let module = std::panic::catch_unwind(|| parse_module(module));
48+
test_group.add_result(
49+
&format!("{}-parse", name),
50+
span,
51+
match module {
52+
Ok(Ok(_)) => Ok(()),
53+
Ok(Err(e)) => Err(e),
54+
Err(e) => Err(Error::Other(format!("failed to parse module: {:?}", e))),
55+
},
56+
);
4657
}
58+
// these all pass already :)
59+
AssertMalformed {
60+
span,
61+
module: QuoteWat::Wat(wast::Wat::Module(module)),
62+
message,
63+
} => {
64+
println!(" assert_malformed: {}", message);
65+
let res = std::panic::catch_unwind(|| parse_module(module).map(|_| ()));
66+
67+
test_group.add_result(
68+
&format!("{}-malformed", name),
69+
span,
70+
match res {
71+
Ok(Ok(_)) => Err(Error::Other("expected module to be malformed".to_string())),
72+
Err(_) | Ok(Err(_)) => Ok(()),
73+
},
74+
);
75+
}
76+
// _ => test_group.add_result(
77+
// &format!("{}-unknown", name),
78+
// span,
79+
// Err(Error::Other("test not implemented".to_string())),
80+
// ),
81+
// TODO: implement more test directives
4782
_ => {}
4883
}
4984
}
5085
});
5186

5287
if test_suite.failed() {
5388
panic!("failed one or more tests: {:#?}", test_suite);
89+
} else {
90+
println!("passed all tests: {:#?}", test_suite);
5491
}
5592
}
5693

57-
struct TestSuite(HashMap<String, TestGroup>);
94+
struct TestSuite(BTreeMap<String, TestGroup>);
5895

5996
impl TestSuite {
6097
fn new() -> Self {
61-
Self(HashMap::new())
98+
Self(BTreeMap::new())
6299
}
63100

64101
fn failed(&self) -> bool {
65-
self.0.values().any(|group| group.failed())
102+
self.0.values().any(|group| group.stats().1 > 0)
66103
}
67104

68105
fn test_group(&mut self, name: &str) -> &mut TestGroup {
@@ -73,49 +110,65 @@ impl TestSuite {
73110
impl Debug for TestSuite {
74111
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
75112
use owo_colors::OwoColorize;
76-
let mut passed_count = 0;
77-
let mut failed_count = 0;
113+
let mut total_passed = 0;
114+
let mut total_failed = 0;
78115

79116
for (group_name, group) in &self.0 {
117+
let (group_passed, group_failed) = group.stats();
118+
total_passed += group_passed;
119+
total_failed += group_failed;
120+
80121
writeln!(f, "{}", group_name.bold().underline())?;
81-
for (test_name, test) in &group.tests {
82-
writeln!(f, " {}", test_name.bold())?;
83-
match test.result {
84-
Ok(()) => {
85-
writeln!(f, " Result: {}", "Passed".green())?;
86-
passed_count += 1;
87-
}
88-
Err(_) => {
89-
writeln!(f, " Result: {}", "Failed".red())?;
90-
failed_count += 1;
91-
}
92-
}
93-
writeln!(f, " Span: {:?}", test.span)?;
94-
}
122+
writeln!(f, " Tests Passed: {}", group_passed.to_string().green())?;
123+
writeln!(f, " Tests Failed: {}", group_failed.to_string().red())?;
124+
125+
// for (test_name, test) in &group.tests {
126+
// write!(f, " {}: ", test_name.bold())?;
127+
// match &test.result {
128+
// Ok(()) => {
129+
// writeln!(f, "{}", "Passed".green())?;
130+
// }
131+
// Err(e) => {
132+
// writeln!(f, "{}", "Failed".red())?;
133+
// // writeln!(f, "Error: {:?}", e)?;
134+
// }
135+
// }
136+
// writeln!(f, " Span: {:?}", test.span)?;
137+
// }
95138
}
96139

97-
writeln!(f, "\n{}", "Test Summary:".bold().underline())?;
98-
writeln!(f, " Total Tests: {}", (passed_count + failed_count))?;
99-
writeln!(f, " Passed: {}", passed_count.to_string().green())?;
100-
writeln!(f, " Failed: {}", failed_count.to_string().red())?;
140+
writeln!(f, "\n{}", "Total Test Summary:".bold().underline())?;
141+
writeln!(f, " Total Tests: {}", (total_passed + total_failed))?;
142+
writeln!(f, " Total Passed: {}", total_passed.to_string().green())?;
143+
writeln!(f, " Total Failed: {}", total_failed.to_string().red())?;
101144
Ok(())
102145
}
103146
}
104147

105148
struct TestGroup {
106-
tests: HashMap<String, TestCase>,
149+
tests: BTreeMap<String, TestCase>,
107150
}
108151

109152
impl TestGroup {
110153
fn new() -> Self {
111-
Self { tests: HashMap::new() }
154+
Self { tests: BTreeMap::new() }
112155
}
113156

114-
fn failed(&self) -> bool {
115-
self.tests.values().any(|test| test.result.is_err())
157+
fn stats(&self) -> (usize, usize) {
158+
let mut passed_count = 0;
159+
let mut failed_count = 0;
160+
161+
for test in self.tests.values() {
162+
match test.result {
163+
Ok(()) => passed_count += 1,
164+
Err(_) => failed_count += 1,
165+
}
166+
}
167+
168+
(passed_count, failed_count)
116169
}
117170

118-
fn module_compiles(&mut self, name: &str, span: wast::token::Span, result: Result<()>) {
171+
fn add_result(&mut self, name: &str, span: wast::token::Span, result: Result<()>) {
119172
self.tests.insert(name.to_string(), TestCase { result, span });
120173
}
121174
}

0 commit comments

Comments
 (0)