github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/utils/mapobject_test.go (about)

     1  /*
     2   * Copyright (c) 2020-present unTill Pro, Ltd.
     3   */
     4  
     5  package coreutils
     6  
     7  import (
     8  	"reflect"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  func TestMapObject(t *testing.T) {
    15  	require := require.New(t)
    16  
    17  	t.Run("basic", func(t *testing.T) {
    18  		mo := MapObject{
    19  			"int641":    int64(1),
    20  			"int642":    float64(2),
    21  			"float64":   float64(4),
    22  			"boolTrue":  true,
    23  			"boolFalse": false,
    24  			"string":    "str",
    25  			"obj": map[string]interface{}{
    26  				"int64": int64(5),
    27  			},
    28  			"objs": []interface{}{
    29  				map[string]interface{}{
    30  					"int64": int64(6),
    31  				},
    32  				map[string]interface{}{
    33  					"int64": int64(7),
    34  				},
    35  			},
    36  		}
    37  		cases := []struct {
    38  			expectedVal interface{}
    39  			f           func() (interface{}, bool, error)
    40  		}{
    41  			{int64(1), func() (interface{}, bool, error) { return mo.AsInt64("int641") }},
    42  			{int64(2), func() (interface{}, bool, error) { return mo.AsInt64("int642") }},
    43  			{float64(4), func() (interface{}, bool, error) { return mo.AsFloat64("float64") }},
    44  			{true, func() (interface{}, bool, error) { return mo.AsBoolean("boolTrue") }},
    45  			{false, func() (interface{}, bool, error) { return mo.AsBoolean("boolFalse") }},
    46  			{"str", func() (interface{}, bool, error) { return mo.AsString("string") }},
    47  			{"str", func() (interface{}, bool, error) {
    48  				val, err := mo.AsStringRequired("string")
    49  				return val, true, err
    50  			}},
    51  			{MapObject{
    52  				"int64": int64(5),
    53  			}, func() (interface{}, bool, error) { return mo.AsObject("obj") }},
    54  			{[]interface{}{
    55  				map[string]interface{}{
    56  					"int64": int64(6),
    57  				},
    58  				map[string]interface{}{
    59  					"int64": int64(7),
    60  				},
    61  			}, func() (interface{}, bool, error) { return mo.AsObjects("objs") }},
    62  		}
    63  
    64  		for _, c := range cases {
    65  			val, ok, err := c.f()
    66  			require.NoError(err)
    67  			require.True(ok)
    68  			require.Equal(c.expectedVal, val)
    69  		}
    70  	})
    71  
    72  	t.Run("empty", func(t *testing.T) {
    73  		mo := MapObject{
    74  			"fld": nil,
    75  		}
    76  		cases := []struct {
    77  			expected interface{}
    78  			f        func(string) (interface{}, bool, error)
    79  		}{
    80  			{false, func(name string) (interface{}, bool, error) { return mo.AsBoolean(name) }},
    81  			{int64(0), func(name string) (interface{}, bool, error) { return mo.AsInt64(name) }},
    82  			{float64(0), func(name string) (interface{}, bool, error) { return mo.AsFloat64(name) }},
    83  			{MapObject(nil), func(name string) (interface{}, bool, error) { return mo.AsObject(name) }},
    84  			{[]interface{}(nil), func(name string) (interface{}, bool, error) { return mo.AsObjects(name) }},
    85  			{"", func(name string) (interface{}, bool, error) { return mo.AsString(name) }},
    86  		}
    87  		for _, c := range cases {
    88  			val, ok, err := c.f("unknown")
    89  			require.NoError(err)
    90  			require.False(ok)
    91  			require.Equal(c.expected, val)
    92  			val, ok, err = c.f("fld")
    93  			require.NoError(err)
    94  			require.False(ok)
    95  			require.Equal(c.expected, val)
    96  		}
    97  	})
    98  
    99  	t.Run("wrong types", func(t *testing.T) {
   100  		mo := MapObject{
   101  			"fld": reflect.TypeOf(0),
   102  		}
   103  
   104  		cases := []struct {
   105  			expected interface{}
   106  			f        func() (interface{}, bool, error)
   107  		}{
   108  			{false, func() (interface{}, bool, error) { return mo.AsBoolean("fld") }},
   109  			{float64(0), func() (interface{}, bool, error) { return mo.AsFloat64("fld") }},
   110  			{int64(0), func() (interface{}, bool, error) { return mo.AsInt64("fld") }},
   111  			{MapObject(nil), func() (interface{}, bool, error) { return mo.AsObject("fld") }},
   112  			{[]interface{}(nil), func() (interface{}, bool, error) { return mo.AsObjects("fld") }},
   113  			{"", func() (interface{}, bool, error) { return mo.AsString("fld") }},
   114  			{"", func() (interface{}, bool, error) {
   115  				val, err := mo.AsStringRequired("fld")
   116  				return val, true, err
   117  			}},
   118  		}
   119  		for _, c := range cases {
   120  			val, ok, err := c.f()
   121  			require.ErrorIs(err, ErrFieldTypeMismatch)
   122  			require.True(ok)
   123  			require.Equal(c.expected, val)
   124  		}
   125  	})
   126  
   127  	t.Run("AsStringRequired", func(t *testing.T) {
   128  		mo := MapObject{
   129  			"str": nil,
   130  		}
   131  		val, err := mo.AsStringRequired("str")
   132  		require.Empty(val)
   133  		require.ErrorIs(err, ErrFieldsMissed)
   134  		val, err = mo.AsStringRequired("unknown")
   135  		require.Empty(val)
   136  		require.ErrorIs(err, ErrFieldsMissed)
   137  	})
   138  
   139  }