go-hep.org/x/hep@v0.38.1/groot/rtree/wvar_test.go (about)

     1  // Copyright ©2020 The go-hep Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package rtree
     6  
     7  import "testing"
     8  
     9  func TestWriteVarsFromStruct(t *testing.T) {
    10  	for _, tc := range []struct {
    11  		name   string
    12  		ptr    any
    13  		wopts  []WriteOption
    14  		want   []WriteVar
    15  		panics string
    16  	}{
    17  		{
    18  			name: "not-ptr",
    19  			ptr: struct {
    20  				I32 int32
    21  			}{},
    22  			panics: "rtree: expect a pointer value, got struct { I32 int32 }",
    23  		},
    24  		{
    25  			name:   "not-ptr-to-struct",
    26  			ptr:    new(int32),
    27  			panics: "rtree: expect a pointer to struct value, got *int32",
    28  		},
    29  		{
    30  			name: "struct-with-int",
    31  			ptr: &struct {
    32  				I32 int
    33  				F32 float32
    34  				Str string
    35  			}{},
    36  			panics: "rtree: invalid field type for \"I32\": int",
    37  		},
    38  		{
    39  			name: "struct-with-map", // FIXME(sbinet)
    40  			ptr: &struct {
    41  				Map map[int32]string
    42  			}{},
    43  			panics: "rtree: invalid field type for \"Map\": map[int32]string (not yet supported)",
    44  		},
    45  		{
    46  			name: "invalid-struct-tag",
    47  			ptr: &struct {
    48  				N int32 `groot:"N[42]"`
    49  			}{},
    50  			panics: "rtree: invalid field type for \"N\", or invalid struct-tag \"N[42]\": int32",
    51  		},
    52  		{
    53  			name: "simple",
    54  			ptr: &struct {
    55  				I32 int32
    56  				F32 float32
    57  				Str string
    58  			}{},
    59  			want: []WriteVar{{Name: "I32"}, {Name: "F32"}, {Name: "Str"}},
    60  		},
    61  		{
    62  			name: "simple-with-unexported",
    63  			ptr: &struct {
    64  				I32 int32
    65  				F32 float32
    66  				val float32
    67  				Str string
    68  			}{},
    69  			want: []WriteVar{{Name: "I32"}, {Name: "F32"}, {Name: "Str"}},
    70  		},
    71  		{
    72  			name: "slices",
    73  			ptr: &struct {
    74  				N      int32
    75  				NN     int64
    76  				SliF32 []float32 `groot:"F32s[N]"`
    77  				SliF64 []float64 `groot:"F64s[NN]"`
    78  			}{},
    79  			want: []WriteVar{
    80  				{Name: "N"},
    81  				{Name: "NN"},
    82  				{Name: "F32s", Count: "N"},
    83  				{Name: "F64s", Count: "NN"},
    84  			},
    85  		},
    86  		{
    87  			name: "slices-no-count",
    88  			ptr: &struct {
    89  				F1 int32
    90  				X2 []float32 `groot:"F2[F1]"`
    91  				X3 []float64 `groot:"F3"`
    92  				F4 []float64
    93  			}{},
    94  			want: []WriteVar{
    95  				{Name: "F1"},
    96  				{Name: "F2", Count: "F1"},
    97  				{Name: "F3"},
    98  				{Name: "F4"},
    99  			},
   100  		},
   101  		{
   102  			name: "arrays",
   103  			ptr: &struct {
   104  				N     int32 `groot:"n"`
   105  				Arr01 [10]float64
   106  				Arr02 [10][10]float64
   107  				Arr03 [10][10][10]float64
   108  				Arr11 [10]float64         `groot:"arr11[10]"`
   109  				Arr12 [10][10]float64     `groot:"arr12[10][10]"`
   110  				Arr13 [10][10][10]float64 `groot:"arr13[10][10][10]"`
   111  				Arr14 [10][10][10]float64 `groot:"arr14"`
   112  			}{},
   113  			want: []WriteVar{
   114  				{Name: "n"},
   115  				{Name: "Arr01"},
   116  				{Name: "Arr02"},
   117  				{Name: "Arr03"},
   118  				{Name: "arr11"},
   119  				{Name: "arr12"},
   120  				{Name: "arr13"},
   121  				{Name: "arr14"},
   122  			},
   123  		},
   124  		{
   125  			name: "struct-with-struct",
   126  			ptr: &struct {
   127  				F1 int64
   128  				F2 struct {
   129  					FF1 int64
   130  					FF2 float64
   131  					FF3 struct {
   132  						FFF1 float64
   133  					}
   134  				}
   135  			}{},
   136  			want: []WriteVar{
   137  				{Name: "F1"},
   138  				{Name: "F2"},
   139  			},
   140  		},
   141  		{
   142  			name: "struct-with-struct+slice",
   143  			ptr: &struct {
   144  				F1 int64
   145  				F2 struct {
   146  					FF1 int64
   147  					FF2 float64
   148  					FF3 []float64
   149  					FF4 []struct {
   150  						FFF1 float64
   151  						FFF2 []float64
   152  					}
   153  				}
   154  			}{},
   155  			want: []WriteVar{
   156  				{Name: "F1"},
   157  				{Name: "F2"},
   158  			},
   159  		},
   160  		{
   161  			name: "invalid-slice-tag",
   162  			ptr: &struct {
   163  				N   int32
   164  				Sli []int32 `groot:"vs[N][N]"`
   165  			}{},
   166  			panics: "rtree: invalid number of slice-dimensions for field \"Sli\": \"vs[N][N]\"",
   167  		},
   168  		{
   169  			name: "invalid-array-tag",
   170  			ptr: &struct {
   171  				N   int32
   172  				Arr [12]int32 `groot:"vs[1][2][3][4]"`
   173  			}{},
   174  			panics: "rtree: invalid number of array-dimension for field \"Arr\": \"vs[1][2][3][4]\"",
   175  		},
   176  		{
   177  			name: "no-split-struct",
   178  			ptr: &struct {
   179  				N   int32
   180  				F32 float32
   181  			}{},
   182  			wopts: []WriteOption{WithTitle("evt"), WithSplitLevel(0)},
   183  			want: []WriteVar{
   184  				{Name: "evt"},
   185  			},
   186  		},
   187  	} {
   188  		t.Run(tc.name, func(t *testing.T) {
   189  			if tc.panics != "" {
   190  				defer func() {
   191  					err := recover()
   192  					if err == nil {
   193  						t.Fatalf("expected a panic")
   194  					}
   195  					if got, want := err.(error).Error(), tc.panics; got != want {
   196  						t.Fatalf("invalid panic message:\ngot= %q\nwant=%q", got, want)
   197  					}
   198  				}()
   199  			}
   200  			got := WriteVarsFromStruct(tc.ptr, tc.wopts...)
   201  			if got, want := len(got), len(tc.want); got != want {
   202  				t.Fatalf("invalid number of wvars: got=%d, want=%d", got, want)
   203  			}
   204  			for i := range got {
   205  				if got, want := got[i].Name, tc.want[i].Name; got != want {
   206  					t.Fatalf("invalid name for wvar[%d]: got=%q, want=%q", i, got, want)
   207  				}
   208  				if got, want := got[i].Count, tc.want[i].Count; got != want {
   209  					t.Fatalf("invalid count for wvar[%d]: got=%q, want=%q", i, got, want)
   210  				}
   211  			}
   212  		})
   213  	}
   214  }