github.com/saucelabs/saucectl@v0.175.1/internal/playwright/grep/grep.go (about)

     1  // Package grep implements functions to parse and filter spec files like playwright is doing.
     2  //
     3  // See https://playwright.dev/docs/test-annotations#tag-tests for details.
     4  package grep
     5  
     6  import (
     7  	"io/fs"
     8  	"regexp"
     9  
    10  	"github.com/saucelabs/saucectl/internal/playwright/code"
    11  )
    12  
    13  // MatchFiles finds the files whose contents match the grep expression in the title parameter
    14  func MatchFiles(sys fs.FS, files []string, grep string, grepInvert string) (matched []string, unmatched []string) {
    15  	grepRE, grepInvertRE := compileRE(grep, grepInvert)
    16  
    17  	for _, f := range files {
    18  		if match(f, grepRE, grepInvertRE) {
    19  			matched = append(matched, f)
    20  			continue
    21  		}
    22  
    23  		// When there is a value in grepInvert, if filename matches the pattern, spec file will be skipped.
    24  		if grepInvertRE != nil {
    25  			unmatched = append(unmatched, f)
    26  			continue
    27  		}
    28  
    29  		b, err := fs.ReadFile(sys, f)
    30  		if err != nil {
    31  			continue
    32  		}
    33  
    34  		testcases := code.Parse(string(b))
    35  
    36  		include := false
    37  		for _, tc := range testcases {
    38  			include = include || match(tc.Title, grepRE, grepInvertRE)
    39  			if include {
    40  				// As long as one testcase matched, we know the spec will need to be executed
    41  				matched = append(matched, f)
    42  				break
    43  			}
    44  		}
    45  		if !include {
    46  			unmatched = append(unmatched, f)
    47  		}
    48  	}
    49  	return matched, unmatched
    50  }
    51  
    52  // compileRE compiles the regexp contained in grep/grepInvert.
    53  // No pattern specified generates nil value.
    54  func compileRE(grep, grepInvert string) (*regexp.Regexp, *regexp.Regexp) {
    55  	var grepRE *regexp.Regexp
    56  	var grepInvertRE *regexp.Regexp
    57  	if grep != "" {
    58  		grepRE, _ = regexp.Compile(grep)
    59  
    60  	}
    61  	if grepInvert != "" {
    62  		grepInvertRE, _ = regexp.Compile(grepInvert)
    63  	}
    64  	return grepRE, grepInvertRE
    65  }
    66  
    67  func match(title string, grepRe *regexp.Regexp, grepInvertRe *regexp.Regexp) bool {
    68  	if title == "" {
    69  		if grepRe != nil {
    70  			return false
    71  		}
    72  		if grepInvertRe != nil {
    73  			return true
    74  		}
    75  		return true
    76  	}
    77  	if grepRe != nil && grepInvertRe == nil {
    78  		return grepRe.MatchString(title)
    79  	}
    80  	if grepRe == nil && grepInvertRe != nil {
    81  		return !grepInvertRe.MatchString(title)
    82  	}
    83  	return grepRe.MatchString(title) && !grepInvertRe.MatchString(title)
    84  }