Skip to content

Commit

Permalink
fix: edge case of tests marked as obsolete (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
gkampitakis authored Dec 29, 2021
1 parent d861350 commit bcffbce
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 72 deletions.
80 changes: 14 additions & 66 deletions snaps/clean.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ package snaps

import (
"bufio"
"errors"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"strings"
)
Expand All @@ -16,9 +14,10 @@ func Clean() {
fmt.Println(yellowText("go-snaps [Warning]: snaps.Clean should only run in 'TestMain'"))
return
}
runOnly := parseRunFlag(os.Args)

obsoleteSnaps, usedSnaps := parseFiles(testsOccur.values, shouldUpdate)
obsoleteTests, err := parseSnaps(testsOccur.values, usedSnaps, shouldUpdate)
obsoleteSnaps, usedSnaps := parseFiles(testsOccur.values, runOnly, shouldUpdate)
obsoleteTests, err := parseSnaps(testsOccur.values, usedSnaps, runOnly, shouldUpdate)
if err != nil {
fmt.Println(err)
}
Expand All @@ -34,7 +33,7 @@ func Clean() {
`Matchsnapshot`). If not skipped and not registed means it's an obsolete snap file
and we mark it as one.
*/
func parseFiles(testsOccur map[string]map[string]int, shouldUpdate bool) (obsolete []string, used []string) {
func parseFiles(testsOccur map[string]map[string]int, runOnly string, shouldUpdate bool) (obsolete []string, used []string) {
uniqueDirs := map[string]struct{}{}

for paths := range testsOccur {
Expand All @@ -53,12 +52,7 @@ func parseFiles(testsOccur map[string]map[string]int, shouldUpdate bool) (obsole
file := filepath.Join(dir, content.Name())

if _, called := testsOccur[file]; !called {
isSkipped, err := isFileSkipped(dir, content.Name())
if err != nil {
fmt.Println(err)
continue
}

isSkipped := isFileSkipped(dir, content.Name(), runOnly)
if isSkipped {
continue
}
Expand All @@ -81,7 +75,7 @@ func parseFiles(testsOccur map[string]map[string]int, shouldUpdate bool) (obsole
return obsolete, used
}

func parseSnaps(testsOccur map[string]map[string]int, used []string, shouldUpdate bool) ([]string, error) {
func parseSnaps(testsOccur map[string]map[string]int, used []string, runOnly string, shouldUpdate bool) ([]string, error) {
obsoleteTests := []string{}

for _, snapPaths := range used {
Expand Down Expand Up @@ -109,7 +103,7 @@ func parseSnaps(testsOccur map[string]map[string]int, used []string, shouldUpdat
}
testID := match[1]

if _, exists := registeredTests[testID]; !exists && !testSkipped(testID) {
if _, exists := registeredTests[testID]; !exists && !testSkipped(testID, runOnly) {
obsoleteTests = append(obsoleteTests, testID)
hasDiffs = true

Expand Down Expand Up @@ -167,43 +161,6 @@ func summary(obsoleteSnaps []string, obsoleteTests []string) {
}
}

/*
Naive approach but works
Checks if the file includes the mod url import and if the Matchsnapshot call exists
*/
func isFileSkipped(dir string, filename string) (bool, error) {
modExists, called := false, false
ext := filepath.Ext(filename)
testFilePath := path.Join(dir, "..", strings.TrimSuffix(filename, ext)+".go")

f, err := os.Open(testFilePath)
if errors.Is(err, os.ErrNotExist) {
return false, nil
}
if err != nil {
return false, err
}

s := bufio.NewScanner(f)
for s.Scan() {
text := s.Text()

if strings.Contains(text, MOD) {
modExists = true
}

if strings.Contains(text, "MatchSnapshot(") {
called = true
}

if modExists && called {
return true, nil
}
}

return false, nil
}

/*
Builds a Set with all snapshot ids registered inside a snap file
Form: testname - number id
Expand All @@ -220,7 +177,7 @@ func isFileSkipped(dir string, filename string) (bool, error) {
as it means there are 3 snapshots registered with that test
*/
func occurrences(tests map[string]int) Set {
result := make(map[string]struct{})
result := make(Set)
for testID, counter := range tests {
if counter > 1 {
for i := 1; i <= counter; i++ {
Expand All @@ -233,23 +190,14 @@ func occurrences(tests map[string]int) Set {
return result
}

/*
This checks if the parent test is skipped
e.g
func TestParallel (t *testing.T) {
snaps.Skip()
...
}
Then every "child" test should be skipped
*/
func testSkipped(testID string) bool {
isSkipped := false
func parseRunFlag(args []string) (runOnly string) {
flag := "-test.run="

for _, name := range skippedTests.values {
if strings.HasPrefix(testID, name) {
return true
for _, arg := range args {
if strings.HasPrefix(arg, flag) {
return strings.Split(arg, flag)[1]
}
}

return isSkipped
return ""
}
24 changes: 19 additions & 5 deletions snaps/clean_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func getFileContent(t *testing.T, name string) string {
func TestParseFiles(t *testing.T) {
t.Run("should parse files", func(t *testing.T) {
tests, dir1, dir2 := setupTempParseFiles(t)
obsolete, used := parseFiles(tests, false)
obsolete, used := parseFiles(tests, "", false)

obsoleteExpected := []string{filepath.FromSlash(dir1 + "/obsolete1.snap"), filepath.FromSlash(dir2 + "/obsolete2.snap")}
usedExpected := []string{filepath.FromSlash(dir1 + "/test1.snap"), filepath.FromSlash(dir2 + "/test2.snap")}
Expand All @@ -137,7 +137,7 @@ func TestParseFiles(t *testing.T) {
t.Run("should remove outdate files", func(t *testing.T) {
shouldUpdate := true
tests, dir1, dir2 := setupTempParseFiles(t)
parseFiles(tests, shouldUpdate)
parseFiles(tests, "", shouldUpdate)

if _, err := os.Stat(filepath.FromSlash(dir1 + "/obsolete1.snap")); !errors.Is(err, os.ErrNotExist) {
t.Error("obsolete obsolete1.snap not removed")
Expand Down Expand Up @@ -174,7 +174,7 @@ func TestParseSnaps(t *testing.T) {
used := []string{filepath.FromSlash(dir1 + "/test1.snap"), filepath.FromSlash(dir2 + "/test2.snap")}
shouldUpdate := false

obsolete, err := parseSnaps(tests, used, shouldUpdate)
obsolete, err := parseSnaps(tests, used, "", shouldUpdate)

Equal(t, []string{}, obsolete)
Equal(t, err, nil)
Expand All @@ -190,7 +190,7 @@ func TestParseSnaps(t *testing.T) {
// Removing the test entirely
delete(tests[used[1]], "TestDir2_2/TestSimple")

obsolete, err := parseSnaps(tests, used, shouldUpdate)
obsolete, err := parseSnaps(tests, used, "", shouldUpdate)
content1 := getFileContent(t, used[0])
content2 := getFileContent(t, used[1])

Expand All @@ -210,7 +210,7 @@ func TestParseSnaps(t *testing.T) {
delete(tests[used[0]], "TestDir1_3/TestSimple")
delete(tests[used[1]], "TestDir2_1/TestSimple")

obsolete, err := parseSnaps(tests, used, shouldUpdate)
obsolete, err := parseSnaps(tests, used, "", shouldUpdate)
content1 := getFileContent(t, used[0])
content2 := getFileContent(t, used[1])

Expand Down Expand Up @@ -248,3 +248,17 @@ string hello world 2 2 1
Equal(t, expected2, content2)
})
}

func TestParseRunFlag(t *testing.T) {
t.Run("should return empty string", func(t *testing.T) {
runOly := parseRunFlag([]string{"-test.flag=ignore"})

Equal(t, "", runOly)
})

t.Run("should return -run value", func(t *testing.T) {
runOly := parseRunFlag([]string{"-test.run=MyTest"})

Equal(t, "MyTest", runOly)
})
}
59 changes: 59 additions & 0 deletions snaps/skip.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package snaps

import (
"go/ast"
"go/parser"
"go/token"
"path"
"strings"
"testing"
)

Expand Down Expand Up @@ -29,3 +34,57 @@ func SkipNow(t *testing.T) {
skippedTests.append(t.Name())
t.SkipNow()
}

/*
This checks if the parent test is skipped
e.g
func TestParallel (t *testing.T) {
snaps.Skip()
...
}
Then every "child" test should be skipped
*/
func testSkipped(testID, runOnly string) bool {
if runOnly != "" && !strings.HasPrefix(testID, runOnly) {
return true
}

for _, name := range skippedTests.values {
if strings.HasPrefix(testID, name) {
return true
}
}

return false
}

func isFileSkipped(dir, filename, runOnly string) bool {
// When a file is skipped through CLI with -run flag we can track it
if runOnly == "" {
return false
}

testFilePath := path.Join(dir, "..", strings.TrimSuffix(filename, ".snap")+".go")
isSkipped := true

fset := token.NewFileSet()
file, err := parser.ParseFile(fset, testFilePath, nil, parser.ParseComments)
if err != nil {
return false
}

for _, decls := range file.Decls {
funcDecl, ok := decls.(*ast.FuncDecl)

if !ok {
continue
}

// If the TestFunction is inside the file then it's not skipped
if funcDecl.Name.String() == runOnly {
isSkipped = false
}
}

return isSkipped
}
1 change: 0 additions & 1 deletion snaps/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ const (
greenCode = "\u001b[32;1m"
redCode = "\u001b[31;1m"
yellowCode = "\u001b[33;1m"
MOD = "github.com/gkampitakis/go-snaps"
)

func redBG(txt string) string {
Expand Down

0 comments on commit bcffbce

Please sign in to comment.