use quote::quote;
use code_product_lib::*;
#[cfg(test)]
macro_rules! assert_expansion {
($expand_mode:ident {$($in:tt)*} == {$($out:tt)*}) => {
let input = quote! { $($in)* };
let output = expand_products(input, ScopeMode::$expand_mode);
let expected = quote! { $($out)* };
assert_eq!(output.to_string(), expected.to_string());
};
($($in:tt)*) => {
assert_expansion!(Expand {$($in)*} == {$($in)*});
};
(SubExpand $($in:tt)*) => {
assert_expansion!(SubExpand {$($in)*} == {$($in)*});
};
}
#[test]
fn smoke() {
assert_expansion! {
#[newtype]
pub struct MyNewtype<T>(T);
};
}
#[test]
fn expansion() {
assert_expansion! {
Expand {
$((a)(b)) $((c)(d)) $((e)(f)) ;
} == {
a c e ;
b c e ;
a d e ;
b d e ;
a c f ;
b c f ;
a d f ;
b d f ;
}
};
}
#[test]
fn nested_expansion() {
assert_expansion! {
Expand {
$((a)(b)) ${ $((c)(d)) $((e)(f)) } ;
} == {
a c e d e c f d f ;
b c e d e c f d f ;
}
};
}
#[test]
fn index_expansion() {
assert_expansion! {
Expand {
$((a)(b)) $0 ;
} == {
a a ;
b b ;
}
};
}
#[test]
fn name_expansion() {
assert_expansion! {
Expand {
$(foo: (a)(b)) $foo ;
} == {
a ;
b ;
}
};
}
#[test]
fn visible_name_expansion() {
assert_expansion! {
Expand {
$($foo: (a)(b)) $foo ;
} == {
a a ;
b b ;
}
};
}
#[test]
fn single_definition() {
assert_expansion! {
Expand {
$($foo: a b ) $foo ;
$foo ;
$(bar: c d) $bar ;
$bar ;
} == {
a b a b ;
a b ;
c d ;
c d ;
}
};
}
#[test]
fn syntax_example_named() {
assert_expansion! {
Expand {
$(Type: (This) (That))
impl Trait<$($T: (Foo)(Bar))> for $Type<$T> {}
} == {
impl Trait<Foo> for This<Foo> {}
impl Trait<Foo> for That<Foo> {}
impl Trait<Bar> for This<Bar> {}
impl Trait<Bar> for That<Bar> {}
}
};
}
#[test]
fn syntax_example_indexed() {
assert_expansion! {
Expand {
impl Trait<$((Foo)(Bar))> for $((This)(That))<$0> {}
} == {
impl Trait<Foo> for This<Foo> {}
impl Trait<Bar> for This<Bar> {}
impl Trait<Foo> for That<Foo> {}
impl Trait<Bar> for That<Bar> {}
}
};
}
#[test]
fn empty_linear_scope() {
assert_expansion! {
Expand {
$[]
} == {
}
};
}
#[test]
fn linear_scope() {
assert_expansion! {
Expand {
$[
$(name: (one)(two)(three))
$(number: (1)(2)(3))
$(xnumber: (1)(2)(3))
$name:$number ;
]
} == {
one:1 ;
two:2 ;
three:3 ;
}
};
}
#[test]
fn linear_scope_no_defs() {
assert_expansion! {
Expand {
$[
foobar ;
]
} == {
foobar ;
}
};
}
#[test]
#[should_panic]
fn linear_scope_len_error() {
assert_expansion! {
Expand {
$[
$(name: (one))
$(number: (1)(2))
]
} == {
}
};
}
#[test]
fn auto_brace_semi() {
assert_expansion! {
AutoBraceSemi {
$((First)(Second)) { }
$((Third)(Fourth)) ;
} == {
First { }
Second { }
Third ;
Fourth ;
}
};
}