Skip to content

Commit

Permalink
Merge pull request flutter#2948 from apwilson/image
Browse files Browse the repository at this point in the history
Add keys to ResourceImages.
  • Loading branch information
apwilson committed Mar 29, 2016
2 parents b1ed094 + ed00f3e commit fad5df4
Show file tree
Hide file tree
Showing 2 changed files with 229 additions and 3 deletions.
12 changes: 9 additions & 3 deletions packages/flutter/lib/src/widgets/basic.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2049,8 +2049,10 @@ class NetworkImage extends StatelessWidget {

@override
Widget build(BuildContext context) {
ImageResource imageResource = imageCache.load(src, scale: scale);
return new RawImageResource(
image: imageCache.load(src, scale: scale),
key: key == null ? new ObjectKey(imageResource) : null,
image: imageResource,
width: width,
height: height,
color: color,
Expand Down Expand Up @@ -2171,8 +2173,10 @@ class AsyncImage extends StatelessWidget {

@override
Widget build(BuildContext context) {
ImageResource imageResource = imageCache.loadProvider(provider);
return new RawImageResource(
image: imageCache.loadProvider(provider),
key: key == null ? new ObjectKey(imageResource) : null,
image: imageResource,
width: width,
height: height,
color: color,
Expand Down Expand Up @@ -2272,8 +2276,10 @@ class AssetImage extends StatelessWidget {

@override
Widget build(BuildContext context) {
ImageResource imageResource = (bundle ?? DefaultAssetBundle.of(context)).loadImage(name);
return new RawImageResource(
image: (bundle ?? DefaultAssetBundle.of(context)).loadImage(name),
key: key == null ? new ObjectKey(imageResource) : null,
image: imageResource,
width: width,
height: height,
color: color,
Expand Down
220 changes: 220 additions & 0 deletions packages/flutter/test/widget/image_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
// Copyright 2016 The Chromium 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:ui' as ui show Image;

import 'package:mojo/core.dart' as core;
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/services.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:test/test.dart';

void main() {
test('Verify NetworkImage sets an ObjectKey on its ImageResource if it doesn\'t have a key', () {
testWidgets((WidgetTester tester) {
final String testUrl = 'https://foo.bar/baz1.png';
tester.pumpWidget(
new NetworkImage(
scale: 1.0,
src: testUrl
)
);

ImageResource imageResource = imageCache.load(testUrl, scale: 1.0);
expect(tester.findElementByKey(new ObjectKey(imageResource)), isNotNull);
});
});

test('Verify NetworkImage doesn\'t set an ObjectKey on its ImageResource if it has a key', () {
testWidgets((WidgetTester tester) {
final String testUrl = 'https://foo.bar/baz2.png';
tester.pumpWidget(
new NetworkImage(
key: new GlobalKey(),
scale: 1.0,
src: testUrl
)
);

ImageResource imageResource = imageCache.load(testUrl, scale: 1.0);
expect(tester.findElementByKey(new ObjectKey(imageResource)), isNull);
});
});

test('Verify AsyncImage sets an ObjectKey on its ImageResource if it doesn\'t have a key', () {
testWidgets((WidgetTester tester) {
ImageProvider imageProvider = new TestImageProvider();
tester.pumpWidget(new AsyncImage(provider: imageProvider));

ImageResource imageResource = imageCache.loadProvider(imageProvider);
expect(tester.findElementByKey(new ObjectKey(imageResource)), isNotNull);
});
});

test('Verify AsyncImage doesn\'t set an ObjectKey on its ImageResource if it has a key', () {
testWidgets((WidgetTester tester) {
ImageProvider imageProvider = new TestImageProvider();
tester.pumpWidget(
new AsyncImage(
key: new GlobalKey(),
provider: imageProvider
)
);

ImageResource imageResource = imageCache.loadProvider(imageProvider);
expect(tester.findElementByKey(new ObjectKey(imageResource)), isNull);
});
});

test('Verify AssetImage sets an ObjectKey on its ImageResource if it doesn\'t have a key', () {
testWidgets((WidgetTester tester) {
final String name = 'foo';
final AssetBundle assetBundle = new TestAssetBundle();
tester.pumpWidget(
new AssetImage(
name: name,
bundle: assetBundle
)
);

ImageResource imageResource = assetBundle.loadImage(name);
expect(tester.findElementByKey(new ObjectKey(imageResource)), isNotNull);
});
});

test('Verify AssetImage doesn\'t set an ObjectKey on its ImageResource if it has a key', () {
testWidgets((WidgetTester tester) {
final String name = 'foo';
final AssetBundle assetBundle = new TestAssetBundle();
tester.pumpWidget(
new AssetImage(
key: new GlobalKey(),
name: name,
bundle: assetBundle
)
);

ImageResource imageResource = assetBundle.loadImage(name);
expect(tester.findElementByKey(new ObjectKey(imageResource)), isNull);
});
});

test('Verify AsyncImage resets its RenderImage when changing providers if it doesn\'t have a key', () {
testWidgets((WidgetTester tester) {
final GlobalKey key = new GlobalKey();
TestImageProvider imageProvider1 = new TestImageProvider();
tester.pumpWidget(
new Container(
key: key,
child: new AsyncImage(
provider: imageProvider1
)
)
);
RenderImage renderImage = key.currentContext.findRenderObject();
expect(renderImage.image, isNull);

// An exception will be thrown when we try to draw the image. Catch it.
RenderingExceptionHandler originalRenderingExceptionHandler = debugRenderingExceptionHandler;
debugRenderingExceptionHandler = (_, __, ___, ____) => null;
imageProvider1.complete();
tester.pump();
tester.pump();
debugRenderingExceptionHandler = originalRenderingExceptionHandler;

renderImage = key.currentContext.findRenderObject();
expect(renderImage.image, isNotNull);

TestImageProvider imageProvider2 = new TestImageProvider();
tester.pumpWidget(
new Container(
key: key,
child: new AsyncImage(
provider: imageProvider2
)
)
);

renderImage = key.currentContext.findRenderObject();
expect(renderImage.image, isNull);

});
});

test('Verify AsyncImage doesn\'t reset its RenderImage when changing providers if it has a key', () {
testWidgets((WidgetTester tester) {
final GlobalKey key = new GlobalKey();
TestImageProvider imageProvider1 = new TestImageProvider();
tester.pumpWidget(
new AsyncImage(
key: key,
provider: imageProvider1
)
);
RenderImage renderImage = key.currentContext.findRenderObject();
expect(renderImage.image, isNull);

// An exception will be thrown when we try to draw the image. Catch it.
RenderingExceptionHandler originalRenderingExceptionHandler = debugRenderingExceptionHandler;
debugRenderingExceptionHandler = (_, __, ___, ____) => null;
imageProvider1.complete();
tester.pump();
tester.pump();
debugRenderingExceptionHandler = originalRenderingExceptionHandler;

renderImage = key.currentContext.findRenderObject();
expect(renderImage.image, isNotNull);

TestImageProvider imageProvider2 = new TestImageProvider();
tester.pumpWidget(
new AsyncImage(
key: key,
provider: imageProvider2
)
);

renderImage = key.currentContext.findRenderObject();
expect(renderImage.image, isNotNull);
});
});

}

class TestImageProvider extends ImageProvider {
final Completer<ImageInfo> _completer = new Completer<ImageInfo>();

@override
Future<ImageInfo> loadImage() => _completer.future;

void complete() {
_completer.complete(new ImageInfo(image:new TestImage()));
}
}

class TestAssetBundle extends AssetBundle {
final ImageResource _imageResource = new ImageResource(new Completer<ImageInfo>().future);

@override
ImageResource loadImage(String key) => _imageResource;

@override
Future<String> loadString(String key) => new Completer<String>().future;

@override
Future<core.MojoDataPipeConsumer> load(String key) => new Completer<core.MojoDataPipeConsumer>().future;
}

class TestImage extends ui.Image {
@override
int get width => 100;

@override
int get height => 100;

@override
void dispose() {
}
}

0 comments on commit fad5df4

Please sign in to comment.