Skip to content

Commit

Permalink
Compare images by pixels instead of bytes (#208)
Browse files Browse the repository at this point in the history
* Compare test images pixel-by-pixel and ignore colours

Signed-off-by: Eamonn Mansour <[email protected]>

* Update comment and black RGBA value

Signed-off-by: Eamonn Mansour <[email protected]>

* Empty commit to kick off build

Signed-off-by: Eamonn Mansour <[email protected]>

---------

Signed-off-by: Eamonn Mansour <[email protected]>
  • Loading branch information
eamansour authored Feb 5, 2024
1 parent f98328d commit 0c7a34b
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 39 deletions.
79 changes: 54 additions & 25 deletions pkg/images/imageExpander_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
package images

import (
"bytes"
"image"
"image/color"
"image/png"
"log"
"os"
"runtime"
Expand All @@ -16,6 +20,10 @@ import (
"github.com/stretchr/testify/assert"
)

var (
BLACK = color.RGBA{0, 0, 0, 255}
)

func TestCanCalculateTargetPathsOk(t *testing.T) {
fs := files.NewMockFileSystem()
embeddedFs := embedded.NewMockReadOnlyFileSystem()
Expand Down Expand Up @@ -154,36 +162,57 @@ func compareImage(t *testing.T, renderedImageToCompare []byte, compareFolderPath
func compareTwoImages(t *testing.T, renderedContents []byte, expectedContents []byte) (bool, error) {
var isSame bool = true
var err error
renderedImageLength := len(renderedContents)
expectedImageLength := len(expectedContents)
if renderedImageLength != expectedImageLength {
assert.Fail(t, "error", "rendered contents length %v is different to the expected contents %v", renderedImageLength, expectedImageLength)
isSame = false
} else {

for i, valueGotBack := range renderedContents {
valueExpected := expectedContents[i]

if valueGotBack != valueExpected {
isSame = false
assert.Fail(t, "error", "rendered image byte %d differs from expected image byte %d", i, i)
break
var renderedImage image.Image
var expectedImage image.Image

renderedImage, err = png.Decode(bytes.NewReader(renderedContents))
if err == nil {
expectedImage, err = png.Decode(bytes.NewReader(expectedContents))

renderedImageBounds := renderedImage.Bounds()
expectedImageBounds := expectedImage.Bounds()

// Make sure the rendered image is the same size as the expected image
if renderedImageBounds == expectedImageBounds {
for column := expectedImage.Bounds().Min.Y; column < expectedImage.Bounds().Max.Y; column++ {
for row := expectedImage.Bounds().Min.X; row < expectedImage.Bounds().Max.X; row++ {
expectedPixelColor := expectedImage.At(column, row)
renderedPixelColor := renderedImage.At(column, row)

// We're ignoring colors because some pixels may have slight differences in RGB values, which
// causes tests to fail. Whenever the expected pixel is black, the rendered pixel should also
// be black, and when the expected pixel is a color, the rendered pixel should also be a color.
if (expectedPixelColor == BLACK && renderedPixelColor != BLACK) ||
(expectedPixelColor != BLACK && renderedPixelColor == BLACK) {
assert.Fail(t, "error", "rendered RGBA value %v does not match expected RGBA value %v at (x: %d, y: %d)", renderedPixelColor, expectedPixelColor, column, row)
isSame = false
break
}
}
if !isSame {
break
}
}
} else {
assert.Fail(t, "error", "rendered image bounds %v are different to expected image bounds %v", renderedImageBounds, expectedImageBounds)
isSame = false
}
}

if isSame {
log.Printf("Rendered file and stored file to compare against were exactly the same.\n")
} else {
// Files don't match, so save the file we got for manual inspection.
// If the user wants, they can copy this file into the project as expected test data.
var renderedFile *os.File
if isSame {
log.Printf("Rendered file and stored file to compare against were exactly the same.\n")
} else {
// Files don't match, so save the file we got for manual inspection.
// If the user wants, they can copy this file into the project as expected test data.
var renderedFile *os.File

renderedFile, err = os.CreateTemp("", "rendered-image-*.png")
defer renderedFile.Close()
renderedFile.Write(renderedContents)
renderedFile, err = os.CreateTemp("", "rendered-image-*.png")
if err == nil {
defer renderedFile.Close()
renderedFile.Write(renderedContents)

log.Printf("A copy of the rendered file has been saved to %s for manual inspection if required.\n", renderedFile.Name())
log.Printf("A copy of the rendered file has been saved to %s for manual inspection if required.\n", renderedFile.Name())
}
}
}

return isSame, err
Expand Down
14 changes: 0 additions & 14 deletions pkg/images/imageRenderer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,6 @@ func assertTerminalImageMatchesExpectedSnapshot(t *testing.T, actualImageBytes [
compareImage(t, actualImageBytes, "./testdata/renderedimages/images-to-compare", t.Name()+".png")
}

func writeRenderedImageToTempDir(t *testing.T, fs files.FileSystem, actualImageBytes []byte) {
outputDirectory, err := fs.MkTempDir()
filePath := filepath.Join(outputDirectory, t.Name()+".png")
if err == nil {
err = fs.WriteBinaryFile(filePath, actualImageBytes)
}

if err != nil {
t.Log("Failed to write the rendered image to a temporary directory")
} else {
fmt.Printf("Rendered image written to: %s", filePath)
}
}

func createTextField(row int, column int, text string, textColor string) TerminalField {
fieldContents := FieldContents{Text: text}

Expand Down

0 comments on commit 0c7a34b

Please sign in to comment.