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

test(gnovm): "*_filetest.gno" instructions #1023

Merged
merged 9 commits into from
Aug 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
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
Loading