Skip to content

test(images): measure the thumbnail decode without imageBuilder - #21

Merged
vannt-dev merged 1 commit into
mainfrom
fix/image-decode-test-measurement
Sep 3, 2026
Merged

test(images): measure the thumbnail decode without imageBuilder#21
vannt-dev merged 1 commit into
mainfrom
fix/image-decode-test-measurement

Conversation

@vannt-dev

Copy link
Copy Markdown
Owner

Unblocks the v1.6.0 release: the push of chore(release): 1.6.0 to main failed
its Android integration job (run 33761887174),
so release-candidate and publish-release were skipped and no tag was cut.

What actually broke

The failure was in the test, not the app.

CachedNetworkImage implements memCacheWidth by handing it to OctoImage,
which wraps the provider in ResizeImage.resizeIfNeeded
(octo_image/lib/src/image/image.dart:205). But when an imageBuilder is
given, _octoImageBuilder throws away the widget OctoImage built and calls
imageBuilder(context, _image) with the raw CachedNetworkImageProvider
(cached_network_image-3.4.1/lib/src/cached_image_widget.dart:299).

The test used imageBuilder purely to detect that loading had finished, then
painted Image(image: provider) — decoding a second, full-resolution copy. Its
assertion read imageCache.currentSizeBytes, a global total, which then held
both bitmaps:

full      = 5_832_000  = 1080 x 1350 x 4
thumbnail = 6_065_280  = 5_832_000 + (216 x 270 x 4)

Whether it passed came down to which decode reached the cache first — it passed
on the PR run for the very same commit and failed on the push to main.

The fix

The app never passes imageBuilder — all six memCacheWidth call sites use a
plain CachedNetworkImage — so the measurement now loads the image the way
production does and completion is detected from the cache itself. One decode,
one number:

full      = 5_832_000
thumbnail =   233_280   (216 x 270 x 4)

Verification

Run on a local Aegis_API_34 emulator against tool/fixture_server.js, the
same pair CI runs — twice, including once on the exact post-dart format file:

  • integration_test/android_storage_test.dart + integration_test/slideshow_render_test.dart20/20 passed, both runs, identical byte counts
  • flutter test — 261 passed, 8 skipped
  • flutter analyze — no issues
  • dart format --set-exit-if-changed lib test integration_test — clean

No production code is touched.

Once this lands on main, release-candidate takes its "Version is unchanged;
checking for an interrupted release" path (.github/workflows/ci.yml:186):
pubspec.yaml is still 1.6.0, CHANGELOG.md has valid [1.6.0] notes, and
v1.6.0 does not exist yet — so the release publishes without another bump.

Given an `imageBuilder`, `CachedNetworkImage` discards the widget
`OctoImage` built and hands the callback its raw provider, so the
`ResizeImage` that implements `memCacheWidth` was lost and the test
decoded a second, full-resolution copy. The assertion read the image
cache total, which then held both the 216x270 thumbnail and the full
1080x1350 bitmap, and passed or failed on whichever decode landed
first: it passed on the 1.6.0 pull request and failed on the push to
main, leaving v1.6.0 unreleased.

The app never passes `imageBuilder`, so the measurement now loads the
image the way production does and the total describes one decode.
@vannt-dev
vannt-dev merged commit cc7355a into main Sep 3, 2026
7 checks passed
@vannt-dev
vannt-dev deleted the fix/image-decode-test-measurement branch September 3, 2026 14:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant