github.com/cycloidio/terraform@v1.1.10-0.20220513142504-76d5c768dc63/lang/funcs/conversion_test.go (about) 1 package funcs 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/cycloidio/terraform/lang/marks" 8 "github.com/zclconf/go-cty/cty" 9 ) 10 11 func TestTo(t *testing.T) { 12 tests := []struct { 13 Value cty.Value 14 TargetTy cty.Type 15 Want cty.Value 16 Err string 17 }{ 18 { 19 cty.StringVal("a"), 20 cty.String, 21 cty.StringVal("a"), 22 ``, 23 }, 24 { 25 cty.UnknownVal(cty.String), 26 cty.String, 27 cty.UnknownVal(cty.String), 28 ``, 29 }, 30 { 31 cty.NullVal(cty.String), 32 cty.String, 33 cty.NullVal(cty.String), 34 ``, 35 }, 36 { 37 cty.StringVal("a").Mark("boop"), 38 cty.String, 39 cty.StringVal("a").Mark("boop"), 40 ``, 41 }, 42 { 43 cty.NullVal(cty.String).Mark("boop"), 44 cty.String, 45 cty.NullVal(cty.String).Mark("boop"), 46 ``, 47 }, 48 { 49 cty.True, 50 cty.String, 51 cty.StringVal("true"), 52 ``, 53 }, 54 { 55 cty.StringVal("a"), 56 cty.Bool, 57 cty.DynamicVal, 58 `cannot convert "a" to bool; only the strings "true" or "false" are allowed`, 59 }, 60 { 61 cty.StringVal("a").Mark("boop"), 62 cty.Bool, 63 cty.DynamicVal, 64 `cannot convert "a" to bool; only the strings "true" or "false" are allowed`, 65 }, 66 { 67 cty.StringVal("a").Mark(marks.Sensitive), 68 cty.Bool, 69 cty.DynamicVal, 70 `cannot convert this sensitive string to bool`, 71 }, 72 { 73 cty.StringVal("a"), 74 cty.Number, 75 cty.DynamicVal, 76 `cannot convert "a" to number; given string must be a decimal representation of a number`, 77 }, 78 { 79 cty.StringVal("a").Mark("boop"), 80 cty.Number, 81 cty.DynamicVal, 82 `cannot convert "a" to number; given string must be a decimal representation of a number`, 83 }, 84 { 85 cty.StringVal("a").Mark(marks.Sensitive), 86 cty.Number, 87 cty.DynamicVal, 88 `cannot convert this sensitive string to number`, 89 }, 90 { 91 cty.NullVal(cty.String), 92 cty.Number, 93 cty.NullVal(cty.Number), 94 ``, 95 }, 96 { 97 cty.UnknownVal(cty.Bool), 98 cty.String, 99 cty.UnknownVal(cty.String), 100 ``, 101 }, 102 { 103 cty.UnknownVal(cty.String), 104 cty.Bool, 105 cty.UnknownVal(cty.Bool), // conversion is optimistic 106 ``, 107 }, 108 { 109 cty.TupleVal([]cty.Value{cty.StringVal("hello"), cty.True}), 110 cty.List(cty.String), 111 cty.ListVal([]cty.Value{cty.StringVal("hello"), cty.StringVal("true")}), 112 ``, 113 }, 114 { 115 cty.TupleVal([]cty.Value{cty.StringVal("hello"), cty.True}), 116 cty.Set(cty.String), 117 cty.SetVal([]cty.Value{cty.StringVal("hello"), cty.StringVal("true")}), 118 ``, 119 }, 120 { 121 cty.ObjectVal(map[string]cty.Value{"foo": cty.StringVal("hello"), "bar": cty.True}), 122 cty.Map(cty.String), 123 cty.MapVal(map[string]cty.Value{"foo": cty.StringVal("hello"), "bar": cty.StringVal("true")}), 124 ``, 125 }, 126 { 127 cty.ObjectVal(map[string]cty.Value{"foo": cty.StringVal("hello"), "bar": cty.StringVal("world").Mark("boop")}), 128 cty.Map(cty.String), 129 cty.MapVal(map[string]cty.Value{"foo": cty.StringVal("hello"), "bar": cty.StringVal("world").Mark("boop")}), 130 ``, 131 }, 132 { 133 cty.ObjectVal(map[string]cty.Value{"foo": cty.StringVal("hello"), "bar": cty.StringVal("world")}).Mark("boop"), 134 cty.Map(cty.String), 135 cty.MapVal(map[string]cty.Value{"foo": cty.StringVal("hello"), "bar": cty.StringVal("world")}).Mark("boop"), 136 ``, 137 }, 138 { 139 cty.TupleVal([]cty.Value{cty.StringVal("hello"), cty.StringVal("world").Mark("boop")}), 140 cty.List(cty.String), 141 cty.ListVal([]cty.Value{cty.StringVal("hello"), cty.StringVal("world").Mark("boop")}), 142 ``, 143 }, 144 { 145 cty.TupleVal([]cty.Value{cty.StringVal("hello"), cty.StringVal("world")}).Mark("boop"), 146 cty.List(cty.String), 147 cty.ListVal([]cty.Value{cty.StringVal("hello"), cty.StringVal("world")}).Mark("boop"), 148 ``, 149 }, 150 { 151 cty.EmptyTupleVal, 152 cty.String, 153 cty.DynamicVal, 154 `cannot convert tuple to string`, 155 }, 156 { 157 cty.UnknownVal(cty.EmptyTuple), 158 cty.String, 159 cty.DynamicVal, 160 `cannot convert tuple to string`, 161 }, 162 { 163 cty.EmptyObjectVal, 164 cty.Object(map[string]cty.Type{"foo": cty.String}), 165 cty.DynamicVal, 166 `incompatible object type for conversion: attribute "foo" is required`, 167 }, 168 } 169 170 for _, test := range tests { 171 t.Run(fmt.Sprintf("to %s(%#v)", test.TargetTy.FriendlyNameForConstraint(), test.Value), func(t *testing.T) { 172 f := MakeToFunc(test.TargetTy) 173 got, err := f.Call([]cty.Value{test.Value}) 174 175 if test.Err != "" { 176 if err == nil { 177 t.Fatal("succeeded; want error") 178 } 179 if got, want := err.Error(), test.Err; got != want { 180 t.Fatalf("wrong error\ngot: %s\nwant: %s", got, want) 181 } 182 return 183 } else if err != nil { 184 t.Fatalf("unexpected error: %s", err) 185 } 186 187 if !got.RawEquals(test.Want) { 188 t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, test.Want) 189 } 190 }) 191 } 192 }