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