package main import ( "context" "testing" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "google.golang.org/protobuf/testing/protocmp" "google.golang.org/protobuf/types/known/durationpb" "github.com/crossplane/function-sdk-go/logging" fnv1 "github.com/crossplane/function-sdk-go/proto/v1" "github.com/crossplane/function-sdk-go/resource" "github.com/crossplane/function-sdk-go/response" ) func TestRunFunction(t *testing.T) { type args struct { ctx context.Context req *fnv1.RunFunctionRequest } type want struct { rsp *fnv1.RunFunctionResponse err error } cases := map[string]struct { reason string args args want want }{ "ResponseIsReturned": { reason: "The Function should return a fatal result if no input was specified", args: args{ req: &fnv1.RunFunctionRequest{ Meta: &fnv1.RequestMeta{Tag: "hello"}, Input: resource.MustStructJSON(`{ "apiVersion": "template.fn.crossplane.io/v1beta1", "kind": "Input", "example": "Hello, world" }`), }, }, want: want{ rsp: &fnv1.RunFunctionResponse{ Meta: &fnv1.ResponseMeta{Tag: "hello", Ttl: durationpb.New(response.DefaultTTL)}, Results: []*fnv1.Result{ { Severity: fnv1.Severity_SEVERITY_NORMAL, Message: "I was run with input \"Hello, world\"!", Target: fnv1.Target_TARGET_COMPOSITE.Enum(), }, }, Conditions: []*fnv1.Condition{ { Type: "FunctionSuccess", Status: fnv1.Status_STATUS_CONDITION_TRUE, Reason: "Success", Target: fnv1.Target_TARGET_COMPOSITE_AND_CLAIM.Enum(), }, }, }, }, }, } for name, tc := range cases { t.Run(name, func(t *testing.T) { f := &Function{log: logging.NewNopLogger()} rsp, err := f.RunFunction(tc.args.ctx, tc.args.req) if diff := cmp.Diff(tc.want.rsp, rsp, protocmp.Transform()); diff != "" { t.Errorf("%s\nf.RunFunction(...): -want rsp, +got rsp:\n%s", tc.reason, diff) } if diff := cmp.Diff(tc.want.err, err, cmpopts.EquateErrors()); diff != "" { t.Errorf("%s\nf.RunFunction(...): -want err, +got err:\n%s", tc.reason, diff) } }) } }