1// Copyright 2014 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'dart:ui' as ui;
6
7import 'package:flutter/rendering.dart';
8import 'package:flutter/widgets.dart';
9import 'package:flutter_test/flutter_test.dart';
10
11Future<ui.Image> createTestImage(int width, int height, ui.Color color) async {
12 final ui.Paint paint =
13 ui.Paint()
14 ..style = ui.PaintingStyle.stroke
15 ..strokeWidth = 1.0
16 ..color = color;
17 final ui.PictureRecorder recorder = ui.PictureRecorder();
18 final ui.Canvas pictureCanvas = ui.Canvas(recorder);
19 pictureCanvas.drawCircle(Offset.zero, 20.0, paint);
20 final ui.Picture picture = recorder.endRecording();
21 final ui.Image image = await picture.toImage(width, height);
22 picture.dispose();
23 return image;
24}
25
26void main() {
27 const ui.Color red = ui.Color.fromARGB(255, 255, 0, 0);
28 const ui.Color green = ui.Color.fromARGB(255, 0, 255, 0);
29 const ui.Color transparentRed = ui.Color.fromARGB(128, 255, 0, 0);
30
31 group('succeeds', () {
32 testWidgets('when images have the same content', (WidgetTester tester) async {
33 final ui.Image image1 = await createTestImage(100, 100, red);
34 addTearDown(image1.dispose);
35 final ui.Image referenceImage1 = await createTestImage(100, 100, red);
36 addTearDown(referenceImage1.dispose);
37
38 await expectLater(image1, matchesReferenceImage(referenceImage1));
39
40 final ui.Image image2 = await createTestImage(100, 100, green);
41 addTearDown(image2.dispose);
42 final ui.Image referenceImage2 = await createTestImage(100, 100, green);
43 addTearDown(referenceImage2.dispose);
44
45 await expectLater(image2, matchesReferenceImage(referenceImage2));
46
47 final ui.Image image3 = await createTestImage(100, 100, transparentRed);
48 addTearDown(image3.dispose);
49 final ui.Image referenceImage3 = await createTestImage(100, 100, transparentRed);
50 addTearDown(referenceImage3.dispose);
51
52 await expectLater(image3, matchesReferenceImage(referenceImage3));
53 });
54
55 testWidgets('when images are identical', (WidgetTester tester) async {
56 final ui.Image image = await createTestImage(100, 100, red);
57 addTearDown(image.dispose);
58 await expectLater(image, matchesReferenceImage(image));
59 });
60
61 testWidgets('when widget looks the same', (WidgetTester tester) async {
62 addTearDown(tester.view.reset);
63 tester.view
64 ..physicalSize = const Size(10, 10)
65 ..devicePixelRatio = 1;
66
67 const ValueKey<String> repaintBoundaryKey = ValueKey<String>('boundary');
68
69 await tester.pumpWidget(
70 const RepaintBoundary(key: repaintBoundaryKey, child: ColoredBox(color: red)),
71 );
72
73 final ui.Image referenceImage =
74 (tester.renderObject(find.byKey(repaintBoundaryKey)) as RenderRepaintBoundary)
75 .toImageSync();
76 addTearDown(referenceImage.dispose);
77
78 await expectLater(find.byKey(repaintBoundaryKey), matchesReferenceImage(referenceImage));
79 });
80 });
81
82 group('fails', () {
83 testWidgets('when image sizes do not match', (WidgetTester tester) async {
84 final ui.Image red50 = await createTestImage(50, 50, red);
85 addTearDown(red50.dispose);
86 final ui.Image red100 = await createTestImage(100, 100, red);
87 addTearDown(red100.dispose);
88
89 expect(
90 await matchesReferenceImage(red50).matchAsync(red100),
91 equals('does not match as width or height do not match. [100×100] != [50×50]'),
92 );
93 });
94
95 testWidgets('when image pixels do not match', (WidgetTester tester) async {
96 final ui.Image red100 = await createTestImage(100, 100, red);
97 addTearDown(red100.dispose);
98 final ui.Image transparentRed100 = await createTestImage(100, 100, transparentRed);
99 addTearDown(transparentRed100.dispose);
100
101 expect(
102 await matchesReferenceImage(red100).matchAsync(transparentRed100),
103 equals('does not match on 57 pixels'),
104 );
105
106 final ui.Image green100 = await createTestImage(100, 100, green);
107 addTearDown(green100.dispose);
108
109 expect(
110 await matchesReferenceImage(red100).matchAsync(green100),
111 equals('does not match on 57 pixels'),
112 );
113 });
114
115 testWidgets('when widget does not look the same', (WidgetTester tester) async {
116 addTearDown(tester.view.reset);
117 tester.view
118 ..physicalSize = const Size(10, 10)
119 ..devicePixelRatio = 1;
120
121 const ValueKey<String> repaintBoundaryKey = ValueKey<String>('boundary');
122
123 await tester.pumpWidget(
124 const RepaintBoundary(key: repaintBoundaryKey, child: ColoredBox(color: red)),
125 );
126
127 final ui.Image referenceImage =
128 (tester.renderObject(find.byKey(repaintBoundaryKey)) as RenderRepaintBoundary)
129 .toImageSync();
130 addTearDown(referenceImage.dispose);
131
132 await tester.pumpWidget(
133 const RepaintBoundary(key: repaintBoundaryKey, child: ColoredBox(color: green)),
134 );
135
136 expect(
137 await matchesReferenceImage(referenceImage).matchAsync(find.byKey(repaintBoundaryKey)),
138 equals('does not match on 100 pixels'),
139 );
140 });
141 });
142}
143

Provided by KDAB

Privacy Policy
Learn more about Flutter for embedded and desktop on industrialflutter.com