opentofu/config/interpolate_test.go
Paul Hinze ffa29090ec
core: Better error for dot indexing on user vars
Dot indexing worked in the "regexps and strings" world of 0.6.x, but it
no longer works on the 0.7 series w/ proper List / Map types.

There is plenty of dot-indexed config out in the wild, so we need to do
what we can to point users to the new syntax.

Here is one place we can do it for user variables (`var.somemap`). We'll
also need to address Resource Variables and Module Variables in a
separate PR.

This fixes the panic in #7103 - a proper error message is now returned.
2016-06-12 10:45:48 -05:00

260 lines
4.4 KiB
Go

package config
import (
"reflect"
"strings"
"testing"
"github.com/hashicorp/hil"
)
func TestNewInterpolatedVariable(t *testing.T) {
cases := []struct {
Input string
Result InterpolatedVariable
Error bool
}{
{
"var.foo",
&UserVariable{
Name: "foo",
key: "var.foo",
},
false,
},
{
"module.foo.bar",
&ModuleVariable{
Name: "foo",
Field: "bar",
key: "module.foo.bar",
},
false,
},
{
"count.index",
&CountVariable{
Type: CountValueIndex,
key: "count.index",
},
false,
},
{
"count.nope",
&CountVariable{
Type: CountValueInvalid,
key: "count.nope",
},
false,
},
{
"path.module",
&PathVariable{
Type: PathValueModule,
key: "path.module",
},
false,
},
{
"self.address",
&SelfVariable{
Field: "address",
key: "self.address",
},
false,
},
}
for i, tc := range cases {
actual, err := NewInterpolatedVariable(tc.Input)
if err != nil != tc.Error {
t.Fatalf("%d. Error: %s", i, err)
}
if !reflect.DeepEqual(actual, tc.Result) {
t.Fatalf("%d bad: %#v", i, actual)
}
}
}
func TestNewResourceVariable(t *testing.T) {
v, err := NewResourceVariable("foo.bar.baz")
if err != nil {
t.Fatalf("err: %s", err)
}
if v.Mode != ManagedResourceMode {
t.Fatalf("bad: %#v", v)
}
if v.Type != "foo" {
t.Fatalf("bad: %#v", v)
}
if v.Name != "bar" {
t.Fatalf("bad: %#v", v)
}
if v.Field != "baz" {
t.Fatalf("bad: %#v", v)
}
if v.Multi {
t.Fatal("should not be multi")
}
if v.FullKey() != "foo.bar.baz" {
t.Fatalf("bad: %#v", v)
}
}
func TestNewResourceVariableData(t *testing.T) {
v, err := NewResourceVariable("data.foo.bar.baz")
if err != nil {
t.Fatalf("err: %s", err)
}
if v.Mode != DataResourceMode {
t.Fatalf("bad: %#v", v)
}
if v.Type != "foo" {
t.Fatalf("bad: %#v", v)
}
if v.Name != "bar" {
t.Fatalf("bad: %#v", v)
}
if v.Field != "baz" {
t.Fatalf("bad: %#v", v)
}
if v.Multi {
t.Fatal("should not be multi")
}
if v.FullKey() != "data.foo.bar.baz" {
t.Fatalf("bad: %#v", v)
}
}
func TestNewUserVariable(t *testing.T) {
v, err := NewUserVariable("var.bar")
if err != nil {
t.Fatalf("err: %s", err)
}
if v.Name != "bar" {
t.Fatalf("bad: %#v", v.Name)
}
if v.FullKey() != "var.bar" {
t.Fatalf("bad: %#v", v)
}
}
func TestNewUserVariable_oldMapDotIndexErr(t *testing.T) {
_, err := NewUserVariable("var.bar.baz")
if err == nil || !strings.Contains(err.Error(), "Invalid dot index") {
t.Fatalf("Expected dot index err, got: %#v", err)
}
}
func TestResourceVariable_impl(t *testing.T) {
var _ InterpolatedVariable = new(ResourceVariable)
}
func TestResourceVariable_Multi(t *testing.T) {
v, err := NewResourceVariable("foo.bar.*.baz")
if err != nil {
t.Fatalf("err: %s", err)
}
if v.Type != "foo" {
t.Fatalf("bad: %#v", v)
}
if v.Name != "bar" {
t.Fatalf("bad: %#v", v)
}
if v.Field != "baz" {
t.Fatalf("bad: %#v", v)
}
if !v.Multi {
t.Fatal("should be multi")
}
}
func TestResourceVariable_MultiIndex(t *testing.T) {
cases := []struct {
Input string
Index int
Field string
}{
{"foo.bar.*.baz", -1, "baz"},
{"foo.bar.0.baz", 0, "baz"},
{"foo.bar.5.baz", 5, "baz"},
}
for _, tc := range cases {
v, err := NewResourceVariable(tc.Input)
if err != nil {
t.Fatalf("err: %s", err)
}
if !v.Multi {
t.Fatalf("should be multi: %s", tc.Input)
}
if v.Index != tc.Index {
t.Fatalf("bad: %d\n\n%s", v.Index, tc.Input)
}
if v.Field != tc.Field {
t.Fatalf("bad: %s\n\n%s", v.Field, tc.Input)
}
}
}
func TestUserVariable_impl(t *testing.T) {
var _ InterpolatedVariable = new(UserVariable)
}
func TestDetectVariables(t *testing.T) {
cases := []struct {
Input string
Result []InterpolatedVariable
}{
{
"foo $${var.foo}",
nil,
},
{
"foo ${var.foo}",
[]InterpolatedVariable{
&UserVariable{
Name: "foo",
key: "var.foo",
},
},
},
{
"foo ${var.foo} ${var.bar}",
[]InterpolatedVariable{
&UserVariable{
Name: "foo",
key: "var.foo",
},
&UserVariable{
Name: "bar",
key: "var.bar",
},
},
},
}
for _, tc := range cases {
ast, err := hil.Parse(tc.Input)
if err != nil {
t.Fatalf("%s\n\nInput: %s", err, tc.Input)
}
actual, err := DetectVariables(ast)
if err != nil {
t.Fatalf("err: %s", err)
}
if !reflect.DeepEqual(actual, tc.Result) {
t.Fatalf("bad: %#v\n\nInput: %s", actual, tc.Input)
}
}
}