File: hsluv_test.go

package info (click to toggle)
golang-github-lucasb-eyer-go-colorful 1.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bookworm-backports, forky, sid, trixie
  • size: 2,460 kB
  • sloc: makefile: 11
file content (143 lines) | stat: -rw-r--r-- 4,962 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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package colorful

// Source: https://github.com/hsluv/hsluv-go
// Under MIT License
// Modified so that Saturation and Luminance are in [0..1] instead of [0..100],
// and so that it works with this library in general.

import (
	"encoding/json"
	"fmt"
	"math"
	"os"
	"testing"
)

type mapping map[string]values

type values struct {
	Rgb   [3]float64
	Xyz   [3]float64
	Luv   [3]float64
	Lch   [3]float64
	Hsluv [3]float64
	Hpluv [3]float64
}

func pack(a, b, c float64) [3]float64 {
	return [3]float64{a, b, c}
}

func unpack(tuple [3]float64) (float64, float64, float64) {
	return tuple[0], tuple[1], tuple[2]
}

func fromHex(s string) Color {
	c, _ := Hex(s)
	return c
}

// const delta = 0.00000001
const hsluvTestDelta = 0.0000000001 // Two more zeros than the original delta, because values are divided by 100

func compareTuple(t *testing.T, result, expected [3]float64, method string, hex string) {
	var err bool
	var errs [3]bool
	for i := 0; i < 3; i++ {
		if math.Abs(result[i]-expected[i]) > hsluvTestDelta {
			err = true
			errs[i] = true
		}
	}
	if err {
		resultOutput := "["
		for i := 0; i < 3; i++ {
			resultOutput += fmt.Sprintf("%f", result[i])
			if errs[i] {
				resultOutput += " *"
			}
			if i < 2 {
				resultOutput += ", "
			}
		}
		resultOutput += "]"
		t.Errorf("result: %s expected: %v, testing %s with test case %s", resultOutput, expected, method, hex)
	}
}

func compareHex(t *testing.T, result, expected string, method string, hex string) {
	if result != expected {
		t.Errorf("result: %v expected: %v, testing %s with test case %s", result, expected, method, hex)
	}
}

func TestHSLuv(t *testing.T) {
	snapshotFile, err := os.Open("hsluv-snapshot-rev4.json")
	if err != nil {
		t.Fatal(err)
	}
	defer snapshotFile.Close()

	jsonParser := json.NewDecoder(snapshotFile)
	snapshot := make(mapping)
	if err = jsonParser.Decode(&snapshot); err != nil {
		t.Fatal(err)
	}

	for hex, colorValues := range snapshot {
		// tests for public methods
		if testing.Verbose() {
			t.Logf("Testing public methods for test case %s", hex)
		}

		// Adjust color values to be in the ranges this library uses
		colorValues.Hsluv[1] /= 100.0
		colorValues.Hsluv[2] /= 100.0
		colorValues.Hpluv[1] /= 100.0
		colorValues.Hpluv[2] /= 100.0

		compareHex(t, HSLuv(unpack(colorValues.Hsluv)).Hex(), hex, "HsluvToHex", hex)
		compareTuple(t, pack(HSLuv(unpack(colorValues.Hsluv)).values()), colorValues.Rgb, "HsluvToRGB", hex)
		compareTuple(t, pack(fromHex(hex).HSLuv()), colorValues.Hsluv, "HsluvFromHex", hex)
		compareTuple(t, pack(Color{colorValues.Rgb[0], colorValues.Rgb[1], colorValues.Rgb[2]}.HSLuv()), colorValues.Hsluv, "HsluvFromRGB", hex)
		compareHex(t, HPLuv(unpack(colorValues.Hpluv)).Hex(), hex, "HpluvToHex", hex)
		compareTuple(t, pack(HPLuv(unpack(colorValues.Hpluv)).values()), colorValues.Rgb, "HpluvToRGB", hex)
		compareTuple(t, pack(fromHex(hex).HPLuv()), colorValues.Hpluv, "HpluvFromHex", hex)
		compareTuple(t, pack(Color{colorValues.Rgb[0], colorValues.Rgb[1], colorValues.Rgb[2]}.HPLuv()), colorValues.Hpluv, "HpluvFromRGB", hex)

		if !testing.Short() {
			// internal tests
			if testing.Verbose() {
				t.Logf("Testing internal methods for test case %s", hex)
			}

			// Adjust color values to be in the ranges this library uses
			colorValues.Lch[0] /= 100.0
			colorValues.Lch[1] /= 100.0
			colorValues.Luv[0] /= 100.0
			colorValues.Luv[1] /= 100.0
			colorValues.Luv[2] /= 100.0

			compareTuple(t, pack(LuvLChWhiteRef(
				colorValues.Lch[0], colorValues.Lch[1], colorValues.Lch[2], hSLuvD65,
			).values()), colorValues.Rgb, "convLchRgb", hex)
			compareTuple(t, pack(Color{
				colorValues.Rgb[0], colorValues.Rgb[1], colorValues.Rgb[2],
			}.LuvLChWhiteRef(hSLuvD65)), colorValues.Lch, "convRgbLch", hex)
			compareTuple(t, pack(XyzToLuvWhiteRef(
				colorValues.Xyz[0], colorValues.Xyz[1], colorValues.Xyz[2], hSLuvD65,
			)), colorValues.Luv, "convXyzLuv", hex)
			compareTuple(t, pack(LuvToXyzWhiteRef(
				colorValues.Luv[0], colorValues.Luv[1], colorValues.Luv[2], hSLuvD65,
			)), colorValues.Xyz, "convLuvXyz", hex)
			compareTuple(t, pack(LuvToLuvLCh(unpack(colorValues.Luv))), colorValues.Lch, "convLuvLch", hex)
			compareTuple(t, pack(LuvLChToLuv(unpack(colorValues.Lch))), colorValues.Luv, "convLchLuv", hex)
			compareTuple(t, pack(HSLuvToLuvLCh(unpack(colorValues.Hsluv))), colorValues.Lch, "convHsluvLch", hex)
			compareTuple(t, pack(LuvLChToHSLuv(unpack(colorValues.Lch))), colorValues.Hsluv, "convLchHsluv", hex)
			compareTuple(t, pack(HPLuvToLuvLCh(unpack(colorValues.Hpluv))), colorValues.Lch, "convHpluvLch", hex)
			compareTuple(t, pack(LuvLChToHPLuv(unpack(colorValues.Lch))), colorValues.Hpluv, "convLchHpluv", hex)
			compareTuple(t, pack(LinearRgb(XyzToLinearRgb(unpack(colorValues.Xyz))).values()), colorValues.Rgb, "convXyzRgb", hex)
			compareTuple(t, pack(Color{colorValues.Rgb[0], colorValues.Rgb[1], colorValues.Rgb[2]}.Xyz()), colorValues.Xyz, "convRgbXyz", hex)
		}
	}
}