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, midpoint, func(c0, c1 color.RGBA) float64 { return 1 }, color.RGBAModel) }) mt.run("NaN distance", func(t *mockTest) { TestDistance(t, 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, 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, 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, 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, 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() }