go-hep.org/x/hep@v0.38.1/hplot/vgop/vgop_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 vgop_test 6 7 import ( 8 "bytes" 9 "encoding/json" 10 "image" 11 "image/color" 12 "image/draw" 13 "math" 14 "os" 15 "runtime" 16 "testing" 17 18 "go-hep.org/x/hep/hplot" 19 "go-hep.org/x/hep/hplot/vgop" 20 "go-hep.org/x/hep/internal/diff" 21 "gonum.org/v1/plot/font" 22 "gonum.org/v1/plot/vg" 23 ) 24 25 func TestJSON(t *testing.T) { 26 sr := font.Font{Typeface: "Liberation", Variant: "Serif"} 27 tr := font.From(sr, 12) 28 ft13 := hplot.DefaultStyle.Fonts.Cache.Lookup(tr, 13) 29 ft20 := hplot.DefaultStyle.Fonts.Cache.Lookup(tr, 20) 30 31 c := vgop.NewJSON(vgop.WithSize(10, 20)) 32 33 c.Push() 34 c.SetLineWidth(2) 35 c.SetLineDash([]vg.Length{1, 2}, 4) 36 c.SetColor(color.RGBA{R: 255, A: 255}) 37 c.SetColor(color.Gray{Y: 100}) 38 c.Rotate(math.Pi / 2) 39 c.Translate(vg.Point{X: 10, Y: 20}) 40 c.Scale(15, 25) 41 c.Pop() 42 p0 := vg.Path(nil) 43 p1 := vg.Path([]vg.PathComp{ 44 {Type: vg.MoveComp, Pos: vg.Point{X: 1, Y: 2}}, 45 {Type: vg.LineComp, Pos: vg.Point{X: 2, Y: 3}}, 46 {Type: vg.ArcComp, Pos: vg.Point{X: 3, Y: 4}, Radius: 5, Start: 6, Angle: 7}, 47 {Type: vg.CurveComp, Pos: vg.Point{X: 4, Y: 5}, Control: []vg.Point{{X: 6, Y: 7}}}, 48 {Type: vg.CurveComp, Pos: vg.Point{X: 5, Y: 6}, Control: []vg.Point{{X: 7, Y: 8}, {X: 9, Y: 10}}}, 49 {Type: vg.CloseComp}, 50 }) 51 c.Stroke(p0) 52 c.Stroke(p1) 53 c.Fill(p0) 54 c.Fill(p1) 55 56 c.FillString(ft13, vg.Point{X: 10, Y: 20}, "hello\nworld") 57 c.FillString(ft20, vg.Point{X: 20, Y: 30}, "BYE.") 58 59 img := image.NewRGBA(image.Rect(0, 0, 20, 30)) 60 draw.Draw(img, img.Rect, image.NewUniform(color.RGBA{0x66, 0x66, 0x66, 0xff}), image.Point{}, draw.Src) 61 62 c.DrawImage(vg.Rectangle{Min: vg.Point{X: 1, Y: 2}, Max: vg.Point{X: 3, Y: 4}}, img) 63 64 f, err := os.Create("testdata/simple.json") 65 if err != nil { 66 t.Fatalf("could not create output JSON file: %+v", err) 67 } 68 defer f.Close() 69 70 enc := json.NewEncoder(f) 71 enc.SetIndent("", " ") 72 73 err = enc.Encode(c) 74 if err != nil { 75 t.Fatalf("could not encode canvas: %+v", err) 76 } 77 78 err = f.Close() 79 if err != nil { 80 t.Fatalf("could not close output JSON file: %+v", err) 81 } 82 83 err = diff.Files("testdata/simple.json", "testdata/simple_golden.json") 84 if err != nil { 85 t.Fatalf("JSON files differ:\n%s", err) 86 } 87 88 c = vgop.NewJSON() 89 got, err := os.ReadFile("testdata/simple.json") 90 if err != nil { 91 t.Fatalf("could not read-back JSON file: %+v", err) 92 } 93 dec := json.NewDecoder(bytes.NewReader(got)) 94 err = dec.Decode(c) 95 if err != nil { 96 t.Fatalf("could not decode JSON canvas: %+v", err) 97 } 98 99 bak := new(bytes.Buffer) 100 enc = json.NewEncoder(bak) 101 enc.SetIndent("", " ") 102 103 err = enc.Encode(c) 104 if err != nil { 105 t.Fatalf("could not re-encode JSON canvas: %+v", err) 106 } 107 108 if got, want := bak.String(), string(got); got != want { 109 o := diff.Format(got, want) 110 t.Fatalf("JSON roundtrip failed:\n%s", o) 111 } 112 113 defer os.Remove("testdata/simple.json") 114 } 115 116 func TestSaveJSON(t *testing.T) { 117 p := hplot.New() 118 p.Title.Text = "Title" 119 p.X.Min = -1 120 p.X.Max = +1 121 p.X.Label.Text = "X" 122 p.Y.Min = -10 123 p.Y.Max = +10 124 p.Y.Label.Text = "Y" 125 126 err := hplot.Save(p, 10*vg.Centimeter, 20*vg.Centimeter, "testdata/plot.json") 127 if err != nil { 128 t.Fatalf("could not save plot to JSON: %+v", err) 129 } 130 131 err = diff.Files("testdata/plot.json", "testdata/plot_golden.json") 132 if err != nil { 133 fatalf := t.Fatalf 134 if runtime.GOOS == "darwin" { 135 // ignore errors for darwin and mac-silicon 136 fatalf = t.Logf 137 } 138 fatalf("JSON files differ:\n%s", err) 139 } 140 141 defer os.Remove("testdata/plot.json") 142 }