|  | // 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/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]!.clone(); | 
|  | } | 
|  |  | 
|  | final ui.Image image = await _createImage(width, height); | 
|  | if (cache) { | 
|  | _cache[cacheKey] = image.clone(); | 
|  | } | 
|  | return image; | 
|  | }); | 
|  |  | 
|  | Future<ui.Image> _createImage(int width, int height) async { | 
|  | 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 completer.future; | 
|  | } |