aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2021-03-05 17:43:16 +0100
committerGustav Sörnäs <gustav@sornas.net>2021-03-05 17:43:16 +0100
commitba2a7b3290102e3573cc7b2727026f4efe8a1d9f (patch)
tree251cafe70c1d5c106f85668967af95f2b82b3bde
parent9a0967033eb63d5b974fa286468c0883c3314205 (diff)
downloadsylt-ba2a7b3290102e3573cc7b2727026f4efe8a1d9f.tar.gz
macro that generates tests from files
-rw-r--r--src/lib.rs2
-rw-r--r--sylt_macro/src/lib.rs46
2 files changed, 46 insertions, 2 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 76486dd..ee5f9c4 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -918,6 +918,8 @@ mod tests {
};
}
+ sylt_macro::find_tests!();
+
#[test]
fn unreachable_token() {
assert_errs!(run_string("<!>\n", true, Vec::new()), [ErrorKind::Unreachable]);
diff --git a/sylt_macro/src/lib.rs b/sylt_macro/src/lib.rs
index 3b8b37c..0f1a584 100644
--- a/sylt_macro/src/lib.rs
+++ b/sylt_macro/src/lib.rs
@@ -1,5 +1,7 @@
+use std::path::{Path, PathBuf};
+
use proc_macro::TokenStream;
-use quote::quote;
+use quote::{format_ident, quote};
use syn::{Expr, Pat, Token, parse::{Parse, ParseStream, Result}, parse_macro_input};
struct ExternBlock {
@@ -137,7 +139,6 @@ impl Parse for Links {
}
}
-
#[proc_macro]
pub fn link(tokens: TokenStream) -> TokenStream {
let links: Links = parse_macro_input!(tokens);
@@ -159,3 +160,44 @@ pub fn link(tokens: TokenStream) -> TokenStream {
};
TokenStream::from(tokens)
}
+
+fn find_test_paths(directory: &Path) -> Vec<PathBuf> {
+ let mut tests = Vec::new();
+
+ for entry in std::fs::read_dir(directory).unwrap() {
+ let path = entry.unwrap().path();
+ let file_name = path.file_name().unwrap().to_str().unwrap();
+
+ if file_name.starts_with("_") {
+ continue;
+ }
+
+ if path.is_dir() {
+ tests.append(&mut find_test_paths(&path));
+ } else {
+ assert!(!path.to_str().unwrap().contains(","), "You should be ashamed.");
+ tests.push(path);
+ }
+ }
+
+ tests
+}
+
+#[proc_macro]
+pub fn find_tests(tokens: TokenStream) -> TokenStream {
+ assert!(tokens.is_empty());
+
+ let tests: Vec<_> = find_test_paths(Path::new("progs/")).iter().map(|path| {
+ let path = path.to_str().unwrap();
+ let test_name = format_ident!("{}", path.replace("/", "_").replace(".sy", ""));
+ quote! {
+ test_file!(#test_name, #path);
+ }
+ }).collect();
+
+ let tokens = quote! {
+ #(#tests)*
+ };
+
+ TokenStream::from(tokens)
+}