gonum.org/v1/gonum@v0.14.0/graph/layout/layout_test.go (about) 1 // Copyright ©2019 The Gonum 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 layout_test 6 7 import ( 8 "bytes" 9 "encoding/base64" 10 "image" 11 "image/png" 12 "os" 13 "path/filepath" 14 "strings" 15 "testing" 16 17 "gonum.org/v1/gonum/graph" 18 "gonum.org/v1/gonum/graph/internal/ordered" 19 "gonum.org/v1/gonum/graph/iterator" 20 "gonum.org/v1/plot/cmpimg" 21 ) 22 23 // orderedGraph wraps a graph.Graph ensuring consistent ordering of nodes 24 // in graph queries. Removal of this causes to tests to fail due to changes 25 // in node iteration order, but the produced graph layouts are still good. 26 type orderedGraph struct { 27 graph.Graph 28 } 29 30 func (g orderedGraph) Nodes() graph.Nodes { 31 n := graph.NodesOf(g.Graph.Nodes()) 32 ordered.ByID(n) 33 return iterator.NewOrderedNodes(n) 34 } 35 36 func (g orderedGraph) From(id int64) graph.Nodes { 37 n := graph.NodesOf(g.Graph.From(id)) 38 ordered.ByID(n) 39 return iterator.NewOrderedNodes(n) 40 } 41 42 func goldenPath(path string) string { 43 ext := filepath.Ext(path) 44 noext := strings.TrimSuffix(path, ext) 45 return noext + "_golden" + ext 46 } 47 48 func checkRenderedLayout(t *testing.T, path string) (ok bool) { 49 if *cmpimg.GenerateTestData { 50 // Recreate Golden image and exit. 51 golden := goldenPath(path) 52 _ = os.Remove(golden) 53 if err := os.Rename(path, golden); err != nil { 54 t.Fatal(err) 55 } 56 return true 57 } 58 59 // Read the images we've just generated and check them against the 60 // Golden Images. 61 got, err := os.ReadFile(path) 62 if err != nil { 63 t.Errorf("failed to read %s: %v", path, err) 64 return true 65 } 66 golden := goldenPath(path) 67 want, err := os.ReadFile(golden) 68 if err != nil { 69 t.Errorf("failed to read golden file %s: %v", golden, err) 70 return true 71 } 72 typ := filepath.Ext(path)[1:] // remove the dot in ".png" 73 ok, err = cmpimg.Equal(typ, got, want) 74 if err != nil { 75 t.Errorf("failed to compare image for %s: %v", path, err) 76 return true 77 } 78 if !ok { 79 t.Errorf("image mismatch for %s\n", path) 80 v1, _, err := image.Decode(bytes.NewReader(got)) 81 if err != nil { 82 t.Errorf("failed to decode %s: %v", path, err) 83 return false 84 } 85 v2, _, err := image.Decode(bytes.NewReader(want)) 86 if err != nil { 87 t.Errorf("failed to decode %s: %v", golden, err) 88 return false 89 } 90 91 dst := image.NewRGBA64(v1.Bounds().Union(v2.Bounds())) 92 rect := cmpimg.Diff(dst, v1, v2) 93 t.Logf("image bounds union:%+v diff bounds intersection:%+v", dst.Bounds(), rect) 94 95 var buf bytes.Buffer 96 err = png.Encode(&buf, dst) 97 if err != nil { 98 t.Errorf("failed to encode difference png: %v", err) 99 return false 100 } 101 t.Log("IMAGE:" + base64.StdEncoding.EncodeToString(buf.Bytes())) 102 } 103 return ok 104 }