From 94baef9aa6b39e9e0ed42a93cb3d5c7420e91933 Mon Sep 17 00:00:00 2001 From: James Bardin Date: Mon, 8 Feb 2021 09:17:28 -0500 Subject: [PATCH] add an ExprMap method to the mock expression Add an ExprMethod so that the mock expressions can be handled by the hcl.ExprMap function. Added basic tests for both ExprList and ExprMap --- hcltest/mock.go | 18 ++++++ hcltest/mock_test.go | 127 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+) diff --git a/hcltest/mock.go b/hcltest/mock.go index 9e3a746..5f5e82c 100644 --- a/hcltest/mock.go +++ b/hcltest/mock.go @@ -166,6 +166,24 @@ func (e mockExprLiteral) ExprList() []hcl.Expression { return nil } +// Implementation for hcl.ExprMap +func (e mockExprLiteral) ExprMap() []hcl.KeyValuePair { + v := e.V + ty := v.Type() + if v.IsKnown() && !v.IsNull() && (ty.IsObjectType() || ty.IsMapType()) { + ret := make([]hcl.KeyValuePair, 0, v.LengthInt()) + for it := v.ElementIterator(); it.Next(); { + k, v := it.Element() + ret = append(ret, hcl.KeyValuePair{ + Key: MockExprLiteral(k), + Value: MockExprLiteral(v), + }) + } + return ret + } + return nil +} + // MockExprVariable returns a hcl.Expression that evaluates to the value of // the variable with the given name. func MockExprVariable(name string) hcl.Expression { diff --git a/hcltest/mock_test.go b/hcltest/mock_test.go index 6d823f9..5b01d02 100644 --- a/hcltest/mock_test.go +++ b/hcltest/mock_test.go @@ -1,6 +1,7 @@ package hcltest import ( + "strings" "testing" "reflect" @@ -266,3 +267,129 @@ func TestMockBodyPartialContent(t *testing.T) { }) } } + +func TestExprList(t *testing.T) { + tests := map[string]struct { + In hcl.Expression + Want []hcl.Expression + Diags string + }{ + "as list": { + In: MockExprLiteral(cty.ListVal([]cty.Value{ + cty.StringVal("foo"), + cty.StringVal("bar"), + })), + Want: []hcl.Expression{ + MockExprLiteral(cty.StringVal("foo")), + MockExprLiteral(cty.StringVal("bar")), + }, + }, + "as tuple": { + In: MockExprLiteral(cty.TupleVal([]cty.Value{ + cty.StringVal("foo"), + cty.StringVal("bar"), + })), + Want: []hcl.Expression{ + MockExprLiteral(cty.StringVal("foo")), + MockExprLiteral(cty.StringVal("bar")), + }, + }, + "not list": { + In: MockExprLiteral(cty.ObjectVal(map[string]cty.Value{ + "a": cty.StringVal("foo"), + "b": cty.StringVal("bar"), + })), + Want: nil, + Diags: "list expression is required", + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + got, diags := hcl.ExprList(tc.In) + if tc.Diags != "" { + if diags.HasErrors() && !strings.Contains(diags.Error(), tc.Diags) { + t.Errorf("expected error %q, got %q", tc.Diags, diags) + } + if !diags.HasErrors() { + t.Errorf("expected diagnostic message %q", tc.Diags) + } + } else if diags.HasErrors() { + t.Error(diags) + } + + if !reflect.DeepEqual(got, tc.Want) { + t.Errorf("incorrect expression,\ngot: %#v\nwant: %#v", got, tc.Want) + } + }) + } +} + +func TestExprMap(t *testing.T) { + tests := map[string]struct { + In hcl.Expression + Want []hcl.KeyValuePair + Diags string + }{ + "as object": { + In: MockExprLiteral(cty.ObjectVal(map[string]cty.Value{ + "name": cty.StringVal("test"), + "count": cty.NumberIntVal(2), + })), + Want: []hcl.KeyValuePair{ + { + Key: MockExprLiteral(cty.StringVal("count")), + Value: MockExprLiteral(cty.NumberIntVal(2)), + }, + { + Key: MockExprLiteral(cty.StringVal("name")), + Value: MockExprLiteral(cty.StringVal("test")), + }, + }, + }, + "as map": { + In: MockExprLiteral(cty.MapVal(map[string]cty.Value{ + "name": cty.StringVal("test"), + "version": cty.StringVal("2.0.0"), + })), + Want: []hcl.KeyValuePair{ + { + Key: MockExprLiteral(cty.StringVal("name")), + Value: MockExprLiteral(cty.StringVal("test")), + }, + { + Key: MockExprLiteral(cty.StringVal("version")), + Value: MockExprLiteral(cty.StringVal("2.0.0")), + }, + }, + }, + "not map": { + In: MockExprLiteral(cty.ListVal([]cty.Value{ + cty.StringVal("foo"), + cty.StringVal("bar"), + })), + Want: nil, + Diags: "map expression is required", + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + got, diags := hcl.ExprMap(tc.In) + if tc.Diags != "" { + if diags.HasErrors() && !strings.Contains(diags.Error(), tc.Diags) { + t.Errorf("expected error %q, got %q", tc.Diags, diags) + } + if !diags.HasErrors() { + t.Errorf("expected diagnostic message %q", tc.Diags) + } + } else if diags.HasErrors() { + t.Error(diags) + } + + if !reflect.DeepEqual(got, tc.Want) { + t.Errorf("incorrect expression,\ngot: %#v\nwant: %#v", got, tc.Want) + } + }) + } +}