go-hep.org/x/hep@v0.38.1/groot/rjson/rjson_test.go (about) 1 // Copyright ©2023 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 rjson_test 6 7 import ( 8 "fmt" 9 "os" 10 "path/filepath" 11 "testing" 12 13 "go-hep.org/x/hep/groot/internal/rtests" 14 "go-hep.org/x/hep/groot/rhist" 15 "go-hep.org/x/hep/groot/rjson" 16 "go-hep.org/x/hep/groot/root" 17 "go-hep.org/x/hep/hbook" 18 "go-hep.org/x/hep/internal/diff" 19 ) 20 21 func TestMarshal(t *testing.T) { 22 for _, tc := range []struct { 23 name string 24 gen func() root.Object 25 }{ 26 { 27 name: "h1d", 28 gen: func() root.Object { 29 h := hbook.NewH1D(100, 0, 100) 30 h.Fill(1, 1) 31 h.Fill(-1, 1) 32 h.Fill(200, 1) 33 h.Ann["name"] = "h1" 34 h.Ann["title"] = "my title" 35 36 return rhist.NewH1DFrom(h) 37 }, 38 }, 39 { 40 name: "h2d", 41 gen: func() root.Object { 42 h := hbook.NewH2D(5, 0, 5, 2, 0, 2) 43 h.Fill(1, 1, 1) 44 h.Fill(-1, -1, 1) 45 h.Fill(200, 300, 1) 46 h.Ann["name"] = "h2" 47 h.Ann["title"] = "my title" 48 49 return rhist.NewH2DFrom(h) 50 }, 51 }, 52 { 53 name: "graph", 54 gen: func() root.Object { 55 s := hbook.NewS2DFrom([]float64{1, 2, 3}, []float64{2, 4, 6}) 56 s.Annotation()["name"] = "s2" 57 s.Annotation()["title"] = "my title" 58 return rhist.NewGraphFrom(s) 59 }, 60 }, 61 { 62 name: "tge", 63 gen: func() root.Object { 64 s := hbook.NewS2D([]hbook.Point2D{ 65 {X: 1, Y: 2, ErrX: hbook.Range{Min: 10, Max: 20}, ErrY: hbook.Range{Min: 11, Max: 22}}, 66 {X: 2, Y: 4, ErrX: hbook.Range{Min: 20, Max: 30}, ErrY: hbook.Range{Min: 12, Max: 23}}, 67 {X: 3, Y: 6, ErrX: hbook.Range{Min: 30, Max: 40}, ErrY: hbook.Range{Min: 13, Max: 24}}, 68 }...) 69 s.Annotation()["name"] = "s2" 70 s.Annotation()["title"] = "my title" 71 return rhist.NewGraphErrorsFrom(s) 72 }, 73 }, 74 { 75 name: "tgae", 76 gen: func() root.Object { 77 s := hbook.NewS2D([]hbook.Point2D{ 78 {X: 1, Y: 2, ErrX: hbook.Range{Min: 10, Max: 20}, ErrY: hbook.Range{Min: 11, Max: 22}}, 79 {X: 2, Y: 4, ErrX: hbook.Range{Min: 20, Max: 30}, ErrY: hbook.Range{Min: 12, Max: 23}}, 80 {X: 3, Y: 6, ErrX: hbook.Range{Min: 30, Max: 40}, ErrY: hbook.Range{Min: 13, Max: 24}}, 81 }...) 82 s.Annotation()["name"] = "s2" 83 s.Annotation()["title"] = "my title" 84 return rhist.NewGraphAsymmErrorsFrom(s) 85 }, 86 }, 87 { 88 name: "tgme", 89 gen: func() root.Object { 90 s := hbook.NewS2D([]hbook.Point2D{ 91 {X: 1, Y: 2, ErrX: hbook.Range{Min: 10, Max: 20}, ErrY: hbook.Range{Min: 11, Max: 22}}, 92 {X: 2, Y: 4, ErrX: hbook.Range{Min: 20, Max: 30}, ErrY: hbook.Range{Min: 12, Max: 23}}, 93 {X: 3, Y: 6, ErrX: hbook.Range{Min: 30, Max: 40}, ErrY: hbook.Range{Min: 13, Max: 24}}, 94 }...) 95 s.Annotation()["name"] = "s2" 96 s.Annotation()["title"] = "my title" 97 return rhist.NewGraphMultiErrorsFrom(s) 98 }, 99 }, 100 } { 101 t.Run(tc.name, func(t *testing.T) { 102 var ( 103 fname = filepath.Join("testdata", tc.name+".json") 104 want = filepath.Join("testdata", tc.name+"_golden.json") 105 ) 106 107 obj := tc.gen() 108 got, err := rjson.Marshal(obj) 109 if err != nil { 110 t.Fatalf("could not generate JSON: %+v", err) 111 } 112 113 err = os.WriteFile(fname, got, 0644) 114 if err != nil { 115 t.Fatalf("could not write JSON: %+v", err) 116 } 117 118 err = diff.Files(fname, want) 119 if err != nil { 120 t.Fatalf("invalid JSON:\n%v", err) 121 } 122 123 if !rtests.HasROOT { 124 return 125 } 126 127 // make sure ROOT can read back that file as well. 128 code := fmt.Sprintf(`#include <iostream> 129 #include <fstream> 130 #include <sstream> 131 #include <string> 132 133 #include "TBufferJSON.h" 134 #include "%[1]s.h" 135 136 void unmarshal(const char *fname) { 137 std:ifstream input(fname); 138 std::stringstream s; 139 while (input >> s.rdbuf()) {} 140 141 auto str = s.str(); 142 143 %[1]s *o = nullptr; 144 TBufferJSON::FromJSON(o, str.c_str()); 145 146 if (o->ClassName() != std::string("%[1]s")) { 147 std::cerr << "invalid class name: got=\"" << o->ClassName() << "\", want=\"%[1]s\"\n"; 148 exit(1); 149 } 150 o->Print(); 151 } 152 `, obj.Class(), 153 ) 154 out, err := rtests.RunCxxROOT("unmarshal", []byte(code), fname) 155 if err != nil { 156 t.Fatalf("could not run C++ ROOT: %+v\noutput:\n%s\ncode:\n%s", err, out, code) 157 } 158 159 defer os.Remove(fname) 160 }) 161 } 162 }