1package stdlib
2
3import (
4	"fmt"
5	"math"
6	"math/big"
7	"testing"
8
9	"github.com/zclconf/go-cty/cty"
10)
11
12func TestAbsolute(t *testing.T) {
13	tests := []struct {
14		Input cty.Value
15		Want  cty.Value
16	}{
17		{
18			cty.NumberIntVal(15),
19			cty.NumberIntVal(15),
20		},
21		{
22			cty.NumberIntVal(-15),
23			cty.NumberIntVal(15),
24		},
25		{
26			cty.NumberIntVal(0),
27			cty.NumberIntVal(0),
28		},
29		{
30			cty.PositiveInfinity,
31			cty.PositiveInfinity,
32		},
33		{
34			cty.NegativeInfinity,
35			cty.PositiveInfinity,
36		},
37		{
38			cty.UnknownVal(cty.Number),
39			cty.UnknownVal(cty.Number),
40		},
41		{
42			cty.DynamicVal,
43			cty.UnknownVal(cty.Number),
44		},
45	}
46
47	for _, test := range tests {
48		t.Run(fmt.Sprintf("Absolute(%#v)", test.Input), func(t *testing.T) {
49			got, err := Absolute(test.Input)
50
51			if err != nil {
52				t.Fatalf("unexpected error: %s", err)
53			}
54
55			if !got.RawEquals(test.Want) {
56				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
57			}
58		})
59	}
60}
61
62func TestAdd(t *testing.T) {
63	tests := []struct {
64		A    cty.Value
65		B    cty.Value
66		Want cty.Value
67	}{
68		{
69			cty.NumberIntVal(1),
70			cty.NumberIntVal(2),
71			cty.NumberIntVal(3),
72		},
73		{
74			cty.NumberIntVal(1),
75			cty.UnknownVal(cty.Number),
76			cty.UnknownVal(cty.Number),
77		},
78		{
79			cty.UnknownVal(cty.Number),
80			cty.UnknownVal(cty.Number),
81			cty.UnknownVal(cty.Number),
82		},
83		{
84			cty.NumberIntVal(1),
85			cty.DynamicVal,
86			cty.UnknownVal(cty.Number),
87		},
88		{
89			cty.DynamicVal,
90			cty.DynamicVal,
91			cty.UnknownVal(cty.Number),
92		},
93	}
94
95	for _, test := range tests {
96		t.Run(fmt.Sprintf("Add(%#v,%#v)", test.A, test.B), func(t *testing.T) {
97			got, err := Add(test.A, test.B)
98
99			if err != nil {
100				t.Fatalf("unexpected error: %s", err)
101			}
102
103			if !got.RawEquals(test.Want) {
104				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
105			}
106		})
107	}
108}
109
110func TestSubtract(t *testing.T) {
111	tests := []struct {
112		A    cty.Value
113		B    cty.Value
114		Want cty.Value
115	}{
116		{
117			cty.NumberIntVal(1),
118			cty.NumberIntVal(2),
119			cty.NumberIntVal(-1),
120		},
121		{
122			cty.NumberIntVal(1),
123			cty.UnknownVal(cty.Number),
124			cty.UnknownVal(cty.Number),
125		},
126		{
127			cty.UnknownVal(cty.Number),
128			cty.UnknownVal(cty.Number),
129			cty.UnknownVal(cty.Number),
130		},
131		{
132			cty.NumberIntVal(1),
133			cty.DynamicVal,
134			cty.UnknownVal(cty.Number),
135		},
136		{
137			cty.DynamicVal,
138			cty.DynamicVal,
139			cty.UnknownVal(cty.Number),
140		},
141	}
142
143	for _, test := range tests {
144		t.Run(fmt.Sprintf("Subtract(%#v,%#v)", test.A, test.B), func(t *testing.T) {
145			got, err := Subtract(test.A, test.B)
146
147			if err != nil {
148				t.Fatalf("unexpected error: %s", err)
149			}
150
151			if !got.RawEquals(test.Want) {
152				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
153			}
154		})
155	}
156}
157
158func TestMultiply(t *testing.T) {
159	tests := []struct {
160		A    cty.Value
161		B    cty.Value
162		Want cty.Value
163	}{
164		{
165			cty.NumberIntVal(5),
166			cty.NumberIntVal(2),
167			cty.NumberIntVal(10),
168		},
169		{
170			cty.NumberIntVal(1),
171			cty.UnknownVal(cty.Number),
172			cty.UnknownVal(cty.Number),
173		},
174		{
175			cty.UnknownVal(cty.Number),
176			cty.UnknownVal(cty.Number),
177			cty.UnknownVal(cty.Number),
178		},
179		{
180			cty.NumberIntVal(1),
181			cty.DynamicVal,
182			cty.UnknownVal(cty.Number),
183		},
184		{
185			cty.DynamicVal,
186			cty.DynamicVal,
187			cty.UnknownVal(cty.Number),
188		},
189	}
190
191	for _, test := range tests {
192		t.Run(fmt.Sprintf("Multiply(%#v,%#v)", test.A, test.B), func(t *testing.T) {
193			got, err := Multiply(test.A, test.B)
194
195			if err != nil {
196				t.Fatalf("unexpected error: %s", err)
197			}
198
199			if !got.RawEquals(test.Want) {
200				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
201			}
202		})
203	}
204}
205
206func TestDivide(t *testing.T) {
207	tests := []struct {
208		A    cty.Value
209		B    cty.Value
210		Want cty.Value
211	}{
212		{
213			cty.NumberIntVal(5),
214			cty.NumberIntVal(2),
215			cty.NumberFloatVal(2.5),
216		},
217		{
218			cty.NumberIntVal(5),
219			cty.NumberIntVal(0),
220			cty.PositiveInfinity,
221		},
222		{
223			cty.NumberIntVal(-5),
224			cty.NumberIntVal(0),
225			cty.NegativeInfinity,
226		},
227		{
228			cty.NumberIntVal(1),
229			cty.PositiveInfinity,
230			cty.Zero,
231		},
232		{
233			cty.NumberIntVal(1),
234			cty.NegativeInfinity,
235			cty.Zero,
236		},
237		{
238			cty.NumberIntVal(1),
239			cty.UnknownVal(cty.Number),
240			cty.UnknownVal(cty.Number),
241		},
242		{
243			cty.UnknownVal(cty.Number),
244			cty.UnknownVal(cty.Number),
245			cty.UnknownVal(cty.Number),
246		},
247		{
248			cty.NumberIntVal(1),
249			cty.DynamicVal,
250			cty.UnknownVal(cty.Number),
251		},
252		{
253			cty.DynamicVal,
254			cty.DynamicVal,
255			cty.UnknownVal(cty.Number),
256		},
257	}
258
259	for _, test := range tests {
260		t.Run(fmt.Sprintf("Divide(%#v,%#v)", test.A, test.B), func(t *testing.T) {
261			got, err := Divide(test.A, test.B)
262
263			if err != nil {
264				t.Fatalf("unexpected error: %s", err)
265			}
266
267			if !got.RawEquals(test.Want) {
268				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
269			}
270		})
271	}
272}
273
274func TestModulo(t *testing.T) {
275	tests := []struct {
276		A    cty.Value
277		B    cty.Value
278		Want cty.Value
279	}{
280		{
281			cty.NumberIntVal(15),
282			cty.NumberIntVal(10),
283			cty.NumberIntVal(5),
284		},
285		{
286			cty.NumberIntVal(0),
287			cty.NumberIntVal(0),
288			cty.NumberIntVal(0),
289		},
290		{
291			cty.PositiveInfinity,
292			cty.NumberIntVal(1),
293			cty.PositiveInfinity,
294		},
295		{
296			cty.NegativeInfinity,
297			cty.NumberIntVal(1),
298			cty.NegativeInfinity,
299		},
300		{
301			cty.NumberIntVal(1),
302			cty.PositiveInfinity,
303			cty.PositiveInfinity,
304		},
305		{
306			cty.NumberIntVal(1),
307			cty.UnknownVal(cty.Number),
308			cty.UnknownVal(cty.Number),
309		},
310		{
311			cty.UnknownVal(cty.Number),
312			cty.UnknownVal(cty.Number),
313			cty.UnknownVal(cty.Number),
314		},
315		{
316			cty.NumberIntVal(1),
317			cty.DynamicVal,
318			cty.UnknownVal(cty.Number),
319		},
320		{
321			cty.DynamicVal,
322			cty.DynamicVal,
323			cty.UnknownVal(cty.Number),
324		},
325	}
326
327	for _, test := range tests {
328		t.Run(fmt.Sprintf("Modulo(%#v,%#v)", test.A, test.B), func(t *testing.T) {
329			got, err := Modulo(test.A, test.B)
330
331			if err != nil {
332				t.Fatalf("unexpected error: %s", err)
333			}
334
335			if !got.RawEquals(test.Want) {
336				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
337			}
338		})
339	}
340}
341
342func TestNegate(t *testing.T) {
343	tests := []struct {
344		Input cty.Value
345		Want  cty.Value
346	}{
347		{
348			cty.NumberIntVal(15),
349			cty.NumberIntVal(-15),
350		},
351		{
352			cty.UnknownVal(cty.Number),
353			cty.UnknownVal(cty.Number),
354		},
355		{
356			cty.DynamicVal,
357			cty.UnknownVal(cty.Number),
358		},
359	}
360
361	for _, test := range tests {
362		t.Run(fmt.Sprintf("Negate(%#v)", test.Input), func(t *testing.T) {
363			got, err := Negate(test.Input)
364
365			if err != nil {
366				t.Fatalf("unexpected error: %s", err)
367			}
368
369			if !got.RawEquals(test.Want) {
370				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
371			}
372		})
373	}
374}
375
376func TestLessThan(t *testing.T) {
377	tests := []struct {
378		A    cty.Value
379		B    cty.Value
380		Want cty.Value
381	}{
382		{
383			cty.NumberIntVal(1),
384			cty.NumberIntVal(2),
385			cty.True,
386		},
387		{
388			cty.NumberIntVal(2),
389			cty.NumberIntVal(1),
390			cty.False,
391		},
392		{
393			cty.NumberIntVal(2),
394			cty.NumberIntVal(2),
395			cty.False,
396		},
397		{
398			cty.NumberIntVal(1),
399			cty.UnknownVal(cty.Number),
400			cty.UnknownVal(cty.Bool),
401		},
402		{
403			cty.UnknownVal(cty.Number),
404			cty.UnknownVal(cty.Number),
405			cty.UnknownVal(cty.Bool),
406		},
407		{
408			cty.NumberIntVal(1),
409			cty.DynamicVal,
410			cty.UnknownVal(cty.Bool),
411		},
412		{
413			cty.DynamicVal,
414			cty.DynamicVal,
415			cty.UnknownVal(cty.Bool),
416		},
417	}
418
419	for _, test := range tests {
420		t.Run(fmt.Sprintf("LessThan(%#v,%#v)", test.A, test.B), func(t *testing.T) {
421			got, err := LessThan(test.A, test.B)
422
423			if err != nil {
424				t.Fatalf("unexpected error: %s", err)
425			}
426
427			if !got.RawEquals(test.Want) {
428				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
429			}
430		})
431	}
432}
433
434func TestLessThanOrEqualTo(t *testing.T) {
435	tests := []struct {
436		A    cty.Value
437		B    cty.Value
438		Want cty.Value
439	}{
440		{
441			cty.NumberIntVal(1),
442			cty.NumberIntVal(2),
443			cty.True,
444		},
445		{
446			cty.NumberIntVal(2),
447			cty.NumberIntVal(1),
448			cty.False,
449		},
450		{
451			cty.NumberIntVal(2),
452			cty.NumberIntVal(2),
453			cty.True,
454		},
455		{
456			cty.NumberIntVal(1),
457			cty.UnknownVal(cty.Number),
458			cty.UnknownVal(cty.Bool),
459		},
460		{
461			cty.UnknownVal(cty.Number),
462			cty.UnknownVal(cty.Number),
463			cty.UnknownVal(cty.Bool),
464		},
465		{
466			cty.NumberIntVal(1),
467			cty.DynamicVal,
468			cty.UnknownVal(cty.Bool),
469		},
470		{
471			cty.DynamicVal,
472			cty.DynamicVal,
473			cty.UnknownVal(cty.Bool),
474		},
475	}
476
477	for _, test := range tests {
478		t.Run(fmt.Sprintf("LessThanOrEqualTo(%#v,%#v)", test.A, test.B), func(t *testing.T) {
479			got, err := LessThanOrEqualTo(test.A, test.B)
480
481			if err != nil {
482				t.Fatalf("unexpected error: %s", err)
483			}
484
485			if !got.RawEquals(test.Want) {
486				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
487			}
488		})
489	}
490}
491
492func TestGreaterThan(t *testing.T) {
493	tests := []struct {
494		A    cty.Value
495		B    cty.Value
496		Want cty.Value
497	}{
498		{
499			cty.NumberIntVal(1),
500			cty.NumberIntVal(2),
501			cty.False,
502		},
503		{
504			cty.NumberIntVal(2),
505			cty.NumberIntVal(1),
506			cty.True,
507		},
508		{
509			cty.NumberIntVal(2),
510			cty.NumberIntVal(2),
511			cty.False,
512		},
513		{
514			cty.NumberIntVal(1),
515			cty.UnknownVal(cty.Number),
516			cty.UnknownVal(cty.Bool),
517		},
518		{
519			cty.UnknownVal(cty.Number),
520			cty.UnknownVal(cty.Number),
521			cty.UnknownVal(cty.Bool),
522		},
523		{
524			cty.NumberIntVal(1),
525			cty.DynamicVal,
526			cty.UnknownVal(cty.Bool),
527		},
528		{
529			cty.DynamicVal,
530			cty.DynamicVal,
531			cty.UnknownVal(cty.Bool),
532		},
533	}
534
535	for _, test := range tests {
536		t.Run(fmt.Sprintf("GreaterThan(%#v,%#v)", test.A, test.B), func(t *testing.T) {
537			got, err := GreaterThan(test.A, test.B)
538
539			if err != nil {
540				t.Fatalf("unexpected error: %s", err)
541			}
542
543			if !got.RawEquals(test.Want) {
544				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
545			}
546		})
547	}
548}
549
550func TestGreaterThanOrEqualTo(t *testing.T) {
551	tests := []struct {
552		A    cty.Value
553		B    cty.Value
554		Want cty.Value
555	}{
556		{
557			cty.NumberIntVal(1),
558			cty.NumberIntVal(2),
559			cty.False,
560		},
561		{
562			cty.NumberIntVal(2),
563			cty.NumberIntVal(1),
564			cty.True,
565		},
566		{
567			cty.NumberIntVal(2),
568			cty.NumberIntVal(2),
569			cty.True,
570		},
571		{
572			cty.NumberIntVal(1),
573			cty.UnknownVal(cty.Number),
574			cty.UnknownVal(cty.Bool),
575		},
576		{
577			cty.UnknownVal(cty.Number),
578			cty.UnknownVal(cty.Number),
579			cty.UnknownVal(cty.Bool),
580		},
581		{
582			cty.NumberIntVal(1),
583			cty.DynamicVal,
584			cty.UnknownVal(cty.Bool),
585		},
586		{
587			cty.DynamicVal,
588			cty.DynamicVal,
589			cty.UnknownVal(cty.Bool),
590		},
591	}
592
593	for _, test := range tests {
594		t.Run(fmt.Sprintf("GreaterThanOrEqualTo(%#v,%#v)", test.A, test.B), func(t *testing.T) {
595			got, err := GreaterThanOrEqualTo(test.A, test.B)
596
597			if err != nil {
598				t.Fatalf("unexpected error: %s", err)
599			}
600
601			if !got.RawEquals(test.Want) {
602				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
603			}
604		})
605	}
606}
607
608func TestMin(t *testing.T) {
609	tests := []struct {
610		Inputs []cty.Value
611		Want   cty.Value
612	}{
613		{
614			[]cty.Value{cty.NumberIntVal(0)},
615			cty.NumberIntVal(0),
616		},
617		{
618			[]cty.Value{cty.NumberIntVal(-12)},
619			cty.NumberIntVal(-12),
620		},
621		{
622			[]cty.Value{cty.NumberIntVal(12)},
623			cty.NumberIntVal(12),
624		},
625		{
626			[]cty.Value{cty.NumberIntVal(-12), cty.NumberIntVal(0), cty.NumberIntVal(2)},
627			cty.NumberIntVal(-12),
628		},
629		{
630			[]cty.Value{cty.NegativeInfinity, cty.NumberIntVal(0)},
631			cty.NegativeInfinity,
632		},
633		{
634			[]cty.Value{cty.PositiveInfinity, cty.NumberIntVal(0)},
635			cty.NumberIntVal(0),
636		},
637		{
638			[]cty.Value{cty.NegativeInfinity},
639			cty.NegativeInfinity,
640		},
641		{
642			[]cty.Value{cty.PositiveInfinity, cty.UnknownVal(cty.Number)},
643			cty.UnknownVal(cty.Number),
644		},
645		{
646			[]cty.Value{cty.PositiveInfinity, cty.DynamicVal},
647			cty.UnknownVal(cty.Number),
648		},
649		{
650			[]cty.Value{cty.Zero.Mark(1), cty.NumberIntVal(1)},
651			cty.Zero.Mark(1),
652		},
653	}
654
655	for _, test := range tests {
656		t.Run(fmt.Sprintf("%#v", test.Inputs), func(t *testing.T) {
657			got, err := Min(test.Inputs...)
658
659			if err != nil {
660				t.Fatalf("unexpected error: %s", err)
661			}
662
663			if !got.RawEquals(test.Want) {
664				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
665			}
666		})
667	}
668}
669
670func TestMax(t *testing.T) {
671	tests := []struct {
672		Inputs []cty.Value
673		Want   cty.Value
674	}{
675		{
676			[]cty.Value{cty.NumberIntVal(0)},
677			cty.NumberIntVal(0),
678		},
679		{
680			[]cty.Value{cty.NumberIntVal(-12)},
681			cty.NumberIntVal(-12),
682		},
683		{
684			[]cty.Value{cty.NumberIntVal(12)},
685			cty.NumberIntVal(12),
686		},
687		{
688			[]cty.Value{cty.NumberIntVal(-12), cty.NumberIntVal(0), cty.NumberIntVal(2)},
689			cty.NumberIntVal(2),
690		},
691		{
692			[]cty.Value{cty.NegativeInfinity, cty.NumberIntVal(0)},
693			cty.NumberIntVal(0),
694		},
695		{
696			[]cty.Value{cty.PositiveInfinity, cty.NumberIntVal(0)},
697			cty.PositiveInfinity,
698		},
699		{
700			[]cty.Value{cty.NegativeInfinity},
701			cty.NegativeInfinity,
702		},
703		{
704			[]cty.Value{cty.PositiveInfinity, cty.UnknownVal(cty.Number)},
705			cty.UnknownVal(cty.Number),
706		},
707		{
708			[]cty.Value{cty.PositiveInfinity, cty.DynamicVal},
709			cty.UnknownVal(cty.Number),
710		},
711	}
712
713	for _, test := range tests {
714		t.Run(fmt.Sprintf("%#v", test.Inputs), func(t *testing.T) {
715			got, err := Max(test.Inputs...)
716
717			if err != nil {
718				t.Fatalf("unexpected error: %s", err)
719			}
720
721			if !got.RawEquals(test.Want) {
722				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
723			}
724		})
725	}
726}
727
728func TestInt(t *testing.T) {
729	tests := []struct {
730		Input cty.Value
731		Want  cty.Value
732	}{
733		{
734			cty.NumberIntVal(0),
735			cty.NumberIntVal(0),
736		},
737		{
738			cty.NumberIntVal(1),
739			cty.NumberIntVal(1),
740		},
741		{
742			cty.NumberIntVal(-1),
743			cty.NumberIntVal(-1),
744		},
745		{
746			cty.NumberFloatVal(1.3),
747			cty.NumberIntVal(1),
748		},
749		{
750			cty.NumberFloatVal(-1.7),
751			cty.NumberIntVal(-1),
752		},
753		{
754			cty.NumberFloatVal(-1.3),
755			cty.NumberIntVal(-1),
756		},
757		{
758			cty.NumberFloatVal(-1.7),
759			cty.NumberIntVal(-1),
760		},
761		{
762			cty.NumberVal(mustParseFloat("999999999999999999999999999999999999999999999999999999999999.7")),
763			cty.NumberVal(mustParseFloat("999999999999999999999999999999999999999999999999999999999999")),
764		},
765		{
766			cty.NumberVal(mustParseFloat("-999999999999999999999999999999999999999999999999999999999999.7")),
767			cty.NumberVal(mustParseFloat("-999999999999999999999999999999999999999999999999999999999999")),
768		},
769	}
770
771	for _, test := range tests {
772		t.Run(test.Input.GoString(), func(t *testing.T) {
773			got, err := Int(test.Input)
774
775			if err != nil {
776				t.Fatalf("unexpected error: %s", err)
777			}
778
779			if !got.RawEquals(test.Want) {
780				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
781			}
782		})
783	}
784}
785
786func mustParseFloat(s string) *big.Float {
787	ret, _, err := big.ParseFloat(s, 10, 0, big.AwayFromZero)
788	if err != nil {
789		panic(err)
790	}
791	return ret
792}
793
794func TestCeil(t *testing.T) {
795	tests := []struct {
796		Num  cty.Value
797		Want cty.Value
798		Err  bool
799	}{
800		{
801			cty.NumberFloatVal(-1.8),
802			cty.NumberFloatVal(-1),
803			false,
804		},
805		{
806			cty.NumberFloatVal(1.2),
807			cty.NumberFloatVal(2),
808			false,
809		},
810		{
811			cty.NumberFloatVal(math.Inf(1)),
812			cty.NumberFloatVal(math.Inf(1)),
813			false,
814		},
815		{
816			cty.NumberFloatVal(math.Inf(-1)),
817			cty.NumberFloatVal(math.Inf(-1)),
818			false,
819		},
820	}
821
822	for _, test := range tests {
823		t.Run(fmt.Sprintf("ceil(%#v)", test.Num), func(t *testing.T) {
824			got, err := Ceil(test.Num)
825
826			if test.Err {
827				if err == nil {
828					t.Fatal("succeeded; want error")
829				}
830				return
831			} else if err != nil {
832				t.Fatalf("unexpected error: %s", err)
833			}
834
835			if !got.RawEquals(test.Want) {
836				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
837			}
838		})
839	}
840}
841
842func TestFloor(t *testing.T) {
843	tests := []struct {
844		Num  cty.Value
845		Want cty.Value
846		Err  bool
847	}{
848		{
849			cty.NumberFloatVal(-1.8),
850			cty.NumberFloatVal(-2),
851			false,
852		},
853		{
854			cty.NumberFloatVal(1.2),
855			cty.NumberFloatVal(1),
856			false,
857		},
858		{
859			cty.NumberFloatVal(math.Inf(1)),
860			cty.NumberFloatVal(math.Inf(1)),
861			false,
862		},
863		{
864			cty.NumberFloatVal(math.Inf(-1)),
865			cty.NumberFloatVal(math.Inf(-1)),
866			false,
867		},
868	}
869
870	for _, test := range tests {
871		t.Run(fmt.Sprintf("floor(%#v)", test.Num), func(t *testing.T) {
872			got, err := Floor(test.Num)
873
874			if test.Err {
875				if err == nil {
876					t.Fatal("succeeded; want error")
877				}
878				return
879			} else if err != nil {
880				t.Fatalf("unexpected error: %s", err)
881			}
882
883			if !got.RawEquals(test.Want) {
884				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
885			}
886		})
887	}
888}
889
890func TestLog(t *testing.T) {
891	tests := []struct {
892		Num  cty.Value
893		Base cty.Value
894		Want cty.Value
895		Err  bool
896	}{
897		{
898			cty.NumberFloatVal(1),
899			cty.NumberFloatVal(10),
900			cty.NumberFloatVal(0),
901			false,
902		},
903		{
904			cty.NumberFloatVal(10),
905			cty.NumberFloatVal(10),
906			cty.NumberFloatVal(1),
907			false,
908		},
909
910		{
911			cty.NumberFloatVal(0),
912			cty.NumberFloatVal(10),
913			cty.NegativeInfinity,
914			false,
915		},
916		{
917			cty.NumberFloatVal(10),
918			cty.NumberFloatVal(0),
919			cty.NumberFloatVal(-0),
920			false,
921		},
922	}
923
924	for _, test := range tests {
925		t.Run(fmt.Sprintf("log(%#v, %#v)", test.Num, test.Base), func(t *testing.T) {
926			got, err := Log(test.Num, test.Base)
927
928			if test.Err {
929				if err == nil {
930					t.Fatal("succeeded; want error")
931				}
932				return
933			} else if err != nil {
934				t.Fatalf("unexpected error: %s", err)
935			}
936
937			if !got.RawEquals(test.Want) {
938				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
939			}
940		})
941	}
942}
943
944func TestPow(t *testing.T) {
945	tests := []struct {
946		Num   cty.Value
947		Power cty.Value
948		Want  cty.Value
949		Err   bool
950	}{
951		{
952			cty.NumberFloatVal(1),
953			cty.NumberFloatVal(0),
954			cty.NumberFloatVal(1),
955			false,
956		},
957		{
958			cty.NumberFloatVal(1),
959			cty.NumberFloatVal(1),
960			cty.NumberFloatVal(1),
961			false,
962		},
963
964		{
965			cty.NumberFloatVal(2),
966			cty.NumberFloatVal(0),
967			cty.NumberFloatVal(1),
968			false,
969		},
970		{
971			cty.NumberFloatVal(2),
972			cty.NumberFloatVal(1),
973			cty.NumberFloatVal(2),
974			false,
975		},
976		{
977			cty.NumberFloatVal(3),
978			cty.NumberFloatVal(2),
979			cty.NumberFloatVal(9),
980			false,
981		},
982		{
983			cty.NumberFloatVal(-3),
984			cty.NumberFloatVal(2),
985			cty.NumberFloatVal(9),
986			false,
987		},
988		{
989			cty.NumberFloatVal(2),
990			cty.NumberFloatVal(-2),
991			cty.NumberFloatVal(0.25),
992			false,
993		},
994		{
995			cty.NumberFloatVal(0),
996			cty.NumberFloatVal(2),
997			cty.NumberFloatVal(0),
998			false,
999		},
1000	}
1001
1002	for _, test := range tests {
1003		t.Run(fmt.Sprintf("pow(%#v, %#v)", test.Num, test.Power), func(t *testing.T) {
1004			got, err := Pow(test.Num, test.Power)
1005
1006			if test.Err {
1007				if err == nil {
1008					t.Fatal("succeeded; want error")
1009				}
1010				return
1011			} else if err != nil {
1012				t.Fatalf("unexpected error: %s", err)
1013			}
1014
1015			if !got.RawEquals(test.Want) {
1016				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
1017			}
1018		})
1019	}
1020}
1021
1022func TestSignum(t *testing.T) {
1023	tests := []struct {
1024		Num  cty.Value
1025		Want cty.Value
1026		Err  bool
1027	}{
1028		{
1029			cty.NumberFloatVal(0),
1030			cty.NumberFloatVal(0),
1031			false,
1032		},
1033		{
1034			cty.NumberFloatVal(12),
1035			cty.NumberFloatVal(1),
1036			false,
1037		},
1038		{
1039			cty.NumberFloatVal(-29),
1040			cty.NumberFloatVal(-1),
1041			false,
1042		},
1043	}
1044
1045	for _, test := range tests {
1046		t.Run(fmt.Sprintf("signum(%#v)", test.Num), func(t *testing.T) {
1047			got, err := Signum(test.Num)
1048
1049			if test.Err {
1050				if err == nil {
1051					t.Fatal("succeeded; want error")
1052				}
1053				return
1054			} else if err != nil {
1055				t.Fatalf("unexpected error: %s", err)
1056			}
1057
1058			if !got.RawEquals(test.Want) {
1059				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
1060			}
1061		})
1062	}
1063}
1064
1065func TestParseInt(t *testing.T) {
1066	tests := []struct {
1067		Num  cty.Value
1068		Base cty.Value
1069		Want cty.Value
1070		Err  bool
1071	}{
1072		{
1073			cty.StringVal("128"),
1074			cty.NumberIntVal(10),
1075			cty.NumberIntVal(128),
1076			false,
1077		},
1078		{
1079			cty.StringVal("-128"),
1080			cty.NumberIntVal(10),
1081			cty.NumberIntVal(-128),
1082			false,
1083		},
1084		{
1085			cty.StringVal("00128"),
1086			cty.NumberIntVal(10),
1087			cty.NumberIntVal(128),
1088			false,
1089		},
1090		{
1091			cty.StringVal("-00128"),
1092			cty.NumberIntVal(10),
1093			cty.NumberIntVal(-128),
1094			false,
1095		},
1096		{
1097			cty.StringVal("FF00"),
1098			cty.NumberIntVal(16),
1099			cty.NumberIntVal(65280),
1100			false,
1101		},
1102		{
1103			cty.StringVal("ff00"),
1104			cty.NumberIntVal(16),
1105			cty.NumberIntVal(65280),
1106			false,
1107		},
1108		{
1109			cty.StringVal("-FF00"),
1110			cty.NumberIntVal(16),
1111			cty.NumberIntVal(-65280),
1112			false,
1113		},
1114		{
1115			cty.StringVal("00FF00"),
1116			cty.NumberIntVal(16),
1117			cty.NumberIntVal(65280),
1118			false,
1119		},
1120		{
1121			cty.StringVal("-00FF00"),
1122			cty.NumberIntVal(16),
1123			cty.NumberIntVal(-65280),
1124			false,
1125		},
1126		{
1127			cty.StringVal("1011111011101111"),
1128			cty.NumberIntVal(2),
1129			cty.NumberIntVal(48879),
1130			false,
1131		},
1132		{
1133			cty.StringVal("aA"),
1134			cty.NumberIntVal(62),
1135			cty.NumberIntVal(656),
1136			false,
1137		},
1138		{
1139			cty.StringVal("Aa"),
1140			cty.NumberIntVal(62),
1141			cty.NumberIntVal(2242),
1142			false,
1143		},
1144		{
1145			cty.StringVal("999999999999999999999999999999999999999999999999999999999999"),
1146			cty.NumberIntVal(10),
1147			cty.MustParseNumberVal("999999999999999999999999999999999999999999999999999999999999"),
1148			false,
1149		},
1150		{
1151			cty.StringVal("FF"),
1152			cty.NumberIntVal(10),
1153			cty.UnknownVal(cty.Number),
1154			true,
1155		},
1156		{
1157			cty.StringVal("00FF"),
1158			cty.NumberIntVal(10),
1159			cty.UnknownVal(cty.Number),
1160			true,
1161		},
1162		{
1163			cty.StringVal("-00FF"),
1164			cty.NumberIntVal(10),
1165			cty.UnknownVal(cty.Number),
1166			true,
1167		},
1168		{
1169			cty.NumberIntVal(2),
1170			cty.NumberIntVal(10),
1171			cty.UnknownVal(cty.Number),
1172			true,
1173		},
1174		{
1175			cty.StringVal("1"),
1176			cty.NumberIntVal(63),
1177			cty.UnknownVal(cty.Number),
1178			true,
1179		},
1180		{
1181			cty.StringVal("1"),
1182			cty.NumberIntVal(-1),
1183			cty.UnknownVal(cty.Number),
1184			true,
1185		},
1186		{
1187			cty.StringVal("1"),
1188			cty.NumberIntVal(1),
1189			cty.UnknownVal(cty.Number),
1190			true,
1191		},
1192		{
1193			cty.StringVal("1"),
1194			cty.NumberIntVal(0),
1195			cty.UnknownVal(cty.Number),
1196			true,
1197		},
1198		{
1199			cty.StringVal("1.2"),
1200			cty.NumberIntVal(10),
1201			cty.UnknownVal(cty.Number),
1202			true,
1203		},
1204	}
1205
1206	for _, test := range tests {
1207		t.Run(fmt.Sprintf("parseint(%#v, %#v)", test.Num, test.Base), func(t *testing.T) {
1208			got, err := ParseInt(test.Num, test.Base)
1209
1210			if test.Err {
1211				if err == nil {
1212					t.Fatal("succeeded; want error")
1213				}
1214				return
1215			} else if err != nil {
1216				t.Fatalf("unexpected error: %s", err)
1217			}
1218
1219			if !got.RawEquals(test.Want) {
1220				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
1221			}
1222		})
1223	}
1224}
1225