go-hep.org/x/hep@v0.38.1/groot/rmeta/rmeta_test.go (about) 1 // Copyright ©2019 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 rmeta_test 6 7 import ( 8 "reflect" 9 "testing" 10 11 "go-hep.org/x/hep/groot/rmeta" 12 ) 13 14 func TestCxxTemplate(t *testing.T) { 15 for _, tc := range []struct { 16 name string 17 want rmeta.CxxTemplate 18 panics string 19 }{ 20 // std::pair 21 { 22 name: "pair<int,int>", 23 want: rmeta.CxxTemplate{ 24 Name: "pair", 25 Args: []string{"int", "int"}, 26 }, 27 }, 28 { 29 name: "pair<int, int>", 30 want: rmeta.CxxTemplate{ 31 Name: "pair", 32 Args: []string{"int", "int"}, 33 }, 34 }, 35 { 36 name: "pair<unsigned int, unsigned int>", 37 want: rmeta.CxxTemplate{ 38 Name: "pair", 39 Args: []string{"unsigned int", "unsigned int"}, 40 }, 41 }, 42 { 43 name: "pair<pair<u T,u T>, pair<v T, v T>>", 44 want: rmeta.CxxTemplate{ 45 Name: "pair", 46 Args: []string{"pair<u T,u T>", "pair<v T, v T>"}, 47 }, 48 }, 49 { 50 name: "pair<T,>", 51 panics: `rmeta: invalid empty type argument "pair<T,>"`, 52 }, 53 { 54 name: "pair<,U>", 55 panics: `rmeta: invalid empty type argument "pair<,U>"`, 56 }, 57 { 58 name: "pair<,>", 59 panics: `rmeta: invalid empty type argument "pair<,>"`, 60 }, 61 { 62 name: "pair<T,U", 63 panics: `rmeta: missing '>' in "pair<T,U"`, 64 }, 65 // std::vector 66 { 67 name: "std::vector<T>", 68 want: rmeta.CxxTemplate{ 69 Name: "std::vector", 70 Args: []string{"T"}, 71 }, 72 }, 73 { 74 name: "std::vector<T, alloc<T>>", 75 want: rmeta.CxxTemplate{ 76 Name: "std::vector", 77 Args: []string{"T", "alloc<T>"}, 78 }, 79 }, 80 { 81 name: "vector<float,ROOT::Detail::VecOps::RAdoptAllocator<float> >", 82 want: rmeta.CxxTemplate{ 83 Name: "vector", 84 Args: []string{"float", "ROOT::Detail::VecOps::RAdoptAllocator<float>"}, 85 }, 86 }, 87 { 88 name: "std::vector<std::map<K,V,Cmp>>", 89 want: rmeta.CxxTemplate{ 90 Name: "std::vector", 91 Args: []string{"std::map<K,V,Cmp>"}, 92 }, 93 }, 94 { 95 name: "vector<pair<int, int>>", 96 want: rmeta.CxxTemplate{ 97 Name: "vector", 98 Args: []string{"pair<int, int>"}, 99 }, 100 }, 101 { 102 name: "vector<pair<string,string> >", 103 want: rmeta.CxxTemplate{ 104 Name: "vector", 105 Args: []string{"pair<string,string>"}, 106 }, 107 }, 108 { 109 name: "std::set<T>", 110 want: rmeta.CxxTemplate{ 111 Name: "std::set", 112 Args: []string{"T"}, 113 }, 114 }, 115 { 116 name: "std::multiset<T>", 117 want: rmeta.CxxTemplate{ 118 Name: "std::multiset", 119 Args: []string{"T"}, 120 }, 121 }, 122 { 123 name: "std::unordered_set<T>", 124 want: rmeta.CxxTemplate{ 125 Name: "std::unordered_set", 126 Args: []string{"T"}, 127 }, 128 }, 129 { 130 name: "std::map<K,V>", 131 want: rmeta.CxxTemplate{ 132 Name: "std::map", 133 Args: []string{"K", "V"}, 134 }, 135 }, 136 { 137 name: "std::map<K, V>", 138 want: rmeta.CxxTemplate{ 139 Name: "std::map", 140 Args: []string{"K", "V"}, 141 }, 142 }, 143 { 144 name: "std::multimap<K, V>", 145 want: rmeta.CxxTemplate{ 146 Name: "std::multimap", 147 Args: []string{"K", "V"}, 148 }, 149 }, 150 { 151 name: "std::unordered_map<K, V>", 152 want: rmeta.CxxTemplate{ 153 Name: "std::unordered_map", 154 Args: []string{"K", "V"}, 155 }, 156 }, 157 { 158 name: "map<K,V>", 159 want: rmeta.CxxTemplate{ 160 Name: "map", 161 Args: []string{"K", "V"}, 162 }, 163 }, 164 { 165 name: "std::map<unsigned long,unsigned int>", 166 want: rmeta.CxxTemplate{ 167 Name: "std::map", 168 Args: []string{"unsigned long", "unsigned int"}, 169 }, 170 }, 171 { 172 name: "std::map<K,std::vector<V> >", 173 want: rmeta.CxxTemplate{ 174 Name: "std::map", 175 Args: []string{"K", "std::vector<V>"}, 176 }, 177 }, 178 { 179 name: "std::map<K,std::vector<V>>", 180 want: rmeta.CxxTemplate{ 181 Name: "std::map", 182 Args: []string{"K", "std::vector<V>"}, 183 }, 184 }, 185 { 186 name: "std::map<K, std::vector<V>>", 187 want: rmeta.CxxTemplate{ 188 Name: "std::map", 189 Args: []string{"K", "std::vector<V>"}, 190 }, 191 }, 192 { 193 name: "map<string,o2::quality_control::core::CheckDefinition>", 194 want: rmeta.CxxTemplate{ 195 Name: "map", 196 Args: []string{"string", "o2::quality_control::core::CheckDefinition"}, 197 }, 198 }, 199 { 200 name: "map<string,o2::quality_control::core::CheckDefinition>", 201 want: rmeta.CxxTemplate{ 202 Name: "map", 203 Args: []string{"string", "o2::quality_control::core::CheckDefinition"}, 204 }, 205 }, 206 { 207 name: "std::map<K, std::map<K2,V2>>", 208 want: rmeta.CxxTemplate{ 209 Name: "std::map", 210 Args: []string{"K", "std::map<K2,V2>"}, 211 }, 212 }, 213 { 214 name: "std::map<std::map<K1,V1>, std::map<K2,V2>>", 215 want: rmeta.CxxTemplate{ 216 Name: "std::map", 217 Args: []string{"std::map<K1,V1>", "std::map<K2,V2>"}, 218 }, 219 }, 220 { 221 name: "std::map<std::map<K1,V1>, Foo<T1,T2,T3>>", 222 want: rmeta.CxxTemplate{ 223 Name: "std::map", 224 Args: []string{"std::map<K1,V1>", "Foo<T1,T2,T3>"}, 225 }, 226 }, 227 { 228 name: "Foo<T1, T2, T3, std::vector<T4, std::allocator<T4>>>", 229 want: rmeta.CxxTemplate{ 230 Name: "Foo", 231 Args: []string{"T1", "T2", "T3", "std::vector<T4, std::allocator<T4>>"}, 232 }, 233 }, 234 { 235 name: "Class<>", 236 want: rmeta.CxxTemplate{ 237 Name: "Class", 238 }, 239 }, 240 { 241 name: "Class<T,1<2>", 242 want: rmeta.CxxTemplate{ 243 Name: "Class", 244 Args: []string{"T", "1<2"}, 245 }, 246 }, 247 { 248 name: "Class<T,1>2>", 249 want: rmeta.CxxTemplate{ 250 Name: "Class", 251 Args: []string{"T", "1>2"}, 252 }, 253 }, 254 { 255 name: "map<Cls<1>,Cls<2>>", 256 want: rmeta.CxxTemplate{ 257 Name: "map", 258 Args: []string{"Cls<1>", "Cls<2>"}, 259 }, 260 }, 261 { 262 name: "map<Cls<1>2>,Cls<2>3>>", 263 want: rmeta.CxxTemplate{ 264 Name: "map", 265 Args: []string{"Cls<1>2>", "Cls<2>3>"}, 266 }, 267 }, 268 { 269 name: "map<Cls<1>2>,Cls<2<3>>", 270 want: rmeta.CxxTemplate{ 271 Name: "map", 272 Args: []string{"Cls<1>2>", "Cls<2<3>"}, 273 }, 274 }, 275 // FIXME(sbinet) ? 276 // for unknown classes, the ambiguity of C++ templates is 277 // undecidable... 278 // { 279 // name: "map<Cls<1<2>,Cls<2>3>>", 280 // want: rmeta.CxxTemplate{ 281 // Name: "map", 282 // Args: []string{"Cls<1<2>", "Cls<2>3>"}, 283 // }, 284 // }, 285 // { 286 // name: "map<Cls<1<2>,Cls<2<3>>", 287 // want: rmeta.CxxTemplate{ 288 // Name: "map", 289 // Args: []string{"Cls<1<2>", "Cls<2<3>"}, 290 // }, 291 // }, 292 // { 293 // name: "Class<T,map<Class<1>2>,V>", 294 // want: rmeta.CxxTemplate{ 295 // Name: "Class", 296 // Args: []string{"T", "map<Class<1>2>,V>"}, 297 // }, 298 // }, 299 { 300 name: "bitset<42>", 301 want: rmeta.CxxTemplate{ 302 Name: "bitset", 303 Args: []string{"42"}, 304 }, 305 }, 306 } { 307 t.Run(tc.name, func(t *testing.T) { 308 if tc.panics != "" { 309 defer func() { 310 err := recover() 311 if err == nil { 312 t.Fatalf("expected a panic (%s)", tc.panics) 313 } 314 if got, want := err.(error).Error(), tc.panics; got != want { 315 t.Fatalf("invalid panic message: got=%s, want=%s", got, want) 316 } 317 }() 318 } 319 320 cxx := rmeta.CxxTemplateFrom(tc.name) 321 if got, want := cxx, tc.want; !reflect.DeepEqual(got, want) { 322 t.Fatalf("invalid template args.\n got=%q\nwant=%q", got, want) 323 } 324 }) 325 } 326 }