Skip to content

Commit

Permalink
Apply defaults to invokes (#142)
Browse files Browse the repository at this point in the history
Fixes #115 

This change applies default values as part of `Invoke`. This is inline
with the behavior for resources.
  • Loading branch information
iwahbe authored Oct 26, 2023
1 parent 9efd441 commit 7cea218
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 0 deletions.
6 changes: 6 additions & 0 deletions infer/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ func (r *derivedInvokeController[F, I, O]) Invoke(ctx p.Context, req p.InvokeReq
Failures: mapFailures,
}, nil
}

err = applyDefaults(&i)
if err != nil {
return p.InvokeResponse{}, fmt.Errorf("unable to apply defaults: %w", err)
}

var f F
// If F is a *struct, we need to rehydrate the underlying struct
if v := reflect.ValueOf(f); v.Kind() == reflect.Pointer && v.IsNil() {
Expand Down
105 changes: 105 additions & 0 deletions infer/tests/invoke_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// Copyright 2022, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package tests

import (
"testing"

"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

p "github.com/pulumi/pulumi-go-provider"
)

func TestInvoke(t *testing.T) {
t.Parallel()
pString := resource.NewStringProperty
type pMap = resource.PropertyMap
type pValue = resource.PropertyValue

t.Run("missing-arg", func(t *testing.T) {
t.Parallel()
prov := provider()
resp, err := prov.Invoke(p.InvokeRequest{
Token: "test:index:getJoin",
Args: pMap{},
})
require.NoError(t, err)
assert.Equal(t, 1, len(resp.Failures)) // Missing required field `elems`
})

t.Run("all-args", func(t *testing.T) {
t.Parallel()
prov := provider()
resp, err := prov.Invoke(p.InvokeRequest{
Token: "test:index:getJoin",
Args: pMap{
"elems": pValue{V: []pValue{
pString("foo"),
pString("bar"),
}},
"sep": pString("-"),
},
})
require.NoError(t, err)
assert.Empty(t, resp.Failures)

assert.Equal(t, pMap{
"result": pString("foo-bar"),
}, resp.Return)
})

t.Run("default-args", func(t *testing.T) {
t.Parallel()
prov := provider()
resp, err := prov.Invoke(p.InvokeRequest{
Token: "test:index:getJoin",
Args: pMap{
"elems": pValue{V: []pValue{
pString("foo"),
pString("bar"),
}},
},
})
require.NoError(t, err)
assert.Empty(t, resp.Failures)

assert.Equal(t, pMap{
"result": pString("foo,bar"), // default value is ","
}, resp.Return)
})
t.Run("zero-args", func(t *testing.T) {
t.Parallel()
prov := provider()
resp, err := prov.Invoke(p.InvokeRequest{
Token: "test:index:getJoin",
Args: pMap{
"elems": pValue{V: []pValue{
pString("foo"),
pString("bar"),
}},
"sep": pString(""),
},
})
require.NoError(t, err)
assert.Empty(t, resp.Failures)

assert.Equal(t, pMap{
"result": pString("foobar"), // The default doesn't apply here
}, resp.Return)
})

}
22 changes: 22 additions & 0 deletions infer/tests/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package tests
import (
"encoding/json"
"fmt"
"strings"

"github.com/blang/semver"
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
Expand Down Expand Up @@ -321,6 +322,24 @@ func (w *ReadConfig) Create(
return "read", ReadConfigOutput{Config: string(bytes)}, err
}

type GetJoin struct{}
type JoinArgs struct {
Elems []string `pulumi:"elems"`
Sep *string `pulumi:"sep,optional"`
}

func (j *JoinArgs) Annotate(a infer.Annotator) {
a.SetDefault(&j.Sep, ",")
}

type JoinResult struct {
Result string `pulumi:"result"`
}

func (*GetJoin) Call(ctx p.Context, args JoinArgs) (JoinResult, error) {
return JoinResult{strings.Join(args.Elems, *args.Sep)}, nil
}

type ConfigCustom struct {
Number *float64 `pulumi:"number,optional"`
Squared float64
Expand Down Expand Up @@ -380,6 +399,9 @@ func providerOpts(config infer.InferredConfig) infer.Options {
infer.Resource[*ReadConfig, ReadConfigArgs, ReadConfigOutput](),
infer.Resource[*ReadConfigCustom, ReadConfigCustomArgs, ReadConfigCustomOutput](),
},
Functions: []infer.InferredFunction{
infer.Function[*GetJoin, JoinArgs, JoinResult](),
},
ModuleMap: map[tokens.ModuleName]tokens.ModuleName{"tests": "index"},
}
}
Expand Down

0 comments on commit 7cea218

Please sign in to comment.