Skip to content

Commit 9bf4078

Browse files
committed
DRY up with ImagesExactlyEqual helper
1 parent 2bd2f02 commit 9bf4078

File tree

3 files changed

+37
-35
lines changed

3 files changed

+37
-35
lines changed

components/camera/camera_test.go

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -258,14 +258,6 @@ func TestCameraWithProjector(t *testing.T) {
258258
test.That(t, cam2.Close(context.Background()), test.ShouldBeNil)
259259
}
260260

261-
// verifyImageEquality compares two images and verifies they are identical.
262-
func verifyImageEquality(t *testing.T, img1, img2 image.Image) {
263-
t.Helper()
264-
diff, _, err := rimage.CompareImages(img1, img2)
265-
test.That(t, err, test.ShouldBeNil)
266-
test.That(t, diff, test.ShouldEqual, 0)
267-
}
268-
269261
// verifyDecodedImage verifies that decoded image bytes match the original image.
270262
func verifyDecodedImage(t *testing.T, imgBytes []byte, mimeType string, originalImg image.Image) {
271263
t.Helper()
@@ -283,7 +275,7 @@ func verifyDecodedImage(t *testing.T, imgBytes []byte, mimeType string, original
283275
// For other formats, compare the decoded images
284276
decodedImg, err := rimage.DecodeImage(context.Background(), imgBytes, mimeType)
285277
test.That(t, err, test.ShouldBeNil)
286-
verifyImageEquality(t, decodedImg, originalImg)
278+
test.That(t, rimage.ImagesExactlyEqual(decodedImg, originalImg), test.ShouldBeTrue)
287279
}
288280

289281
func TestGetImageFromGetImages(t *testing.T) {
@@ -409,7 +401,7 @@ func TestGetImagesFromGetImage(t *testing.T) {
409401
test.That(t, images[0].SourceName, test.ShouldEqual, "")
410402
img, err := images[0].Image(context.Background())
411403
test.That(t, err, test.ShouldBeNil)
412-
verifyImageEquality(t, img, testImg)
404+
test.That(t, rimage.ImagesExactlyEqual(img, testImg), test.ShouldBeTrue)
413405
test.That(t, metadata.CapturedAt.IsZero(), test.ShouldBeFalse)
414406
test.That(t, metadata.CapturedAt.After(startTime), test.ShouldBeTrue)
415407
test.That(t, metadata.CapturedAt.Before(endTime), test.ShouldBeTrue)
@@ -453,7 +445,7 @@ func TestGetImagesFromGetImage(t *testing.T) {
453445
test.That(t, metadata.CapturedAt.Before(endTime), test.ShouldBeTrue)
454446
img, err := images[0].Image(context.Background())
455447
test.That(t, err, test.ShouldBeNil)
456-
verifyImageEquality(t, img, rgbaImg) // we should ignore the requested mime type and get back an RGBA image
448+
test.That(t, rimage.ImagesExactlyEqual(img, rgbaImg), test.ShouldBeTrue)
457449
})
458450

459451
t.Run("error case", func(t *testing.T) {
@@ -503,7 +495,7 @@ func TestImages(t *testing.T) {
503495
test.That(t, len(images), test.ShouldEqual, 1)
504496
img, err := images[0].Image(ctx)
505497
test.That(t, err, test.ShouldBeNil)
506-
verifyImageEquality(t, img, respImg)
498+
test.That(t, rimage.ImagesExactlyEqual(img, respImg), test.ShouldBeTrue)
507499
test.That(t, images[0].SourceName, test.ShouldEqual, source1Name)
508500
})
509501

@@ -592,7 +584,7 @@ func TestImages(t *testing.T) {
592584
test.That(t, imgs[0].MimeType(), test.ShouldEqual, rutils.MimeTypeRawDepth)
593585
img, err := imgs[0].Image(ctx)
594586
test.That(t, err, test.ShouldBeNil)
595-
verifyImageEquality(t, img, img2)
587+
test.That(t, rimage.ImagesExactlyEqual(img, img2), test.ShouldBeTrue)
596588
})
597589

598590
t.Run("multiple valid sources", func(t *testing.T) {
@@ -609,12 +601,12 @@ func TestImages(t *testing.T) {
609601
test.That(t, imgs[0].MimeType(), test.ShouldEqual, rutils.MimeTypeJPEG)
610602
img, err := imgs[0].Image(ctx)
611603
test.That(t, err, test.ShouldBeNil)
612-
verifyImageEquality(t, img, img3)
604+
test.That(t, rimage.ImagesExactlyEqual(img, img3), test.ShouldBeTrue)
613605

614606
test.That(t, imgs[1].MimeType(), test.ShouldEqual, rutils.MimeTypePNG)
615607
img, err = imgs[1].Image(ctx)
616608
test.That(t, err, test.ShouldBeNil)
617-
verifyImageEquality(t, img, img1)
609+
test.That(t, rimage.ImagesExactlyEqual(img, img1), test.ShouldBeTrue)
618610
})
619611

620612
t.Run("single invalid source", func(t *testing.T) {
@@ -641,7 +633,7 @@ func TestNamedImage(t *testing.T) {
641633
badBytes := []byte("trust bro i'm an image ong")
642634
sourceName := "test_source"
643635

644-
t.Run("NamedImageFromBytes", func(t *testing.T) {
636+
t.Run("NamedImageFromBytes", func(t *testing.T) {
645637
t.Run("success", func(t *testing.T) {
646638
ni, err := camera.NamedImageFromBytes(testImgPNGBytes, sourceName, rutils.MimeTypePNG)
647639
test.That(t, err, test.ShouldBeNil)
@@ -658,15 +650,15 @@ func TestNamedImage(t *testing.T) {
658650
})
659651
})
660652

661-
t.Run("NamedImageFromImage", func(t *testing.T) {
653+
t.Run("NamedImageFromImage", func(t *testing.T) {
662654
t.Run("success", func(t *testing.T) {
663655
ni, err := camera.NamedImageFromImage(testImg, sourceName, rutils.MimeTypePNG)
664656
test.That(t, err, test.ShouldBeNil)
665657
test.That(t, ni.SourceName, test.ShouldEqual, sourceName)
666658
test.That(t, ni.MimeType(), test.ShouldEqual, rutils.MimeTypePNG)
667659
img, err := ni.Image(ctx)
668660
test.That(t, err, test.ShouldBeNil)
669-
verifyImageEquality(t, img, testImg)
661+
test.That(t, rimage.ImagesExactlyEqual(img, testImg), test.ShouldBeTrue)
670662
})
671663
t.Run("error on nil image", func(t *testing.T) {
672664
_, err := camera.NamedImageFromImage(nil, sourceName, rutils.MimeTypePNG)
@@ -684,7 +676,7 @@ func TestNamedImage(t *testing.T) {
684676
test.That(t, err, test.ShouldBeNil)
685677
img, err := ni.Image(ctx)
686678
test.That(t, err, test.ShouldBeNil)
687-
verifyImageEquality(t, img, testImg)
679+
test.That(t, rimage.ImagesExactlyEqual(img, testImg), test.ShouldBeTrue)
688680

689681
// should return the same image instance
690682
img2, err := ni.Image(ctx)
@@ -699,12 +691,12 @@ func TestNamedImage(t *testing.T) {
699691
// first call should decode
700692
img, err := ni.Image(ctx)
701693
test.That(t, err, test.ShouldBeNil)
702-
verifyImageEquality(t, img, testImg)
694+
test.That(t, rimage.ImagesExactlyEqual(img, testImg), test.ShouldBeTrue)
703695

704696
// second call should return cached image
705697
img2, err := ni.Image(ctx)
706698
test.That(t, err, test.ShouldBeNil)
707-
verifyImageEquality(t, img2, testImg)
699+
test.That(t, rimage.ImagesExactlyEqual(img2, testImg), test.ShouldBeTrue)
708700
test.That(t, reflect.ValueOf(img).Pointer(), test.ShouldEqual, reflect.ValueOf(img2).Pointer())
709701
})
710702

components/camera/client_test.go

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ func TestClient(t *testing.T) {
7676
}
7777
projA = intrinsics
7878

79+
// expected source images for reuse across subtests
80+
expectedColor := rimage.NewImage(40, 50)
81+
expectedDepth := rimage.NewEmptyDepthMap(10, 20)
82+
7983
// color camera
8084
injectCamera.NextPointCloudFunc = func(ctx context.Context) (pointcloud.PointCloud, error) {
8185
return pcA, nil
@@ -96,15 +100,13 @@ func TestClient(t *testing.T) {
96100
) ([]camera.NamedImage, resource.ResponseMetadata, error) {
97101
images := []camera.NamedImage{}
98102
// one color image
99-
color := rimage.NewImage(40, 50)
100-
namedImgColor, err := camera.NamedImageFromImage(color, "color", rutils.MimeTypeRawRGBA)
103+
namedImgColor, err := camera.NamedImageFromImage(expectedColor, "color", rutils.MimeTypeRawRGBA)
101104
if err != nil {
102105
return nil, resource.ResponseMetadata{}, err
103106
}
104107
images = append(images, namedImgColor)
105108
// one depth image
106-
depth := rimage.NewEmptyDepthMap(10, 20)
107-
namedImgDepth, err := camera.NamedImageFromImage(depth, "depth", rutils.MimeTypeRawDepth)
109+
namedImgDepth, err := camera.NamedImageFromImage(expectedDepth, "depth", rutils.MimeTypeRawDepth)
108110
if err != nil {
109111
return nil, resource.ResponseMetadata{}, err
110112
}
@@ -409,13 +411,11 @@ func TestClient(t *testing.T) {
409411
filterSourceNames []string,
410412
extra map[string]interface{},
411413
) ([]camera.NamedImage, resource.ResponseMetadata, error) {
412-
color := rimage.NewImage(40, 50)
413-
namedImgColor, err := camera.NamedImageFromImage(color, "color", rutils.MimeTypeRawRGBA)
414+
namedImgColor, err := camera.NamedImageFromImage(expectedColor, "color", rutils.MimeTypeRawRGBA)
414415
if err != nil {
415416
return nil, resource.ResponseMetadata{}, err
416417
}
417-
depth := rimage.NewEmptyDepthMap(10, 20)
418-
namedImgDepth, err := camera.NamedImageFromImage(depth, "depth", rutils.MimeTypeRawDepth)
418+
namedImgDepth, err := camera.NamedImageFromImage(expectedDepth, "depth", rutils.MimeTypeRawDepth)
419419
if err != nil {
420420
return nil, resource.ResponseMetadata{}, err
421421
}
@@ -450,11 +450,13 @@ func TestClient(t *testing.T) {
450450
test.That(t, err, test.ShouldBeNil)
451451
test.That(t, colorImg.Bounds().Dx(), test.ShouldEqual, 40)
452452
test.That(t, colorImg.Bounds().Dy(), test.ShouldEqual, 50)
453+
test.That(t, rimage.ImagesExactlyEqual(colorImg, expectedColor), test.ShouldBeTrue)
453454

454455
depthImg, err := images[1].Image(ctx)
455456
test.That(t, err, test.ShouldBeNil)
456457
test.That(t, depthImg.Bounds().Dx(), test.ShouldEqual, 10)
457458
test.That(t, depthImg.Bounds().Dy(), test.ShouldEqual, 20)
459+
test.That(t, rimage.ImagesExactlyEqual(depthImg, expectedDepth), test.ShouldBeTrue)
458460
})
459461

460462
t.Run("empty and nil filters", func(t *testing.T) {
@@ -466,10 +468,12 @@ func TestClient(t *testing.T) {
466468
test.That(t, err, test.ShouldBeNil)
467469
test.That(t, colorImg.Bounds().Dx(), test.ShouldEqual, 40)
468470
test.That(t, colorImg.Bounds().Dy(), test.ShouldEqual, 50)
471+
test.That(t, rimage.ImagesExactlyEqual(colorImg, expectedColor), test.ShouldBeTrue)
469472
depthImg, err := images[1].Image(ctx)
470473
test.That(t, err, test.ShouldBeNil)
471474
test.That(t, depthImg.Bounds().Dx(), test.ShouldEqual, 10)
472475
test.That(t, depthImg.Bounds().Dy(), test.ShouldEqual, 20)
476+
test.That(t, rimage.ImagesExactlyEqual(depthImg, expectedDepth), test.ShouldBeTrue)
473477

474478
// Test nil filter
475479
images, _, err = camClient.Images(ctx, nil, nil)
@@ -479,10 +483,12 @@ func TestClient(t *testing.T) {
479483
test.That(t, err, test.ShouldBeNil)
480484
test.That(t, colorImg.Bounds().Dx(), test.ShouldEqual, 40)
481485
test.That(t, colorImg.Bounds().Dy(), test.ShouldEqual, 50)
486+
test.That(t, rimage.ImagesExactlyEqual(colorImg, expectedColor), test.ShouldBeTrue)
482487
depthImg, err = images[1].Image(ctx)
483488
test.That(t, err, test.ShouldBeNil)
484489
test.That(t, depthImg.Bounds().Dx(), test.ShouldEqual, 10)
485490
test.That(t, depthImg.Bounds().Dy(), test.ShouldEqual, 20)
491+
test.That(t, rimage.ImagesExactlyEqual(depthImg, expectedDepth), test.ShouldBeTrue)
486492
})
487493
})
488494
}
@@ -661,9 +667,7 @@ func TestClientLazyImage(t *testing.T) {
661667
test.That(t, frameLazy.RawData(), test.ShouldResemble, imgBuf.Bytes())
662668

663669
test.That(t, frameLazy.MIMEType(), test.ShouldEqual, rutils.MimeTypePNG)
664-
compVal, _, err := rimage.CompareImages(img, frame)
665-
test.That(t, err, test.ShouldBeNil)
666-
test.That(t, compVal, test.ShouldEqual, 0) // exact copy, no color conversion
670+
test.That(t, rimage.ImagesExactlyEqual(frame, img), test.ShouldBeTrue)
667671

668672
// when DecodeImageFromCamera is called without a mime type, defaults to JPEG
669673
var called bool
@@ -679,9 +683,7 @@ func TestClientLazyImage(t *testing.T) {
679683
test.That(t, frame, test.ShouldHaveSameTypeAs, &rimage.LazyEncodedImage{})
680684
frameLazy = frame.(*rimage.LazyEncodedImage)
681685
test.That(t, frameLazy.MIMEType(), test.ShouldEqual, rutils.MimeTypeJPEG)
682-
compVal, _, err = rimage.CompareImages(imgJpeg, frame)
683-
test.That(t, err, test.ShouldBeNil)
684-
test.That(t, compVal, test.ShouldEqual, 0) // exact copy, no color conversion
686+
test.That(t, rimage.ImagesExactlyEqual(frame, imgJpeg), test.ShouldBeTrue)
685687
test.That(t, called, test.ShouldBeTrue)
686688
test.That(t, conn.Close(), test.ShouldBeNil)
687689
}

rimage/compare_img.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,14 @@ func CompareImages(img1, img2 image.Image) (int, image.Image, error) {
6363
return int(math.Sqrt(float64(accumError))), resultImg, nil
6464
}
6565

66+
// ImagesExactlyEqual returns true if the two images are exactly equal pixel-for-pixel.
67+
// It uses CompareImages under the hood and treats any non-zero difference or error
68+
// (including different bounds) as not equal.
69+
func ImagesExactlyEqual(img1, img2 image.Image) bool {
70+
diff, _, err := CompareImages(img1, img2)
71+
return err == nil && diff == 0
72+
}
73+
6674
func sqDiffUInt32(x, y uint32) uint64 {
6775
d := uint64(x) - uint64(y)
6876
return d * d

0 commit comments

Comments
 (0)