Skip to content

Commit

Permalink
Refactor code
Browse files Browse the repository at this point in the history
  • Loading branch information
SupunS committed Mar 23, 2021
1 parent 7de6ef1 commit 037b0b0
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 82 deletions.
34 changes: 21 additions & 13 deletions runtime/argument_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ func valueConformsToDynamicType(value interpreter.Value, dynamicType interpreter

switch typ := dynamicType.(type) {
case interpreter.ArrayDynamicType:
ok = valueConfirmsToArrayDynamicType(value, typ)
ok = valueConformsToArrayDynamicType(value, typ)
case interpreter.CompositeDynamicType:
ok = valueConformsToSemaType(value, typ.StaticType)
case interpreter.DictionaryDynamicType:
ok = valueConfirmsToDictionaryDynamicType(value, typ)
ok = valueConformsToDictionaryDynamicType(value, typ)
case interpreter.SomeDynamicType:
ok = valueConfirmsToSomeDynamicType(value, typ)
ok = valueConformsToSomeDynamicType(value, typ)

// Following types are guaranteed to be decoded correctly by the json.decode().
// However, this additional layer is added to protect the Cadence runtime,
Expand Down Expand Up @@ -87,7 +87,7 @@ func valueConformsToDynamicType(value interpreter.Value, dynamicType interpreter
// TODO: add support for checking the referenced value conformance (if importing is supported).
_, ok = value.(*interpreter.StorageReferenceValue)
case interpreter.EphemeralReferenceDynamicType:
ok = valueConfirmsToEphemeralReferenceDynamicType(value, typ)
ok = valueConformsToEphemeralReferenceDynamicType(value, typ)
case interpreter.VoidDynamicType:
// Void type cannot have a value.
ok = false
Expand All @@ -96,7 +96,7 @@ func valueConformsToDynamicType(value interpreter.Value, dynamicType interpreter
return
}

func valueConfirmsToArrayDynamicType(value interpreter.Value, arrayType interpreter.ArrayDynamicType) bool {
func valueConformsToArrayDynamicType(value interpreter.Value, arrayType interpreter.ArrayDynamicType) bool {
arrayValue, ok := value.(*interpreter.ArrayValue)
if !ok || len(arrayValue.Values) != len(arrayType.ElementTypes) {
return false
Expand All @@ -111,7 +111,11 @@ func valueConfirmsToArrayDynamicType(value interpreter.Value, arrayType interpre
return true
}

func valueConfirmsToDictionaryDynamicType(value interpreter.Value, dictionaryType interpreter.DictionaryDynamicType) bool {
func valueConformsToDictionaryDynamicType(
value interpreter.Value,
dictionaryType interpreter.DictionaryDynamicType,
) bool {

dictionaryValue, ok := value.(*interpreter.DictionaryValue)
if !ok || len(dictionaryValue.Keys.Values) != len(dictionaryType.EntryTypes) {
return false
Expand All @@ -137,7 +141,7 @@ func valueConfirmsToDictionaryDynamicType(value interpreter.Value, dictionaryTyp
return true
}

func valueConfirmsToSomeDynamicType(value interpreter.Value, someType interpreter.SomeDynamicType) bool {
func valueConformsToSomeDynamicType(value interpreter.Value, someType interpreter.SomeDynamicType) bool {
someValue, ok := value.(*interpreter.SomeValue)
if !ok {
return false
Expand All @@ -146,7 +150,11 @@ func valueConfirmsToSomeDynamicType(value interpreter.Value, someType interprete
return valueConformsToDynamicType(someValue.Value, someType.InnerType)
}

func valueConfirmsToEphemeralReferenceDynamicType(value interpreter.Value, refType interpreter.EphemeralReferenceDynamicType) bool {
func valueConformsToEphemeralReferenceDynamicType(
value interpreter.Value,
refType interpreter.EphemeralReferenceDynamicType,
) bool {

referenceValue, ok := value.(*interpreter.EphemeralReferenceValue)
if !ok {
return false
Expand Down Expand Up @@ -224,7 +232,7 @@ func valueConformsToSemaType(value interpreter.Value, semaType sema.Type) (ok bo
case *sema.FunctionType:
_, ok = value.(interpreter.FunctionValue)
case *sema.TransactionType:
ok = false
// false
}

return
Expand Down Expand Up @@ -327,16 +335,16 @@ func valueConformsToDictionaryType(value interpreter.Value, dictionaryType *sema
return false
}

for _, entryKey := range dictionaryValue.Keys.Values {
for _, key := range dictionaryValue.Keys.Values {
// Check the key
if !valueConformsToSemaType(entryKey, dictionaryType.KeyType) {
if !valueConformsToSemaType(key, dictionaryType.KeyType) {
return false
}

// Check the value. Here it is assumed an imported value can only have
// static entries, but not deferred keys/values.
key := interpreter.DictionaryKey(entryKey)
entryValue, ok := dictionaryValue.Entries.Get(key)
dictionaryKey := interpreter.DictionaryKey(key)
entryValue, ok := dictionaryValue.Entries.Get(dictionaryKey)
if !ok || !valueConformsToSemaType(entryValue, dictionaryType.ValueType) {
return false
}
Expand Down
121 changes: 54 additions & 67 deletions runtime/convertValues_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1015,18 +1015,18 @@ func importAndExportValuesFromScript(t *testing.T, script string, arg cadence.Va
)
}

type importValueTest struct {
type argumentPassingTest struct {
label string
typeSignature string
exportedValue cadence.Value
skipExport bool
}

func TestImportValue(t *testing.T) {
func TestArgumentPassing(t *testing.T) {

t.Parallel()

var importValueTests = []importValueTest{
var argumentPassingTests = []argumentPassingTest{
{
label: "Nil",
typeSignature: "String?",
Expand Down Expand Up @@ -1208,7 +1208,8 @@ func TestImportValue(t *testing.T) {
exportedValue: cadence.NewAddress([8]byte{0, 0, 0, 0, 0, 1, 0, 2}),
},

// TODO: Enable once https://github.com/onflow/cadence/issues/712 is fixed.
// TODO: Enable below once https://github.com/onflow/cadence/issues/712 is fixed.
// TODO: Add a malformed argument test for capabilities
//{
// label: "Capability",
// typeSignature: "Capability<&Foo>",
Expand All @@ -1233,14 +1234,15 @@ func TestImportValue(t *testing.T) {

}

testImport := func(test importValueTest) {
testArgumentPassing := func(test argumentPassingTest) {

t.Run(test.label, func(t *testing.T) {

t.Parallel()

returnSignature := ""
returnStmt := ""

if !test.skipExport {
returnSignature = fmt.Sprintf(": %[1]s", test.typeSignature)
returnStmt = "return arg"
Expand All @@ -1262,23 +1264,24 @@ func TestImportValue(t *testing.T) {

actual, err := importAndExportValuesFromScript(t, script, test.exportedValue)
require.NoError(t, err)

if !test.skipExport {
assert.Equal(t, test.exportedValue, actual)
}
})
}

for _, testCase := range importValueTests {
testImport(testCase)
for _, testCase := range argumentPassingTests {
testArgumentPassing(testCase)
}
}

func TestImportComplexStruct(t *testing.T) {
func TestComplexStructArgumentPassing(t *testing.T) {

t.Parallel()

// Complex struct value
fooStructValue := cadence.Struct{
complexStructValue := cadence.Struct{
StructType: &cadence.StructType{
Location: utils.TestLocation,
QualifiedIdentifier: "Foo",
Expand Down Expand Up @@ -1331,6 +1334,7 @@ func TestImportComplexStruct(t *testing.T) {
},
},
},

Fields: []cadence.Value{
cadence.NewString("John"),
cadence.NewDictionary([]cadence.KeyValuePair{
Expand Down Expand Up @@ -1364,66 +1368,49 @@ func TestImportComplexStruct(t *testing.T) {
},
}

testImport := func(test importValueTest) {

t.Run(test.label, func(t *testing.T) {

t.Parallel()

script := fmt.Sprintf(
`pub fun main(arg: %[1]s): %[1]s {
script := fmt.Sprintf(
`pub fun main(arg: %[1]s): %[1]s {
if !arg.isInstance(Type<%[1]s>()) {
panic("Not a %[1]s value")
}
return arg
}
pub struct Foo {
pub var a: String?
pub var b: {String: String}
pub var c: [String]
pub var d: [String; 2]
pub var e: Address
pub var f: Bool
pub var g: StoragePath
pub var h: PublicPath
pub var i: PrivatePath
if !arg.isInstance(Type<%[1]s>()) {
panic("Not a %[1]s value")
}
init() {
self.a = "Hello"
self.b = {}
self.c = []
self.d = ["foo", "bar"]
self.e = 0x42
self.f = true
self.g = /storage/foo
self.h = /public/foo
self.i = /private/foo
}
}`,
test.typeSignature,
)
return arg
}
actual, err := importAndExportValuesFromScript(t, script, test.exportedValue)
require.NoError(t, err)
if !test.skipExport {
assert.Equal(t, test.exportedValue, actual)
pub struct Foo {
pub var a: String?
pub var b: {String: String}
pub var c: [String]
pub var d: [String; 2]
pub var e: Address
pub var f: Bool
pub var g: StoragePath
pub var h: PublicPath
pub var i: PrivatePath
init() {
self.a = "Hello"
self.b = {}
self.c = []
self.d = ["foo", "bar"]
self.e = 0x42
self.f = true
self.g = /storage/foo
self.h = /public/foo
self.i = /private/foo
}
})
}

testImport(
importValueTest{
label: "Struct",
typeSignature: "Foo",
exportedValue: fooStructValue,
},
}`,
"Foo",
)

actual, err := importAndExportValuesFromScript(t, script, complexStructValue)
require.NoError(t, err)
assert.Equal(t, complexStructValue, actual)

}

func TestMalformedImportValue(t *testing.T) {
func TestMalformedArgumentPassing(t *testing.T) {

t.Parallel()

Expand Down Expand Up @@ -1511,7 +1498,7 @@ func TestMalformedImportValue(t *testing.T) {
},
}

var importValueTests = []importValueTest{
var argumentPassingTests = []argumentPassingTest{
{
label: "Malformed Struct field type",
typeSignature: "Foo",
Expand Down Expand Up @@ -1568,7 +1555,7 @@ func TestMalformedImportValue(t *testing.T) {
},
}

testImport := func(test importValueTest) {
testArgumentPassing := func(test argumentPassingTest) {

t.Run(test.label, func(t *testing.T) {

Expand Down Expand Up @@ -1623,12 +1610,12 @@ func TestMalformedImportValue(t *testing.T) {
assert.Contains(
t,
argError.Err.Error(),
fmt.Sprintf("malformed value `%s`", test.exportedValue.String()),
fmt.Sprintf("malformed argument `%s`", test.exportedValue.String()),
)
})
}

for _, testCase := range importValueTests {
testImport(testCase)
for _, testCase := range argumentPassingTests {
testArgumentPassing(testCase)
}
}
2 changes: 1 addition & 1 deletion runtime/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ type MalformedArgumentError struct {

func (e *MalformedArgumentError) Error() string {
return fmt.Sprintf(
"malformed value `%s`",
"malformed argument `%s`",
e.Value,
)
}
Expand Down
2 changes: 1 addition & 1 deletion runtime/interpreter/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -5801,7 +5801,7 @@ func (v *DictionaryValue) Destroy(inter *Interpreter, getLocationRange func() Lo
}

func (v *DictionaryValue) ContainsKey(keyValue Value) BoolValue {
key := dictionaryKey(keyValue)
key := DictionaryKey(keyValue)
_, ok := v.Entries.Get(key)
if ok {
return true
Expand Down

0 comments on commit 037b0b0

Please sign in to comment.