github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/lang/funcs/number_test.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package funcs 5 6 import ( 7 "fmt" 8 "testing" 9 10 "github.com/terramate-io/tf/lang/marks" 11 "github.com/zclconf/go-cty/cty" 12 ) 13 14 func TestLog(t *testing.T) { 15 tests := []struct { 16 Num cty.Value 17 Base cty.Value 18 Want cty.Value 19 Err bool 20 }{ 21 { 22 cty.NumberFloatVal(1), 23 cty.NumberFloatVal(10), 24 cty.NumberFloatVal(0), 25 false, 26 }, 27 { 28 cty.NumberFloatVal(10), 29 cty.NumberFloatVal(10), 30 cty.NumberFloatVal(1), 31 false, 32 }, 33 34 { 35 cty.NumberFloatVal(0), 36 cty.NumberFloatVal(10), 37 cty.NegativeInfinity, 38 false, 39 }, 40 { 41 cty.NumberFloatVal(10), 42 cty.NumberFloatVal(0), 43 cty.NumberFloatVal(-0), 44 false, 45 }, 46 } 47 48 for _, test := range tests { 49 t.Run(fmt.Sprintf("log(%#v, %#v)", test.Num, test.Base), func(t *testing.T) { 50 got, err := Log(test.Num, test.Base) 51 52 if test.Err { 53 if err == nil { 54 t.Fatal("succeeded; want error") 55 } 56 return 57 } else if err != nil { 58 t.Fatalf("unexpected error: %s", err) 59 } 60 61 if !got.RawEquals(test.Want) { 62 t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, test.Want) 63 } 64 }) 65 } 66 } 67 68 func TestPow(t *testing.T) { 69 tests := []struct { 70 Num cty.Value 71 Power cty.Value 72 Want cty.Value 73 Err bool 74 }{ 75 { 76 cty.NumberFloatVal(1), 77 cty.NumberFloatVal(0), 78 cty.NumberFloatVal(1), 79 false, 80 }, 81 { 82 cty.NumberFloatVal(1), 83 cty.NumberFloatVal(1), 84 cty.NumberFloatVal(1), 85 false, 86 }, 87 88 { 89 cty.NumberFloatVal(2), 90 cty.NumberFloatVal(0), 91 cty.NumberFloatVal(1), 92 false, 93 }, 94 { 95 cty.NumberFloatVal(2), 96 cty.NumberFloatVal(1), 97 cty.NumberFloatVal(2), 98 false, 99 }, 100 { 101 cty.NumberFloatVal(3), 102 cty.NumberFloatVal(2), 103 cty.NumberFloatVal(9), 104 false, 105 }, 106 { 107 cty.NumberFloatVal(-3), 108 cty.NumberFloatVal(2), 109 cty.NumberFloatVal(9), 110 false, 111 }, 112 { 113 cty.NumberFloatVal(2), 114 cty.NumberFloatVal(-2), 115 cty.NumberFloatVal(0.25), 116 false, 117 }, 118 { 119 cty.NumberFloatVal(0), 120 cty.NumberFloatVal(2), 121 cty.NumberFloatVal(0), 122 false, 123 }, 124 } 125 126 for _, test := range tests { 127 t.Run(fmt.Sprintf("pow(%#v, %#v)", test.Num, test.Power), func(t *testing.T) { 128 got, err := Pow(test.Num, test.Power) 129 130 if test.Err { 131 if err == nil { 132 t.Fatal("succeeded; want error") 133 } 134 return 135 } else if err != nil { 136 t.Fatalf("unexpected error: %s", err) 137 } 138 139 if !got.RawEquals(test.Want) { 140 t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, test.Want) 141 } 142 }) 143 } 144 } 145 146 func TestSignum(t *testing.T) { 147 tests := []struct { 148 Num cty.Value 149 Want cty.Value 150 Err bool 151 }{ 152 { 153 cty.NumberFloatVal(0), 154 cty.NumberFloatVal(0), 155 false, 156 }, 157 { 158 cty.NumberFloatVal(12), 159 cty.NumberFloatVal(1), 160 false, 161 }, 162 { 163 cty.NumberFloatVal(-29), 164 cty.NumberFloatVal(-1), 165 false, 166 }, 167 } 168 169 for _, test := range tests { 170 t.Run(fmt.Sprintf("signum(%#v)", test.Num), func(t *testing.T) { 171 got, err := Signum(test.Num) 172 173 if test.Err { 174 if err == nil { 175 t.Fatal("succeeded; want error") 176 } 177 return 178 } else if err != nil { 179 t.Fatalf("unexpected error: %s", err) 180 } 181 182 if !got.RawEquals(test.Want) { 183 t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, test.Want) 184 } 185 }) 186 } 187 } 188 189 func TestParseInt(t *testing.T) { 190 tests := []struct { 191 Num cty.Value 192 Base cty.Value 193 Want cty.Value 194 Err string 195 }{ 196 { 197 cty.StringVal("128"), 198 cty.NumberIntVal(10), 199 cty.NumberIntVal(128), 200 ``, 201 }, 202 { 203 cty.StringVal("128").Mark(marks.Sensitive), 204 cty.NumberIntVal(10), 205 cty.NumberIntVal(128).Mark(marks.Sensitive), 206 ``, 207 }, 208 { 209 cty.StringVal("128"), 210 cty.NumberIntVal(10).Mark(marks.Sensitive), 211 cty.NumberIntVal(128).Mark(marks.Sensitive), 212 ``, 213 }, 214 { 215 cty.StringVal("128").Mark(marks.Sensitive), 216 cty.NumberIntVal(10).Mark(marks.Sensitive), 217 cty.NumberIntVal(128).Mark(marks.Sensitive), 218 ``, 219 }, 220 { 221 cty.StringVal("128").Mark("boop"), 222 cty.NumberIntVal(10).Mark(marks.Sensitive), 223 cty.NumberIntVal(128).WithMarks(cty.NewValueMarks("boop", marks.Sensitive)), 224 ``, 225 }, 226 { 227 cty.StringVal("-128"), 228 cty.NumberIntVal(10), 229 cty.NumberIntVal(-128), 230 ``, 231 }, 232 { 233 cty.StringVal("00128"), 234 cty.NumberIntVal(10), 235 cty.NumberIntVal(128), 236 ``, 237 }, 238 { 239 cty.StringVal("-00128"), 240 cty.NumberIntVal(10), 241 cty.NumberIntVal(-128), 242 ``, 243 }, 244 { 245 cty.StringVal("FF00"), 246 cty.NumberIntVal(16), 247 cty.NumberIntVal(65280), 248 ``, 249 }, 250 { 251 cty.StringVal("ff00"), 252 cty.NumberIntVal(16), 253 cty.NumberIntVal(65280), 254 ``, 255 }, 256 { 257 cty.StringVal("-FF00"), 258 cty.NumberIntVal(16), 259 cty.NumberIntVal(-65280), 260 ``, 261 }, 262 { 263 cty.StringVal("00FF00"), 264 cty.NumberIntVal(16), 265 cty.NumberIntVal(65280), 266 ``, 267 }, 268 { 269 cty.StringVal("-00FF00"), 270 cty.NumberIntVal(16), 271 cty.NumberIntVal(-65280), 272 ``, 273 }, 274 { 275 cty.StringVal("1011111011101111"), 276 cty.NumberIntVal(2), 277 cty.NumberIntVal(48879), 278 ``, 279 }, 280 { 281 cty.StringVal("aA"), 282 cty.NumberIntVal(62), 283 cty.NumberIntVal(656), 284 ``, 285 }, 286 { 287 cty.StringVal("Aa"), 288 cty.NumberIntVal(62), 289 cty.NumberIntVal(2242), 290 ``, 291 }, 292 { 293 cty.StringVal("999999999999999999999999999999999999999999999999999999999999"), 294 cty.NumberIntVal(10), 295 cty.MustParseNumberVal("999999999999999999999999999999999999999999999999999999999999"), 296 ``, 297 }, 298 { 299 cty.StringVal("FF"), 300 cty.NumberIntVal(10), 301 cty.UnknownVal(cty.Number), 302 `cannot parse "FF" as a base 10 integer`, 303 }, 304 { 305 cty.StringVal("FF").Mark(marks.Sensitive), 306 cty.NumberIntVal(10), 307 cty.UnknownVal(cty.Number), 308 `cannot parse (sensitive value) as a base 10 integer`, 309 }, 310 { 311 cty.StringVal("FF").Mark(marks.Sensitive), 312 cty.NumberIntVal(10).Mark(marks.Sensitive), 313 cty.UnknownVal(cty.Number), 314 `cannot parse (sensitive value) as a base (sensitive value) integer`, 315 }, 316 { 317 cty.StringVal("00FF"), 318 cty.NumberIntVal(10), 319 cty.UnknownVal(cty.Number), 320 `cannot parse "00FF" as a base 10 integer`, 321 }, 322 { 323 cty.StringVal("-00FF"), 324 cty.NumberIntVal(10), 325 cty.UnknownVal(cty.Number), 326 `cannot parse "-00FF" as a base 10 integer`, 327 }, 328 { 329 cty.NumberIntVal(2), 330 cty.NumberIntVal(10), 331 cty.UnknownVal(cty.Number), 332 `first argument must be a string, not number`, 333 }, 334 { 335 cty.StringVal("1"), 336 cty.NumberIntVal(63), 337 cty.UnknownVal(cty.Number), 338 `base must be a whole number between 2 and 62 inclusive`, 339 }, 340 { 341 cty.StringVal("1"), 342 cty.NumberIntVal(-1), 343 cty.UnknownVal(cty.Number), 344 `base must be a whole number between 2 and 62 inclusive`, 345 }, 346 { 347 cty.StringVal("1"), 348 cty.NumberIntVal(1), 349 cty.UnknownVal(cty.Number), 350 `base must be a whole number between 2 and 62 inclusive`, 351 }, 352 { 353 cty.StringVal("1"), 354 cty.NumberIntVal(0), 355 cty.UnknownVal(cty.Number), 356 `base must be a whole number between 2 and 62 inclusive`, 357 }, 358 { 359 cty.StringVal("1.2"), 360 cty.NumberIntVal(10), 361 cty.UnknownVal(cty.Number), 362 `cannot parse "1.2" as a base 10 integer`, 363 }, 364 } 365 366 for _, test := range tests { 367 t.Run(fmt.Sprintf("parseint(%#v, %#v)", test.Num, test.Base), func(t *testing.T) { 368 got, err := ParseInt(test.Num, test.Base) 369 370 if test.Err != "" { 371 if err == nil { 372 t.Fatal("succeeded; want error") 373 } 374 if got, want := err.Error(), test.Err; got != want { 375 t.Errorf("wrong error\ngot: %s\nwant: %s", got, want) 376 } 377 return 378 } else if err != nil { 379 t.Fatalf("unexpected error: %s", err) 380 } 381 382 if !got.RawEquals(test.Want) { 383 t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, test.Want) 384 } 385 }) 386 } 387 }