@@ -20,8 +20,8 @@ use crate::{
2020 } ,
2121 generated:: ast_nodes:: { AstNode , AstNodes } ,
2222 utils:: {
23- is_long_curried_call , member_chain :: simple_argument :: SimpleArgument ,
24- write_arguments_multi_line,
23+ call_expression :: is_test_call_expression , is_long_curried_call ,
24+ member_chain :: simple_argument :: SimpleArgument , write_arguments_multi_line,
2525 } ,
2626 write,
2727 write:: {
@@ -981,190 +981,3 @@ fn is_react_hook_with_deps_array(
981981 _ => false ,
982982 }
983983}
984-
985- /// This is a specialized function that checks if the current [call expression]
986- /// resembles a call expression usually used by a testing frameworks.
987- ///
988- /// If the [call expression] matches the criteria, a different formatting is applied.
989- ///
990- /// To evaluate the eligibility of a [call expression] to be a test framework like,
991- /// we need to check its [callee] and its [arguments].
992- ///
993- /// 1. The [callee] must contain a name or a chain of names that belongs to the
994- /// test frameworks, for example: `test()`, `test.only()`, etc.
995- /// 2. The [arguments] should be at the least 2
996- /// 3. The first argument has to be a string literal
997- /// 4. The third argument, if present, has to be a number literal
998- /// 5. The second argument has to be an [arrow function expression] or [function expression]
999- /// 6. Both function must have zero or one parameters
1000- ///
1001- /// [call expression]: CallExpression
1002- /// [callee]: Expression
1003- /// [arguments]: CallExpression::arguments
1004- /// [arrow function expression]: ArrowFunctionExpression
1005- /// [function expression]: Function
1006- pub fn is_test_call_expression ( call : & AstNode < CallExpression < ' _ > > ) -> bool {
1007- let callee = & call. callee ;
1008- let arguments = & call. arguments ;
1009-
1010- let mut args = arguments. iter ( ) ;
1011-
1012- match ( args. next ( ) , args. next ( ) , args. next ( ) ) {
1013- ( Some ( argument) , None , None ) if arguments. len ( ) == 1 => {
1014- if is_angular_test_wrapper ( call) && {
1015- if let AstNodes :: CallExpression ( call) = call. parent . parent ( ) {
1016- is_test_call_expression ( call)
1017- } else {
1018- false
1019- }
1020- } {
1021- return matches ! (
1022- argument,
1023- Argument :: ArrowFunctionExpression ( _) | Argument :: FunctionExpression ( _)
1024- ) ;
1025- }
1026-
1027- if is_unit_test_set_up_callee ( callee) {
1028- return argument. as_expression ( ) . is_some_and ( is_angular_test_wrapper_expression) ;
1029- }
1030-
1031- false
1032- }
1033-
1034- // it("description", ..)
1035- // it(Test.name, ..)
1036- ( _, Some ( second) , third) if arguments. len ( ) <= 3 && contains_a_test_pattern ( callee) => {
1037- // it('name', callback, duration)
1038- if !matches ! ( third, None | Some ( Argument :: NumericLiteral ( _) ) ) {
1039- return false ;
1040- }
1041-
1042- if second. as_expression ( ) . is_some_and ( is_angular_test_wrapper_expression) {
1043- return true ;
1044- }
1045-
1046- let ( parameter_count, has_block_body) = match second {
1047- Argument :: FunctionExpression ( function) => {
1048- ( function. params . parameters_count ( ) , true )
1049- }
1050- Argument :: ArrowFunctionExpression ( arrow) => {
1051- ( arrow. params . parameters_count ( ) , !arrow. expression )
1052- }
1053- _ => return false ,
1054- } ;
1055-
1056- parameter_count == 2 || ( parameter_count <= 1 && has_block_body)
1057- }
1058- _ => false ,
1059- }
1060- }
1061-
1062- /// Note: `inject` is used in AngularJS 1.x, `async` and `fakeAsync` in
1063- /// Angular 2+, although `async` is deprecated and replaced by `waitForAsync`
1064- /// since Angular 12.
1065- ///
1066- /// example: <https://docs.angularjs.org/guide/unit-testing#using-beforeall->
1067- ///
1068- /// @param {CallExpression} node
1069- /// @returns {boolean}
1070- ///
1071- fn is_angular_test_wrapper_expression ( expression : & Expression ) -> bool {
1072- matches ! ( expression, Expression :: CallExpression ( call) if is_angular_test_wrapper( call) )
1073- }
1074-
1075- fn is_angular_test_wrapper ( call : & CallExpression ) -> bool {
1076- matches ! ( & call. callee,
1077- Expression :: Identifier ( ident) if
1078- matches!( ident. name. as_str( ) , "async" | "inject" | "fakeAsync" | "waitForAsync" )
1079- )
1080- }
1081-
1082- /// Tests if the callee is a `beforeEach`, `beforeAll`, `afterEach` or `afterAll` identifier
1083- /// that is commonly used in test frameworks.
1084- fn is_unit_test_set_up_callee ( callee : & Expression ) -> bool {
1085- matches ! ( callee, Expression :: Identifier ( ident) if {
1086- matches!( ident. name. as_str( ) , "beforeEach" | "beforeAll" | "afterEach" | "afterAll" )
1087- } )
1088- }
1089-
1090- /// Iterator that returns the callee names in "top down order".
1091- ///
1092- /// # Examples
1093- ///
1094- /// ```javascript
1095- /// it.only() -> [`only`, `it`]
1096- /// ```
1097- ///
1098- /// Same as <https://github.com/biomejs/biome/blob/4a5ef84930344ae54f3877da36888a954711f4a6/crates/biome_js_syntax/src/expr_ext.rs#L1402-L1438>.
1099- pub fn callee_name_iterator < ' b > ( expr : & ' b Expression < ' _ > ) -> impl Iterator < Item = & ' b str > {
1100- let mut current = Some ( expr) ;
1101- std:: iter:: from_fn ( move || match current {
1102- Some ( Expression :: Identifier ( ident) ) => {
1103- current = None ;
1104- Some ( ident. name . as_str ( ) )
1105- }
1106- Some ( Expression :: StaticMemberExpression ( static_member) ) => {
1107- current = Some ( & static_member. object ) ;
1108- Some ( static_member. property . name . as_str ( ) )
1109- }
1110- _ => None ,
1111- } )
1112- }
1113-
1114- /// This function checks if a call expressions has one of the following members:
1115- /// - `it`
1116- /// - `it.only`
1117- /// - `it.skip`
1118- /// - `describe`
1119- /// - `describe.only`
1120- /// - `describe.skip`
1121- /// - `test`
1122- /// - `test.only`
1123- /// - `test.skip`
1124- /// - `test.step`
1125- /// - `test.describe`
1126- /// - `test.describe.only`
1127- /// - `test.describe.parallel`
1128- /// - `test.describe.parallel.only`
1129- /// - `test.describe.serial`
1130- /// - `test.describe.serial.only`
1131- /// - `skip`
1132- /// - `xit`
1133- /// - `xdescribe`
1134- /// - `xtest`
1135- /// - `fit`
1136- /// - `fdescribe`
1137- /// - `ftest`
1138- /// - `Deno.test`
1139- ///
1140- /// Based on this [article]
1141- ///
1142- /// [article]: https://craftinginterpreters.com/scanning-on-demand.html#tries-and-state-machines
1143- pub fn contains_a_test_pattern ( expr : & Expression < ' _ > ) -> bool {
1144- let mut names = callee_name_iterator ( expr) ;
1145-
1146- match names. next ( ) {
1147- Some ( "it" | "describe" | "Deno" ) => match names. next ( ) {
1148- None => true ,
1149- Some ( "only" | "skip" | "test" ) => names. next ( ) . is_none ( ) ,
1150- _ => false ,
1151- } ,
1152- Some ( "test" ) => match names. next ( ) {
1153- None => true ,
1154- Some ( "only" | "skip" | "step" ) => names. next ( ) . is_none ( ) ,
1155- Some ( "describe" ) => match names. next ( ) {
1156- None => true ,
1157- Some ( "only" ) => names. next ( ) . is_none ( ) ,
1158- Some ( "parallel" | "serial" ) => match names. next ( ) {
1159- None => true ,
1160- Some ( "only" ) => names. next ( ) . is_none ( ) ,
1161- _ => false ,
1162- } ,
1163- _ => false ,
1164- } ,
1165- _ => false ,
1166- } ,
1167- Some ( "skip" | "xit" | "xdescribe" | "xtest" | "fit" | "fdescribe" | "ftest" ) => true ,
1168- _ => false ,
1169- }
1170- }
0 commit comments