diff options
Diffstat (limited to 'rola-utils/space-system/macros/src/space_root_test.rs')
| -rw-r--r-- | rola-utils/space-system/macros/src/space_root_test.rs | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/rola-utils/space-system/macros/src/space_root_test.rs b/rola-utils/space-system/macros/src/space_root_test.rs new file mode 100644 index 0000000..71c48c0 --- /dev/null +++ b/rola-utils/space-system/macros/src/space_root_test.rs @@ -0,0 +1,110 @@ +use proc_macro::TokenStream; +use quote::quote; +use syn::{ + DeriveInput, Token, + parse::{Parse, ParseStream}, + parse_macro_input, +}; + +/// Parsed content of `#[space_root_test_generic(...)]`. +struct GenericArgs { + types: Vec<syn::Type>, +} + +impl Parse for GenericArgs { + fn parse(input: ParseStream) -> syn::Result<Self> { + let mut types = Vec::new(); + if !input.is_empty() { + types.push(input.parse()?); + while !input.is_empty() { + let _: Token![,] = input.parse()?; + if !input.is_empty() { + types.push(input.parse()?); + } + } + } + Ok(GenericArgs { types }) + } +} + +pub(crate) fn internal_space_root_test_derive(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + + let name = &input.ident; + + // Extract generic args from `#[space_root_test_generic(...)]` + let generics = input + .attrs + .iter() + .find(|attr| attr.path().is_ident("space_root_test_generic")) + .and_then(|attr| attr.parse_args::<GenericArgs>().ok()) + .unwrap_or(GenericArgs { types: Vec::new() }); + + // Build the turbofish segment if there are generic args + let turbofish = if generics.types.is_empty() { + quote! {} + } else { + let params = &generics.types[..]; + quote! { ::< #(#params),* > } + }; + + let test_mod_name = syn::Ident::new( + &format!( + "test_{}_space_root", + just_fmt::snake_case!(name.to_string()) + ), + name.span(), + ); + + let expanded = quote! { + #[cfg(test)] + mod #test_mod_name { + use super::*; + use shared_functions::rola_test_sandbox; + use space_system::{Space, SpaceRoot, SpaceRootFindPattern}; + use std::env::set_current_dir; + + #[tokio::test] + async fn test_create_space() { + let sandbox = rola_test_sandbox(stringify!(#name)); + set_current_dir(&*sandbox).unwrap(); + + let mut space = Space::new(#name #turbofish ::default()); + + match #name #turbofish ::get_pattern() { + SpaceRootFindPattern::AbsolutePath(path_buf) => { + let dir = sandbox.join("root"); + println!("Redirect absolute path:"); + println!(" from: `{}`", path_buf.display()); + println!(" to: `{}`", dir.display()); + space.set_override_pattern(Some( + SpaceRootFindPattern::AbsolutePath(dir.clone()), + )); + + println!("Checking if {} absolute directory does not exist before initialization", stringify!(#name)); + assert!(!dir.exists()); + + space.init_here().await.unwrap(); + + println!("Checking if {} absolute directory exists after initialization", stringify!(#name)); + assert!(dir.exists()); + println!("\u{001b}[33;1mwarning\u{001b}[0m: Absolute path test completed in isolated environment, may not fully represent system runtime conditions"); + + return; + }, + _ => {} + } + + println!("Checking if {} does not exist before initialization", stringify!(#name)); + assert!(space.space_dir_current().is_err()); + + space.init_here().await.unwrap(); + + println!("Checking if {} exists after initialization", stringify!(#name)); + assert!(space.space_dir_current().is_ok()); + } + } + }; + + TokenStream::from(expanded) +} |
