oficina / sheets Public

Clone
git clone https://amadan.net/oficina/sheets

Plain git — no account needed to clone.

Download

Download this file

1package xlsx
2
3import (
4 "math"
5 "testing"
6)
7
8// The OKLCH round trip only needs to be good enough that snapping a hex
9// to hue/chroma and back doesn't visibly drift — FillHex, not this
10// conversion, is what actually drives lossless export (colors.go's own
11// doc comment). A few ULP of float error is fine; a wrong channel is not.
12func TestHexOKLCHRoundTrip(t *testing.T) {
13 cases := []string{"FF00B050", "FFFF0000", "FF0000FF", "FFFFFFFF", "FF000000", "FF808080"}
14 for _, hex := range cases {
15 hue, chroma, err := hexToOKLCH(hex)
16 if err != nil {
17 t.Fatalf("hexToOKLCH(%s): %v", hex, err)
18 }
19 got := oklchToHex2(hue, chroma, hex)
20 r1, g1, b1, _ := parseHexRGB(hex)
21 r2, g2, b2, _ := parseHexRGB(got)
22 if diff(r1, r2) > 2 || diff(g1, g2) > 2 || diff(b1, b2) > 2 {
23 t.Errorf("%s round-tripped to %s (hue=%.2f chroma=%.4f), channels drifted more than 2/255", hex, got, hue, chroma)
24 }
25 }
26}
27
28// oklchToHex2 mirrors oklchToHex but at the SOURCE lightness rather than
29// defaultFillLightness, isolating the hue/chroma conversion from the
30// lightness-loss that's expected (and documented) when re-deriving a hex
31// from a lightness-free intent.
32func oklchToHex2(hue, chroma float64, srcHex string) string {
33 r, g, b, _ := parseHexRGB(srcHex)
34 l, _, _ := srgbToOKLCH(r, g, b)
35 rr, gg, bb := oklchToSRGB(l, chroma, hue)
36 return argbHex(rr, gg, bb)
37}
38
39func diff(a, b float64) float64 { return math.Abs(a - b) }
40
41func TestParseHexRGBAcceptsSixAndEightChar(t *testing.T) {
42 r, g, b, err := parseHexRGB("FF00B050")
43 if err != nil || r != 0 || g != 176 || b != 80 {
44 t.Fatalf("8-char parse = %v %v %v %v", r, g, b, err)
45 }
46 r2, g2, b2, err := parseHexRGB("00B050")
47 if err != nil || r2 != r || g2 != g || b2 != b {
48 t.Fatalf("6-char parse mismatch: %v %v %v %v", r2, g2, b2, err)
49 }
50}
51
52func TestParseHexRGBRejectsGarbage(t *testing.T) {
53 if _, _, _, err := parseHexRGB("not-a-color"); err == nil {
54 t.Fatal("want error for invalid hex")
55 }
56 if _, _, _, err := parseHexRGB("ABCD"); err == nil {
57 t.Fatal("want error for wrong-length hex")
58 }
59}
60
61func TestArgbHexAlwaysOpaqueEightChar(t *testing.T) {
62 h := argbHex(0, 176, 80)
63 if h != "FF00B050" {
64 t.Fatalf("argbHex(0,176,80) = %s, want FF00B050", h)
65 }
66}
67