github.com/hairyhenderson/gomplate/v4@v4.0.0-pre-2.0.20240520121557-362f058f0c93/conv/conv_test.go (about)

     1  package conv
     2  
     3  import (
     4  	"fmt"
     5  	"math"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  func TestBool(t *testing.T) {
    13  	testdata := []struct {
    14  		in  string
    15  		out bool
    16  	}{
    17  		{"", false},
    18  		{"asdf", false},
    19  		{"1234", false},
    20  		{"False", false},
    21  		{"0", false},
    22  		{"false", false},
    23  		{"F", false},
    24  		{"f", false},
    25  		{"true", true},
    26  		{"True", true},
    27  		{"t", true},
    28  		{"T", true},
    29  		{"1", true},
    30  	}
    31  	for _, d := range testdata {
    32  		assert.Equal(t, d.out, Bool(d.in))
    33  	}
    34  }
    35  
    36  func TestSlice(t *testing.T) {
    37  	expected := []string{"foo", "bar"}
    38  	actual := Slice("foo", "bar")
    39  	assert.Equal(t, expected[0], actual[0])
    40  	assert.Equal(t, expected[1], actual[1])
    41  }
    42  
    43  func TestJoin(t *testing.T) {
    44  	testdata := []struct {
    45  		in  interface{}
    46  		sep string
    47  		out string
    48  	}{
    49  		{[]interface{}{"foo", "bar"}, ",", "foo,bar"},
    50  		{[]interface{}{"foo", "bar"}, ",\n", "foo,\nbar"},
    51  		// Join handles all kinds of scalar types too...
    52  		{[]interface{}{42, uint64(18446744073709551615)}, "-", "42-18446744073709551615"},
    53  		{[]int{42, 100}, ",", "42,100"},
    54  		{[]int64{42, 100}, ",", "42,100"},
    55  		{[]uint64{42, 100}, ",", "42,100"},
    56  		{[]bool{true, false}, ",", "true,false"},
    57  		{[]float64{1, 2}, ",", "1,2"},
    58  		{[]interface{}{1, "", true, 3.14, "foo", nil}, ",", "1,,true,3.14,foo,nil"},
    59  		// and best-effort with weird types
    60  		{[]interface{}{[]string{"foo"}, "bar"}, ",", "[foo],bar"},
    61  	}
    62  	for _, d := range testdata {
    63  		out, err := Join(d.in, d.sep)
    64  		require.NoError(t, err)
    65  		assert.Equal(t, d.out, out)
    66  	}
    67  }
    68  
    69  func TestHas(t *testing.T) {
    70  	in := map[string]interface{}{
    71  		"foo": "bar",
    72  		"baz": map[string]interface{}{
    73  			"qux": "quux",
    74  		},
    75  	}
    76  
    77  	testdata := []struct {
    78  		in  interface{}
    79  		key interface{}
    80  		out bool
    81  	}{
    82  		{in, "foo", true},
    83  		{in, "bar", false},
    84  		{in["baz"], "qux", true},
    85  		{[]string{"foo", "bar", "baz"}, "bar", true},
    86  		{[]interface{}{"foo", "bar", "baz"}, "bar", true},
    87  		{[]interface{}{"foo", "bar", "baz"}, 42, false},
    88  		{[]int{1, 2, 42}, 42, true},
    89  	}
    90  
    91  	for _, d := range testdata {
    92  		assert.Equal(t, d.out, Has(d.in, d.key))
    93  	}
    94  }
    95  
    96  func TestMustParseInt(t *testing.T) {
    97  	for _, i := range []string{"0", "-0", "foo", "", "*&^%"} {
    98  		assert.Equal(t, 0, int(MustParseInt(i, 10, 64)))
    99  	}
   100  	assert.Equal(t, 1, int(MustParseInt("1", 10, 64)))
   101  	assert.Equal(t, -1, int(MustParseInt("-1", 10, 64)))
   102  }
   103  
   104  func TestMustAtoi(t *testing.T) {
   105  	for _, i := range []string{"0", "-0", "foo", "", "*&^%"} {
   106  		assert.Equal(t, 0, MustAtoi(i))
   107  	}
   108  	assert.Equal(t, 1, MustAtoi("1"))
   109  	assert.Equal(t, -1, MustAtoi("-1"))
   110  }
   111  
   112  func TestMustParseUint(t *testing.T) {
   113  	for _, i := range []string{"0", "-0", "-1", "foo", "", "*&^%"} {
   114  		assert.Equal(t, uint64(0), MustParseUint(i, 10, 64))
   115  	}
   116  	assert.Equal(t, uint64(1), MustParseUint("1", 10, 64))
   117  }
   118  
   119  func TestMustParseFloat(t *testing.T) {
   120  	for _, i := range []string{"0", "-0", "foo", "", "*&^%"} {
   121  		assert.Zero(t, MustParseFloat(i, 64))
   122  	}
   123  	assert.InEpsilon(t, 1.0, MustParseFloat("1", 64), 1e-12)
   124  	assert.InEpsilon(t, -1.0, MustParseFloat("-1", 64), 1e-12)
   125  }
   126  
   127  func TestToInt64(t *testing.T) {
   128  	assert.Equal(t, int64(1), ToInt64(1))
   129  	assert.Equal(t, int64(1), ToInt64(int32(1)))
   130  	assert.Equal(t, int64(1), ToInt64(int64(1)))
   131  	assert.Equal(t, int64(1), ToInt64(float32(1)))
   132  	assert.Equal(t, int64(1), ToInt64(float64(1)))
   133  	assert.Equal(t, int64(42), ToInt64(42))
   134  	assert.Equal(t, int64(42), ToInt64("42.0"))
   135  	assert.Equal(t, int64(3), ToInt64("3.5"))
   136  	assert.Equal(t, int64(-1), ToInt64(uint64(math.MaxUint64)))
   137  	assert.Equal(t, int64(0xFF), ToInt64(uint8(math.MaxUint8)))
   138  
   139  	assert.Equal(t, int64(0), ToInt64(nil))
   140  	assert.Equal(t, int64(0), ToInt64(false))
   141  	assert.Equal(t, int64(1), ToInt64(true))
   142  	assert.Equal(t, int64(0), ToInt64(""))
   143  	assert.Equal(t, int64(0), ToInt64("foo"))
   144  	assert.Equal(t, int64(0xFFFF), ToInt64("0xFFFF"))
   145  	assert.Equal(t, int64(8), ToInt64("010"))
   146  	assert.Equal(t, int64(4096), ToInt64("4,096"))
   147  	assert.Equal(t, int64(-4096), ToInt64("-4,096.00"))
   148  }
   149  
   150  func TestToInt(t *testing.T) {
   151  	assert.Equal(t, 1, ToInt(1))
   152  	assert.Equal(t, 1, ToInt(int32(1)))
   153  	assert.Equal(t, 1, ToInt(int64(1)))
   154  	assert.Equal(t, 1, ToInt(float32(1)))
   155  	assert.Equal(t, 1, ToInt(float64(1)))
   156  	assert.Equal(t, 42, ToInt(42))
   157  	assert.Equal(t, -1, ToInt(uint64(math.MaxUint64)))
   158  	assert.Equal(t, 0xFF, ToInt(uint8(math.MaxUint8)))
   159  
   160  	assert.Equal(t, 0, ToInt(nil))
   161  	assert.Equal(t, 0, ToInt(false))
   162  	assert.Equal(t, 1, ToInt(true))
   163  	assert.Equal(t, 0, ToInt(""))
   164  	assert.Equal(t, 0, ToInt("foo"))
   165  	assert.Equal(t, 0xFFFF, ToInt("0xFFFF"))
   166  	assert.Equal(t, 8, ToInt("010"))
   167  	assert.Equal(t, 4096, ToInt("4,096"))
   168  	assert.Equal(t, -4096, ToInt("-4,096.00"))
   169  }
   170  
   171  func TestToInt64s(t *testing.T) {
   172  	assert.Equal(t, []int64{}, ToInt64s())
   173  
   174  	assert.Equal(t, []int64{0}, ToInt64s(""))
   175  	assert.Equal(t, []int64{0}, ToInt64s("0"))
   176  	assert.Equal(t, []int64{42, 15}, ToInt64s("42", "15"))
   177  	assert.Equal(t, []int64{0, 0, 0, 1, 1, 2, 3, 5, 8, 13, -1000},
   178  		ToInt64s(nil, false, "", true, 1, 2.0, uint8(3), int64(5), float32(8), "13", "-1,000"))
   179  }
   180  
   181  func TestToInts(t *testing.T) {
   182  	assert.Equal(t, []int{}, ToInts())
   183  
   184  	assert.Equal(t, []int{0}, ToInts(""))
   185  	assert.Equal(t, []int{0}, ToInts("0"))
   186  	assert.Equal(t, []int{42, 15}, ToInts("42", "15"))
   187  	assert.Equal(t, []int{0, 0, 0, 1, 1, 2, 3, 5, 8, 13, 42000},
   188  		ToInts(nil, false, "", true, 1, 2.0, uint8(3), int64(5), float32(8), "13", "42,000"))
   189  }
   190  
   191  func TestToFloat64(t *testing.T) {
   192  	z := []interface{}{0, 0.0, nil, false, float32(0), "", "0", "foo", int64(0), uint(0), "0x0", "00", "0,000"}
   193  	for _, n := range z {
   194  		assert.Zero(t, ToFloat64(n))
   195  	}
   196  	assert.InEpsilon(t, 1.0, ToFloat64(true), 1e-12)
   197  	z = []interface{}{42, 42.0, float32(42), "42", "42.0", uint8(42), "0x2A", "052"}
   198  	for _, n := range z {
   199  		assert.InEpsilon(t, 42.0, ToFloat64(n), 1e-12)
   200  	}
   201  	z = []interface{}{1000.34, "1000.34", "1,000.34"}
   202  	for _, n := range z {
   203  		assert.InEpsilon(t, 1000.34, ToFloat64(n), 1e-12)
   204  	}
   205  }
   206  
   207  func TestToFloat64s(t *testing.T) {
   208  	assert.Equal(t, []float64{}, ToFloat64s())
   209  	assert.Equal(t, []float64{0, 1.0, 2.0, math.Pi, 4.0}, ToFloat64s(nil, true, "2", math.Pi, uint8(4)))
   210  }
   211  
   212  type foo struct {
   213  	val string
   214  }
   215  
   216  func (f foo) String() string {
   217  	return f.val
   218  }
   219  
   220  func TestToString(t *testing.T) {
   221  	var p *string
   222  	f := "foo"
   223  	p = &f
   224  
   225  	var n *string
   226  
   227  	testdata := []struct {
   228  		in  interface{}
   229  		out string
   230  	}{
   231  		{nil, "nil"},
   232  		{"", ""},
   233  		{"foo", "foo"},
   234  		{true, "true"},
   235  		{42, "42"},
   236  		{3.14, "3.14"},
   237  		{-127, "-127"},
   238  		{0xFF, "255"},
   239  		{uint8(42), "42"},
   240  		{math.Pi, "3.141592653589793"},
   241  		{math.NaN(), "NaN"},
   242  		{math.Inf(1), "+Inf"},
   243  		{math.Inf(-1), "-Inf"},
   244  		{foo{"bar"}, "bar"},
   245  		{p, "foo"},
   246  		{fmt.Errorf("hi"), "hi"},
   247  		{n, "<nil>"},
   248  		{[]byte("hello world"), "hello world"},
   249  	}
   250  
   251  	for _, d := range testdata {
   252  		d := d
   253  		t.Run(fmt.Sprintf("%T/%#v == %s", d.in, d.in, d.out), func(t *testing.T) {
   254  			out := ToString(d.in)
   255  			assert.Equal(t, d.out, out)
   256  		})
   257  	}
   258  }
   259  
   260  func TestToBool(t *testing.T) {
   261  	trueData := []interface{}{
   262  		true,
   263  		1,
   264  		int8(1),
   265  		uint8(1),
   266  		int32(1),
   267  		uint32(1),
   268  		int64(1),
   269  		uint64(1),
   270  		float32(1),
   271  		float64(1),
   272  		"1",
   273  		"0x1",
   274  		"1.0",
   275  		"01",
   276  		"true",
   277  		"True",
   278  		"T",
   279  		"t",
   280  		"TrUe",
   281  		"yes",
   282  		"YES",
   283  	}
   284  	for _, d := range trueData {
   285  		out := ToBool(d)
   286  		assert.True(t, out)
   287  	}
   288  
   289  	falseData := []interface{}{
   290  		nil,
   291  		false,
   292  		42,
   293  		uint64(math.MaxUint64),
   294  		uint8(math.MaxUint8),
   295  		"",
   296  		"false",
   297  		"foo",
   298  		"0xFFFF",
   299  		"010",
   300  		"4,096",
   301  		"-4,096.00",
   302  	}
   303  	for _, d := range falseData {
   304  		out := ToBool(d)
   305  		assert.False(t, out)
   306  	}
   307  }
   308  
   309  func TestDict(t *testing.T) {
   310  	testdata := []struct {
   311  		expected map[string]interface{}
   312  		args     []interface{}
   313  	}{
   314  		{expected: map[string]interface{}{}},
   315  		{
   316  			args:     []interface{}{},
   317  			expected: map[string]interface{}{},
   318  		},
   319  		{
   320  			args:     []interface{}{"foo"},
   321  			expected: map[string]interface{}{"foo": ""},
   322  		},
   323  		{
   324  			args:     []interface{}{42},
   325  			expected: map[string]interface{}{"42": ""},
   326  		},
   327  		{
   328  			args:     []interface{}{"foo", nil},
   329  			expected: map[string]interface{}{"foo": nil},
   330  		},
   331  		{
   332  			args:     []interface{}{"foo", "bar"},
   333  			expected: map[string]interface{}{"foo": "bar"},
   334  		},
   335  		{
   336  			args: []interface{}{"foo", "bar", "baz", true},
   337  			expected: map[string]interface{}{
   338  				"foo": "bar",
   339  				"baz": true,
   340  			},
   341  		},
   342  	}
   343  
   344  	for _, d := range testdata {
   345  		actual, _ := Dict(d.args...)
   346  		assert.Equal(t, d.expected, actual)
   347  	}
   348  }