Allow new methods to be added to ui.Image for tests (#65876)
Remove fake image implementations, add createTestImage to flutter_test
This commit is contained in:
parent
8d2e257633
commit
7eb8447485
@ -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 @@
|
|||||||
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() {
|
|||||||
);
|
);
|
||||||
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() {
|
|||||||
},
|
},
|
||||||
<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) {
|
|||||||
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 @@
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
}, 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';
|
|||||||
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 {
|
|||||||
});
|
});
|
||||||
|
|
||||||
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';
|
|||||||
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';
|
|||||||
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';
|
|||||||
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
|
|||||||
|
|
||||||
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 @@
|
|||||||
|
|
||||||
// @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> [
|
|||||||
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';
|
|||||||
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;
|
|||||||
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 {
|
|||||||
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;
|
|
||||||
}
|
|
||||||
|
@ -6,8 +6,7 @@
|
|||||||
|
|
||||||
@TestOn('!chrome')
|
@TestOn('!chrome')
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:typed_data';
|
import 'dart:ui' as ui show Image, ColorFilter;
|
||||||
import 'dart:ui' as ui show Image, ImageByteFormat, ColorFilter;
|
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/painting.dart';
|
import 'package:flutter/painting.dart';
|
||||||
@ -29,6 +28,10 @@ class TestCanvas implements Canvas {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class SynchronousTestImageProvider extends ImageProvider<int> {
|
class SynchronousTestImageProvider extends ImageProvider<int> {
|
||||||
|
const SynchronousTestImageProvider(this.image);
|
||||||
|
|
||||||
|
final ui.Image image;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<int> obtainKey(ImageConfiguration configuration) {
|
Future<int> obtainKey(ImageConfiguration configuration) {
|
||||||
return SynchronousFuture<int>(1);
|
return SynchronousFuture<int>(1);
|
||||||
@ -37,7 +40,7 @@ class SynchronousTestImageProvider extends ImageProvider<int> {
|
|||||||
@override
|
@override
|
||||||
ImageStreamCompleter load(int key, DecoderCallback decode) {
|
ImageStreamCompleter load(int key, DecoderCallback decode) {
|
||||||
return OneFrameImageStreamCompleter(
|
return OneFrameImageStreamCompleter(
|
||||||
SynchronousFuture<ImageInfo>(TestImageInfo(key, image: TestImage(), scale: 1.0))
|
SynchronousFuture<ImageInfo>(TestImageInfo(key, image: image, scale: 1.0))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,6 +76,10 @@ class AsyncTestImageProvider extends ImageProvider<int> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class DelayedImageProvider extends ImageProvider<DelayedImageProvider> {
|
class DelayedImageProvider extends ImageProvider<DelayedImageProvider> {
|
||||||
|
DelayedImageProvider(this.image);
|
||||||
|
|
||||||
|
final ui.Image image;
|
||||||
|
|
||||||
final Completer<ImageInfo> _completer = Completer<ImageInfo>();
|
final Completer<ImageInfo> _completer = Completer<ImageInfo>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -85,30 +92,14 @@ class DelayedImageProvider extends ImageProvider<DelayedImageProvider> {
|
|||||||
return OneFrameImageStreamCompleter(_completer.future);
|
return OneFrameImageStreamCompleter(_completer.future);
|
||||||
}
|
}
|
||||||
|
|
||||||
void complete() {
|
Future<void> complete() async {
|
||||||
_completer.complete(ImageInfo(image: TestImage()));
|
_completer.complete(ImageInfo(image: image));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => '${describeIdentity(this)}()';
|
String toString() => '${describeIdentity(this)}()';
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestImage implements ui.Image {
|
|
||||||
@override
|
|
||||||
int get width => 100;
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get height => 100;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() { }
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<ByteData> toByteData({ ui.ImageByteFormat format = ui.ImageByteFormat.rawRgba }) async {
|
|
||||||
throw UnsupportedError('Cannot encode test image');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
TestRenderingFlutterBinding(); // initializes the imageCache
|
TestRenderingFlutterBinding(); // initializes the imageCache
|
||||||
|
|
||||||
@ -141,8 +132,9 @@ void main() {
|
|||||||
expect(a, equals(b));
|
expect(a, equals(b));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('BoxDecorationImageListenerSync', () {
|
test('BoxDecorationImageListenerSync', () async {
|
||||||
final ImageProvider imageProvider = SynchronousTestImageProvider();
|
final ui.Image image = await createTestImage(width: 100, height: 100);
|
||||||
|
final ImageProvider imageProvider = SynchronousTestImageProvider(image);
|
||||||
final DecorationImage backgroundImage = DecorationImage(image: imageProvider);
|
final DecorationImage backgroundImage = DecorationImage(image: imageProvider);
|
||||||
|
|
||||||
final BoxDecoration boxDecoration = BoxDecoration(image: backgroundImage);
|
final BoxDecoration boxDecoration = BoxDecoration(image: backgroundImage);
|
||||||
@ -183,11 +175,12 @@ void main() {
|
|||||||
|
|
||||||
// Regression test for https://github.com/flutter/flutter/issues/7289.
|
// Regression test for https://github.com/flutter/flutter/issues/7289.
|
||||||
// A reference test would be better.
|
// A reference test would be better.
|
||||||
test('BoxDecoration backgroundImage clip', () {
|
test('BoxDecoration backgroundImage clip', () async {
|
||||||
|
final ui.Image image = await createTestImage(width: 100, height: 100);
|
||||||
void testDecoration({ BoxShape shape = BoxShape.rectangle, BorderRadius borderRadius, bool expectClip }) {
|
void testDecoration({ BoxShape shape = BoxShape.rectangle, BorderRadius borderRadius, bool expectClip }) {
|
||||||
assert(shape != null);
|
assert(shape != null);
|
||||||
FakeAsync().run((FakeAsync async) {
|
FakeAsync().run((FakeAsync async) async {
|
||||||
final DelayedImageProvider imageProvider = DelayedImageProvider();
|
final DelayedImageProvider imageProvider = DelayedImageProvider(image);
|
||||||
final DecorationImage backgroundImage = DecorationImage(image: imageProvider);
|
final DecorationImage backgroundImage = DecorationImage(image: imageProvider);
|
||||||
|
|
||||||
final BoxDecoration boxDecoration = BoxDecoration(
|
final BoxDecoration boxDecoration = BoxDecoration(
|
||||||
@ -209,7 +202,7 @@ void main() {
|
|||||||
// _BoxDecorationPainter._paintDecorationImage() resolves the background
|
// _BoxDecorationPainter._paintDecorationImage() resolves the background
|
||||||
// image and adds a listener to the resolved image stream.
|
// image and adds a listener to the resolved image stream.
|
||||||
boxPainter.paint(canvas, Offset.zero, imageConfiguration);
|
boxPainter.paint(canvas, Offset.zero, imageConfiguration);
|
||||||
imageProvider.complete();
|
await imageProvider.complete();
|
||||||
|
|
||||||
// Run the listener which calls onChanged() which saves an internal
|
// Run the listener which calls onChanged() which saves an internal
|
||||||
// reference to the TestImage.
|
// reference to the TestImage.
|
||||||
@ -237,10 +230,11 @@ void main() {
|
|||||||
testDecoration(expectClip: false);
|
testDecoration(expectClip: false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('DecorationImage test', () {
|
test('DecorationImage test', () async {
|
||||||
const ColorFilter colorFilter = ui.ColorFilter.mode(Color(0xFF00FF00), BlendMode.src);
|
const ColorFilter colorFilter = ui.ColorFilter.mode(Color(0xFF00FF00), BlendMode.src);
|
||||||
|
final ui.Image image = await createTestImage(width: 100, height: 100);
|
||||||
final DecorationImage backgroundImage = DecorationImage(
|
final DecorationImage backgroundImage = DecorationImage(
|
||||||
image: SynchronousTestImageProvider(),
|
image: SynchronousTestImageProvider(image),
|
||||||
colorFilter: colorFilter,
|
colorFilter: colorFilter,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
alignment: Alignment.bottomLeft,
|
alignment: Alignment.bottomLeft,
|
||||||
@ -256,7 +250,7 @@ void main() {
|
|||||||
final Invocation call = canvas.invocations.singleWhere((Invocation call) => call.memberName == #drawImageNine);
|
final Invocation call = canvas.invocations.singleWhere((Invocation call) => call.memberName == #drawImageNine);
|
||||||
expect(call.isMethod, isTrue);
|
expect(call.isMethod, isTrue);
|
||||||
expect(call.positionalArguments, hasLength(4));
|
expect(call.positionalArguments, hasLength(4));
|
||||||
expect(call.positionalArguments[0], isA<TestImage>());
|
expect(call.positionalArguments[0], isA<ui.Image>());
|
||||||
expect(call.positionalArguments[1], const Rect.fromLTRB(10.0, 20.0, 40.0, 60.0));
|
expect(call.positionalArguments[1], const Rect.fromLTRB(10.0, 20.0, 40.0, 60.0));
|
||||||
expect(call.positionalArguments[2], const Rect.fromLTRB(0.0, 0.0, 100.0, 100.0));
|
expect(call.positionalArguments[2], const Rect.fromLTRB(0.0, 0.0, 100.0, 100.0));
|
||||||
expect(call.positionalArguments[3], isA<Paint>());
|
expect(call.positionalArguments[3], isA<Paint>());
|
||||||
@ -265,10 +259,10 @@ void main() {
|
|||||||
expect(call.positionalArguments[3].filterQuality, FilterQuality.low);
|
expect(call.positionalArguments[3].filterQuality, FilterQuality.low);
|
||||||
});
|
});
|
||||||
|
|
||||||
test(
|
test('DecorationImage with null textDirection configuration should throw Error', () async {
|
||||||
'DecorationImage with null textDirection configuration should throw Error', () {
|
final ui.Image image = await createTestImage(width: 100, height: 100);
|
||||||
final DecorationImage backgroundImage = DecorationImage(
|
final DecorationImage backgroundImage = DecorationImage(
|
||||||
image: SynchronousTestImageProvider(),
|
image: SynchronousTestImageProvider(image),
|
||||||
matchTextDirection: true,
|
matchTextDirection: true,
|
||||||
);
|
);
|
||||||
final BoxDecoration boxDecoration = BoxDecoration(
|
final BoxDecoration boxDecoration = BoxDecoration(
|
||||||
@ -434,12 +428,12 @@ void main() {
|
|||||||
expect(Decoration.lerp(const FlutterLogoDecoration(), const BoxDecoration(), 1.0), isA<BoxDecoration>());
|
expect(Decoration.lerp(const FlutterLogoDecoration(), const BoxDecoration(), 1.0), isA<BoxDecoration>());
|
||||||
});
|
});
|
||||||
|
|
||||||
test('paintImage BoxFit.none scale test', () {
|
test('paintImage BoxFit.none scale test', () async {
|
||||||
for (double scale = 1.0; scale <= 4.0; scale += 1.0) {
|
for (double scale = 1.0; scale <= 4.0; scale += 1.0) {
|
||||||
final TestCanvas canvas = TestCanvas(<Invocation>[]);
|
final TestCanvas canvas = TestCanvas(<Invocation>[]);
|
||||||
|
|
||||||
const Rect outputRect = Rect.fromLTWH(30.0, 30.0, 250.0, 250.0);
|
const Rect outputRect = Rect.fromLTWH(30.0, 30.0, 250.0, 250.0);
|
||||||
final ui.Image image = TestImage();
|
final ui.Image image = await createTestImage(width: 100, height: 100);
|
||||||
|
|
||||||
paintImage(
|
paintImage(
|
||||||
canvas: canvas,
|
canvas: canvas,
|
||||||
@ -459,7 +453,7 @@ void main() {
|
|||||||
expect(call.isMethod, isTrue);
|
expect(call.isMethod, isTrue);
|
||||||
expect(call.positionalArguments, hasLength(4));
|
expect(call.positionalArguments, hasLength(4));
|
||||||
|
|
||||||
expect(call.positionalArguments[0], isA<TestImage>());
|
expect(call.positionalArguments[0], isA<ui.Image>());
|
||||||
|
|
||||||
// sourceRect should contain all pixels of the source image
|
// sourceRect should contain all pixels of the source image
|
||||||
expect(call.positionalArguments[1], Offset.zero & imageSize);
|
expect(call.positionalArguments[1], Offset.zero & imageSize);
|
||||||
@ -477,13 +471,13 @@ void main() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('paintImage BoxFit.scaleDown scale test', () {
|
test('paintImage BoxFit.scaleDown scale test', () async {
|
||||||
for (double scale = 1.0; scale <= 4.0; scale += 1.0) {
|
for (double scale = 1.0; scale <= 4.0; scale += 1.0) {
|
||||||
final TestCanvas canvas = TestCanvas(<Invocation>[]);
|
final TestCanvas canvas = TestCanvas(<Invocation>[]);
|
||||||
|
|
||||||
// container size > scaled image size
|
// container size > scaled image size
|
||||||
const Rect outputRect = Rect.fromLTWH(30.0, 30.0, 250.0, 250.0);
|
const Rect outputRect = Rect.fromLTWH(30.0, 30.0, 250.0, 250.0);
|
||||||
final ui.Image image = TestImage();
|
final ui.Image image = await createTestImage(width: 100, height: 100);
|
||||||
|
|
||||||
paintImage(
|
paintImage(
|
||||||
canvas: canvas,
|
canvas: canvas,
|
||||||
@ -503,7 +497,7 @@ void main() {
|
|||||||
expect(call.isMethod, isTrue);
|
expect(call.isMethod, isTrue);
|
||||||
expect(call.positionalArguments, hasLength(4));
|
expect(call.positionalArguments, hasLength(4));
|
||||||
|
|
||||||
expect(call.positionalArguments[0], isA<TestImage>());
|
expect(call.positionalArguments[0], isA<ui.Image>());
|
||||||
|
|
||||||
// sourceRect should contain all pixels of the source image
|
// sourceRect should contain all pixels of the source image
|
||||||
expect(call.positionalArguments[1], Offset.zero & imageSize);
|
expect(call.positionalArguments[1], Offset.zero & imageSize);
|
||||||
@ -521,12 +515,12 @@ void main() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('paintImage BoxFit.scaleDown test', () {
|
test('paintImage BoxFit.scaleDown test', () async {
|
||||||
final TestCanvas canvas = TestCanvas(<Invocation>[]);
|
final TestCanvas canvas = TestCanvas(<Invocation>[]);
|
||||||
|
|
||||||
// container height (20 px) < scaled image height (50 px)
|
// container height (20 px) < scaled image height (50 px)
|
||||||
const Rect outputRect = Rect.fromLTWH(30.0, 30.0, 250.0, 20.0);
|
const Rect outputRect = Rect.fromLTWH(30.0, 30.0, 250.0, 20.0);
|
||||||
final ui.Image image = TestImage();
|
final ui.Image image = await createTestImage(width: 100, height: 100);
|
||||||
|
|
||||||
paintImage(
|
paintImage(
|
||||||
canvas: canvas,
|
canvas: canvas,
|
||||||
@ -546,7 +540,7 @@ void main() {
|
|||||||
expect(call.isMethod, isTrue);
|
expect(call.isMethod, isTrue);
|
||||||
expect(call.positionalArguments, hasLength(4));
|
expect(call.positionalArguments, hasLength(4));
|
||||||
|
|
||||||
expect(call.positionalArguments[0], isA<TestImage>());
|
expect(call.positionalArguments[0], isA<ui.Image>());
|
||||||
|
|
||||||
// sourceRect should contain all pixels of the source image
|
// sourceRect should contain all pixels of the source image
|
||||||
expect(call.positionalArguments[1], Offset.zero & imageSize);
|
expect(call.positionalArguments[1], Offset.zero & imageSize);
|
||||||
@ -563,7 +557,7 @@ void main() {
|
|||||||
expect(call.positionalArguments[3], isA<Paint>());
|
expect(call.positionalArguments[3], isA<Paint>());
|
||||||
});
|
});
|
||||||
|
|
||||||
test('paintImage boxFit, scale and alignment test', () {
|
test('paintImage boxFit, scale and alignment test', () async {
|
||||||
const List<BoxFit> boxFits = <BoxFit>[
|
const List<BoxFit> boxFits = <BoxFit>[
|
||||||
BoxFit.contain,
|
BoxFit.contain,
|
||||||
BoxFit.cover,
|
BoxFit.cover,
|
||||||
@ -578,7 +572,7 @@ void main() {
|
|||||||
final TestCanvas canvas = TestCanvas(<Invocation>[]);
|
final TestCanvas canvas = TestCanvas(<Invocation>[]);
|
||||||
|
|
||||||
const Rect outputRect = Rect.fromLTWH(30.0, 30.0, 250.0, 250.0);
|
const Rect outputRect = Rect.fromLTWH(30.0, 30.0, 250.0, 250.0);
|
||||||
final ui.Image image = TestImage();
|
final ui.Image image = await createTestImage(width: 100, height: 100);
|
||||||
|
|
||||||
paintImage(
|
paintImage(
|
||||||
canvas: canvas,
|
canvas: canvas,
|
||||||
@ -601,9 +595,10 @@ void main() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('scale cannot be null in DecorationImage', () {
|
test('scale cannot be null in DecorationImage', () async {
|
||||||
|
final ui.Image image = await createTestImage(width: 100, height: 100);
|
||||||
try {
|
try {
|
||||||
DecorationImage(scale: null, image: SynchronousTestImageProvider());
|
DecorationImage(scale: null, image: SynchronousTestImageProvider(image));
|
||||||
} on AssertionError catch (error) {
|
} on AssertionError catch (error) {
|
||||||
expect(error.toString(), contains('scale != null'));
|
expect(error.toString(), contains('scale != null'));
|
||||||
expect(error.toString(), contains('is not true'));
|
expect(error.toString(), contains('is not true'));
|
||||||
@ -612,9 +607,10 @@ void main() {
|
|||||||
fail('DecorationImage did not throw AssertionError when scale was null');
|
fail('DecorationImage did not throw AssertionError when scale was null');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('DecorationImage scale test', () {
|
test('DecorationImage scale test', () async {
|
||||||
|
final ui.Image image = await createTestImage(width: 100, height: 100);
|
||||||
final DecorationImage backgroundImage = DecorationImage(
|
final DecorationImage backgroundImage = DecorationImage(
|
||||||
image: SynchronousTestImageProvider(),
|
image: SynchronousTestImageProvider(image),
|
||||||
scale: 4,
|
scale: 4,
|
||||||
alignment: Alignment.topLeft
|
alignment: Alignment.topLeft
|
||||||
);
|
);
|
||||||
|
@ -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 @@
|
|||||||
|
|
||||||
// @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() {
|
|||||||
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() {
|
|||||||
|
|
||||||
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() {
|
|||||||
|
|
||||||
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));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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';
|
||||||
|
|
||||||
@ -23,82 +25,82 @@ void main() {
|
|||||||
test('maintains cache size', () async {
|
test('maintains cache size', () async {
|
||||||
imageCache.maximumSize = 3;
|
imageCache.maximumSize = 3;
|
||||||
|
|
||||||
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;
|
||||||
expect(a.value, equals(1));
|
expect(a.value, equals(1));
|
||||||
final TestImageInfo b = await extractOneFrame(const TestImageProvider(1, 2).resolve(ImageConfiguration.empty)) as TestImageInfo;
|
final TestImageInfo b = await extractOneFrame(TestImageProvider(1, 2, image: await createTestImage()).resolve(ImageConfiguration.empty)) as TestImageInfo;
|
||||||
expect(b.value, equals(1));
|
expect(b.value, equals(1));
|
||||||
final TestImageInfo c = await extractOneFrame(const TestImageProvider(1, 3).resolve(ImageConfiguration.empty)) as TestImageInfo;
|
final TestImageInfo c = await extractOneFrame(TestImageProvider(1, 3, image: await createTestImage()).resolve(ImageConfiguration.empty)) as TestImageInfo;
|
||||||
expect(c.value, equals(1));
|
expect(c.value, equals(1));
|
||||||
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(d.value, equals(1));
|
expect(d.value, equals(1));
|
||||||
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(1));
|
expect(e.value, equals(1));
|
||||||
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(1));
|
expect(f.value, equals(1));
|
||||||
|
|
||||||
expect(f, equals(a));
|
expect(f, equals(a));
|
||||||
|
|
||||||
// cache still only has one entry in it: 1(1)
|
// cache still only has one entry in it: 1(1)
|
||||||
|
|
||||||
final TestImageInfo g = await extractOneFrame(const TestImageProvider(2, 7).resolve(ImageConfiguration.empty)) as TestImageInfo;
|
final TestImageInfo g = await extractOneFrame(TestImageProvider(2, 7, image: await createTestImage()).resolve(ImageConfiguration.empty)) as TestImageInfo;
|
||||||
expect(g.value, equals(7));
|
expect(g.value, equals(7));
|
||||||
|
|
||||||
// cache has two entries in it: 1(1), 2(7)
|
// cache has two entries in it: 1(1), 2(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(1));
|
expect(h.value, equals(1));
|
||||||
|
|
||||||
// cache still has two entries in it: 2(7), 1(1)
|
// cache still has two entries in it: 2(7), 1(1)
|
||||||
|
|
||||||
final TestImageInfo i = await extractOneFrame(const TestImageProvider(3, 9).resolve(ImageConfiguration.empty)) as TestImageInfo;
|
final TestImageInfo i = await extractOneFrame(TestImageProvider(3, 9, image: await createTestImage()).resolve(ImageConfiguration.empty)) as TestImageInfo;
|
||||||
expect(i.value, equals(9));
|
expect(i.value, equals(9));
|
||||||
|
|
||||||
// cache has three entries in it: 2(7), 1(1), 3(9)
|
// cache has three entries in it: 2(7), 1(1), 3(9)
|
||||||
|
|
||||||
final TestImageInfo j = await extractOneFrame(const TestImageProvider(1, 10).resolve(ImageConfiguration.empty)) as TestImageInfo;
|
final TestImageInfo j = await extractOneFrame(TestImageProvider(1, 10, image: await createTestImage()).resolve(ImageConfiguration.empty)) as TestImageInfo;
|
||||||
expect(j.value, equals(1));
|
expect(j.value, equals(1));
|
||||||
|
|
||||||
// cache still has three entries in it: 2(7), 3(9), 1(1)
|
// cache still has three entries in it: 2(7), 3(9), 1(1)
|
||||||
|
|
||||||
final TestImageInfo k = await extractOneFrame(const TestImageProvider(4, 11).resolve(ImageConfiguration.empty)) as TestImageInfo;
|
final TestImageInfo k = await extractOneFrame(TestImageProvider(4, 11, image: await createTestImage()).resolve(ImageConfiguration.empty)) as TestImageInfo;
|
||||||
expect(k.value, equals(11));
|
expect(k.value, equals(11));
|
||||||
|
|
||||||
// cache has three entries: 3(9), 1(1), 4(11)
|
// cache has three entries: 3(9), 1(1), 4(11)
|
||||||
|
|
||||||
final TestImageInfo l = await extractOneFrame(const TestImageProvider(1, 12).resolve(ImageConfiguration.empty)) as TestImageInfo;
|
final TestImageInfo l = await extractOneFrame(TestImageProvider(1, 12, image: await createTestImage()).resolve(ImageConfiguration.empty)) as TestImageInfo;
|
||||||
expect(l.value, equals(1));
|
expect(l.value, equals(1));
|
||||||
|
|
||||||
// cache has three entries: 3(9), 4(11), 1(1)
|
// cache has three entries: 3(9), 4(11), 1(1)
|
||||||
|
|
||||||
final TestImageInfo m = await extractOneFrame(const TestImageProvider(2, 13).resolve(ImageConfiguration.empty)) as TestImageInfo;
|
final TestImageInfo m = await extractOneFrame(TestImageProvider(2, 13, image: await createTestImage()).resolve(ImageConfiguration.empty)) as TestImageInfo;
|
||||||
expect(m.value, equals(13));
|
expect(m.value, equals(13));
|
||||||
|
|
||||||
// cache has three entries: 4(11), 1(1), 2(13)
|
// cache has three entries: 4(11), 1(1), 2(13)
|
||||||
|
|
||||||
final TestImageInfo n = await extractOneFrame(const TestImageProvider(3, 14).resolve(ImageConfiguration.empty)) as TestImageInfo;
|
final TestImageInfo n = await extractOneFrame(TestImageProvider(3, 14, image: await createTestImage()).resolve(ImageConfiguration.empty)) as TestImageInfo;
|
||||||
expect(n.value, equals(14));
|
expect(n.value, equals(14));
|
||||||
|
|
||||||
// cache has three entries: 1(1), 2(13), 3(14)
|
// cache has three entries: 1(1), 2(13), 3(14)
|
||||||
|
|
||||||
final TestImageInfo o = await extractOneFrame(const TestImageProvider(4, 15).resolve(ImageConfiguration.empty)) as TestImageInfo;
|
final TestImageInfo o = await extractOneFrame(TestImageProvider(4, 15, image: await createTestImage()).resolve(ImageConfiguration.empty)) as TestImageInfo;
|
||||||
expect(o.value, equals(15));
|
expect(o.value, equals(15));
|
||||||
|
|
||||||
// cache has three entries: 2(13), 3(14), 4(15)
|
// cache has three entries: 2(13), 3(14), 4(15)
|
||||||
|
|
||||||
final TestImageInfo p = await extractOneFrame(const TestImageProvider(1, 16).resolve(ImageConfiguration.empty)) as TestImageInfo;
|
final TestImageInfo p = await extractOneFrame(TestImageProvider(1, 16, image: await createTestImage()).resolve(ImageConfiguration.empty)) as TestImageInfo;
|
||||||
expect(p.value, equals(16));
|
expect(p.value, equals(16));
|
||||||
|
|
||||||
// cache has three entries: 3(14), 4(15), 1(16)
|
// cache has three entries: 3(14), 4(15), 1(16)
|
||||||
});
|
});
|
||||||
|
|
||||||
test('clear removes all images and resets cache size', () async {
|
test('clear removes all images and resets cache size', () async {
|
||||||
const TestImage testImage = TestImage(width: 8, height: 8);
|
final ui.Image testImage = await createTestImage(width: 8, height: 8);
|
||||||
|
|
||||||
expect(imageCache.currentSize, 0);
|
expect(imageCache.currentSize, 0);
|
||||||
expect(imageCache.currentSizeBytes, 0);
|
expect(imageCache.currentSizeBytes, 0);
|
||||||
|
|
||||||
await extractOneFrame(const TestImageProvider(1, 1, image: testImage).resolve(ImageConfiguration.empty));
|
await extractOneFrame(TestImageProvider(1, 1, image: testImage).resolve(ImageConfiguration.empty));
|
||||||
await extractOneFrame(const TestImageProvider(2, 2, image: testImage).resolve(ImageConfiguration.empty));
|
await extractOneFrame(TestImageProvider(2, 2, image: testImage).resolve(ImageConfiguration.empty));
|
||||||
|
|
||||||
expect(imageCache.currentSize, 2);
|
expect(imageCache.currentSize, 2);
|
||||||
expect(imageCache.currentSizeBytes, 256 * 2);
|
expect(imageCache.currentSizeBytes, 256 * 2);
|
||||||
@ -110,9 +112,9 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('evicts individual images', () async {
|
test('evicts individual images', () async {
|
||||||
const TestImage testImage = TestImage(width: 8, height: 8);
|
final ui.Image testImage = await createTestImage(width: 8, height: 8);
|
||||||
await extractOneFrame(const TestImageProvider(1, 1, image: testImage).resolve(ImageConfiguration.empty));
|
await extractOneFrame(TestImageProvider(1, 1, image: testImage).resolve(ImageConfiguration.empty));
|
||||||
await extractOneFrame(const TestImageProvider(2, 2, image: testImage).resolve(ImageConfiguration.empty));
|
await extractOneFrame(TestImageProvider(2, 2, image: testImage).resolve(ImageConfiguration.empty));
|
||||||
|
|
||||||
expect(imageCache.currentSize, 2);
|
expect(imageCache.currentSize, 2);
|
||||||
expect(imageCache.currentSizeBytes, 256 * 2);
|
expect(imageCache.currentSizeBytes, 256 * 2);
|
||||||
@ -122,10 +124,10 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Do not cache large images', () async {
|
test('Do not cache large images', () async {
|
||||||
const TestImage testImage = TestImage(width: 8, height: 8);
|
final ui.Image testImage = await createTestImage(width: 8, height: 8);
|
||||||
|
|
||||||
imageCache.maximumSizeBytes = 1;
|
imageCache.maximumSizeBytes = 1;
|
||||||
await extractOneFrame(const TestImageProvider(1, 1, image: testImage).resolve(ImageConfiguration.empty));
|
await extractOneFrame(TestImageProvider(1, 1, image: testImage).resolve(ImageConfiguration.empty));
|
||||||
expect(imageCache.currentSize, 0);
|
expect(imageCache.currentSize, 0);
|
||||||
expect(imageCache.currentSizeBytes, 0);
|
expect(imageCache.currentSizeBytes, 0);
|
||||||
expect(imageCache.maximumSizeBytes, 1);
|
expect(imageCache.maximumSizeBytes, 1);
|
||||||
@ -143,7 +145,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('already pending image is returned when it is put into the cache again', () async {
|
test('already pending image is returned when it is put into the cache again', () async {
|
||||||
const TestImage testImage = TestImage(width: 8, height: 8);
|
final ui.Image testImage = await createTestImage(width: 8, height: 8);
|
||||||
|
|
||||||
final TestImageStreamCompleter completer1 = TestImageStreamCompleter();
|
final TestImageStreamCompleter completer1 = TestImageStreamCompleter();
|
||||||
final TestImageStreamCompleter completer2 = TestImageStreamCompleter();
|
final TestImageStreamCompleter completer2 = TestImageStreamCompleter();
|
||||||
@ -160,7 +162,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('pending image is removed when cache is cleared', () async {
|
test('pending image is removed when cache is cleared', () async {
|
||||||
const TestImage testImage = TestImage(width: 8, height: 8);
|
final ui.Image testImage = await createTestImage(width: 8, height: 8);
|
||||||
|
|
||||||
final TestImageStreamCompleter completer1 = TestImageStreamCompleter();
|
final TestImageStreamCompleter completer1 = TestImageStreamCompleter();
|
||||||
final TestImageStreamCompleter completer2 = TestImageStreamCompleter();
|
final TestImageStreamCompleter completer2 = TestImageStreamCompleter();
|
||||||
@ -187,7 +189,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('pending image is removed when image is evicted', () async {
|
test('pending image is removed when image is evicted', () async {
|
||||||
const TestImage testImage = TestImage(width: 8, height: 8);
|
final ui.Image testImage = await createTestImage(width: 8, height: 8);
|
||||||
|
|
||||||
final TestImageStreamCompleter completer1 = TestImageStreamCompleter();
|
final TestImageStreamCompleter completer1 = TestImageStreamCompleter();
|
||||||
final TestImageStreamCompleter completer2 = TestImageStreamCompleter();
|
final TestImageStreamCompleter completer2 = TestImageStreamCompleter();
|
||||||
@ -207,21 +209,25 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("failed image can successfully be removed from the cache's pending images", () async {
|
test("failed image can successfully be removed from the cache's pending images", () async {
|
||||||
const TestImage testImage = TestImage(width: 8, height: 8);
|
final ui.Image testImage = await createTestImage(width: 8, height: 8);
|
||||||
|
|
||||||
const FailingTestImageProvider(1, 1, image: testImage)
|
FailingTestImageProvider(1, 1, image: testImage)
|
||||||
.resolve(ImageConfiguration.empty)
|
.resolve(ImageConfiguration.empty)
|
||||||
.addListener(ImageStreamListener(
|
.addListener(ImageStreamListener(
|
||||||
(ImageInfo image, bool synchronousCall) { },
|
(ImageInfo image, bool synchronousCall) {
|
||||||
|
fail('Image should not complete successfully');
|
||||||
|
},
|
||||||
onError: (dynamic exception, StackTrace stackTrace) {
|
onError: (dynamic exception, StackTrace stackTrace) {
|
||||||
final bool evictionResult = imageCache.evict(1);
|
final bool evictionResult = imageCache.evict(1);
|
||||||
expect(evictionResult, isTrue);
|
expect(evictionResult, isTrue);
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
// yield an event turn so that async work can complete.
|
||||||
|
await null;
|
||||||
});
|
});
|
||||||
|
|
||||||
test('containsKey - pending', () async {
|
test('containsKey - pending', () async {
|
||||||
const TestImage testImage = TestImage(width: 8, height: 8);
|
final ui.Image testImage = await createTestImage(width: 8, height: 8);
|
||||||
|
|
||||||
final TestImageStreamCompleter completer1 = TestImageStreamCompleter();
|
final TestImageStreamCompleter completer1 = TestImageStreamCompleter();
|
||||||
|
|
||||||
@ -234,7 +240,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('containsKey - completed', () async {
|
test('containsKey - completed', () async {
|
||||||
const TestImage testImage = TestImage(width: 8, height: 8);
|
final ui.Image testImage = await createTestImage(width: 8, height: 8);
|
||||||
|
|
||||||
final TestImageStreamCompleter completer1 = TestImageStreamCompleter();
|
final TestImageStreamCompleter completer1 = TestImageStreamCompleter();
|
||||||
|
|
||||||
@ -251,8 +257,8 @@ void main() {
|
|||||||
|
|
||||||
test('putIfAbsent updates LRU properties of a live image', () async {
|
test('putIfAbsent updates LRU properties of a live image', () async {
|
||||||
imageCache.maximumSize = 1;
|
imageCache.maximumSize = 1;
|
||||||
const TestImage testImage = TestImage(width: 8, height: 8);
|
final ui.Image testImage = await createTestImage(width: 8, height: 8);
|
||||||
const TestImage testImage2 = TestImage(width: 10, height: 10);
|
final ui.Image testImage2 = await createTestImage(width: 10, height: 10);
|
||||||
|
|
||||||
final TestImageStreamCompleter completer1 = TestImageStreamCompleter()..testSetImage(testImage);
|
final TestImageStreamCompleter completer1 = TestImageStreamCompleter()..testSetImage(testImage);
|
||||||
final TestImageStreamCompleter completer2 = TestImageStreamCompleter()..testSetImage(testImage2);
|
final TestImageStreamCompleter completer2 = TestImageStreamCompleter()..testSetImage(testImage2);
|
||||||
@ -286,12 +292,12 @@ void main() {
|
|||||||
test('Live image cache avoids leaks of unlistened streams', () async {
|
test('Live image cache avoids leaks of unlistened streams', () async {
|
||||||
imageCache.maximumSize = 3;
|
imageCache.maximumSize = 3;
|
||||||
|
|
||||||
const TestImageProvider(1, 1).resolve(ImageConfiguration.empty);
|
TestImageProvider(1, 1, image: await createTestImage()).resolve(ImageConfiguration.empty);
|
||||||
const TestImageProvider(2, 2).resolve(ImageConfiguration.empty);
|
TestImageProvider(2, 2, image: await createTestImage()).resolve(ImageConfiguration.empty);
|
||||||
const TestImageProvider(3, 3).resolve(ImageConfiguration.empty);
|
TestImageProvider(3, 3, image: await createTestImage()).resolve(ImageConfiguration.empty);
|
||||||
const TestImageProvider(4, 4).resolve(ImageConfiguration.empty);
|
TestImageProvider(4, 4, image: await createTestImage()).resolve(ImageConfiguration.empty);
|
||||||
const TestImageProvider(5, 5).resolve(ImageConfiguration.empty);
|
TestImageProvider(5, 5, image: await createTestImage()).resolve(ImageConfiguration.empty);
|
||||||
const TestImageProvider(6, 6).resolve(ImageConfiguration.empty);
|
TestImageProvider(6, 6, image: await createTestImage()).resolve(ImageConfiguration.empty);
|
||||||
|
|
||||||
// wait an event loop to let image resolution process.
|
// wait an event loop to let image resolution process.
|
||||||
await null;
|
await null;
|
||||||
@ -303,12 +309,12 @@ void main() {
|
|||||||
test('Disabled image cache does not leak live images', () async {
|
test('Disabled image cache does not leak live images', () async {
|
||||||
imageCache.maximumSize = 0;
|
imageCache.maximumSize = 0;
|
||||||
|
|
||||||
const TestImageProvider(1, 1).resolve(ImageConfiguration.empty);
|
TestImageProvider(1, 1, image: await createTestImage()).resolve(ImageConfiguration.empty);
|
||||||
const TestImageProvider(2, 2).resolve(ImageConfiguration.empty);
|
TestImageProvider(2, 2, image: await createTestImage()).resolve(ImageConfiguration.empty);
|
||||||
const TestImageProvider(3, 3).resolve(ImageConfiguration.empty);
|
TestImageProvider(3, 3, image: await createTestImage()).resolve(ImageConfiguration.empty);
|
||||||
const TestImageProvider(4, 4).resolve(ImageConfiguration.empty);
|
TestImageProvider(4, 4, image: await createTestImage()).resolve(ImageConfiguration.empty);
|
||||||
const TestImageProvider(5, 5).resolve(ImageConfiguration.empty);
|
TestImageProvider(5, 5, image: await createTestImage()).resolve(ImageConfiguration.empty);
|
||||||
const TestImageProvider(6, 6).resolve(ImageConfiguration.empty);
|
TestImageProvider(6, 6, image: await createTestImage()).resolve(ImageConfiguration.empty);
|
||||||
|
|
||||||
// wait an event loop to let image resolution process.
|
// wait an event loop to let image resolution process.
|
||||||
await null;
|
await null;
|
||||||
@ -318,7 +324,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Evicting a pending image clears the live image by default', () async {
|
test('Evicting a pending image clears the live image by default', () async {
|
||||||
const TestImage testImage = TestImage(width: 8, height: 8);
|
final ui.Image testImage = await createTestImage(width: 8, height: 8);
|
||||||
|
|
||||||
final TestImageStreamCompleter completer1 = TestImageStreamCompleter();
|
final TestImageStreamCompleter completer1 = TestImageStreamCompleter();
|
||||||
|
|
||||||
@ -332,7 +338,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Evicting a pending image does clear the live image when includeLive is false and only cache listening', () async {
|
test('Evicting a pending image does clear the live image when includeLive is false and only cache listening', () async {
|
||||||
const TestImage testImage = TestImage(width: 8, height: 8);
|
final ui.Image testImage = await createTestImage(width: 8, height: 8);
|
||||||
|
|
||||||
final TestImageStreamCompleter completer1 = TestImageStreamCompleter();
|
final TestImageStreamCompleter completer1 = TestImageStreamCompleter();
|
||||||
|
|
||||||
@ -348,7 +354,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Evicting a pending image does clear the live image when includeLive is false and some other listener', () async {
|
test('Evicting a pending image does clear the live image when includeLive is false and some other listener', () async {
|
||||||
const TestImage testImage = TestImage(width: 8, height: 8);
|
final ui.Image testImage = await createTestImage(width: 8, height: 8);
|
||||||
|
|
||||||
final TestImageStreamCompleter completer1 = TestImageStreamCompleter();
|
final TestImageStreamCompleter completer1 = TestImageStreamCompleter();
|
||||||
|
|
||||||
@ -365,7 +371,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Evicting a completed image does clear the live image by default', () async {
|
test('Evicting a completed image does clear the live image by default', () async {
|
||||||
const TestImage testImage = TestImage(width: 8, height: 8);
|
final ui.Image testImage = await createTestImage(width: 8, height: 8);
|
||||||
|
|
||||||
final TestImageStreamCompleter completer1 = TestImageStreamCompleter()
|
final TestImageStreamCompleter completer1 = TestImageStreamCompleter()
|
||||||
..testSetImage(testImage)
|
..testSetImage(testImage)
|
||||||
@ -381,7 +387,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Evicting a completed image does not clear the live image when includeLive is set to false', () async {
|
test('Evicting a completed image does not clear the live image when includeLive is set to false', () async {
|
||||||
const TestImage testImage = TestImage(width: 8, height: 8);
|
final ui.Image testImage = await createTestImage(width: 8, height: 8);
|
||||||
|
|
||||||
final TestImageStreamCompleter completer1 = TestImageStreamCompleter()
|
final TestImageStreamCompleter completer1 = TestImageStreamCompleter()
|
||||||
..testSetImage(testImage)
|
..testSetImage(testImage)
|
||||||
@ -399,7 +405,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Clearing liveImages removes callbacks', () async {
|
test('Clearing liveImages removes callbacks', () async {
|
||||||
const TestImage testImage = TestImage(width: 8, height: 8);
|
final ui.Image testImage = await createTestImage(width: 8, height: 8);
|
||||||
|
|
||||||
final ImageStreamListener listener = ImageStreamListener((ImageInfo info, bool syncCall) {});
|
final ImageStreamListener listener = ImageStreamListener((ImageInfo info, bool syncCall) {});
|
||||||
|
|
||||||
@ -442,7 +448,7 @@ void main() {
|
|||||||
// If the live image did not track the size properly, the last line of
|
// If the live image did not track the size properly, the last line of
|
||||||
// this test will fail.
|
// this test will fail.
|
||||||
|
|
||||||
const TestImage testImage = TestImage(width: 8, height: 8);
|
final ui.Image testImage = await createTestImage(width: 8, height: 8);
|
||||||
const int testImageSize = 8 * 8 * 4;
|
const int testImageSize = 8 * 8 * 4;
|
||||||
|
|
||||||
final ImageStreamListener listener = ImageStreamListener((ImageInfo info, bool syncCall) {});
|
final ImageStreamListener listener = ImageStreamListener((ImageInfo info, bool syncCall) {});
|
||||||
|
@ -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';
|
|||||||
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';
|
|||||||
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';
|
|||||||
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() {
|
|||||||
|
|
||||||
|
|
||||||
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';
|
|||||||
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() {
|
|||||||
|
|
||||||
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() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
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() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
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 {
|
|||||||
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 @@
|
|||||||
// @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> {
|
|||||||
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 @@
|
|||||||
// @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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
|||||||
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
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 @@
|
|||||||
|
|
||||||
// @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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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 @@
|
|||||||
|
|
||||||
// @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() {
|
|||||||
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() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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> {
|
|||||||
@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 @@
|
|||||||
|
|
||||||
// @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() {
|
|||||||
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() {
|
|||||||
' 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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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';
|
|||||||
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;
|
|||||||
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);
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
// 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';
|
|||||||
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';
|
|||||||
|
|
||||||
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() {
|
|||||||
|
|
||||||
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),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
@TestOn('!chrome') // asset bundle behaves differently.
|
@TestOn('!chrome') // asset bundle behaves differently.
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'dart:ui' as ui show Image, ImageByteFormat;
|
import 'dart:ui' as ui show Image;
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
@ -14,26 +14,7 @@ import 'package:flutter/services.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 'image_data.dart';
|
import '../image_data.dart';
|
||||||
|
|
||||||
class TestImage implements ui.Image {
|
|
||||||
TestImage(this.scale);
|
|
||||||
final double scale;
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get width => (48*scale).floor();
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get height => (48*scale).floor();
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() { }
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<ByteData> toByteData({ ui.ImageByteFormat format = ui.ImageByteFormat.rawRgba }) async {
|
|
||||||
throw UnsupportedError('Cannot encode test image');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TestByteData implements ByteData {
|
class TestByteData implements ByteData {
|
||||||
TestByteData(this.scale);
|
TestByteData(this.scale);
|
||||||
@ -104,14 +85,17 @@ class FakeImageStreamCompleter extends ImageStreamCompleter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class TestAssetImage extends AssetImage {
|
class TestAssetImage extends AssetImage {
|
||||||
const TestAssetImage(String name) : super(name);
|
const TestAssetImage(String name, this.images) : super(name);
|
||||||
|
|
||||||
|
final Map<double, ui.Image> images;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ImageStreamCompleter load(AssetBundleImageKey key, DecoderCallback decode) {
|
ImageStreamCompleter load(AssetBundleImageKey key, DecoderCallback decode) {
|
||||||
ImageInfo imageInfo;
|
ImageInfo imageInfo;
|
||||||
key.bundle.load(key.name).then<void>((ByteData data) {
|
key.bundle.load(key.name).then<void>((ByteData data) {
|
||||||
final TestByteData testData = data as TestByteData;
|
final TestByteData testData = data as TestByteData;
|
||||||
final ui.Image image = TestImage(testData.scale);
|
final ui.Image image = images[testData.scale];
|
||||||
|
assert(image != null, 'Expected ${testData.scale} to have a key in $images');
|
||||||
imageInfo = ImageInfo(image: image, scale: key.scale);
|
imageInfo = ImageInfo(image: image, scale: key.scale);
|
||||||
});
|
});
|
||||||
assert(imageInfo != null);
|
assert(imageInfo != null);
|
||||||
@ -121,7 +105,7 @@ class TestAssetImage extends AssetImage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildImageAtRatio(String image, Key key, double ratio, bool inferSize, [ AssetBundle bundle ]) {
|
Widget buildImageAtRatio(String imageName, Key key, double ratio, bool inferSize, Map<double, ui.Image> images, [ AssetBundle bundle ]) {
|
||||||
const double windowSize = 500.0; // 500 logical pixels
|
const double windowSize = 500.0; // 500 logical pixels
|
||||||
const double imageSize = 200.0; // 200 logical pixels
|
const double imageSize = 200.0; // 200 logical pixels
|
||||||
|
|
||||||
@ -138,12 +122,12 @@ Widget buildImageAtRatio(String image, Key key, double ratio, bool inferSize, [
|
|||||||
Image(
|
Image(
|
||||||
key: key,
|
key: key,
|
||||||
excludeFromSemantics: true,
|
excludeFromSemantics: true,
|
||||||
image: TestAssetImage(image),
|
image: TestAssetImage(imageName, images),
|
||||||
) :
|
) :
|
||||||
Image(
|
Image(
|
||||||
key: key,
|
key: key,
|
||||||
excludeFromSemantics: true,
|
excludeFromSemantics: true,
|
||||||
image: TestAssetImage(image),
|
image: TestAssetImage(imageName, images),
|
||||||
height: imageSize,
|
height: imageSize,
|
||||||
width: imageSize,
|
width: imageSize,
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
@ -180,9 +164,6 @@ Widget buildImageCacheResized(String name, Key key, int width, int height, int c
|
|||||||
RenderImage getRenderImage(WidgetTester tester, Key key) {
|
RenderImage getRenderImage(WidgetTester tester, Key key) {
|
||||||
return tester.renderObject<RenderImage>(find.byKey(key));
|
return tester.renderObject<RenderImage>(find.byKey(key));
|
||||||
}
|
}
|
||||||
TestImage getTestImage(WidgetTester tester, Key key) {
|
|
||||||
return tester.renderObject<RenderImage>(find.byKey(key)).image as TestImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> pumpTreeToLayout(WidgetTester tester, Widget widget) {
|
Future<void> pumpTreeToLayout(WidgetTester tester, Widget widget) {
|
||||||
const Duration pumpDuration = Duration(milliseconds: 0);
|
const Duration pumpDuration = Duration(milliseconds: 0);
|
||||||
@ -193,88 +174,96 @@ Future<void> pumpTreeToLayout(WidgetTester tester, Widget widget) {
|
|||||||
void main() {
|
void main() {
|
||||||
const String image = 'assets/image.png';
|
const String image = 'assets/image.png';
|
||||||
|
|
||||||
|
final Map<double, ui.Image> images = <double, ui.Image>{};
|
||||||
|
setUpAll(() async {
|
||||||
|
for (final double scale in const <double>[0.5, 1.0, 1.5, 2.0, 4.0, 10.0]) {
|
||||||
|
final int dimension = (48 * scale).floor();
|
||||||
|
images[scale] = await createTestImage(width: dimension, height: dimension);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('Image for device pixel ratio 1.0', (WidgetTester tester) async {
|
testWidgets('Image for device pixel ratio 1.0', (WidgetTester tester) async {
|
||||||
const double ratio = 1.0;
|
const double ratio = 1.0;
|
||||||
Key key = GlobalKey();
|
Key key = GlobalKey();
|
||||||
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false));
|
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false, images));
|
||||||
expect(getRenderImage(tester, key).size, const Size(200.0, 200.0));
|
expect(getRenderImage(tester, key).size, const Size(200.0, 200.0));
|
||||||
expect(getTestImage(tester, key).scale, 1.0);
|
expect(getRenderImage(tester, key).scale, 1.0);
|
||||||
key = GlobalKey();
|
key = GlobalKey();
|
||||||
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true));
|
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true, images));
|
||||||
expect(getRenderImage(tester, key).size, const Size(48.0, 48.0));
|
expect(getRenderImage(tester, key).size, const Size(48.0, 48.0));
|
||||||
expect(getTestImage(tester, key).scale, 1.0);
|
expect(getRenderImage(tester, key).scale, 1.0);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Image for device pixel ratio 0.5', (WidgetTester tester) async {
|
testWidgets('Image for device pixel ratio 0.5', (WidgetTester tester) async {
|
||||||
const double ratio = 0.5;
|
const double ratio = 0.5;
|
||||||
Key key = GlobalKey();
|
Key key = GlobalKey();
|
||||||
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false));
|
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false, images));
|
||||||
expect(getRenderImage(tester, key).size, const Size(200.0, 200.0));
|
expect(getRenderImage(tester, key).size, const Size(200.0, 200.0));
|
||||||
expect(getTestImage(tester, key).scale, 1.0);
|
expect(getRenderImage(tester, key).scale, 1.0);
|
||||||
key = GlobalKey();
|
key = GlobalKey();
|
||||||
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true));
|
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true, images));
|
||||||
expect(getRenderImage(tester, key).size, const Size(48.0, 48.0));
|
expect(getRenderImage(tester, key).size, const Size(48.0, 48.0));
|
||||||
expect(getTestImage(tester, key).scale, 1.0);
|
expect(getRenderImage(tester, key).scale, 1.0);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Image for device pixel ratio 1.5', (WidgetTester tester) async {
|
testWidgets('Image for device pixel ratio 1.5', (WidgetTester tester) async {
|
||||||
const double ratio = 1.5;
|
const double ratio = 1.5;
|
||||||
Key key = GlobalKey();
|
Key key = GlobalKey();
|
||||||
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false));
|
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false, images));
|
||||||
expect(getRenderImage(tester, key).size, const Size(200.0, 200.0));
|
expect(getRenderImage(tester, key).size, const Size(200.0, 200.0));
|
||||||
expect(getTestImage(tester, key).scale, 1.5);
|
expect(getRenderImage(tester, key).scale, 1.5);
|
||||||
key = GlobalKey();
|
key = GlobalKey();
|
||||||
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true));
|
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true, images));
|
||||||
expect(getRenderImage(tester, key).size, const Size(48.0, 48.0));
|
expect(getRenderImage(tester, key).size, const Size(48.0, 48.0));
|
||||||
expect(getTestImage(tester, key).scale, 1.5);
|
expect(getRenderImage(tester, key).scale, 1.5);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Image for device pixel ratio 1.75', (WidgetTester tester) async {
|
testWidgets('Image for device pixel ratio 1.75', (WidgetTester tester) async {
|
||||||
const double ratio = 1.75;
|
const double ratio = 1.75;
|
||||||
Key key = GlobalKey();
|
Key key = GlobalKey();
|
||||||
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false));
|
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false, images));
|
||||||
expect(getRenderImage(tester, key).size, const Size(200.0, 200.0));
|
expect(getRenderImage(tester, key).size, const Size(200.0, 200.0));
|
||||||
expect(getTestImage(tester, key).scale, 1.5);
|
expect(getRenderImage(tester, key).scale, 1.5);
|
||||||
key = GlobalKey();
|
key = GlobalKey();
|
||||||
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true));
|
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true, images));
|
||||||
expect(getRenderImage(tester, key).size, const Size(48.0, 48.0));
|
expect(getRenderImage(tester, key).size, const Size(48.0, 48.0));
|
||||||
expect(getTestImage(tester, key).scale, 1.5);
|
expect(getRenderImage(tester, key).scale, 1.5);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Image for device pixel ratio 2.3', (WidgetTester tester) async {
|
testWidgets('Image for device pixel ratio 2.3', (WidgetTester tester) async {
|
||||||
const double ratio = 2.3;
|
const double ratio = 2.3;
|
||||||
Key key = GlobalKey();
|
Key key = GlobalKey();
|
||||||
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false));
|
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false, images));
|
||||||
expect(getRenderImage(tester, key).size, const Size(200.0, 200.0));
|
expect(getRenderImage(tester, key).size, const Size(200.0, 200.0));
|
||||||
expect(getTestImage(tester, key).scale, 2.0);
|
expect(getRenderImage(tester, key).scale, 2.0);
|
||||||
key = GlobalKey();
|
key = GlobalKey();
|
||||||
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true));
|
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true, images));
|
||||||
expect(getRenderImage(tester, key).size, const Size(48.0, 48.0));
|
expect(getRenderImage(tester, key).size, const Size(48.0, 48.0));
|
||||||
expect(getTestImage(tester, key).scale, 2.0);
|
expect(getRenderImage(tester, key).scale, 2.0);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Image for device pixel ratio 3.7', (WidgetTester tester) async {
|
testWidgets('Image for device pixel ratio 3.7', (WidgetTester tester) async {
|
||||||
const double ratio = 3.7;
|
const double ratio = 3.7;
|
||||||
Key key = GlobalKey();
|
Key key = GlobalKey();
|
||||||
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false));
|
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false, images));
|
||||||
expect(getRenderImage(tester, key).size, const Size(200.0, 200.0));
|
expect(getRenderImage(tester, key).size, const Size(200.0, 200.0));
|
||||||
expect(getTestImage(tester, key).scale, 4.0);
|
expect(getRenderImage(tester, key).scale, 4.0);
|
||||||
key = GlobalKey();
|
key = GlobalKey();
|
||||||
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true));
|
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true, images));
|
||||||
expect(getRenderImage(tester, key).size, const Size(48.0, 48.0));
|
expect(getRenderImage(tester, key).size, const Size(48.0, 48.0));
|
||||||
expect(getTestImage(tester, key).scale, 4.0);
|
expect(getRenderImage(tester, key).scale, 4.0);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Image for device pixel ratio 5.1', (WidgetTester tester) async {
|
testWidgets('Image for device pixel ratio 5.1', (WidgetTester tester) async {
|
||||||
const double ratio = 5.1;
|
const double ratio = 5.1;
|
||||||
Key key = GlobalKey();
|
Key key = GlobalKey();
|
||||||
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false));
|
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false, images));
|
||||||
expect(getRenderImage(tester, key).size, const Size(200.0, 200.0));
|
expect(getRenderImage(tester, key).size, const Size(200.0, 200.0));
|
||||||
expect(getTestImage(tester, key).scale, 4.0);
|
expect(getRenderImage(tester, key).scale, 4.0);
|
||||||
key = GlobalKey();
|
key = GlobalKey();
|
||||||
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true));
|
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true, images));
|
||||||
expect(getRenderImage(tester, key).size, const Size(48.0, 48.0));
|
expect(getRenderImage(tester, key).size, const Size(48.0, 48.0));
|
||||||
expect(getTestImage(tester, key).scale, 4.0);
|
expect(getRenderImage(tester, key).scale, 4.0);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Image for device pixel ratio 1.0, with no main asset', (WidgetTester tester) async {
|
testWidgets('Image for device pixel ratio 1.0, with no main asset', (WidgetTester tester) async {
|
||||||
@ -292,13 +281,13 @@ void main() {
|
|||||||
|
|
||||||
const double ratio = 1.0;
|
const double ratio = 1.0;
|
||||||
Key key = GlobalKey();
|
Key key = GlobalKey();
|
||||||
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false, bundle));
|
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false, images, bundle));
|
||||||
expect(getRenderImage(tester, key).size, const Size(200.0, 200.0));
|
expect(getRenderImage(tester, key).size, const Size(200.0, 200.0));
|
||||||
expect(getTestImage(tester, key).scale, 1.5);
|
expect(getRenderImage(tester, key).scale, 1.5);
|
||||||
key = GlobalKey();
|
key = GlobalKey();
|
||||||
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true, bundle));
|
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true, images, bundle));
|
||||||
expect(getRenderImage(tester, key).size, const Size(48.0, 48.0));
|
expect(getRenderImage(tester, key).size, const Size(48.0, 48.0));
|
||||||
expect(getTestImage(tester, key).scale, 1.5);
|
expect(getRenderImage(tester, key).scale, 1.5);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Image for device pixel ratio 1.0, with a main asset and a 1.0x asset', (WidgetTester tester) async {
|
testWidgets('Image for device pixel ratio 1.0, with a main asset and a 1.0x asset', (WidgetTester tester) async {
|
||||||
@ -321,13 +310,15 @@ void main() {
|
|||||||
|
|
||||||
const double ratio = 1.0;
|
const double ratio = 1.0;
|
||||||
Key key = GlobalKey();
|
Key key = GlobalKey();
|
||||||
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false, bundle));
|
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, false, images, bundle));
|
||||||
expect(getRenderImage(tester, key).size, const Size(200.0, 200.0));
|
expect(getRenderImage(tester, key).size, const Size(200.0, 200.0));
|
||||||
expect(getTestImage(tester, key).scale, 10.0);
|
// Verify we got the 10x scaled image, since the TestByteData said it should be 10x.
|
||||||
|
expect(getRenderImage(tester, key).image.height, 480);
|
||||||
key = GlobalKey();
|
key = GlobalKey();
|
||||||
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true, bundle));
|
await pumpTreeToLayout(tester, buildImageAtRatio(image, key, ratio, true, images, bundle));
|
||||||
expect(getRenderImage(tester, key).size, const Size(480.0, 480.0));
|
expect(getRenderImage(tester, key).size, const Size(480.0, 480.0));
|
||||||
expect(getTestImage(tester, key).scale, 10.0);
|
// Verify we got the 10x scaled image, since the TestByteData said it should be 10x.
|
||||||
|
expect(getRenderImage(tester, key).image.height, 480);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Image cache resize upscale display 5', (WidgetTester tester) async {
|
testWidgets('Image cache resize upscale display 5', (WidgetTester tester) async {
|
||||||
|
@ -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';
|
|||||||
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> {
|
|||||||
@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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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() {
|
|||||||
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,
|
||||||
),
|
),
|
||||||
|
@ -15,24 +15,18 @@ import 'package:flutter/scheduler.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 'semantics_tester.dart';
|
import 'semantics_tester.dart';
|
||||||
|
|
||||||
// This must be run with [WidgetTester.runAsync] since it performs real async
|
|
||||||
// work.
|
|
||||||
Future<ui.Image> createTestImage([List<int> bytes = kTransparentImage]) async {
|
|
||||||
final ui.Codec codec = await ui.instantiateImageCodec(Uint8List.fromList(bytes));
|
|
||||||
final ui.FrameInfo frameInfo = await codec.getNextFrame();
|
|
||||||
return frameInfo.image;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
int originalCacheSize;
|
int originalCacheSize;
|
||||||
|
ui.Image image10x10;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() async {
|
||||||
originalCacheSize = imageCache.maximumSize;
|
originalCacheSize = imageCache.maximumSize;
|
||||||
imageCache.clear();
|
imageCache.clear();
|
||||||
imageCache.clearLiveImages();
|
imageCache.clearLiveImages();
|
||||||
|
image10x10 = await createTestImage(width: 10, height: 10);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() {
|
tearDown(() {
|
||||||
@ -56,7 +50,7 @@ void main() {
|
|||||||
RenderImage renderImage = key.currentContext.findRenderObject() as RenderImage;
|
RenderImage renderImage = key.currentContext.findRenderObject() as RenderImage;
|
||||||
expect(renderImage.image, isNull);
|
expect(renderImage.image, isNull);
|
||||||
|
|
||||||
imageProvider1.complete();
|
imageProvider1.complete(image10x10);
|
||||||
await tester.idle(); // resolve the future from the image provider
|
await tester.idle(); // resolve the future from the image provider
|
||||||
await tester.pump(null, EnginePhase.layout);
|
await tester.pump(null, EnginePhase.layout);
|
||||||
|
|
||||||
@ -98,7 +92,7 @@ void main() {
|
|||||||
RenderImage renderImage = key.currentContext.findRenderObject() as RenderImage;
|
RenderImage renderImage = key.currentContext.findRenderObject() as RenderImage;
|
||||||
expect(renderImage.image, isNull);
|
expect(renderImage.image, isNull);
|
||||||
|
|
||||||
imageProvider1.complete();
|
imageProvider1.complete(image10x10);
|
||||||
await tester.idle(); // resolve the future from the image provider
|
await tester.idle(); // resolve the future from the image provider
|
||||||
await tester.pump(null, EnginePhase.layout);
|
await tester.pump(null, EnginePhase.layout);
|
||||||
|
|
||||||
@ -138,7 +132,7 @@ void main() {
|
|||||||
RenderImage renderImage = key.currentContext.findRenderObject() as RenderImage;
|
RenderImage renderImage = key.currentContext.findRenderObject() as RenderImage;
|
||||||
expect(renderImage.image, isNull);
|
expect(renderImage.image, isNull);
|
||||||
|
|
||||||
imageProvider1.complete();
|
imageProvider1.complete(image10x10);
|
||||||
await tester.idle(); // resolve the future from the image provider
|
await tester.idle(); // resolve the future from the image provider
|
||||||
await tester.pump(null, EnginePhase.layout);
|
await tester.pump(null, EnginePhase.layout);
|
||||||
|
|
||||||
@ -176,7 +170,7 @@ void main() {
|
|||||||
RenderImage renderImage = key.currentContext.findRenderObject() as RenderImage;
|
RenderImage renderImage = key.currentContext.findRenderObject() as RenderImage;
|
||||||
expect(renderImage.image, isNull);
|
expect(renderImage.image, isNull);
|
||||||
|
|
||||||
imageProvider1.complete();
|
imageProvider1.complete(image10x10);
|
||||||
await tester.idle(); // resolve the future from the image provider
|
await tester.idle(); // resolve the future from the image provider
|
||||||
await tester.pump(null, EnginePhase.layout);
|
await tester.pump(null, EnginePhase.layout);
|
||||||
|
|
||||||
@ -466,15 +460,19 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Verify Image stops listening to ImageStream', (WidgetTester tester) async {
|
testWidgets('Verify Image stops listening to ImageStream', (WidgetTester tester) async {
|
||||||
|
final ui.Image image100x100 = await tester.runAsync(() async => createTestImage(width: 100, height: 100));
|
||||||
|
// Web does not override the toString, whereas VM does
|
||||||
|
final String imageString = image100x100.toString();
|
||||||
|
|
||||||
final TestImageProvider imageProvider = TestImageProvider();
|
final TestImageProvider imageProvider = TestImageProvider();
|
||||||
await tester.pumpWidget(Image(image: imageProvider, excludeFromSemantics: true));
|
await tester.pumpWidget(Image(image: imageProvider, excludeFromSemantics: true));
|
||||||
final State<Image> image = tester.state/*State<Image>*/(find.byType(Image));
|
final State<Image> image = tester.state/*State<Image>*/(find.byType(Image));
|
||||||
expect(image.toString(), equalsIgnoringHashCodes('_ImageState#00000(stream: ImageStream#00000(OneFrameImageStreamCompleter#00000, unresolved, 2 listeners), pixels: null, loadingProgress: null, frameNumber: null, wasSynchronouslyLoaded: false)'));
|
expect(image.toString(), equalsIgnoringHashCodes('_ImageState#00000(stream: ImageStream#00000(OneFrameImageStreamCompleter#00000, unresolved, 2 listeners), pixels: null, loadingProgress: null, frameNumber: null, wasSynchronouslyLoaded: false)'));
|
||||||
imageProvider.complete();
|
imageProvider.complete(image100x100);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(image.toString(), equalsIgnoringHashCodes('_ImageState#00000(stream: ImageStream#00000(OneFrameImageStreamCompleter#00000, [100×100] @ 1.0x, 1 listener), pixels: [100×100] @ 1.0x, loadingProgress: null, frameNumber: 0, wasSynchronouslyLoaded: false)'));
|
expect(image.toString(), equalsIgnoringHashCodes('_ImageState#00000(stream: ImageStream#00000(OneFrameImageStreamCompleter#00000, $imageString @ 1.0x, 1 listener), pixels: $imageString @ 1.0x, loadingProgress: null, frameNumber: 0, wasSynchronouslyLoaded: false)'));
|
||||||
await tester.pumpWidget(Container());
|
await tester.pumpWidget(Container());
|
||||||
expect(image.toString(), equalsIgnoringHashCodes('_ImageState#00000(lifecycle state: defunct, not mounted, stream: ImageStream#00000(OneFrameImageStreamCompleter#00000, [100×100] @ 1.0x, 0 listeners), pixels: [100×100] @ 1.0x, loadingProgress: null, frameNumber: 0, wasSynchronouslyLoaded: false)'));
|
expect(image.toString(), equalsIgnoringHashCodes('_ImageState#00000(lifecycle state: defunct, not mounted, stream: ImageStream#00000(OneFrameImageStreamCompleter#00000, $imageString @ 1.0x, 0 listeners), pixels: $imageString @ 1.0x, loadingProgress: null, frameNumber: 0, wasSynchronouslyLoaded: false)'));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Stream completer errors can be listened to by attaching before resolving', (WidgetTester tester) async {
|
testWidgets('Stream completer errors can be listened to by attaching before resolving', (WidgetTester tester) async {
|
||||||
@ -768,7 +766,7 @@ void main() {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
provider.complete();
|
provider.complete(image10x10);
|
||||||
await precache;
|
await precache;
|
||||||
expect(provider._lastResolvedConfiguration, isNotNull);
|
expect(provider._lastResolvedConfiguration, isNotNull);
|
||||||
|
|
||||||
@ -862,6 +860,7 @@ void main() {
|
|||||||
|
|
||||||
final TestImageProvider imageProvider1 = TestImageProvider();
|
final TestImageProvider imageProvider1 = TestImageProvider();
|
||||||
final TestImageProvider imageProvider2 = TestImageProvider();
|
final TestImageProvider imageProvider2 = TestImageProvider();
|
||||||
|
final ui.Image image100x100 = await tester.runAsync(() async => createTestImage(width: 100, height: 100));
|
||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
Container(
|
Container(
|
||||||
@ -877,8 +876,8 @@ void main() {
|
|||||||
RenderImage renderImage = key.currentContext.findRenderObject() as RenderImage;
|
RenderImage renderImage = key.currentContext.findRenderObject() as RenderImage;
|
||||||
expect(renderImage.image, isNull);
|
expect(renderImage.image, isNull);
|
||||||
|
|
||||||
imageProvider1.complete();
|
imageProvider1.complete(image10x10);
|
||||||
imageProvider2.complete();
|
imageProvider2.complete(image100x100);
|
||||||
await tester.idle(); // resolve the future from the image provider
|
await tester.idle(); // resolve the future from the image provider
|
||||||
await tester.pump(null, EnginePhase.layout);
|
await tester.pump(null, EnginePhase.layout);
|
||||||
|
|
||||||
@ -905,8 +904,8 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Image State can be reconfigured to use another image', (WidgetTester tester) async {
|
testWidgets('Image State can be reconfigured to use another image', (WidgetTester tester) async {
|
||||||
final Image image1 = Image(image: TestImageProvider()..complete(), width: 10.0, excludeFromSemantics: true);
|
final Image image1 = Image(image: TestImageProvider()..complete(image10x10), width: 10.0, excludeFromSemantics: true);
|
||||||
final Image image2 = Image(image: TestImageProvider()..complete(), width: 20.0, excludeFromSemantics: true);
|
final Image image2 = Image(image: TestImageProvider()..complete(image10x10), width: 20.0, excludeFromSemantics: true);
|
||||||
|
|
||||||
final Column column = Column(children: <Widget>[image1, image2]);
|
final Column column = Column(children: <Widget>[image1, image2]);
|
||||||
await tester.pumpWidget(column, null, EnginePhase.layout);
|
await tester.pumpWidget(column, null, EnginePhase.layout);
|
||||||
@ -1014,7 +1013,6 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Image invokes frameBuilder with correct wasSynchronouslyLoaded=false', (WidgetTester tester) async {
|
testWidgets('Image invokes frameBuilder with correct wasSynchronouslyLoaded=false', (WidgetTester tester) async {
|
||||||
final ui.Image image = await tester.runAsync(createTestImage);
|
|
||||||
final TestImageStreamCompleter streamCompleter = TestImageStreamCompleter();
|
final TestImageStreamCompleter streamCompleter = TestImageStreamCompleter();
|
||||||
final TestImageProvider imageProvider = TestImageProvider(streamCompleter: streamCompleter);
|
final TestImageProvider imageProvider = TestImageProvider(streamCompleter: streamCompleter);
|
||||||
int lastFrame;
|
int lastFrame;
|
||||||
@ -1034,15 +1032,14 @@ void main() {
|
|||||||
expect(lastFrame, isNull);
|
expect(lastFrame, isNull);
|
||||||
expect(lastFrameWasSync, isFalse);
|
expect(lastFrameWasSync, isFalse);
|
||||||
expect(find.byType(RawImage), findsOneWidget);
|
expect(find.byType(RawImage), findsOneWidget);
|
||||||
streamCompleter.setData(imageInfo: ImageInfo(image: image));
|
streamCompleter.setData(imageInfo: ImageInfo(image: image10x10));
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(lastFrame, 0);
|
expect(lastFrame, 0);
|
||||||
expect(lastFrameWasSync, isFalse);
|
expect(lastFrameWasSync, isFalse);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Image invokes frameBuilder with correct wasSynchronouslyLoaded=true', (WidgetTester tester) async {
|
testWidgets('Image invokes frameBuilder with correct wasSynchronouslyLoaded=true', (WidgetTester tester) async {
|
||||||
final ui.Image image = await tester.runAsync(createTestImage);
|
final TestImageStreamCompleter streamCompleter = TestImageStreamCompleter(ImageInfo(image: image10x10));
|
||||||
final TestImageStreamCompleter streamCompleter = TestImageStreamCompleter(ImageInfo(image: image));
|
|
||||||
final TestImageProvider imageProvider = TestImageProvider(streamCompleter: streamCompleter);
|
final TestImageProvider imageProvider = TestImageProvider(streamCompleter: streamCompleter);
|
||||||
int lastFrame;
|
int lastFrame;
|
||||||
bool lastFrameWasSync;
|
bool lastFrameWasSync;
|
||||||
@ -1061,7 +1058,7 @@ void main() {
|
|||||||
expect(lastFrame, 0);
|
expect(lastFrame, 0);
|
||||||
expect(lastFrameWasSync, isTrue);
|
expect(lastFrameWasSync, isTrue);
|
||||||
expect(find.byType(RawImage), findsOneWidget);
|
expect(find.byType(RawImage), findsOneWidget);
|
||||||
streamCompleter.setData(imageInfo: ImageInfo(image: image));
|
streamCompleter.setData(imageInfo: ImageInfo(image: image10x10));
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(lastFrame, 1);
|
expect(lastFrame, 1);
|
||||||
expect(lastFrameWasSync, isTrue);
|
expect(lastFrameWasSync, isTrue);
|
||||||
@ -1173,7 +1170,6 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Image invokes loadingBuilder on chunk event notification', (WidgetTester tester) async {
|
testWidgets('Image invokes loadingBuilder on chunk event notification', (WidgetTester tester) async {
|
||||||
final ui.Image image = await tester.runAsync(createTestImage);
|
|
||||||
final TestImageStreamCompleter streamCompleter = TestImageStreamCompleter();
|
final TestImageStreamCompleter streamCompleter = TestImageStreamCompleter();
|
||||||
final TestImageProvider imageProvider = TestImageProvider(streamCompleter: streamCompleter);
|
final TestImageProvider imageProvider = TestImageProvider(streamCompleter: streamCompleter);
|
||||||
final List<ImageChunkEvent> chunkEvents = <ImageChunkEvent>[];
|
final List<ImageChunkEvent> chunkEvents = <ImageChunkEvent>[];
|
||||||
@ -1208,7 +1204,7 @@ void main() {
|
|||||||
expect(chunkEvents.length, 3);
|
expect(chunkEvents.length, 3);
|
||||||
expect(find.text('loading 30 / 100'), findsOneWidget);
|
expect(find.text('loading 30 / 100'), findsOneWidget);
|
||||||
expect(find.byType(RawImage), findsNothing);
|
expect(find.byType(RawImage), findsNothing);
|
||||||
streamCompleter.setData(imageInfo: ImageInfo(image: image));
|
streamCompleter.setData(imageInfo: ImageInfo(image: image10x10));
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(chunkEvents.length, 4);
|
expect(chunkEvents.length, 4);
|
||||||
expect(find.byType(Text), findsNothing);
|
expect(find.byType(Text), findsNothing);
|
||||||
@ -1216,7 +1212,6 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets("Image doesn't rebuild on chunk events if loadingBuilder is null", (WidgetTester tester) async {
|
testWidgets("Image doesn't rebuild on chunk events if loadingBuilder is null", (WidgetTester tester) async {
|
||||||
final ui.Image image = await tester.runAsync(createTestImage);
|
|
||||||
final TestImageStreamCompleter streamCompleter = TestImageStreamCompleter();
|
final TestImageStreamCompleter streamCompleter = TestImageStreamCompleter();
|
||||||
final TestImageProvider imageProvider = TestImageProvider(streamCompleter: streamCompleter);
|
final TestImageProvider imageProvider = TestImageProvider(streamCompleter: streamCompleter);
|
||||||
|
|
||||||
@ -1230,7 +1225,7 @@ void main() {
|
|||||||
expect(tester.binding.hasScheduledFrame, isFalse);
|
expect(tester.binding.hasScheduledFrame, isFalse);
|
||||||
streamCompleter.setData(chunkEvent: const ImageChunkEvent(cumulativeBytesLoaded: 10, expectedTotalBytes: 100));
|
streamCompleter.setData(chunkEvent: const ImageChunkEvent(cumulativeBytesLoaded: 10, expectedTotalBytes: 100));
|
||||||
expect(tester.binding.hasScheduledFrame, isFalse);
|
expect(tester.binding.hasScheduledFrame, isFalse);
|
||||||
streamCompleter.setData(imageInfo: ImageInfo(image: image));
|
streamCompleter.setData(imageInfo: ImageInfo(image: image10x10));
|
||||||
expect(tester.binding.hasScheduledFrame, isTrue);
|
expect(tester.binding.hasScheduledFrame, isTrue);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
streamCompleter.setData(chunkEvent: const ImageChunkEvent(cumulativeBytesLoaded: 10, expectedTotalBytes: 100));
|
streamCompleter.setData(chunkEvent: const ImageChunkEvent(cumulativeBytesLoaded: 10, expectedTotalBytes: 100));
|
||||||
@ -1451,7 +1446,6 @@ void main() {
|
|||||||
testWidgets('Same image provider in multiple parts of the tree, no cache room left', (WidgetTester tester) async {
|
testWidgets('Same image provider in multiple parts of the tree, no cache room left', (WidgetTester tester) async {
|
||||||
imageCache.maximumSize = 0;
|
imageCache.maximumSize = 0;
|
||||||
|
|
||||||
final ui.Image image = await tester.runAsync(createTestImage);
|
|
||||||
final TestImageProvider provider1 = TestImageProvider();
|
final TestImageProvider provider1 = TestImageProvider();
|
||||||
final TestImageProvider provider2 = TestImageProvider();
|
final TestImageProvider provider2 = TestImageProvider();
|
||||||
|
|
||||||
@ -1480,10 +1474,10 @@ void main() {
|
|||||||
expect(provider1.loadCallCount, 1);
|
expect(provider1.loadCallCount, 1);
|
||||||
expect(provider2.loadCallCount, 1);
|
expect(provider2.loadCallCount, 1);
|
||||||
|
|
||||||
provider1.complete(image);
|
provider1.complete(image10x10);
|
||||||
await tester.idle();
|
await tester.idle();
|
||||||
|
|
||||||
provider2.complete(image);
|
provider2.complete(image10x10);
|
||||||
await tester.idle();
|
await tester.idle();
|
||||||
|
|
||||||
expect(imageCache.liveImageCount, 2);
|
expect(imageCache.liveImageCount, 2);
|
||||||
@ -1516,7 +1510,7 @@ void main() {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
provider.complete();
|
provider.complete(image10x10);
|
||||||
await precache;
|
await precache;
|
||||||
|
|
||||||
// Should have ended up with only a weak ref, not in cache because cache size is 0
|
// Should have ended up with only a weak ref, not in cache because cache size is 0
|
||||||
@ -1566,7 +1560,7 @@ void main() {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
provider.complete();
|
provider.complete(image10x10);
|
||||||
await precache;
|
await precache;
|
||||||
|
|
||||||
// Should have ended up in the cache and have a weak reference.
|
// Should have ended up in the cache and have a weak reference.
|
||||||
@ -1644,7 +1638,7 @@ void main() {
|
|||||||
Object caughtException;
|
Object caughtException;
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
Image(
|
Image(
|
||||||
image: const FailingImageProvider(failOnObtainKey: true, throws: 'threw'),
|
image: FailingImageProvider(failOnObtainKey: true, throws: 'threw', image: image10x10),
|
||||||
errorBuilder: (BuildContext context, Object error, StackTrace stackTrace) {
|
errorBuilder: (BuildContext context, Object error, StackTrace stackTrace) {
|
||||||
caughtException = error;
|
caughtException = error;
|
||||||
return SizedBox.expand(key: errorKey);
|
return SizedBox.expand(key: errorKey);
|
||||||
@ -1664,7 +1658,7 @@ void main() {
|
|||||||
Object caughtException;
|
Object caughtException;
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
Image(
|
Image(
|
||||||
image: const FailingImageProvider(failOnLoad: true, throws: 'threw'),
|
image: FailingImageProvider(failOnLoad: true, throws: 'threw', image: image10x10),
|
||||||
errorBuilder: (BuildContext context, Object error, StackTrace stackTrace) {
|
errorBuilder: (BuildContext context, Object error, StackTrace stackTrace) {
|
||||||
caughtException = error;
|
caughtException = error;
|
||||||
return SizedBox.expand(key: errorKey);
|
return SizedBox.expand(key: errorKey);
|
||||||
@ -1681,8 +1675,8 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('no errorBuilder - failure reported to FlutterError', (WidgetTester tester) async {
|
testWidgets('no errorBuilder - failure reported to FlutterError', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
const Image(
|
Image(
|
||||||
image: FailingImageProvider(failOnLoad: true, throws: 'threw'),
|
image: FailingImageProvider(failOnLoad: true, throws: 'threw', image: image10x10),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1736,7 +1730,7 @@ void main() {
|
|||||||
imageSizeInfo = info;
|
imageSizeInfo = info;
|
||||||
};
|
};
|
||||||
|
|
||||||
final ui.Image image = await tester.runAsync(() => createTestImage(kBlueRectPng));
|
final ui.Image image = await tester.runAsync(() => createTestImage(width: 100, height: 100));
|
||||||
final TestImageStreamCompleter streamCompleter = TestImageStreamCompleter(
|
final TestImageStreamCompleter streamCompleter = TestImageStreamCompleter(
|
||||||
ImageInfo(
|
ImageInfo(
|
||||||
image: image,
|
image: image,
|
||||||
@ -1847,8 +1841,7 @@ class TestImageProvider extends ImageProvider<Object> {
|
|||||||
return _streamCompleter;
|
return _streamCompleter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void complete([ui.Image image]) {
|
void complete(ui.Image image) {
|
||||||
image ??= TestImage();
|
|
||||||
_completer.complete(ImageInfo(image: image));
|
_completer.complete(ImageInfo(image: image));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1898,25 +1891,6 @@ class TestImageStreamCompleter extends ImageStreamCompleter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestImage implements ui.Image {
|
|
||||||
@override
|
|
||||||
int get width => 100;
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get height => 100;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() { }
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<ByteData> toByteData({ ui.ImageByteFormat format = ui.ImageByteFormat.rawRgba }) async {
|
|
||||||
throw UnsupportedError('Cannot encode test image');
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() => '[$width\u00D7$height]';
|
|
||||||
}
|
|
||||||
|
|
||||||
class DebouncingImageProvider extends ImageProvider<Object> {
|
class DebouncingImageProvider extends ImageProvider<Object> {
|
||||||
DebouncingImageProvider(this.imageProvider, this.seenKeys);
|
DebouncingImageProvider(this.imageProvider, this.seenKeys);
|
||||||
|
|
||||||
@ -1949,14 +1923,17 @@ class FailingImageProvider extends ImageProvider<int> {
|
|||||||
this.failOnObtainKey = false,
|
this.failOnObtainKey = false,
|
||||||
this.failOnLoad = false,
|
this.failOnLoad = false,
|
||||||
@required this.throws,
|
@required this.throws,
|
||||||
|
@required this.image,
|
||||||
}) : assert(failOnLoad != null),
|
}) : assert(failOnLoad != null),
|
||||||
assert(failOnObtainKey != null),
|
assert(failOnObtainKey != null),
|
||||||
assert(failOnLoad == true || failOnObtainKey == true),
|
assert(failOnLoad == true || failOnObtainKey == true),
|
||||||
assert(throws != null);
|
assert(throws != null),
|
||||||
|
assert(image != null);
|
||||||
|
|
||||||
final bool failOnObtainKey;
|
final bool failOnObtainKey;
|
||||||
final bool failOnLoad;
|
final bool failOnLoad;
|
||||||
final Object throws;
|
final Object throws;
|
||||||
|
final ui.Image image;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<int> obtainKey(ImageConfiguration configuration) {
|
Future<int> obtainKey(ImageConfiguration configuration) {
|
||||||
@ -1974,7 +1951,7 @@ class FailingImageProvider extends ImageProvider<int> {
|
|||||||
return OneFrameImageStreamCompleter(
|
return OneFrameImageStreamCompleter(
|
||||||
Future<ImageInfo>.value(
|
Future<ImageInfo>.value(
|
||||||
ImageInfo(
|
ImageInfo(
|
||||||
image: TestImage(),
|
image: image,
|
||||||
scale: 0,
|
scale: 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -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 @@
|
|||||||
|
|
||||||
// @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() {
|
|||||||
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() {
|
|||||||
));
|
));
|
||||||
|
|
||||||
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() {
|
|||||||
));
|
));
|
||||||
|
|
||||||
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() {
|
|||||||
));
|
));
|
||||||
|
|
||||||
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() {
|
|||||||
));
|
));
|
||||||
|
|
||||||
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() {
|
|||||||
));
|
));
|
||||||
|
|
||||||
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() {
|
|||||||
));
|
));
|
||||||
|
|
||||||
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() {
|
|||||||
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;
|
|||||||
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';
|
|||||||
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';
|
||||||
|
119
packages/flutter_test/lib/src/image.dart
Normal file
119
packages/flutter_test/lib/src/image.dart
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
// 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;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user