color/internal/helper/model.go

93 lines
2.6 KiB
Go

package helper
import (
_color "image/color"
)
func Model[C _color.Color](fromColor func(_color.Color) C) _color.Model {
return _color.ModelFunc(func(c _color.Color) _color.Color {
return fromColor(c)
})
}
// Interface that the colours used in this package are expected to implement.
type Color interface {
comparable
_color.Color
NRGBA() (r, g, b, a uint32)
NLRGBA() (r, g, b, a float64)
NXYZA() (x, y, z, a float64)
NOkLabA() (lightness, chromaA, chromaB, a float64)
}
type ConvertTest[C Color] struct {
Name string
In _color.Color
Out C
}
func TestModel[T tester[T], C Color](t T, color, alpha bool, m _color.Model, eq func(c0, c1 C) bool, extra []ConvertTest[C]) {
t.Run("legal colours", func(t T) {
for wantRGBA := range Enum(color, alpha, true) {
_gotC := m.Convert(wantRGBA)
gotC, ok := _gotC.(C)
if !ok {
t.Errorf("model.Convert(%#+v) returned %T, expected %T", wantRGBA, _gotC, gotC)
return
}
r, g, b, a := gotC.RGBA()
gotRGBA := _color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
if gotRGBA != wantRGBA {
t.Errorf("%#+v.RGBA() = %v, want %v", gotC, gotRGBA, wantRGBA)
return
}
wantNRGBA := _color.NRGBA64Model.Convert(wantRGBA)
r, g, b, a = gotC.NRGBA()
gotNRGBA := _color.NRGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
if gotNRGBA != wantNRGBA {
t.Errorf("%#+v.NRGBA() = %v, want %v", gotC, gotNRGBA, wantNRGBA)
return
}
wantNLRGBA := collect4(NRGBAtoNLRGBA(r, g, b, a))
if gotNLRGBA := collect4(gotC.NLRGBA()); !EqFloat64SliceFuzzy(gotNLRGBA[:], wantNLRGBA[:]) {
t.Errorf("%#+v.NLRGBA() = %v, want %v", gotC, gotNLRGBA, wantNLRGBA)
return
}
var wantNXYZA [4]float64
wantNXYZA[0], wantNXYZA[1], wantNXYZA[2] = LRGBtoXYZ(wantNLRGBA[0], wantNLRGBA[1], wantNLRGBA[2])
wantNXYZA[3] = wantNLRGBA[3]
if gotNXYZA := collect4(gotC.NXYZA()); !EqFloat64SliceFuzzy(gotNXYZA[:], wantNXYZA[:]) {
t.Errorf("%#+v.NXYZA() = %v want %v", gotC, gotNXYZA, wantNXYZA)
return
}
var wantNOkLabA [4]float64
wantNOkLabA[0], wantNOkLabA[1], wantNOkLabA[2] = LMStoOkLab(LRGBtoLMS(wantNLRGBA[0], wantNLRGBA[1], wantNLRGBA[2]))
wantNOkLabA[3] = wantNLRGBA[3]
if gotNOkLabA := collect4(gotC.NOkLabA()); !EqFloat64SliceFuzzy(gotNOkLabA[:], wantNOkLabA[:]) {
t.Errorf("%#+v.NOkLabA()[:3] = %v want %v", gotC, gotNOkLabA[:], wantNOkLabA[:])
return
}
}
})
for _, tt := range extra {
t.Run(tt.Name, func(t T) {
gotC := m.Convert(tt.In).(C)
if !eq(gotC, tt.Out) {
t.Errorf("model.Convert(%#+v) = %#+v, want %#+v", tt.In, gotC, tt.Out)
return
}
})
}
}