diff --git a/test/test_framework_test.go b/test/test_framework_test.go index c2e34ffc..d5d782d0 100644 --- a/test/test_framework_test.go +++ b/test/test_framework_test.go @@ -22,7 +22,9 @@ import ( "bytes" "errors" "fmt" + "os" "testing" + "time" "github.com/rs/zerolog" "github.com/stretchr/testify/assert" @@ -5932,3 +5934,36 @@ func TestGetTests(t *testing.T) { assert.ElementsMatch(t, []string{"test1", "test2", "test3"}, tests) } + +func TestEVMContract(t *testing.T) { + t.Parallel() + + const testCode = ` + import Test + import "EVM" + + access(all) + fun testCOACreation() { + let coa <- EVM.createCadenceOwnedAccount() + Test.assertEqual(UInt(0), coa.address().balance().inAttoFLOW()) + + destroy <- coa + } + ` + + importResolver := func(location common.Location) (string, error) { + return "", fmt.Errorf("cannot find import location: %s", location) + } + + output := zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.RFC3339} + log := zerolog.New(output).With().Timestamp().Logger() + runner := NewTestRunner(). + WithImportResolver(importResolver). + WithLogger(log) + + results, err := runner.RunTests(testCode) + require.NoError(t, err) + for _, result := range results { + require.NoError(t, result.Error) + } +} diff --git a/test/test_runner.go b/test/test_runner.go index 77255437..a3a0e977 100644 --- a/test/test_runner.go +++ b/test/test_runner.go @@ -27,6 +27,9 @@ import ( "github.com/rs/zerolog" "github.com/onflow/atree" + "github.com/onflow/flow-go/fvm/environment" + "github.com/onflow/flow-go/fvm/evm" + "github.com/onflow/flow-go/fvm/systemcontracts" "github.com/onflow/flow-go/model/flow" "github.com/onflow/cadence/runtime" @@ -474,8 +477,9 @@ func (r *TestRunner) initializeEnvironment() ( backend.contracts = r.contracts r.backend = backend + fvmEnv := r.backend.blockchain.NewScriptEnvironment() ctx := runtime.Context{ - Interface: r.backend.blockchain.NewScriptEnvironment(), + Interface: fvmEnv, Location: testScriptLocation, Environment: env, } @@ -506,6 +510,11 @@ func (r *TestRunner) initializeEnvironment() ( r.coverageReport, ) + err := setupEVMEnvironment(fvmEnv, env) + if err != nil { + panic(err) + } + return env, ctx } @@ -786,6 +795,15 @@ func (r *TestRunner) parseAndCheckImport( env.CheckerConfig.ContractValueHandler = contractValueHandler + fvmEnv, ok := startCtx.Interface.(environment.Environment) + if !ok { + panic(fmt.Errorf("failed to retrieve FVM Environment")) + } + err = setupEVMEnvironment(fvmEnv, env) + if err != nil { + panic(err) + } + code = r.replaceImports(code) program, err := r.testRuntime.ParseAndCheckProgram([]byte(code), ctx) @@ -796,6 +814,20 @@ func (r *TestRunner) parseAndCheckImport( return program.Program, program.Elaboration, nil } +func setupEVMEnvironment( + fvmEnv environment.Environment, + runtimeEnv runtime.Environment, +) error { + sc := systemcontracts.SystemContractsForChain(chain.ChainID()) + return evm.SetupEnvironment( + chain.ChainID(), + fvmEnv, + runtimeEnv, + chain.ServiceAddress(), + sc.FlowToken.Address, + ) +} + func baseContracts() map[string]common.Address { contracts := make(map[string]common.Address, 0) serviceAddress := common.Address(chain.ServiceAddress())