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)) } }