Some of the apply rewriter's assumptions were broken by the richer expressions available in HCL2. These changes fix those broken assumptions, in particular the assumption that only scope traversal expressions are sources of eventual values.
106 lines
2.6 KiB
Go
106 lines
2.6 KiB
Go
package hcl2
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/hcl/v2"
|
|
"github.com/pulumi/pulumi/pkg/v2/codegen/hcl2/model"
|
|
"github.com/pulumi/pulumi/pkg/v2/codegen/hcl2/syntax"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
type nameInfo int
|
|
|
|
func (nameInfo) Format(name string) string {
|
|
return name
|
|
}
|
|
|
|
func TestApplyRewriter(t *testing.T) {
|
|
cases := []struct {
|
|
input, output string
|
|
}{
|
|
{
|
|
input: `"v: ${resource.foo.bar}"`,
|
|
output: `__apply(resource.foo,eval(foo, "v: ${foo.bar}"))`,
|
|
},
|
|
{
|
|
input: `"v: ${resource.baz[0]}"`,
|
|
output: `__apply(resource.baz,eval(baz, "v: ${baz[0]}"))`,
|
|
},
|
|
{
|
|
input: `"v: ${resources[0].foo.bar}"`,
|
|
output: `__apply(resources[0].foo,eval(foo, "v: ${foo.bar}"))`,
|
|
},
|
|
{
|
|
input: `"v: ${resources.*.id[0]}"`,
|
|
output: `__apply(resources.*.id[0],eval(id, "v: ${id}"))`,
|
|
},
|
|
{
|
|
input: `"v: ${element(resources.*.id, 0)}"`,
|
|
output: `__apply(element(resources.*.id, 0),eval(ids, "v: ${ids}"))`,
|
|
},
|
|
{
|
|
input: `"v: ${resource[key]}"`,
|
|
output: `__apply(resource[key],eval(key, "v: ${key}"))`,
|
|
},
|
|
{
|
|
input: `"v: ${resource[resource.id]}"`,
|
|
output: `__apply(__apply(resource.id,eval(id, resource[id])),eval(id, "v: ${id}"))`,
|
|
},
|
|
{
|
|
input: `toJSON({
|
|
Version = "2012-10-17"
|
|
Statement = [{
|
|
Effect = "Allow"
|
|
Principal = "*"
|
|
Action = [ "s3:GetObject" ]
|
|
Resource = [ "arn:aws:s3:::${resource.id}/*" ]
|
|
}]
|
|
})`,
|
|
output: `__apply(resource.id,eval(id, toJSON({
|
|
Version = "2012-10-17"
|
|
Statement = [{
|
|
Effect = "Allow"
|
|
Principal = "*"
|
|
Action = [ "s3:GetObject" ]
|
|
Resource = [ "arn:aws:s3:::${id}/*" ]
|
|
}]
|
|
})))`,
|
|
},
|
|
}
|
|
|
|
resourceType := model.NewObjectType(map[string]model.Type{
|
|
"id": model.NewOutputType(model.StringType),
|
|
"foo": model.NewOutputType(model.NewObjectType(map[string]model.Type{
|
|
"bar": model.StringType,
|
|
})),
|
|
"baz": model.NewOutputType(model.NewListType(model.StringType)),
|
|
})
|
|
|
|
scope := model.NewRootScope(syntax.None)
|
|
scope.Define("key", &model.Variable{
|
|
Name: "key",
|
|
VariableType: model.StringType,
|
|
})
|
|
scope.Define("resource", &model.Variable{
|
|
Name: "resource",
|
|
VariableType: resourceType,
|
|
})
|
|
scope.Define("resources", &model.Variable{
|
|
Name: "resources",
|
|
VariableType: model.NewListType(resourceType),
|
|
})
|
|
scope.DefineFunction("element", pulumiBuiltins["element"])
|
|
scope.DefineFunction("toJSON", pulumiBuiltins["toJSON"])
|
|
|
|
for _, c := range cases {
|
|
expr, diags := model.BindExpressionText(c.input, scope, hcl.Pos{})
|
|
assert.Len(t, diags, 0)
|
|
|
|
expr, diags = RewriteApplies(expr, nameInfo(0), true)
|
|
assert.Len(t, diags, 0)
|
|
|
|
assert.Equal(t, c.output, fmt.Sprintf("%v", expr))
|
|
}
|
|
}
|