File: palette_test.go

package info (click to toggle)
golang-github-charmbracelet-x 0.0~git20251028.0cf22f8%2Bds-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,940 kB
  • sloc: sh: 124; makefile: 5
file content (122 lines) | stat: -rw-r--r-- 3,349 bytes parent folder | download
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
113
114
115
116
117
118
119
120
121
122
package sixel

import (
	"image"
	"image/color"
	"slices"
	"testing"
)

type testCase struct {
	maxColors       int
	expectedPalette []sixelColor
}

func TestPaletteCreationRedGreen(t *testing.T) {
	redGreen := image.NewRGBA(image.Rect(0, 0, 2, 2))
	redGreen.Set(0, 0, color.RGBA{255, 0, 0, 255})
	redGreen.Set(0, 1, color.RGBA{128, 0, 0, 255})
	redGreen.Set(1, 0, color.RGBA{0, 255, 0, 255})
	redGreen.Set(1, 1, color.RGBA{0, 128, 0, 255})

	testCases := map[string]testCase{
		"way too many colors": {
			maxColors: 16,
			expectedPalette: []sixelColor{
				{100, 0, 0, 100},
				{50, 0, 0, 100},
				{0, 100, 0, 100},
				{0, 50, 0, 100},
			},
		},
		"just the right number of colors": {
			maxColors: 4,
			expectedPalette: []sixelColor{
				{100, 0, 0, 100},
				{50, 0, 0, 100},
				{0, 100, 0, 100},
				{0, 50, 0, 100},
			},
		},
		"color reduction": {
			maxColors: 2,
			expectedPalette: []sixelColor{
				{75, 0, 0, 100},
				{0, 75, 0, 100},
			},
		},
	}

	runTests(t, redGreen, testCases)
}

func TestPaletteWithSemiTransparency(t *testing.T) {
	blueAlpha := image.NewRGBA(image.Rect(0, 0, 2, 2))
	blueAlpha.Set(0, 0, color.RGBA{0, 0, 255, 255})
	blueAlpha.Set(0, 1, color.RGBA{0, 0, 128, 255})
	blueAlpha.Set(1, 0, color.RGBA{0, 0, 255, 128})
	blueAlpha.Set(1, 1, color.RGBA{0, 0, 255, 0})

	testCases := map[string]testCase{
		"just the right number of colors": {
			maxColors: 4,
			expectedPalette: []sixelColor{
				{0, 0, 100, 100},
				{0, 0, 50, 100},
				{0, 0, 100, 50},
				{0, 0, 100, 0},
			},
		},
		"color reduction": {
			maxColors: 2,
			expectedPalette: []sixelColor{
				{0, 0, 75, 100},
				{0, 0, 100, 25},
			},
		},
	}
	runTests(t, blueAlpha, testCases)
}

func runTests(t *testing.T, img image.Image, testCases map[string]testCase) {
	for testName, test := range testCases {
		t.Run(testName, func(t *testing.T) {
			palette := newSixelPalette(img, test.maxColors)
			if len(palette.PaletteColors) != len(test.expectedPalette) {
				t.Errorf("Expected colors %+v in palette, but got %+v", test.expectedPalette, palette.PaletteColors)
				return
			}

			for _, c := range test.expectedPalette {
				var foundColor bool
				if slices.Contains(palette.PaletteColors, c) {
					foundColor = true
				}

				if !foundColor {
					t.Errorf("Expected colors %+v in palette, but got %+v", test.expectedPalette, palette.PaletteColors)
					return
				}
			}

			for lookupRawColor, lookupPaletteColor := range palette.colorConvert {
				paletteIndex, inReverseLookup := palette.paletteIndexes[lookupRawColor]
				if !inReverseLookup {
					t.Errorf("Color %+v maps to color %+v in the colorConvert map, but %+v is does not have a corresponding palette index.", lookupRawColor, lookupPaletteColor, lookupPaletteColor)
					return
				}

				if paletteIndex >= len(palette.PaletteColors) {
					t.Errorf("Image color %+v maps to palette index %d, but there are only %d palette colors.", lookupRawColor, paletteIndex, len(palette.PaletteColors))
					return
				}

				colorFromPalette := palette.PaletteColors[paletteIndex]
				if colorFromPalette != lookupPaletteColor {
					t.Errorf("Image color %+v maps to palette color %+v and palette index %d, but palette index %d is actually palette color %+v", lookupRawColor, lookupPaletteColor, paletteIndex, paletteIndex, colorFromPalette)
					return
				}
			}
		})
	}
}