-
Notifications
You must be signed in to change notification settings - Fork 104
/
testutil.go
112 lines (94 loc) · 2.62 KB
/
testutil.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package render
import (
"fmt"
"image"
"image/color"
"strings"
"github.com/tidbyt/gg"
)
var DefaultPalette = map[string]color.RGBA{
"r": {0xff, 0, 0, 0xff},
"g": {0, 0xff, 0, 0xff},
"b": {0, 0, 0xff, 0xff},
"w": {0xff, 0xff, 0xff, 0xff},
".": {0, 0, 0, 0},
"x": {0, 0, 0, 0xff},
}
type ImageChecker struct {
Palette map[string]color.RGBA
}
func (ic ImageChecker) Check(expected []string, actual image.Image) error {
var runes [][]string
for _, str := range expected {
runes = append(runes, strings.Split(str, ""))
}
if len(expected) != actual.Bounds().Dy() {
ic.PrintDiff(expected, actual)
return fmt.Errorf("expected %d rows, found %d", len(expected), actual.Bounds().Dy())
}
for y := 0; y < actual.Bounds().Dy(); y++ {
if len(runes[y]) != actual.Bounds().Dx() {
ic.PrintDiff(expected, actual)
return fmt.Errorf(
"row %d: expected %d columns, found %d",
y, len(runes[0]), actual.Bounds().Dx())
}
for x := 0; x < actual.Bounds().Dx(); x++ {
var actualColorRGBA color.RGBA
actualColor := actual.At(x, y)
if nrgba, ok := actualColor.(color.NRGBA); ok {
r, g, b, a := nrgba.RGBA()
actualColorRGBA = color.RGBA{uint8(r), uint8(g), uint8(b), uint8(a)}
} else {
actualColorRGBA = actualColor.(color.RGBA)
}
if actualColorRGBA != ic.Palette[string(runes[y][x])] {
ic.PrintDiff(expected, actual)
return fmt.Errorf("color differs at %d,%d", x, y)
}
}
}
return nil
}
func (ic ImageChecker) PrintDiff(expected []string, actual image.Image) {
fmt.Println("EXPECTED")
for _, row := range expected {
fmt.Println(row)
}
fmt.Println("ACTUAL")
ic.PrintImage(actual)
}
func (ic ImageChecker) PrintImage(im image.Image) {
color2Ascii := map[color.RGBA]string{}
for t, rgba := range ic.Palette {
color2Ascii[rgba] = t
}
for y := 0; y < im.Bounds().Dy(); y++ {
for x := 0; x < im.Bounds().Dx(); x++ {
ascii := color2Ascii[im.At(x, y).(color.RGBA)]
if ascii == "" {
ascii = "?"
}
fmt.Printf(ascii)
}
fmt.Printf("\n")
}
}
func printExpectedActual(expected []string, actual image.Image) {
ic := ImageChecker{Palette: DefaultPalette}
ic.PrintDiff(expected, actual)
}
func checkImage(expected []string, actual image.Image) error {
ic := ImageChecker{Palette: DefaultPalette}
return ic.Check(expected, actual)
}
func CheckImage(expected []string, actual image.Image) error {
ic := ImageChecker{Palette: DefaultPalette}
return ic.Check(expected, actual)
}
func PaintWidget(w Widget, bounds image.Rectangle, frameIdx int) image.Image {
pb := w.PaintBounds(bounds, frameIdx)
dc := gg.NewContext(pb.Dx(), pb.Dy())
w.Paint(dc, bounds, frameIdx)
return dc.Image()
}