github.com/hashicorp/packer@v1.14.3/hcl2template/function/sum_test.go (about)

     1  package function
     2  
     3  import (
     4  	"fmt"
     5  	"math"
     6  	"testing"
     7  
     8  	"github.com/zclconf/go-cty/cty"
     9  )
    10  
    11  func TestSum(t *testing.T) {
    12  	tests := []struct {
    13  		List cty.Value
    14  		Want cty.Value
    15  		Err  string
    16  	}{
    17  		{
    18  			cty.ListVal([]cty.Value{
    19  				cty.NumberIntVal(1),
    20  				cty.NumberIntVal(2),
    21  				cty.NumberIntVal(3),
    22  			}),
    23  			cty.NumberIntVal(6),
    24  			"",
    25  		},
    26  		{
    27  			cty.ListVal([]cty.Value{
    28  				cty.NumberIntVal(1476),
    29  				cty.NumberIntVal(2093),
    30  				cty.NumberIntVal(2092495),
    31  				cty.NumberIntVal(64589234),
    32  				cty.NumberIntVal(234),
    33  			}),
    34  			cty.NumberIntVal(66685532),
    35  			"",
    36  		},
    37  		{
    38  			cty.ListVal([]cty.Value{
    39  				cty.StringVal("a"),
    40  				cty.StringVal("b"),
    41  				cty.StringVal("c"),
    42  			}),
    43  			cty.UnknownVal(cty.String),
    44  			"argument must be list, set, or tuple of number values",
    45  		},
    46  		{
    47  			cty.ListVal([]cty.Value{
    48  				cty.NumberIntVal(10),
    49  				cty.NumberIntVal(-19),
    50  				cty.NumberIntVal(5),
    51  			}),
    52  			cty.NumberIntVal(-4),
    53  			"",
    54  		},
    55  		{
    56  			cty.ListVal([]cty.Value{
    57  				cty.NumberFloatVal(10.2),
    58  				cty.NumberFloatVal(19.4),
    59  				cty.NumberFloatVal(5.7),
    60  			}),
    61  			cty.NumberFloatVal(35.3),
    62  			"",
    63  		},
    64  		{
    65  			cty.ListVal([]cty.Value{
    66  				cty.NumberFloatVal(-10.2),
    67  				cty.NumberFloatVal(-19.4),
    68  				cty.NumberFloatVal(-5.7),
    69  			}),
    70  			cty.NumberFloatVal(-35.3),
    71  			"",
    72  		},
    73  		{
    74  			cty.ListVal([]cty.Value{cty.NullVal(cty.Number)}),
    75  			cty.NilVal,
    76  			"argument must be list, set, or tuple of number values",
    77  		},
    78  		{
    79  			cty.ListVal([]cty.Value{
    80  				cty.NumberIntVal(5),
    81  				cty.NullVal(cty.Number),
    82  			}),
    83  			cty.NilVal,
    84  			"argument must be list, set, or tuple of number values",
    85  		},
    86  		{
    87  			cty.SetVal([]cty.Value{
    88  				cty.StringVal("a"),
    89  				cty.StringVal("b"),
    90  				cty.StringVal("c"),
    91  			}),
    92  			cty.UnknownVal(cty.String).RefineNotNull(),
    93  			"argument must be list, set, or tuple of number values",
    94  		},
    95  		{
    96  			cty.SetVal([]cty.Value{
    97  				cty.NumberIntVal(10),
    98  				cty.NumberIntVal(-19),
    99  				cty.NumberIntVal(5),
   100  			}),
   101  			cty.NumberIntVal(-4),
   102  			"",
   103  		},
   104  		{
   105  			cty.SetVal([]cty.Value{
   106  				cty.NumberIntVal(10),
   107  				cty.NumberIntVal(25),
   108  				cty.NumberIntVal(30),
   109  			}),
   110  			cty.NumberIntVal(65),
   111  			"",
   112  		},
   113  		{
   114  			cty.SetVal([]cty.Value{
   115  				cty.NumberFloatVal(2340.8),
   116  				cty.NumberFloatVal(10.2),
   117  				cty.NumberFloatVal(3),
   118  			}),
   119  			cty.NumberFloatVal(2354),
   120  			"",
   121  		},
   122  		{
   123  			cty.SetVal([]cty.Value{
   124  				cty.NumberFloatVal(2),
   125  			}),
   126  			cty.NumberFloatVal(2),
   127  			"",
   128  		},
   129  		{
   130  			cty.SetVal([]cty.Value{
   131  				cty.NumberFloatVal(-2),
   132  				cty.NumberFloatVal(-50),
   133  				cty.NumberFloatVal(-20),
   134  				cty.NumberFloatVal(-123),
   135  				cty.NumberFloatVal(-4),
   136  			}),
   137  			cty.NumberFloatVal(-199),
   138  			"",
   139  		},
   140  		{
   141  			cty.TupleVal([]cty.Value{
   142  				cty.NumberIntVal(12),
   143  				cty.StringVal("a"),
   144  				cty.NumberIntVal(38),
   145  			}),
   146  			cty.UnknownVal(cty.String).RefineNotNull(),
   147  			"argument must be list, set, or tuple of number values",
   148  		},
   149  		{
   150  			cty.NumberIntVal(12),
   151  			cty.NilVal,
   152  			"cannot sum noniterable",
   153  		},
   154  		{
   155  			cty.ListValEmpty(cty.Number),
   156  			cty.NilVal,
   157  			"cannot sum an empty list",
   158  		},
   159  		{
   160  			cty.MapVal(map[string]cty.Value{"hello": cty.True}),
   161  			cty.NilVal,
   162  			"argument must be list, set, or tuple. Received map of bool",
   163  		},
   164  		{
   165  			cty.UnknownVal(cty.Number),
   166  			cty.UnknownVal(cty.Number).RefineNotNull(),
   167  			"",
   168  		},
   169  		{
   170  			cty.UnknownVal(cty.List(cty.Number)),
   171  			cty.UnknownVal(cty.Number).RefineNotNull(),
   172  			"",
   173  		},
   174  		{ // known list containing unknown values
   175  			cty.ListVal([]cty.Value{cty.UnknownVal(cty.Number)}),
   176  			cty.UnknownVal(cty.Number).RefineNotNull(),
   177  			"",
   178  		},
   179  		{ // numbers too large to represent as float64
   180  			cty.ListVal([]cty.Value{
   181  				cty.MustParseNumberVal("1e+500"),
   182  				cty.MustParseNumberVal("1e+500"),
   183  			}),
   184  			cty.MustParseNumberVal("2e+500"),
   185  			"",
   186  		},
   187  		{ // edge case we have a special error handler for
   188  			cty.ListVal([]cty.Value{
   189  				cty.NumberFloatVal(math.Inf(1)),
   190  				cty.NumberFloatVal(math.Inf(-1)),
   191  			}),
   192  			cty.NilVal,
   193  			"can't compute sum of opposing infinities",
   194  		},
   195  		{
   196  			cty.ListVal([]cty.Value{
   197  				cty.StringVal("1"),
   198  				cty.StringVal("2"),
   199  				cty.StringVal("3"),
   200  			}),
   201  			cty.NumberIntVal(6),
   202  			"",
   203  		},
   204  	}
   205  
   206  	for _, test := range tests {
   207  		t.Run(fmt.Sprintf("sum(%#v)", test.List), func(t *testing.T) {
   208  			got, err := Sum(test.List)
   209  
   210  			if test.Err != "" {
   211  				if err == nil {
   212  					t.Fatal("succeeded; want error")
   213  				} else if got, want := err.Error(), test.Err; got != want {
   214  					t.Fatalf("wrong error\n got: %s\nwant: %s", got, want)
   215  				}
   216  				return
   217  			} else if err != nil {
   218  				t.Fatalf("unexpected error: %s", err)
   219  			}
   220  
   221  			if !got.RawEquals(test.Want) {
   222  				t.Errorf("wrong result\ngot:  %#v\nwant: %#v", got, test.Want)
   223  			}
   224  		})
   225  	}
   226  }