|
| 1 | +//! This crate provides a way to access the WebAssembly spec testsuite. |
| 2 | +//! |
| 3 | +//! The testsuite is included as a git submodule and embedded into the binary. |
| 4 | +//! |
| 5 | +//! Generated from https://github.com/WebAssembly/testsuite |
| 6 | +
|
| 7 | +#![forbid(unsafe_code)] |
| 8 | +#![doc(test( |
| 9 | + no_crate_inject, |
| 10 | + attr( |
| 11 | + deny(warnings, rust_2018_idioms), |
| 12 | + allow(dead_code, unused_assignments, unused_variables) |
| 13 | + ) |
| 14 | +))] |
| 15 | +#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms, unreachable_pub)] |
| 16 | + |
| 17 | +use rust_embed::RustEmbed; |
| 18 | +use std::borrow::Cow; |
| 19 | + |
| 20 | +#[derive(RustEmbed)] |
| 21 | +#[folder = "data/"] |
| 22 | +#[include = "*.wast"] |
| 23 | +struct Asset; |
| 24 | + |
| 25 | +/// List of all proposals. |
| 26 | +/// This list is generated from the `proposals` folder in https://github.com/WebAssembly/testsuite |
| 27 | +#[rustfmt::skip] |
| 28 | +pub const PROPOSALS: &[&str] = &["annotations", "exception-handling", "memory64", "function-references", "multi-memory", "relaxed-simd", "tail-call", "threads", "extended-const", "gc"]; |
| 29 | + |
| 30 | +/// Get all test file names and their contents. |
| 31 | +/// |
| 32 | +/// Proposals can be filtered by passing a list of proposal names. |
| 33 | +/// Valid proposal names are listed in [`PROPOSALS`]. |
| 34 | +/// Returns an iterator over tuples of the form `(test_name, test_data)`. |
| 35 | +/// test_name is the name of the test file and the proposal name (if any), e.g. `annotations/br.wast`. |
| 36 | +pub fn get_tests(include_proposals: &[String]) -> impl Iterator<Item = (String, Cow<'static, [u8]>)> { |
| 37 | + let include_proposals = include_proposals.to_vec(); |
| 38 | + |
| 39 | + Asset::iter().filter_map(move |x| { |
| 40 | + let mut parts = x.split('/'); |
| 41 | + match parts.next() { |
| 42 | + Some("proposals") => { |
| 43 | + let proposal = parts.next(); |
| 44 | + let test_name = parts.next().unwrap_or_default(); |
| 45 | + |
| 46 | + if proposal.map_or(false, |p| include_proposals.contains(&p.to_string())) { |
| 47 | + let full_path = format!("{}/{}", proposal.unwrap_or_default(), test_name); |
| 48 | + let data = Asset::get(&x).unwrap().data; |
| 49 | + Some((full_path, data)) |
| 50 | + } else { |
| 51 | + None |
| 52 | + } |
| 53 | + } |
| 54 | + Some(test_name) => { |
| 55 | + let data = Asset::get(&x).unwrap().data; |
| 56 | + Some((test_name.to_owned(), data)) |
| 57 | + } |
| 58 | + None => None, |
| 59 | + } |
| 60 | + }) |
| 61 | +} |
| 62 | + |
| 63 | +/// Get the WAST file as a byte slice. |
| 64 | +/// |
| 65 | +/// # Examples |
| 66 | +/// proposals: {proposal}/{test_name}.wast |
| 67 | +/// tests: {test_name}.wast |
| 68 | +pub fn get_wast(name: &str) -> Option<Cow<'_, [u8]>> { |
| 69 | + if !name.ends_with(".wast") { |
| 70 | + panic!("Expected .wast file. Got: {}", name); |
| 71 | + } |
| 72 | + |
| 73 | + match name.contains('/') { |
| 74 | + true => Asset::get(&format!("proposals/{}", name)).map(|x| x.data), |
| 75 | + false => Asset::get(name).map(|x| x.data), |
| 76 | + } |
| 77 | +} |
| 78 | + |
| 79 | +#[cfg(test)] |
| 80 | +mod tests { |
| 81 | + use std::collections::HashSet; |
| 82 | + |
| 83 | + use super::*; |
| 84 | + |
| 85 | + #[test] |
| 86 | + fn test_proposals() { |
| 87 | + let mut unique_proposals = HashSet::new(); |
| 88 | + |
| 89 | + // check that all proposals are present |
| 90 | + for proposal in Asset::iter() { |
| 91 | + if !proposal.starts_with("proposals/") { |
| 92 | + continue; |
| 93 | + } |
| 94 | + |
| 95 | + let proposal = proposal.split('/').nth(1).unwrap(); |
| 96 | + unique_proposals.insert(proposal.to_owned()); |
| 97 | + // assert!(PROPOSALS.contains(&proposal)); |
| 98 | + } |
| 99 | + println!("{:?}", unique_proposals); |
| 100 | + } |
| 101 | + |
| 102 | + #[test] |
| 103 | + fn test_get_tests() { |
| 104 | + let tests = get_tests(&["annotations".to_owned()]); |
| 105 | + let tests: Vec<_> = tests.collect(); |
| 106 | + println!("{:?}", tests.iter().map(|(name, _)| name).collect::<Vec<_>>()); |
| 107 | + |
| 108 | + // for (name, data) in tests { |
| 109 | + // println!("{}: {}", name, data.len()); |
| 110 | + // } |
| 111 | + } |
| 112 | +} |
0 commit comments