117 lines
3.1 KiB
Go
117 lines
3.1 KiB
Go
package helper
|
|
|
|
import (
|
|
"cmp"
|
|
"image/color"
|
|
"math"
|
|
"testing"
|
|
)
|
|
|
|
func TestTestDistance(t *testing.T) {
|
|
mt := mockTester{t: t}
|
|
|
|
midpoint := func(c0, c1 color.RGBA) color.RGBA {
|
|
return color.RGBA{
|
|
uint8((uint16(c0.R) + uint16(c1.R)) / 2),
|
|
uint8((uint16(c0.G) + uint16(c1.G)) / 2),
|
|
uint8((uint16(c0.B) + uint16(c1.B)) / 2),
|
|
uint8((uint16(c0.A) + uint16(c1.A)) / 2),
|
|
}
|
|
}
|
|
|
|
mt.run("non-zero distance for identical colours", func(t *mockTest) {
|
|
TestDistance(t, true, true, midpoint, func(c0, c1 color.RGBA) float64 {
|
|
return 1
|
|
}, color.RGBAModel)
|
|
})
|
|
|
|
mt.run("NaN distance", func(t *mockTest) {
|
|
TestDistance(t, true, true, midpoint, func(c0, c1 color.RGBA) float64 {
|
|
if c0 == c1 {
|
|
return 0
|
|
}
|
|
|
|
return math.NaN()
|
|
}, color.RGBAModel)
|
|
})
|
|
|
|
mt.run("negative distance", func(t *mockTest) {
|
|
TestDistance(t, true, true, midpoint, func(c0, c1 color.RGBA) float64 {
|
|
if c0 == c1 {
|
|
return 0
|
|
}
|
|
|
|
return -1
|
|
}, color.RGBAModel)
|
|
})
|
|
|
|
mt.run("asymmetric distance", func(t *mockTest) {
|
|
TestDistance(t, true, true, midpoint, func(c0, c1 color.RGBA) float64 {
|
|
if c0 == c1 {
|
|
return 0
|
|
}
|
|
|
|
if cmp.Or(int(c0.R)-int(c1.R), int(c0.G)-int(c1.G), int(c0.B)-int(c1.B), int(c0.A)-int(c1.A)) > 0 {
|
|
return 1
|
|
}
|
|
|
|
return 2
|
|
}, color.RGBAModel)
|
|
})
|
|
|
|
mt.run("triangle inequality", func(t *mockTest) {
|
|
TestDistance(t, true, true, midpoint, func(c0, c1 color.RGBA) float64 {
|
|
dR := int(c0.R) - int(c1.R)
|
|
dG := int(c0.G) - int(c1.G)
|
|
dB := int(c0.B) - int(c1.B)
|
|
dA := int(c0.A) - int(c1.A)
|
|
|
|
d2 := float64(dR*dR + dG*dG + dB*dB + dA*dA)
|
|
|
|
return d2
|
|
}, color.RGBAModel)
|
|
})
|
|
|
|
mt.run("euclidean distance", func(t *mockTest) {
|
|
TestDistance(t, true, true, midpoint, func(c0, c1 color.RGBA) float64 {
|
|
dR := int(c0.R) - int(c1.R)
|
|
dG := int(c0.G) - int(c1.G)
|
|
dB := int(c0.B) - int(c1.B)
|
|
dA := int(c0.A) - int(c1.A)
|
|
|
|
d2 := float64(dR*dR + dG*dG + dB*dB + dA*dA)
|
|
|
|
return math.Sqrt(d2)
|
|
}, color.RGBAModel)
|
|
})
|
|
|
|
mt.expectError(
|
|
"non-zero distance for identical colours",
|
|
`Distance(color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}) = 1.000000, want 0`,
|
|
)
|
|
|
|
mt.expectError(
|
|
"NaN distance",
|
|
`Distance(color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, color.RGBA{R:0x0, G:0x0, B:0x0, A:0x55}) = NaN, want finite`,
|
|
)
|
|
|
|
mt.expectError(
|
|
"negative distance",
|
|
`Distance(color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, color.RGBA{R:0x0, G:0x0, B:0x0, A:0x55}) = -1.000000, want > 0`,
|
|
)
|
|
|
|
mt.expectError(
|
|
"asymmetric distance",
|
|
`Distance(color.RGBA{R:0x0, G:0x0, B:0x0, A:0x55}, color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}) != Distance(color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, color.RGBA{R:0x0, G:0x0, B:0x0, A:0x55}), want 2.000000 == 1.000000`,
|
|
)
|
|
|
|
mt.expectError(
|
|
"triangle inequality",
|
|
`Distance(color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, color.RGBA{R:0x0, G:0x0, B:0x0, A:0x2a})+Distance(color.RGBA{R:0x0, G:0x0, B:0x0, A:0x2a}, color.RGBA{R:0x0, G:0x0, B:0x0, A:0x55}) < Distance(color.RGBA{R:0x0, G:0x0, B:0x0, A:0x0}, color.RGBA{R:0x0, G:0x0, B:0x0, A:0x55}), want 3613.000000 >= 7225.000000`,
|
|
)
|
|
|
|
mt.expectSuccess("euclidean distance")
|
|
|
|
mt.expectAllHandled()
|
|
}
|