1mod fixture;
2mod test;
3mod utils;
4
5use fixture::{FixtureAttr, fixture_impl};
6use proc_macro::TokenStream;
7use quote::quote;
8use std::sync::atomic::Ordering;
9use syn::{ItemFn, parse_macro_input};
10use test::{TEST_COUNT, TestAttr, test_impl};
11
12#[proc_macro_attribute]
13pub fn test(args: TokenStream, input: TokenStream) -> TokenStream {
14 let input = parse_macro_input!(input as ItemFn);
15 let args = parse_macro_input!(args as TestAttr);
16 match test_impl(args, input) {
17 Ok(output) => output,
18 Err(output) => output,
19 }
20 .into()
21}
22
23#[proc_macro_attribute]
24pub fn fixture(args: TokenStream, input: TokenStream) -> TokenStream {
25 let input = parse_macro_input!(input as ItemFn);
26 let args = parse_macro_input!(args as FixtureAttr);
27 match fixture_impl(args, input) {
28 Ok(output) => output,
29 Err(output) => output,
30 }
31 .into()
32}
33
34#[proc_macro_attribute]
35pub fn main(_args: TokenStream, _input: TokenStream) -> TokenStream {
36 let test_count = TEST_COUNT.load(Ordering::Relaxed);
37 (quote! {
38 static mut TEST_GENERATORS: [Option<::rustest::TestGeneratorFn>; #test_count] = [None; #test_count];
39
40 fn main() -> std::process::ExitCode {
41 let test_registers = unsafe { TEST_GENERATORS.iter().map(|r| r.expect("Slot should be filled")).collect::<Vec<_>>() };
44 ::rustest::run_tests(&test_registers)
45 }
46 })
47 .into()
48}