github.com/coveo/gotemplate@v2.7.7+incompatible/hcl/hcl_test.go (about) 1 package hcl 2 3 import ( 4 "fmt" 5 "reflect" 6 "testing" 7 8 "github.com/coveo/gotemplate/collections" 9 "github.com/stretchr/testify/assert" 10 ) 11 12 func Test_list_String(t *testing.T) { 13 t.Parallel() 14 15 tests := []struct { 16 name string 17 l hclList 18 want string 19 }{ 20 {"Nil", nil, "[]"}, 21 {"Empty list", hclList{}, "[]"}, 22 {"List of int", hclList{1, 2, 3}, "[1,2,3]"}, 23 {"List of string", strFixture, `["Hello","World,","I'm","Foo","Bar!"]`}, 24 } 25 for _, tt := range tests { 26 t.Run(tt.name, func(t *testing.T) { 27 if got := tt.l.String(); got != tt.want { 28 t.Errorf("hclList.String() = %v, want %v", got, tt.want) 29 } 30 }) 31 } 32 } 33 34 func Test_dict_String(t *testing.T) { 35 t.Parallel() 36 37 tests := []struct { 38 name string 39 d hclDict 40 want string 41 }{ 42 {"nil", nil, ""}, 43 {"Empty dict", hclDict{}, ""}, 44 {"Map", dictFixture, `float=1.23 int=123 list=[1,"two"] listInt=[1,2,3] map{sub1=1 sub2="two"} mapInt{"1"=1 "2"="two"} string="Foo bar"`}, 45 } 46 for _, tt := range tests { 47 t.Run(tt.name, func(t *testing.T) { 48 if got := tt.d.String(); got != tt.want { 49 t.Errorf("hclList.String():\n got %v\nwant %v", got, tt.want) 50 } 51 }) 52 } 53 } 54 55 func TestMarshalHCLVars(t *testing.T) { 56 t.Parallel() 57 58 type test struct { 59 Name string `hcl:",omitempty"` 60 Value int `hcl:",omitempty"` 61 } 62 const ( 63 noIndent = "" 64 indent = " " 65 ) 66 var testNilPtr *test 67 68 type args struct { 69 value interface{} 70 indent string 71 } 72 tests := []struct { 73 name string 74 args args 75 want string 76 }{ 77 {"Integer", args{2, noIndent}, "2"}, 78 {"Boolean", args{true, noIndent}, "true"}, 79 {"String", args{"Hello world", noIndent}, `"Hello world"`}, 80 {"String with newline", args{"Hello\nworld\n", noIndent}, `"Hello\nworld\n"`}, 81 {"String with newline (pretty)", args{"Hello\n\"world\"\n", indent}, "<<-EOF\nHello\n\"world\"\nEOF"}, 82 {"Null value", args{nil, noIndent}, "null"}, 83 {"Null struct", args{testNilPtr, noIndent}, "null"}, 84 {"List of integer", args{[]int{0, 1, 2, 3}, noIndent}, "[0,1,2,3]"}, 85 {"One level map", args{hclDict{"a": hclDict{"b": 10}}, noIndent}, "a {b=10}"}, 86 {"One level map (pretty)", args{hclDict{"a": hclDict{"b": 10}}, indent}, "a {\n b = 10\n}"}, 87 {"Two level map 1", args{hclDict{"a": hclDict{"b": hclDict{"c": 10, "d": 20}}}, noIndent}, "a b {c=10 d=20}"}, 88 {"Two level map 1 (pretty)", args{hclDict{"a": hclDict{"b": hclDict{"c": 10, "d": 20}}}, indent}, "a b {\n c = 10\n d = 20\n}"}, 89 {"Two level map 2", args{hclDict{"a": hclDict{"b": hclDict{"c": 10, "d": 20}}, "e": 30}, noIndent}, "a b {c=10 d=20} e=30"}, 90 {"Two level map 2 (pretty)", args{hclDict{"a": hclDict{"b": hclDict{"c": 10, "d": 20}}, "e": 30}, indent}, "e = 30\n\na b {\n c = 10\n d = 20\n}"}, 91 {"Map", args{hclDict{"a": 0, "bb": 1}, noIndent}, "a=0 bb=1"}, 92 {"Map (pretty)", args{hclDict{"a": 0, "bb": 1}, indent}, "a = 0\nbb = 1"}, 93 {"Structure (pretty)", args{test{"name", 1}, indent}, "Name = \"name\"\nValue = 1"}, 94 {"Structure Ptr (pretty)", args{&test{"name", 1}, indent}, "Name = \"name\"\nValue = 1"}, 95 {"Array of 1 structure (pretty)", args{[]test{{"name", 1}}, indent}, "Name = \"name\"\nValue = 1"}, 96 {"Array of 2 structures (pretty)", args{[]test{{"val1", 1}, {"val2", 1}}, indent}, "[\n {\n Name = \"val1\"\n Value = 1\n },\n {\n Name = \"val2\"\n Value = 1\n },\n]"}, 97 } 98 for _, tt := range tests { 99 t.Run(tt.name, func(t *testing.T) { 100 value := collections.ToNativeRepresentation(tt.args.value) 101 if got, _ := marshalHCL(value, true, true, "", tt.args.indent); !reflect.DeepEqual(got, tt.want) { 102 t.Errorf("MarshalHCLVars() = %v, want %v", got, tt.want) 103 } 104 }) 105 } 106 } 107 108 func TestUnmarshal(t *testing.T) { 109 t.Parallel() 110 111 tests := []struct { 112 name string 113 hcl string 114 want interface{} 115 wantErr bool 116 }{ 117 {"Empty", "", hclDict{}, false}, 118 {"Empty list", "[]", hclList{}, false}, 119 {"List of int", "[1,2,3]", hclList{1, 2, 3}, false}, 120 {"Array of map", "a { b { c { d = 1 e = 2 }}}", hclDict{"a": hclDict{"b": hclDict{"c": hclDict{"d": 1, "e": 2}}}}, false}, 121 {"Map", fmt.Sprint(dictFixture), dictFixture, false}, 122 } 123 for _, tt := range tests { 124 t.Run(tt.name, func(t *testing.T) { 125 var out interface{} 126 err := Unmarshal([]byte(tt.hcl), &out) 127 if (err != nil) != tt.wantErr { 128 t.Errorf("Unmarshal() error = %v, wantErr %v", err, tt.wantErr) 129 } 130 if err == nil && !reflect.DeepEqual(out, tt.want) { 131 t.Errorf("Unmarshal:\n got %[1]v (%[1]T)\nwant %[2]v (%[2]T)", out, tt.want) 132 } 133 }) 134 } 135 } 136 137 func TestUnmarshalStrict(t *testing.T) { 138 t.Parallel() 139 140 tests := []struct { 141 name string 142 hcl string 143 want interface{} 144 wantErr bool 145 }{ 146 {"Empty", "", map[string]interface{}{}, false}, 147 {"Empty list", "[]", nil, true}, 148 {"List of int", "[1,2,3]", nil, true}, 149 {"Array of map", "a { b { c { d = 1 e = 2 }}}", map[string]interface{}{"a": map[string]interface{}{"b": map[string]interface{}{"c": map[string]interface{}{"d": 1, "e": 2}}}}, false}, 150 {"Map", fmt.Sprint(dictFixture), dictFixture.Native(), false}, 151 } 152 for _, tt := range tests { 153 t.Run(tt.name, func(t *testing.T) { 154 var out map[string]interface{} 155 err := Unmarshal([]byte(tt.hcl), &out) 156 if (err != nil) != tt.wantErr { 157 t.Errorf("Unmarshal() error = %v, wantErr %v", err, tt.wantErr) 158 } 159 if err == nil && !reflect.DeepEqual(out, tt.want) { 160 t.Errorf("Unmarshal:\n got %[1]v (%[1]T)\nwant %[2]v (%[2]T)", out, tt.want) 161 } 162 }) 163 } 164 } 165 166 func TestUnmarshalHereDoc(t *testing.T) { 167 test := ` 168 string = <<-EOF 169 Hello world! 170 EOF` 171 var out interface{} 172 err := Unmarshal([]byte(test), &out) 173 assert.NoError(t, err) 174 assert.Equal(t, hclDict{"string": "Hello world!\n"}, out) 175 }