| // Copyright 2019 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:io'; |
| import 'dart:typed_data'; |
| import 'dart:ui'; |
| |
| import 'package:litetest/litetest.dart'; |
| import 'package:path/path.dart' as path; |
| |
| void main() { |
| bool assertsEnabled = false; |
| assert(() { |
| assertsEnabled = true; |
| return true; |
| }()); |
| |
| test('Handles are distinct', () async { |
| final Uint8List bytes = await readFile('2x2.png'); |
| final Codec codec = await instantiateImageCodec(bytes); |
| final FrameInfo frame = await codec.getNextFrame(); |
| |
| expect(frame.image.width, 2); |
| expect(frame.image.height, 2); |
| final Image handle1 = frame.image.clone(); |
| expect(handle1.width, frame.image.width); |
| expect(handle1.height, frame.image.height); |
| |
| final Image handle2 = handle1.clone(); |
| expect(handle1 != handle2, true); |
| expect(handle1 != frame.image, true); |
| expect(frame.image == frame.image, true); |
| |
| frame.image.dispose(); |
| }); |
| |
| test('Canvas can paint image from handle and byte data from handle', () async { |
| final Uint8List bytes = await readFile('2x2.png'); |
| final Codec codec = await instantiateImageCodec(bytes); |
| final FrameInfo frame = await codec.getNextFrame(); |
| |
| expect(frame.image.width, 2); |
| expect(frame.image.height, 2); |
| final Image handle1 = frame.image.clone(); |
| |
| final PictureRecorder recorder = PictureRecorder(); |
| final Canvas canvas = Canvas(recorder); |
| |
| const Rect rect = Rect.fromLTRB(0, 0, 2, 2); |
| canvas.drawImage(handle1, Offset.zero, Paint()); |
| canvas.drawImageRect(handle1, rect, rect, Paint()); |
| canvas.drawImageNine(handle1, rect, rect, Paint()); |
| canvas.drawAtlas(handle1, <RSTransform>[], <Rect>[], <Color>[], BlendMode.src, rect, Paint()); |
| canvas.drawRawAtlas(handle1, Float32List(0), Float32List(0), Int32List(0), BlendMode.src, rect, Paint()); |
| |
| final Picture picture = recorder.endRecording(); |
| |
| final Image rasterizedImage = await picture.toImage(2, 2); |
| final ByteData sourceData = (await frame.image.toByteData())!; |
| final ByteData handleData = (await handle1.toByteData())!; |
| final ByteData rasterizedData = (await rasterizedImage.toByteData())!; |
| |
| expect(sourceData.buffer.asUint8List(), equals(handleData.buffer.asUint8List())); |
| expect(sourceData.buffer.asUint8List(), equals(rasterizedData.buffer.asUint8List())); |
| }); |
| |
| test('Records stack traces', () async { |
| final Uint8List bytes = await readFile('2x2.png'); |
| final Codec codec = await instantiateImageCodec(bytes); |
| final FrameInfo frame = await codec.getNextFrame(); |
| |
| final Image handle1 = frame.image.clone(); |
| final Image handle2 = handle1.clone(); |
| |
| List<StackTrace> stackTraces = (frame.image.debugGetOpenHandleStackTraces())!; |
| expect(stackTraces.length, 3); |
| expect(stackTraces, equals(handle1.debugGetOpenHandleStackTraces())); |
| |
| handle1.dispose(); |
| stackTraces = (frame.image.debugGetOpenHandleStackTraces())!; |
| expect(stackTraces.length, 2); |
| expect(stackTraces, equals(handle2.debugGetOpenHandleStackTraces())); |
| |
| handle2.dispose(); |
| stackTraces = (frame.image.debugGetOpenHandleStackTraces())!; |
| expect(stackTraces.length, 1); |
| expect(stackTraces, equals(frame.image.debugGetOpenHandleStackTraces())); |
| |
| frame.image.dispose(); |
| expect(frame.image.debugGetOpenHandleStackTraces(), isEmpty); |
| }, skip: !assertsEnabled); |
| |
| test('Clones can be compared', () async { |
| final Uint8List bytes = await readFile('2x2.png'); |
| final Codec codec = await instantiateImageCodec(bytes); |
| final FrameInfo frame = await codec.getNextFrame(); |
| |
| final Image handle1 = frame.image.clone(); |
| final Image handle2 = handle1.clone(); |
| |
| expect(handle1.isCloneOf(handle2), true); |
| expect(handle2.isCloneOf(handle1), true); |
| expect(handle1.isCloneOf(frame.image), true); |
| |
| handle1.dispose(); |
| expect(handle1.isCloneOf(handle2), true); |
| expect(handle2.isCloneOf(handle1), true); |
| expect(handle1.isCloneOf(frame.image), true); |
| |
| final Codec codec2 = await instantiateImageCodec(bytes); |
| final FrameInfo frame2 = await codec2.getNextFrame(); |
| |
| expect(frame2.image.isCloneOf(frame.image), false); |
| }); |
| |
| test('getNextFrame does not return a disposed image', () async { |
| final Uint8List bytes = await readFile('2x2.png'); |
| final Codec codec = await instantiateImageCodec(bytes); |
| final FrameInfo frame = await codec.getNextFrame(); |
| |
| frame.image.dispose(); |
| |
| final FrameInfo frame2 = await codec.getNextFrame(); |
| expect(frame2.image.clone()..dispose(), isNotNull); |
| frame2.image.dispose(); |
| }); |
| |
| test('debugDisposed works', () async { |
| final Uint8List bytes = await readFile('2x2.png'); |
| final Codec codec = await instantiateImageCodec(bytes); |
| final FrameInfo frame = await codec.getNextFrame(); |
| |
| if (assertsEnabled) { |
| expect(frame.image.debugDisposed, false); |
| } else { |
| expect(() => frame.image.debugDisposed, throwsStateError); |
| } |
| |
| frame.image.dispose(); |
| if (assertsEnabled) { |
| expect(frame.image.debugDisposed, true); |
| } else { |
| expect(() => frame.image.debugDisposed, throwsStateError); |
| } |
| }); |
| } |
| |
| Future<Uint8List> readFile(String fileName) async { |
| final File file = File(path.join( |
| 'flutter', |
| 'testing', |
| 'resources', |
| fileName, |
| )); |
| return file.readAsBytes(); |
| } |