Skip to content

Commit

Permalink
Add native function declarations for all relevant Test contract funct…
Browse files Browse the repository at this point in the history
…ions
  • Loading branch information
m-Peter committed Nov 6, 2023
1 parent e46a491 commit 9ebf7d6
Show file tree
Hide file tree
Showing 4 changed files with 268 additions and 43 deletions.
14 changes: 2 additions & 12 deletions runtime/sema/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -4738,11 +4738,7 @@ func (t *CompositeType) GetMembers() map[string]MemberResolver {
}

func (t *CompositeType) initializeMemberResolvers() {
t.memberResolversOnce.Do(t.initializerMemberResolversFunc())
}

func (t *CompositeType) initializerMemberResolversFunc() func() {
return func() {
t.memberResolversOnce.Do(func() {
memberResolvers := MembersMapAsResolvers(t.Members)

// Check conformances.
Expand Down Expand Up @@ -4777,13 +4773,7 @@ func (t *CompositeType) initializerMemberResolversFunc() func() {
}

t.memberResolvers = withBuiltinMembers(t, memberResolvers)
}
}

func (t *CompositeType) ResolveMembers() {
if t.Members.Len() != len(t.GetMembers()) {
t.initializerMemberResolversFunc()()
}
})
}

func (t *CompositeType) FieldPosition(name string, declaration ast.CompositeLikeDeclaration) ast.Position {
Expand Down
83 changes: 83 additions & 0 deletions runtime/stdlib/contracts/test.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -473,4 +473,87 @@ contract Test {

assert(found, message: "the error message did not contain the given sub-string")
}

/// Creates a matcher with a test function.
/// The test function is of type 'fun(T): Bool',
/// where 'T' is bound to 'AnyStruct'.
///
access(all)
native fun newMatcher<T: AnyStruct>(_ test: fun(T): Bool): Test.Matcher {}

/// Wraps a function call in a closure, and expects it to fail with
/// an error message that contains the given error message portion.
///
access(all)
native fun expectFailure(
_ functionWrapper: fun(): Void,
errorMessageSubstring: String
) {}

/// Expect function tests a value against a matcher
/// and fails the test if it's not a match.
///
access(all)
native fun expect<T: AnyStruct>(_ value: T, _ matcher: Test.Matcher) {}

/// Returns a matcher that succeeds if the tested
/// value is equal to the given value.
///
access(all)
native fun equal<T: AnyStruct>(_ value: T): Test.Matcher {}

/// Fails the test-case if the given values are not equal, and
/// reports a message which explains how the two values differ.
///
access(all)
native fun assertEqual(_ expected: AnyStruct, _ actual: AnyStruct) {}

/// Returns a matcher that succeeds if the tested value is
/// an array or dictionary and the tested value contains
/// no elements.
///
access(all)
native fun beEmpty(): Test.Matcher {}

/// Returns a matcher that succeeds if the tested value is
/// an array or dictionary and has the given number of elements.
///
access(all)
native fun haveElementCount(_ count: Int): Test.Matcher {}

/// Returns a matcher that succeeds if the tested value is
/// an array that contains a value that is equal to the given
/// value, or the tested value is a dictionary that contains
/// an entry where the key is equal to the given value.
///
access(all)
native fun contain(_ element: AnyStruct): Test.Matcher {}

/// Returns a matcher that succeeds if the tested value
/// is a number and greater than the given number.
///
access(all)
native fun beGreaterThan(_ value: Number): Test.Matcher {}

/// Returns a matcher that succeeds if the tested value
/// is a number and less than the given number.
///
access(all)
native fun beLessThan(_ value: Number): Test.Matcher {}

/// Read a local file, and return the content as a string.
///
access(all)
native fun readFile(_ path: String): String {}

/// Fails the test-case if the given condition is false,
/// and reports a message which explains how the condition is false.
///
access(all)
native fun assert(_ condition: Bool, message: String = ""): Void {}

/// Fails the test-case with a message.
///
access(all)
native fun fail(message: String = ""): Void {}
}
23 changes: 12 additions & 11 deletions runtime/stdlib/test_contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,12 @@ var testTypeAssertFunctionType = &sema.FunctionType{
TypeAnnotation: sema.BoolTypeAnnotation,
},
{
Identifier: "message",
TypeAnnotation: sema.StringTypeAnnotation,
Identifier: "message",
TypeAnnotation: sema.StringTypeAnnotation,
DefaultArgument: sema.StringType,
},
},
ReturnTypeAnnotation: sema.VoidTypeAnnotation,
// `message` parameter is optional
Arity: &sema.Arity{Min: 1, Max: 2},
}

var testTypeAssertFunction = interpreter.NewUnmeteredHostFunctionValue(
Expand Down Expand Up @@ -181,13 +180,12 @@ var testTypeFailFunctionType = &sema.FunctionType{
Purity: sema.FunctionPurityView,
Parameters: []sema.Parameter{
{
Identifier: "message",
TypeAnnotation: sema.StringTypeAnnotation,
Identifier: "message",
TypeAnnotation: sema.StringTypeAnnotation,
DefaultArgument: sema.StringType,
},
},
ReturnTypeAnnotation: sema.VoidTypeAnnotation,
// `message` parameter is optional
Arity: &sema.Arity{Min: 0, Max: 1},
}

var testTypeFailFunction = interpreter.NewUnmeteredHostFunctionValue(
Expand Down Expand Up @@ -915,7 +913,10 @@ func newTestContractType() *TestContractType {
program, err := parser.ParseProgram(
nil,
contracts.TestContract,
parser.Config{},
parser.Config{
NativeModifierEnabled: true,
TypeParametersEnabled: true,
},
)
if err != nil {
panic(err)
Expand All @@ -933,7 +934,8 @@ func newTestContractType() *TestContractType {
BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation {
return activation
},
AccessCheckMode: sema.AccessCheckModeStrict,
AccessCheckMode: sema.AccessCheckModeStrict,
AllowNativeDeclarations: true,
},
)
if err != nil {
Expand Down Expand Up @@ -1160,7 +1162,6 @@ func newTestContractType() *TestContractType {
ty.expectFailureFunction = newTestTypeExpectFailureFunction(
expectFailureFunctionType,
)
compositeType.ResolveMembers()

return ty
}
Expand Down
Loading

0 comments on commit 9ebf7d6

Please sign in to comment.