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  }