winch: Adding support for integration tests (#5588)
* Adding in the foundations for Winch `filetests` This commit adds two new crates into the Winch workspace: `filetests` and `test-macros`. The intent is to mimic the structure of Cranelift `filetests`, but in a simpler way. * Updates to documentation This commits adds a high level document to outline how to test Winch through the `winch-tools` utility. It also updates some inline documentation which gets propagated to the CLI. * Updating test-macro to use a glob instead of only a flat directory
This commit is contained in:
82
winch/test-macros/src/lib.rs
Normal file
82
winch/test-macros/src/lib.rs
Normal file
@@ -0,0 +1,82 @@
|
||||
extern crate proc_macro;
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use glob::glob;
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::ItemFn;
|
||||
|
||||
fn get_test_name_for_root(root: &Path, path: &Path) -> String {
|
||||
let test_name = path
|
||||
.strip_prefix(root)
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.replace("/", "_")
|
||||
.replace("\\", "_")
|
||||
.replace(".wat", "");
|
||||
|
||||
format!("winch_filetests_{}", test_name)
|
||||
}
|
||||
|
||||
/// Generate a test case for every .wat file in the filetests directory.
|
||||
/// This should only be used from the filetests crate.
|
||||
#[proc_macro_attribute]
|
||||
pub fn generate_file_tests(_attr: TokenStream, input: TokenStream) -> TokenStream {
|
||||
// Parse the input as a function.
|
||||
let input = proc_macro2::TokenStream::from(input);
|
||||
|
||||
let fn_ast: ItemFn =
|
||||
syn::parse(input.clone().into()).expect("Failed to parse tokens as function");
|
||||
|
||||
// Get the function's name and body.
|
||||
let name = &fn_ast.sig.ident;
|
||||
|
||||
let filetests_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("../filetests/filetests");
|
||||
|
||||
let test_file_entries = glob(format!("{}/**/*.wat", filetests_dir.to_str().unwrap()).as_str())
|
||||
.expect("Failed to read glob pattern");
|
||||
|
||||
// Create a list of test cases by opening every .wat file in the directory.
|
||||
let test_cases = test_file_entries.map(|entry| {
|
||||
let path = entry.expect("Failed to read glob entry");
|
||||
|
||||
let full = path.to_str().expect("Path for file was empty");
|
||||
|
||||
let test_name = proc_macro2::Ident::new(
|
||||
&get_test_name_for_root(&filetests_dir, &path),
|
||||
proc_macro2::Span::call_site(),
|
||||
);
|
||||
quote! {
|
||||
#[test]
|
||||
fn #test_name() {
|
||||
#name(#full);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Assemble the output by combining the function and test cases.
|
||||
let output = quote! {
|
||||
#input
|
||||
|
||||
#(#test_cases)*
|
||||
};
|
||||
|
||||
output.into()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_get_test_name_for_root_unix() {
|
||||
let root = Path::new("/home/user/Documents/winch/filetests/filetests");
|
||||
let path = Path::new("/home/user/Documents/winch/filetests/filetests/simd/simple.wat");
|
||||
|
||||
let test_name = get_test_name_for_root(root, path);
|
||||
|
||||
assert_eq!(test_name, "winch_filetests_simd_simple");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user