@@ -3,12 +3,20 @@ mod utils;
33use darling:: ast:: NestedMeta ;
44use darling:: { Error , FromMeta } ;
55use proc_macro:: TokenStream ;
6- use quote:: { format_ident , quote} ;
7- use syn:: { parse_macro_input, parse_quote, Item } ;
6+ use quote:: quote;
7+ use syn:: { parse_macro_input, parse_quote, Ident , Item } ;
88
99fn plugin_timeout_secs_default ( ) -> u64 {
1010 5
1111}
12+
13+ fn parse_attrs < T : FromMeta > ( attr : TokenStream ) -> Result < T , TokenStream > {
14+ NestedMeta :: parse_meta_list ( attr. into ( ) )
15+ . map_err ( Error :: from)
16+ . and_then ( |attr| T :: from_list ( & attr) )
17+ . map_err ( |e| TokenStream :: from ( e. write_errors ( ) ) )
18+ }
19+
1220#[ derive( Debug , FromMeta ) ]
1321struct PluginCfg {
1422 path : Option < String > ,
@@ -19,19 +27,9 @@ struct PluginCfg {
1927#[ proc_macro_attribute]
2028pub fn picotest ( attr : TokenStream , item : TokenStream ) -> TokenStream {
2129 let input = parse_macro_input ! ( item as Item ) ;
22-
23- let attr = match NestedMeta :: parse_meta_list ( attr. into ( ) ) {
24- Ok ( v) => v,
25- Err ( e) => {
26- return TokenStream :: from ( Error :: from ( e) . write_errors ( ) ) ;
27- }
28- } ;
29-
30- let cfg = match PluginCfg :: from_list ( & attr) {
31- Ok ( v) => v,
32- Err ( e) => {
33- return TokenStream :: from ( e. write_errors ( ) ) ;
34- }
30+ let cfg: PluginCfg = match parse_attrs ( attr) {
31+ Ok ( cfg) => cfg,
32+ Err ( err) => return err,
3533 } ;
3634
3735 let path = cfg. path ;
@@ -69,6 +67,8 @@ pub fn picotest(attr: TokenStream, item: TokenStream) -> TokenStream {
6967 TokenStream :: from ( quote ! ( #input) )
7068}
7169
70+ static UNIT_COUNTER : std:: sync:: atomic:: AtomicUsize = std:: sync:: atomic:: AtomicUsize :: new ( 1 ) ;
71+
7272#[ proc_macro_attribute]
7373pub fn picotest_unit ( _: TokenStream , tokens : TokenStream ) -> TokenStream {
7474 match parse_macro_input ! ( tokens as Item ) {
@@ -87,7 +87,13 @@ pub fn picotest_unit(_: TokenStream, tokens: TokenStream) -> TokenStream {
8787 // Create test runner - it's a wrapper around main test function.
8888 // This wrapper will call main test routine in a Lua runtime running
8989 // inside picodata instance.
90- let test_runner_ident = format_ident ! ( "{}_" , test_fn. sig. ident) ;
90+ let test_runner_ident = test_fn. sig . ident . clone ( ) ;
91+
92+ // Name of the function to be invoked on instance-side as test payload
93+ let test_idx = UNIT_COUNTER . fetch_add ( 1 , std:: sync:: atomic:: Ordering :: Acquire ) ;
94+ let ffi_test_callable = format ! ( "test_impl_{test_idx}_{test_fn_name}" ) ;
95+ test_fn. sig . ident = Ident :: new ( & ffi_test_callable, test_fn. sig . ident . span ( ) ) ;
96+
9197 let test_runner = quote ! {
9298 #[ test]
9399 fn #test_runner_ident( ) {
@@ -100,7 +106,7 @@ pub fn picotest_unit(_: TokenStream, tokens: TokenStream) -> TokenStream {
100106
101107 let call_test_fn_query =
102108 internal:: lua_ffi_call_unit_test(
103- #test_fn_name , plugin_dylib_path. to_str( ) . unwrap( ) ) ;
109+ #ffi_test_callable , plugin_dylib_path. to_str( ) . unwrap( ) ) ;
104110
105111 let cluster = picotest:: get_or_create_session_cluster(
106112 plugin_path. to_str( ) . unwrap( ) . into( ) ,
0 commit comments