github.com/sfdevops1/terrra4orm@v0.11.12-beta1/config/hcl2_shim_util_test.go (about) 1 package config 2 3 import ( 4 "testing" 5 6 hcl2 "github.com/hashicorp/hcl2/hcl" 7 hcl2syntax "github.com/hashicorp/hcl2/hcl/hclsyntax" 8 "github.com/zclconf/go-cty/cty" 9 ) 10 11 func TestHCL2InterpolationFuncs(t *testing.T) { 12 // This is not a comprehensive test of all the functions (they are tested 13 // in interpolation_funcs_test.go already) but rather just calling a 14 // representative set via the HCL2 API to verify that the HCL2-to-HIL 15 // function shim is working as expected. 16 tests := []struct { 17 Expr string 18 Want cty.Value 19 Err bool 20 }{ 21 { 22 `upper("hello")`, 23 cty.StringVal("HELLO"), 24 false, 25 }, 26 { 27 `abs(-2)`, 28 cty.NumberIntVal(2), 29 false, 30 }, 31 { 32 `abs(-2.5)`, 33 cty.NumberFloatVal(2.5), 34 false, 35 }, 36 { 37 `cidrsubnet("")`, 38 cty.DynamicVal, 39 true, // not enough arguments 40 }, 41 { 42 `cidrsubnet("10.1.0.0/16", 8, 2)`, 43 cty.StringVal("10.1.2.0/24"), 44 false, 45 }, 46 { 47 `concat([])`, 48 // Since HIL doesn't maintain element type information for list 49 // types, HCL2 can't either without elements to sniff. 50 cty.ListValEmpty(cty.DynamicPseudoType), 51 false, 52 }, 53 { 54 `concat([], [])`, 55 cty.ListValEmpty(cty.DynamicPseudoType), 56 false, 57 }, 58 { 59 `concat(["a"], ["b", "c"])`, 60 cty.ListVal([]cty.Value{ 61 cty.StringVal("a"), 62 cty.StringVal("b"), 63 cty.StringVal("c"), 64 }), 65 false, 66 }, 67 { 68 `list()`, 69 cty.ListValEmpty(cty.DynamicPseudoType), 70 false, 71 }, 72 { 73 `list("a", "b", "c")`, 74 cty.ListVal([]cty.Value{ 75 cty.StringVal("a"), 76 cty.StringVal("b"), 77 cty.StringVal("c"), 78 }), 79 false, 80 }, 81 { 82 `list(list("a"), list("b"), list("c"))`, 83 // The types emerge here in a bit of a strange tangle because of 84 // the guesswork we do when trying to recover lost information from 85 // HIL, but the rest of the language doesn't really care whether 86 // we use lists or tuples here as long as we are consistent with 87 // the type system invariants. 88 cty.ListVal([]cty.Value{ 89 cty.TupleVal([]cty.Value{cty.StringVal("a")}), 90 cty.TupleVal([]cty.Value{cty.StringVal("b")}), 91 cty.TupleVal([]cty.Value{cty.StringVal("c")}), 92 }), 93 false, 94 }, 95 { 96 `list(list("a"), "b")`, 97 cty.DynamicVal, 98 true, // inconsistent types 99 }, 100 { 101 `length([])`, 102 cty.NumberIntVal(0), 103 false, 104 }, 105 { 106 `length([2])`, 107 cty.NumberIntVal(1), 108 false, 109 }, 110 { 111 `jsonencode(2)`, 112 cty.StringVal(`2`), 113 false, 114 }, 115 { 116 `jsonencode(true)`, 117 cty.StringVal(`true`), 118 false, 119 }, 120 { 121 `jsonencode("foo")`, 122 cty.StringVal(`"foo"`), 123 false, 124 }, 125 { 126 `jsonencode({})`, 127 cty.StringVal(`{}`), 128 false, 129 }, 130 { 131 `jsonencode([1])`, 132 cty.StringVal(`[1]`), 133 false, 134 }, 135 { 136 `jsondecode("{}")`, 137 cty.EmptyObjectVal, 138 false, 139 }, 140 { 141 `jsondecode("[5, true]")[0]`, 142 cty.NumberIntVal(5), 143 false, 144 }, 145 } 146 147 for _, test := range tests { 148 t.Run(test.Expr, func(t *testing.T) { 149 expr, diags := hcl2syntax.ParseExpression([]byte(test.Expr), "", hcl2.Pos{Line: 1, Column: 1}) 150 if len(diags) != 0 { 151 for _, diag := range diags { 152 t.Logf("- %s", diag) 153 } 154 t.Fatalf("unexpected diagnostics while parsing expression") 155 } 156 157 got, diags := expr.Value(&hcl2.EvalContext{ 158 Functions: hcl2InterpolationFuncs(), 159 }) 160 gotErr := diags.HasErrors() 161 if gotErr != test.Err { 162 if test.Err { 163 t.Errorf("expected errors but got none") 164 } else { 165 t.Errorf("unexpected errors") 166 for _, diag := range diags { 167 t.Logf("- %s", diag) 168 } 169 } 170 } 171 if !got.RawEquals(test.Want) { 172 t.Errorf("wrong result\nexpr: %s\ngot: %#v\nwant: %#v", test.Expr, got, test.Want) 173 } 174 }) 175 } 176 }