summaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorHenry Gressmann <mail@henrygressmann.de>2023-12-10 13:35:13 +0100
committerHenry Gressmann <mail@henrygressmann.de>2023-12-10 13:35:13 +0100
commit52bebfac2e6a2dc934273e38230d3986e68a3fe3 (patch)
treead61563a281112266e8ab387261c6b2d35a40250 /crates
parent8eec592bba5279ec9213bfa1de816dc046748c0f (diff)
feat: move wasm core testsuite to a seperate crate
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
Diffstat (limited to 'crates')
-rw-r--r--crates/wasm-testsuite/Cargo.toml17
m---------crates/wasm-testsuite/data (renamed from crates/tinywasm/tests/spec/testsuite)0
-rw-r--r--crates/wasm-testsuite/lib.rs112
3 files changed, 129 insertions, 0 deletions
diff --git a/crates/wasm-testsuite/Cargo.toml b/crates/wasm-testsuite/Cargo.toml
new file mode 100644
index 0000000..1145b3c
--- /dev/null
+++ b/crates/wasm-testsuite/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+name="wasm-testsuite"
+version="0.0.1"
+description="Mirror of the WebAssembly core testsuite for use in testing WebAssembly implementations"
+edition.workspace=true
+license.workspace=true
+authors.workspace=true
+repository.workspace=true
+
+[lib]
+path="lib.rs"
+
+[package.metadata.workspaces]
+independent=true
+
+[dependencies]
+rust-embed={version="8.1.0", features=["include-exclude"]}
diff --git a/crates/tinywasm/tests/spec/testsuite b/crates/wasm-testsuite/data
-Subproject dc27dad3e34e466bdbfea32fe3c73f5e31f8856
+Subproject dc27dad3e34e466bdbfea32fe3c73f5e31f8856
diff --git a/crates/wasm-testsuite/lib.rs b/crates/wasm-testsuite/lib.rs
new file mode 100644
index 0000000..102389a
--- /dev/null
+++ b/crates/wasm-testsuite/lib.rs
@@ -0,0 +1,112 @@
+//! This crate provides a way to access the WebAssembly spec testsuite.
+//!
+//! The testsuite is included as a git submodule and embedded into the binary.
+//!
+//! Generated from https://github.com/WebAssembly/testsuite
+
+#![forbid(unsafe_code)]
+#![doc(test(
+ no_crate_inject,
+ attr(
+ deny(warnings, rust_2018_idioms),
+ allow(dead_code, unused_assignments, unused_variables)
+ )
+))]
+#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms, unreachable_pub)]
+
+use rust_embed::RustEmbed;
+use std::borrow::Cow;
+
+#[derive(RustEmbed)]
+#[folder = "data/"]
+#[include = "*.wast"]
+struct Asset;
+
+/// List of all proposals.
+/// This list is generated from the `proposals` folder in https://github.com/WebAssembly/testsuite
+#[rustfmt::skip]
+pub const PROPOSALS: &[&str] = &["annotations", "exception-handling", "memory64", "function-references", "multi-memory", "relaxed-simd", "tail-call", "threads", "extended-const", "gc"];
+
+/// Get all test file names and their contents.
+///
+/// Proposals can be filtered by passing a list of proposal names.
+/// Valid proposal names are listed in [`PROPOSALS`].
+/// Returns an iterator over tuples of the form `(test_name, test_data)`.
+/// test_name is the name of the test file and the proposal name (if any), e.g. `annotations/br.wast`.
+pub fn get_tests(include_proposals: &[String]) -> impl Iterator<Item = (String, Cow<'static, [u8]>)> {
+ let include_proposals = include_proposals.to_vec();
+
+ Asset::iter().filter_map(move |x| {
+ let mut parts = x.split('/');
+ match parts.next() {
+ Some("proposals") => {
+ let proposal = parts.next();
+ let test_name = parts.next().unwrap_or_default();
+
+ if proposal.map_or(false, |p| include_proposals.contains(&p.to_string())) {
+ let full_path = format!("{}/{}", proposal.unwrap_or_default(), test_name);
+ let data = Asset::get(&x).unwrap().data;
+ Some((full_path, data))
+ } else {
+ None
+ }
+ }
+ Some(test_name) => {
+ let data = Asset::get(&x).unwrap().data;
+ Some((test_name.to_owned(), data))
+ }
+ None => None,
+ }
+ })
+}
+
+/// Get the WAST file as a byte slice.
+///
+/// # Examples
+/// proposals: {proposal}/{test_name}.wast
+/// tests: {test_name}.wast
+pub fn get_wast(name: &str) -> Option<Cow<'_, [u8]>> {
+ if !name.ends_with(".wast") {
+ panic!("Expected .wast file. Got: {}", name);
+ }
+
+ match name.contains('/') {
+ true => Asset::get(&format!("proposals/{}", name)).map(|x| x.data),
+ false => Asset::get(name).map(|x| x.data),
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use std::collections::HashSet;
+
+ use super::*;
+
+ #[test]
+ fn test_proposals() {
+ let mut unique_proposals = HashSet::new();
+
+ // check that all proposals are present
+ for proposal in Asset::iter() {
+ if !proposal.starts_with("proposals/") {
+ continue;
+ }
+
+ let proposal = proposal.split('/').nth(1).unwrap();
+ unique_proposals.insert(proposal.to_owned());
+ // assert!(PROPOSALS.contains(&proposal));
+ }
+ println!("{:?}", unique_proposals);
+ }
+
+ #[test]
+ fn test_get_tests() {
+ let tests = get_tests(&["annotations".to_owned()]);
+ let tests: Vec<_> = tests.collect();
+ println!("{:?}", tests.iter().map(|(name, _)| name).collect::<Vec<_>>());
+
+ // for (name, data) in tests {
+ // println!("{}: {}", name, data.len());
+ // }
+ }
+}