go-hep.org/x/hep@v0.38.1/groot/rdict/rw_test.go (about)

     1  // Copyright ©2018 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 rdict
     6  
     7  import (
     8  	"io"
     9  	"reflect"
    10  	"testing"
    11  
    12  	"go-hep.org/x/hep/groot/internal/rtests"
    13  	"go-hep.org/x/hep/groot/rbase"
    14  	"go-hep.org/x/hep/groot/rbytes"
    15  	"go-hep.org/x/hep/groot/rmeta"
    16  	"go-hep.org/x/hep/groot/rtypes"
    17  )
    18  
    19  func TestWRBuffer(t *testing.T) {
    20  	for _, tc := range []struct {
    21  		name string
    22  		want rtests.ROOTer
    23  	}{
    24  		{
    25  			name: "TStreamerBase",
    26  			want: &StreamerBase{
    27  				StreamerElement: StreamerElement{
    28  					named:  *rbase.NewNamed("TAttLine", "Line attributes"),
    29  					etype:  0,
    30  					esize:  0,
    31  					arrlen: 0,
    32  					arrdim: 0,
    33  					maxidx: [5]int32{0, 0, 0, 0, 0},
    34  					offset: 0,
    35  					ename:  "BASE",
    36  					xmin:   0,
    37  					xmax:   0,
    38  					factor: 0,
    39  				},
    40  				vbase: 1,
    41  			},
    42  		},
    43  		{
    44  			name: "TStreamerBasicType",
    45  			want: &StreamerBasicType{
    46  				StreamerElement: StreamerElement{
    47  					named:  *rbase.NewNamed("fEntries", "Number of entries"),
    48  					etype:  16,
    49  					esize:  8,
    50  					arrlen: 0,
    51  					arrdim: 0,
    52  					maxidx: [5]int32{0, 0, 0, 0, 0},
    53  					offset: 0,
    54  					ename:  "Long64_t",
    55  					xmin:   0,
    56  					xmax:   0,
    57  					factor: 0,
    58  				},
    59  			},
    60  		},
    61  		{
    62  			name: "TStreamerBasicType",
    63  			want: &StreamerBasicType{
    64  				StreamerElement: StreamerElement{
    65  					named:  *rbase.NewNamed("fEntries", "Array of entries"),
    66  					etype:  rmeta.OffsetL + rmeta.ULong,
    67  					esize:  40,
    68  					arrlen: 5,
    69  					arrdim: 1,
    70  					maxidx: [5]int32{0, 0, 0, 0, 0},
    71  					offset: 0,
    72  					ename:  "ULong_t",
    73  					xmin:   0,
    74  					xmax:   0,
    75  					factor: 0,
    76  				},
    77  			},
    78  		},
    79  		{
    80  			name: "TStreamerBasicPointer",
    81  			want: &StreamerBasicPointer{
    82  				StreamerElement: StreamerElement{
    83  					named:  *rbase.NewNamed("fClusterRangeEnd", "[fNClusterRange] Last entry of a cluster range."),
    84  					etype:  56,
    85  					esize:  8,
    86  					arrlen: 0,
    87  					arrdim: 0,
    88  					maxidx: [5]int32{0, 0, 0, 0, 0},
    89  					offset: 0,
    90  					ename:  "Long64_t*",
    91  					xmin:   0,
    92  					xmax:   0,
    93  					factor: 0,
    94  				},
    95  				cvers: 19,
    96  				cname: "fNClusterRange",
    97  				ccls:  "TTree",
    98  			},
    99  		},
   100  		{
   101  			name: "TStreamerBasicType",
   102  			want: &StreamerBasicType{
   103  				StreamerElement: StreamerElement{
   104  					named:  *rbase.NewNamed("fEntries", "DynArray of entries"),
   105  					etype:  rmeta.OffsetP + rmeta.ULong,
   106  					esize:  8,
   107  					arrlen: 0,
   108  					arrdim: 1,
   109  					maxidx: [5]int32{0, 0, 0, 0, 0},
   110  					offset: 0,
   111  					ename:  "ULong_t",
   112  					xmin:   0,
   113  					xmax:   0,
   114  					factor: 0,
   115  				},
   116  			},
   117  		},
   118  		{
   119  			name: "TStreamerLoop",
   120  			want: &StreamerLoop{
   121  				StreamerElement: StreamerElement{
   122  					named: *rbase.NewNamed("fLoop", "A streamer loop"),
   123  				},
   124  				cvers:  1,
   125  				cname:  "fArrayCount",
   126  				cclass: "MyArrayCount",
   127  			},
   128  		},
   129  		{
   130  			name: "TStreamerObject",
   131  			want: &StreamerObject{
   132  				StreamerElement: StreamerElement{
   133  					named:  *rbase.NewNamed("fBranches", "List of branches"),
   134  					etype:  61,
   135  					esize:  64,
   136  					arrlen: 0,
   137  					arrdim: 0,
   138  					maxidx: [5]int32{0, 0, 0, 0, 0},
   139  					offset: 0,
   140  					ename:  "TObjArray",
   141  					xmin:   0,
   142  					xmax:   0,
   143  					factor: 0,
   144  				},
   145  			},
   146  		},
   147  		{
   148  			name: "TStreamerObjectAnyPointer",
   149  			want: &StreamerObjectAnyPointer{
   150  				StreamerElement: StreamerElement{
   151  					named: *rbase.NewNamed("fObjAnyPtr", "A pointer to any object"),
   152  				},
   153  			},
   154  		},
   155  		{
   156  			name: "TStreamerObjectAny",
   157  			want: &StreamerObjectAny{
   158  				StreamerElement: StreamerElement{
   159  					named: *rbase.NewNamed("fIndexValues", "Sorted index values"),
   160  
   161  					etype:  62,
   162  					esize:  24,
   163  					arrlen: 0,
   164  					arrdim: 0,
   165  					maxidx: [5]int32{0, 0, 0, 0, 0},
   166  					offset: 0,
   167  					ename:  "TArrayD",
   168  					xmin:   0,
   169  					xmax:   0,
   170  					factor: 0,
   171  				},
   172  			},
   173  		},
   174  		{
   175  			name: "TStreamerString",
   176  			want: &StreamerString{
   177  				StreamerElement: StreamerElement{
   178  					named:  *rbase.NewNamed("fName", "object identifier"),
   179  					etype:  65,
   180  					esize:  24,
   181  					arrlen: 0,
   182  					arrdim: 0,
   183  					maxidx: [5]int32{0, 0, 0, 0, 0},
   184  					offset: 0,
   185  					ename:  "TString",
   186  					xmin:   0,
   187  					xmax:   0,
   188  					factor: 0,
   189  				},
   190  			},
   191  		},
   192  		{
   193  			name: "TStreamerSTL",
   194  			want: &StreamerSTL{
   195  				StreamerElement: StreamerElement{
   196  					named: *rbase.NewNamed("fStdSet", "A std::set<int>"),
   197  					etype: rmeta.STL,
   198  					ename: "set<int>",
   199  				},
   200  				vtype: rmeta.STLset,
   201  				ctype: rmeta.Int,
   202  			},
   203  		},
   204  		{
   205  			name: "TStreamerSTL",
   206  			want: &StreamerSTL{
   207  				StreamerElement: StreamerElement{
   208  					named: *rbase.NewNamed("fStdMultimap", "A std::multimap<int,int>"),
   209  					etype: rmeta.STL,
   210  					ename: "multimap<int,int>",
   211  				},
   212  				vtype: rmeta.STLmultimap,
   213  				ctype: rmeta.Int,
   214  			},
   215  		},
   216  		{
   217  			name: "TStreamerSTLstring",
   218  			want: &StreamerSTLstring{
   219  				StreamerSTL: StreamerSTL{
   220  					StreamerElement: StreamerElement{
   221  						named: *rbase.NewNamed("fStdString", "A std::string"),
   222  						etype: rmeta.STL,
   223  						ename: "string",
   224  					},
   225  					vtype: rmeta.STLany,
   226  					ctype: rmeta.STLstring,
   227  				},
   228  			},
   229  		},
   230  		{
   231  			name: "TStreamerArtificial",
   232  			want: &StreamerArtificial{
   233  				StreamerElement: StreamerElement{
   234  					named: *rbase.NewNamed("fArtificial", "An artificial streamer"),
   235  					ename: "std::artificial",
   236  				},
   237  			},
   238  		},
   239  	} {
   240  		t.Run(tc.name, func(t *testing.T) {
   241  			{
   242  				wbuf := rbytes.NewWBuffer(nil, nil, 0, nil)
   243  				wbuf.SetErr(io.EOF)
   244  				_, err := tc.want.MarshalROOT(wbuf)
   245  				if err == nil {
   246  					t.Fatalf("expected an error")
   247  				}
   248  				if err != io.EOF {
   249  					t.Fatalf("got=%v, want=%v", err, io.EOF)
   250  				}
   251  			}
   252  			wbuf := rbytes.NewWBuffer(nil, nil, 0, nil)
   253  			_, err := tc.want.MarshalROOT(wbuf)
   254  			if err != nil {
   255  				t.Fatalf("could not marshal ROOT: %v", err)
   256  			}
   257  
   258  			rbuf := rbytes.NewRBuffer(wbuf.Bytes(), nil, 0, nil)
   259  			class := tc.want.Class()
   260  			obj := rtypes.Factory.Get(class)().Interface().(rbytes.Unmarshaler)
   261  			{
   262  				rbuf.SetErr(io.EOF)
   263  				err = obj.UnmarshalROOT(rbuf)
   264  				if err == nil {
   265  					t.Fatalf("expected an error")
   266  				}
   267  				if err != io.EOF {
   268  					t.Fatalf("got=%v, want=%v", err, io.EOF)
   269  				}
   270  				rbuf.SetErr(nil)
   271  			}
   272  			err = obj.UnmarshalROOT(rbuf)
   273  			if err != nil {
   274  				t.Fatalf("could not unmarshal ROOT: %v", err)
   275  			}
   276  
   277  			if !reflect.DeepEqual(obj, tc.want) {
   278  				t.Fatalf("error\ngot= %+v\nwant=%+v\n", obj, tc.want)
   279  			}
   280  		})
   281  	}
   282  }
   283  
   284  func TestNewStreamerSTL(t *testing.T) {
   285  	for _, tc := range []struct {
   286  		name  string
   287  		vtype rmeta.ESTLType
   288  		ctype rmeta.Enum
   289  		want  *StreamerSTL
   290  	}{
   291  		{
   292  			name:  "v",
   293  			vtype: rmeta.STLvector,
   294  			ctype: rmeta.Int,
   295  			want: &StreamerSTL{
   296  				StreamerElement: StreamerElement{
   297  					named: *rbase.NewNamed("v", ""),
   298  					esize: int32(ptrSize + 2*intSize),
   299  					ename: "vector<int>",
   300  					etype: rmeta.Streamer,
   301  				},
   302  				vtype: rmeta.STLvector,
   303  				ctype: rmeta.Int,
   304  			},
   305  		},
   306  		{
   307  			name:  "v",
   308  			vtype: rmeta.STLvector,
   309  			ctype: rmeta.Float64,
   310  			want: &StreamerSTL{
   311  				StreamerElement: StreamerElement{
   312  					named: *rbase.NewNamed("v", ""),
   313  					esize: int32(ptrSize + 2*intSize),
   314  					ename: "vector<double>",
   315  					etype: rmeta.Streamer,
   316  				},
   317  				vtype: rmeta.STLvector,
   318  				ctype: rmeta.Float64,
   319  			},
   320  		},
   321  		{
   322  			name:  "v",
   323  			vtype: rmeta.STLvector,
   324  			ctype: rmeta.TString,
   325  			want: &StreamerSTL{
   326  				StreamerElement: StreamerElement{
   327  					named: *rbase.NewNamed("v", ""),
   328  					esize: int32(ptrSize + 2*intSize),
   329  					ename: "vector<TString>",
   330  					etype: rmeta.Streamer,
   331  				},
   332  				vtype: rmeta.STLvector,
   333  				ctype: rmeta.TString,
   334  			},
   335  		},
   336  		{
   337  			name:  "v",
   338  			vtype: rmeta.STLvector,
   339  			ctype: rmeta.STLstring,
   340  			want: &StreamerSTL{
   341  				StreamerElement: StreamerElement{
   342  					named: *rbase.NewNamed("v", ""),
   343  					esize: int32(ptrSize + 2*intSize),
   344  					ename: "vector<string>",
   345  					etype: rmeta.Streamer,
   346  				},
   347  				vtype: rmeta.STLvector,
   348  				ctype: rmeta.STLstring,
   349  			},
   350  		},
   351  		{
   352  			name:  "v",
   353  			vtype: rmeta.STLlist,
   354  			ctype: rmeta.UInt,
   355  			want: &StreamerSTL{
   356  				StreamerElement: StreamerElement{
   357  					named: *rbase.NewNamed("v", ""),
   358  					esize: int32(ptrSize + 2*intSize),
   359  					ename: "list<unsigned int>",
   360  					etype: rmeta.Streamer,
   361  				},
   362  				vtype: rmeta.STLlist,
   363  				ctype: rmeta.UInt,
   364  			},
   365  		},
   366  		{
   367  			name:  "v",
   368  			vtype: rmeta.STLdeque,
   369  			ctype: rmeta.UInt,
   370  			want: &StreamerSTL{
   371  				StreamerElement: StreamerElement{
   372  					named: *rbase.NewNamed("v", ""),
   373  					esize: int32(ptrSize + 2*intSize),
   374  					ename: "deque<unsigned int>",
   375  					etype: rmeta.Streamer,
   376  				},
   377  				vtype: rmeta.STLdeque,
   378  				ctype: rmeta.UInt,
   379  			},
   380  		},
   381  		{
   382  			name:  "v",
   383  			vtype: rmeta.STLset,
   384  			ctype: rmeta.UInt,
   385  			want: &StreamerSTL{
   386  				StreamerElement: StreamerElement{
   387  					named: *rbase.NewNamed("v", ""),
   388  					esize: int32(ptrSize + 2*intSize),
   389  					ename: "set<unsigned int>",
   390  					etype: rmeta.Streamer,
   391  				},
   392  				vtype: rmeta.STLset,
   393  				ctype: rmeta.UInt,
   394  			},
   395  		},
   396  		{
   397  			name:  "v",
   398  			vtype: rmeta.STLmultiset,
   399  			ctype: rmeta.UInt,
   400  			want: &StreamerSTL{
   401  				StreamerElement: StreamerElement{
   402  					named: *rbase.NewNamed("v", ""),
   403  					esize: int32(ptrSize + 2*intSize),
   404  					ename: "multiset<unsigned int>",
   405  					etype: rmeta.Streamer,
   406  				},
   407  				vtype: rmeta.STLmultiset,
   408  				ctype: rmeta.UInt,
   409  			},
   410  		},
   411  		{
   412  			name:  "v",
   413  			vtype: rmeta.STLunorderedset,
   414  			ctype: rmeta.UInt,
   415  			want: &StreamerSTL{
   416  				StreamerElement: StreamerElement{
   417  					named: *rbase.NewNamed("v", ""),
   418  					esize: int32(ptrSize + 2*intSize),
   419  					ename: "unordered_set<unsigned int>",
   420  					etype: rmeta.Streamer,
   421  				},
   422  				vtype: rmeta.STLunorderedset,
   423  				ctype: rmeta.UInt,
   424  			},
   425  		},
   426  		{
   427  			name:  "v",
   428  			vtype: rmeta.STLunorderedmultiset,
   429  			ctype: rmeta.UInt,
   430  			want: &StreamerSTL{
   431  				StreamerElement: StreamerElement{
   432  					named: *rbase.NewNamed("v", ""),
   433  					esize: int32(ptrSize + 2*intSize),
   434  					ename: "unordered_multiset<unsigned int>",
   435  					etype: rmeta.Streamer,
   436  				},
   437  				vtype: rmeta.STLunorderedmultiset,
   438  				ctype: rmeta.UInt,
   439  			},
   440  		},
   441  		{
   442  			name:  "v",
   443  			vtype: rmeta.STLforwardlist,
   444  			ctype: rmeta.UInt,
   445  			want: &StreamerSTL{
   446  				StreamerElement: StreamerElement{
   447  					named: *rbase.NewNamed("v", ""),
   448  					esize: int32(ptrSize + 2*intSize),
   449  					ename: "forward_list<unsigned int>",
   450  					etype: rmeta.Streamer,
   451  				},
   452  				vtype: rmeta.STLforwardlist,
   453  				ctype: rmeta.UInt,
   454  			},
   455  		},
   456  	} {
   457  		t.Run(tc.name, func(t *testing.T) {
   458  			got := NewStreamerSTL(tc.name, tc.vtype, tc.ctype)
   459  			if !reflect.DeepEqual(got, tc.want) {
   460  				t.Fatalf("error:\ngot= %#v\nwant=%#v", *got, *tc.want)
   461  			}
   462  		})
   463  	}
   464  }