feat: update workspace paths and enhance gitignore
- Updated stablediffusion crate path from "../stable-diffusion-burn" to "./crates/stable-diffusion-burn" for proper workspace resolution - Enhanced .gitignore to include generated model files (.mpk, .pt, .bin, .safetensors, .ckpt) and user_data directory - Added Cargo.lock to gitignore with appropriate comment - Reorganized IDE files section in gitignore for better clarity - Added newline at end of file for proper formatting
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
[package]
|
||||
authors = ["nathanielsimard <nathaniel.simard.42@gmail.com>"]
|
||||
description = "Test generation crate for burn-tensor"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
name = "burn-tensor-testgen"
|
||||
readme.workspace = true
|
||||
repository = "https://github.com/tracel-ai/burn/tree/main/crates/burn-tensor-testgen"
|
||||
version.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = { workspace = true }
|
||||
quote = { workspace = true }
|
||||
syn = { workspace = true }
|
||||
@@ -0,0 +1 @@
|
||||
../../LICENSE-APACHE
|
||||
@@ -0,0 +1 @@
|
||||
../../LICENSE-MIT
|
||||
@@ -0,0 +1,6 @@
|
||||
# Burn Tensor Test Generation
|
||||
|
||||
> [Burn](https://github.com/tracel-ai/burn) tensor test generation
|
||||
|
||||
[](https://crates.io/crates/burn-tensor-testgen)
|
||||
[](https://github.com/tracel-ai/burn-tensor-testgen/blob/master/README.md)
|
||||
@@ -0,0 +1,130 @@
|
||||
use proc_macro::TokenStream;
|
||||
use quote::{format_ident, quote};
|
||||
|
||||
use syn::parse::{Parse, ParseStream};
|
||||
use syn::punctuated::Punctuated;
|
||||
use syn::token::Comma;
|
||||
use syn::{Attribute, Expr, ItemFn, Lit, Meta, MetaNameValue, parse_macro_input};
|
||||
|
||||
// Define a structure to parse the attribute arguments
|
||||
struct AttributeArgs {
|
||||
args: Punctuated<Meta, Comma>,
|
||||
}
|
||||
|
||||
impl Parse for AttributeArgs {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
Ok(AttributeArgs {
|
||||
args: Punctuated::parse_terminated(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::test_attr_in_doctest)]
|
||||
/// **This is only meaningful when the `reason` is specific and clear.**
|
||||
///
|
||||
/// A proc macro attribute that adds panic handling to test functions.
|
||||
///
|
||||
/// # Usage
|
||||
/// ```rust, ignore
|
||||
/// #[might_panic(reason = "expected panic message prefix")]
|
||||
/// #[test]
|
||||
/// fn test_that_might_panic() {
|
||||
/// // test code that might panic (with acceptable reason)
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// # Behavior
|
||||
/// - If the test does not panic, it passes.
|
||||
/// - If the test panics with a message starting with the expected prefix, the failure is ignored.
|
||||
/// - If the test panics with a different message, the test fails.
|
||||
///
|
||||
/// # Note
|
||||
/// This proc macro uses [`std::panic::catch_unwind`]. As such, it does not work in a no-std environment.
|
||||
/// Make sure it is feature gated when an `"std"` feature is available.
|
||||
#[proc_macro_attribute]
|
||||
pub fn might_panic(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
// Parse the attribute arguments
|
||||
let args = parse_macro_input!(args as AttributeArgs);
|
||||
let input_fn = parse_macro_input!(input as ItemFn);
|
||||
|
||||
// Extract the expected panic reason
|
||||
let mut expected_reason = None;
|
||||
for arg in args.args.iter() {
|
||||
if let Meta::NameValue(MetaNameValue { path, value, .. }) = arg
|
||||
&& path.is_ident("reason")
|
||||
&& let Expr::Lit(lit) = value
|
||||
&& let Lit::Str(ref lit_str) = lit.lit
|
||||
{
|
||||
expected_reason = Some(lit_str.value());
|
||||
}
|
||||
}
|
||||
|
||||
let expected_reason = match expected_reason {
|
||||
Some(reason) => reason,
|
||||
None => {
|
||||
return syn::Error::new(
|
||||
proc_macro2::Span::call_site(),
|
||||
"The #[might_panic] attribute requires a 'reason' parameter",
|
||||
)
|
||||
.to_compile_error()
|
||||
.into();
|
||||
}
|
||||
};
|
||||
|
||||
let fn_name = &input_fn.sig.ident;
|
||||
let fn_vis = &input_fn.vis;
|
||||
let fn_generics = &input_fn.sig.generics;
|
||||
let fn_block = &input_fn.block;
|
||||
let fn_attrs = input_fn
|
||||
.attrs
|
||||
.iter()
|
||||
.filter(|attr| !attr.path().is_ident("test"))
|
||||
.collect::<Vec<&Attribute>>();
|
||||
|
||||
// Create a wrapped test function
|
||||
let wrapper_name = format_ident!("{}_might_panic", fn_name);
|
||||
|
||||
let expanded = quote! {
|
||||
#(#fn_attrs)*
|
||||
#fn_vis fn #fn_name #fn_generics() {
|
||||
#fn_block
|
||||
}
|
||||
|
||||
#[test]
|
||||
#fn_vis fn #wrapper_name #fn_generics() {
|
||||
use std::panic::{self, AssertUnwindSafe};
|
||||
|
||||
let expected_reason = #expected_reason;
|
||||
let result = panic::catch_unwind(AssertUnwindSafe(|| {
|
||||
#fn_name();
|
||||
}));
|
||||
|
||||
match result {
|
||||
Ok(_) => {
|
||||
// Test passed without panic - this is OK
|
||||
}
|
||||
Err(e) => {
|
||||
// Convert the panic payload to a string
|
||||
let panic_msg = if let Some(s) = e.downcast_ref::<String>() {
|
||||
s.to_string()
|
||||
} else if let Some(s) = e.downcast_ref::<&str>() {
|
||||
s.to_string()
|
||||
} else {
|
||||
"Unknown panic".to_string()
|
||||
};
|
||||
|
||||
// Check if the panic message starts with the expected reason
|
||||
if !panic_msg.starts_with(expected_reason) {
|
||||
panic!(
|
||||
"Test '{}' marked as 'might_panic' failed. Expected reason: '{}'",
|
||||
stringify!(#fn_name),
|
||||
expected_reason
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
expanded.into()
|
||||
}
|
||||
Reference in New Issue
Block a user