image_test.dart 10.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
// 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:flutter_test/flutter_test.dart';
import 'package:flutter/services.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';

void main() {
14 15 16
  testWidgets('Verify Image resets its RenderImage when changing providers', (WidgetTester tester) async {
    final GlobalKey key = new GlobalKey();
    TestImageProvider imageProvider1 = new TestImageProvider();
17
    await tester.pumpWidget(
18 19 20 21 22 23 24 25
      new Container(
        key: key,
        child: new Image(
          image: imageProvider1
        )
      ),
      null,
      EnginePhase.layout
26
    );
27 28
    RenderImage renderImage = key.currentContext.findRenderObject();
    expect(renderImage.image, isNull);
29

30 31 32
    imageProvider1.complete();
    await tester.idle(); // resolve the future from the image provider
    await tester.pump(null, EnginePhase.layout);
33

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

37
    TestImageProvider imageProvider2 = new TestImageProvider();
38
    await tester.pumpWidget(
39 40 41 42 43 44 45 46
      new Container(
        key: key,
        child: new Image(
          image: imageProvider2
        )
      ),
      null,
      EnginePhase.layout
47 48
    );

49 50
    renderImage = key.currentContext.findRenderObject();
    expect(renderImage.image, isNull);
51 52
  });

53 54 55
  testWidgets('Verify Image doesn\'t reset its RenderImage when changing providers if it has gaplessPlayback set', (WidgetTester tester) async {
    final GlobalKey key = new GlobalKey();
    TestImageProvider imageProvider1 = new TestImageProvider();
56
    await tester.pumpWidget(
57 58 59 60 61 62 63 64 65
      new Container(
        key: key,
        child: new Image(
          gaplessPlayback: true,
          image: imageProvider1
        )
      ),
      null,
      EnginePhase.layout
66
    );
67 68
    RenderImage renderImage = key.currentContext.findRenderObject();
    expect(renderImage.image, isNull);
69

70 71 72
    imageProvider1.complete();
    await tester.idle(); // resolve the future from the image provider
    await tester.pump(null, EnginePhase.layout);
73

74 75 76 77
    renderImage = key.currentContext.findRenderObject();
    expect(renderImage.image, isNotNull);

    TestImageProvider imageProvider2 = new TestImageProvider();
78
    await tester.pumpWidget(
79 80 81 82 83 84 85 86 87
      new Container(
        key: key,
        child: new Image(
          gaplessPlayback: true,
          image: imageProvider2
        )
      ),
      null,
      EnginePhase.layout
88 89
    );

90 91
    renderImage = key.currentContext.findRenderObject();
    expect(renderImage.image, isNotNull);
92 93
  });

94
  testWidgets('Verify Image resets its RenderImage when changing providers if it has a key', (WidgetTester tester) async {
95 96
    final GlobalKey key = new GlobalKey();
    TestImageProvider imageProvider1 = new TestImageProvider();
97
    await tester.pumpWidget(
98
      new Image(
99
        key: key,
100
        image: imageProvider1
101 102 103 104 105 106 107 108
      ),
      null,
      EnginePhase.layout
    );
    RenderImage renderImage = key.currentContext.findRenderObject();
    expect(renderImage.image, isNull);

    imageProvider1.complete();
109 110
    await tester.idle(); // resolve the future from the image provider
    await tester.pump(null, EnginePhase.layout);
111 112 113 114 115

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

    TestImageProvider imageProvider2 = new TestImageProvider();
116
    await tester.pumpWidget(
117
      new Image(
118
        key: key,
119
        image: imageProvider2
120 121 122 123
      ),
      null,
      EnginePhase.layout
    );
124

125 126
    renderImage = key.currentContext.findRenderObject();
    expect(renderImage.image, isNull);
127 128
  });

129
  testWidgets('Verify Image doesn\'t reset its RenderImage when changing providers if it has gaplessPlayback set', (WidgetTester tester) async {
130 131
    final GlobalKey key = new GlobalKey();
    TestImageProvider imageProvider1 = new TestImageProvider();
132
    await tester.pumpWidget(
133 134 135 136
      new Image(
        key: key,
        gaplessPlayback: true,
        image: imageProvider1
137 138 139 140 141 142 143 144
      ),
      null,
      EnginePhase.layout
    );
    RenderImage renderImage = key.currentContext.findRenderObject();
    expect(renderImage.image, isNull);

    imageProvider1.complete();
145 146
    await tester.idle(); // resolve the future from the image provider
    await tester.pump(null, EnginePhase.layout);
147 148 149 150 151

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

    TestImageProvider imageProvider2 = new TestImageProvider();
152
    await tester.pumpWidget(
153
      new Image(
154
        key: key,
155 156
        gaplessPlayback: true,
        image: imageProvider2
157 158 159 160 161 162 163
      ),
      null,
      EnginePhase.layout
    );

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

166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
  testWidgets('Verify ImageProvider configuration inheritance', (WidgetTester tester) async {
    final GlobalKey mediaQueryKey1 = new GlobalKey(debugLabel: 'mediaQueryKey1');
    final GlobalKey mediaQueryKey2 = new GlobalKey(debugLabel: 'mediaQueryKey2');
    final GlobalKey imageKey = new GlobalKey(debugLabel: 'image');
    final TestImageProvider imageProvider = new TestImageProvider();

    // Of the two nested MediaQuery objects, the innermost one,
    // mediaQuery2, should define the configuration of the imageProvider.
    await tester.pumpWidget(
      new MediaQuery(
        key: mediaQueryKey1,
        data: new MediaQueryData(
          devicePixelRatio: 10.0,
          padding: EdgeInsets.zero,
        ),
        child: new MediaQuery(
          key: mediaQueryKey2,
          data: new MediaQueryData(
            devicePixelRatio: 5.0,
            padding: EdgeInsets.zero,
          ),
          child: new Image(
            key: imageKey,
            image: imageProvider
          ),
        )
      )
    );

    expect(imageProvider._configuration.devicePixelRatio, 5.0);

    // This is the same widget hierarchy as before except that the
    // two MediaQuery objects have exchanged places. The imageProvider
    // should be resolved again, with the new innermost MediaQuery.
    await tester.pumpWidget(
      new MediaQuery(
        key: mediaQueryKey2,
        data: new MediaQueryData(
          devicePixelRatio: 5.0,
          padding: EdgeInsets.zero,
        ),
        child: new MediaQuery(
          key: mediaQueryKey1,
          data: new MediaQueryData(
            devicePixelRatio: 10.0,
            padding: EdgeInsets.zero,
          ),
          child: new Image(
            key: imageKey,
            image: imageProvider
          ),
        )
      )
    );

    expect(imageProvider._configuration.devicePixelRatio, 10.0);
  });

  testWidgets('Verify ImageProvider configuration inheritance again', (WidgetTester tester) async {
    final GlobalKey mediaQueryKey1 = new GlobalKey(debugLabel: 'mediaQueryKey1');
    final GlobalKey mediaQueryKey2 = new GlobalKey(debugLabel: 'mediaQueryKey2');
    final GlobalKey imageKey = new GlobalKey(debugLabel: 'image');
    final TestImageProvider imageProvider = new TestImageProvider();

    // This is just a variation on the previous test.  In this version the location
    // of the Image changes and the MediaQuery widgets do not.
    await tester.pumpWidget(
      new Row(
        children: <Widget> [
          new MediaQuery(
            key: mediaQueryKey2,
            data: new MediaQueryData(
              devicePixelRatio: 5.0,
              padding: EdgeInsets.zero,
            ),
            child: new Image(
              key: imageKey,
              image: imageProvider
            )
          ),
          new MediaQuery(
            key: mediaQueryKey1,
            data: new MediaQueryData(
              devicePixelRatio: 10.0,
              padding: EdgeInsets.zero,
            ),
            child: new Container(width: 100.0)
          )
        ]
      )
    );

    expect(imageProvider._configuration.devicePixelRatio, 5.0);

    await tester.pumpWidget(
      new Row(
        children: <Widget> [
          new MediaQuery(
            key: mediaQueryKey2,
            data: new MediaQueryData(
              devicePixelRatio: 5.0,
              padding: EdgeInsets.zero,
            ),
            child: new Container(width: 100.0)
          ),
          new MediaQuery(
            key: mediaQueryKey1,
            data: new MediaQueryData(
              devicePixelRatio: 10.0,
              padding: EdgeInsets.zero,
            ),
            child: new Image(
              key: imageKey,
              image: imageProvider
            )
          )
        ]
      )
    );

    expect(imageProvider._configuration.devicePixelRatio, 10.0);
  });

289 290 291 292 293 294 295 296 297 298 299 300
  testWidgets('Verify Image stops listening to ImageStream', (WidgetTester tester) async {
    TestImageProvider imageProvider = new TestImageProvider();
    await tester.pumpWidget(new Image(image: imageProvider));
    State<Image> image = tester.state/*State<Image>*/(find.byType(Image));
    expect(image.toString(), matches(new RegExp(r'_ImageState\([0-9]+; stream: ImageStream\(OneFrameImageStreamCompleter; unresolved; 1 listener\); pixels: null\)')));
    imageProvider.complete();
    await tester.pump();
    expect(image.toString(), matches(new RegExp(r'_ImageState\([0-9]+; stream: ImageStream\(OneFrameImageStreamCompleter; \[100×100\] @ 1\.0x; 1 listener\); pixels: \[100×100\] @ 1\.0x\)')));
    await tester.pumpWidget(new Container());
    expect(image.toString(), matches(new RegExp(r'_ImageState\([0-9]+; _StateLifecycle.defunct; not mounted; stream: ImageStream\(OneFrameImageStreamCompleter; \[100×100\] @ 1\.0x; 0 listeners\); pixels: \[100×100\] @ 1\.0x\)')));
  });

301 302
}

303
class TestImageProvider extends ImageProvider<TestImageProvider> {
304
  final Completer<ImageInfo> _completer = new Completer<ImageInfo>();
305
  ImageConfiguration _configuration;
306 307

  @override
308 309
  Future<TestImageProvider> obtainKey(ImageConfiguration configuration) {
    return new SynchronousFuture<TestImageProvider>(this);
310 311
  }

312 313 314 315 316 317
  @override
  ImageStream resolve(ImageConfiguration configuration) {
    _configuration = configuration;
    return super.resolve(configuration);
  }

318
  @override
319
  ImageStreamCompleter load(TestImageProvider key) => new OneFrameImageStreamCompleter(_completer.future);
320

321 322 323
  void complete() {
    _completer.complete(new ImageInfo(image: new TestImage()));
  }
324 325

  @override
326
  String toString() => '$runtimeType($hashCode)';
327 328 329 330 331 332 333 334 335 336
}

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

  @override
  int get height => 100;

  @override
337
  void dispose() { }
338
}