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  }