diff --git a/account_test.go b/account_test.go index bfce366..c94435c 100644 --- a/account_test.go +++ b/account_test.go @@ -17,19 +17,18 @@ func TestErrorsInAccountCreation(t *testing.T) { }) t.Run("Should give error on wrong contract name", func(t *testing.T) { - assert.Panics(t, func() { - NewTestingEmulator().Config("testdata/non_existing_contract.json").Start() - }) + _, err := OverflowTesting(WithFlowConfig("testdata/non_existing_contract.json")) + assert.ErrorContains(t, err, "deployment contains nonexisting contract Debug2") }) t.Run("Should give error on invalid env var in flow.json", func(t *testing.T) { - _, err := NewTestingEmulator().Config("testdata/invalid_env_flow.json").StartE() + _, err := OverflowTesting(WithFlowConfig("testdata/invalid_env_flow.json")) require.Error(t, err) assert.Contains(t, err.Error(), "invalid private key for account: emulator-5") }) t.Run("Should give error on wrong account name", func(t *testing.T) { - _, err := NewTestingEmulator().Config("testdata/invalid_account_in_deployment.json").StartE() + _, err := OverflowTesting(WithFlowConfig("testdata/invalid_account_in_deployment.json")) require.Error(t, err) assert.Contains(t, err.Error(), "deployment contains nonexisting account emulator-firs") }) @@ -39,7 +38,7 @@ func TestErrorsInAccountCreation(t *testing.T) { func TestGetAccount(t *testing.T) { t.Run("Should return the account", func(t *testing.T) { - g, err := NewTestingEmulator().StartE() + g, err := OverflowTesting() require.NoError(t, err) account, err := g.GetAccount("account") @@ -48,7 +47,7 @@ func TestGetAccount(t *testing.T) { }) t.Run("Should return an error if account doesn't exist", func(t *testing.T) { - g, err := NewTestingEmulator().StartE() + g, err := OverflowTesting() require.NoError(t, err) _, err = g.GetAccount("doesnotexist") assert.ErrorContains(t, err, "could not find account with name emulator-doesnotexist in the configuration") @@ -56,7 +55,7 @@ func TestGetAccount(t *testing.T) { }) t.Run("Should return an error if sa does not exist", func(t *testing.T) { - _, err := NewTestingEmulator().SetServiceSuffix("dummy").StartE() + _, err := OverflowTesting(WithServiceAccountSuffix("dummy")) assert.ErrorContains(t, err, "could not find account with name emulator-dummy in the configuration") @@ -67,7 +66,9 @@ func TestGetAccount(t *testing.T) { func TestCheckContractUpdate(t *testing.T) { t.Run("Should return the updatable contracts", func(t *testing.T) { - g, _ := NewTestingEmulator().StartE() + + g, err := OverflowTesting() + require.NoError(t, err) res, err := g.CheckContractUpdates() assert.Nil(t, err) @@ -75,7 +76,8 @@ func TestCheckContractUpdate(t *testing.T) { }) t.Run("Should return the updatable contracts (updatable)", func(t *testing.T) { - g, _ := NewTestingEmulator().StartE() + g, err := OverflowTesting() + require.NoError(t, err) code := []byte(`pub contract Debug{ @@ -128,7 +130,7 @@ func TestCheckContractUpdate(t *testing.T) { Network: "emulator", } - err := g.AddContract("account", contract, true) + err = g.AddContract("account", contract, true) assert.Nil(t, err) res, err := g.CheckContractUpdates() diff --git a/argument.go b/argument.go deleted file mode 100644 index de6e142..0000000 --- a/argument.go +++ /dev/null @@ -1,432 +0,0 @@ -package overflow - -import ( - "fmt" - - "github.com/onflow/cadence" - "github.com/onflow/flow-go-sdk" -) - -// OverflowArgumentsBuilder -// -// # The old way of specifying arguments to interactions -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -type OverflowArgumentsBuilder struct { - Overflow *OverflowState - Arguments []cadence.Value - Error error -} - -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) Build() []cadence.Value { - if a.Error != nil { - panic(a.Error) - } - return a.Arguments -} - -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) RawAddress(address string) *OverflowArgumentsBuilder { - account := flow.HexToAddress(address) - accountArg := cadence.BytesToAddress(account.Bytes()) - return a.Argument(accountArg) -} - -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) Address(key string) *OverflowArgumentsBuilder { - f := a.Overflow - - account, err := f.AccountE(key) - if err != nil { - a.Error = err - return a - } - return a.Argument(cadence.BytesToAddress(account.Address().Bytes())) -} - -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) RawAccount(address string) *OverflowArgumentsBuilder { - account := flow.HexToAddress(address) - accountArg := cadence.BytesToAddress(account.Bytes()) - return a.Argument(accountArg) -} - -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) Account(key string) *OverflowArgumentsBuilder { - f := a.Overflow - - account, err := f.AccountE(key) - if err != nil { - a.Error = err - return a - } - return a.Argument(cadence.BytesToAddress(account.Address().Bytes())) -} - -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) String(value string) *OverflowArgumentsBuilder { - return a.Argument(cadence.String(value)) -} - -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) Boolean(value bool) *OverflowArgumentsBuilder { - return a.Argument(cadence.NewBool(value)) -} - -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) Bytes(value []byte) *OverflowArgumentsBuilder { - return a.Argument(cadence.NewBytes(value)) -} - -// Int add an Int Argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) Int(value int) *OverflowArgumentsBuilder { - return a.Argument(cadence.NewInt(value)) -} - -// Int8 add an Int8 Argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) Int8(value int8) *OverflowArgumentsBuilder { - return a.Argument(cadence.NewInt8(value)) -} - -// Int16 add an Int16 Argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) Int16(value int16) *OverflowArgumentsBuilder { - return a.Argument(cadence.NewInt16(value)) -} - -// Int32 add an Int32 Argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) Int32(value int32) *OverflowArgumentsBuilder { - return a.Argument(cadence.NewInt32(value)) -} - -// Int64 add an Int64 Argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) Int64(value int64) *OverflowArgumentsBuilder { - return a.Argument(cadence.NewInt64(value)) -} - -// Int128 add an Int128 Argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) Int128(value int) *OverflowArgumentsBuilder { - return a.Argument(cadence.NewInt128(value)) -} - -// Int256 add an Int256 Argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) Int256(value int) *OverflowArgumentsBuilder { - return a.Argument(cadence.NewInt256(value)) -} - -// UInt add an UInt Argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) UInt(value uint) *OverflowArgumentsBuilder { - return a.Argument(cadence.NewUInt(value)) -} - -// UInt8 add an UInt8 Argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) UInt8(value uint8) *OverflowArgumentsBuilder { - return a.Argument(cadence.NewUInt8(value)) -} - -// UInt16 add an UInt16 Argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) UInt16(value uint16) *OverflowArgumentsBuilder { - return a.Argument(cadence.NewUInt16(value)) -} - -// UInt32 add an UInt32 Argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) UInt32(value uint32) *OverflowArgumentsBuilder { - return a.Argument(cadence.NewUInt32(value)) -} - -// UInt64 add an UInt64 Argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) UInt64(value uint64) *OverflowArgumentsBuilder { - return a.Argument(cadence.NewUInt64(value)) -} - -// UInt128 add an UInt128 Argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) UInt128(value uint) *OverflowArgumentsBuilder { - return a.Argument(cadence.NewUInt128(value)) -} - -// UInt256 add an UInt256 Argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) UInt256(value uint) *OverflowArgumentsBuilder { - return a.Argument(cadence.NewUInt256(value)) -} - -// Word8 add a Word8 Argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) Word8(value uint8) *OverflowArgumentsBuilder { - return a.Argument(cadence.NewWord8(value)) -} - -// Word16 add a Word16 Argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) Word16(value uint16) *OverflowArgumentsBuilder { - return a.Argument(cadence.NewWord16(value)) -} - -// Word32 add a Word32 Argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) Word32(value uint32) *OverflowArgumentsBuilder { - return a.Argument(cadence.NewWord32(value)) -} - -// Word64 add a Word64 Argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) Word64(value uint64) *OverflowArgumentsBuilder { - return a.Argument(cadence.NewWord64(value)) -} - -// Fix64 add a Fix64 Argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) Fix64(value string) *OverflowArgumentsBuilder { - amount, err := cadence.NewFix64(value) - if err != nil { - a.Error = err - return a - } - return a.Argument(amount) -} - -// DateStringAsUnixTimestamp sends a dateString parsed in the timezone as a unix timeszone ufix -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) DateStringAsUnixTimestamp(dateString string, timezone string) *OverflowArgumentsBuilder { - value, err := parseTime(dateString, timezone) - if err != nil { - a.Error = err - return a - } - - //swallow the error since it will never happen here, we control the input - amount, _ := cadence.NewUFix64(value) - return a.Argument(amount) -} - -// UFix64 add a UFix64 Argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) UFix64(input float64) *OverflowArgumentsBuilder { - value := fmt.Sprintf("%.8f", input) - amount, err := cadence.NewUFix64(value) - if err != nil { - a.Error = err - return a - } - return a.Argument(amount) -} - -// PublicPath argument -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) PublicPath(input string) *OverflowArgumentsBuilder { - path := cadence.Path{Domain: "public", Identifier: input} - return a.Argument(path) -} - -// StoragePath argument -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) StoragePath(input string) *OverflowArgumentsBuilder { - path := cadence.Path{Domain: "storage", Identifier: input} - return a.Argument(path) -} - -// PrivatePath argument -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) PrivatePath(input string) *OverflowArgumentsBuilder { - path := cadence.Path{Domain: "private", Identifier: input} - return a.Argument(path) -} - -// Argument add an argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) Argument(value cadence.Value) *OverflowArgumentsBuilder { - a.Arguments = append(a.Arguments, value) - return a -} - -// Add an {String:String} to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) StringMap(input map[string]string) *OverflowArgumentsBuilder { - array := []cadence.KeyValuePair{} - for key, val := range input { - array = append(array, cadence.KeyValuePair{Key: cadenceString(key), Value: cadenceString(val)}) - } - a.Arguments = append(a.Arguments, cadence.NewDictionary(array)) - return a -} - -// Add an {String:UFix64} to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) ScalarMap(input map[string]string) *OverflowArgumentsBuilder { - array := []cadence.KeyValuePair{} - for key, val := range input { - UFix64Val, err := cadence.NewUFix64(val) - if err != nil { - a.Error = err - return a - } - array = append(array, cadence.KeyValuePair{Key: cadenceString(key), Value: UFix64Val}) - } - a.Arguments = append(a.Arguments, cadence.NewDictionary(array)) - return a -} - -// Argument add an StringArray to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) StringArray(value ...string) *OverflowArgumentsBuilder { - array := []cadence.Value{} - for _, val := range value { - array = append(array, cadenceString(val)) - } - a.Arguments = append(a.Arguments, cadence.NewArray(array)) - return a -} - -// Argument add an StringMapArray to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) StringMapArray(value ...map[string]string) *OverflowArgumentsBuilder { - array := []cadence.Value{} - for _, vals := range value { - dict := []cadence.KeyValuePair{} - for key, val := range vals { - dict = append(dict, cadence.KeyValuePair{Key: cadenceString(key), Value: cadenceString(val)}) - } - array = append(array, cadence.NewDictionary(dict)) - } - a.Arguments = append(a.Arguments, cadence.NewArray(array)) - return a -} - -// Argument add an StringArray to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) ScalarMapArray(value ...map[string]string) *OverflowArgumentsBuilder { - array := []cadence.Value{} - for _, vals := range value { - dict := []cadence.KeyValuePair{} - for key, val := range vals { - UFix64Val, err := cadence.NewUFix64(val) - if err != nil { - a.Error = err - return a - } - dict = append(dict, cadence.KeyValuePair{Key: cadenceString(key), Value: UFix64Val}) - } - array = append(array, cadence.NewDictionary(dict)) - } - a.Arguments = append(a.Arguments, cadence.NewArray(array)) - return a -} - -// Argument add a RawAddressArray to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) RawAddressArray(value ...string) *OverflowArgumentsBuilder { - array := []cadence.Value{} - for _, val := range value { - address := flow.HexToAddress(val) - cadenceAddress := cadence.BytesToAddress(address.Bytes()) - array = append(array, cadenceAddress) - } - a.Arguments = append(a.Arguments, cadence.NewArray(array)) - return a -} - -// Argument add a RawAddressArray to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) AccountArray(value ...string) *OverflowArgumentsBuilder { - array := []cadence.Value{} - for _, val := range value { - address, err := a.Overflow.AccountE(val) - if err != nil { - a.Error = err - return a - } - cadenceAddress := cadence.BytesToAddress(address.Address().Bytes()) - array = append(array, cadenceAddress) - } - a.Arguments = append(a.Arguments, cadence.NewArray(array)) - return a -} - -// Argument add an argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) UInt64Array(value ...uint64) *OverflowArgumentsBuilder { - array := []cadence.Value{} - for _, val := range value { - cadenceVal := cadence.NewUInt64(val) - array = append(array, cadenceVal) - } - a.Arguments = append(a.Arguments, cadence.NewArray(array)) - return a -} - -// Argument add an argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) UInt8Array(value ...uint8) *OverflowArgumentsBuilder { - array := []cadence.Value{} - for _, val := range value { - cadenceVal := cadence.NewUInt8(val) - array = append(array, cadenceVal) - } - a.Arguments = append(a.Arguments, cadence.NewArray(array)) - return a -} - -// Argument add an argument to the transaction -// -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (a *OverflowArgumentsBuilder) UFix64Array(value ...float64) *OverflowArgumentsBuilder { - array := []cadence.Value{} - for _, val := range value { - stringValue := fmt.Sprintf("%f", val) - amount, err := cadence.NewUFix64(stringValue) - if err != nil { - a.Error = err - return a - } - array = append(array, amount) - } - a.Arguments = append(a.Arguments, cadence.NewArray(array)) - return a -} diff --git a/argument_test.go b/argument_test.go deleted file mode 100644 index e5e02a7..0000000 --- a/argument_test.go +++ /dev/null @@ -1,239 +0,0 @@ -package overflow - -import ( - "testing" - - "github.com/hexops/autogold" - "github.com/onflow/cadence" - "github.com/onflow/flow-go-sdk" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -/* -Tests must be in the same folder as flow.json with contracts and transactions/scripts in subdirectories in order for the path resolver to work correctly -*/ -func TestArguments(t *testing.T) { - g, err := NewTestingEmulator().StartE() - require.NoError(t, err) - t.Parallel() - - t.Run("Argument test", func(t *testing.T) { - - fix, _ := cadence.NewFix64("-1.0") - ufix, _ := cadence.NewUFix64("1.0") - dateFix, _ := cadence.NewUFix64("1627560000.00000000") - - foo, _ := cadence.NewString("foo") - bar, _ := cadence.NewString("bar") - - address1 := flow.HexToAddress("f8d6e0586b0a20c7") - address2 := flow.HexToAddress("01cf0e2f2f715450") - cadenceAddress1 := cadence.BytesToAddress(address1.Bytes()) - cadenceAddress2 := cadence.BytesToAddress(address2.Bytes()) - - stringValues := []cadence.Value{foo, bar} - addressValues := []cadence.Value{cadenceAddress1, cadenceAddress2} - - builder := g.Arguments().Boolean(true). - Bytes([]byte{1}). - Fix64("-1.0"). - UFix64(1.0). - DateStringAsUnixTimestamp("July 29, 2021 08:00:00 AM", "America/New_York"). - StringArray("foo", "bar"). - RawAddressArray("f8d6e0586b0a20c7", "01cf0e2f2f715450") - - assert.Contains(t, builder.Arguments, cadence.NewBool(true)) - assert.Contains(t, builder.Arguments, cadence.NewBytes([]byte{1})) - assert.Contains(t, builder.Arguments, fix) - assert.Contains(t, builder.Arguments, ufix) - assert.Contains(t, builder.Arguments, dateFix) - assert.Contains(t, builder.Arguments, cadence.NewArray(stringValues)) - assert.Contains(t, builder.Arguments, cadence.NewArray(addressValues)) - }) - - t.Run("Word argument test", func(t *testing.T) { - builder := g.Arguments(). - Word8(8). - Word16(16). - Word32(32). - Word64(64) - - assert.Contains(t, builder.Arguments, cadence.NewWord8(8)) - assert.Contains(t, builder.Arguments, cadence.NewWord16(16)) - assert.Contains(t, builder.Arguments, cadence.NewWord32(32)) - assert.Contains(t, builder.Arguments, cadence.NewWord64(64)) - }) - - t.Run("UInt argument test", func(t *testing.T) { - builder := g.Arguments(). - UInt(1). - UInt8(8). - UInt16(16). - UInt32(32). - UInt64(64). - UInt128(128). - UInt256(256) - - assert.Contains(t, builder.Arguments, cadence.NewUInt(1)) - assert.Contains(t, builder.Arguments, cadence.NewUInt8(8)) - assert.Contains(t, builder.Arguments, cadence.NewUInt16(16)) - assert.Contains(t, builder.Arguments, cadence.NewUInt32(32)) - assert.Contains(t, builder.Arguments, cadence.NewUInt64(64)) - assert.Contains(t, builder.Arguments, cadence.NewUInt128(128)) - assert.Contains(t, builder.Arguments, cadence.NewUInt256(256)) - }) - - t.Run("Int argument test", func(t *testing.T) { - builder := g.Arguments(). - Int(1). - Int8(-8). - Int16(16). - Int32(32). - Int64(64). - Int128(128). - Int256(256) - - assert.Contains(t, builder.Arguments, cadence.NewInt(1)) - assert.Contains(t, builder.Arguments, cadence.NewInt8(-8)) - assert.Contains(t, builder.Arguments, cadence.NewInt16(16)) - assert.Contains(t, builder.Arguments, cadence.NewInt32(32)) - assert.Contains(t, builder.Arguments, cadence.NewInt64(64)) - assert.Contains(t, builder.Arguments, cadence.NewInt128(128)) - assert.Contains(t, builder.Arguments, cadence.NewInt256(256)) - }) - - t.Run("Raw address", func(t *testing.T) { - builder := g.Arguments().RawAddress("0x01cf0e2f2f715450") - autogold.Equal(t, builder.Arguments) - }) - - t.Run("Address", func(t *testing.T) { - builder := g.Arguments().Address("first") - autogold.Equal(t, builder.Arguments) - }) - - t.Run("Fix64 error", func(t *testing.T) { - builder := g.Arguments().Fix64("first") - assert.ErrorContains(t, builder.Error, "missing decimal point") - }) - - t.Run("Fix64 error build", func(t *testing.T) { - assert.Panics(t, func() { - g.Arguments().Fix64("first").Build() - }) - }) - - t.Run("UFix64 error", func(t *testing.T) { - builder := g.Arguments().UFix64(-1.0) - assert.ErrorContains(t, builder.Error, "invalid negative integer part") - }) - - t.Run("UFix64Array error", func(t *testing.T) { - builder := g.Arguments().UFix64Array(-1.0) - assert.ErrorContains(t, builder.Error, "invalid negative integer part") - }) - - t.Run("DateTime wrong locale", func(t *testing.T) { - builder := g.Arguments().DateStringAsUnixTimestamp("asd", "asd") - assert.ErrorContains(t, builder.Error, "unknown time zone as") - }) - - t.Run("DateTime wrong string", func(t *testing.T) { - builder := g.Arguments().DateStringAsUnixTimestamp("asd", "Europe/Oslo") - assert.ErrorContains(t, builder.Error, "Could not find format for \"asd\"") - }) - - t.Run("Paths", func(t *testing.T) { - builder := g.Arguments().PublicPath("foo").StoragePath("foo").PrivatePath("foo") - autogold.Equal(t, builder.Arguments) - }) - - t.Run("StringMap", func(t *testing.T) { - builder := g.Arguments().StringMap(map[string]string{"foo": "bar"}) - autogold.Equal(t, builder.Arguments) - }) - - t.Run("ScalarMap", func(t *testing.T) { - builder := g.Arguments().ScalarMap(map[string]string{"foo": "1.0"}) - autogold.Equal(t, builder.Arguments) - }) - - t.Run("ScalarMapError", func(t *testing.T) { - builder := g.Arguments().ScalarMap(map[string]string{"foo": "foo"}) - assert.ErrorContains(t, builder.Error, "missing decimal point") - }) - - t.Run("StringArray", func(t *testing.T) { - builder := g.Arguments().StringArray("foo", "bar") - autogold.Equal(t, builder.Arguments) - }) - - t.Run("StringMapArray", func(t *testing.T) { - builder := g.Arguments().StringMapArray(map[string]string{"Sith": "Darth Vader"}, map[string]string{"Jedi": "Luke"}) - autogold.Equal(t, builder.Arguments) - }) - - t.Run("ScalarMapArray", func(t *testing.T) { - builder := g.Arguments().ScalarMapArray(map[string]string{"Sith": "2.0"}, map[string]string{"Jedi": "1000.0"}) - autogold.Equal(t, builder.Arguments) - }) - - t.Run("ScalarMapArray error", func(t *testing.T) { - builder := g.Arguments().ScalarMapArray(map[string]string{"Sith": "2.0"}, map[string]string{"Jedi": "asd"}) - assert.ErrorContains(t, builder.Error, "missing decimal point") - }) - - t.Run("AccountArray", func(t *testing.T) { - builder := g.Arguments().AccountArray("first", "second") - autogold.Equal(t, builder.Arguments) - }) - - t.Run("Uint64Array", func(t *testing.T) { - builder := g.Arguments().UInt64Array(1, 2, 3) - autogold.Equal(t, builder.Arguments) - }) - - t.Run("Uint8Array", func(t *testing.T) { - builder := g.Arguments().UInt8Array(1, 2, 3) - autogold.Equal(t, builder.Arguments) - }) - - t.Run("UFix64Array", func(t *testing.T) { - builder := g.Arguments().UFix64Array(1.0, 2.0, 3.0) - autogold.Equal(t, builder.Arguments) - }) - - t.Run("Argument string array", func(t *testing.T) { - builder := g.Transaction(` -transaction(names: [String]) { - -} -`).NamedArguments(map[string]string{ - "names": `["Bjarte", "Karlsen"]`, - }) - - arrayValues := []cadence.Value{ - cadenceString("Bjarte"), - cadenceString("Karlsen"), - } - assert.Contains(t, builder.Arguments, cadence.NewArray(arrayValues)) - - }) - - t.Run("Argument ufix64 array", func(t *testing.T) { - builder := g.Transaction(` -transaction(names: [UFix64]) { - -} -`).NamedArguments(map[string]string{ - "names": `[10.0, 20.0]`, - }) - - fix, _ := cadence.NewUFix64("10.0") - fix1, _ := cadence.NewUFix64("20.0") - arrayValues := []cadence.Value{fix, fix1} - assert.Contains(t, builder.Arguments, cadence.NewArray(arrayValues)) - - }) -} diff --git a/blocks_test.go b/blocks_test.go index afc99ae..c78050b 100644 --- a/blocks_test.go +++ b/blocks_test.go @@ -10,7 +10,7 @@ import ( func TestGetBlock(t *testing.T) { t.Run("Should get latest block", func(t *testing.T) { - g, err := NewTestingEmulator().StartE() + g, err := OverflowTesting() require.NoError(t, err) block, err := g.GetLatestBlock() @@ -19,7 +19,7 @@ func TestGetBlock(t *testing.T) { }) t.Run("Should get block by height", func(t *testing.T) { - g, err := NewTestingEmulator().StartE() + g, err := OverflowTesting() require.NoError(t, err) block, err := g.GetBlockAtHeight(0) @@ -29,7 +29,7 @@ func TestGetBlock(t *testing.T) { t.Run("Should get block by ID", func(t *testing.T) { BlockZeroID := "13c7ff23bb65feb5757cc65fdd75cd243506518c126385fae530ddebdad10b17" - g, err := NewTestingEmulator().StartE() + g, err := OverflowTesting() require.NoError(t, err) block, err := g.GetBlockById(BlockZeroID) diff --git a/cadence_test.go b/cadence_test.go index ae9a13a..1af64c9 100644 --- a/cadence_test.go +++ b/cadence_test.go @@ -161,6 +161,37 @@ func TestMarshalCadenceStructWithStructTag(t *testing.T) { } +func TestPrimitiveInptuToCadence(t *testing.T) { + tests := []struct { + name string + value interface{} + }{ + {name: "int", value: 1}, + {name: "int8", value: int8(8)}, + {name: "int16", value: int16(16)}, + {name: "int32", value: int32(32)}, + {name: "int64", value: int64(64)}, + {name: "uint8", value: uint8(8)}, + {name: "uint16", value: uint16(16)}, + {name: "uint32", value: uint32(32)}, + {name: "true", value: true}, + {name: "false", value: false}, + } + + resolver := func(string) (string, error) { + return "", nil + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + cadenceValue, err := InputToCadence(test.value, resolver) + assert.NoError(t, err) + result2 := CadenceValueToInterface(cadenceValue) + assert.Equal(t, test.value, result2) + }) + } +} + // in Debug.cdc type Foo struct { Bar string diff --git a/event_fetcher_integration_test.go b/event_fetcher_integration_test.go index 1fcf39c..c4ac18b 100644 --- a/event_fetcher_integration_test.go +++ b/event_fetcher_integration_test.go @@ -13,7 +13,7 @@ import ( func startOverflowAndMintTokens(t *testing.T) *OverflowState { t.Helper() - o, err := NewTestingEmulator().StartE() + o, err := OverflowTesting() require.NoError(t, err) result := o.Tx("mint_tokens", WithSignerServiceAccount(), WithArg("recipient", "first"), WithArg("amount", 100.0)) assert.NoError(t, result.Err) @@ -33,17 +33,6 @@ type MarketEvent struct { func TestIntegrationEventFetcher(t *testing.T) { - t.Run("Test that if end is larger then from we return with empty result", func(t *testing.T) { - result, err := startOverflowAndMintTokens(t).FetchEvents( - WithEndIndex(2), - WithFromIndex(1), - WithEvent("A.0ae53cb6e3f42a79.FlowToken.TokensMinted"), - ) - assert.NoError(t, err) - assert.Equal(t, len(result), 0) - - }) - t.Run("Test that from index cannot be negative", func(t *testing.T) { _, err := startOverflowAndMintTokens(t).FetchEvents( WithEndIndex(2), @@ -111,7 +100,7 @@ func TestIntegrationEventFetcher(t *testing.T) { ) defer os.Remove("progress") assert.NoError(t, err) - assert.Equal(t, 1, len(ev)) + assert.Equal(t, 3, len(ev)) event := ev[0] graffleEvent := event.ToGraffleEvent() @@ -123,7 +112,7 @@ func TestIntegrationEventFetcher(t *testing.T) { autogold.Equal(t, graffleEvent.BlockEventData, autogold.Name("graffle-event")) var marshalTo MarketEvent assert.NoError(t, graffleEvent.MarshalAs(&marshalTo)) - assert.Equal(t, float64(100), marshalTo.BlockEventData.Amount) + assert.Equal(t, float64(10), marshalTo.BlockEventData.Amount) }) t.Run("Return progress writer ", func(t *testing.T) { @@ -137,6 +126,10 @@ func TestIntegrationEventFetcher(t *testing.T) { WithReturnProgressWriter(), ) require.NoError(t, res.Error) + want := autogold.Want("eventProgress", `Fetched number=1 of events within from=8 block to=8 for events=A.0ae53cb6e3f42a79.FlowToken.TokensMinted +`) + want.Equal(t, res.String()) + progress, err := readProgressFromFile(progressFile) require.NoError(t, err) assert.Equal(t, int64(0), progress) @@ -145,7 +138,7 @@ func TestIntegrationEventFetcher(t *testing.T) { progress, err = readProgressFromFile(progressFile) require.NoError(t, err) - assert.Equal(t, int64(7), progress) + assert.Equal(t, int64(9), progress) ev := res.Events defer os.Remove(progressFile) diff --git a/event_fetcher_old.go b/event_fetcher_old.go deleted file mode 100644 index 1575733..0000000 --- a/event_fetcher_old.go +++ /dev/null @@ -1,344 +0,0 @@ -package overflow - -import ( - "encoding/json" - "fmt" - "log" - "reflect" - "sort" - "strconv" - "time" - - "github.com/onflow/flow-go-sdk" -) - -// Deprecated: Deprecated in favor of FetchEvent with builder -// -// EventFetcher create an event fetcher builder. -func (o *OverflowState) EventFetcher() OverflowEventFetcherBuilder { - return OverflowEventFetcherBuilder{ - OverflowState: o, - EventsAndIgnoreFields: map[string][]string{}, - EndAtCurrentHeight: true, - FromIndex: -10, - ProgressFile: "", - EventBatchSize: 250, - NumberOfWorkers: 20, - } -} - -// Deprecated: Deprecated in favor of FetchEvent with builder -// -// Workers sets the number of workers. -func (e OverflowEventFetcherBuilder) Workers(workers int) OverflowEventFetcherBuilder { - e.NumberOfWorkers = workers - return e -} - -// Deprecated: Deprecated in favor of FetchEvent with builder -// -// BatchSize sets the size of a batch -func (e OverflowEventFetcherBuilder) BatchSize(batchSize uint64) OverflowEventFetcherBuilder { - e.EventBatchSize = batchSize - return e -} - -// Deprecated: Deprecated in favor of FetchEvent with builder -// -// Event fetches and Events and all its fields -func (e OverflowEventFetcherBuilder) Event(eventName string) OverflowEventFetcherBuilder { - e.EventsAndIgnoreFields[eventName] = []string{} - return e -} - -// Deprecated: Deprecated in favor of FetchEvent with builder -// -// EventIgnoringFields fetch event and ignore the specified fields -func (e OverflowEventFetcherBuilder) EventIgnoringFields(eventName string, ignoreFields []string) OverflowEventFetcherBuilder { - e.EventsAndIgnoreFields[eventName] = ignoreFields - return e -} - -// Deprecated: Deprecated in favor of FetchEvent with builder -// -// Start specify what blockHeight to fetch starting atm. This can be negative related to end/until -func (e OverflowEventFetcherBuilder) Start(blockHeight int64) OverflowEventFetcherBuilder { - e.FromIndex = blockHeight - return e -} - -// Deprecated: Deprecated in favor of FetchEvent with builder -// -// From specify what blockHeight to fetch from. This can be negative related to end. -func (e OverflowEventFetcherBuilder) From(blockHeight int64) OverflowEventFetcherBuilder { - e.FromIndex = blockHeight - return e -} - -// Deprecated: Deprecated in favor of FetchEvent with builder -// -// End specify what index to end at -func (e OverflowEventFetcherBuilder) End(blockHeight uint64) OverflowEventFetcherBuilder { - e.EndIndex = blockHeight - e.EndAtCurrentHeight = false - return e -} - -// Deprecated: Deprecated in favor of FetchEvent with builder -// -// Last fetch events from the number last blocks -func (e OverflowEventFetcherBuilder) Last(number uint64) OverflowEventFetcherBuilder { - e.EndAtCurrentHeight = true - e.FromIndex = -int64(number) - return e -} - -// Deprecated: Deprecated in favor of FetchEvent with builder -// -// Until specify what index to end at -func (e OverflowEventFetcherBuilder) Until(blockHeight uint64) OverflowEventFetcherBuilder { - e.EndIndex = blockHeight - e.EndAtCurrentHeight = false - return e -} - -// Deprecated: Deprecated in favor of FetchEvent with builder -// -// UntilCurrent Specify to fetch events until the current Block -func (e OverflowEventFetcherBuilder) UntilCurrent() OverflowEventFetcherBuilder { - e.EndAtCurrentHeight = true - e.EndIndex = 0 - return e -} - -// Deprecated: Deprecated in favor of FetchEvent with builder -// -// TrackProgressIn Specify a file to store progress in -func (e OverflowEventFetcherBuilder) TrackProgressIn(fileName string) OverflowEventFetcherBuilder { - e.ProgressFile = fileName - e.EndIndex = 0 - e.FromIndex = 0 - e.EndAtCurrentHeight = true - return e -} - -// Deprecated: Deprecated in favor of FetchEvent with builder -// -// Run runs the eventfetcher returning events or an error -func (e OverflowEventFetcherBuilder) Run() ([]*OverflowFormatedEvent, error) { - - //if we have a progress file read the value from it and set it as oldHeight - if e.ProgressFile != "" { - - present, err := exists(e.ProgressFile) - if err != nil { - return nil, err - } - - if !present { - err := writeProgressToFile(e.ProgressFile, 0) - if err != nil { - return nil, fmt.Errorf("could not create initial progress file %v", err) - } - - e.FromIndex = 0 - } else { - oldHeight, err := readProgressFromFile(e.ProgressFile) - if err != nil { - return nil, fmt.Errorf("could not parse progress file as block height %v", err) - } - e.FromIndex = oldHeight - } - } - - endIndex := e.EndIndex - if e.EndAtCurrentHeight { - blockHeight, err := e.OverflowState.Services.Blocks.GetLatestBlockHeight() - if err != nil { - return nil, err - } - endIndex = blockHeight - } - - fromIndex := e.FromIndex - //if we have a negative fromIndex is is relative to endIndex - if e.FromIndex <= 0 { - fromIndex = int64(endIndex) + e.FromIndex - } - - if fromIndex < 0 { - return nil, fmt.Errorf("FromIndex is negative") - } - - e.OverflowState.Logger.Info(fmt.Sprintf("Fetching events from %d to %d", fromIndex, endIndex)) - - var events []string - for key := range e.EventsAndIgnoreFields { - events = append(events, key) - } - - blockEvents, err := e.OverflowState.Services.Events.Get(events, uint64(fromIndex), endIndex, e.EventBatchSize, e.NumberOfWorkers) - if err != nil { - return nil, err - } - - formatedEvents := FormatEvents(blockEvents, e.EventsAndIgnoreFields) - - if e.ProgressFile != "" { - err := writeProgressToFile(e.ProgressFile, endIndex+1) - if err != nil { - return nil, fmt.Errorf("could not write progress to file %v", err) - } - } - sort.Slice(formatedEvents, func(i, j int) bool { - return formatedEvents[i].BlockHeight < formatedEvents[j].BlockHeight - }) - - return formatedEvents, nil - -} - -// Deprecated: Deprecated in favor of FetchEvent with builder -// -// PrintEvents prints th events, ignoring fields specified for the given event typeID -func PrintEvents(events []flow.Event, ignoreFields map[string][]string) { - if len(events) > 0 { - log.Println("EVENTS") - log.Println("======") - } - - for _, event := range events { - ignoreFieldsForType := ignoreFields[event.Type] - ev := ParseEvent(event, uint64(0), time.Now(), ignoreFieldsForType) - prettyJSON, err := json.MarshalIndent(ev, "", " ") - - if err != nil { - panic(err) - } - - log.Printf("%s\n", string(prettyJSON)) - } - if len(events) > 0 { - log.Println("======") - } -} - -// FormatEvents -func FormatEvents(blockEvents []flow.BlockEvents, ignoreFields map[string][]string) []*OverflowFormatedEvent { - var events []*OverflowFormatedEvent - - for _, blockEvent := range blockEvents { - for _, event := range blockEvent.Events { - ev := ParseEvent(event, blockEvent.Height, blockEvent.BlockTimestamp, ignoreFields[event.Type]) - events = append(events, ev) - } - } - return events -} - -// ParseEvent parses a flow event into a more terse representation -func ParseEvent(event flow.Event, blockHeight uint64, time time.Time, ignoreFields []string) *OverflowFormatedEvent { - - var fieldNames []string - - for _, eventTypeFields := range event.Value.EventType.Fields { - fieldNames = append(fieldNames, eventTypeFields.Identifier) - } - - finalFields := map[string]interface{}{} - - for id, field := range event.Value.Fields { - - skip := false - name := fieldNames[id] - - for _, ignoreField := range ignoreFields { - if ignoreField == name { - skip = true - } - } - if skip { - continue - } - value := CadenceValueToInterface(field) - if value != nil { - finalFields[name] = value - } - } - return &OverflowFormatedEvent{ - Name: event.Type, - Fields: finalFields, - BlockHeight: blockHeight, - Time: time, - } -} - -// Deprecated: Deprecated in favor of FetchEvent with builder -// -// OverflowFormatedEvent event in a more condensed formated form -type OverflowFormatedEvent struct { - Name string `json:"name"` - BlockHeight uint64 `json:"blockHeight,omitempty"` - Time time.Time `json:"time,omitempty"` - Fields map[string]interface{} `json:"fields"` -} - -// Deprecated: Deprecated in favor of FetchEvent with builder -func (o OverflowFormatedEvent) ExistIn(events []*OverflowFormatedEvent) bool { - for _, ev := range events { - result := reflect.DeepEqual(o, *ev) - if result { - return true - } - } - return false -} - -// Deprecated: Deprecated in favor of FetchEvent with builder -func (fe OverflowFormatedEvent) ShortName() string { - return fe.Name[19:] -} - -// Deprecated: Deprecated in favor of FetchEvent with builder -func NewTestEvent(name string, fields map[string]interface{}) *OverflowFormatedEvent { - loc, _ := time.LoadLocation("UTC") - // handle err - time.Local = loc // -> this is setting the global timezone - newFields := map[string]interface{}{} - for key, value := range fields { - if value != nil { - newFields[key] = value - } - } - return &OverflowFormatedEvent{ - Name: name, - BlockHeight: 0, - Time: time.Unix(0, 0), - Fields: newFields, - } -} - -// Deprecated: Deprecated in favor of FetchEvent with builder -// -// String pretty print an event as a String -func (e OverflowFormatedEvent) String() string { - j, err := json.MarshalIndent(e, "", " ") - if err != nil { - panic(err) - } - return string(j) -} - -// Deprecated: Deprecated in favor of FetchEvent with builder -func (e OverflowFormatedEvent) GetFieldAsUInt64(field string) uint64 { - id := e.Fields[field] - fieldAsString := fmt.Sprintf("%v", id) - if fieldAsString == "" { - panic("field is empty") - } - n, err := strconv.ParseUint(fieldAsString, 10, 64) - if err != nil { - panic(err) - } - return n -} diff --git a/event_fetcher_test.go b/event_fetcher_test.go index 5cc9d00..eab8a02 100644 --- a/event_fetcher_test.go +++ b/event_fetcher_test.go @@ -10,7 +10,7 @@ import ( func TestEventFetcher(t *testing.T) { - g, err := NewTestingEmulator().StartE() + g, err := OverflowTesting() require.NoError(t, err) t.Run("Start argument", func(t *testing.T) { diff --git a/event_integration_test.go b/event_integration_test.go index b32fe79..c666b30 100644 --- a/event_integration_test.go +++ b/event_integration_test.go @@ -12,81 +12,73 @@ import ( func TestIntegrationEvents(t *testing.T) { t.Run("Test that from index cannot be negative", func(t *testing.T) { - g, err := NewTestingEmulator().StartE() + g, err := OverflowTesting() require.NoError(t, err) - g.TransactionFromFile("mint_tokens"). - SignProposeAndPayAsService(). - Args(g.Arguments(). - Account("first"). - UFix64(100.0)). - Test(t). - AssertSuccess(). - AssertEventCount(3) - - _, err = g.EventFetcher().End(2).From(-10).Event("A.0ae53cb6e3f42a79.FlowToken.TokensMinted").Run() + + g.Tx("mint_tokens", + WithSignerServiceAccount(), + WithArg("recipient", "first"), + WithArg("amount", 100.0), + ).AssertSuccess(t). + AssertEventCount(t, 3) + + _, err = g.FetchEvents( + WithEndIndex(2), + WithFromIndex(-10), + WithEvent("A.0ae53cb6e3f42a79.FlowToken.TokensMinted"), + ) assert.Error(t, err) assert.Contains(t, err.Error(), "FromIndex is negative") }) t.Run("Fetch last events", func(t *testing.T) { - - g, err := NewTestingEmulator().StartE() + g, err := OverflowTesting() require.NoError(t, err) - g.TransactionFromFile("mint_tokens"). - SignProposeAndPayAsService(). - Args(g.Arguments(). - Account("first"). - UFix64(100.0)). - Test(t). - AssertSuccess(). - AssertEventCount(3) - - ev, err := g.EventFetcher().Last(2).Event("A.0ae53cb6e3f42a79.FlowToken.TokensMinted").Run() + g.Tx("mint_tokens", + WithSignerServiceAccount(), + WithArg("recipient", "first"), + WithArg("amount", 100.0), + ).AssertSuccess(t). + AssertEventCount(t, 3) + ev, err := g.FetchEvents(WithLastBlocks(2), WithEvent("A.0ae53cb6e3f42a79.FlowToken.TokensMinted")) assert.NoError(t, err) assert.Equal(t, 1, len(ev)) }) t.Run("Fetch last events and sort them ", func(t *testing.T) { - - g, err := NewTestingEmulator().StartE() + g, err := OverflowTesting() require.NoError(t, err) - g.TransactionFromFile("mint_tokens"). - SignProposeAndPayAsService(). - Args(g.Arguments(). - Account("first"). - UFix64(100.0)). - Test(t). - AssertSuccess(). - AssertEventCount(3) - - g.TransactionFromFile("mint_tokens"). - SignProposeAndPayAsService(). - Args(g.Arguments(). - Account("first"). - UFix64(100.0)). - Test(t). - AssertSuccess(). - AssertEventCount(3) - - ev, err := g.EventFetcher().Last(3).Event("A.0ae53cb6e3f42a79.FlowToken.TokensMinted").Run() + g.Tx("mint_tokens", + WithSignerServiceAccount(), + WithArg("recipient", "first"), + WithArg("amount", 100.0), + ).AssertSuccess(t). + AssertEventCount(t, 3) + + g.Tx("mint_tokens", + WithSignerServiceAccount(), + WithArg("recipient", "first"), + WithArg("amount", 100.0), + ).AssertSuccess(t). + AssertEventCount(t, 3) + + ev, err := g.FetchEvents(WithLastBlocks(2), WithEvent("A.0ae53cb6e3f42a79.FlowToken.TokensMinted")) assert.NoError(t, err) assert.Equal(t, 2, len(ev)) assert.True(t, ev[0].BlockHeight < ev[1].BlockHeight) }) t.Run("Fetch last write progress file", func(t *testing.T) { - g, err := NewTestingEmulator().StartE() + g, err := OverflowTesting() require.NoError(t, err) - g.TransactionFromFile("mint_tokens"). - SignProposeAndPayAsService(). - Args(g.Arguments(). - Account("first"). - UFix64(100.0)). - Test(t). - AssertSuccess(). - AssertEventCount(3) - - ev, err := g.EventFetcher().Event("A.0ae53cb6e3f42a79.FlowToken.TokensMinted").TrackProgressIn("progress").Run() + g.Tx("mint_tokens", + WithSignerServiceAccount(), + WithArg("recipient", "first"), + WithArg("amount", 100.0), + ).AssertSuccess(t). + AssertEventCount(t, 3) + + ev, err := g.FetchEvents(WithEvent("A.0ae53cb6e3f42a79.FlowToken.TokensMinted"), WithTrackProgressIn("progress")) defer os.Remove("progress") assert.NoError(t, err) assert.Equal(t, 1, len(ev)) @@ -96,9 +88,10 @@ func TestIntegrationEvents(t *testing.T) { err := os.WriteFile("progress", []byte("invalid"), fs.ModePerm) assert.NoError(t, err) - g, err := NewTestingEmulator().StartE() + g, err := OverflowTesting() require.NoError(t, err) - _, err = g.EventFetcher().Event("A.0ae53cb6e3f42a79.FlowToken.TokensMinted").TrackProgressIn("progress").Run() + + _, err = g.FetchEvents(WithEvent("A.0ae53cb6e3f42a79.FlowToken.TokensMinted"), WithTrackProgressIn("progress")) defer os.Remove("progress") assert.Error(t, err) assert.Equal(t, "could not parse progress file as block height strconv.ParseInt: parsing \"invalid\": invalid syntax", err.Error()) @@ -109,20 +102,18 @@ func TestIntegrationEvents(t *testing.T) { err := os.WriteFile("progress", []byte("1"), fs.ModePerm) assert.NoError(t, err) - g, err := NewTestingEmulator().StartE() - require.NoError(t, err) - g.TransactionFromFile("mint_tokens"). - SignProposeAndPayAsService(). - Args(g.Arguments(). - Account("first"). - UFix64(100.0)). - Test(t). - AssertSuccess(). - AssertEventCount(3) - - ev, err := g.EventFetcher().Event("A.0ae53cb6e3f42a79.FlowToken.TokensMinted").TrackProgressIn("progress").Run() + g, err := OverflowTesting() + assert.NoError(t, err) + g.Tx("mint_tokens", + WithSignerServiceAccount(), + WithArg("recipient", "first"), + WithArg("amount", 100.0), + ).AssertSuccess(t). + AssertEventCount(t, 3) + + ev, err := g.FetchEvents(WithEvent("A.0ae53cb6e3f42a79.FlowToken.TokensMinted"), WithTrackProgressIn("progress")) defer os.Remove("progress") assert.NoError(t, err) - assert.Equal(t, 1, len(ev)) + assert.Equal(t, 3, len(ev)) }) } diff --git a/event_test.go b/event_test.go deleted file mode 100644 index 99c3699..0000000 --- a/event_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package overflow - -import ( - "os" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestEvent(t *testing.T) { - - g, err := NewTestingEmulator().StartE() - require.NoError(t, err) - - t.Run("Start argument", func(t *testing.T) { - ef := g.EventFetcher().Start(100) - assert.Equal(t, ef.FromIndex, int64(100)) - }) - - t.Run("From argument", func(t *testing.T) { - ef := g.EventFetcher().From(100) - assert.Equal(t, ef.FromIndex, int64(100)) - }) - - t.Run("End argument", func(t *testing.T) { - ef := g.EventFetcher().End(100) - assert.Equal(t, ef.EndIndex, uint64(100)) - assert.False(t, ef.EndAtCurrentHeight) - }) - - t.Run("Until argument", func(t *testing.T) { - ef := g.EventFetcher().Until(100) - assert.Equal(t, ef.EndIndex, uint64(100)) - assert.False(t, ef.EndAtCurrentHeight) - }) - - t.Run("Until current argument", func(t *testing.T) { - ef := g.EventFetcher().UntilCurrent() - assert.Equal(t, ef.EndIndex, uint64(0)) - assert.True(t, ef.EndAtCurrentHeight) - }) - - t.Run("workers argument", func(t *testing.T) { - ef := g.EventFetcher().Workers(100) - assert.Equal(t, ef.NumberOfWorkers, 100) - }) - - t.Run("batch size argument", func(t *testing.T) { - ef := g.EventFetcher().BatchSize(100) - assert.Equal(t, ef.EventBatchSize, uint64(100)) - }) - - t.Run("event ignoring field argument", func(t *testing.T) { - ef := g.EventFetcher().EventIgnoringFields("foo", []string{"bar", "baz"}) - assert.Equal(t, ef.EventsAndIgnoreFields["foo"], []string{"bar", "baz"}) - }) - - t.Run("failed reading invalid file", func(t *testing.T) { - _, err := readProgressFromFile("boing.boinb") - assert.Error(t, err) - assert.Contains(t, err.Error(), "ProgressFile is not valid open boing.boinb") - }) - - t.Run("Cannot write to file that is dir", func(t *testing.T) { - err := os.Mkdir("foo", os.ModeDir) - assert.NoError(t, err) - defer os.RemoveAll("foo") - - err = writeProgressToFile("foo", 1) - assert.Error(t, err) - assert.Contains(t, err.Error(), "foo: is a directory") - - }) -} diff --git a/generate_test.go b/generate_test.go index bcde916..e4bd823 100644 --- a/generate_test.go +++ b/generate_test.go @@ -12,7 +12,7 @@ Tests must be in the same folder as flow.json with contracts and transactions/sc */ func TestGenerate(t *testing.T) { - o, err := NewTestingEmulator().StartE() + o, err := OverflowTesting() require.NoError(t, err) t.Run("script", func(t *testing.T) { stub, err := o.GenerateStub("emulator", "scripts/test.cdc", false) diff --git a/interaction_builder.go b/interaction_builder.go index bc83d04..e7d3bf3 100644 --- a/interaction_builder.go +++ b/interaction_builder.go @@ -6,8 +6,6 @@ import ( "fmt" "math" "strings" - "testing" - "time" "github.com/enescakir/emoji" "github.com/onflow/cadence" @@ -81,24 +79,6 @@ type OverflowInteractionBuilder struct { PrintOptions *[]OverflowPrinterOption } -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (f OverflowInteractionBuilder) Test(t *testing.T) OverflowTransactionResult { - locale, _ := time.LoadLocation("UTC") - time.Local = locale - result := f.Send() - var formattedEvents []*OverflowFormatedEvent - for _, event := range result.RawEvents { - ev := ParseEvent(event, uint64(0), time.Unix(0, 0), []string{}) - formattedEvents = append(formattedEvents, ev) - } - return OverflowTransactionResult{ - Err: result.Err, - Events: formattedEvents, - Result: result, - Testing: t, - } -} - // get the contract code func (oib OverflowInteractionBuilder) getContractCode(codeFileName string) ([]byte, error) { code := []byte(oib.Content) diff --git a/parse_integration_test.go b/parse_integration_test.go index cbf31eb..a962f1c 100644 --- a/parse_integration_test.go +++ b/parse_integration_test.go @@ -10,7 +10,7 @@ import ( ) func TestParseConfig(t *testing.T) { - g, err := NewTestingEmulator().StartE() + g, err := OverflowTesting() require.NoError(t, err) t.Parallel() diff --git a/script_integration_old_test.go b/script_integration_old_test.go deleted file mode 100644 index 2d40576..0000000 --- a/script_integration_old_test.go +++ /dev/null @@ -1,132 +0,0 @@ -package overflow - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestScriptIntegrationLegacy(t *testing.T) { - g, err := NewTestingEmulator().StartE() - require.NoError(t, err) - t.Parallel() - - t.Run("Raw account argument", func(t *testing.T) { - value := g.ScriptFromFile("test").Args(g.Arguments().RawAccount("0x1cf0e2f2f715450")).RunReturnsInterface() - assert.Equal(t, "0x01cf0e2f2f715450", value) - }) - - t.Run("run and output result", func(t *testing.T) { - g.ScriptFromFile("test").Args(g.Arguments().RawAccount("0x1cf0e2f2f715450")).Run() - }) - - t.Run("Raw account argument", func(t *testing.T) { - value := g.ScriptFromFile("test").Args(g.Arguments().Account("first")).RunReturnsInterface() - assert.Equal(t, "0x01cf0e2f2f715450", value) - }) - - t.Run("Script in different folder", func(t *testing.T) { - _, err := g.ScriptFromFile("block").ScriptPath("./cadence/scripts").RunReturns() - assert.NoError(t, err) - }) - - t.Run("Script should report failure", func(t *testing.T) { - value, err := g.ScriptFromFile("asdf").RunReturns() - assert.Error(t, err) - assert.Contains(t, err.Error(), "open ./scripts/asdf.cdc: no such file or directory") - assert.Nil(t, value) - - }) - - t.Run("Script should report failure", func(t *testing.T) { - value, err := g.InlineScript("asdf").RunReturns() - assert.Error(t, err) - assert.Contains(t, err.Error(), "Parsing failed") - assert.Nil(t, value) - - }) - - t.Run("marshal test result into struct", func(t *testing.T) { - var result []TestReturn - err := g.InlineScript(` -pub struct Report{ - pub let name: String - pub let test: String - - init(name: String, test:String) { - self.name=name - self.test=test - } - } - - //👌 Inline Tx computation:?? loops:? statements:? invocations:? id:? - pub fun main() : [Report] { - return [Report(name:"name1", test: "test1"), Report(name:"name2", test: "test2")] - } - `).RunMarshalAs(&result) - assert.NoError(t, err) - assert.Equal(t, 2, len(result)) - assert.Equal(t, TestReturn{Name: "name1", Test: "test1"}, result[0]) - }) - - t.Run("marshal test result into struct should fail if wrong type", func(t *testing.T) { - var result TestReturn - err := g.InlineScript(` -pub struct Report{ - pub let name: String - pub let test: String - - init(name: String, test:String) { - self.name=name - self.test=test - } - } - - pub fun main() : [Report] { - return [Report(name:"name1", test: "test1"), Report(name:"name2", test: "test2")] - } - `).RunMarshalAs(&result) - assert.Error(t, err, "should return error") - assert.Contains(t, err.Error(), "json: cannot unmarshal array into Go value of type overflow.TestReturn") - }) - - t.Run("Named arguments", func(t *testing.T) { - value := g.ScriptFromFile("test"). - NamedArguments(map[string]string{ - "account": "first", - }).RunReturnsInterface() - - assert.Equal(t, "0x01cf0e2f2f715450", value) - }) - - t.Run("Named arguments error if not all arguments", func(t *testing.T) { - _, err := g.ScriptFromFile("test"). - NamedArguments(map[string]string{ - "aaccount": "first", - }).RunReturns() - assert.ErrorContains(t, err, "the following arguments where not present [account]") - }) - - t.Run("Named arguments error if wrong file", func(t *testing.T) { - _, err := g.ScriptFromFile("foo/test"). - NamedArguments(map[string]string{ - "aaccount": "first", - }).RunReturns() - assert.ErrorContains(t, err, "open ./scripts/foo/test.cdc: no such file or directory") - }) - - t.Run("Named arguments blank", func(t *testing.T) { - value := g.ScriptFromFile("block"). - NamedArguments(map[string]string{}). - RunReturnsInterface() - - assert.Equal(t, uint64(5), value) - }) - -} - -type TestReturn struct { - Name string - Test string -} diff --git a/script_test.go b/script_test.go deleted file mode 100644 index 02c68d4..0000000 --- a/script_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package overflow - -import ( - "testing" - - "github.com/onflow/cadence" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestScriptArguments(t *testing.T) { - g, err := NewTestingEmulator().StartE() - require.NoError(t, err) - t.Parallel() - - t.Run("Argument test", func(t *testing.T) { - ufix, _ := cadence.NewUFix64("1.0") - builder := g.InlineScript("").Args(g.Arguments().UFix64(1.0)) - assert.Contains(t, builder.Arguments, ufix) - }) - - t.Run("Argument test values", func(t *testing.T) { - ufix, _ := cadence.NewUFix64("1.0") - builder := g.InlineScript("").ArgsV(g.Arguments().UFix64(1.0).Build()) - assert.Contains(t, builder.Arguments, ufix) - }) - - t.Run("Argument test function", func(t *testing.T) { - ufix, _ := cadence.NewUFix64("1.0") - builder := g.InlineScript("").ArgsFn(func(a *OverflowArgumentsBuilder) { - a.UFix64(1.0) - }) - assert.Contains(t, builder.Arguments, ufix) - }) -} diff --git a/scripts_old.go b/scripts_old.go deleted file mode 100644 index 0b83201..0000000 --- a/scripts_old.go +++ /dev/null @@ -1,202 +0,0 @@ -package overflow - -import ( - "encoding/json" - "fmt" - - "github.com/enescakir/emoji" - "github.com/onflow/cadence" - "github.com/onflow/flow-cli/pkg/flowkit/services" - "github.com/pkg/errors" -) - -// OverflowScriptBuilder is a struct to hold information for running a script -// -// Deprecated: use FlowInteractionBuilder and the Script method -type OverflowScriptBuilder struct { - Overflow *OverflowState - FileName string - Arguments []cadence.Value - ScriptAsString string - BasePath string - Error error -} - -// Script start a script builder with the inline script as body -// -// Deprecated: use FlowInteractionBuilder and the Script method -func (o *OverflowState) InlineScript(content string) OverflowScriptBuilder { - return OverflowScriptBuilder{ - Overflow: o, - FileName: "inline", - Arguments: []cadence.Value{}, - ScriptAsString: content, - BasePath: fmt.Sprintf("%s/scripts", o.BasePath), - } -} - -// ScriptFromFile will start a flow script builder -// -// Deprecated: use FlowInteractionBuilder and the Script method -func (o *OverflowState) ScriptFromFile(filename string) OverflowScriptBuilder { - return OverflowScriptBuilder{ - Overflow: o, - FileName: filename, - Arguments: []cadence.Value{}, - ScriptAsString: "", - BasePath: fmt.Sprintf("%s/scripts", o.BasePath), - } -} - -// Deprecated: use FlowInteractionBuilder and the Script method -func (t OverflowScriptBuilder) ScriptPath(path string) OverflowScriptBuilder { - t.BasePath = path - return t -} - -// Deprecated: use FlowInteractionBuilder and the Script method -func (t OverflowScriptBuilder) NamedArguments(args map[string]string) OverflowScriptBuilder { - - scriptFilePath := fmt.Sprintf("%s/%s.cdc", t.BasePath, t.FileName) - code, err := t.getScriptCode(scriptFilePath) - if err != nil { - t.Error = err - return t - } - parseArgs, err := t.Overflow.ParseArgumentsWithoutType(t.FileName, code, args) - if err != nil { - t.Error = err - return t - } - t.Arguments = parseArgs - return t -} - -// Specify arguments to send to transaction using a raw list of values -// -// Deprecated: use FlowInteractionBuilder and the Script method -func (t OverflowScriptBuilder) ArgsV(args []cadence.Value) OverflowScriptBuilder { - t.Arguments = args - return t -} - -// Specify arguments to send to transaction using a builder you send in -// -// Deprecated: use FlowInteractionBuilder and the Script method -func (t OverflowScriptBuilder) Args(args *OverflowArgumentsBuilder) OverflowScriptBuilder { - t.Arguments = args.Build() - return t -} - -// Specify arguments to send to transaction using a function that takes a builder where you call the builder -// -// Deprecated: use FlowInteractionBuilder and the Script method -func (t OverflowScriptBuilder) ArgsFn(fn func(*OverflowArgumentsBuilder)) OverflowScriptBuilder { - args := t.Overflow.Arguments() - fn(args) - t.Arguments = args.Build() - return t -} - -// Run executes a read only script -// Deprecated: use FlowInteractionBuilder and the Script method -func (t OverflowScriptBuilder) Run() { - result := t.RunFailOnError() - res, err := CadenceValueToJsonString(result) - if err != nil { - panic(err) - } - t.Overflow.Logger.Info(fmt.Sprintf("%v Script run from result: %v\n", emoji.Star, res)) -} - -// Deprecated: use FlowInteractionBuilder -func (t OverflowScriptBuilder) getScriptCode(scriptFilePath string) ([]byte, error) { - - var err error - script := []byte(t.ScriptAsString) - if t.ScriptAsString == "" { - script, err = t.Overflow.State.ReaderWriter().ReadFile(scriptFilePath) - if err != nil { - return nil, err - } - } - - return script, nil -} - -// RunReturns executes a read only script -// -// Deprecated: use FlowInteractionBuilder and the Script method -func (t OverflowScriptBuilder) RunReturns() (cadence.Value, error) { - - if t.Error != nil { - return nil, t.Error - } - - f := t.Overflow - scriptFilePath := fmt.Sprintf("%s/%s.cdc", t.BasePath, t.FileName) - script, err := t.getScriptCode(scriptFilePath) - if err != nil { - return nil, err - } - - t.Overflow.EmulatorLog.Reset() - - flowScript := &services.Script{ - Code: script, - Args: t.Arguments, - Filename: scriptFilePath, - } - result, err := f.Services.Scripts.Execute(flowScript, f.Network) - if err != nil { - return nil, err - } - - t.Overflow.EmulatorLog.Reset() - f.Logger.Info(fmt.Sprintf("%v Script run from path %s\n", emoji.Star, scriptFilePath)) - return result, nil -} - -// Deprecated: use FlowInteractionBuilder and the Script method -func (t OverflowScriptBuilder) RunFailOnError() cadence.Value { - result, err := t.RunReturns() - if err != nil { - panic(errors.Wrapf(err, "scriptName:%s", t.FileName)) - } - return result - -} - -// RunMarshalAs runs the script and marshals the result into the provided value, returning an error if any -// -// Deprecated: use FlowInteractionBuilder and the Script method -func (t OverflowScriptBuilder) RunMarshalAs(value interface{}) error { - result, err := t.RunReturns() - if err != nil { - return err - } - jsonResult, err := CadenceValueToJsonString(result) - if err != nil { - return err - } - err = json.Unmarshal([]byte(jsonResult), &value) - return err -} - -// RunReturnsJsonString runs the script and returns pretty printed json string -// -// Deprecated: use FlowInteractionBuilder and the Script method -func (t OverflowScriptBuilder) RunReturnsJsonString() string { - res, err := CadenceValueToJsonString(t.RunFailOnError()) - if err != nil { - panic(err) - } - return res -} - -// RunReturnsInterface runs the script and returns interface{} -// -// Deprecated: use FlowInteractionBuilder and the Script method -func (t OverflowScriptBuilder) RunReturnsInterface() interface{} { - return CadenceValueToInterface(t.RunFailOnError()) -} diff --git a/setup_old.go b/setup_old.go deleted file mode 100644 index edd4c7a..0000000 --- a/setup_old.go +++ /dev/null @@ -1,183 +0,0 @@ -package overflow - -import ( - "fmt" - "os" - "strconv" - - "github.com/enescakir/emoji" - "github.com/onflow/flow-cli/pkg/flowkit/config" - "github.com/onflow/flow-cli/pkg/flowkit/output" -) - -// NewOverflow creates a new OverflowBuilder reading some confiuration from ENV var ( -// OVERFLOW_ENV : sets the environment to use, valid values here are emulator|testnet|mainnet|embedded -// OVERFLOW_CONTINUE : if set to `true` will not create accounts and deploy contracts even if on embedded/emulator -// OVERFLOW_LOGGING : set the logging level of flowkit and overflow itself, 0 = No Log, 1 = Errors only, 2 = Debug, 3(default) = Info -// -// Deprecated: use Overflow function with builder -func NewOverflow() *OverflowBuilder { - network := os.Getenv("OVERFLOW_ENV") - existing := os.Getenv("OVERFLOW_CONTINUE") - loglevel := os.Getenv("OVERFLOW_LOGGING") - var log int - var err error - if loglevel != "" { - log, err = strconv.Atoi(loglevel) - if err != nil { - panic(err) - } - } else { - log = output.InfoLog - } - return NewOverflowBuilder(network, existing != "true", log) - -} - -// Deprecated: use Overflow function with builder -func NewOverflowBuilder(network string, newEmulator bool, logLevel int) *OverflowBuilder { - inMemory := false - deployContracts := newEmulator - initializeAccounts := newEmulator - - if network == "embedded" || network == "" { - inMemory = true - network = emulatorValue - } - - if network == emulatorValue { - deployContracts = true - initializeAccounts = true - } - - return &OverflowBuilder{ - Network: network, - InMemory: inMemory, - DeployContracts: deployContracts, - GasLimit: 9999, - Path: ".", - TransactionFolderName: "transactions", - ScriptFolderName: "scripts", - LogLevel: logLevel, - InitializeAccounts: initializeAccounts, - PrependNetworkName: true, - ServiceSuffix: "account", - ConfigFiles: config.DefaultPaths(), - FilterOutEmptyWithDrawDepositEvents: true, - FilterOutFeeEvents: true, - GlobalEventFilter: OverflowEventFilter{}, - StopOnError: false, - PrintOptions: nil, - NewAccountFlowAmount: 0.0, - TransactionFees: false, - } -} - -// ExistingEmulator this if you are using an existing emulator and you do not want to create contracts or initializeAccounts -// -// Deprecated: use Overflow function with builder -func (o *OverflowBuilder) ExistingEmulator() *OverflowBuilder { - o.DeployContracts = false - o.InitializeAccounts = false - return o -} - -// DoNotPrependNetworkToAccountNames sets that network names will not be prepends to account names -// -// Deprecated: use Overflow function with builder -func (o *OverflowBuilder) DoNotPrependNetworkToAccountNames() *OverflowBuilder { - o.PrependNetworkName = false - return o -} - -// SetServiceSuffix will set the suffix to use for the service account. The default is `account` -// -// Deprecated: use Overflow function with builder -func (o *OverflowBuilder) SetServiceSuffix(suffix string) *OverflowBuilder { - o.ServiceSuffix = suffix - return o -} - -// NoneLog will turn of logging, making the script work well in batch jobs -// -// Deprecated: use Overflow function with builder -func (o *OverflowBuilder) NoneLog() *OverflowBuilder { - o.LogLevel = output.NoneLog - return o -} - -// DefaultGas sets the default gas limit to use -// -// Deprecated: use Overflow function with builder -func (o *OverflowBuilder) DefaultGas(gas int) *OverflowBuilder { - o.GasLimit = gas - return o -} - -// BasePath set the base path for transactions/scripts/contracts -// -// Deprecated: use Overflow function with builder -func (o *OverflowBuilder) BasePath(path string) *OverflowBuilder { - o.Path = path - return o -} - -// Config sets the file path to the flow.json config files to use -// -// Deprecated: use Overflow function with builder -func (o *OverflowBuilder) Config(files ...string) *OverflowBuilder { - o.ConfigFiles = files - return o -} - -// Start will start the overflow builder and return OverflowState, will panic if there are errors -// -// Deprecated: use Overflow function with builder -func (ob *OverflowBuilder) Start() *OverflowState { - o, err := ob.StartE() - if err != nil { - panic(fmt.Sprintf("%v error %+v", emoji.PileOfPoo, err)) - } - return o -} - -// NewOverflowInMemoryEmulator this method is used to create an in memory emulator, deploy all contracts for the emulator and create all accounts -// Deprecated: use Overflow function with builder -func NewOverflowInMemoryEmulator() *OverflowBuilder { - return NewOverflowBuilder("embedded", true, output.InfoLog) -} - -// NewOverflowForNetwork creates a new overflow client for the provided network -// -// Deprecated: use Overflow function with builder -func NewOverflowForNetwork(network string) *OverflowBuilder { - return NewOverflowBuilder(network, false, output.InfoLog) -} - -// NewOverflowEmulator create a new client -// -// Deprecated: use Overflow function with builder -func NewOverflowEmulator() *OverflowBuilder { - return NewOverflowBuilder(emulatorValue, false, output.InfoLog) -} - -// NewTestingEmulator starts an embedded emulator with no log to be used most often in tests -// -// Deprecated: use Overflow function with builder -func NewTestingEmulator() *OverflowBuilder { - return NewOverflowBuilder("embedded", true, 0) -} - -// NewOverflowTestnet creates a new overflow client for devnet/testnet -// -// Deprecated: use Overflow function with builder -func NewOverflowTestnet() *OverflowBuilder { - return NewOverflowBuilder("testnet", false, output.InfoLog) -} - -// NewOverflowMainnet creates a new gwft client for mainnet -// -// Deprecated: use Overflow function with builder -func NewOverflowMainnet() *OverflowBuilder { - return NewOverflowBuilder("mainnet", false, output.InfoLog) -} diff --git a/setup_test.go b/setup_test.go index ea62c17..7e3509b 100644 --- a/setup_test.go +++ b/setup_test.go @@ -7,86 +7,121 @@ import ( "github.com/stretchr/testify/assert" ) -func TestSetup(t *testing.T) { - t.Parallel() +func TestOverflowv3(t *testing.T) { + + t.Run("WithNetworkEmbedded", func(t *testing.T) { + b := Apply(WithNetwork("embedded")) + assert.Equal(t, "emulator", b.Network) + assert.True(t, b.DeployContracts) + assert.True(t, b.InitializeAccounts) + assert.True(t, b.InMemory) + assert.Equal(t, output.NoneLog, b.LogLevel) + }) + + t.Run("WithNetworkTesting", func(t *testing.T) { + b := Apply(WithNetwork("testing")) + assert.Equal(t, "emulator", b.Network) + assert.True(t, b.DeployContracts) + assert.True(t, b.InitializeAccounts) + assert.True(t, b.InMemory) + assert.Equal(t, output.NoneLog, b.LogLevel) + }) - t.Run("default builder", func(t *testing.T) { - o := NewOverflow() - assert.Equal(t, output.InfoLog, o.LogLevel) + t.Run("WithNetworkEmulator", func(t *testing.T) { + b := Apply(WithNetwork("emulator")) + assert.Equal(t, "emulator", b.Network) + assert.True(t, b.DeployContracts) + assert.True(t, b.InitializeAccounts) + assert.False(t, b.InMemory) }) - t.Run("default builder with loglevel from env", func(t *testing.T) { - t.Setenv("OVERFLOW_LOGGING", "2") - o := NewOverflow() - assert.Equal(t, output.DebugLog, o.LogLevel) + t.Run("WithNetworkTestnet", func(t *testing.T) { + b := Apply(WithNetwork("testnet")) + assert.Equal(t, "testnet", b.Network) + assert.False(t, b.DeployContracts) + assert.False(t, b.InitializeAccounts) + assert.False(t, b.InMemory) }) - t.Run("panic on wrong logging level", func(t *testing.T) { - t.Setenv("OVERFLOW_LOGGING", "asd") - assert.Panics(t, func() { NewOverflow() }) + t.Run("WithNetworkMainnet", func(t *testing.T) { + b := Apply(WithNetwork("mainnet")) + assert.Equal(t, "mainnet", b.Network) + assert.False(t, b.DeployContracts) + assert.False(t, b.InitializeAccounts) + assert.False(t, b.InMemory) }) - t.Run("none log", func(t *testing.T) { - o := NewOverflow().NoneLog() - assert.Equal(t, output.NoneLog, o.LogLevel) + t.Run("WithInMemory", func(t *testing.T) { + b := Apply() + assert.True(t, b.InMemory) + assert.True(t, b.InitializeAccounts) + assert.True(t, b.DeployContracts) + assert.Equal(t, "emulator", b.Network) }) - t.Run("new overflow builder for network", func(t *testing.T) { - o := NewOverflowForNetwork("testnet") - assert.Equal(t, "testnet", o.Network) + t.Run("WithExistingEmulator", func(t *testing.T) { + b := Apply(WithExistingEmulator()) + assert.False(t, b.InitializeAccounts) + assert.False(t, b.DeployContracts) }) - t.Run("new overflow in memory", func(t *testing.T) { - o := NewOverflowInMemoryEmulator() - assert.Equal(t, "emulator", o.Network) + t.Run("DoNotPrependNetworkToAccountNames", func(t *testing.T) { + b := Apply(WithNoPrefixToAccountNames()) + assert.False(t, b.PrependNetworkName) }) - t.Run("new overflow testnet", func(t *testing.T) { - o := NewOverflowTestnet() - assert.Equal(t, "testnet", o.Network) + t.Run("WithServiceAccountSuffix", func(t *testing.T) { + b := Apply(WithServiceAccountSuffix("foo")) + assert.Equal(t, "foo", b.ServiceSuffix) }) - t.Run("new overflow mainnet", func(t *testing.T) { - o := NewOverflowMainnet() - assert.Equal(t, "mainnet", o.Network) + + t.Run("WithBasePath", func(t *testing.T) { + b := Apply(WithBasePath("../")) + assert.Equal(t, "../", b.Path) }) - t.Run("new overflow emulator", func(t *testing.T) { - o := NewOverflowEmulator() - assert.Equal(t, "emulator", o.Network) + t.Run("WithNoLog", func(t *testing.T) { + b := Apply(WithLogNone()) + assert.Equal(t, output.NoneLog, b.LogLevel) }) - t.Run("new overflow builder without network", func(t *testing.T) { - o := NewOverflowBuilder("", false, 1) - assert.Equal(t, "emulator", o.Network) + t.Run("WithGas", func(t *testing.T) { + b := Apply(WithGas(42)) + assert.Equal(t, 42, b.GasLimit) }) - t.Run("existing emulator", func(t *testing.T) { - o := NewOverflow().ExistingEmulator() - assert.Equal(t, false, o.DeployContracts) - assert.Equal(t, false, o.InitializeAccounts) + t.Run("WithFlowConfig", func(t *testing.T) { + b := Apply(WithFlowConfig("foo.json", "bar.json")) + assert.Equal(t, []string{"foo.json", "bar.json"}, b.ConfigFiles) }) - t.Run("should error on getting invalid account", func(t *testing.T) { - o := NewOverflowInMemoryEmulator().ExistingEmulator().DoNotPrependNetworkToAccountNames() - _, err := o.Start().AccountE("foobar") - assert.ErrorContains(t, err, "could not find account with name foobar in the configuration") + t.Run("WithScriptFolderName", func(t *testing.T) { + b := Apply(WithScriptFolderName("script")) + assert.Equal(t, "script", b.ScriptFolderName) }) - t.Run("do not prepend network names", func(t *testing.T) { - o := NewOverflowInMemoryEmulator().ExistingEmulator().DoNotPrependNetworkToAccountNames() - assert.Equal(t, false, o.PrependNetworkName) - assert.Equal(t, "account", o.Start().ServiceAccountName()) + t.Run("WithGlobalPrintOptions", func(t *testing.T) { + b := Apply(WithGlobalPrintOptions(WithoutId())) + assert.Equal(t, 1, len(*b.PrintOptions)) + }) + t.Run("WithPrintResults", func(t *testing.T) { + b := Apply(WithPrintResults(WithoutId())) + assert.Equal(t, 1, len(*b.PrintOptions)) }) - t.Run("default gas", func(t *testing.T) { - o := NewOverflow().DefaultGas(100) - assert.Equal(t, 100, o.GasLimit) + t.Run("WithTransactionFolderName", func(t *testing.T) { + b := Apply(WithTransactionFolderName("tx")) + assert.Equal(t, "tx", b.TransactionFolderName) }) - t.Run("base path", func(t *testing.T) { - o := NewOverflow().BasePath("../") - assert.Equal(t, "../", o.Path) + t.Run("Overflow panics", func(t *testing.T) { + assert.Panics(t, func() { + Overflow(WithFlowConfig("nonexistant.json")) + }) }) +} +func Apply(opt ...OverflowOption) *OverflowBuilder { + return defaultOverflowBuilder.applyOptions(opt) } diff --git a/setup_v3_test.go b/setup_v3_test.go deleted file mode 100644 index 7e3509b..0000000 --- a/setup_v3_test.go +++ /dev/null @@ -1,127 +0,0 @@ -package overflow - -import ( - "testing" - - "github.com/onflow/flow-cli/pkg/flowkit/output" - "github.com/stretchr/testify/assert" -) - -func TestOverflowv3(t *testing.T) { - - t.Run("WithNetworkEmbedded", func(t *testing.T) { - b := Apply(WithNetwork("embedded")) - assert.Equal(t, "emulator", b.Network) - assert.True(t, b.DeployContracts) - assert.True(t, b.InitializeAccounts) - assert.True(t, b.InMemory) - assert.Equal(t, output.NoneLog, b.LogLevel) - }) - - t.Run("WithNetworkTesting", func(t *testing.T) { - b := Apply(WithNetwork("testing")) - assert.Equal(t, "emulator", b.Network) - assert.True(t, b.DeployContracts) - assert.True(t, b.InitializeAccounts) - assert.True(t, b.InMemory) - assert.Equal(t, output.NoneLog, b.LogLevel) - }) - - t.Run("WithNetworkEmulator", func(t *testing.T) { - b := Apply(WithNetwork("emulator")) - assert.Equal(t, "emulator", b.Network) - assert.True(t, b.DeployContracts) - assert.True(t, b.InitializeAccounts) - assert.False(t, b.InMemory) - }) - - t.Run("WithNetworkTestnet", func(t *testing.T) { - b := Apply(WithNetwork("testnet")) - assert.Equal(t, "testnet", b.Network) - assert.False(t, b.DeployContracts) - assert.False(t, b.InitializeAccounts) - assert.False(t, b.InMemory) - }) - - t.Run("WithNetworkMainnet", func(t *testing.T) { - b := Apply(WithNetwork("mainnet")) - assert.Equal(t, "mainnet", b.Network) - assert.False(t, b.DeployContracts) - assert.False(t, b.InitializeAccounts) - assert.False(t, b.InMemory) - }) - - t.Run("WithInMemory", func(t *testing.T) { - b := Apply() - assert.True(t, b.InMemory) - assert.True(t, b.InitializeAccounts) - assert.True(t, b.DeployContracts) - assert.Equal(t, "emulator", b.Network) - }) - - t.Run("WithExistingEmulator", func(t *testing.T) { - b := Apply(WithExistingEmulator()) - assert.False(t, b.InitializeAccounts) - assert.False(t, b.DeployContracts) - }) - - t.Run("DoNotPrependNetworkToAccountNames", func(t *testing.T) { - b := Apply(WithNoPrefixToAccountNames()) - assert.False(t, b.PrependNetworkName) - }) - - t.Run("WithServiceAccountSuffix", func(t *testing.T) { - b := Apply(WithServiceAccountSuffix("foo")) - assert.Equal(t, "foo", b.ServiceSuffix) - }) - - t.Run("WithBasePath", func(t *testing.T) { - b := Apply(WithBasePath("../")) - assert.Equal(t, "../", b.Path) - }) - - t.Run("WithNoLog", func(t *testing.T) { - b := Apply(WithLogNone()) - assert.Equal(t, output.NoneLog, b.LogLevel) - }) - - t.Run("WithGas", func(t *testing.T) { - b := Apply(WithGas(42)) - assert.Equal(t, 42, b.GasLimit) - }) - - t.Run("WithFlowConfig", func(t *testing.T) { - b := Apply(WithFlowConfig("foo.json", "bar.json")) - assert.Equal(t, []string{"foo.json", "bar.json"}, b.ConfigFiles) - }) - - t.Run("WithScriptFolderName", func(t *testing.T) { - b := Apply(WithScriptFolderName("script")) - assert.Equal(t, "script", b.ScriptFolderName) - }) - - t.Run("WithGlobalPrintOptions", func(t *testing.T) { - b := Apply(WithGlobalPrintOptions(WithoutId())) - assert.Equal(t, 1, len(*b.PrintOptions)) - }) - - t.Run("WithPrintResults", func(t *testing.T) { - b := Apply(WithPrintResults(WithoutId())) - assert.Equal(t, 1, len(*b.PrintOptions)) - }) - - t.Run("WithTransactionFolderName", func(t *testing.T) { - b := Apply(WithTransactionFolderName("tx")) - assert.Equal(t, "tx", b.TransactionFolderName) - }) - - t.Run("Overflow panics", func(t *testing.T) { - assert.Panics(t, func() { - Overflow(WithFlowConfig("nonexistant.json")) - }) - }) -} - -func Apply(opt ...OverflowOption) *OverflowBuilder { - return defaultOverflowBuilder.applyOptions(opt) -} diff --git a/sign_integration_test.go b/sign_integration_test.go index 4373f42..a7cd60a 100644 --- a/sign_integration_test.go +++ b/sign_integration_test.go @@ -7,7 +7,8 @@ import ( ) func TestSignIntegration(t *testing.T) { - g := NewTestingEmulator().Start() + g, err := OverflowTesting() + assert.NoError(t, err) t.Parallel() t.Run("fail on missing signer", func(t *testing.T) { diff --git a/state.go b/state.go index f7b8aea..2a07e9a 100644 --- a/state.go +++ b/state.go @@ -471,98 +471,6 @@ func (o *OverflowState) GetAccount(key string) (*flow.Account, error) { return o.Services.Accounts.Get(rawAddress) } -// Deprecated: use the new Tx/Script method and the argument functions -func (o *OverflowState) ParseArgumentsWithoutType(fileName string, code []byte, inputArgs map[string]string) ([]cadence.Value, error) { - var resultArgs []cadence.Value = make([]cadence.Value, 0) - - codes := map[common.Location][]byte{} - location := common.StringLocation(fileName) - program, must := cmd.PrepareProgram(code, location, codes) - checker, _ := cmd.PrepareChecker(program, location, codes, nil, must) - - var parameterList []*ast.Parameter - - functionDeclaration := sema.FunctionEntryPointDeclaration(program) - if functionDeclaration != nil { - if functionDeclaration.ParameterList != nil { - parameterList = functionDeclaration.ParameterList.Parameters - } - } - - transactionDeclaration := program.TransactionDeclarations() - if len(transactionDeclaration) == 1 { - if transactionDeclaration[0].ParameterList != nil { - parameterList = transactionDeclaration[0].ParameterList.Parameters - } - } - - if parameterList == nil { - return resultArgs, nil - } - - argumentNotPresent := []string{} - args := []string{} - for _, parameter := range parameterList { - parameterName := parameter.Identifier.Identifier - value, ok := inputArgs[parameterName] - if !ok { - argumentNotPresent = append(argumentNotPresent, parameterName) - } else { - args = append(args, value) - } - } - - if len(argumentNotPresent) > 0 { - err := fmt.Errorf("the following arguments where not present %v", argumentNotPresent) - return nil, err - } - - for index, argumentString := range args { - astType := parameterList[index].TypeAnnotation.Type - semaType := checker.ConvertType(astType) - - switch semaType { - case sema.StringType: - if len(argumentString) > 0 && !strings.HasPrefix(argumentString, "\"") { - argumentString = "\"" + argumentString + "\"" - } - } - - switch semaType.(type) { - case *sema.AddressType: - - account, _ := o.AccountE(argumentString) - - if account != nil { - argumentString = account.Address().String() - } - - if !strings.Contains(argumentString, "0x") { - argumentString = fmt.Sprintf("0x%s", argumentString) - } - } - - inter, interErr := interpreter.NewInterpreter(nil, nil, &interpreter.Config{}) - if interErr != nil { - return nil, interErr - } - var value, err = runtime.ParseLiteral(argumentString, semaType, inter) - if err != nil { - return nil, errors.Wrapf(err, "argument `%s` is not expected type `%s`", parameterList[index].Identifier, semaType) - } - resultArgs = append(resultArgs, value) - } - return resultArgs, nil -} - -// Deprecated: This builder and all its methods are deprecated. Use the new Tx/Script methods and its argument method -func (o *OverflowState) Arguments() *OverflowArgumentsBuilder { - return &OverflowArgumentsBuilder{ - Overflow: o, - Arguments: []cadence.Value{}, - } -} - func (o OverflowState) readLog() ([]OverflowEmulatorLogMessage, error) { var logMessage []OverflowEmulatorLogMessage diff --git a/templates.go b/templates.go index e6e7aaf..776ab69 100644 --- a/templates.go +++ b/templates.go @@ -54,7 +54,7 @@ func (o *OverflowState) UploadImageAsDataUrl(filename string, accountName string // UploadString will upload the given string data in 1mb chunkts to /storage/upload of the given account func (o *OverflowState) UploadString(content string, accountName string) error { //unload previous content if any. - if _, err := o.Transaction(` + res := o.Tx(` transaction { prepare(signer: AuthAccount) { let path = /storage/upload @@ -62,13 +62,14 @@ func (o *OverflowState) UploadString(content string, accountName string) error { log(existing) } } - `).SignProposeAndPayAs(accountName).RunE(); err != nil { - return err + `, WithSigner(accountName)) + if res.Err != nil { + return res.Err } parts := splitByWidthMake(content, 1_000_000) for _, part := range parts { - if _, err := o.Transaction(` + res := o.Tx(` transaction(part: String) { prepare(signer: AuthAccount) { let path = /storage/upload @@ -78,8 +79,9 @@ func (o *OverflowState) UploadString(content string, accountName string) error { log(part) } } - `).SignProposeAndPayAs(accountName).Args(o.Arguments().String(part)).RunE(); err != nil { - return err + `, WithSigner(accountName), WithArg("part", part)) + if res.Err != nil { + return res.Err } } @@ -89,16 +91,18 @@ func (o *OverflowState) UploadString(content string, accountName string) error { // Get the free capacity in an account func (o *OverflowState) GetFreeCapacity(accountName string) int { - result, ok := o.InlineScript(` + result := o.Script(` pub fun main(user:Address): UInt64{ let account=getAccount(user) return account.storageCapacity - account.storageUsed } -`).Args(o.Arguments().Account(accountName)).RunReturnsInterface().(uint64) +`, WithArg("user", accountName)) + + value, ok := result.Output.(uint64) if !ok { panic("Type conversion of free capacity failed") } - return int(result) + return int(value) } func (o *OverflowState) MintFlowTokens(accountName string, amount float64) *OverflowState { diff --git a/testdata/graffle-event.golden b/testdata/graffle-event.golden index 8c7ade5..100aa94 100644 --- a/testdata/graffle-event.golden +++ b/testdata/graffle-event.golden @@ -1 +1 @@ -map[string]interface{}{"amount": 100} +map[string]interface{}{"amount": 10} diff --git a/transaction.go b/transaction.go deleted file mode 100644 index f333032..0000000 --- a/transaction.go +++ /dev/null @@ -1,230 +0,0 @@ -package overflow - -import ( - "fmt" - "strings" - "testing" - - "github.com/sanity-io/litter" - "github.com/stretchr/testify/assert" - "golang.org/x/exp/slices" -) - -// OverflowTransactionResult -// -// # The old result object from an transaction -// -// Deprecated: use the new Tx() method and OverflowResult -type OverflowTransactionResult struct { - Err error - Events []*OverflowFormatedEvent - Result *OverflowResult - Testing *testing.T -} - -// Deprecated: use the new Tx() method and Asserts on the result -func (t OverflowTransactionResult) AssertFailure(msg string) OverflowTransactionResult { - assert.Error(t.Testing, t.Err) - if t.Err != nil { - assert.Contains(t.Testing, t.Err.Error(), msg) - } - return t -} - -// Deprecated: use the new Tx() method and Asserts on the result -func (t OverflowTransactionResult) AssertSuccess() OverflowTransactionResult { - t.Testing.Helper() - - if t.Err != nil { - assert.Fail(t.Testing, fmt.Sprintf("Received unexpected error:\n%+v", t.Err), fmt.Sprintf("transactionName:%s", t.Result.Name)) - } - return t -} - -// Deprecated: use the new Tx() method and Asserts on the result -func (t OverflowTransactionResult) AssertEventCount(number int) OverflowTransactionResult { - assert.Equal(t.Testing, number, len(t.Events)) - return t -} - -// Deprecated: use the new Tx() method and Asserts on the result -func (t OverflowTransactionResult) AssertNoEvents() OverflowTransactionResult { - res := assert.Empty(t.Testing, t.Events) - - t.logFailure(res) - return t -} - -// Deprecated: use the new Tx() method and Asserts on the result -func (t OverflowTransactionResult) logFailure(res bool) { - if !res { - for _, ev := range t.Events { - t.Testing.Log(litter.Sdump(ev)) - } - } -} - -// Deprecated: use the new Tx() method and Asserts on the result -func (t OverflowTransactionResult) AssertEmitEventNameShortForm(event ...string) OverflowTransactionResult { - var eventNames []string - for _, fe := range t.Events { - eventNames = append(eventNames, fe.ShortName()) - } - - res := false - for _, ev := range event { - if assert.Contains(t.Testing, eventNames, ev) { - res = true - } - } - - t.logFailure(res) - - return t -} - -// Deprecated: use the new Tx() method and Asserts on the result -func (t OverflowTransactionResult) AssertEmitEventName(event ...string) OverflowTransactionResult { - var eventNames []string - for _, fe := range t.Events { - eventNames = append(eventNames, fe.Name) - } - - res := false - for _, ev := range event { - if assert.Contains(t.Testing, eventNames, ev) { - res = true - } - } - - t.logFailure(res) - - return t -} - -// Deprecated: use the new Tx() method and Asserts on the result -func (t OverflowTransactionResult) AssertEmitEventJson(event ...string) OverflowTransactionResult { - - var jsonEvents []string - for _, fe := range t.Events { - jsonEvents = append(jsonEvents, fe.String()) - } - - res := true - for _, ev := range event { - //TODO: keep as before if this fails - if !slices.Contains(jsonEvents, ev) { - assert.Fail(t.Testing, fmt.Sprintf("event not found %s", litter.Sdump(ev))) - res = false - } - } - - t.logFailure(res) - return t -} - -// Deprecated: use the new Tx() method and Asserts on the result -func (t OverflowTransactionResult) AssertPartialEvent(expected *OverflowFormatedEvent) OverflowTransactionResult { - - events := t.Events - newEvents := []*OverflowFormatedEvent{} - for _, ev := range events { - //todo do we need more then just name here? - if ev.Name == expected.Name { - fields := map[string]interface{}{} - for key, value := range ev.Fields { - _, exist := expected.Fields[key] - if exist { - fields[key] = value - } - } - - if len(fields) > 0 { - newEvents = append(newEvents, &OverflowFormatedEvent{ - Name: ev.Name, - Time: ev.Time, - BlockHeight: ev.BlockHeight, - Fields: fields, - }) - } - } - } - if !expected.ExistIn(newEvents) { - assert.Fail(t.Testing, fmt.Sprintf("event not found %s", litter.Sdump(expected))) - t.logFailure(false) - } - - return t -} - -// Deprecated: use the new Tx() method and Asserts on the result -func (t OverflowTransactionResult) AssertEmitEvent(event ...*OverflowFormatedEvent) OverflowTransactionResult { - res := true - for _, ev := range event { - //This is not a compile error - - if !ev.ExistIn(t.Events) { - assert.Fail(t.Testing, fmt.Sprintf("event not found %s", litter.Sdump(ev))) - res = false - } - } - - t.logFailure(res) - - return t -} - -// Deprecated: use the new Tx() method and Asserts on the result -func (t OverflowTransactionResult) AssertDebugLog(message ...string) OverflowTransactionResult { - var logMessages []interface{} - for _, fe := range t.Events { - if strings.HasSuffix(fe.Name, "Debug.Log") { - logMessages = append(logMessages, fe.Fields["msg"]) - } - } - - for _, ev := range message { - assert.Contains(t.Testing, logMessages, ev) - } - return t -} - -// Deprecated: use the new Tx() method and Asserts on the result -func (t OverflowTransactionResult) AssertEmulatorLog(message string) OverflowTransactionResult { - - for _, log := range t.Result.EmulatorLog { - if strings.Contains(log, message) { - return t - } - } - - assert.Fail(t.Testing, "No emulator log contain message "+message, t.Result.EmulatorLog) - - return t -} - -// Deprecated: use the new Tx() method and Asserts on the result -func (t OverflowTransactionResult) AssertComputationLessThenOrEqual(computation int) OverflowTransactionResult { - assert.LessOrEqual(t.Testing, t.Result.ComputationUsed, computation) - return t -} - -// Deprecated: use the new Tx() method and Asserts on the result -func (t OverflowTransactionResult) AssertComputationUsed(computation int) OverflowTransactionResult { - t.Testing.Helper() - assert.Equal(t.Testing, computation, t.Result.ComputationUsed) - return t -} - -// Deprecated: use the new Tx() method and Asserts on the result -func (t OverflowTransactionResult) GetIdFromEvent(eventName string, fieldName string) uint64 { - t.Testing.Helper() - - for _, ev := range t.Events { - if ev.Name == eventName { - return ev.GetFieldAsUInt64(fieldName) - } - } - panic("from event name of fieldname") - -} diff --git a/transaction_integration_old_test.go b/transaction_integration_old_test.go deleted file mode 100644 index bfa6b2b..0000000 --- a/transaction_integration_old_test.go +++ /dev/null @@ -1,309 +0,0 @@ -package overflow - -import ( - "bytes" - "log" - "os" - "testing" - - "github.com/stretchr/testify/assert" -) - -/* -Tests must be in the same folder as flow.json with contracts and transactions/scripts in subdirectories in order for the path resolver to work correctly -*/ -func TestTransactionIntegrationLegacy(t *testing.T) { - logNumName := "A.f8d6e0586b0a20c7.Debug.LogNum" - g := NewTestingEmulator().Start() - g.Tx("mint_tokens", WithSignerServiceAccount(), WithArg("recipient", "first"), WithArg("amount", 1.0)) - - t.Parallel() - - t.Run("fail on missing signer with run method", func(t *testing.T) { - assert.PanicsWithError(t, "💩 You need to set the proposer signer", func() { - g.TransactionFromFile("create_nft_collection").Run() - }) - }) - - t.Run("fail on missing signer", func(t *testing.T) { - g.TransactionFromFile("create_nft_collection"). - Test(t). //This method will return a TransactionResult that we can assert upon - AssertFailure("You need to set the proposer signer") //we assert that there is a failure - }) - - t.Run("fail on wrong transaction name", func(t *testing.T) { - g.TransactionFromFile("create_nf_collection"). - SignProposeAndPayAs("first"). - Test(t). //This method will return a TransactionResult that we can assert upon - AssertFailure("Could not read interaction file from path=./transactions/create_nf_collection.cdc") //we assert that there is a failure - }) - - t.Run("Assert get id", func(t *testing.T) { - result := g.Transaction(` - import Debug from "../contracts/Debug.cdc" - transaction(id:UInt64) { - prepare(acct: AuthAccount) { - Debug.id(id) - } - }`). - SignProposeAndPayAs("first"). - Args(g.Arguments().UInt64(1)). - Test(t). - AssertSuccess() - - res, err := result.Result.GetIdFromEvent(logNumName, "id") - assert.NoError(t, err) - - assert.Equal(t, uint64(1), result.GetIdFromEvent(logNumName, "id")) - assert.Equal(t, uint64(1), res) - assert.Equal(t, []uint64{1}, result.Result.GetIdsFromEvent(logNumName, "id")) - - }) - - t.Run("run get id print all", func(t *testing.T) { - result := g.Transaction(` - import Debug from "../contracts/Debug.cdc" - transaction(id:UInt64) { - prepare(acct: AuthAccount) { - Debug.id(id) - } - }`). - SignProposeAndPayAs("first"). - Args(g.Arguments().UInt64(1)). - RunGetIdFromEventPrintAll(logNumName, "id") - - assert.Equal(t, uint64(1), result) - }) - - t.Run("run get ids", func(t *testing.T) { - result, err := g.Transaction(` - import Debug from "../contracts/Debug.cdc" - transaction(id:UInt64) { - prepare(acct: AuthAccount) { - Debug.id(id) - } - }`). - SignProposeAndPayAs("first"). - Args(g.Arguments().UInt64(1)). - RunGetIds(logNumName, "id") - - assert.NoError(t, err) - assert.Equal(t, []uint64{1}, result) - }) - - t.Run("run get ids fail", func(t *testing.T) { - _, err := g.Transaction(` - import Debug from "../contracts/Debug.cdc" - transaction(id:UInt64) { - prepare(acct: AuthAccount) { - Debug.id(id) - } - }`). - SignProposeAndPayAs("first"). - RunGetIds(logNumName, "id") - - assert.ErrorContains(t, err, "entry point parameter count mismatch: expected 1, got 0") - }) - - t.Run("run get id print all panic on failed", func(t *testing.T) { - - assert.Panics(t, func() { - g.Transaction(` - import Debug from "../contracts/Debug.cdc" - transaction(id:UInt64) { - prepare(acct: AuthAccount) { - Debug.id(id) - } - }`).SignProposeAndPayAs("first").RunGetIdFromEvent(logNumName, "id") - }) - - }) - - t.Run("run get id print all panic on wrong field name", func(t *testing.T) { - - assert.Panics(t, func() { - g.Transaction(` - import Debug from "../contracts/Debug.cdc" - transaction(id:UInt64) { - prepare(acct: AuthAccount) { - Debug.id(id) - } - }`).SignProposeAndPayAs("first"). - Args(g.Arguments().UInt64(1)). - RunGetIdFromEvent(logNumName, "id2") - }) - - }) - - t.Run("run get events with name", func(t *testing.T) { - result := g.Transaction(` - import Debug from "../contracts/Debug.cdc" - transaction(id:UInt64) { - prepare(acct: AuthAccount) { - Debug.id(id) - } - }`). - SignProposeAndPayAs("first"). - Args(g.Arguments().UInt64(1)). - RunGetEventsWithName(logNumName) - - assert.Equal(t, 1, len(result)) - }) - - t.Run("run get events with name or error", func(t *testing.T) { - result, err := g.Transaction(` - import Debug from "../contracts/Debug.cdc" - transaction(id:UInt64) { - prepare(acct: AuthAccount) { - Debug.id(id) - } - }`). - SignProposeAndPayAs("first"). - Args(g.Arguments().UInt64(1)). - RunGetEventsWithNameOrError(logNumName) - - assert.NoError(t, err) - assert.Equal(t, 1, len(result)) - }) - - t.Run("Inline transaction with debug log", func(t *testing.T) { - g.Transaction(` - import Debug from "../contracts/Debug.cdc" - transaction(message:String) { - prepare(acct: AuthAccount, account2: AuthAccount) { - Debug.log(message) } }`). - SignProposeAndPayAs("first"). - PayloadSigner("second"). - Args(g.Arguments().String("foobar")). - Test(t). - AssertSuccess(). - AssertDebugLog("foobar"). //assert that we have debug logged something. The assertion is contains so you do not need to write the entire debug log output if you do not like - AssertComputationUsed(5). - AssertEmulatorLog("Transaction submitted") - - }) - - t.Run("Raw account argument", func(t *testing.T) { - g.Transaction(` - import Debug from "../contracts/Debug.cdc" - transaction(user:Address) { - prepare(acct: AuthAccount) { - Debug.log(user.toString()) - } - }`). - SignProposeAndPayAsService(). - Args(g.Arguments().RawAccount("0x01cf0e2f2f715450")). - Test(t). - AssertSuccess(). - AssertDebugLog("0x01cf0e2f2f715450"). - AssertComputationLessThenOrEqual(40) - }) - - t.Run("transaction that should fail", func(t *testing.T) { - g.Transaction(` - import Debug from "../contracts/Debug.cdc" - transaction(user:Address) { - prepare(acct: AuthAccount) { - Debug.log(user.toStrig()) - } - }`). - SignProposeAndPayAsService(). - Args(g.Arguments(). - RawAccount("0x1cf0e2f2f715450")). - Test(t). - AssertFailure("has no member `toStrig`") //assert failure with an error message. uses contains so you do not need to write entire message - }) - - t.Run("Assert print events", func(t *testing.T) { - var str bytes.Buffer - log.SetOutput(&str) - defer log.SetOutput(os.Stdout) - - g.SimpleTxArgs("mint_tokens", "account", g.Arguments().Account("first").UFix64(100.0)) - assert.Contains(t, str.String(), "A.0ae53cb6e3f42a79.FlowToken.MinterCreated") - }) - - t.Run("Assert print events", func(t *testing.T) { - var str bytes.Buffer - log.SetOutput(&str) - defer log.SetOutput(os.Stdout) - - g.TransactionFromFile("mint_tokens"). - SignProposeAndPayAsService(). - Args(g.Arguments(). - Account("first"). - UFix64(100.0)). - RunPrintEvents(map[string][]string{"A.0ae53cb6e3f42a79.FlowToken.TokensDeposited": {"to"}}) - - assert.NotContains(t, str.String(), "0x1cf0e2f2f715450") - }) - - /* - https://github.com/bjartek/overflow/issues/45 - t.Run("Meters test", func(t *testing.T) { - res := g.TransactionFromFile("mint_tokens"). - SignProposeAndPayAsService(). - NamedArguments(map[string]string{ - "recipient": "first", - "amount": "100.0", - }). - Test(t).AssertSuccess() - - assert.Equal(t, 0, res.Result.Meter.Loops()) - assert.Equal(t, 15, res.Result.Meter.FunctionInvocations()) - assert.Equal(t, 42, res.Result.ComputationUsed) - - }) - */ - - t.Run("Named arguments wrong type", func(t *testing.T) { - g.TransactionFromFile("mint_tokens"). - SignProposeAndPayAsService(). - NamedArguments(map[string]string{ - "recipient": "first", - "amount": "asd", - }). - Test(t).AssertFailure("argument `amount` is not expected type `UFix64`") - }) - - t.Run("Named arguments with string", func(t *testing.T) { - g.TransactionFromFile("arguments"). - SignProposeAndPayAsService(). - NamedArguments(map[string]string{ - "test": "first", - }). - Test(t).AssertSuccess() - }) - - t.Run("Named arguments error if not all arguments", func(t *testing.T) { - g.TransactionFromFile("mint_tokens"). - SignProposeAndPayAsService(). - NamedArguments(map[string]string{ - "recipient": "first", - }). - Test(t).AssertFailure("the following arguments where not present [amount]") - }) - - t.Run("Named arguments error if file not correct", func(t *testing.T) { - g.TransactionFromFile("mint_tokens2"). - SignProposeAndPayAsService(). - NamedArguments(map[string]string{ - "recipient": "first", - }). - Test(t).AssertFailure("Could not read interaction file from path=./transactions/mint_tokens2.cdc") - }) -} - -func TestFillUpSpace(t *testing.T) { - o, err := OverflowTesting(WithFlowForNewUsers(0.002)) - assert.NoError(t, err) - - result := o.GetFreeCapacity("first") - assert.Equal(t, 299213, result) - o.FillUpStorage("first") - assert.NoError(t, o.Error) - - result2 := o.GetFreeCapacity("first") - assert.LessOrEqual(t, result2, 40000) - -} diff --git a/transaction_test.go b/transaction_test.go index 32cf16f..4aaac18 100644 --- a/transaction_test.go +++ b/transaction_test.go @@ -1,46 +1,250 @@ package overflow import ( + "fmt" "testing" - "github.com/onflow/cadence" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) -/* -Tests must be in the same folder as flow.json with contracts and transactions/scripts in subdirectories in order for the path resolver to work correctly -*/ -func TestTransactionArguments(t *testing.T) { - g := NewTestingEmulator().Start() - t.Parallel() +func TestTransaction(t *testing.T) { + o, err := OverflowTesting() + require.NoError(t, err) + t.Run("Run simple tx", func(t *testing.T) { + res := o.Tx("arguments", WithArg("test", "foo"), WithSignerServiceAccount()) + assert.NoError(t, res.Err) + }) + + t.Run("error on missing argument", func(t *testing.T) { + res := o.Tx("arguments", WithSignerServiceAccount()) + assert.ErrorContains(t, res.Err, "the interaction 'arguments' is missing [test]") + }) + + t.Run("error on redundant argument", func(t *testing.T) { + res := o.Tx("arguments", WithArg("test2", "foo"), WithArg("test", "foo"), WithSignerServiceAccount()) + assert.ErrorContains(t, res.Err, "the interaction 'arguments' has the following extra arguments [test2]") + }) + + t.Run("Run simple tx with sa proposer", func(t *testing.T) { + res := o.Tx("arguments", WithArg("test", "foo"), WithPayloadSigner("first"), WithProposerServiceAccount()) + assert.Contains(t, res.EmulatorLog[4], "0x01cf0e2f2f715450") + }) + + t.Run("Run simple tx with custom proposer", func(t *testing.T) { + res := o.Tx("arguments", WithArg("test", "foo"), WithPayloadSigner("first"), WithProposer("account")) + assert.Contains(t, res.EmulatorLog[4], "0x01cf0e2f2f715450") + }) + + t.Run("Fail when invalid proposer", func(t *testing.T) { + res := o.Tx("arguments", WithArg("test", "foo"), WithPayloadSigner("first"), WithProposer("account2")) + assert.ErrorContains(t, res.Err, "could not find account with name emulator-account2 in the configuration") + }) + + t.Run("Run linine tx", func(t *testing.T) { + res := o.Tx(` +transaction(test:String) { + prepare(acct: AuthAccount) { + log(test) + } +} +`, WithArg("test", "foo"), WithSignerServiceAccount()) + assert.NoError(t, res.Err) + }) + + t.Run("Run linine tx", func(t *testing.T) { + res := o.Tx(` +transaction(test:UInt64) { + prepare(acct: AuthAccount) { + log(test) + } +} +`, WithArg("test", uint64(1)), WithSignerServiceAccount()) + assert.NoError(t, res.Err) + }) + + t.Run("Run simple tx with custom signer", func(t *testing.T) { + res := o.Tx("arguments", WithArg("test", "foo"), WithSigner("account")) + assert.NoError(t, res.Err) + }) + + t.Run("Error on wrong signer name", func(t *testing.T) { + res := o.Tx("arguments", WithArg("test", "foo"), WithSigner("account2")) + assert.ErrorContains(t, res.Err, "could not find account with name emulator-account2") + }) + + t.Run("compose a function", func(t *testing.T) { + serviceAccountTx := o.TxFN(WithSignerServiceAccount()) + res := serviceAccountTx("arguments", WithArg("test", "foo")) + assert.NoError(t, res.Err) + }) + + t.Run("create function with name", func(t *testing.T) { + argumentTx := o.TxFileNameFN("arguments", WithSignerServiceAccount()) + res := argumentTx(WithArg("test", "foo")) + assert.NoError(t, res.Err) + }) + + t.Run("Should not allow varags builder arg with single element", func(t *testing.T) { + res := o.Tx("arguments", WithArgs("test")) + assert.ErrorContains(t, res.Err, "Please send in an even number of string : interface{} pairs") + }) + + t.Run("Should not allow varag with non string keys", func(t *testing.T) { + res := o.Tx("arguments", WithArgs(1, "test")) + assert.ErrorContains(t, res.Err, "even parameters in Args needs to be string") + }) + + t.Run("Arg, with cadence raw value", func(t *testing.T) { + res := o.Tx("arguments", WithSignerServiceAccount(), WithArg("test", cadenceString("test"))) + assert.NoError(t, res.Err) + }) + + t.Run("date time arg", func(t *testing.T) { + res := o.BuildInteraction(` +transaction(test:UFix64) { + prepare(acct: AuthAccount) { + + } +} +`, "transaction", WithArgDateTime("test", "July 29, 2021 08:00:00 AM", "America/New_York"), WithSignerServiceAccount()) + assert.NoError(t, res.Error) + }) + + t.Run("date time arg error", func(t *testing.T) { + res := o.BuildInteraction(` +transaction(test:UFix64) { + prepare(acct: AuthAccount) { + + } +} +`, "transaction", WithArgDateTime("test", "July 29021 08:00:00 AM", "America/New_York"), WithSignerServiceAccount()) + assert.ErrorContains(t, res.Error, "cannot parse") + }) + + t.Run("Map args", func(t *testing.T) { + res := o.Tx("arguments", WithSignerServiceAccount(), WithArgsMap(map[string]interface{}{"test": "test"})) + assert.NoError(t, res.Err) + }) + + t.Run("Parse addresses should fail if not valid account name and hex", func(t *testing.T) { + res := o.BuildInteraction(` +transaction(test:[Address]) { + prepare(acct: AuthAccount) { + + } +} +`, "transaction", WithAddresses("test", "bjartek"), WithSignerServiceAccount()) + assert.ErrorContains(t, res.Error, "bjartek is not an valid account name or an address") + }) + + t.Run("Parse array of addresses", func(t *testing.T) { + res := o.BuildInteraction(` +transaction(test:[Address]) { + prepare(acct: AuthAccount) { + + } +} +`, "transaction", WithAddresses("test", "account", "45a1763c93006ca"), WithSignerServiceAccount()) + assert.Equal(t, "[0xf8d6e0586b0a20c7, 0x045a1763c93006ca]", fmt.Sprintf("%v", res.NamedArgs["test"])) + }) + + t.Run("Parse String to String map", func(t *testing.T) { + res := o.BuildInteraction(` +transaction(test:{String:String}) { + prepare(acct: AuthAccount) { + + } +} +`, "transaction", WithArg("test", `{ "foo" : "bar"}`), WithSignerServiceAccount()) + assert.Equal(t, `{ "foo" : "bar"}`, fmt.Sprintf("%v", res.NamedArgs["test"])) + }) + + t.Run("Parse String to UFix64 map", func(t *testing.T) { + res := o.BuildInteraction(` +transaction(test:{String:UFix64}) { + prepare(acct: AuthAccount) { + + } +} +`, "transaction", WithArg("test", `{ "foo" : 1.0}`), WithSignerServiceAccount()) + assert.Equal(t, `{ "foo" : 1.0}`, fmt.Sprintf("%v", res.NamedArgs["test"])) + }) + + t.Run("Error when parsing invalid address", func(t *testing.T) { + res := o.BuildInteraction(` +transaction(test:Address) { + prepare(acct: AuthAccount) { + + } +} +`, "transaction", WithArg("test", "bjartek"), WithSignerServiceAccount()) + assert.ErrorContains(t, res.Error, "argument `test` with value `0xbjartek` is not expected type `Address`") - t.Run("Gas test", func(t *testing.T) { - builder := g.Transaction("").Gas(100) - assert.Equal(t, uint64(100), builder.GasLimit) }) - t.Run("Signer error", func(t *testing.T) { - builder := g.Transaction("").SignProposeAndPayAs("asd") - assert.ErrorContains(t, builder.Error, "could not find account with name emulator-asd") + t.Run("Should set gas", func(t *testing.T) { + res := o.BuildInteraction(` +transaction(test:Address) { + prepare(acct: AuthAccount) { + + } +} +`, "transaction", WithArg("test", "bjartek"), WithSignerServiceAccount(), WithMaxGas(100)) + + assert.Equal(t, uint64(100), res.GasLimit) + }) - t.Run("Argument test builder", func(t *testing.T) { - ufix, _ := cadence.NewUFix64("1.0") - builder := g.Transaction("").Args(g.Arguments().UFix64(1.0)) - assert.Contains(t, builder.Arguments, ufix) + t.Run("Should report error if invalid payload signer", func(t *testing.T) { + res := o.Tx(` +transaction{ + prepare(acct: AuthAccount, user:AuthAccount) { + + } +} +`, WithSignerServiceAccount(), WithPayloadSigner("bjartek")) + + assert.Error(t, res.Err, "asd") + }) - t.Run("Argument test values", func(t *testing.T) { - ufix, _ := cadence.NewUFix64("1.0") - builder := g.Transaction("").ArgsV(g.Arguments().UFix64(1.0).Build()) - assert.Contains(t, builder.Arguments, ufix) + t.Run("ufix64", func(t *testing.T) { + res := o.BuildInteraction(` +transaction(test:UFix64) { + prepare(acct: AuthAccount) { + + } +} +`, "transaction", WithArg("test", 1.0), WithSignerServiceAccount()) + assert.NoError(t, res.Error) }) - t.Run("Argument test function", func(t *testing.T) { - ufix, _ := cadence.NewUFix64("1.0") - builder := g.Transaction("").ArgsFn(func(a *OverflowArgumentsBuilder) { - a.UFix64(1.0) - }) - assert.Contains(t, builder.Arguments, ufix) + t.Run("add printer args", func(t *testing.T) { + res := o.BuildInteraction(` +transaction(test:UFix64) { + prepare(acct: AuthAccount) { + + } +} +`, "transaction", WithArg("test", 1.0), WithSignerServiceAccount(), WithPrintOptions(WithEmulatorLog()), WithPrintOptions(WithFullMeter())) + assert.NoError(t, res.Error) + assert.Equal(t, 2, len(*res.PrintOptions)) + }) + + t.Run("add event filter", func(t *testing.T) { + filter := OverflowEventFilter{ + "Deposit": []string{"id"}, + } + + res := o.BuildInteraction(` +transaction(test:UFix64) { + prepare(acct: AuthAccount) { + } +} +`, "transaction", WithArg("test", 1.0), WithSignerServiceAccount(), WithoutGlobalEventFilter(), WithEventsFilter(filter)) + assert.NoError(t, res.Error) + assert.True(t, res.IgnoreGlobalEventFilters) + assert.Equal(t, 1, len(res.EventFilter)) }) } diff --git a/transaction_v3_test.go b/transaction_v3_test.go deleted file mode 100644 index 22a0e67..0000000 --- a/transaction_v3_test.go +++ /dev/null @@ -1,249 +0,0 @@ -package overflow - -import ( - "fmt" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestTransaction(t *testing.T) { - o, _ := OverflowTesting() - - t.Run("Run simple tx", func(t *testing.T) { - res := o.Tx("arguments", WithArg("test", "foo"), WithSignerServiceAccount()) - assert.NoError(t, res.Err) - }) - - t.Run("error on missing argument", func(t *testing.T) { - res := o.Tx("arguments", WithSignerServiceAccount()) - assert.ErrorContains(t, res.Err, "the interaction 'arguments' is missing [test]") - }) - - t.Run("error on redundant argument", func(t *testing.T) { - res := o.Tx("arguments", WithArg("test2", "foo"), WithArg("test", "foo"), WithSignerServiceAccount()) - assert.ErrorContains(t, res.Err, "the interaction 'arguments' has the following extra arguments [test2]") - }) - - t.Run("Run simple tx with sa proposer", func(t *testing.T) { - res := o.Tx("arguments", WithArg("test", "foo"), WithPayloadSigner("first"), WithProposerServiceAccount()) - assert.Contains(t, res.EmulatorLog[4], "0x01cf0e2f2f715450") - }) - - t.Run("Run simple tx with custom proposer", func(t *testing.T) { - res := o.Tx("arguments", WithArg("test", "foo"), WithPayloadSigner("first"), WithProposer("account")) - assert.Contains(t, res.EmulatorLog[4], "0x01cf0e2f2f715450") - }) - - t.Run("Fail when invalid proposer", func(t *testing.T) { - res := o.Tx("arguments", WithArg("test", "foo"), WithPayloadSigner("first"), WithProposer("account2")) - assert.ErrorContains(t, res.Err, "could not find account with name emulator-account2 in the configuration") - }) - - t.Run("Run linine tx", func(t *testing.T) { - res := o.Tx(` -transaction(test:String) { - prepare(acct: AuthAccount) { - log(test) - } -} -`, WithArg("test", "foo"), WithSignerServiceAccount()) - assert.NoError(t, res.Err) - }) - - t.Run("Run linine tx", func(t *testing.T) { - res := o.Tx(` -transaction(test:UInt64) { - prepare(acct: AuthAccount) { - log(test) - } -} -`, WithArg("test", uint64(1)), WithSignerServiceAccount()) - assert.NoError(t, res.Err) - }) - - t.Run("Run simple tx with custom signer", func(t *testing.T) { - res := o.Tx("arguments", WithArg("test", "foo"), WithSigner("account")) - assert.NoError(t, res.Err) - }) - - t.Run("Error on wrong signer name", func(t *testing.T) { - res := o.Tx("arguments", WithArg("test", "foo"), WithSigner("account2")) - assert.ErrorContains(t, res.Err, "could not find account with name emulator-account2") - }) - - t.Run("compose a function", func(t *testing.T) { - serviceAccountTx := o.TxFN(WithSignerServiceAccount()) - res := serviceAccountTx("arguments", WithArg("test", "foo")) - assert.NoError(t, res.Err) - }) - - t.Run("create function with name", func(t *testing.T) { - argumentTx := o.TxFileNameFN("arguments", WithSignerServiceAccount()) - res := argumentTx(WithArg("test", "foo")) - assert.NoError(t, res.Err) - }) - - t.Run("Should not allow varags builder arg with single element", func(t *testing.T) { - res := o.Tx("arguments", WithArgs("test")) - assert.ErrorContains(t, res.Err, "Please send in an even number of string : interface{} pairs") - }) - - t.Run("Should not allow varag with non string keys", func(t *testing.T) { - res := o.Tx("arguments", WithArgs(1, "test")) - assert.ErrorContains(t, res.Err, "even parameters in Args needs to be string") - }) - - t.Run("Arg, with cadence raw value", func(t *testing.T) { - res := o.Tx("arguments", WithSignerServiceAccount(), WithArg("test", cadenceString("test"))) - assert.NoError(t, res.Err) - }) - - t.Run("date time arg", func(t *testing.T) { - res := o.BuildInteraction(` -transaction(test:UFix64) { - prepare(acct: AuthAccount) { - - } -} -`, "transaction", WithArgDateTime("test", "July 29, 2021 08:00:00 AM", "America/New_York"), WithSignerServiceAccount()) - assert.NoError(t, res.Error) - }) - - t.Run("date time arg error", func(t *testing.T) { - res := o.BuildInteraction(` -transaction(test:UFix64) { - prepare(acct: AuthAccount) { - - } -} -`, "transaction", WithArgDateTime("test", "July 29021 08:00:00 AM", "America/New_York"), WithSignerServiceAccount()) - assert.ErrorContains(t, res.Error, "cannot parse") - }) - - t.Run("Map args", func(t *testing.T) { - res := o.Tx("arguments", WithSignerServiceAccount(), WithArgsMap(map[string]interface{}{"test": "test"})) - assert.NoError(t, res.Err) - }) - - t.Run("Parse addresses should fail if not valid account name and hex", func(t *testing.T) { - res := o.BuildInteraction(` -transaction(test:[Address]) { - prepare(acct: AuthAccount) { - - } -} -`, "transaction", WithAddresses("test", "bjartek"), WithSignerServiceAccount()) - assert.ErrorContains(t, res.Error, "bjartek is not an valid account name or an address") - }) - - t.Run("Parse array of addresses", func(t *testing.T) { - res := o.BuildInteraction(` -transaction(test:[Address]) { - prepare(acct: AuthAccount) { - - } -} -`, "transaction", WithAddresses("test", "account", "45a1763c93006ca"), WithSignerServiceAccount()) - assert.Equal(t, "[0xf8d6e0586b0a20c7, 0x045a1763c93006ca]", fmt.Sprintf("%v", res.NamedArgs["test"])) - }) - - t.Run("Parse String to String map", func(t *testing.T) { - res := o.BuildInteraction(` -transaction(test:{String:String}) { - prepare(acct: AuthAccount) { - - } -} -`, "transaction", WithArg("test", `{ "foo" : "bar"}`), WithSignerServiceAccount()) - assert.Equal(t, `{ "foo" : "bar"}`, fmt.Sprintf("%v", res.NamedArgs["test"])) - }) - - t.Run("Parse String to UFix64 map", func(t *testing.T) { - res := o.BuildInteraction(` -transaction(test:{String:UFix64}) { - prepare(acct: AuthAccount) { - - } -} -`, "transaction", WithArg("test", `{ "foo" : 1.0}`), WithSignerServiceAccount()) - assert.Equal(t, `{ "foo" : 1.0}`, fmt.Sprintf("%v", res.NamedArgs["test"])) - }) - - t.Run("Error when parsing invalid address", func(t *testing.T) { - res := o.BuildInteraction(` -transaction(test:Address) { - prepare(acct: AuthAccount) { - - } -} -`, "transaction", WithArg("test", "bjartek"), WithSignerServiceAccount()) - assert.ErrorContains(t, res.Error, "argument `test` with value `0xbjartek` is not expected type `Address`") - - }) - - t.Run("Should set gas", func(t *testing.T) { - res := o.BuildInteraction(` -transaction(test:Address) { - prepare(acct: AuthAccount) { - - } -} -`, "transaction", WithArg("test", "bjartek"), WithSignerServiceAccount(), WithMaxGas(100)) - - assert.Equal(t, uint64(100), res.GasLimit) - - }) - - t.Run("Should report error if invalid payload signer", func(t *testing.T) { - res := o.Tx(` -transaction{ - prepare(acct: AuthAccount, user:AuthAccount) { - - } -} -`, WithSignerServiceAccount(), WithPayloadSigner("bjartek")) - - assert.Error(t, res.Err, "asd") - - }) - - t.Run("ufix64", func(t *testing.T) { - res := o.BuildInteraction(` -transaction(test:UFix64) { - prepare(acct: AuthAccount) { - - } -} -`, "transaction", WithArg("test", 1.0), WithSignerServiceAccount()) - assert.NoError(t, res.Error) - }) - - t.Run("add printer args", func(t *testing.T) { - res := o.BuildInteraction(` -transaction(test:UFix64) { - prepare(acct: AuthAccount) { - - } -} -`, "transaction", WithArg("test", 1.0), WithSignerServiceAccount(), WithPrintOptions(WithEmulatorLog()), WithPrintOptions(WithFullMeter())) - assert.NoError(t, res.Error) - assert.Equal(t, 2, len(*res.PrintOptions)) - }) - - t.Run("add event filter", func(t *testing.T) { - filter := OverflowEventFilter{ - "Deposit": []string{"id"}, - } - - res := o.BuildInteraction(` -transaction(test:UFix64) { - prepare(acct: AuthAccount) { - } -} -`, "transaction", WithArg("test", 1.0), WithSignerServiceAccount(), WithoutGlobalEventFilter(), WithEventsFilter(filter)) - assert.NoError(t, res.Error) - assert.True(t, res.IgnoreGlobalEventFilters) - assert.Equal(t, 1, len(res.EventFilter)) - }) -} diff --git a/transactions_old.go b/transactions_old.go deleted file mode 100644 index 31015ac..0000000 --- a/transactions_old.go +++ /dev/null @@ -1,253 +0,0 @@ -package overflow - -import ( - "fmt" - "time" - - "github.com/enescakir/emoji" - "github.com/onflow/cadence" - "github.com/onflow/flow-cli/pkg/flowkit" - "github.com/onflow/flow-go-sdk" -) - -// Deprecated: Use Tx() -func (o *OverflowState) SimpleTxArgs(filename string, signer string, args *OverflowArgumentsBuilder) { - o.TransactionFromFile(filename).SignProposeAndPayAs(signer).Args(args).RunPrintEventsFull() -} - -// Deprecated: Use Tx() -// -// TransactionFromFile will start a flow transaction builder -func (o *OverflowState) TransactionFromFile(filename string) OverflowInteractionBuilder { - return OverflowInteractionBuilder{ - Overflow: o, - FileName: filename, - Payer: nil, - Arguments: []cadence.Value{}, - NamedCadenceArguments: CadenceArguments{}, - PayloadSigners: []*flowkit.Account{}, - GasLimit: uint64(o.Gas), - BasePath: fmt.Sprintf("%s/transactions", o.BasePath), - } -} - -// Deprecated: Use Tx() -// -// Transaction will start a flow transaction builder using the inline transaction -func (o *OverflowState) Transaction(content string) OverflowInteractionBuilder { - return OverflowInteractionBuilder{ - Overflow: o, - FileName: "inline", - Content: content, - Payer: nil, - Arguments: []cadence.Value{}, - NamedCadenceArguments: CadenceArguments{}, - PayloadSigners: []*flowkit.Account{}, - GasLimit: uint64(o.Gas), - BasePath: fmt.Sprintf("%s/transactions", o.BasePath), - } -} - -// Deprecated: Use ArgM -func (t OverflowInteractionBuilder) NamedArguments(args map[string]string) OverflowInteractionBuilder { - - codeFileName := fmt.Sprintf("%s/%s.cdc", t.BasePath, t.FileName) - code, err := t.getContractCode(codeFileName) - if err != nil { - t.Error = err - } - parseArgs, err := t.Overflow.ParseArgumentsWithoutType(t.FileName, code, args) - if err != nil { - t.Error = err - } - t.Arguments = parseArgs - return t -} - -// Deprecated: Use Args -// -// Specify arguments to send to transaction using a raw list of values -func (t OverflowInteractionBuilder) ArgsV(args []cadence.Value) OverflowInteractionBuilder { - t.Arguments = args - return t -} - -// Deprecated: Use Arg -// -// Specify arguments to send to transaction using a builder you send in -func (t OverflowInteractionBuilder) Args(args *OverflowArgumentsBuilder) OverflowInteractionBuilder { - t.Arguments = args.Build() - return t -} - -// Deprecated: Use Arg -// -// Specify arguments to send to transaction using a function that takes a builder where you call the builder -func (t OverflowInteractionBuilder) ArgsFn(fn func(*OverflowArgumentsBuilder)) OverflowInteractionBuilder { - args := t.Overflow.Arguments() - fn(args) - t.Arguments = args.Build() - return t -} - -// Deprecated: Use Tx function -func (t OverflowInteractionBuilder) TransactionPath(path string) OverflowInteractionBuilder { - t.BasePath = path - return t -} - -// Deprecated: Use Tx function -// -// Gas sets the gas limit for this transaction -func (t OverflowInteractionBuilder) Gas(limit uint64) OverflowInteractionBuilder { - t.GasLimit = limit - return t -} - -// Deprecated: Use Tx function -// -// SignProposeAndPayAs set the payer, proposer and envelope signer -func (t OverflowInteractionBuilder) SignProposeAndPayAs(signer string) OverflowInteractionBuilder { - account, err := t.Overflow.AccountE(signer) - if err != nil { - t.Error = err - return t - } - t.Proposer = account - t.Payer = account - return t -} - -// Deprecated: Use Tx function -// -// SignProposeAndPayAsService set the payer, proposer and envelope signer -func (t OverflowInteractionBuilder) SignProposeAndPayAsService() OverflowInteractionBuilder { - key := t.Overflow.ServiceAccountName() - //swallow error as you cannot start a overflow without a valid sa - account, _ := t.Overflow.State.Accounts().ByName(key) - t.Payer = account - t.Proposer = account - return t -} - -// Deprecated: Use Tx function -// -// PayloadSigner set a signer for the payload -func (t OverflowInteractionBuilder) PayloadSigner(value string) OverflowInteractionBuilder { - signer, err := t.Overflow.AccountE(value) - if err != nil { - t.Error = err - return t - } - t.PayloadSigners = append(t.PayloadSigners, signer) - return t -} - -// Deprecated: use Send().PrintEvents() -// -// RunPrintEventsFull will run a transaction and print all events -func (t OverflowInteractionBuilder) RunPrintEventsFull() { - PrintEvents(t.Run(), map[string][]string{}) -} - -// Deprecated: use Send().PrintEventsFiltered() -// -// RunPrintEvents will run a transaction and print all events ignoring some fields -func (t OverflowInteractionBuilder) RunPrintEvents(ignoreFields map[string][]string) { - PrintEvents(t.Run(), ignoreFields) -} - -// Deprecated: use Send and get entire result -// -// Run run the transaction -func (t OverflowInteractionBuilder) Run() []flow.Event { - result := t.Send() - if result.Err != nil { - t.Overflow.Logger.Error(fmt.Sprintf("%v Error executing script: %s output %v", emoji.PileOfPoo, t.FileName, result.Err)) - panic(result.Err) - } - return result.RawEvents -} - -// Deprecated: Use Tx().Print().GetIdFromEvent -func (t OverflowInteractionBuilder) RunGetIdFromEventPrintAll(eventName string, fieldName string) uint64 { - result := t.Send() - if result.Err != nil { - panic(result.Err) - } - - PrintEvents(result.RawEvents, map[string][]string{}) - - res, err := result.GetIdFromEvent(eventName, fieldName) - if err != nil { - panic(err) - } - return res -} - -// Deprecated, use Send().GetIdFromEvent -func (t OverflowInteractionBuilder) RunGetIdFromEvent(eventName string, fieldName string) uint64 { - - result := t.Send() - if result.Err != nil { - panic(result.Err) - } - res, err := result.GetIdFromEvent(eventName, fieldName) - if err != nil { - panic(err) - } - return res -} - -// Deprecated: Use Tx().Print().GetIdsFromEvent -func (t OverflowInteractionBuilder) RunGetIds(eventName string, fieldName string) ([]uint64, error) { - - result := t.Send() - if result.Err != nil { - return nil, result.Err - } - return result.GetIdsFromEvent(eventName, fieldName), nil -} - -// Deprecated: use Tx().GetEventsWithName -func (t OverflowInteractionBuilder) RunGetEventsWithNameOrError(eventName string) ([]OverflowFormatedEvent, error) { - - result := t.Send() - if result.Err != nil { - return nil, result.Err - } - var events []OverflowFormatedEvent - for _, event := range result.RawEvents { - ev := ParseEvent(event, uint64(0), time.Unix(0, 0), []string{}) - if ev.Name == eventName { - events = append(events, *ev) - } - } - return events, nil - -} - -// Deprecated: Use Send().GetEventsWithName() -func (t OverflowInteractionBuilder) RunGetEventsWithName(eventName string) []OverflowFormatedEvent { - - result := t.Send() - if result.Err != nil { - panic(result.Err) - } - var events []OverflowFormatedEvent - for _, event := range result.RawEvents { - ev := ParseEvent(event, uint64(0), time.Unix(0, 0), []string{}) - if ev.Name == eventName { - events = append(events, *ev) - } - } - return events -} - -// Deprecated: use Send() -// -// RunE runs returns events and error -func (t OverflowInteractionBuilder) RunE() ([]flow.Event, error) { - result := t.Send() - return result.RawEvents, result.Err -} diff --git a/upload_integration_test.go b/upload_integration_test.go index f257fd0..65ddbbd 100644 --- a/upload_integration_test.go +++ b/upload_integration_test.go @@ -7,7 +7,8 @@ import ( ) func TestTransactionUpload(t *testing.T) { - g := NewTestingEmulator().Start() + g, err := OverflowTesting() + assert.NoError(t, err) t.Run("Upload image file invalid file", func(t *testing.T) { @@ -25,56 +26,46 @@ func TestTransactionUpload(t *testing.T) { t.Run("Upload test file", func(t *testing.T) { - //need flow in account to upload - g.TransactionFromFile("mint_tokens"). - SignProposeAndPayAsService(). - Args(g.Arguments(). - Account("first"). - UFix64(100.0)). - Test(t). - AssertSuccess() + g.Tx("mint_tokens", + WithSignerServiceAccount(), + WithArg("recipient", "first"), + WithArg("amount", 100.0), + ).AssertSuccess(t) err := g.UploadFile("testdata/testFile.txt", "first") assert.NoError(t, err) - g.Transaction(` + g.Tx(` import Debug from "../contracts/Debug.cdc" transaction { prepare(account: AuthAccount) { var content= account.load(from: /storage/upload) ?? panic("could not load content") Debug.log(content) } -}`). - SignProposeAndPayAs("first"). - Test(t). - AssertSuccess(). - AssertDebugLog("VGhpcyBpcyBhIGZpbGU=") +}`, WithSigner("first")). + AssertSuccess(t). + AssertDebugLog(t, "VGhpcyBpcyBhIGZpbGU=") }) t.Run("Upload test image", func(t *testing.T) { - //need flow in account to upload - g.TransactionFromFile("mint_tokens"). - SignProposeAndPayAsService(). - Args(g.Arguments(). - Account("first"). - UFix64(100.0)). - Test(t). - AssertSuccess() + g.Tx("mint_tokens", + WithSignerServiceAccount(), + WithArg("recipient", "first"), + WithArg("amount", 100.0), + ).AssertSuccess(t) err := g.UploadImageAsDataUrl("testdata/pig.png", "first") assert.NoError(t, err) - g.Transaction(` + g.Tx(` import Debug from "../contracts/Debug.cdc" transaction { prepare(account: AuthAccount) { var content= account.load(from: /storage/upload) ?? panic("could not load content") Debug.log(content) } -}`). - SignProposeAndPayAs("first"). - Test(t). - AssertSuccess(). - AssertDebugLog("data:image/png;base64, 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") +}`, WithSigner("first")). + AssertSuccess(t). + AssertDebugLog(t, "data:image/png;base64, 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") }) t.Run("Download and upload file fails wrong url", func(t *testing.T) { @@ -95,54 +86,47 @@ transaction { t.Run("Download and upload file", func(t *testing.T) { //need flow in account to upload image - g.TransactionFromFile("mint_tokens"). - SignProposeAndPayAsService(). - Args(g.Arguments(). - Account("first"). - UFix64(100.0)). - Test(t). - AssertSuccess() + + g.Tx("mint_tokens", + WithSignerServiceAccount(), + WithArg("recipient", "first"), + WithArg("amount", 100.0), + ).AssertSuccess(t) err := g.DownloadAndUploadFile("https://httpbin.org/image/png", "first") assert.NoError(t, err) - g.Transaction(` + g.Tx(` import Debug from "../contracts/Debug.cdc" transaction { prepare(account: AuthAccount) { var content= account.load(from: /storage/upload) ?? panic("could not load content") Debug.log(content) } -}`). - SignProposeAndPayAs("first"). - Test(t). - AssertSuccess() +}`, WithSigner("first")). + AssertSuccess(t) }) + t.Run("Download image and upload", func(t *testing.T) { //need flow in account to upload image - g.TransactionFromFile("mint_tokens"). - SignProposeAndPayAsService(). - Args(g.Arguments(). - Account("first"). - UFix64(100.0)). - Test(t). - AssertSuccess() + g.Tx("mint_tokens", + WithSignerServiceAccount(), + WithArg("recipient", "first"), + WithArg("amount", 100.0), + ).AssertSuccess(t) err := g.DownloadImageAndUploadAsDataUrl("https://httpbin.org/image/png", "first") assert.NoError(t, err) - g.Transaction(` + g.Tx(` import Debug from "../contracts/Debug.cdc" transaction { prepare(account: AuthAccount) { var content= account.load(from: /storage/upload) ?? panic("could not load content") Debug.log(content) } -}`). - SignProposeAndPayAs("first"). - Test(t). - AssertSuccess() +}`, WithSigner("first")).AssertSuccess(t) }) }