Skip to content

Commit

Permalink
fix(gnovm): PrevRealm in _test files (#896)
Browse files Browse the repository at this point in the history
Co-authored-by: Manfred Touron <94029+moul@users.noreply.github.com>
  • Loading branch information
tbruyelle and moul committed Aug 6, 2023
1 parent ce2daf4 commit e8016f3
Show file tree
Hide file tree
Showing 11 changed files with 86 additions and 18 deletions.
6 changes: 3 additions & 3 deletions examples/gno.land/r/demo/tests/tests.gno
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package tests
import (
"std"

"gno.land/r/demo/tests/subtests"
rsubtests "gno.land/r/demo/tests/subtests"
)

var counter int
Expand Down Expand Up @@ -78,8 +78,8 @@ func GetPrevRealm() std.Realm {
return std.PrevRealm()
}

func GetPSubtestsPrevRealm() std.Realm {
return subtests.GetPrevRealm()
func GetRSubtestsPrevRealm() std.Realm {
return rsubtests.GetPrevRealm()
}

func Exec(fn func()) {
Expand Down
16 changes: 16 additions & 0 deletions examples/gno.land/r/demo/tests/tests_test.gno
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package tests

import (
"std"
"testing"

"gno.land/p/demo/testutils"
Expand Down Expand Up @@ -30,3 +31,18 @@ func TestAssertOriginCall(t *testing.T) {
AssertOriginCall()
}()
}

func TestPrevRealm(t *testing.T) {
var (
user1Addr = std.DerivePkgAddr("user1.gno")
rTestsAddr = std.DerivePkgAddr("gno.land/r/demo/tests")
)
// When a single realm in the frames, PrevRealm returns the user
if addr := GetPrevRealm().Addr(); addr != user1Addr {
t.Errorf("want GetPrevRealm().Addr==%s, got %s", user1Addr, addr)
}
// When 2 or more realms in the frames, PrevRealm returns the second to last
if addr := GetRSubtestsPrevRealm().Addr(); addr != rTestsAddr {
t.Errorf("want GetRSubtestsPrevRealm().Addr==%s, got %s", rTestsAddr, addr)
}
}
2 changes: 1 addition & 1 deletion gnovm/cmd/gno/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func testMainCaseRun(t *testing.T, tc []testMainCase) {
require.False(t, recoverShouldBeEmpty, "should panic")
require.True(t, errShouldBeEmpty, "should not return an error")
if test.recoverShouldContain != "" {
require.Contains(t, output, test.recoverShouldContain, "recover should contain")
require.Regexpf(t, test.recoverShouldContain, output, "recover should contain")
}
if test.recoverShouldBe != "" {
require.Equal(t, test.recoverShouldBe, output, "recover should be")
Expand Down
25 changes: 18 additions & 7 deletions gnovm/cmd/gno/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@ import (
"text/template"
"time"

"go.uber.org/multierr"

gno "github.com/gnolang/gno/gnovm/pkg/gnolang"
"github.com/gnolang/gno/gnovm/pkg/gnomod"
"github.com/gnolang/gno/gnovm/tests"
"github.com/gnolang/gno/tm2/pkg/commands"
"github.com/gnolang/gno/tm2/pkg/errors"
"github.com/gnolang/gno/tm2/pkg/random"
"github.com/gnolang/gno/tm2/pkg/std"
"github.com/gnolang/gno/tm2/pkg/testutils"
"go.uber.org/multierr"
)

type testCfg struct {
Expand Down Expand Up @@ -240,11 +243,9 @@ func gnoTestPkg(
stdin = io.In
stdout = io.Out
stderr = io.Err
errs error
)

filter := splitRegexp(runFlag)
var errs error

mode := tests.ImportModeStdlibsOnly
if cfg.withNativeFallback {
// XXX: display a warn?
Expand All @@ -267,14 +268,23 @@ func gnoTestPkg(

// testing with *_test.gno
if len(unittestFiles) > 0 {
memPkg := gno.ReadMemPackage(pkgPath, pkgPath)
// Determine gnoPkgPath by reading gno.mod
var gnoPkgPath string
modfile, err := gnomod.ParseAt(pkgPath)
if err == nil {
gnoPkgPath = modfile.Module.Mod.Path
} else {
// unable to read pkgPath from gno.mod, generate a random realm path
gnoPkgPath = gno.GnoRealmPkgsPrefixBefore + random.RandStr(8)
}
memPkg := gno.ReadMemPackage(pkgPath, gnoPkgPath)

// tfiles, ifiles := gno.ParseMemPackageTests(memPkg)
tfiles, ifiles := parseMemPackageTests(memPkg)

// run test files in pkg
{
m := tests.TestMachine(testStore, stdout, "main")
m := tests.TestMachine(testStore, stdout, gnoPkgPath)
if printRuntimeMetrics {
// from tm2/pkg/sdk/vm/keeper.go
// XXX: make maxAllocTx configurable.
Expand Down Expand Up @@ -305,6 +315,7 @@ func gnoTestPkg(

// testing with *_filetest.gno
{
filter := splitRegexp(runFlag)
for _, testFile := range filetestFiles {
testFileName := filepath.Base(testFile)
testName := "file/" + testFileName
Expand Down Expand Up @@ -377,7 +388,7 @@ func runTestFiles(
}

m.RunFiles(files.Files...)
n := gno.MustParseFile("testmain.go", testmain)
n := gno.MustParseFile("main_test.gno", testmain)
m.RunFiles(n)

for _, test := range testFuncs.Tests {
Expand Down
6 changes: 3 additions & 3 deletions gnovm/cmd/gno/test_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,19 +153,19 @@ func TestTest(t *testing.T) {
},
{
args: []string{"test", "--verbose", "../../tests/integ/native-lib"},
recoverShouldContain: "./../../tests/integ/native-lib/contract.gno:1: unknown import path net",
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: "./../../tests/integ/unknown-lib/contract.gno:1: unknown import path foobarbaz",
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: "./../../tests/integ/unknown-lib/contract.gno:1: unknown import path foobarbaz",
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"},
Expand Down
3 changes: 3 additions & 0 deletions gnovm/pkg/doc/dirs.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ func newDirs(dirs []string, modDirs []string) *bfsDirs {

// tries to parse gno mod file given the filename, using Parse and Validate from
// the gnomod package
//
// TODO(tb): replace by `gnomod.ParseAt` ? The key difference is the latter
// looks for gno.mod in parent directories, while this function doesn't.
func parseGnoMod(fname string) (*gnomod.File, error) {
file, err := os.Stat(fname)
if err != nil {
Expand Down
6 changes: 5 additions & 1 deletion gnovm/pkg/gnolang/realm.go
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,10 @@ func copyValueWithRefs(parent Object, val Value) Value {
}
case *FuncValue:
source := toRefNode(cv.Source)
if strings.HasSuffix(source.Location.File, "_test.gno") {
// Ignore _test files
return nil
}
var closure Value
if cv.Closure != nil {
closure = toRefValue(parent, cv.Closure)
Expand Down Expand Up @@ -1502,7 +1506,7 @@ func isUnsaved(oo Object) bool {

func IsRealmPath(pkgPath string) bool {
// TODO: make it more distinct to distinguish from normal paths.
if strings.HasPrefix(pkgPath, "gno.land/r/") {
if strings.HasPrefix(pkgPath, GnoRealmPkgsPrefixBefore) {
return true
} else {
return false
Expand Down
33 changes: 33 additions & 0 deletions gnovm/pkg/gnomod/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,46 @@ package gnomod

import (
"fmt"
"os"
"path/filepath"
"reflect"
"strings"

"golang.org/x/mod/modfile"
"golang.org/x/mod/module"
)

// ParseAt parses, validates and returns a gno.mod file located at dir or at
// dir's parents.
func ParseAt(dir string) (*File, error) {
ferr := func(err error) (*File, error) {
return nil, fmt.Errorf("parsing gno.mod at %s: %w", dir, err)
}

// FindRootDir requires absolute path, make sure its the case
absDir, err := filepath.Abs(dir)
if err != nil {
return ferr(err)
}
rd, err := FindRootDir(absDir)
if err != nil {
return ferr(err)
}
fname := filepath.Join(rd, "gno.mod")
b, err := os.ReadFile(fname)
if err != nil {
return ferr(err)
}
gm, err := Parse(fname, b)
if err != nil {
return ferr(err)
}
if err := gm.Validate(); err != nil {
return ferr(err)
}
return gm, nil
}

// Parse parses and returns a gno.mod file.
//
// - file is the name of the file, used in positions and errors.
Expand Down
2 changes: 1 addition & 1 deletion gnovm/tests/files/zrealm_crossrealm11.gno
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func main() {
},
{
callStackAdd: " -> r/demo/tests -> r/demo/tests/subtests",
callerFn: rtests.GetPSubtestsPrevRealm,
callerFn: rtests.GetRSubtestsPrevRealm,
},
{
callStackAdd: " -> p/demo/tests -> r/demo/tests",
Expand Down
2 changes: 1 addition & 1 deletion gnovm/tests/files/zrealm_tests0.gno
Original file line number Diff line number Diff line change
Expand Up @@ -972,7 +972,7 @@ func main() {
// },
// "FileName": "tests.gno",
// "IsMethod": false,
// "Name": "GetPSubtestsPrevRealm",
// "Name": "GetRSubtestsPrevRealm",
// "PkgPath": "gno.land/r/demo/tests",
// "Source": {
// "@type": "/gno.RefNode",
Expand Down
3 changes: 2 additions & 1 deletion gnovm/tests/imports.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ func TestStore(rootDir, filesPath string, stdin io.Reader, stdout, stderr io.Wri
Output: stdout,
Store: store,
})
return m2.RunMemPackage(memPkg, true)
save := pkgPath != "testing" // never save the "testing" package
return m2.RunMemPackage(memPkg, save)
}
}

Expand Down

0 comments on commit e8016f3

Please sign in to comment.