Skip to content

Commit

Permalink
test(gnovm): "*_filetest.gno" instructions (gnolang#1023)
Browse files Browse the repository at this point in the history
  • Loading branch information
tbruyelle authored and Doozers committed Aug 31, 2023
1 parent a25871a commit b7a6b0d
Show file tree
Hide file tree
Showing 46 changed files with 816 additions and 253 deletions.
47 changes: 46 additions & 1 deletion gnovm/cmd/gno/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"

"github.com/gnolang/gno/tm2/pkg/commands"
"github.com/rogpeppe/go-internal/testscript"
"github.com/stretchr/testify/require"

"github.com/gnolang/gno/tm2/pkg/commands"
)

func TestMain_Gnodev(t *testing.T) {
Expand Down Expand Up @@ -141,3 +144,45 @@ func testMainCaseRun(t *testing.T, tc []testMainCase) {
})
}
}

func setupTestScript(t *testing.T, txtarDir string) testscript.Params {
t.Helper()
// Get root location of github.com/gnolang/gno
goModPath, err := exec.Command("go", "env", "GOMOD").CombinedOutput()
require.NoError(t, err)
rootDir := filepath.Dir(string(goModPath))
// Build a fresh gno binary in a temp directory
gnoBin := filepath.Join(t.TempDir(), "gno")
err = exec.Command("go", "build", "-o", gnoBin, filepath.Join(rootDir, "gnovm", "cmd", "gno")).Run()
require.NoError(t, err)
// Define script params
return testscript.Params{
Setup: func(env *testscript.Env) error {
env.Vars = append(env.Vars,
"GNOROOT="+rootDir, // thx PR 1014 :)
// by default, $HOME=/no-home, but we need an existing $HOME directory
// because some commands needs to access $HOME/.cache/go-build
"HOME="+t.TempDir(),
)
return nil
},
Cmds: map[string]func(ts *testscript.TestScript, neg bool, args []string){
// add a custom "gno" command so txtar files can easily execute "gno"
// without knowing where is the binary or how it is executed.
"gno": func(ts *testscript.TestScript, neg bool, args []string) {
err := ts.Exec(gnoBin, args...)
if err != nil {
ts.Logf("[%v]\n", err)
if !neg {
ts.Fatalf("unexpected gno command failure")
}
} else {
if neg {
ts.Fatalf("unexpected gno command success")
}
}
},
},
Dir: txtarDir,
}
}
197 changes: 6 additions & 191 deletions gnovm/cmd/gno/test_test.go
Original file line number Diff line number Diff line change
@@ -1,196 +1,11 @@
package main

import "testing"
import (
"testing"

func TestTest(t *testing.T) {
tc := []testMainCase{
{
args: []string{"test"},
errShouldBe: "flag: help requested",
},
{
args: []string{"test", "../../../examples/gno.land/p/demo/rand"},
stderrShouldContain: "ok ./../../../examples/gno.land/p/demo/rand \t",
},
{
args: []string{"test", "../../tests/integ/no-such-dir"},
errShouldContain: "no such file or directory",
},
{
args: []string{"test", "../../tests/integ/empty-dir"},
stderrShouldContain: "no packages to test",
},
{
// FIXME: should have an output
args: []string{"test", "../../tests/integ/minimalist-gno1"},
stderrShouldBe: "? ./../../tests/integ/minimalist-gno1 \t[no test files]\n",
},
{
args: []string{"test", "../../tests/integ/minimalist-gno2"},
stderrShouldContain: "ok ",
},
{
args: []string{"test", "../../tests/integ/minimalist-gno3"},
stderrShouldContain: "ok ",
},
{
args: []string{"test", "--verbose", "../../tests/integ/valid1"},
stderrShouldContain: "ok ",
},
{
args: []string{"test", "../../tests/integ/valid2"},
stderrShouldContain: "ok ",
},
{
args: []string{"test", "--verbose", "../../tests/integ/valid2"},
stderrShouldContain: "ok ",
},
{
args: []string{"test", "../../tests/integ/empty-gno1"},
stderrShouldBe: "? ./../../tests/integ/empty-gno1 \t[no test files]\n",
},
{
args: []string{"test", "--precompile", "../../tests/integ/empty-gno1"},
errShouldBe: "FAIL: 1 build errors, 0 test errors",
stderrShouldContain: "../../tests/integ/empty-gno1/empty.gno: parse: tmp.gno:1:1: expected 'package', found 'EOF'",
},
{
args: []string{"test", "../../tests/integ/empty-gno2"},
recoverShouldBe: "empty.gno:1:1: expected 'package', found 'EOF'",
},
{
// FIXME: better error handling + rename dontcare.gno with actual test file
args: []string{"test", "--precompile", "../../tests/integ/empty-gno2"},
errShouldContain: "FAIL: 1 build errors, 0 test errors",
stderrShouldContain: "../../tests/integ/empty-gno2/empty.gno: parse: tmp.gno:1:1: expected 'package', found 'EOF'",
},
{
args: []string{"test", "../../tests/integ/empty-gno3"},
recoverShouldBe: "../../tests/integ/empty-gno3/empty_filetest.gno:1:1: expected 'package', found 'EOF'",
},
{
// FIXME: better error handling
args: []string{"test", "--precompile", "../../tests/integ/empty-gno3"},
errShouldContain: "FAIL: 1 build errors, 0 test errors",
stderrShouldContain: "../../tests/integ/empty-gno3/empty.gno: parse: tmp.gno:1:1: expected 'package', found 'EOF'",
},
{
args: []string{"test", "--verbose", "../../tests/integ/failing1"},
errShouldBe: "FAIL: 0 build errors, 1 test errors",
stderrShouldContain: "FAIL: TestAlwaysFailing",
},
{
args: []string{"test", "--verbose", "--precompile", "../../tests/integ/failing1"},
errShouldBe: "FAIL: 0 build errors, 1 test errors",
stderrShouldContain: "FAIL: TestAlwaysFailing",
},
{
args: []string{"test", "--verbose", "../../tests/integ/failing2"},
recoverShouldBe: "fail on ../../tests/integ/failing2/failing_filetest.gno: got unexpected error: beep boop",
stderrShouldContain: "== RUN file/failing_filetest.gno",
},
{
args: []string{"test", "--verbose", "--precompile", "../../tests/integ/failing2"},
stderrShouldBe: "=== PREC ./../../tests/integ/failing2\n=== BUILD ./../../tests/integ/failing2\n=== RUN file/failing_filetest.gno\n",
recoverShouldBe: "fail on ../../tests/integ/failing2/failing_filetest.gno: got unexpected error: beep boop",
},
{
args: []string{"test", "../../../examples/gno.land/p/demo/ufmt"},
stdoutShouldContain: "RUN TestSprintf",
stderrShouldContain: "ok ./../../../examples/gno.land/p/demo/ufmt",
},
{
args: []string{"test", "../../../examples/gno.land/p/demo/ufmt/ufmt_test.gno"},
stdoutShouldContain: "RUN TestSprintf",
stderrShouldContain: "ok ../../../examples/gno.land/p/demo/ufmt",
},
{
args: []string{"test", "--verbose", "../../../examples/gno.land/p/demo/ufmt"},
stdoutShouldContain: "RUN TestSprintf",
stderrShouldContain: "ok ./../../../examples/gno.land/p/demo/ufmt",
},
{
args: []string{"test", "--verbose", "--run", ".*", "../../../examples/gno.land/p/demo/ufmt"},
stdoutShouldContain: "RUN TestSprintf",
stderrShouldContain: "ok ./../../../examples/gno.land/p/demo/ufmt",
},
{
args: []string{"test", "--verbose", "--run", "NoExists", "../../../examples/gno.land/p/demo/ufmt"},
stderrShouldContain: "ok ./../../../examples/gno.land/p/demo/ufmt",
},
{
args: []string{"test", "--verbose", "--run", ".*/hello", "../../../examples/gno.land/p/demo/ufmt"},
stdoutShouldContain: "RUN TestSprintf",
stderrShouldContain: "ok ./../../../examples/gno.land/p/demo/ufmt",
},
{
args: []string{"test", "--verbose", "--run", ".*/hi", "../../../examples/gno.land/p/demo/ufmt"},
stdoutShouldContain: "RUN TestSprintf",
stderrShouldContain: "ok ./../../../examples/gno.land/p/demo/ufmt",
},
{
args: []string{"test", "--verbose", "--run", ".*/NoExists", "../../../examples/gno.land/p/demo/ufmt"},
stderrShouldContain: "ok ./../../../examples/gno.land/p/demo/ufmt",
},
{
args: []string{"test", "--verbose", "--run", ".*/hello/NoExists", "../../../examples/gno.land/p/demo/ufmt"},
stdoutShouldContain: "RUN TestSprintf",
stderrShouldContain: "ok ./../../../examples/gno.land/p/demo/ufmt",
},
{
args: []string{"test", "--verbose", "--run", "Sprintf/", "../../../examples/gno.land/p/demo/ufmt"},
stdoutShouldContain: "RUN TestSprintf",
stderrShouldContain: "ok ./../../../examples/gno.land/p/demo/ufmt",
},
{
args: []string{"test", "--verbose", "--run", "Sprintf/.*", "../../../examples/gno.land/p/demo/ufmt"},
stdoutShouldContain: "RUN TestSprintf",
stderrShouldContain: "ok ./../../../examples/gno.land/p/demo/ufmt",
},
{
args: []string{"test", "--verbose", "--run", "Sprintf/hello", "../../../examples/gno.land/p/demo/ufmt"},
stdoutShouldContain: "RUN TestSprintf",
stderrShouldContain: "ok ./../../../examples/gno.land/p/demo/ufmt",
},
{
args: []string{"test", "--verbose", "--timeout", "1000000s", "../../../examples/gno.land/p/demo/ufmt"},
stdoutShouldContain: "RUN TestSprintf",
stderrShouldContain: "ok ./../../../examples/gno.land/p/demo/ufmt",
},
{
args: []string{"test", "--verbose", "../../tests/integ/native-lib"},
recoverShouldContain: "gno.land/r/\\w{8}/contract.gno:1: unknown import path net",
},
{
args: []string{"test", "--verbose", "--with-native-fallback", "../../tests/integ/native-lib"},
stderrShouldContain: "ok ./../../tests/integ/native-lib",
},
{
args: []string{"test", "--verbose", "../../tests/integ/unknown-lib"},
recoverShouldContain: "gno.land/r/\\w{8}/contract.gno:1: unknown import path foobarbaz",
},
{
args: []string{"test", "--verbose", "--with-native-fallback", "../../tests/integ/unknown-lib"},
recoverShouldContain: "gno.land/r/\\w{8}/contract.gno:1: unknown import path foobarbaz",
},
{
args: []string{"test", "--verbose", "--print-runtime-metrics", "../../../examples/gno.land/p/demo/ufmt"},
stdoutShouldContain: "RUN TestSprintf",
stderrShouldContain: "cycle=",
},
"github.com/rogpeppe/go-internal/testscript"
)

// TODO: when 'gnodev test' will by default imply running precompile, we should use the following tests.
// {args: []string{"test", "../../tests/integ/empty-gno1", "--no-precompile"}, stderrShouldBe: "? ./../../tests/integ/empty-gno1 \t[no test files]\n"},
// {args: []string{"test", "../../tests/integ/empty-gno1"}, errShouldBe: "FAIL: 1 build errors, 0 test errors", stderrShouldContain: "../../tests/integ/empty-gno1/empty.gno: parse: tmp.gno:1:1: expected 'package', found 'EOF'"},
// {args: []string{"test", "../../tests/integ/empty-gno2", "--no-precompile"}, recoverShouldBe: "empty.gno:1:1: expected 'package', found 'EOF'"}, // FIXME: better error handling + rename dontcare.gno with actual test file
// {args: []string{"test", "../../tests/integ/empty-gno2"}, errShouldContain: "FAIL: 1 build errors, 0 test errors", stderrShouldContain: "../../tests/integ/empty-gno2/empty.gno: parse: tmp.gno:1:1: expected 'package', found 'EOF'"},
// {args: []string{"test", "../../tests/integ/empty-gno3", "--no-precompile"}, recoverShouldBe: "../../tests/integ/empty-gno3/empty_filetest.gno:1:1: expected 'package', found 'EOF'"}, // FIXME: better error handling
// {args: []string{"test", "../../tests/integ/empty-gno3"}, errShouldContain: "FAIL: 1 build errors, 0 test errors", stderrShouldContain: "../../tests/integ/empty-gno3/empty.gno: parse: tmp.gno:1:1: expected 'package', found 'EOF'"},
// {args: []string{"test", "../../tests/integ/failing1", "--verbose", "--no-precompile"}, errShouldBe: "FAIL: 0 build errors, 1 test errors", stderrShouldContain: "FAIL: TestAlwaysFailing"},
// {args: []string{"test", "../../tests/integ/failing1", "--verbose"}, errShouldBe: "FAIL: 0 build errors, 1 test errors", stderrShouldContain: "FAIL: TestAlwaysFailing"},
// {args: []string{"test", "../../tests/integ/failing2", "--verbose", "--no-precompile"}, recoverShouldBe: "fail on ../../tests/integ/failing2/failing_filetest.gno: got unexpected error: beep boop", stderrShouldContain: "== RUN file/failing_filetest.gno"},
// {args: []string{"test", "../../tests/integ/failing2", "--verbose"}, stderrShouldBe: "=== PREC ./../../tests/integ/failing2\n=== BUILD ./../../tests/integ/failing2\n=== RUN file/failing_filetest.gno\n", recoverShouldBe: "fail on ../../tests/integ/failing2/failing_filetest.gno: got unexpected error: beep boop"},
// {args: []string{"test", "../../../examples/gno.land/p/demo/ufmt", "--verbose", "--timeout", "10000" /* 10µs */}, recoverShouldContain: "test timed out after"}, // FIXME: should be testable
}
testMainCaseRun(t, tc)
func TestTest(t *testing.T) {
testscript.Run(t, setupTestScript(t, "testdata/gno_test"))
}
6 changes: 6 additions & 0 deletions gnovm/cmd/gno/testdata/gno_test/dir_not_exist.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Run gno test with a dir that doesn't exists

! gno test no-such-dir

! stdout .+
stderr 'no such file or directory'
6 changes: 6 additions & 0 deletions gnovm/cmd/gno/testdata/gno_test/empty_dir.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Run gno test on an empty dir

gno test .

! stdout .+
stderr 'no packages to test'
13 changes: 13 additions & 0 deletions gnovm/cmd/gno/testdata/gno_test/empty_gno1.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Test empty gno1

gno test .

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

! gno test --precompile .

! stdout .+
stderr 'expected ''package'', found ''EOF'''

-- empty.gno --
14 changes: 14 additions & 0 deletions gnovm/cmd/gno/testdata/gno_test/empty_gno2.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Test empty gno2

! gno test .

! stdout .+
stderr 'expected ''package'', found ''EOF'''

! gno test --precompile .

! stdout .+
stderr 'expected ''package'', found ''EOF'''

-- empty.gno --
-- empty_test.gno --
14 changes: 14 additions & 0 deletions gnovm/cmd/gno/testdata/gno_test/empty_gno3.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Test empty gno3

! gno test .

! stdout .+
stderr 'expected ''package'', found ''EOF'''

! gno test --precompile .

! stdout .+
stderr 'expected ''package'', found ''EOF'''

-- empty.gno --
-- empty_filetest.gno --
18 changes: 18 additions & 0 deletions gnovm/cmd/gno/testdata/gno_test/error_correct.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Test Error instruction correct

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'

-- x_filetest.gno --
package main

func main() {
panic("oups")
}

// Error:
// oups
17 changes: 17 additions & 0 deletions gnovm/cmd/gno/testdata/gno_test/error_incorrect.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Test Error instruction incorrect

! gno test -verbose .

stdout 'Machine\.RunMain\(\) panic: oups'
stderr '=== RUN file/x_filetest.gno'
stderr 'panic: fail on x_filetest.gno: got "oups", want: "xxx"'

-- x_filetest.gno --
package main

func main() {
panic("oups")
}

// Error:
// xxx
32 changes: 32 additions & 0 deletions gnovm/cmd/gno/testdata/gno_test/error_sync.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Test Error instruction updated
# NOTE: unlike Output and Realm instruction updates, Error update is not driven
# by the '-update-golden-tests' flag. The Error is only updated when it is
# empty.

! gno test -verbose .

stdout 'Machine\.RunMain\(\) panic: oups'
stderr '=== RUN file/x_filetest.gno'

cmp x_filetest.gno x_filetest.gno.golden

-- x_filetest.gno --
package main

func main() {
panic("oups")
}

// Error:

-- x_filetest.gno.golden --
package main

func main() {
panic("oups")
}

// Error:
// oups
// *** CHECK THE ERR MESSAGES ABOVE, MAKE SURE IT'S WHAT YOU EXPECTED, DELETE THIS LINE AND RUN TEST AGAIN ***

Loading

0 comments on commit b7a6b0d

Please sign in to comment.