// 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:convert'; import 'package:flutter/painting.dart'; import 'package:flutter_test/flutter_test.dart'; import 'common.dart'; void main() { initTimelineTests(); TestWidgetsFlutterBinding.ensureInitialized(); test('Image cache tracing', () async { final TestImageStreamCompleter completer1 = TestImageStreamCompleter(); final TestImageStreamCompleter completer2 = TestImageStreamCompleter(); PaintingBinding.instance.imageCache.putIfAbsent( 'Test', () => completer1, ); PaintingBinding.instance.imageCache.clear(); completer2.testSetImage(ImageInfo(image: await createTestImage())); PaintingBinding.instance.imageCache.putIfAbsent( 'Test2', () => completer2, ); PaintingBinding.instance.imageCache.evict('Test2'); _expectTimelineEvents( await fetchTimelineEvents(), >[ { 'name': 'ImageCache.putIfAbsent', 'args': {'key': 'Test', 'isolateId': isolateId} }, { 'name': 'listener', 'args': {'isolateId': isolateId} }, { 'name': 'ImageCache.clear', 'args': { 'pendingImages': 1, 'keepAliveImages': 0, 'liveImages': 1, 'currentSizeInBytes': 0, 'isolateId': isolateId, } }, { 'name': 'ImageCache.putIfAbsent', 'args': {'key': 'Test2', 'isolateId': isolateId} }, { 'name': 'ImageCache.evict', 'args': {'sizeInBytes': 4, 'isolateId': isolateId} }, ], ); }, skip: isBrowser); // [intended] uses dart:isolate and io. } void _expectTimelineEvents(List events, List> expected) { for (final TimelineEvent event in events) { for (int index = 0; index < expected.length; index += 1) { if (expected[index]['name'] == event.json!['name']) { final Map expectedArgs = expected[index]['args'] as Map; final Map args = event.json!['args'] as Map; if (_mapsEqual(expectedArgs, args)) { expected.removeAt(index); } } } } if (expected.isNotEmpty) { final String encodedEvents = jsonEncode(events); fail('Timeline did not contain expected events: $expected\nactual: $encodedEvents'); } } bool _mapsEqual(Map expectedArgs, Map args) { for (final String key in expectedArgs.keys) { if (expectedArgs[key] != args[key]) { return false; } } return true; } class TestImageStreamCompleter extends ImageStreamCompleter { void testSetImage(ImageInfo image) { setImage(image); } }