github.com/fraugster/parquet-go@v0.12.0/floor/interfaces/unmarshaller_test.go (about)

     1  package interfaces
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/require"
     7  )
     8  
     9  func TestObjectUnmarshalling(t *testing.T) {
    10  	obj := NewUnmarshallObject(map[string]interface{}{
    11  		"foo":  int64(23),
    12  		"bar":  int32(42),
    13  		"baz":  true,
    14  		"name": []byte("John Doe"),
    15  		"my_group": map[string]interface{}{
    16  			"foo1": float32(23.5),
    17  			"bar1": float64(9000.5),
    18  		},
    19  		"id_list": map[string]interface{}{
    20  			"list": []map[string]interface{}{
    21  				{
    22  					"element": int64(1),
    23  				},
    24  				{
    25  					"element": int64(2),
    26  				},
    27  				{
    28  					"element": int64(15),
    29  				},
    30  				{
    31  					"element": int64(28),
    32  				},
    33  				{
    34  					"element": int64(32),
    35  				},
    36  			},
    37  		},
    38  		"data_map": map[string]interface{}{
    39  			"key_value": []map[string]interface{}{
    40  				{
    41  					"key":   []byte("data0"),
    42  					"value": int32(0),
    43  				},
    44  				{
    45  					"key":   []byte("data1"),
    46  					"value": int32(1),
    47  				},
    48  				{
    49  					"key":   []byte("data2"),
    50  					"value": int32(2),
    51  				},
    52  				{
    53  					"key":   []byte("data3"),
    54  					"value": int32(3),
    55  				},
    56  				{
    57  					"key":   []byte("data4"),
    58  					"value": int32(4),
    59  				},
    60  			},
    61  		},
    62  		"nested_data_map": map[string]interface{}{
    63  			"key_value": []map[string]interface{}{
    64  				{
    65  					"key": int64(23),
    66  					"value": map[string]interface{}{
    67  						"foo": int32(42),
    68  					},
    69  				},
    70  			},
    71  		},
    72  	})
    73  
    74  	i64, err := obj.GetField("foo").Int64()
    75  	require.NoError(t, err, "getting foo as int64 failed")
    76  	require.Equal(t, int64(23), i64)
    77  
    78  	elem := obj.GetField("bar")
    79  	i32, err := elem.Int32()
    80  	require.NoError(t, err, "getting bar as int32 failed")
    81  	require.Equal(t, int32(42), i32)
    82  
    83  	elem = obj.GetField("baz")
    84  	b, err := elem.Bool()
    85  	require.NoError(t, err, "getting baz as bool failed")
    86  	require.Equal(t, true, b)
    87  
    88  	elem = obj.GetField("my_group")
    89  	myGroup, err := elem.Group()
    90  	require.NoError(t, err, "getting my_group as group failed")
    91  
    92  	elem = myGroup.GetField("foo1")
    93  	f32, err := elem.Float32()
    94  	require.NoError(t, err, "getting my_group.foo1 as float32 failed")
    95  	require.Equal(t, float32(23.5), f32)
    96  
    97  	elem = myGroup.GetField("bar1")
    98  	f64, err := elem.Float64()
    99  	require.NoError(t, err, "getting my_group.bar1 as float64 failed")
   100  	require.Equal(t, float64(9000.5), f64)
   101  
   102  	elem = obj.GetField("id_list")
   103  	idList, err := elem.List()
   104  	require.NoError(t, err, "getting id_list as list failed")
   105  
   106  	var i64List []int64
   107  
   108  	for idList.Next() {
   109  		v, err2 := idList.Value()
   110  		require.NoError(t, err2, "getting list value failed")
   111  		i64, err3 := v.Int64()
   112  		require.NoError(t, err3, "getting list value as int64 failed")
   113  		i64List = append(i64List, i64)
   114  	}
   115  
   116  	require.Equal(t, []int64{1, 2, 15, 28, 32}, i64List, "list id_list values don't match")
   117  
   118  	elem = obj.GetField("data_map")
   119  	dataMap, err := elem.Map()
   120  	require.NoError(t, err, "getting data_map as map failed")
   121  
   122  	mapData := make(map[string]int32)
   123  
   124  	for dataMap.Next() {
   125  		key, err := dataMap.Key()
   126  		require.NoError(t, err, "getting key from map failed")
   127  		keyData, err := key.ByteArray()
   128  		require.NoError(t, err, "getting key as []byte failed")
   129  
   130  		value, err := dataMap.Value()
   131  		require.NoError(t, err, "getting value from map failed")
   132  		valueData, err := value.Int32()
   133  		require.NoError(t, err, "getting value as int32 failed")
   134  
   135  		mapData[string(keyData)] = valueData
   136  	}
   137  
   138  	require.Equal(t, map[string]int32{"data0": 0, "data1": 1, "data2": 2, "data3": 3, "data4": 4}, mapData)
   139  }
   140  
   141  func TestObjectUnmarshallingErrors(t *testing.T) {
   142  	obj := NewUnmarshallObject(map[string]interface{}{
   143  		"foo":          int64(23),
   144  		"bar":          int32(42),
   145  		"invalid_list": map[string]interface{}{},
   146  		"invalid_list_2": map[string]interface{}{
   147  			"list": map[string]interface{}{"foo": int32(0)},
   148  		},
   149  		"invalid_list_element": map[string]interface{}{
   150  			"list": []map[string]interface{}{
   151  				{"foo": int32(0)},
   152  			},
   153  		},
   154  		"invalid_map": map[string]interface{}{},
   155  		"invalid_map_2": map[string]interface{}{
   156  			"key_value": map[string]interface{}{"foo": int32(0)},
   157  		},
   158  
   159  		"data_map_no_keyvalues": map[string]interface{}{
   160  			"key_value": []map[string]interface{}{
   161  				{},
   162  			},
   163  		},
   164  	})
   165  
   166  	err := obj.GetField("does_not_exist").Error()
   167  	require.Error(t, err)
   168  
   169  	elem := obj.GetField("foo")
   170  	_, err = elem.Bool()
   171  	require.Error(t, err)
   172  	_, err = elem.ByteArray()
   173  	require.Error(t, err)
   174  	_, err = elem.Float32()
   175  	require.Error(t, err)
   176  	_, err = elem.Float64()
   177  	require.Error(t, err)
   178  	_, err = elem.Int32()
   179  	require.Error(t, err)
   180  	_, err = elem.Group()
   181  	require.Error(t, err)
   182  	_, err = elem.List()
   183  	require.Error(t, err)
   184  	_, err = elem.Map()
   185  	require.Error(t, err)
   186  
   187  	elem = obj.GetField("bar")
   188  	_, err = elem.Int64()
   189  	require.Error(t, err)
   190  
   191  	elem = obj.GetField("invalid_list")
   192  	_, err = elem.List()
   193  	require.Error(t, err)
   194  
   195  	elem = obj.GetField("invalid_list_2")
   196  	_, err = elem.List()
   197  	require.Error(t, err)
   198  
   199  	elem = obj.GetField("invalid_list_element")
   200  	list, err := elem.List()
   201  	require.NoError(t, err)
   202  
   203  	for list.Next() {
   204  		_, err2 := list.Value()
   205  		require.Error(t, err2)
   206  	}
   207  
   208  	_, err = list.Value()
   209  	require.Error(t, err)
   210  
   211  	elem = obj.GetField("invalid_map")
   212  	_, err = elem.Map()
   213  	require.Error(t, err)
   214  
   215  	elem = obj.GetField("invalid_map_2")
   216  	_, err = elem.Map()
   217  	require.Error(t, err)
   218  
   219  	elem = obj.GetField("data_map_no_keyvalues")
   220  	dataMap, err := elem.Map()
   221  	require.NoError(t, err)
   222  
   223  	for dataMap.Next() {
   224  		_, err = dataMap.Key()
   225  		require.Error(t, err)
   226  
   227  		_, err = dataMap.Value()
   228  		require.Error(t, err)
   229  	}
   230  
   231  	_, err = dataMap.Key()
   232  	require.Error(t, err)
   233  
   234  	_, err = dataMap.Value()
   235  	require.Error(t, err)
   236  }
   237  
   238  func TestObjectUnmarshallingList(t *testing.T) {
   239  	testData := map[string]map[string]interface{}{
   240  		"new-style-list": {
   241  			"emails": map[string]interface{}{
   242  				"list": []map[string]interface{}{
   243  					{
   244  						"element": []byte("foo@example.com"),
   245  					},
   246  					{
   247  						"element": []byte("bar@example.com"),
   248  					},
   249  				},
   250  			},
   251  		},
   252  		"athena-compat": {
   253  			"emails": map[string]interface{}{
   254  				"bag": []map[string]interface{}{
   255  					{
   256  						"array_element": []byte("foo@example.com"),
   257  					},
   258  					{
   259  						"array_element": []byte("bar@example.com"),
   260  					},
   261  				},
   262  			},
   263  		},
   264  	}
   265  
   266  	for testName, input := range testData {
   267  		t.Run(testName, func(t *testing.T) {
   268  			obj := NewUnmarshallObject(input)
   269  
   270  			emailList, err := obj.GetField("emails").List()
   271  			require.NoError(t, err)
   272  
   273  			require.True(t, emailList.Next())
   274  
   275  			v, err := emailList.Value()
   276  			require.NoError(t, err)
   277  			v1, err := v.ByteArray()
   278  			require.NoError(t, err)
   279  			require.Equal(t, "foo@example.com", string(v1))
   280  
   281  			require.True(t, emailList.Next())
   282  
   283  			v, err = emailList.Value()
   284  			require.NoError(t, err)
   285  			v2, err := v.ByteArray()
   286  			require.NoError(t, err)
   287  			require.Equal(t, "bar@example.com", string(v2))
   288  
   289  			require.False(t, emailList.Next())
   290  		})
   291  	}
   292  }