diff options
Diffstat (limited to 'vendor/github.com/hashicorp/hcl/decoder_test.go')
-rw-r--r-- | vendor/github.com/hashicorp/hcl/decoder_test.go | 1203 |
1 files changed, 0 insertions, 1203 deletions
diff --git a/vendor/github.com/hashicorp/hcl/decoder_test.go b/vendor/github.com/hashicorp/hcl/decoder_test.go deleted file mode 100644 index 8682f470e..000000000 --- a/vendor/github.com/hashicorp/hcl/decoder_test.go +++ /dev/null @@ -1,1203 +0,0 @@ -package hcl - -import ( - "io/ioutil" - "path/filepath" - "reflect" - "testing" - "time" - - "github.com/davecgh/go-spew/spew" - "github.com/hashicorp/hcl/hcl/ast" -) - -func TestDecode_interface(t *testing.T) { - cases := []struct { - File string - Err bool - Out interface{} - }{ - { - "basic.hcl", - false, - map[string]interface{}{ - "foo": "bar", - "bar": "${file(\"bing/bong.txt\")}", - }, - }, - { - "basic_squish.hcl", - false, - map[string]interface{}{ - "foo": "bar", - "bar": "${file(\"bing/bong.txt\")}", - "foo-bar": "baz", - }, - }, - { - "empty.hcl", - false, - map[string]interface{}{ - "resource": []map[string]interface{}{ - map[string]interface{}{ - "foo": []map[string]interface{}{ - map[string]interface{}{}, - }, - }, - }, - }, - }, - { - "tfvars.hcl", - false, - map[string]interface{}{ - "regularvar": "Should work", - "map.key1": "Value", - "map.key2": "Other value", - }, - }, - { - "escape.hcl", - false, - map[string]interface{}{ - "foo": "bar\"baz\\n", - "qux": "back\\slash", - "bar": "new\nline", - "qax": `slash\:colon`, - "nested": `${HH\\:mm\\:ss}`, - "nestedquotes": `${"\"stringwrappedinquotes\""}`, - }, - }, - { - "float.hcl", - false, - map[string]interface{}{ - "a": 1.02, - "b": 2, - }, - }, - { - "multiline_bad.hcl", - true, - nil, - }, - { - "multiline_literal.hcl", - true, - nil, - }, - { - "multiline_literal_with_hil.hcl", - false, - map[string]interface{}{"multiline_literal_with_hil": "${hello\n world}"}, - }, - { - "multiline_no_marker.hcl", - true, - nil, - }, - { - "multiline.hcl", - false, - map[string]interface{}{"foo": "bar\nbaz\n"}, - }, - { - "multiline_indented.hcl", - false, - map[string]interface{}{"foo": " bar\n baz\n"}, - }, - { - "multiline_no_hanging_indent.hcl", - false, - map[string]interface{}{"foo": " baz\n bar\n foo\n"}, - }, - { - "multiline_no_eof.hcl", - false, - map[string]interface{}{"foo": "bar\nbaz\n", "key": "value"}, - }, - { - "multiline.json", - false, - map[string]interface{}{"foo": "bar\nbaz"}, - }, - { - "null_strings.json", - false, - map[string]interface{}{ - "module": []map[string]interface{}{ - map[string]interface{}{ - "app": []map[string]interface{}{ - map[string]interface{}{"foo": ""}, - }, - }, - }, - }, - }, - { - "scientific.json", - false, - map[string]interface{}{ - "a": 1e-10, - "b": 1e+10, - "c": 1e10, - "d": 1.2e-10, - "e": 1.2e+10, - "f": 1.2e10, - }, - }, - { - "scientific.hcl", - false, - map[string]interface{}{ - "a": 1e-10, - "b": 1e+10, - "c": 1e10, - "d": 1.2e-10, - "e": 1.2e+10, - "f": 1.2e10, - }, - }, - { - "terraform_heroku.hcl", - false, - map[string]interface{}{ - "name": "terraform-test-app", - "config_vars": []map[string]interface{}{ - map[string]interface{}{ - "FOO": "bar", - }, - }, - }, - }, - { - "structure_multi.hcl", - false, - map[string]interface{}{ - "foo": []map[string]interface{}{ - map[string]interface{}{ - "baz": []map[string]interface{}{ - map[string]interface{}{"key": 7}, - }, - }, - map[string]interface{}{ - "bar": []map[string]interface{}{ - map[string]interface{}{"key": 12}, - }, - }, - }, - }, - }, - { - "structure_multi.json", - false, - map[string]interface{}{ - "foo": []map[string]interface{}{ - map[string]interface{}{ - "baz": []map[string]interface{}{ - map[string]interface{}{"key": 7}, - }, - }, - map[string]interface{}{ - "bar": []map[string]interface{}{ - map[string]interface{}{"key": 12}, - }, - }, - }, - }, - }, - { - "list_of_lists.hcl", - false, - map[string]interface{}{ - "foo": []interface{}{ - []interface{}{"foo"}, - []interface{}{"bar"}, - }, - }, - }, - { - "list_of_maps.hcl", - false, - map[string]interface{}{ - "foo": []interface{}{ - map[string]interface{}{"somekey1": "someval1"}, - map[string]interface{}{"somekey2": "someval2", "someextrakey": "someextraval"}, - }, - }, - }, - { - "assign_deep.hcl", - false, - map[string]interface{}{ - "resource": []interface{}{ - map[string]interface{}{ - "foo": []interface{}{ - map[string]interface{}{ - "bar": []map[string]interface{}{ - map[string]interface{}{}}}}}}}, - }, - { - "structure_list.hcl", - false, - map[string]interface{}{ - "foo": []map[string]interface{}{ - map[string]interface{}{ - "key": 7, - }, - map[string]interface{}{ - "key": 12, - }, - }, - }, - }, - { - "structure_list.json", - false, - map[string]interface{}{ - "foo": []map[string]interface{}{ - map[string]interface{}{ - "key": 7, - }, - map[string]interface{}{ - "key": 12, - }, - }, - }, - }, - { - "structure_list_deep.json", - false, - map[string]interface{}{ - "bar": []map[string]interface{}{ - map[string]interface{}{ - "foo": []map[string]interface{}{ - map[string]interface{}{ - "name": "terraform_example", - "ingress": []map[string]interface{}{ - map[string]interface{}{ - "from_port": 22, - }, - map[string]interface{}{ - "from_port": 80, - }, - }, - }, - }, - }, - }, - }, - }, - - { - "structure_list_empty.json", - false, - map[string]interface{}{ - "foo": []interface{}{}, - }, - }, - - { - "nested_block_comment.hcl", - false, - map[string]interface{}{ - "bar": "value", - }, - }, - - { - "unterminated_block_comment.hcl", - true, - nil, - }, - - { - "unterminated_brace.hcl", - true, - nil, - }, - - { - "nested_provider_bad.hcl", - true, - nil, - }, - - { - "object_list.json", - false, - map[string]interface{}{ - "resource": []map[string]interface{}{ - map[string]interface{}{ - "aws_instance": []map[string]interface{}{ - map[string]interface{}{ - "db": []map[string]interface{}{ - map[string]interface{}{ - "vpc": "foo", - "provisioner": []map[string]interface{}{ - map[string]interface{}{ - "file": []map[string]interface{}{ - map[string]interface{}{ - "source": "foo", - "destination": "bar", - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - - // Terraform GH-8295 sanity test that basic decoding into - // interface{} works. - { - "terraform_variable_invalid.json", - false, - map[string]interface{}{ - "variable": []map[string]interface{}{ - map[string]interface{}{ - "whatever": "abc123", - }, - }, - }, - }, - - { - "interpolate.json", - false, - map[string]interface{}{ - "default": `${replace("europe-west", "-", " ")}`, - }, - }, - - { - "block_assign.hcl", - true, - nil, - }, - - { - "escape_backslash.hcl", - false, - map[string]interface{}{ - "output": []map[string]interface{}{ - map[string]interface{}{ - "one": `${replace(var.sub_domain, ".", "\\.")}`, - "two": `${replace(var.sub_domain, ".", "\\\\.")}`, - "many": `${replace(var.sub_domain, ".", "\\\\\\\\.")}`, - }, - }, - }, - }, - - { - "git_crypt.hcl", - true, - nil, - }, - - { - "object_with_bool.hcl", - false, - map[string]interface{}{ - "path": []map[string]interface{}{ - map[string]interface{}{ - "policy": "write", - "permissions": []map[string]interface{}{ - map[string]interface{}{ - "bool": []interface{}{false}, - }, - }, - }, - }, - }, - }, - } - - for _, tc := range cases { - t.Run(tc.File, func(t *testing.T) { - d, err := ioutil.ReadFile(filepath.Join(fixtureDir, tc.File)) - if err != nil { - t.Fatalf("err: %s", err) - } - - var out interface{} - err = Decode(&out, string(d)) - if (err != nil) != tc.Err { - t.Fatalf("Input: %s\n\nError: %s", tc.File, err) - } - - if !reflect.DeepEqual(out, tc.Out) { - t.Fatalf("Input: %s. Actual, Expected.\n\n%#v\n\n%#v", tc.File, out, tc.Out) - } - - var v interface{} - err = Unmarshal(d, &v) - if (err != nil) != tc.Err { - t.Fatalf("Input: %s\n\nError: %s", tc.File, err) - } - - if !reflect.DeepEqual(v, tc.Out) { - t.Fatalf("Input: %s. Actual, Expected.\n\n%#v\n\n%#v", tc.File, out, tc.Out) - } - }) - } -} - -func TestDecode_interfaceInline(t *testing.T) { - cases := []struct { - Value string - Err bool - Out interface{} - }{ - {"t t e{{}}", true, nil}, - {"t=0t d {}", true, map[string]interface{}{"t": 0}}, - {"v=0E0v d{}", true, map[string]interface{}{"v": float64(0)}}, - } - - for _, tc := range cases { - t.Logf("Testing: %q", tc.Value) - - var out interface{} - err := Decode(&out, tc.Value) - if (err != nil) != tc.Err { - t.Fatalf("Input: %q\n\nError: %s", tc.Value, err) - } - - if !reflect.DeepEqual(out, tc.Out) { - t.Fatalf("Input: %q. Actual, Expected.\n\n%#v\n\n%#v", tc.Value, out, tc.Out) - } - - var v interface{} - err = Unmarshal([]byte(tc.Value), &v) - if (err != nil) != tc.Err { - t.Fatalf("Input: %q\n\nError: %s", tc.Value, err) - } - - if !reflect.DeepEqual(v, tc.Out) { - t.Fatalf("Input: %q. Actual, Expected.\n\n%#v\n\n%#v", tc.Value, out, tc.Out) - } - } -} - -func TestDecode_equal(t *testing.T) { - cases := []struct { - One, Two string - }{ - { - "basic.hcl", - "basic.json", - }, - { - "float.hcl", - "float.json", - }, - /* - { - "structure.hcl", - "structure.json", - }, - */ - { - "structure.hcl", - "structure_flat.json", - }, - { - "terraform_heroku.hcl", - "terraform_heroku.json", - }, - } - - for _, tc := range cases { - p1 := filepath.Join(fixtureDir, tc.One) - p2 := filepath.Join(fixtureDir, tc.Two) - - d1, err := ioutil.ReadFile(p1) - if err != nil { - t.Fatalf("err: %s", err) - } - - d2, err := ioutil.ReadFile(p2) - if err != nil { - t.Fatalf("err: %s", err) - } - - var i1, i2 interface{} - err = Decode(&i1, string(d1)) - if err != nil { - t.Fatalf("err: %s", err) - } - - err = Decode(&i2, string(d2)) - if err != nil { - t.Fatalf("err: %s", err) - } - - if !reflect.DeepEqual(i1, i2) { - t.Fatalf( - "%s != %s\n\n%#v\n\n%#v", - tc.One, tc.Two, - i1, i2) - } - } -} - -func TestDecode_flatMap(t *testing.T) { - var val map[string]map[string]string - - err := Decode(&val, testReadFile(t, "structure_flatmap.hcl")) - if err != nil { - t.Fatalf("err: %s", err) - } - - expected := map[string]map[string]string{ - "foo": map[string]string{ - "foo": "bar", - "key": "7", - }, - } - - if !reflect.DeepEqual(val, expected) { - t.Fatalf("Actual: %#v\n\nExpected: %#v", val, expected) - } -} - -func TestDecode_structure(t *testing.T) { - type Embedded interface{} - - type V struct { - Embedded `hcl:"-"` - Key int - Foo string - } - - var actual V - - err := Decode(&actual, testReadFile(t, "flat.hcl")) - if err != nil { - t.Fatalf("err: %s", err) - } - - expected := V{ - Key: 7, - Foo: "bar", - } - - if !reflect.DeepEqual(actual, expected) { - t.Fatalf("Actual: %#v\n\nExpected: %#v", actual, expected) - } -} - -func TestDecode_structurePtr(t *testing.T) { - type V struct { - Key int - Foo string - } - - var actual *V - - err := Decode(&actual, testReadFile(t, "flat.hcl")) - if err != nil { - t.Fatalf("err: %s", err) - } - - expected := &V{ - Key: 7, - Foo: "bar", - } - - if !reflect.DeepEqual(actual, expected) { - t.Fatalf("Actual: %#v\n\nExpected: %#v", actual, expected) - } -} - -func TestDecode_structureArray(t *testing.T) { - // This test is extracted from a failure in Consul (consul.io), - // hence the interesting structure naming. - - type KeyPolicyType string - - type KeyPolicy struct { - Prefix string `hcl:",key"` - Policy KeyPolicyType - } - - type Policy struct { - Keys []KeyPolicy `hcl:"key,expand"` - } - - expected := Policy{ - Keys: []KeyPolicy{ - KeyPolicy{ - Prefix: "", - Policy: "read", - }, - KeyPolicy{ - Prefix: "foo/", - Policy: "write", - }, - KeyPolicy{ - Prefix: "foo/bar/", - Policy: "read", - }, - KeyPolicy{ - Prefix: "foo/bar/baz", - Policy: "deny", - }, - }, - } - - files := []string{ - "decode_policy.hcl", - "decode_policy.json", - } - - for _, f := range files { - var actual Policy - - err := Decode(&actual, testReadFile(t, f)) - if err != nil { - t.Fatalf("Input: %s\n\nerr: %s", f, err) - } - - if !reflect.DeepEqual(actual, expected) { - t.Fatalf("Input: %s\n\nActual: %#v\n\nExpected: %#v", f, actual, expected) - } - } -} - -func TestDecode_sliceExpand(t *testing.T) { - type testInner struct { - Name string `hcl:",key"` - Key string - } - - type testStruct struct { - Services []testInner `hcl:"service,expand"` - } - - expected := testStruct{ - Services: []testInner{ - testInner{ - Name: "my-service-0", - Key: "value", - }, - testInner{ - Name: "my-service-1", - Key: "value", - }, - }, - } - - files := []string{ - "slice_expand.hcl", - } - - for _, f := range files { - t.Logf("Testing: %s", f) - - var actual testStruct - err := Decode(&actual, testReadFile(t, f)) - if err != nil { - t.Fatalf("Input: %s\n\nerr: %s", f, err) - } - - if !reflect.DeepEqual(actual, expected) { - t.Fatalf("Input: %s\n\nActual: %#v\n\nExpected: %#v", f, actual, expected) - } - } -} - -func TestDecode_structureMap(t *testing.T) { - // This test is extracted from a failure in Terraform (terraform.io), - // hence the interesting structure naming. - - type hclVariable struct { - Default interface{} - Description string - Fields []string `hcl:",decodedFields"` - } - - type rawConfig struct { - Variable map[string]hclVariable - } - - expected := rawConfig{ - Variable: map[string]hclVariable{ - "foo": hclVariable{ - Default: "bar", - Description: "bar", - Fields: []string{"Default", "Description"}, - }, - - "amis": hclVariable{ - Default: []map[string]interface{}{ - map[string]interface{}{ - "east": "foo", - }, - }, - Fields: []string{"Default"}, - }, - }, - } - - files := []string{ - "decode_tf_variable.hcl", - "decode_tf_variable.json", - } - - for _, f := range files { - t.Logf("Testing: %s", f) - - var actual rawConfig - err := Decode(&actual, testReadFile(t, f)) - if err != nil { - t.Fatalf("Input: %s\n\nerr: %s", f, err) - } - - if !reflect.DeepEqual(actual, expected) { - t.Fatalf("Input: %s\n\nActual: %#v\n\nExpected: %#v", f, actual, expected) - } - } -} - -func TestDecode_structureMapInvalid(t *testing.T) { - // Terraform GH-8295 - - type hclVariable struct { - Default interface{} - Description string - Fields []string `hcl:",decodedFields"` - } - - type rawConfig struct { - Variable map[string]*hclVariable - } - - var actual rawConfig - err := Decode(&actual, testReadFile(t, "terraform_variable_invalid.json")) - if err == nil { - t.Fatal("expected error") - } -} - -func TestDecode_interfaceNonPointer(t *testing.T) { - var value interface{} - err := Decode(value, testReadFile(t, "basic_int_string.hcl")) - if err == nil { - t.Fatal("should error") - } -} - -func TestDecode_intString(t *testing.T) { - var value struct { - Count int - } - - err := Decode(&value, testReadFile(t, "basic_int_string.hcl")) - if err != nil { - t.Fatalf("err: %s", err) - } - - if value.Count != 3 { - t.Fatalf("bad: %#v", value.Count) - } -} - -func TestDecode_float32(t *testing.T) { - var value struct { - A float32 `hcl:"a"` - B float32 `hcl:"b"` - } - - err := Decode(&value, testReadFile(t, "float.hcl")) - if err != nil { - t.Fatalf("err: %s", err) - } - - if got, want := value.A, float32(1.02); got != want { - t.Fatalf("wrong result %#v; want %#v", got, want) - } - if got, want := value.B, float32(2); got != want { - t.Fatalf("wrong result %#v; want %#v", got, want) - } -} - -func TestDecode_float64(t *testing.T) { - var value struct { - A float64 `hcl:"a"` - B float64 `hcl:"b"` - } - - err := Decode(&value, testReadFile(t, "float.hcl")) - if err != nil { - t.Fatalf("err: %s", err) - } - - if got, want := value.A, float64(1.02); got != want { - t.Fatalf("wrong result %#v; want %#v", got, want) - } - if got, want := value.B, float64(2); got != want { - t.Fatalf("wrong result %#v; want %#v", got, want) - } -} - -func TestDecode_intStringAliased(t *testing.T) { - var value struct { - Count time.Duration - } - - err := Decode(&value, testReadFile(t, "basic_int_string.hcl")) - if err != nil { - t.Fatalf("err: %s", err) - } - - if value.Count != time.Duration(3) { - t.Fatalf("bad: %#v", value.Count) - } -} - -func TestDecode_Node(t *testing.T) { - // given - var value struct { - Content ast.Node - Nested struct { - Content ast.Node - } - } - - content := ` -content { - hello = "world" -} -` - - // when - err := Decode(&value, content) - - // then - if err != nil { - t.Errorf("unable to decode content, %v", err) - return - } - - // verify ast.Node can be decoded later - var v map[string]interface{} - err = DecodeObject(&v, value.Content) - if err != nil { - t.Errorf("unable to decode content, %v", err) - return - } - - if v["hello"] != "world" { - t.Errorf("expected mapping to be returned") - } -} - -func TestDecode_NestedNode(t *testing.T) { - // given - var value struct { - Nested struct { - Content ast.Node - } - } - - content := ` -nested "content" { - hello = "world" -} -` - - // when - err := Decode(&value, content) - - // then - if err != nil { - t.Errorf("unable to decode content, %v", err) - return - } - - // verify ast.Node can be decoded later - var v map[string]interface{} - err = DecodeObject(&v, value.Nested.Content) - if err != nil { - t.Errorf("unable to decode content, %v", err) - return - } - - if v["hello"] != "world" { - t.Errorf("expected mapping to be returned") - } -} - -// https://github.com/hashicorp/hcl/issues/60 -func TestDecode_topLevelKeys(t *testing.T) { - type Template struct { - Source string - } - - templates := struct { - Templates []*Template `hcl:"template"` - }{} - - err := Decode(&templates, ` - template { - source = "blah" - } - - template { - source = "blahblah" - }`) - - if err != nil { - t.Fatal(err) - } - - if templates.Templates[0].Source != "blah" { - t.Errorf("bad source: %s", templates.Templates[0].Source) - } - - if templates.Templates[1].Source != "blahblah" { - t.Errorf("bad source: %s", templates.Templates[1].Source) - } -} - -func TestDecode_flattenedJSON(t *testing.T) { - // make sure we can also correctly extract a Name key too - type V struct { - Name string `hcl:",key"` - Description string - Default map[string]string - } - type Vars struct { - Variable []*V - } - - cases := []struct { - JSON string - Out interface{} - Expected interface{} - }{ - { // Nested object, no sibling keys - JSON: ` -{ - "var_name": { - "default": { - "key1": "a", - "key2": "b" - } - } -} - `, - Out: &[]*V{}, - Expected: &[]*V{ - &V{ - Name: "var_name", - Default: map[string]string{"key1": "a", "key2": "b"}, - }, - }, - }, - - { // Nested object with a sibling key (this worked previously) - JSON: ` -{ - "var_name": { - "description": "Described", - "default": { - "key1": "a", - "key2": "b" - } - } -} - `, - Out: &[]*V{}, - Expected: &[]*V{ - &V{ - Name: "var_name", - Description: "Described", - Default: map[string]string{"key1": "a", "key2": "b"}, - }, - }, - }, - - { // Multiple nested objects, one with a sibling key - JSON: ` -{ - "variable": { - "var_1": { - "default": { - "key1": "a", - "key2": "b" - } - }, - "var_2": { - "description": "Described", - "default": { - "key1": "a", - "key2": "b" - } - } - } -} - `, - Out: &Vars{}, - Expected: &Vars{ - Variable: []*V{ - &V{ - Name: "var_1", - Default: map[string]string{"key1": "a", "key2": "b"}, - }, - &V{ - Name: "var_2", - Description: "Described", - Default: map[string]string{"key1": "a", "key2": "b"}, - }, - }, - }, - }, - - { // Nested object to maps - JSON: ` -{ - "variable": { - "var_name": { - "description": "Described", - "default": { - "key1": "a", - "key2": "b" - } - } - } -} - `, - Out: &[]map[string]interface{}{}, - Expected: &[]map[string]interface{}{ - { - "variable": []map[string]interface{}{ - { - "var_name": []map[string]interface{}{ - { - "description": "Described", - "default": []map[string]interface{}{ - { - "key1": "a", - "key2": "b", - }, - }, - }, - }, - }, - }, - }, - }, - }, - - { // Nested object to maps without a sibling key should decode the same as above - JSON: ` -{ - "variable": { - "var_name": { - "default": { - "key1": "a", - "key2": "b" - } - } - } -} - `, - Out: &[]map[string]interface{}{}, - Expected: &[]map[string]interface{}{ - { - "variable": []map[string]interface{}{ - { - "var_name": []map[string]interface{}{ - { - "default": []map[string]interface{}{ - { - "key1": "a", - "key2": "b", - }, - }, - }, - }, - }, - }, - }, - }, - }, - - { // Nested objects, one with a sibling key, and one without - JSON: ` -{ - "variable": { - "var_1": { - "default": { - "key1": "a", - "key2": "b" - } - }, - "var_2": { - "description": "Described", - "default": { - "key1": "a", - "key2": "b" - } - } - } -} - `, - Out: &[]map[string]interface{}{}, - Expected: &[]map[string]interface{}{ - { - "variable": []map[string]interface{}{ - { - "var_1": []map[string]interface{}{ - { - "default": []map[string]interface{}{ - { - "key1": "a", - "key2": "b", - }, - }, - }, - }, - }, - }, - }, - { - "variable": []map[string]interface{}{ - { - "var_2": []map[string]interface{}{ - { - "description": "Described", - "default": []map[string]interface{}{ - { - "key1": "a", - "key2": "b", - }, - }, - }, - }, - }, - }, - }, - }, - }, - } - - for i, tc := range cases { - err := Decode(tc.Out, tc.JSON) - if err != nil { - t.Fatalf("[%d] err: %s", i, err) - } - - if !reflect.DeepEqual(tc.Out, tc.Expected) { - t.Fatalf("[%d]\ngot: %s\nexpected: %s\n", i, spew.Sdump(tc.Out), spew.Sdump(tc.Expected)) - } - } -} |