Replace AnimationSheetBuilder.display with collate
Summary
#The AnimationSheetBuilder.display
and sheetSize
methods are deprecated, and should be replaced with
AnimationSheetBuilder.collate
.
Context
#AnimationSheetBuilder
is a testing utility
class that records frames of an animating widget,
and later composes the frames into a single
animation sheet for golden testing. The old way
of composing involves display
to list the images
into a table-like widget, adjusting the testing
surface with sheetSize
, and capturing the table
widget for comparison. A new way, collate
, has
been added that directly puts the frames together
into an image for comparison, which requires less
boilerplate code and outputs a smaller image without
compromise in quality. APIs for the old way are thus
deprecated.
The reason why collate
outputs a smaller image,
is because the old way captures on a testing surface
with pixel ratio 3.0, which means it uses a 3x3 pixel
block of the exactly same color to represent 1 actual
pixel, making the image 9 times as large as necessary
(before PNG compression).
Description of change
#The following changes have been made to the
AnimationSheetBuilder
class:
- 'display' is deprecated and shouldn't be used
- 'sheetSize' is deprecated and shouldn't be used
Migration guide
#To migrate to the new API, change the process of setting
surface size and displaying the widget into
AnimationSheetBuilder.collate
.
Derive cells per row
#The collate
requires an explicit cellsPerRow
argument, which is the number of frames per
row in the output image. It can be manually counted,
or calculated as follows:
- Find the width of frame, specified when constructing
AnimationSheetBuilder
. For example, in the following snippet it's 80:
final AnimationSheetBuilder animationSheet = AnimationSheetBuilder(frameSize: const Size(80, 30));
- Find the width of surface size, specified when setting the surface size; the default is 800. For example, in the following snippet it's 600:
tester.binding.setSurfaceSize(animationSheet.sheetSize(600));
- The frames per row should be the result of the two numbers divided, rounded down. For example, 600 / 80 = 7 (rounded down), therefore
animationSheet.collate(7)
Migrate code
#Code before migration:
testWidgets('Indeterminate CircularProgressIndicator', (WidgetTester tester) async {
final AnimationSheetBuilder animationSheet = AnimationSheetBuilder(frameSize: const Size(40, 40));
await tester.pumpFrames(animationSheet.record(
const Directionality(
textDirection: TextDirection.ltr,
child: Padding(
padding: EdgeInsets.all(4),
child: CircularProgressIndicator(),
),
),
), const Duration(seconds: 2));
// The code starting here needs migration.
tester.binding.setSurfaceSize(animationSheet.sheetSize());
final Widget display = await animationSheet.display();
await tester.pumpWidget(display);
await expectLater(
find.byWidget(display),
matchesGoldenFile('material.circular_progress_indicator.indeterminate.png'),
);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/42767
Code after migration (cellsPerRow
is 20, derived from 800 / 40):
testWidgets('Indeterminate CircularProgressIndicator', (WidgetTester tester) async {
final AnimationSheetBuilder animationSheet = AnimationSheetBuilder(frameSize: const Size(40, 40));
await tester.pumpFrames(animationSheet.record(
const Directionality(
textDirection: TextDirection.ltr,
child: Padding(
padding: EdgeInsets.all(4),
child: CircularProgressIndicator(),
),
),
), const Duration(seconds: 2));
await expectLater(
animationSheet.collate(20),
matchesGoldenFile('material.circular_progress_indicator.indeterminate.png'),
);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/42767
It's expected that related golden test reference images are invalidated, which should all be updated. The new images should be identical to the old ones except 1/3 in scale.
Timeline
#Landed in version: v2.3.0-13.0.pre
In stable release: 2.5
References
#API documentation:
Relevant PR:
除非另有说明,本文档之所提及适用于 Flutter 的最新稳定版本,本页面最后更新时间: 2024-10-09。 查看文档源码 或者 为本页面内容提出建议。