github.com/fraugster/parquet-go@v0.12.0/parquetschema/autoschema/gen_test.go (about)

     1  package autoschema
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  	"unsafe"
     7  
     8  	"github.com/stretchr/testify/require"
     9  )
    10  
    11  func TestGenerateSchema(t *testing.T) {
    12  	tests := map[string]struct {
    13  		Input          interface{}
    14  		ExpectErr      bool
    15  		ExpectedOutput string
    16  	}{
    17  		"simple types": {
    18  			Input: struct {
    19  				Foo  string
    20  				Bar  int
    21  				Baz  uint
    22  				Quux float64
    23  				Bla  int64
    24  				Abc  uint64
    25  				Def  float32
    26  				Ghi  int32
    27  				Jkl  uint32
    28  				Mno  int16
    29  				Pqr  uint16
    30  				Rst  int8
    31  				Uvw  uint8
    32  				Xyz  bool
    33  			}{},
    34  			ExpectErr:      false,
    35  			ExpectedOutput: "message autogen_schema {\n  required binary foo (STRING);\n  required int64 bar (INT(64, true));\n  required int32 baz (INT(32, false));\n  required double quux;\n  required int64 bla (INT(64, true));\n  required int64 abc (INT(64, false));\n  required float def;\n  required int32 ghi (INT(32, true));\n  required int32 jkl (INT(32, false));\n  required int32 mno (INT(16, true));\n  required int32 pqr (INT(16, false));\n  required int32 rst (INT(8, true));\n  required int32 uvw (INT(8, false));\n  required boolean xyz;\n}\n",
    36  		},
    37  		"optional type": {
    38  			Input: struct {
    39  				Foo *int
    40  			}{},
    41  			ExpectErr:      false,
    42  			ExpectedOutput: "message autogen_schema {\n  optional int64 foo (INT(64, true));\n}\n",
    43  		},
    44  		"struct pointer": {
    45  			Input: (*struct {
    46  				Foo int
    47  			})(nil),
    48  			ExpectErr:      false,
    49  			ExpectedOutput: "message autogen_schema {\n  required int64 foo (INT(64, true));\n}\n",
    50  		},
    51  		"structs within struct": {
    52  			Input: (*struct {
    53  				Foo *struct {
    54  					Bar int32
    55  				}
    56  				Baz struct {
    57  					Quux int64
    58  				}
    59  			})(nil),
    60  			ExpectErr:      false,
    61  			ExpectedOutput: "message autogen_schema {\n  optional group foo {\n    required int32 bar (INT(32, true));\n  }\n  required group baz {\n    required int64 quux (INT(64, true));\n  }\n}\n",
    62  		},
    63  		"slices": {
    64  			Input: (*struct {
    65  				Foo []int
    66  				Bar []*int
    67  				Baz []struct {
    68  					Quux int
    69  				}
    70  				Bla []*struct {
    71  					Fasel *int
    72  				}
    73  			})(nil),
    74  			ExpectErr:      false,
    75  			ExpectedOutput: "message autogen_schema {\n  required group foo (LIST) {\n    repeated group list {\n      required int64 element (INT(64, true));\n    }\n  }\n  optional group bar (LIST) {\n    repeated group list {\n      required int64 element (INT(64, true));\n    }\n  }\n  required group baz (LIST) {\n    repeated group list {\n      required group element {\n        required int64 quux (INT(64, true));\n      }\n    }\n  }\n  optional group bla (LIST) {\n    repeated group list {\n      required group element {\n        optional int64 fasel (INT(64, true));\n      }\n    }\n  }\n}\n",
    76  		},
    77  		"arrays": {
    78  			Input: (*struct {
    79  				Foo [1]int
    80  				Bar [10]*int
    81  				Baz [5]struct {
    82  					Quux int
    83  				}
    84  				Bla [23]*struct {
    85  					Fasel *int
    86  				}
    87  			})(nil),
    88  			ExpectErr:      false,
    89  			ExpectedOutput: "message autogen_schema {\n  required group foo (LIST) {\n    repeated group list {\n      required int64 element (INT(64, true));\n    }\n  }\n  optional group bar (LIST) {\n    repeated group list {\n      required int64 element (INT(64, true));\n    }\n  }\n  required group baz (LIST) {\n    repeated group list {\n      required group element {\n        required int64 quux (INT(64, true));\n      }\n    }\n  }\n  optional group bla (LIST) {\n    repeated group list {\n      required group element {\n        optional int64 fasel (INT(64, true));\n      }\n    }\n  }\n}\n",
    90  		},
    91  		"byte slices": {
    92  			Input: (*struct {
    93  				Foo []byte
    94  				Bar *[]byte
    95  			})(nil),
    96  			ExpectErr:      false,
    97  			ExpectedOutput: "message autogen_schema {\n  required binary foo;\n  optional binary bar;\n}\n",
    98  		},
    99  		"struct tags": {
   100  			Input: (*struct {
   101  				Foo []byte  `parquet:"foobar"`
   102  				Bar *[]byte `parquet:"barman"`
   103  				Baz int64   `parquet:"bazinga"`
   104  			})(nil),
   105  			ExpectErr:      false,
   106  			ExpectedOutput: "message autogen_schema {\n  required binary foobar;\n  optional binary barman;\n  required int64 bazinga (INT(64, true));\n}\n",
   107  		},
   108  		"byte array": {
   109  			Input: (*struct {
   110  				Foo [23]byte
   111  				Bar *[42]byte
   112  			})(nil),
   113  			ExpectErr:      false,
   114  			ExpectedOutput: "message autogen_schema {\n  required fixed_len_byte_array(23) foo;\n  optional fixed_len_byte_array(42) bar;\n}\n",
   115  		},
   116  		"simple map": {
   117  			Input: (*struct {
   118  				Foo map[string]int64
   119  			})(nil),
   120  			ExpectErr:      false,
   121  			ExpectedOutput: "message autogen_schema {\n  optional group foo (MAP) {\n    repeated group key_value (MAP_KEY_VALUE) {\n      required binary key (STRING);\n      required int64 value (INT(64, true));\n    }\n  }\n}\n",
   122  		},
   123  		"chan": {
   124  			Input: (*struct {
   125  				Foo chan int
   126  			})(nil),
   127  			ExpectErr: true,
   128  		},
   129  		"func": {
   130  			Input: (*struct {
   131  				Foo func()
   132  			})(nil),
   133  			ExpectErr: true,
   134  		},
   135  		"interface": {
   136  			Input: (*struct {
   137  				Foo interface{}
   138  			})(nil),
   139  			ExpectErr: true,
   140  		},
   141  		"unsafe.Pointer": {
   142  			Input: (*struct {
   143  				Foo unsafe.Pointer
   144  			})(nil),
   145  			ExpectErr: true,
   146  		},
   147  		"complex64": {
   148  			Input: (*struct {
   149  				Foo complex64
   150  			})(nil),
   151  			ExpectErr: true,
   152  		},
   153  		"complex128": {
   154  			Input: (*struct {
   155  				Foo complex128
   156  			})(nil),
   157  			ExpectErr: true,
   158  		},
   159  		"uintptr": {
   160  			Input: (*struct {
   161  				Foo uintptr
   162  			})(nil),
   163  			ExpectErr: true,
   164  		},
   165  		"invalid struct within struct": {
   166  			Input: (*struct {
   167  				Foo struct {
   168  					Bar uintptr
   169  				}
   170  			})(nil),
   171  			ExpectErr: true,
   172  		},
   173  		"invalid slice": {
   174  			Input: (*struct {
   175  				Foo []chan int
   176  			})(nil),
   177  			ExpectErr: true,
   178  		},
   179  		"invalid pointer": {
   180  			Input: (*struct {
   181  				Foo *complex128
   182  			})(nil),
   183  			ExpectErr: true,
   184  		},
   185  		"invalid map key": {
   186  			Input: (*struct {
   187  				Foo map[complex128]string
   188  			})(nil),
   189  			ExpectErr: true,
   190  		},
   191  		"invalid map value": {
   192  			Input: (*struct {
   193  				Foo map[string]complex64
   194  			})(nil),
   195  			ExpectErr: true,
   196  		},
   197  		"non-struct input": {
   198  			Input:     int64(42),
   199  			ExpectErr: true,
   200  		},
   201  		"time.Time": {
   202  			Input: (*struct {
   203  				Foo time.Time
   204  			})(nil),
   205  			ExpectedOutput: "message autogen_schema {\n  required int64 foo (TIMESTAMP(NANOS, true));\n}\n",
   206  		},
   207  	}
   208  
   209  	for testName, testData := range tests {
   210  		t.Run(testName, func(t *testing.T) {
   211  			output, err := GenerateSchema(testData.Input)
   212  			if testData.ExpectErr {
   213  				require.Error(t, err)
   214  			} else {
   215  				require.NoError(t, err)
   216  				require.Equal(t, testData.ExpectedOutput, output.String())
   217  			}
   218  		})
   219  	}
   220  }