@@ -168,6 +168,9 @@ impl Generator {
168168 let mut module = Module :: new ( & mod_name) ;
169169 module. attr ( "allow(unused_imports)" ) ;
170170 module. attr ( "allow(clippy::module_inception)" ) ;
171+ if self . curr_path . iter ( ) . any ( |s| s. contains ( "experimental" ) ) {
172+ module. attr ( r#"cfg(feature = "experimental")"# ) ;
173+ }
171174 module. import ( "super" , "*" ) ;
172175
173176 self . push_scope ( Some ( mod_name. clone ( ) ) ) ;
@@ -194,6 +197,9 @@ impl Generator {
194197 let mut module = Module :: new ( & mod_name. escape_module_name ( ) ) ;
195198 module. attr ( "allow(unused_imports)" ) ;
196199 module. attr ( "allow(clippy::module_inception)" ) ;
200+ if self . curr_path . iter ( ) . any ( |s| s. contains ( "experimental" ) ) {
201+ module. attr ( r#"cfg(feature = "experimental")"# ) ;
202+ }
197203 module. import ( "super" , "*" ) ;
198204
199205 self . push_scope ( Some ( mod_name. clone ( ) ) ) ;
@@ -216,6 +222,10 @@ impl Generator {
216222 let module = scope. new_module ( & mod_name. escape_module_name ( ) ) ;
217223 module. attr ( "allow(unused_imports)" ) ;
218224 module. attr ( "allow(clippy::module_inception)" ) ;
225+
226+ if self . curr_path . iter ( ) . any ( |s| s. contains ( "experimental" ) ) {
227+ module. attr ( r#"cfg(feature = "experimental")"# ) ;
228+ }
219229 module. import ( "super" , "*" ) ;
220230
221231 self . push_scope ( Some ( mod_name) ) ;
@@ -232,6 +242,10 @@ impl Generator {
232242 let module = scope. new_module ( & mod_name. escape_module_name ( ) ) ;
233243 module. attr ( "allow(unused_imports)" ) ;
234244 module. attr ( "allow(clippy::module_inception)" ) ;
245+
246+ if self . curr_path . iter ( ) . any ( |s| s. contains ( "experimental" ) ) {
247+ module. attr ( r#"cfg(feature = "experimental")"# ) ;
248+ }
235249 module. import ( "super" , "*" ) ;
236250
237251 self . push_scope ( Some ( mod_name) ) ;
@@ -328,6 +342,9 @@ impl Generator {
328342 let module = scope. new_module ( & mod_name. escape_module_name ( ) ) ;
329343 module. attr ( "allow(unused_imports)" ) ;
330344 module. import ( "super" , "*" ) ;
345+ if self . curr_path . iter ( ) . any ( |s| s. contains ( "experimental" ) ) {
346+ module. attr ( r#"cfg(feature = "experimental")"# ) ;
347+ }
331348
332349 self . push_scope ( Some ( mod_name. clone ( ) ) ) ;
333350 self . gen_variants ( module. scope ( ) , & namespace. contents ) ;
@@ -362,13 +379,16 @@ impl Generator {
362379 }
363380 }
364381
365- fn create_test < ' a > (
382+ fn create_test < F > (
366383 & mut self ,
367- scope : & ' a mut Scope ,
384+ scope : & mut Scope ,
368385 test_case : & TestCase ,
369386 name_prefix : Option < & str > ,
370387 needs_env : bool ,
371- ) -> & ' a mut Function {
388+ mut body : F ,
389+ ) where
390+ F : FnMut ( & mut Function ) ,
391+ {
372392 let bare_name = & test_case. name ;
373393 let prefixed_name = if let Some ( prefix) = name_prefix {
374394 format ! ( "{prefix}_{bare_name}" )
@@ -398,10 +418,9 @@ impl Generator {
398418 } else {
399419 quote ! { }
400420 } ;
401-
402421 test_fn. line ( escape_fn_code ( env) ) ;
403422
404- test_fn
423+ body ( test_fn)
405424 }
406425
407426 fn write_aside_expected ( & mut self , test_case : & TestCase , expected : String ) -> ( String , bool ) {
@@ -439,90 +458,105 @@ impl Generator {
439458 let test_case_expr =
440459 |gen : & dyn Fn ( & str ) -> _ | stmts. iter ( ) . map ( |s| gen ( s) ) . collect :: < Vec < _ > > ( ) ;
441460
442- fn mode_data ( eval_mode : & EvaluationMode ) -> ( & ' static str , TokenStream ) {
461+ fn mode_data ( eval_mode : & EvaluationMode ) -> ( & ' static str , & ' static str , TokenStream ) {
443462 match eval_mode {
444- EvaluationMode :: EvalModeError => ( "strict" , quote ! { EvaluationMode :: Error } ) ,
445- EvaluationMode :: EvalModeCoerce => ( "permissive" , quote ! { EvaluationMode :: Coerce } ) ,
463+ EvaluationMode :: EvalModeError => {
464+ ( "strict" , "strict" , quote ! { EvaluationMode :: Error } )
465+ }
466+ EvaluationMode :: EvalModeCoerce => (
467+ "permissive" ,
468+ "permissive" ,
469+ quote ! { EvaluationMode :: Coerce } ,
470+ ) ,
446471 }
447472 }
448473
449474 for assertion in & test_case. assert {
450475 match assertion {
451476 Assertion :: SyntaxSuccess ( _) => {
452- let test_fn = self . create_test ( scope, test_case, None , false ) ;
453- let stmts = test_case_expr ( & |stmt : & str | quote ! { pass_syntax( #stmt) ; } ) ;
454- test_fn. line ( escape_fn_code ( quote ! {
455- #( #stmts) *
456- } ) ) ;
477+ self . create_test ( scope, test_case, None , false , |test_fn| {
478+ test_fn. attr ( r#"cfg(feature = "syntax")"# ) ;
479+ let stmts = test_case_expr ( & |stmt : & str | quote ! { pass_syntax( #stmt) ; } ) ;
480+ test_fn. line ( escape_fn_code ( quote ! {
481+ #( #stmts) *
482+ } ) ) ;
483+ } )
457484 }
458485 Assertion :: SyntaxFail ( _) => {
459- let test_fn = self . create_test ( scope, test_case, None , false ) ;
460- let stmts = test_case_expr ( & |stmt : & str | quote ! { fail_syntax( #stmt) ; } ) ;
461- test_fn. line ( escape_fn_code ( quote ! {
462- #( #stmts) *
463- } ) ) ;
486+ self . create_test ( scope, test_case, None , false , |test_fn| {
487+ test_fn. attr ( r#"cfg(feature = "syntax")"# ) ;
488+ let stmts = test_case_expr ( & |stmt : & str | quote ! { fail_syntax( #stmt) ; } ) ;
489+ test_fn. line ( escape_fn_code ( quote ! {
490+ #( #stmts) *
491+ } ) ) ;
492+ } )
464493 }
465494 Assertion :: StaticAnalysisFail ( _) => {
466- let test_fn = self . create_test ( scope, test_case, None , false ) ;
467-
468- let stmts = test_case_expr ( & |stmt : & str | quote ! { fail_semantics( #stmt) ; } ) ;
469- test_fn. line ( escape_fn_code ( quote ! {
470- #( #stmts) *
471- } ) ) ;
495+ self . create_test ( scope, test_case, None , false , |test_fn| {
496+ test_fn. attr ( r#"cfg(feature = "semantics")"# ) ;
497+ let stmts = test_case_expr ( & |stmt : & str | quote ! { fail_semantics( #stmt) ; } ) ;
498+ test_fn. line ( escape_fn_code ( quote ! {
499+ #( #stmts) *
500+ } ) ) ;
501+ } )
472502 }
473503 Assertion :: EvaluationSuccess ( EvaluationSuccessAssertion {
474504 output,
475505 eval_mode,
476506 ..
477507 } ) => {
478508 for mode in eval_mode {
479- let ( prefix, mode) = mode_data ( mode) ;
480-
481- let test_fn = self . create_test ( scope, test_case, Some ( prefix) , true ) ;
482- test_fn. line ( "\n //**** evaluation success test case(s) ****//" ) ;
483-
509+ let ( prefix, feature, mode) = mode_data ( mode) ;
484510 let ( expected, is_file) =
485511 self . write_aside_expected ( test_case, elt_to_string ( output) ) ;
486- let expected = if is_file {
487- quote ! { include_str!( #expected) }
488- } else {
489- quote ! { #expected}
490- } ;
491-
492- // emit asserts for all statements
493- let stmts = test_case_expr ( & |stmt : & str | {
494- // emit PartiQL statement and evaluation mode assert
495- quote ! {
496- let stmt = #stmt;
497- pass_eval( stmt, #mode, & env, & expected) ;
498- }
499- } ) ;
500512
501- test_fn. line ( escape_fn_code ( quote ! {
502- let expected = #expected. into( ) ;
503- #( #stmts) *
504- } ) ) ;
513+ self . create_test ( scope, test_case, Some ( prefix) , true , |test_fn| {
514+ test_fn. attr ( & format ! ( r#"cfg(feature = "{feature}")"# ) ) ;
515+ test_fn. line ( "\n //**** evaluation success test case(s) ****//" ) ;
516+
517+ let expected = if is_file {
518+ quote ! { include_str!( #expected) }
519+ } else {
520+ quote ! { #expected}
521+ } ;
522+
523+ // emit asserts for all statements
524+ let stmts = test_case_expr ( & |stmt : & str | {
525+ // emit PartiQL statement and evaluation mode assert
526+ quote ! {
527+ let stmt = #stmt;
528+ pass_eval( stmt, #mode, & env, & expected) ;
529+ }
530+ } ) ;
531+
532+ test_fn. line ( escape_fn_code ( quote ! {
533+ let expected = #expected. into( ) ;
534+ #( #stmts) *
535+ } ) ) ;
536+ } ) ;
505537 }
506538 }
507539 Assertion :: EvaluationFail ( EvaluationFailAssertion { eval_mode, .. } ) => {
508540 for mode in eval_mode {
509- let ( prefix, mode) = mode_data ( mode) ;
510-
511- let test_fn = self . create_test ( scope, test_case, Some ( prefix) , true ) ;
512- test_fn. line ( "\n //**** evaluation failure test case(s) ****//" ) ;
513-
514- // emit asserts for all statements
515- let stmts = test_case_expr ( & |stmt : & str | {
516- // emit PartiQL statement and evaluation mode assert
517- quote ! {
518- let stmt = #stmt;
519- fail_eval( stmt, #mode, & env) ;
520- }
541+ let ( prefix, feature, mode) = mode_data ( mode) ;
542+
543+ self . create_test ( scope, test_case, Some ( prefix) , true , |test_fn| {
544+ test_fn. attr ( & format ! ( r#"cfg(feature = "{feature}")"# ) ) ;
545+ test_fn. line ( "\n //**** evaluation failure test case(s) ****//" ) ;
546+
547+ // emit asserts for all statements
548+ let stmts = test_case_expr ( & |stmt : & str | {
549+ // emit PartiQL statement and evaluation mode assert
550+ quote ! {
551+ let stmt = #stmt;
552+ fail_eval( stmt, #mode, & env) ;
553+ }
554+ } ) ;
555+
556+ test_fn. line ( escape_fn_code ( quote ! {
557+ #( #stmts) *
558+ } ) ) ;
521559 } ) ;
522-
523- test_fn. line ( escape_fn_code ( quote ! {
524- #( #stmts) *
525- } ) ) ;
526560 }
527561 }
528562 }
0 commit comments