Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: gno test support /... pattern #1078

Merged
merged 10 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
with:
go-version: ${{ matrix.goversion }}
- run: go install -v ./gnovm/cmd/gno
- run: go run ./gnovm/cmd/gno test --verbose ./examples
- run: go run ./gnovm/cmd/gno test --verbose ./examples/...
lint:
strategy:
fail-fast: false
Expand Down
4 changes: 2 additions & 2 deletions examples/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ build: precompile

.PHONY: test
test:
go run ../gnovm/cmd/gno test --verbose .
go run ../gnovm/cmd/gno test --verbose ./...

.PHONY: lint
lint:
go run ../gnovm/cmd/gno lint $(OFFICIAL_PACKAGES)

.PHONY: test.sync
test.sync:
go run ../gnovm/cmd/gno test --verbose --update-golden-tests .
go run ../gnovm/cmd/gno test --verbose --update-golden-tests ./...

.PHONY: clean
clean:
Expand Down
6 changes: 3 additions & 3 deletions gnovm/cmd/gno/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
'gno test' recompiles each package along with any files with names matching the
file pattern "*_test.gno" or "*_filetest.gno".

The only <package> supported for now is a directory (relative or absolute).
The <package> can be directory or file path (relative or absolute).

- "*_test.gno" files work like "*_test.go" files, but they contain only test
functions. Benchmark and fuzz functions aren't supported yet. Similarly, only
Expand Down Expand Up @@ -182,9 +182,9 @@
cfg.rootDir = guessRootDir()
}

paths, err := gnoPackagesFromArgs(args)
paths, err := targetsFromPatterns(args)

Check warning on line 185 in gnovm/cmd/gno/test.go

View check run for this annotation

Codecov / codecov/patch

gnovm/cmd/gno/test.go#L185

Added line #L185 was not covered by tests
if err != nil {
return fmt.Errorf("list package paths from args: %w", err)
return fmt.Errorf("list targets from patterns: %w", err)

Check warning on line 187 in gnovm/cmd/gno/test.go

View check run for this annotation

Codecov / codecov/patch

gnovm/cmd/gno/test.go#L187

Added line #L187 was not covered by tests
}
if len(paths) == 0 {
io.ErrPrintln("no packages to test")
Expand Down
5 changes: 5 additions & 0 deletions gnovm/cmd/gno/testdata/gno_test/empty_dir.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,10 @@

gno test .

! stdout .+
stderr '[no test files]'

gno test ./...

! stdout .+
stderr 'no packages to test'
2 changes: 1 addition & 1 deletion gnovm/cmd/gno/testdata/gno_test/empty_gno1.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
gno test .

! stdout .+
stderr '\? \./\. \[no test files\]'
stderr '\? \. \[no test files\]'

! gno test --precompile .

Expand Down
2 changes: 1 addition & 1 deletion gnovm/cmd/gno/testdata/gno_test/error_correct.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ gno test -verbose .
stdout 'Machine\.RunMain\(\) panic: oups'
stderr '=== RUN file/x_filetest.gno'
stderr '--- PASS: file/x_filetest.gno \(\d\.\d\ds\)'
stderr 'ok \./\. \d\.\d\ds'
stderr 'ok \. \d\.\d\ds'

-- x_filetest.gno --
package main
Expand Down
4 changes: 2 additions & 2 deletions gnovm/cmd/gno/testdata/gno_test/failing_filetest.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ stderr 'panic: fail on failing_filetest.gno: got unexpected error: beep boop'
! gno test -verbose --precompile .

stdout 'Machine.RunMain\(\) panic: beep boop'
stderr '=== PREC \./\.'
stderr '=== BUILD \./\.'
stderr '=== PREC \.'
stderr '=== BUILD \.'
stderr '=== RUN file/failing_filetest.gno'
stderr 'panic: fail on failing_filetest.gno: got unexpected error: beep boop'

Expand Down
2 changes: 1 addition & 1 deletion gnovm/cmd/gno/testdata/gno_test/minim1.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
gno test .

! stdout .+
stderr '\? \./\. \[no test files\]'
stderr '\? \. \[no test files\]'

-- minim.gno --
package minim
2 changes: 1 addition & 1 deletion gnovm/cmd/gno/testdata/gno_test/minim2.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
gno test .

! stdout .+
stderr 'ok \./\. \d\.\d\ds'
stderr 'ok \. \d\.\d\ds'

-- minim.gno --
package minim
Expand Down
2 changes: 1 addition & 1 deletion gnovm/cmd/gno/testdata/gno_test/minim3.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
gno test .

! stdout .+
stderr 'ok \./\. \d\.\d\ds'
stderr 'ok \. \d\.\d\ds'

-- minim.gno --
package minim
Expand Down
2 changes: 1 addition & 1 deletion gnovm/cmd/gno/testdata/gno_test/output_correct.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ gno test -verbose .
! stdout .+ # stdout should be empty
stderr '=== RUN file/x_filetest.gno'
stderr '--- PASS: file/x_filetest.gno \(\d\.\d\ds\)'
stderr 'ok \./\. \d\.\d\ds'
stderr 'ok \. \d\.\d\ds'

-- x_filetest.gno --
package main
Expand Down
2 changes: 1 addition & 1 deletion gnovm/cmd/gno/testdata/gno_test/output_sync.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ gno test -verbose . -update-golden-tests
! stdout .+ # stdout should be empty
stderr '=== RUN file/x_filetest.gno'
stderr '--- PASS: file/x_filetest.gno \(\d\.\d\ds\)'
stderr 'ok \./\. \d\.\d\ds'
stderr 'ok \. \d\.\d\ds'

cmp x_filetest.gno x_filetest.gno.golden

Expand Down
2 changes: 1 addition & 1 deletion gnovm/cmd/gno/testdata/gno_test/realm_correct.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ gno test -verbose .
! stdout .+ # stdout should be empty
stderr '=== RUN file/x_filetest.gno'
stderr '--- PASS: file/x_filetest.gno \(\d\.\d\ds\)'
stderr 'ok \./\. \d\.\d\ds'
stderr 'ok \. \d\.\d\ds'

-- x_filetest.gno --
// PKGPATH: gno.land/r/x
Expand Down
2 changes: 1 addition & 1 deletion gnovm/cmd/gno/testdata/gno_test/realm_sync.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ gno test -verbose . -update-golden-tests
! stdout .+ # stdout should be empty
stderr '=== RUN file/x_filetest.gno'
stderr '--- PASS: file/x_filetest.gno \(\d\.\d\ds\)'
stderr 'ok \./\. \d\.\d\ds'
stderr 'ok \. \d\.\d\ds'

cmp x_filetest.gno x_filetest.gno.golden

Expand Down
4 changes: 2 additions & 2 deletions gnovm/cmd/gno/testdata/gno_test/valid_filetest.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
gno test .

! stdout .+
stderr 'ok \./\. \d\.\d\ds'
stderr 'ok \. \d\.\d\ds'

gno test -verbose .

! stdout .+
stderr '=== RUN file/valid_filetest.gno'
stderr '--- PASS: file/valid_filetest.gno \(\d\.\d\ds\)'
stderr 'ok \./\. \d\.\d\ds'
stderr 'ok \. \d\.\d\ds'

-- valid.gno --
package valid
Expand Down
7 changes: 6 additions & 1 deletion gnovm/cmd/gno/testdata/gno_test/valid_test.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
gno test .

! stdout .+
stderr 'ok \./\. \d\.\d\ds'
stderr 'ok \. \d\.\d\ds'

gno test ./...

! stdout .+
stderr 'ok \. \d\.\d\ds'

-- valid.gno --
package valid
Expand Down
84 changes: 84 additions & 0 deletions gnovm/cmd/gno/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"time"

Expand Down Expand Up @@ -105,6 +106,89 @@
return paths, nil
}

// targetsFromPatterns returns a list of target paths that match the patterns.
// Each pattern can represent a file or a directory, and if the pattern
// includes "/...", the "..." is treated as a wildcard, matching any string.
// Intended to be used by gno commands such as `gno test`.
func targetsFromPatterns(patterns []string) ([]string, error) {
paths := []string{}
for _, p := range patterns {
var match func(string) bool
patternLookup := false
dirToSearch := p

// Check if the pattern includes `/...`
if strings.Contains(p, "/...") {
index := strings.Index(p, "/...")
if index != -1 {
dirToSearch = p[:index] // Extract the directory path to search
}
match = matchPattern(strings.TrimPrefix(p, "./"))
patternLookup = true
}

info, err := os.Stat(dirToSearch)
if err != nil {
return nil, fmt.Errorf("invalid file or package path: %w", err)
}

// If the pattern is a file or a directory
// without `/...`, add it to the list.
if !info.IsDir() || !patternLookup {
paths = append(paths, p)
continue
}

// the pattern is a dir containing `/...`, walk the dir recursively and
// look for directories containing at least one .gno file and match pattern.
visited := map[string]bool{} // used to run the builder only once per folder.
err = filepath.WalkDir(dirToSearch, func(curpath string, f fs.DirEntry, err error) error {
if err != nil {
return fmt.Errorf("%s: walk dir: %w", dirToSearch, err)
}

Check warning on line 148 in gnovm/cmd/gno/util.go

View check run for this annotation

Codecov / codecov/patch

gnovm/cmd/gno/util.go#L147-L148

Added lines #L147 - L148 were not covered by tests
// Skip directories and non ".gno" files.
if f.IsDir() || !isGnoFile(f) {
return nil
}

parentDir := filepath.Dir(curpath)
if _, found := visited[parentDir]; found {
return nil
}

Check warning on line 157 in gnovm/cmd/gno/util.go

View check run for this annotation

Codecov / codecov/patch

gnovm/cmd/gno/util.go#L156-L157

Added lines #L156 - L157 were not covered by tests

visited[parentDir] = true
if match(parentDir) {
paths = append(paths, parentDir)
}

return nil
})
if err != nil {
return nil, err
}

Check warning on line 168 in gnovm/cmd/gno/util.go

View check run for this annotation

Codecov / codecov/patch

gnovm/cmd/gno/util.go#L167-L168

Added lines #L167 - L168 were not covered by tests
}
return paths, nil
}

// matchPattern(pattern)(name) reports whether
// name matches pattern. Pattern is a limited glob
// pattern in which '...' means 'any string' and there
// is no other special syntax.
// Simplified version of go source's matchPatternInternal
// (see $GOROOT/src/cmd/internal/pkgpattern)
func matchPattern(pattern string) func(name string) bool {
re := regexp.QuoteMeta(pattern)
re = strings.Replace(re, `\.\.\.`, `.*`, -1)
// Special case: foo/... matches foo too.
if strings.HasSuffix(re, `/.*`) {
re = re[:len(re)-len(`/.*`)] + `(/.*)?`
}
reg := regexp.MustCompile(`^` + re + `$`)
return func(name string) bool {
return reg.MatchString(name)
}
}

func fmtDuration(d time.Duration) string {
return fmt.Sprintf("%.2fs", d.Seconds())
}
Expand Down
Loading
Loading