-
Notifications
You must be signed in to change notification settings - Fork 210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support Paparazzi#gif with APNGs #1186
Conversation
paparazzi-gradle-plugin/src/test/projects/verify-gif/src/main/AndroidManifest.xml
Outdated
Show resolved
Hide resolved
paparazzi-gradle-plugin/src/test/java/app/cash/paparazzi/gradle/PaparazziPluginTest.kt
Show resolved
Hide resolved
d331286
to
cc6e415
Compare
HYPE! |
Will this be compatible with composables? |
Yup! Works as expected out of the box 🙌 |
cc6e415
to
58862a2
Compare
What's blocking this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR looks good to me. Anything blocking this from getting merged? cc @gamepro65
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Are you planning on adding the HtmlReportWriter
test for the .apng
file check?
58862a2
to
3a65ffb
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Partial feedback; will give another pass, but wanted to get this out to start the conversation.
paparazzi/src/test/java/app/cash/paparazzi/internal/apng/ApngVerifierTest.kt
Outdated
Show resolved
Hide resolved
sample/src/test/java/app/cash/paparazzi/sample/KeypadViewTest.kt
Outdated
Show resolved
Hide resolved
paparazzi-gradle-plugin/src/test/java/app/cash/paparazzi/gradle/PaparazziPluginTest.kt
Show resolved
Hide resolved
paparazzi-gradle-plugin/src/test/java/app/cash/paparazzi/gradle/PaparazziPluginTest.kt
Outdated
Show resolved
Hide resolved
paparazzi-gradle-plugin/src/test/java/app/cash/paparazzi/gradle/PaparazziPluginTest.kt
Show resolved
Hide resolved
e9ba4a9
to
664fe3d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More feedback, mostly on the record/report mode; will give one last pass for verification.
paparazzi/src/test/java/app/cash/paparazzi/internal/apng/TestPngUtils.kt
Outdated
Show resolved
Hide resolved
paparazzi/src/test/java/app/cash/paparazzi/internal/apng/ApngWriterTest.kt
Outdated
Show resolved
Hide resolved
paparazzi/src/test/java/app/cash/paparazzi/internal/apng/TestPngUtils.kt
Outdated
Show resolved
Hide resolved
paparazzi/src/test/java/app/cash/paparazzi/HtmlReportWriterTest.kt
Outdated
Show resolved
Hide resolved
paparazzi/src/test/java/app/cash/paparazzi/HtmlReportWriterTest.kt
Outdated
Show resolved
Hide resolved
paparazzi/src/test/java/app/cash/paparazzi/HtmlReportWriterTest.kt
Outdated
Show resolved
Hide resolved
paparazzi/src/main/java/app/cash/paparazzi/internal/apng/ApngVerifier.kt
Show resolved
Hide resolved
ee736eb
to
3fc88fd
Compare
paparazzi/src/test/java/app/cash/paparazzi/internal/apng/ApngReaderTest.kt
Outdated
Show resolved
Hide resolved
paparazzi/src/main/java/app/cash/paparazzi/internal/ImageUtils.kt
Outdated
Show resolved
Hide resolved
3fc88fd
to
acbe144
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
awesome stuff, @gamepro65!
paparazzi/src/main/java/app/cash/paparazzi/internal/apng/ApngVerifier.kt
Outdated
Show resolved
Hide resolved
paparazzi/src/main/java/app/cash/paparazzi/internal/apng/ApngVerifier.kt
Outdated
Show resolved
Hide resolved
// Expected on the left | ||
// Golden on the right | ||
g.drawImage(goldenImage, 0, 0, null) | ||
g.drawImage(image, goldenImageWidth + deltaWidth, 0, null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
before the delta was only drawn on error, but this proposes drawing it on every similarity check. is there any perf impact to take into account here, i.e., does this contribute much to that ~130ms per frame analysis?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The delta image is generated while calculating the % error, we previously were just throwing it away when no error.
paparazzi/src/main/java/app/cash/paparazzi/internal/apng/ApngVerifier.kt
Show resolved
Hide resolved
paparazzi/src/main/java/app/cash/paparazzi/internal/apng/ApngVerifier.kt
Show resolved
Hide resolved
} | ||
readNextFrame() | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this method is tough to read, given all the implicit receivers. consider rewriting as:
private fun ApngReader.initializeWriter(): ApngWriter {
val writer = ApngWriter(deltaFilePath, commonFrameRate, fileSystem)
val currentFrameNumber = frameNumber - 1
reset()
repeat(currentFrameNumber) {
val nextFrame = readNextFrame() ?: blankFrame
val (deltaImage) = ImageUtils.compareImages(
goldenImage = nextFrame,
image = nextFrame,
withText = withErrorText
)
writer.writeImage(deltaImage)
}
readNextFrame()
return writer
}
or
private fun initializeWriter(reader: ApngReader): ApngWriter {
return ApngWriter(deltaFilePath, commonFrameRate, fileSystem).apply {
val currentFrameNumber = reader.frameNumber - 1
reader.reset()
repeat(currentFrameNumber) {
val nextFrame = reader.readNextFrame() ?: blankFrame
val (deltaImage) = ImageUtils.compareImages(
goldenImage = nextFrame,
image = nextFrame,
withText = withErrorText
)
writeImage(deltaImage)
}
reader.readNextFrame()
}
}
to reduce one of the implicit receivers. FWIW, I like the first slightly better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like the hard part is discerning reader from writer. I think this would strike a happy medium
private fun ApngReader.initializeWriter(): ApngWriter {
val currentFrameNumber = frameNumber - 1
reset()
return ApngWriter(deltaFilePath, commonFrameRate, fileSystem).apply {
repeat(currentFrameNumber) {
val nextFrame = readNextFrame() ?: blankFrame
val (deltaImage) = ImageUtils.compareImages(
expected = nextFrame,
actual = nextFrame,
withText = withErrorText
)
writeImage(deltaImage)
}
readNextFrame()
}
}
import kotlin.math.max | ||
import kotlin.math.min | ||
|
||
internal class ApngVerifier( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a work of art. kudos!
paparazzi/src/test/java/app/cash/paparazzi/internal/apng/ApngVerifierTest.kt
Outdated
Show resolved
Hide resolved
import java.io.File | ||
import java.lang.AssertionError | ||
|
||
class ApngVerifierTest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like this test
acbe144
to
7199d1c
Compare
Handles all the different error configurations that can happen during gif verification. By default the verifier is only used for gif, potentially could be used for all snapshots but wanted to take it one step at a time. General performance testing a base gif during recordPaparazzi averaged ~35ms per frame on an M1 Pro with verifyPaparazzi delta video (which is 3x as wide) taking upward of ~130ms per frame.
Refactored the hard coded failure dir from ImageUtils so we can seed it properly. For testing the delta image generation we opt out of rendering java text (IE. Expected / Actual) because it is different between platforms and would require a non-zero % diff image assertion.
Mismatched frames:
![delta-app cash paparazzi sample_KeypadViewTest_testViews_spin](https://private-user-images.githubusercontent.com/672316/289652682-0a4cec0f-097f-4e49-9e70-3461470a2f26.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjAwNTA2OTYsIm5iZiI6MTcyMDA1MDM5NiwicGF0aCI6Ii82NzIzMTYvMjg5NjUyNjgyLTBhNGNlYzBmLTA5N2YtNGU0OS05ZTcwLTM0NjE0NzBhMmYyNi5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwNzAzJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDcwM1QyMzQ2MzZaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT04YTc0OThmNDAyMTg4YzdjNWFhMTZiN2ZiMDA5ZjQ4MjJiODYwNjkyODAzNmZkYjM0Njg5MTM0Y2I3YmEyYjAxJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.-Q55ZOml4bN1qhn5WIWy9MslnlpJLDbzxNmUftdSVfA)
More frames than golden:
![delta-app cash paparazzi sample_KeypadViewTest_testViews_spin](https://private-user-images.githubusercontent.com/672316/289652930-ce65b2f4-b167-4e8f-b3a2-f3d56f99b94b.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjAwNTA2OTYsIm5iZiI6MTcyMDA1MDM5NiwicGF0aCI6Ii82NzIzMTYvMjg5NjUyOTMwLWNlNjViMmY0LWIxNjctNGU4Zi1iM2EyLWYzZDU2Zjk5Yjk0Yi5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwNzAzJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDcwM1QyMzQ2MzZaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT04Njc0YjM1ZmUzMWEwMGQxOGE0MDVlYTcwZTA3YmQxNTU2YzdiZWRkMTA5NmFlMDBiZDA5MTIyY2UyMDBhZDQwJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.aiiDtM4dRkdlh2k0IGztiQHfnVD0mcJcYOY_BThSD80)
Less frames than golden:
![delta-app cash paparazzi sample_KeypadViewTest_testViews_spin](https://private-user-images.githubusercontent.com/672316/289653114-56bca35c-502a-48e9-aa3f-109822d671db.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjAwNTA2OTYsIm5iZiI6MTcyMDA1MDM5NiwicGF0aCI6Ii82NzIzMTYvMjg5NjUzMTE0LTU2YmNhMzVjLTUwMmEtNDhlOS1hYTNmLTEwOTgyMmQ2NzFkYi5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwNzAzJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDcwM1QyMzQ2MzZaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT1hZDdiMWViMTg3NjU0MDI4YWFmOTZmMDg3ODNlNDZmNDkwNTgwMDk5YmMyZGY0YjNhZDY2YTBjMTgxNDkzN2M0JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9._xF1cRxOfX5CucYvIBpOlpKS3LleYrL3VJrDWRqKgy0)
Mismatched fps:
![delta-app cash paparazzi sample_KeypadViewTest_testViews_spin](https://private-user-images.githubusercontent.com/672316/289653535-93a3f638-b1a6-4061-a0a0-65b2e3d1b47f.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjAwNTA2OTYsIm5iZiI6MTcyMDA1MDM5NiwicGF0aCI6Ii82NzIzMTYvMjg5NjUzNTM1LTkzYTNmNjM4LWIxYTYtNDA2MS1hMGEwLTY1YjJlM2QxYjQ3Zi5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwNzAzJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDcwM1QyMzQ2MzZaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT04MTRkZTAyMzAxNDQ0MGNjZWE3OTk3NDU5MjI5MjJkY2Y1OGFjMGMwMDhmNTQxYjg2ZTc4MWRkNjY1YzVhN2YzJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.X7b0t8dmEglXHqDgPI67dm0cU_59_6i1CECuHxnaopE)