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 }