Skip to content

Commit 1a42e0e

Browse files
committed
Add tests and repro cases
1 parent ca94122 commit 1a42e0e

File tree

4 files changed

+107
-3
lines changed

4 files changed

+107
-3
lines changed

paparazzi/src/main/java/app/cash/paparazzi/internal/OffByTwo.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ internal object OffByTwo : Differ {
4949
continue
5050
}
5151

52+
val deltaA = (actualRgb and -0x1000000).ushr(24) - (expectedRgb and -0x1000000).ushr(24)
5253
val deltaR = (actualRgb and 0xFF0000).ushr(16) - (expectedRgb and 0xFF0000).ushr(16)
5354
val deltaG = (actualRgb and 0x00FF00).ushr(8) - (expectedRgb and 0x00FF00).ushr(8)
5455
val deltaB = (actualRgb and 0x0000FF) - (expectedRgb and 0x0000FF)
@@ -60,7 +61,8 @@ internal object OffByTwo : Differ {
6061
((expectedRgb and -0x1000000).ushr(24) + (actualRgb and -0x1000000).ushr(24)) / 2 shl 24
6162
val newRGB = avgAlpha or (newR shl 16) or (newG shl 8) or newB
6263

63-
if (abs(deltaR) <= 2 && abs(deltaG) <= 2 && abs(deltaB) <= 2) {
64+
if (abs(deltaR) <= 2 && abs(deltaG) <= 2 && abs(deltaB) <= 2 //* && abs(deltaA) <= 2 *//
65+
) {
6466
similarPixels++
6567
deltaImage.setRGB(expectedWidth + x, y, 0xFF0000FF.toInt())
6668
continue
@@ -84,7 +86,13 @@ internal object OffByTwo : Differ {
8486

8587
// 3 different colors, 256 color levels
8688
val total = actualHeight.toLong() * actualWidth.toLong() * 3L * 256L
87-
val percentDifference = (delta * 100 / total.toDouble()).toFloat()
89+
var percentDifference = (delta * 100 / total.toDouble()).toFloat()
90+
91+
// If the delta diff is all black pixels, the computed difference is 0, but there are still
92+
// different pixels. We can fallback to the amount of different pixels to less precise difference to ensure difference is reported.
93+
if (differentPixels > 0 && percentDifference == 0f) {
94+
percentDifference = differentPixels * 100 / (actualWidth * actualHeight.toDouble()).toFloat()
95+
}
8896

8997
return if (differentPixels > 0) {
9098
DiffResult.Different(

paparazzi/src/main/java/app/cash/paparazzi/internal/PixelPerfect.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,13 @@ internal object PixelPerfect : Differ {
7878

7979
// 3 different colors, 256 color levels
8080
val total = actualHeight.toLong() * actualWidth.toLong() * 3L * 256L
81-
val percentDifference = (delta * 100 / total.toDouble()).toFloat()
81+
var percentDifference = (delta * 100 / total.toDouble()).toFloat()
82+
83+
// If the delta diff is all black pixels, the computed difference is 0, but there are still
84+
// different pixels. We can fallback to the amount of different pixels to less precise difference to ensure difference is reported.
85+
// if (differentPixels > 0 && percentDifference == 0f) {
86+
// percentDifference = differentPixels * 100 / (actualWidth * actualHeight.toDouble()).toFloat()
87+
// }
8288

8389
return if (percentDifference == 0f) {
8490
DiffResult.Identical(delta = deltaImage)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package app.cash.paparazzi.internal
2+
3+
import com.google.common.truth.Truth.assertThat
4+
import org.junit.Test
5+
import java.awt.image.BufferedImage
6+
import java.awt.image.BufferedImage.TYPE_INT_ARGB
7+
8+
class OffByTwoTest {
9+
@Test
10+
fun `compare identical images`() {
11+
val expected = BufferedImage(1, 1, TYPE_INT_ARGB)
12+
val actual = BufferedImage(1, 1, TYPE_INT_ARGB)
13+
val result = OffByTwo.compare(expected, actual)
14+
assertThat(result).isInstanceOf(Differ.DiffResult.Identical::class.java)
15+
}
16+
17+
@Test
18+
fun `compare similar images`() {
19+
val expected = BufferedImage(1, 1, TYPE_INT_ARGB)
20+
val actual = BufferedImage(1, 1, TYPE_INT_ARGB)
21+
expected.setRGB(0, 0, 0xFFFFFFFE.toInt())
22+
actual.setRGB(0, 0, 0xFFFFFFFF.toInt())
23+
val result = OffByTwo.compare(expected, actual)
24+
assertThat(result).isInstanceOf(Differ.DiffResult.Similar::class.java)
25+
}
26+
27+
@Test
28+
fun `compare similar images using black actual and alpha expected`() {
29+
val expected = BufferedImage(1, 1, TYPE_INT_ARGB)
30+
val actual = BufferedImage(1, 1, TYPE_INT_ARGB)
31+
expected.setRGB(0, 0, 0x00000000.toInt())
32+
actual.setRGB(0, 0, 0xFF000000.toInt())
33+
val result = OffByTwo.compare(expected, actual)
34+
assertThat(result).isInstanceOf(Differ.DiffResult.Similar::class.java)
35+
}
36+
37+
@Test
38+
fun `compare different images`() {
39+
val expected = BufferedImage(1, 1, TYPE_INT_ARGB)
40+
val actual = BufferedImage(1, 1, TYPE_INT_ARGB)
41+
actual.setRGB(0, 0, 0xFFFFFFFF.toInt())
42+
val result = OffByTwo.compare(expected, actual)
43+
assertThat(result).isInstanceOf(Differ.DiffResult.Different::class.java)
44+
}
45+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package app.cash.paparazzi.internal
2+
3+
import com.google.common.truth.Truth.assertThat
4+
import org.junit.Test
5+
import java.awt.image.BufferedImage
6+
import java.awt.image.BufferedImage.TYPE_INT_ARGB
7+
8+
class PixelPerfectTest {
9+
@Test
10+
fun `compare identical images`() {
11+
val expected = BufferedImage(1, 1, TYPE_INT_ARGB)
12+
val actual = BufferedImage(1, 1, TYPE_INT_ARGB)
13+
val result = PixelPerfect.compare(expected, actual)
14+
assertThat(result).isInstanceOf(Differ.DiffResult.Identical::class.java)
15+
}
16+
17+
@Test
18+
fun `compare similar images`() {
19+
val expected = BufferedImage(1, 1, TYPE_INT_ARGB)
20+
val actual = BufferedImage(1, 1, TYPE_INT_ARGB)
21+
expected.setRGB(0, 0, 0xFFFFFFFE.toInt())
22+
actual.setRGB(0, 0, 0xFFFFFFFF.toInt())
23+
val result = PixelPerfect.compare(expected, actual)
24+
assertThat(result).isInstanceOf(Differ.DiffResult.Different::class.java)
25+
}
26+
27+
@Test
28+
fun `compare similar images using black actual and alpha expected`() {
29+
val expected = BufferedImage(1, 1, TYPE_INT_ARGB)
30+
val actual = BufferedImage(1, 1, TYPE_INT_ARGB)
31+
expected.setRGB(0, 0, 0x00000000.toInt())
32+
actual.setRGB(0, 0, 0xFF000000.toInt())
33+
val result = PixelPerfect.compare(expected, actual)
34+
assertThat(result).isInstanceOf(Differ.DiffResult.Identical::class.java)
35+
}
36+
37+
@Test
38+
fun `compare different images`() {
39+
val expected = BufferedImage(1, 1, TYPE_INT_ARGB)
40+
val actual = BufferedImage(1, 1, TYPE_INT_ARGB)
41+
actual.setRGB(0, 0, 0xFFFFFFFF.toInt())
42+
val result = PixelPerfect.compare(expected, actual)
43+
assertThat(result).isInstanceOf(Differ.DiffResult.Different::class.java)
44+
}
45+
}

0 commit comments

Comments
 (0)