Unverified Commit 7eb84474 authored by Dan Field's avatar Dan Field Committed by GitHub

Allow new methods to be added to ui.Image for tests (#65876)

Remove fake image implementations, add createTestImage to flutter_test
parent 8d2e2576
...@@ -6,7 +6,7 @@ import 'dart:io'; ...@@ -6,7 +6,7 @@ import 'dart:io';
import 'package:mockito/mockito.dart'; import 'package:mockito/mockito.dart';
import '../../../packages/flutter/test/painting/image_data.dart'; import '../../../packages/flutter/test/image_data.dart';
// Returns a mock HTTP client that responds with an image to all requests. // Returns a mock HTTP client that responds with an image to all requests.
MockHttpClient createMockImageHttpClient(SecurityContext _) { MockHttpClient createMockImageHttpClient(SecurityContext _) {
......
...@@ -5,8 +5,6 @@ ...@@ -5,8 +5,6 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:developer' as developer; import 'dart:developer' as developer;
import 'dart:isolate' as isolate; import 'dart:isolate' as isolate;
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
...@@ -40,8 +38,7 @@ void main() { ...@@ -40,8 +38,7 @@ void main() {
); );
PaintingBinding.instance.imageCache.clear(); PaintingBinding.instance.imageCache.clear();
// ignore: invalid_use_of_protected_member completer2.testSetImage(ImageInfo(image: await createTestImage()));
completer2.setImage(const ImageInfo(image: TestImage()));
PaintingBinding.instance.imageCache.putIfAbsent( PaintingBinding.instance.imageCache.putIfAbsent(
'Test2', 'Test2',
() => completer2, () => completer2,
...@@ -76,7 +73,7 @@ void main() { ...@@ -76,7 +73,7 @@ void main() {
}, },
<String, dynamic>{ <String, dynamic>{
'name': 'ImageCache.evict', 'name': 'ImageCache.evict',
'args': <String, dynamic>{'sizeInBytes': 0, 'isolateId': isolateId} 'args': <String, dynamic>{'sizeInBytes': 4, 'isolateId': isolateId}
}, },
], ],
); );
...@@ -110,20 +107,8 @@ bool _mapsEqual(Map<String, dynamic> expectedArgs, Map<String, dynamic> args) { ...@@ -110,20 +107,8 @@ bool _mapsEqual(Map<String, dynamic> expectedArgs, Map<String, dynamic> args) {
return true; return true;
} }
class TestImageStreamCompleter extends ImageStreamCompleter {} class TestImageStreamCompleter extends ImageStreamCompleter {
void testSetImage(ImageInfo image) {
class TestImage implements ui.Image { setImage(image);
const TestImage({this.height = 0, this.width = 0});
@override
final int height;
@override
final int width;
@override
void dispose() { }
@override
Future<ByteData> toByteData({ ui.ImageByteFormat format = ui.ImageByteFormat.rawRgba }) {
throw UnimplementedError();
} }
} }
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert' show jsonEncode; import 'dart:convert' show jsonEncode;
import 'dart:developer' as developer; import 'dart:developer' as developer;
import 'dart:typed_data';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
...@@ -46,7 +45,7 @@ void main() { ...@@ -46,7 +45,7 @@ void main() {
final Completer<Event> completer = Completer<Event>(); final Completer<Event> completer = Completer<Event>();
vmService.onExtensionEvent.first.then(completer.complete); vmService.onExtensionEvent.first.then(completer.complete);
const TestImage image = TestImage(width: 300, height: 300); final ui.Image image = await createTestImage(width: 300, height: 300);
final TestCanvas canvas = TestCanvas(); final TestCanvas canvas = TestCanvas();
paintImage( paintImage(
canvas: canvas, canvas: canvas,
...@@ -79,7 +78,7 @@ void main() { ...@@ -79,7 +78,7 @@ void main() {
final Completer<Event> completer = Completer<Event>(); final Completer<Event> completer = Completer<Event>();
vmService.onExtensionEvent.first.then(completer.complete); vmService.onExtensionEvent.first.then(completer.complete);
const TestImage image = TestImage(width: 300, height: 300); final ui.Image image = await createTestImage(width: 300, height: 300);
final TestCanvas canvas = TestCanvas(); final TestCanvas canvas = TestCanvas();
paintImage( paintImage(
canvas: canvas, canvas: canvas,
...@@ -105,23 +104,6 @@ void main() { ...@@ -105,23 +104,6 @@ void main() {
}, skip: isBrowser); // uses dart:isolate and io }, skip: isBrowser); // uses dart:isolate and io
} }
class TestImage implements ui.Image {
const TestImage({this.height = 0, this.width = 0});
@override
final int height;
@override
final int width;
@override
void dispose() {}
@override
Future<ByteData> toByteData(
{ui.ImageByteFormat format = ui.ImageByteFormat.rawRgba}) {
throw UnimplementedError();
}
}
class TestCanvas implements Canvas { class TestCanvas implements Canvas {
@override @override
void noSuchMethod(Invocation invocation) {} void noSuchMethod(Invocation invocation) {}
......
...@@ -10,7 +10,7 @@ import 'package:flutter/cupertino.dart'; ...@@ -10,7 +10,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../painting/image_data.dart'; import '../image_data.dart';
import '../widgets/semantics_tester.dart'; import '../widgets/semantics_tester.dart';
Future<void> pumpWidgetWithBoilerplate(WidgetTester tester, Widget widget) async { Future<void> pumpWidgetWithBoilerplate(WidgetTester tester, Widget widget) async {
...@@ -257,7 +257,7 @@ Future<void> main() async { ...@@ -257,7 +257,7 @@ Future<void> main() async {
}); });
testWidgets('Use active icon', (WidgetTester tester) async { testWidgets('Use active icon', (WidgetTester tester) async {
final MemoryImage activeIcon = MemoryImage(Uint8List.fromList(kBlueSquare)); final MemoryImage activeIcon = MemoryImage(Uint8List.fromList(kBlueSquarePng));
final MemoryImage inactiveIcon = MemoryImage(Uint8List.fromList(kTransparentImage)); final MemoryImage inactiveIcon = MemoryImage(Uint8List.fromList(kTransparentImage));
await pumpWidgetWithBoilerplate(tester, MediaQuery( await pumpWidgetWithBoilerplate(tester, MediaQuery(
......
...@@ -10,7 +10,7 @@ import 'package:flutter/cupertino.dart'; ...@@ -10,7 +10,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../../painting/image_data.dart'; import '../../image_data.dart';
List<int> selectedTabs; List<int> selectedTabs;
......
...@@ -9,7 +9,7 @@ import 'dart:typed_data'; ...@@ -9,7 +9,7 @@ import 'dart:typed_data';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../painting/image_data.dart'; import '../image_data.dart';
import '../rendering/mock_canvas.dart'; import '../rendering/mock_canvas.dart';
/// Integration tests testing both [CupertinoPageScaffold] and [CupertinoTabScaffold]. /// Integration tests testing both [CupertinoPageScaffold] and [CupertinoTabScaffold].
......
...@@ -9,7 +9,7 @@ import 'dart:typed_data'; ...@@ -9,7 +9,7 @@ import 'dart:typed_data';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../painting/image_data.dart'; import '../image_data.dart';
import '../rendering/rendering_tester.dart'; import '../rendering/rendering_tester.dart';
List<int> selectedTabs; List<int> selectedTabs;
......
...@@ -12,6 +12,7 @@ import 'package:test_api/test_api.dart' as test_package show TypeMatcher; // ign ...@@ -12,6 +12,7 @@ import 'package:test_api/test_api.dart' as test_package show TypeMatcher; // ign
export 'package:test_api/test_api.dart' hide TypeMatcher, isInstanceOf; // ignore: deprecated_member_use export 'package:test_api/test_api.dart' hide TypeMatcher, isInstanceOf; // ignore: deprecated_member_use
export 'package:test_api/fake.dart'; // ignore: deprecated_member_use export 'package:test_api/fake.dart'; // ignore: deprecated_member_use
export 'package:flutter_test/flutter_test.dart' show createTestImage;
/// A matcher that compares the type of the actual value to the type argument T. /// A matcher that compares the type of the actual value to the type argument T.
test_package.TypeMatcher<T> isInstanceOf<T>() => isA<T>(); test_package.TypeMatcher<T> isInstanceOf<T>() => isA<T>();
......
...@@ -4,9 +4,8 @@ ...@@ -4,9 +4,8 @@
// @dart = 2.8 // @dart = 2.8
/// A 50x50 blue square png. /// A 50x50 blue square png.
const List<int> kBlueSquare = <int>[ const List<int> kBlueSquarePng = <int>[
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49,
0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, 0x08, 0x06, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, 0x08, 0x06,
0x00, 0x00, 0x00, 0x1e, 0x3f, 0x88, 0xb1, 0x00, 0x00, 0x00, 0x48, 0x49, 0x44, 0x00, 0x00, 0x00, 0x1e, 0x3f, 0x88, 0xb1, 0x00, 0x00, 0x00, 0x48, 0x49, 0x44,
...@@ -41,7 +40,7 @@ const List<int> kAnimatedGif = <int> [ ...@@ -41,7 +40,7 @@ const List<int> kAnimatedGif = <int> [
0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x44, 0x01, 0x00, 0x3b, 0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x44, 0x01, 0x00, 0x3b,
]; ];
// A PNG with 100x100 blue pixels. /// A PNG with 100x100 blue pixels.
// //
// Constructed by the following code: // Constructed by the following code:
// ```dart // ```dart
......
...@@ -10,7 +10,7 @@ import 'package:flutter/material.dart'; ...@@ -10,7 +10,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../painting/image_data.dart'; import '../image_data.dart';
void main() { void main() {
testWidgets('CircleAvatar with dark background color', (WidgetTester tester) async { testWidgets('CircleAvatar with dark background color', (WidgetTester tester) async {
......
...@@ -9,16 +9,18 @@ import 'dart:ui' as ui; ...@@ -9,16 +9,18 @@ import 'dart:ui' as ui;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
import 'package:flutter_test/flutter_test.dart';
Future<void> main() async {
final ui.Image image = await createTestImage();
void main() {
testWidgets('didHaveMemoryPressure clears imageCache', (WidgetTester tester) async { testWidgets('didHaveMemoryPressure clears imageCache', (WidgetTester tester) async {
imageCache.putIfAbsent(1, () => OneFrameImageStreamCompleter( imageCache.putIfAbsent(1, () => OneFrameImageStreamCompleter(
Future<ImageInfo>.value(ImageInfo( Future<ImageInfo>.value(ImageInfo(
image: FakeImage(), image: image,
scale: 1.0, scale: 1.0,
), ),
))); )));
...@@ -115,19 +117,3 @@ class FakeImageCache extends ImageCache { ...@@ -115,19 +117,3 @@ class FakeImageCache extends ImageCache {
super.clearLiveImages(); super.clearLiveImages();
} }
} }
class FakeImage implements ui.Image {
@override
void dispose() {}
@override
int get height => 10;
@override
Future<ByteData> toByteData({ui.ImageByteFormat format = ui.ImageByteFormat.rawRgba}) {
throw UnimplementedError();
}
@override
int get width => 10;
}
...@@ -10,8 +10,8 @@ import 'dart:typed_data'; ...@@ -10,8 +10,8 @@ import 'dart:typed_data';
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../image_data.dart';
import '../rendering/rendering_tester.dart'; import '../rendering/rendering_tester.dart';
import 'image_data.dart';
void main() { void main() {
TestRenderingFlutterBinding(); TestRenderingFlutterBinding();
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
// @dart = 2.8 // @dart = 2.8
import 'dart:ui' as ui;
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
import '../flutter_test_alternative.dart'; import '../flutter_test_alternative.dart';
...@@ -22,10 +24,10 @@ void main() { ...@@ -22,10 +24,10 @@ void main() {
test('Image cache resizing based on count', () async { test('Image cache resizing based on count', () async {
imageCache.maximumSize = 2; imageCache.maximumSize = 2;
final TestImageInfo a = await extractOneFrame(const TestImageProvider(1, 1).resolve(ImageConfiguration.empty)) as TestImageInfo; final TestImageInfo a = await extractOneFrame(TestImageProvider(1, 1, image: await createTestImage()).resolve(ImageConfiguration.empty)) as TestImageInfo;
final TestImageInfo b = await extractOneFrame(const TestImageProvider(2, 2).resolve(ImageConfiguration.empty)) as TestImageInfo; final TestImageInfo b = await extractOneFrame(TestImageProvider(2, 2, image: await createTestImage()).resolve(ImageConfiguration.empty)) as TestImageInfo;
final TestImageInfo c = await extractOneFrame(const TestImageProvider(3, 3).resolve(ImageConfiguration.empty)) as TestImageInfo; final TestImageInfo c = await extractOneFrame(TestImageProvider(3, 3, image: await createTestImage()).resolve(ImageConfiguration.empty)) as TestImageInfo;
final TestImageInfo d = await extractOneFrame(const TestImageProvider(1, 4).resolve(ImageConfiguration.empty)) as TestImageInfo; final TestImageInfo d = await extractOneFrame(TestImageProvider(1, 4, image: await createTestImage()).resolve(ImageConfiguration.empty)) as TestImageInfo;
expect(a.value, equals(1)); expect(a.value, equals(1));
expect(b.value, equals(2)); expect(b.value, equals(2));
expect(c.value, equals(3)); expect(c.value, equals(3));
...@@ -33,29 +35,29 @@ void main() { ...@@ -33,29 +35,29 @@ void main() {
imageCache.maximumSize = 0; imageCache.maximumSize = 0;
final TestImageInfo e = await extractOneFrame(const TestImageProvider(1, 5).resolve(ImageConfiguration.empty)) as TestImageInfo; final TestImageInfo e = await extractOneFrame(TestImageProvider(1, 5, image: await createTestImage()).resolve(ImageConfiguration.empty)) as TestImageInfo;
expect(e.value, equals(5)); expect(e.value, equals(5));
final TestImageInfo f = await extractOneFrame(const TestImageProvider(1, 6).resolve(ImageConfiguration.empty)) as TestImageInfo; final TestImageInfo f = await extractOneFrame(TestImageProvider(1, 6, image: await createTestImage()).resolve(ImageConfiguration.empty)) as TestImageInfo;
expect(f.value, equals(6)); expect(f.value, equals(6));
imageCache.maximumSize = 3; imageCache.maximumSize = 3;
final TestImageInfo g = await extractOneFrame(const TestImageProvider(1, 7).resolve(ImageConfiguration.empty)) as TestImageInfo; final TestImageInfo g = await extractOneFrame(TestImageProvider(1, 7, image: await createTestImage()).resolve(ImageConfiguration.empty)) as TestImageInfo;
expect(g.value, equals(7)); expect(g.value, equals(7));
final TestImageInfo h = await extractOneFrame(const TestImageProvider(1, 8).resolve(ImageConfiguration.empty)) as TestImageInfo; final TestImageInfo h = await extractOneFrame(TestImageProvider(1, 8, image: await createTestImage()).resolve(ImageConfiguration.empty)) as TestImageInfo;
expect(h.value, equals(7)); expect(h.value, equals(7));
}); });
test('Image cache resizing based on size', () async { test('Image cache resizing based on size', () async {
const TestImage testImage = TestImage(width: 8, height: 8); // 256 B. final ui.Image testImage = await createTestImage(width: 8, height: 8); // 256 B.
imageCache.maximumSizeBytes = 256 * 2; imageCache.maximumSizeBytes = 256 * 2;
final TestImageInfo a = await extractOneFrame(const TestImageProvider(1, 1, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo; final TestImageInfo a = await extractOneFrame(TestImageProvider(1, 1, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
final TestImageInfo b = await extractOneFrame(const TestImageProvider(2, 2, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo; final TestImageInfo b = await extractOneFrame(TestImageProvider(2, 2, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
final TestImageInfo c = await extractOneFrame(const TestImageProvider(3, 3, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo; final TestImageInfo c = await extractOneFrame(TestImageProvider(3, 3, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
final TestImageInfo d = await extractOneFrame(const TestImageProvider(1, 4, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo; final TestImageInfo d = await extractOneFrame(TestImageProvider(1, 4, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
expect(a.value, equals(1)); expect(a.value, equals(1));
expect(b.value, equals(2)); expect(b.value, equals(2));
expect(c.value, equals(3)); expect(c.value, equals(3));
...@@ -63,18 +65,18 @@ void main() { ...@@ -63,18 +65,18 @@ void main() {
imageCache.maximumSizeBytes = 0; imageCache.maximumSizeBytes = 0;
final TestImageInfo e = await extractOneFrame(const TestImageProvider(1, 5, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo; final TestImageInfo e = await extractOneFrame(TestImageProvider(1, 5, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
expect(e.value, equals(5)); expect(e.value, equals(5));
final TestImageInfo f = await extractOneFrame(const TestImageProvider(1, 6, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo; final TestImageInfo f = await extractOneFrame(TestImageProvider(1, 6, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
expect(f.value, equals(6)); expect(f.value, equals(6));
imageCache.maximumSizeBytes = 256 * 3; imageCache.maximumSizeBytes = 256 * 3;
final TestImageInfo g = await extractOneFrame(const TestImageProvider(1, 7, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo; final TestImageInfo g = await extractOneFrame(TestImageProvider(1, 7, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
expect(g.value, equals(7)); expect(g.value, equals(7));
final TestImageInfo h = await extractOneFrame(const TestImageProvider(1, 8, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo; final TestImageInfo h = await extractOneFrame(TestImageProvider(1, 8, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
expect(h.value, equals(7)); expect(h.value, equals(7));
}); });
} }
...@@ -10,7 +10,7 @@ import 'dart:ui' as ui; ...@@ -10,7 +10,7 @@ import 'dart:ui' as ui;
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
import '../flutter_test_alternative.dart'; import '../flutter_test_alternative.dart';
import 'image_data.dart'; import '../image_data.dart';
import 'painting_utils.dart'; import 'painting_utils.dart';
void main() { void main() {
......
...@@ -12,8 +12,8 @@ import 'package:flutter/painting.dart'; ...@@ -12,8 +12,8 @@ import 'package:flutter/painting.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../image_data.dart';
import '../rendering/rendering_tester.dart'; import '../rendering/rendering_tester.dart';
import 'image_data.dart';
import 'mocks_for_image_cache.dart'; import 'mocks_for_image_cache.dart';
void main() { void main() {
......
...@@ -15,8 +15,8 @@ import 'package:flutter/painting.dart'; ...@@ -15,8 +15,8 @@ import 'package:flutter/painting.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../flutter_test_alternative.dart' show Fake; import '../flutter_test_alternative.dart' show Fake;
import '../image_data.dart';
import '../rendering/rendering_tester.dart'; import '../rendering/rendering_tester.dart';
import 'image_data.dart';
void main() { void main() {
TestRenderingFlutterBinding(); TestRenderingFlutterBinding();
......
...@@ -10,8 +10,8 @@ import 'dart:typed_data'; ...@@ -10,8 +10,8 @@ import 'dart:typed_data';
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../image_data.dart';
import '../rendering/rendering_tester.dart'; import '../rendering/rendering_tester.dart';
import 'image_data.dart';
void main() { void main() {
TestRenderingFlutterBinding(); TestRenderingFlutterBinding();
...@@ -36,7 +36,7 @@ void main() { ...@@ -36,7 +36,7 @@ void main() {
test('ResizeImage resizes to the correct dimensions (down)', () async { test('ResizeImage resizes to the correct dimensions (down)', () async {
final Uint8List bytes = Uint8List.fromList(kBlueSquare); final Uint8List bytes = Uint8List.fromList(kBlueSquarePng);
final MemoryImage imageProvider = MemoryImage(bytes); final MemoryImage imageProvider = MemoryImage(bytes);
final Size rawImageSize = await _resolveAndGetSize(imageProvider); final Size rawImageSize = await _resolveAndGetSize(imageProvider);
expect(rawImageSize, const Size(50, 50)); expect(rawImageSize, const Size(50, 50));
......
...@@ -15,8 +15,8 @@ import 'package:flutter/painting.dart'; ...@@ -15,8 +15,8 @@ import 'package:flutter/painting.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../image_data.dart';
import '../rendering/rendering_tester.dart'; import '../rendering/rendering_tester.dart';
import 'image_data.dart';
import 'mocks_for_image_cache.dart'; import 'mocks_for_image_cache.dart';
void main() { void main() {
...@@ -149,7 +149,7 @@ void main() { ...@@ -149,7 +149,7 @@ void main() {
test('File image sets tag', () async { test('File image sets tag', () async {
final MemoryFileSystem fs = MemoryFileSystem(); final MemoryFileSystem fs = MemoryFileSystem();
final File file = fs.file('/blue.png')..createSync(recursive: true)..writeAsBytesSync(kBlueRectPng); final File file = fs.file('/blue.png')..createSync(recursive: true)..writeAsBytesSync(kBlueSquarePng);
final FileImage provider = FileImage(file); final FileImage provider = FileImage(file);
final MultiFrameImageStreamCompleter completer = provider.load(provider, _decoder) as MultiFrameImageStreamCompleter; final MultiFrameImageStreamCompleter completer = provider.load(provider, _decoder) as MultiFrameImageStreamCompleter;
...@@ -158,7 +158,7 @@ void main() { ...@@ -158,7 +158,7 @@ void main() {
}); });
test('Memory image sets tag', () async { test('Memory image sets tag', () async {
final Uint8List bytes = Uint8List.fromList(kBlueRectPng); final Uint8List bytes = Uint8List.fromList(kBlueSquarePng);
final MemoryImage provider = MemoryImage(bytes); final MemoryImage provider = MemoryImage(bytes);
final MultiFrameImageStreamCompleter completer = provider.load(provider, _decoder) as MultiFrameImageStreamCompleter; final MultiFrameImageStreamCompleter completer = provider.load(provider, _decoder) as MultiFrameImageStreamCompleter;
...@@ -176,7 +176,7 @@ void main() { ...@@ -176,7 +176,7 @@ void main() {
}); });
test('Resize image sets tag', () async { test('Resize image sets tag', () async {
final Uint8List bytes = Uint8List.fromList(kBlueRectPng); final Uint8List bytes = Uint8List.fromList(kBlueSquarePng);
final ResizeImage provider = ResizeImage(MemoryImage(bytes), width: 40, height: 40); final ResizeImage provider = ResizeImage(MemoryImage(bytes), width: 40, height: 40);
final MultiFrameImageStreamCompleter completer = provider.load( final MultiFrameImageStreamCompleter completer = provider.load(
await provider.obtainKey(ImageConfiguration.empty), await provider.obtainKey(ImageConfiguration.empty),
...@@ -206,6 +206,6 @@ class FakeCodec implements Codec { ...@@ -206,6 +206,6 @@ class FakeCodec implements Codec {
class _TestAssetBundle extends CachingAssetBundle { class _TestAssetBundle extends CachingAssetBundle {
@override @override
Future<ByteData> load(String key) async { Future<ByteData> load(String key) async {
return Uint8List.fromList(kBlueRectPng).buffer.asByteData(); return Uint8List.fromList(kBlueSquarePng).buffer.asByteData();
} }
} }
...@@ -5,13 +5,13 @@ ...@@ -5,13 +5,13 @@
// @dart = 2.8 // @dart = 2.8
import 'dart:async'; import 'dart:async';
import 'dart:typed_data';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
import 'image_data.dart'; import 'package:flutter_test/flutter_test.dart';
class TestImageProvider extends ImageProvider<TestImageProvider> { class TestImageProvider extends ImageProvider<TestImageProvider> {
TestImageProvider(this.testImage); TestImageProvider(this.testImage);
...@@ -49,12 +49,6 @@ class TestImageProvider extends ImageProvider<TestImageProvider> { ...@@ -49,12 +49,6 @@ class TestImageProvider extends ImageProvider<TestImageProvider> {
String toString() => '${describeIdentity(this)}()'; String toString() => '${describeIdentity(this)}()';
} }
Future<ui.Image> createTestImage() {
final Completer<ui.Image> uiImage = Completer<ui.Image>();
ui.decodeImageFromList(Uint8List.fromList(kTransparentImage), uiImage.complete);
return uiImage.future;
}
class FakeImageConfiguration implements ImageConfiguration { class FakeImageConfiguration implements ImageConfiguration {
@override @override
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
......
...@@ -5,9 +5,7 @@ ...@@ -5,9 +5,7 @@
// @dart = 2.8 // @dart = 2.8
import 'dart:async'; import 'dart:async';
import 'dart:typed_data';
import 'dart:ui' as ui show Image; import 'dart:ui' as ui show Image;
import 'dart:ui';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
...@@ -31,7 +29,7 @@ class TestImageInfo implements ImageInfo { ...@@ -31,7 +29,7 @@ class TestImageInfo implements ImageInfo {
} }
class TestImageProvider extends ImageProvider<int> { class TestImageProvider extends ImageProvider<int> {
const TestImageProvider(this.key, this.imageValue, { this.image = const TestImage() }) const TestImageProvider(this.key, this.imageValue, { @required this.image })
: assert(image != null); : assert(image != null);
final int key; final int key;
...@@ -74,22 +72,6 @@ Future<ImageInfo> extractOneFrame(ImageStream stream) { ...@@ -74,22 +72,6 @@ Future<ImageInfo> extractOneFrame(ImageStream stream) {
return completer.future; return completer.future;
} }
class TestImage implements ui.Image {
const TestImage({this.height = 0, this.width = 0});
@override
final int height;
@override
final int width;
@override
void dispose() { }
@override
Future<ByteData> toByteData({ ImageByteFormat format = ImageByteFormat.rawRgba }) {
throw UnimplementedError();
}
}
class ErrorImageProvider extends ImageProvider<ErrorImageProvider> { class ErrorImageProvider extends ImageProvider<ErrorImageProvider> {
@override @override
ImageStreamCompleter load(ErrorImageProvider key, DecoderCallback decode) { ImageStreamCompleter load(ErrorImageProvider key, DecoderCallback decode) {
...@@ -141,7 +123,7 @@ class LoadErrorCompleterImageProvider extends ImageProvider<LoadErrorCompleterIm ...@@ -141,7 +123,7 @@ class LoadErrorCompleterImageProvider extends ImageProvider<LoadErrorCompleterIm
} }
class TestImageStreamCompleter extends ImageStreamCompleter { class TestImageStreamCompleter extends ImageStreamCompleter {
void testSetImage(TestImage image) { void testSetImage(ui.Image image) {
setImage(ImageInfo(image: image, scale: 1.0)); setImage(ImageInfo(image: image, scale: 1.0));
} }
} }
...@@ -4,31 +4,12 @@ ...@@ -4,31 +4,12 @@
// @dart = 2.8 // @dart = 2.8
import 'dart:typed_data';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
class TestImage implements ui.Image {
TestImage({ this.width, this.height });
@override
final int width;
@override
final int height;
@override
void dispose() { }
@override
Future<ByteData> toByteData({ ui.ImageByteFormat format = ui.ImageByteFormat.rawRgba }) async {
throw UnsupportedError('Cannot encode test image');
}
}
class TestCanvas implements Canvas { class TestCanvas implements Canvas {
final List<Invocation> invocations = <Invocation>[]; final List<Invocation> invocations = <Invocation>[];
...@@ -39,17 +20,23 @@ class TestCanvas implements Canvas { ...@@ -39,17 +20,23 @@ class TestCanvas implements Canvas {
} }
void main() { void main() {
ui.Image image300x300;
ui.Image image300x200;
setUpAll(() async {
image300x300 = await createTestImage(width: 300, height: 300, cache: false);
image300x200 = await createTestImage(width: 300, height: 200, cache: false);
});
setUp(() { setUp(() {
debugFlushLastFrameImageSizeInfo(); debugFlushLastFrameImageSizeInfo();
}); });
test('Cover and align', () { test('Cover and align', () async {
final TestImage image = TestImage(width: 300, height: 300);
final TestCanvas canvas = TestCanvas(); final TestCanvas canvas = TestCanvas();
paintImage( paintImage(
canvas: canvas, canvas: canvas,
rect: const Rect.fromLTWH(50.0, 75.0, 200.0, 100.0), rect: const Rect.fromLTWH(50.0, 75.0, 200.0, 100.0),
image: image, image: image300x300,
fit: BoxFit.cover, fit: BoxFit.cover,
alignment: const Alignment(-1.0, 0.0), alignment: const Alignment(-1.0, 0.0),
); );
...@@ -59,12 +46,12 @@ void main() { ...@@ -59,12 +46,12 @@ void main() {
}); });
expect(command, isNotNull); expect(command, isNotNull);
expect(command.positionalArguments[0], equals(image)); expect(command.positionalArguments[0], equals(image300x300));
expect(command.positionalArguments[1], equals(const Rect.fromLTWH(0.0, 75.0, 300.0, 150.0))); expect(command.positionalArguments[1], equals(const Rect.fromLTWH(0.0, 75.0, 300.0, 150.0)));
expect(command.positionalArguments[2], equals(const Rect.fromLTWH(50.0, 75.0, 200.0, 100.0))); expect(command.positionalArguments[2], equals(const Rect.fromLTWH(50.0, 75.0, 200.0, 100.0)));
}); });
test('debugInvertOversizedImages', () { test('debugInvertOversizedImages', () async {
debugInvertOversizedImages = true; debugInvertOversizedImages = true;
final FlutterExceptionHandler oldFlutterError = FlutterError.onError; final FlutterExceptionHandler oldFlutterError = FlutterError.onError;
...@@ -73,14 +60,13 @@ void main() { ...@@ -73,14 +60,13 @@ void main() {
messages.add(details.exceptionAsString()); messages.add(details.exceptionAsString());
}; };
final TestImage image = TestImage(width: 300, height: 300);
final TestCanvas canvas = TestCanvas(); final TestCanvas canvas = TestCanvas();
const Rect rect = Rect.fromLTWH(50.0, 50.0, 200.0, 100.0); const Rect rect = Rect.fromLTWH(50.0, 50.0, 200.0, 100.0);
paintImage( paintImage(
canvas: canvas, canvas: canvas,
rect: rect, rect: rect,
image: image, image: image300x300,
debugImageLabel: 'TestImage', debugImageLabel: 'TestImage',
fit: BoxFit.fill, fit: BoxFit.fill,
); );
...@@ -132,12 +118,11 @@ void main() { ...@@ -132,12 +118,11 @@ void main() {
imageSizeInfo = info; imageSizeInfo = info;
}; };
final TestImage image = TestImage(width: 300, height: 300);
final TestCanvas canvas = TestCanvas(); final TestCanvas canvas = TestCanvas();
paintImage( paintImage(
canvas: canvas, canvas: canvas,
rect: const Rect.fromLTWH(50.0, 75.0, 200.0, 100.0), rect: const Rect.fromLTWH(50.0, 75.0, 200.0, 100.0),
image: image, image: image300x300,
debugImageLabel: 'test.png', debugImageLabel: 'test.png',
); );
...@@ -155,7 +140,7 @@ void main() { ...@@ -155,7 +140,7 @@ void main() {
paintImage( paintImage(
canvas: canvas, canvas: canvas,
rect: const Rect.fromLTWH(50.0, 75.0, 200.0, 100.0), rect: const Rect.fromLTWH(50.0, 75.0, 200.0, 100.0),
image: image, image: image300x300,
debugImageLabel: 'test.png', debugImageLabel: 'test.png',
); );
...@@ -172,12 +157,11 @@ void main() { ...@@ -172,12 +157,11 @@ void main() {
imageSizeInfo = info; imageSizeInfo = info;
}; };
final TestImage image = TestImage(width: 300, height: 300);
final TestCanvas canvas = TestCanvas(); final TestCanvas canvas = TestCanvas();
paintImage( paintImage(
canvas: canvas, canvas: canvas,
rect: const Rect.fromLTWH(50.0, 75.0, 200.0, 100.0), rect: const Rect.fromLTWH(50.0, 75.0, 200.0, 100.0),
image: image, image: image300x300,
debugImageLabel: 'test.png', debugImageLabel: 'test.png',
); );
...@@ -195,7 +179,7 @@ void main() { ...@@ -195,7 +179,7 @@ void main() {
paintImage( paintImage(
canvas: canvas, canvas: canvas,
rect: const Rect.fromLTWH(50.0, 75.0, 200.0, 150.0), rect: const Rect.fromLTWH(50.0, 75.0, 200.0, 150.0),
image: image, image: image300x300,
debugImageLabel: 'test.png', debugImageLabel: 'test.png',
); );
...@@ -216,12 +200,11 @@ void main() { ...@@ -216,12 +200,11 @@ void main() {
imageSizeInfo = info; imageSizeInfo = info;
}; };
final TestImage image = TestImage(width: 300, height: 200);
final TestCanvas canvas = TestCanvas(); final TestCanvas canvas = TestCanvas();
paintImage( paintImage(
canvas: canvas, canvas: canvas,
rect: const Rect.fromLTWH(50.0, 75.0, 200.0, 100.0), rect: const Rect.fromLTWH(50.0, 75.0, 200.0, 100.0),
image: image, image: image300x200,
); );
expect(count, 1); expect(count, 1);
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
// @dart = 2.8 // @dart = 2.8
import 'dart:typed_data';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
...@@ -59,12 +58,13 @@ void main() { ...@@ -59,12 +58,13 @@ void main() {
expect(b.hitTest(size, const Offset(20.0, 50.0)), isTrue); expect(b.hitTest(size, const Offset(20.0, 50.0)), isTrue);
}); });
test('ShapeDecoration.image RTL test', () { test('ShapeDecoration.image RTL test', () async {
final ui.Image image = await createTestImage(width: 100, height: 200);
final List<int> log = <int>[]; final List<int> log = <int>[];
final ShapeDecoration decoration = ShapeDecoration( final ShapeDecoration decoration = ShapeDecoration(
shape: const CircleBorder(), shape: const CircleBorder(),
image: DecorationImage( image: DecorationImage(
image: TestImageProvider(), image: TestImageProvider(image),
alignment: AlignmentDirectional.bottomEnd, alignment: AlignmentDirectional.bottomEnd,
), ),
); );
...@@ -113,6 +113,10 @@ void main() { ...@@ -113,6 +113,10 @@ void main() {
} }
class TestImageProvider extends ImageProvider<TestImageProvider> { class TestImageProvider extends ImageProvider<TestImageProvider> {
TestImageProvider(this.image);
final ui.Image image;
@override @override
Future<TestImageProvider> obtainKey(ImageConfiguration configuration) { Future<TestImageProvider> obtainKey(ImageConfiguration configuration) {
return SynchronousFuture<TestImageProvider>(this); return SynchronousFuture<TestImageProvider>(this);
...@@ -121,23 +125,7 @@ class TestImageProvider extends ImageProvider<TestImageProvider> { ...@@ -121,23 +125,7 @@ class TestImageProvider extends ImageProvider<TestImageProvider> {
@override @override
ImageStreamCompleter load(TestImageProvider key, DecoderCallback decode) { ImageStreamCompleter load(TestImageProvider key, DecoderCallback decode) {
return OneFrameImageStreamCompleter( return OneFrameImageStreamCompleter(
SynchronousFuture<ImageInfo>(ImageInfo(image: TestImage(), scale: 1.0)), SynchronousFuture<ImageInfo>(ImageInfo(image: image, scale: 1.0)),
); );
} }
} }
class TestImage implements ui.Image {
@override
int get width => 100;
@override
int get height => 200;
@override
void dispose() { }
@override
Future<ByteData> toByteData({ ui.ImageByteFormat format = ui.ImageByteFormat.rawRgba }) async {
throw UnsupportedError('Cannot encode test image');
}
}
...@@ -4,76 +4,22 @@ ...@@ -4,76 +4,22 @@
// @dart = 2.8 // @dart = 2.8
import 'dart:typed_data'; import 'dart:ui' as ui show Image;
import 'dart:ui' as ui show Image, ImageByteFormat;
import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'rendering_tester.dart'; import 'rendering_tester.dart';
class SquareImage implements ui.Image { Future<void> main() async {
@override final ui.Image squareImage = await createTestImage(width: 10, height: 10);
int get width => 10; final ui.Image wideImage = await createTestImage(width: 20, height: 10);
final ui.Image tallImage = await createTestImage(width: 10, height: 20);
@override
int get height => 10;
@override
Future<ByteData> toByteData({ ui.ImageByteFormat format = ui.ImageByteFormat.rawRgba }) async {
throw UnsupportedError('Cannot encode test image');
}
@override
String toString() => '[$width\u00D7$height]';
@override
void dispose() { }
}
class WideImage implements ui.Image {
@override
int get width => 20;
@override
int get height => 10;
@override
Future<ByteData> toByteData({ ui.ImageByteFormat format = ui.ImageByteFormat.rawRgba }) async {
throw UnsupportedError('Cannot encode test image');
}
@override
String toString() => '[$width\u00D7$height]';
@override
void dispose() { }
}
class TallImage implements ui.Image {
@override
int get width => 10;
@override
int get height => 20;
@override
Future<ByteData> toByteData({ ui.ImageByteFormat format = ui.ImageByteFormat.rawRgba }) async {
throw UnsupportedError('Cannot encode test image');
}
@override
String toString() => '[$width\u00D7$height]';
@override
void dispose() { }
}
void main() {
test('Image sizing', () { test('Image sizing', () {
RenderImage image; RenderImage image;
image = RenderImage(image: SquareImage()); image = RenderImage(image: squareImage);
layout(image, layout(image,
constraints: const BoxConstraints( constraints: const BoxConstraints(
minWidth: 25.0, minWidth: 25.0,
...@@ -83,7 +29,8 @@ void main() { ...@@ -83,7 +29,8 @@ void main() {
expect(image.size.width, equals(25.0)); expect(image.size.width, equals(25.0));
expect(image.size.height, equals(25.0)); expect(image.size.height, equals(25.0));
expect(image, hasAGoodToStringDeep); // TODO(dnfield): https://github.com/flutter/flutter/issues/66289
expect(image, hasAGoodToStringDeep, skip: kIsWeb);
expect( expect(
image.toStringDeep(minLevel: DiagnosticLevel.info), image.toStringDeep(minLevel: DiagnosticLevel.info),
equalsIgnoringHashCodes( equalsIgnoringHashCodes(
...@@ -91,14 +38,14 @@ void main() { ...@@ -91,14 +38,14 @@ void main() {
' parentData: <none> (can use size)\n' ' parentData: <none> (can use size)\n'
' constraints: BoxConstraints(25.0<=w<=100.0, 25.0<=h<=100.0)\n' ' constraints: BoxConstraints(25.0<=w<=100.0, 25.0<=h<=100.0)\n'
' size: Size(25.0, 25.0)\n' ' size: Size(25.0, 25.0)\n'
' image: [10×10]\n' ' image: $squareImage\n'
' alignment: center\n' ' alignment: center\n'
' invertColors: false\n' ' invertColors: false\n'
' filterQuality: low\n' ' filterQuality: low\n'
), ),
); );
image = RenderImage(image: WideImage()); image = RenderImage(image: wideImage);
layout(image, layout(image,
constraints: const BoxConstraints( constraints: const BoxConstraints(
minWidth: 5.0, minWidth: 5.0,
...@@ -108,7 +55,7 @@ void main() { ...@@ -108,7 +55,7 @@ void main() {
expect(image.size.width, equals(60.0)); expect(image.size.width, equals(60.0));
expect(image.size.height, equals(30.0)); expect(image.size.height, equals(30.0));
image = RenderImage(image: TallImage()); image = RenderImage(image: tallImage);
layout(image, layout(image,
constraints: const BoxConstraints( constraints: const BoxConstraints(
minWidth: 50.0, minWidth: 50.0,
...@@ -118,7 +65,7 @@ void main() { ...@@ -118,7 +65,7 @@ void main() {
expect(image.size.width, equals(50.0)); expect(image.size.width, equals(50.0));
expect(image.size.height, equals(75.0)); expect(image.size.height, equals(75.0));
image = RenderImage(image: WideImage()); image = RenderImage(image: wideImage);
layout(image, layout(image,
constraints: const BoxConstraints( constraints: const BoxConstraints(
minWidth: 5.0, minWidth: 5.0,
...@@ -128,7 +75,7 @@ void main() { ...@@ -128,7 +75,7 @@ void main() {
expect(image.size.width, equals(20.0)); expect(image.size.width, equals(20.0));
expect(image.size.height, equals(10.0)); expect(image.size.height, equals(10.0));
image = RenderImage(image: WideImage()); image = RenderImage(image: wideImage);
layout(image, layout(image,
constraints: const BoxConstraints( constraints: const BoxConstraints(
minWidth: 5.0, minWidth: 5.0,
...@@ -138,7 +85,7 @@ void main() { ...@@ -138,7 +85,7 @@ void main() {
expect(image.size.width, equals(16.0)); expect(image.size.width, equals(16.0));
expect(image.size.height, equals(8.0)); expect(image.size.height, equals(8.0));
image = RenderImage(image: TallImage()); image = RenderImage(image: tallImage);
layout(image, layout(image,
constraints: const BoxConstraints( constraints: const BoxConstraints(
minWidth: 5.0, minWidth: 5.0,
...@@ -148,7 +95,7 @@ void main() { ...@@ -148,7 +95,7 @@ void main() {
expect(image.size.width, equals(8.0)); expect(image.size.width, equals(8.0));
expect(image.size.height, equals(16.0)); expect(image.size.height, equals(16.0));
image = RenderImage(image: SquareImage()); image = RenderImage(image: squareImage);
layout(image, layout(image,
constraints: const BoxConstraints( constraints: const BoxConstraints(
minWidth: 4.0, minWidth: 4.0,
...@@ -158,7 +105,7 @@ void main() { ...@@ -158,7 +105,7 @@ void main() {
expect(image.size.width, equals(8.0)); expect(image.size.width, equals(8.0));
expect(image.size.height, equals(8.0)); expect(image.size.height, equals(8.0));
image = RenderImage(image: WideImage()); image = RenderImage(image: wideImage);
layout(image, layout(image,
constraints: const BoxConstraints( constraints: const BoxConstraints(
minWidth: 20.0, minWidth: 20.0,
...@@ -168,7 +115,7 @@ void main() { ...@@ -168,7 +115,7 @@ void main() {
expect(image.size.width, equals(30.0)); expect(image.size.width, equals(30.0));
expect(image.size.height, equals(20.0)); expect(image.size.height, equals(20.0));
image = RenderImage(image: TallImage()); image = RenderImage(image: tallImage);
layout(image, layout(image,
constraints: const BoxConstraints( constraints: const BoxConstraints(
minWidth: 20.0, minWidth: 20.0,
......
...@@ -15,7 +15,7 @@ import 'package:flutter/painting.dart'; ...@@ -15,7 +15,7 @@ import 'package:flutter/painting.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../painting/image_data.dart'; import '../image_data.dart';
import '../rendering/mock_canvas.dart'; import '../rendering/mock_canvas.dart';
class TestImageProvider extends ImageProvider<TestImageProvider> { class TestImageProvider extends ImageProvider<TestImageProvider> {
......
...@@ -10,7 +10,8 @@ import 'dart:ui' as ui; ...@@ -10,7 +10,8 @@ import 'dart:ui' as ui;
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../painting/image_data.dart';
import '../image_data.dart';
import '../painting/image_test_utils.dart'; import '../painting/image_test_utils.dart';
const Duration animationDuration = Duration(milliseconds: 50); const Duration animationDuration = Duration(milliseconds: 50);
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
const List<int> kTransparentImage = <int>[
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49,
0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06,
0x00, 0x00, 0x00, 0x1F, 0x15, 0xC4, 0x89, 0x00, 0x00, 0x00, 0x0A, 0x49, 0x44,
0x41, 0x54, 0x78, 0x9C, 0x63, 0x00, 0x01, 0x00, 0x00, 0x05, 0x00, 0x01, 0x0D,
0x0A, 0x2D, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE,
];
/// An animated GIF image with 3 1x1 pixel frames (a red, green, and blue
/// frames). The GIF animates forever, and each frame has a 100ms delay.
const List<int> kAnimatedGif = <int> [
0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00, 0x01, 0x00, 0xa1, 0x03, 0x00,
0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0x21,
0xff, 0x0b, 0x4e, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e, 0x30,
0x03, 0x01, 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x0a, 0x00, 0xff, 0x00,
0x2c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x4c,
0x01, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x0a, 0x00, 0xff, 0x00, 0x2c, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x54, 0x01, 0x00, 0x21,
0xf9, 0x04, 0x00, 0x0a, 0x00, 0xff, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x44, 0x01, 0x00, 0x3b,
];
...@@ -11,7 +11,7 @@ import 'package:flutter/widgets.dart'; ...@@ -11,7 +11,7 @@ import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../flutter_test_alternative.dart' show Fake; import '../flutter_test_alternative.dart' show Fake;
import '../painting/image_data.dart'; import '../image_data.dart';
void main() { void main() {
final MockHttpClient client = MockHttpClient(); final MockHttpClient client = MockHttpClient();
......
...@@ -10,13 +10,22 @@ import 'package:flutter_test/flutter_test.dart'; ...@@ -10,13 +10,22 @@ import 'package:flutter_test/flutter_test.dart';
import '../painting/mocks_for_image_cache.dart'; import '../painting/mocks_for_image_cache.dart';
const ImageProvider _kImage = TestImageProvider(21, 42);
void main() { void main() {
ImageProvider _image;
setUpAll(() async {
_image = TestImageProvider(
21,
42,
image: await createTestImage(width: 10, height: 10),
);
});
testWidgets('ImageIcon sizing - no theme, default size', (WidgetTester tester) async { testWidgets('ImageIcon sizing - no theme, default size', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
const Center( Center(
child: ImageIcon(_kImage), child: ImageIcon(_image),
), ),
); );
...@@ -27,10 +36,10 @@ void main() { ...@@ -27,10 +36,10 @@ void main() {
testWidgets('Icon opacity', (WidgetTester tester) async { testWidgets('Icon opacity', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
const Center( Center(
child: IconTheme( child: IconTheme(
data: IconThemeData(opacity: 0.5), data: const IconThemeData(opacity: 0.5),
child: ImageIcon(_kImage), child: ImageIcon(_image),
), ),
), ),
); );
......
...@@ -4,8 +4,7 @@ ...@@ -4,8 +4,7 @@
// @dart = 2.8 // @dart = 2.8
import 'dart:typed_data'; import 'dart:ui' as ui show Image;
import 'dart:ui' as ui show Image, ImageByteFormat;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
...@@ -14,6 +13,10 @@ import 'package:flutter_test/flutter_test.dart'; ...@@ -14,6 +13,10 @@ import 'package:flutter_test/flutter_test.dart';
import '../rendering/mock_canvas.dart'; import '../rendering/mock_canvas.dart';
class TestImageProvider extends ImageProvider<TestImageProvider> { class TestImageProvider extends ImageProvider<TestImageProvider> {
const TestImageProvider(this.image);
final ui.Image image;
@override @override
Future<TestImageProvider> obtainKey(ImageConfiguration configuration) { Future<TestImageProvider> obtainKey(ImageConfiguration configuration) {
return SynchronousFuture<TestImageProvider>(this); return SynchronousFuture<TestImageProvider>(this);
...@@ -22,28 +25,16 @@ class TestImageProvider extends ImageProvider<TestImageProvider> { ...@@ -22,28 +25,16 @@ class TestImageProvider extends ImageProvider<TestImageProvider> {
@override @override
ImageStreamCompleter load(TestImageProvider key, DecoderCallback decode) { ImageStreamCompleter load(TestImageProvider key, DecoderCallback decode) {
return OneFrameImageStreamCompleter( return OneFrameImageStreamCompleter(
SynchronousFuture<ImageInfo>(ImageInfo(image: TestImage())) SynchronousFuture<ImageInfo>(ImageInfo(image: image)),
); );
} }
} }
class TestImage implements ui.Image {
@override
int get width => 16;
@override
int get height => 9;
@override
void dispose() { }
@override
Future<ByteData> toByteData({ ui.ImageByteFormat format = ui.ImageByteFormat.rawRgba }) async {
throw UnsupportedError('Cannot encode test image');
}
}
void main() { void main() {
ui.Image testImage;
setUpAll(() async {
testImage = await createTestImage(width: 16, height: 9);
});
testWidgets('DecorationImage RTL with alignment topEnd and match', (WidgetTester tester) async { testWidgets('DecorationImage RTL with alignment topEnd and match', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
...@@ -54,7 +45,7 @@ void main() { ...@@ -54,7 +45,7 @@ void main() {
height: 50.0, height: 50.0,
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
image: TestImageProvider(), image: TestImageProvider(testImage),
alignment: AlignmentDirectional.topEnd, alignment: AlignmentDirectional.topEnd,
repeat: ImageRepeat.repeatX, repeat: ImageRepeat.repeatX,
matchTextDirection: true, matchTextDirection: true,
...@@ -93,7 +84,7 @@ void main() { ...@@ -93,7 +84,7 @@ void main() {
height: 50.0, height: 50.0,
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
image: TestImageProvider(), image: TestImageProvider(testImage),
alignment: AlignmentDirectional.topEnd, alignment: AlignmentDirectional.topEnd,
repeat: ImageRepeat.repeatX, repeat: ImageRepeat.repeatX,
matchTextDirection: true, matchTextDirection: true,
...@@ -129,7 +120,7 @@ void main() { ...@@ -129,7 +120,7 @@ void main() {
height: 50.0, height: 50.0,
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
image: TestImageProvider(), image: TestImageProvider(testImage),
alignment: AlignmentDirectional.topEnd, alignment: AlignmentDirectional.topEnd,
repeat: ImageRepeat.repeatX, repeat: ImageRepeat.repeatX,
), ),
...@@ -164,7 +155,7 @@ void main() { ...@@ -164,7 +155,7 @@ void main() {
height: 50.0, height: 50.0,
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
image: TestImageProvider(), image: TestImageProvider(testImage),
alignment: AlignmentDirectional.topEnd, alignment: AlignmentDirectional.topEnd,
repeat: ImageRepeat.repeatX, repeat: ImageRepeat.repeatX,
), ),
...@@ -199,7 +190,7 @@ void main() { ...@@ -199,7 +190,7 @@ void main() {
height: 50.0, height: 50.0,
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
image: TestImageProvider(), image: TestImageProvider(testImage),
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
matchTextDirection: true, matchTextDirection: true,
), ),
...@@ -231,7 +222,7 @@ void main() { ...@@ -231,7 +222,7 @@ void main() {
height: 50.0, height: 50.0,
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
image: TestImageProvider(), image: TestImageProvider(testImage),
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
), ),
), ),
...@@ -258,7 +249,7 @@ void main() { ...@@ -258,7 +249,7 @@ void main() {
height: 50.0, height: 50.0,
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
image: TestImageProvider(), image: TestImageProvider(testImage),
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
matchTextDirection: true, matchTextDirection: true,
), ),
...@@ -286,7 +277,7 @@ void main() { ...@@ -286,7 +277,7 @@ void main() {
height: 50.0, height: 50.0,
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
image: TestImageProvider(), image: TestImageProvider(testImage),
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
matchTextDirection: true, matchTextDirection: true,
), ),
...@@ -313,7 +304,7 @@ void main() { ...@@ -313,7 +304,7 @@ void main() {
width: 100.0, width: 100.0,
height: 50.0, height: 50.0,
child: Image( child: Image(
image: TestImageProvider(), image: TestImageProvider(testImage),
alignment: AlignmentDirectional.topEnd, alignment: AlignmentDirectional.topEnd,
repeat: ImageRepeat.repeatX, repeat: ImageRepeat.repeatX,
matchTextDirection: true, matchTextDirection: true,
...@@ -350,7 +341,7 @@ void main() { ...@@ -350,7 +341,7 @@ void main() {
width: 100.0, width: 100.0,
height: 50.0, height: 50.0,
child: Image( child: Image(
image: TestImageProvider(), image: TestImageProvider(testImage),
alignment: AlignmentDirectional.topEnd, alignment: AlignmentDirectional.topEnd,
repeat: ImageRepeat.repeatX, repeat: ImageRepeat.repeatX,
matchTextDirection: true, matchTextDirection: true,
...@@ -384,7 +375,7 @@ void main() { ...@@ -384,7 +375,7 @@ void main() {
width: 100.0, width: 100.0,
height: 50.0, height: 50.0,
child: Image( child: Image(
image: TestImageProvider(), image: TestImageProvider(testImage),
alignment: AlignmentDirectional.topEnd, alignment: AlignmentDirectional.topEnd,
repeat: ImageRepeat.repeatX, repeat: ImageRepeat.repeatX,
), ),
...@@ -417,7 +408,7 @@ void main() { ...@@ -417,7 +408,7 @@ void main() {
width: 100.0, width: 100.0,
height: 50.0, height: 50.0,
child: Image( child: Image(
image: TestImageProvider(), image: TestImageProvider(testImage),
alignment: AlignmentDirectional.topEnd, alignment: AlignmentDirectional.topEnd,
repeat: ImageRepeat.repeatX, repeat: ImageRepeat.repeatX,
), ),
...@@ -450,15 +441,13 @@ void main() { ...@@ -450,15 +441,13 @@ void main() {
width: 100.0, width: 100.0,
height: 50.0, height: 50.0,
child: Image( child: Image(
image: TestImageProvider(), image: TestImageProvider(testImage),
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
matchTextDirection: true, matchTextDirection: true,
), ),
), ),
), ),
), ),
Duration.zero,
EnginePhase.layout, // so that we don't try to paint the fake images
); );
expect(find.byType(Container), paints expect(find.byType(Container), paints
..translate(x: 50.0, y: 0.0) ..translate(x: 50.0, y: 0.0)
...@@ -480,7 +469,7 @@ void main() { ...@@ -480,7 +469,7 @@ void main() {
width: 100.0, width: 100.0,
height: 50.0, height: 50.0,
child: Image( child: Image(
image: TestImageProvider(), image: TestImageProvider(testImage),
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
), ),
), ),
...@@ -505,7 +494,7 @@ void main() { ...@@ -505,7 +494,7 @@ void main() {
width: 100.0, width: 100.0,
height: 50.0, height: 50.0,
child: Image( child: Image(
image: TestImageProvider(), image: TestImageProvider(testImage),
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
matchTextDirection: true, matchTextDirection: true,
), ),
...@@ -531,7 +520,7 @@ void main() { ...@@ -531,7 +520,7 @@ void main() {
width: 100.0, width: 100.0,
height: 50.0, height: 50.0,
child: Image( child: Image(
image: TestImageProvider(), image: TestImageProvider(testImage),
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
matchTextDirection: true, matchTextDirection: true,
), ),
...@@ -553,7 +542,7 @@ void main() { ...@@ -553,7 +542,7 @@ void main() {
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: Image( child: Image(
image: TestImageProvider(), image: TestImageProvider(testImage),
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
matchTextDirection: false, matchTextDirection: false,
), ),
...@@ -565,7 +554,7 @@ void main() { ...@@ -565,7 +554,7 @@ void main() {
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: Image( child: Image(
image: TestImageProvider(), image: TestImageProvider(testImage),
alignment: AlignmentDirectional.centerEnd, alignment: AlignmentDirectional.centerEnd,
matchTextDirection: true, matchTextDirection: true,
), ),
...@@ -577,7 +566,7 @@ void main() { ...@@ -577,7 +566,7 @@ void main() {
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: Image( child: Image(
image: TestImageProvider(), image: TestImageProvider(testImage),
alignment: Alignment.centerRight, alignment: Alignment.centerRight,
matchTextDirection: false, matchTextDirection: false,
), ),
......
...@@ -11,9 +11,9 @@ import 'package:flutter/material.dart'; ...@@ -11,9 +11,9 @@ import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../image_data.dart';
import '../painting/fake_codec.dart'; import '../painting/fake_codec.dart';
import '../painting/fake_image_provider.dart'; import '../painting/fake_image_provider.dart';
import '../painting/image_data.dart';
Future<void> main() async { Future<void> main() async {
final FakeCodec fakeCodec = await FakeCodec.fromData(Uint8List.fromList(kAnimatedGif)); final FakeCodec fakeCodec = await FakeCodec.fromData(Uint8List.fromList(kAnimatedGif));
......
...@@ -4,13 +4,21 @@ ...@@ -4,13 +4,21 @@
// @dart = 2.8 // @dart = 2.8
import 'dart:ui' as ui show Image;
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import '../painting/image_test_utils.dart'; import '../painting/image_test_utils.dart';
import '../painting/mocks_for_image_cache.dart' show TestImage;
void main() { void main() {
ui.Image testImage;
setUpAll(() async {
testImage = await createTestImage(width: 10, height: 10);
});
tearDown(() { tearDown(() {
imageCache.clear(); imageCache.clear();
}); });
...@@ -28,7 +36,6 @@ void main() { ...@@ -28,7 +36,6 @@ void main() {
await tester.pumpWidget(TestWidget(key)); await tester.pumpWidget(TestWidget(key));
final DisposableBuildContext context = DisposableBuildContext(key.currentState); final DisposableBuildContext context = DisposableBuildContext(key.currentState);
const TestImage testImage = TestImage(width: 10, height: 10);
final TestImageProvider testImageProvider = TestImageProvider(testImage); final TestImageProvider testImageProvider = TestImageProvider(testImage);
final ScrollAwareImageProvider<TestImageProvider> imageProvider = ScrollAwareImageProvider<TestImageProvider>( final ScrollAwareImageProvider<TestImageProvider> imageProvider = ScrollAwareImageProvider<TestImageProvider>(
context: context, context: context,
...@@ -64,7 +71,6 @@ void main() { ...@@ -64,7 +71,6 @@ void main() {
)); ));
final DisposableBuildContext context = DisposableBuildContext(key.currentState); final DisposableBuildContext context = DisposableBuildContext(key.currentState);
const TestImage testImage = TestImage(width: 10, height: 10);
final TestImageProvider testImageProvider = TestImageProvider(testImage); final TestImageProvider testImageProvider = TestImageProvider(testImage);
final ScrollAwareImageProvider<TestImageProvider> imageProvider = ScrollAwareImageProvider<TestImageProvider>( final ScrollAwareImageProvider<TestImageProvider> imageProvider = ScrollAwareImageProvider<TestImageProvider>(
context: context, context: context,
...@@ -105,7 +111,6 @@ void main() { ...@@ -105,7 +111,6 @@ void main() {
)); ));
final DisposableBuildContext context = DisposableBuildContext(keys.last.currentState); final DisposableBuildContext context = DisposableBuildContext(keys.last.currentState);
const TestImage testImage = TestImage(width: 10, height: 10);
final TestImageProvider testImageProvider = TestImageProvider(testImage); final TestImageProvider testImageProvider = TestImageProvider(testImage);
final ScrollAwareImageProvider<TestImageProvider> imageProvider = ScrollAwareImageProvider<TestImageProvider>( final ScrollAwareImageProvider<TestImageProvider> imageProvider = ScrollAwareImageProvider<TestImageProvider>(
context: context, context: context,
...@@ -163,7 +168,6 @@ void main() { ...@@ -163,7 +168,6 @@ void main() {
)); ));
final DisposableBuildContext context = DisposableBuildContext(keys.last.currentState); final DisposableBuildContext context = DisposableBuildContext(keys.last.currentState);
const TestImage testImage = TestImage(width: 10, height: 10);
final TestImageProvider testImageProvider = TestImageProvider(testImage); final TestImageProvider testImageProvider = TestImageProvider(testImage);
final ScrollAwareImageProvider<TestImageProvider> imageProvider = ScrollAwareImageProvider<TestImageProvider>( final ScrollAwareImageProvider<TestImageProvider> imageProvider = ScrollAwareImageProvider<TestImageProvider>(
context: context, context: context,
...@@ -231,7 +235,6 @@ void main() { ...@@ -231,7 +235,6 @@ void main() {
)); ));
final DisposableBuildContext context = DisposableBuildContext(keys.last.currentState); final DisposableBuildContext context = DisposableBuildContext(keys.last.currentState);
const TestImage testImage = TestImage(width: 10, height: 10);
final TestImageProvider testImageProvider = TestImageProvider(testImage); final TestImageProvider testImageProvider = TestImageProvider(testImage);
final ScrollAwareImageProvider<TestImageProvider> imageProvider = ScrollAwareImageProvider<TestImageProvider>( final ScrollAwareImageProvider<TestImageProvider> imageProvider = ScrollAwareImageProvider<TestImageProvider>(
context: context, context: context,
...@@ -297,7 +300,6 @@ void main() { ...@@ -297,7 +300,6 @@ void main() {
)); ));
final DisposableBuildContext context = DisposableBuildContext(key.currentState); final DisposableBuildContext context = DisposableBuildContext(key.currentState);
const TestImage testImage = TestImage(width: 10, height: 10);
final TestImageProvider testImageProvider = TestImageProvider(testImage); final TestImageProvider testImageProvider = TestImageProvider(testImage);
final ScrollAwareImageProvider<TestImageProvider> imageProvider = ScrollAwareImageProvider<TestImageProvider>( final ScrollAwareImageProvider<TestImageProvider> imageProvider = ScrollAwareImageProvider<TestImageProvider>(
context: context, context: context,
...@@ -349,7 +351,6 @@ void main() { ...@@ -349,7 +351,6 @@ void main() {
)); ));
final DisposableBuildContext context = DisposableBuildContext(key.currentState); final DisposableBuildContext context = DisposableBuildContext(key.currentState);
const TestImage testImage = TestImage(width: 10, height: 10);
final TestImageProvider testImageProvider = TestImageProvider(testImage); final TestImageProvider testImageProvider = TestImageProvider(testImage);
final ScrollAwareImageProvider<TestImageProvider> imageProvider = ScrollAwareImageProvider<TestImageProvider>( final ScrollAwareImageProvider<TestImageProvider> imageProvider = ScrollAwareImageProvider<TestImageProvider>(
context: context, context: context,
...@@ -369,7 +370,7 @@ void main() { ...@@ -369,7 +370,7 @@ void main() {
expect(imageCache.currentSize, 0); expect(imageCache.currentSize, 0);
// Occupy the only slot in the cache with another image. // Occupy the only slot in the cache with another image.
final TestImageProvider testImageProvider2 = TestImageProvider(const TestImage()); final TestImageProvider testImageProvider2 = TestImageProvider(testImage);
testImageProvider2.complete(); testImageProvider2.complete();
await precacheImage(testImageProvider2, context.context); await precacheImage(testImageProvider2, context.context);
expect(imageCache.containsKey(testImageProvider), false); expect(imageCache.containsKey(testImageProvider), false);
......
...@@ -10,7 +10,7 @@ import 'dart:ui' as ui show Image; ...@@ -10,7 +10,7 @@ import 'dart:ui' as ui show Image;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../painting/image_data.dart'; import '../image_data.dart';
import '../painting/mocks_for_image_cache.dart'; import '../painting/mocks_for_image_cache.dart';
import '../rendering/mock_canvas.dart'; import '../rendering/mock_canvas.dart';
import 'test_border.dart' show TestBorder; import 'test_border.dart' show TestBorder;
......
...@@ -56,6 +56,7 @@ export 'src/event_simulation.dart'; ...@@ -56,6 +56,7 @@ export 'src/event_simulation.dart';
export 'src/finders.dart'; export 'src/finders.dart';
export 'src/frame_timing_summarizer.dart'; export 'src/frame_timing_summarizer.dart';
export 'src/goldens.dart'; export 'src/goldens.dart';
export 'src/image.dart';
export 'src/matchers.dart'; export 'src/matchers.dart';
export 'src/nonconst.dart'; export 'src/nonconst.dart';
export 'src/platform.dart'; export 'src/platform.dart';
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart';
import 'test_async_utils.dart';
final Map<int, ui.Image> _cache = <int, ui.Image>{};
/// Creates an arbitrarily sized image for testing.
///
/// If the [cache] parameter is set to true, the image will be cached for the
/// rest of this suite. This is normally desirable, assuming a test suite uses
/// images with the same dimensions in most tests, as it will save on memory
/// usage and CPU time over the course of the suite. However, it should be
/// avoided for images that are used only once in a test suite, especially if
/// the image is large, as it will require holding on to the memory for that
/// image for the duration of the suite.
///
/// This method requires real async work, and will not work properly in the
/// [FakeAsync] zones set up by [testWidgets]. Typically, it should be invoked
/// as a setup step before [testWidgets] are run, such as [setUp] or [setUpAll].
/// If needed, it can be invoked using [WidgetTester.runAsync].
Future<ui.Image> createTestImage({
int width = 1,
int height = 1,
bool cache = true,
}) => TestAsyncUtils.guard(() async {
assert(width != null && width > 0);
assert(height != null && height > 0);
assert(cache != null);
final int cacheKey = hashValues(width, height);
if (cache && _cache.containsKey(cacheKey)) {
return _cache[cacheKey];
}
final ui.Image image = await _createImage(width, height);
if (cache) {
_cache[cacheKey] = image;
}
return image;
});
Future<ui.Image> _createImage(int width, int height) async {
if (kIsWeb) {
return await _webCreateTestImage(
width: width,
height: height,
);
}
final Completer<ui.Image> completer = Completer<ui.Image>();
ui.decodeImageFromPixels(
Uint8List.fromList(List<int>.filled(width * height * 4, 0, growable: false)),
width,
height,
ui.PixelFormat.rgba8888,
(ui.Image image) {
completer.complete(image);
},
);
return await completer.future;
}
/// Web doesn't support [decodeImageFromPixels]. Instead, generate a 1bpp BMP
/// and just use [instantiateImageCodec].
// TODO(dnfield): Remove this when https://github.com/flutter/flutter/issues/49244
// is resolved.
Future<ui.Image> _webCreateTestImage({
int width,
int height,
}) async {
// See https://en.wikipedia.org/wiki/BMP_file_format for format examples.
final int bufferSize = 0x36 + (width * height);
final ByteData bmpData = ByteData(bufferSize);
// 'BM' header
bmpData.setUint8(0x00, 0x42);
bmpData.setUint8(0x01, 0x4D);
// Size of data
bmpData.setUint32(0x02, bufferSize, Endian.little);
// Offset where pixel array begins
bmpData.setUint32(0x0A, 0x36, Endian.little);
// Bytes in DIB header
bmpData.setUint32(0x0E, 0x28, Endian.little);
// width
bmpData.setUint32(0x12, width, Endian.little);
// height
bmpData.setUint32(0x16, height, Endian.little);
// Color panes
bmpData.setUint16(0x1A, 0x01, Endian.little);
// bpp
bmpData.setUint16(0x1C, 0x01, Endian.little);
// no compression
bmpData.setUint32(0x1E, 0x00, Endian.little);
// raw bitmap data size
bmpData.setUint32(0x22, width * height, Endian.little);
// print DPI width
bmpData.setUint32(0x26, width, Endian.little);
// print DPI height
bmpData.setUint32(0x2A, height, Endian.little);
// colors in the palette
bmpData.setUint32(0x2E, 0x00, Endian.little);
// important colors
bmpData.setUint32(0x32, 0x00, Endian.little);
// rest of data is zeroed as black pixels.
final ui.Codec codec = await ui.instantiateImageCodec(
bmpData.buffer.asUint8List(),
);
final ui.FrameInfo frameInfo = await codec.getNextFrame();
return frameInfo.image;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment