Migrate non-test files in flutter/test (#67098)

This commit is contained in:
Michael Goderbauer 2020-10-02 21:57:04 -07:00 committed by GitHub
parent ddb8177018
commit cbf1e135c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 307 additions and 331 deletions

View File

@ -58,6 +58,10 @@ class SynchronousErrorTestImageProvider extends ImageProvider<int> {
} }
class AsyncTestImageProvider extends ImageProvider<int> { class AsyncTestImageProvider extends ImageProvider<int> {
AsyncTestImageProvider(this.image);
final ui.Image image;
@override @override
Future<int> obtainKey(ImageConfiguration configuration) { Future<int> obtainKey(ImageConfiguration configuration) {
return Future<int>.value(2); return Future<int>.value(2);
@ -66,7 +70,7 @@ class AsyncTestImageProvider extends ImageProvider<int> {
@override @override
ImageStreamCompleter load(int key, DecoderCallback decode) { ImageStreamCompleter load(int key, DecoderCallback decode) {
return OneFrameImageStreamCompleter( return OneFrameImageStreamCompleter(
Future<ImageInfo>.value(TestImageInfo(key)) Future<ImageInfo>.value(TestImageInfo(key, image: image))
); );
} }
} }
@ -147,9 +151,10 @@ void main() {
expect(onChangedCalled, equals(false)); expect(onChangedCalled, equals(false));
}); });
test('BoxDecorationImageListenerAsync', () { test('BoxDecorationImageListenerAsync', () async {
FakeAsync().run((FakeAsync async) { final ui.Image image = await createTestImage(width: 10, height: 10);
final ImageProvider imageProvider = AsyncTestImageProvider(); FakeAsync().run((FakeAsync async) {
final ImageProvider imageProvider = AsyncTestImageProvider(image);
final DecorationImage backgroundImage = DecorationImage(image: imageProvider); final DecorationImage backgroundImage = DecorationImage(image: imageProvider);
final BoxDecoration boxDecoration = BoxDecoration(image: backgroundImage); final BoxDecoration boxDecoration = BoxDecoration(image: backgroundImage);

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:typed_data'; import 'dart:typed_data';
import 'dart:ui' as ui show Codec, FrameInfo, instantiateImageCodec; import 'dart:ui' as ui show Codec, FrameInfo, instantiateImageCodec;
@ -28,9 +26,9 @@ class FakeCodec implements ui.Codec {
static Future<FakeCodec> fromData(Uint8List data) async { static Future<FakeCodec> fromData(Uint8List data) async {
final ui.Codec codec = await ui.instantiateImageCodec(data); final ui.Codec codec = await ui.instantiateImageCodec(data);
final int frameCount = codec.frameCount; final int frameCount = codec.frameCount;
final List<ui.FrameInfo> frameInfos = List<ui.FrameInfo>(frameCount); final List<ui.FrameInfo> frameInfos = <ui.FrameInfo>[];
for (int i = 0; i < frameCount; i += 1) for (int i = 0; i < frameCount; i += 1)
frameInfos[i] = await codec.getNextFrame(); frameInfos.add(await codec.getNextFrame());
return FakeCodec._(frameCount, codec.repetitionCount, frameInfos); return FakeCodec._(frameCount, codec.repetitionCount, frameInfos);
} }

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:ui' as ui show Codec; import 'dart:ui' as ui show Codec;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:async'; import 'dart:async';
import 'dart:ui' as ui; import 'dart:ui' as ui;
@ -19,7 +17,7 @@ class TestImageProvider extends ImageProvider<TestImageProvider> {
final ui.Image testImage; final ui.Image testImage;
final Completer<ImageInfo> _completer = Completer<ImageInfo>.sync(); final Completer<ImageInfo> _completer = Completer<ImageInfo>.sync();
ImageConfiguration configuration; ImageConfiguration? configuration;
int loadCallCount = 0; int loadCallCount = 0;
@override @override

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:async'; import 'dart:async';
import 'dart:ui' as ui show Image; import 'dart:ui' as ui show Image;
@ -11,7 +9,7 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
class TestImageInfo implements ImageInfo { class TestImageInfo implements ImageInfo {
const TestImageInfo(this.value, { this.image, this.scale = 1.0, this.debugLabel }); const TestImageInfo(this.value, { required this.image, this.scale = 1.0, this.debugLabel });
@override @override
final ui.Image image; final ui.Image image;
@ -20,7 +18,7 @@ class TestImageInfo implements ImageInfo {
final double scale; final double scale;
@override @override
final String debugLabel; final String? debugLabel;
final int value; final int value;
@ -29,7 +27,7 @@ class TestImageInfo implements ImageInfo {
} }
class TestImageProvider extends ImageProvider<int> { class TestImageProvider extends ImageProvider<int> {
const TestImageProvider(this.key, this.imageValue, { @required this.image }) const TestImageProvider(this.key, this.imageValue, { required this.image })
: assert(image != null); : assert(image != null);
final int key; final int key;
@ -53,7 +51,7 @@ class TestImageProvider extends ImageProvider<int> {
} }
class FailingTestImageProvider extends TestImageProvider { class FailingTestImageProvider extends TestImageProvider {
const FailingTestImageProvider(int key, int imageValue, { ui.Image image }) : super(key, imageValue, image: image); const FailingTestImageProvider(int key, int imageValue, { required ui.Image image }) : super(key, imageValue, image: image);
@override @override
ImageStreamCompleter load(int key, DecoderCallback decode) { ImageStreamCompleter load(int key, DecoderCallback decode) {
@ -63,7 +61,7 @@ class FailingTestImageProvider extends TestImageProvider {
Future<ImageInfo> extractOneFrame(ImageStream stream) { Future<ImageInfo> extractOneFrame(ImageStream stream) {
final Completer<ImageInfo> completer = Completer<ImageInfo>(); final Completer<ImageInfo> completer = Completer<ImageInfo>();
ImageStreamListener listener; late ImageStreamListener listener;
listener = ImageStreamListener((ImageInfo image, bool synchronousCall) { listener = ImageStreamListener((ImageInfo image, bool synchronousCall) {
completer.complete(image); completer.complete(image);
stream.removeListener(listener); stream.removeListener(listener);

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:typed_data'; import 'dart:typed_data';
import 'dart:ui' as ui; import 'dart:ui' as ui;
@ -17,7 +15,7 @@ class PaintingBindingSpy extends BindingBase with SchedulerBinding, ServicesBind
int get instantiateImageCodecCalledCount => counter; int get instantiateImageCodecCalledCount => counter;
@override @override
Future<ui.Codec> instantiateImageCodec(Uint8List list, {int cacheWidth, int cacheHeight, bool allowUpscaling = false}) { Future<ui.Codec> instantiateImageCodec(Uint8List list, {int? cacheWidth, int? cacheHeight, bool allowUpscaling = false}) {
counter++; counter++;
return ui.instantiateImageCodec(list); return ui.instantiateImageCodec(list);
} }

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:ui' as ui show Paragraph, Image; import 'dart:ui' as ui show Paragraph, Image;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -102,14 +100,14 @@ abstract class PaintPattern {
/// Calls are skipped until a call to [Canvas.translate] is found. The call's /// Calls are skipped until a call to [Canvas.translate] is found. The call's
/// arguments are compared to those provided here. If any fail to match, or if /// arguments are compared to those provided here. If any fail to match, or if
/// no call to [Canvas.translate] is found, then the matcher fails. /// no call to [Canvas.translate] is found, then the matcher fails.
void translate({ double x, double y }); void translate({ double? x, double? y });
/// Indicates that a scale transform is expected next. /// Indicates that a scale transform is expected next.
/// ///
/// Calls are skipped until a call to [Canvas.scale] is found. The call's /// Calls are skipped until a call to [Canvas.scale] is found. The call's
/// arguments are compared to those provided here. If any fail to match, or if /// arguments are compared to those provided here. If any fail to match, or if
/// no call to [Canvas.scale] is found, then the matcher fails. /// no call to [Canvas.scale] is found, then the matcher fails.
void scale({ double x, double y }); void scale({ double? x, double? y });
/// Indicates that a rotate transform is expected next. /// Indicates that a rotate transform is expected next.
/// ///
@ -117,7 +115,7 @@ abstract class PaintPattern {
/// argument is provided here, the call's argument is compared to it. If that /// argument is provided here, the call's argument is compared to it. If that
/// fails to match, or if no call to [Canvas.rotate] is found, then the /// fails to match, or if no call to [Canvas.rotate] is found, then the
/// matcher fails. /// matcher fails.
void rotate({ double angle }); void rotate({ double? angle });
/// Indicates that a save is expected next. /// Indicates that a save is expected next.
/// ///
@ -165,7 +163,7 @@ abstract class PaintPattern {
/// ///
/// Any calls made between the last matched call (if any) and the /// Any calls made between the last matched call (if any) and the
/// [Canvas.clipRect] call are ignored. /// [Canvas.clipRect] call are ignored.
void clipRect({ Rect rect }); void clipRect({ Rect? rect });
/// Indicates that a path clip is expected next. /// Indicates that a path clip is expected next.
/// ///
@ -177,7 +175,7 @@ abstract class PaintPattern {
/// ///
/// Any calls made between the last matched call (if any) and the /// Any calls made between the last matched call (if any) and the
/// [Canvas.clipPath] call are ignored. /// [Canvas.clipPath] call are ignored.
void clipPath({ Matcher pathMatcher }); void clipPath({ Matcher? pathMatcher });
/// Indicates that a rectangle is expected next. /// Indicates that a rectangle is expected next.
/// ///
@ -195,7 +193,7 @@ abstract class PaintPattern {
/// painting has completed, not at the time of the call. If the same [Paint] /// painting has completed, not at the time of the call. If the same [Paint]
/// object is reused multiple times, then this may not match the actual /// object is reused multiple times, then this may not match the actual
/// arguments as they were seen by the method. /// arguments as they were seen by the method.
void rect({ Rect rect, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }); void rect({ Rect? rect, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style });
/// Indicates that a rounded rectangle clip is expected next. /// Indicates that a rounded rectangle clip is expected next.
/// ///
@ -207,7 +205,7 @@ abstract class PaintPattern {
/// ///
/// Any calls made between the last matched call (if any) and the /// Any calls made between the last matched call (if any) and the
/// [Canvas.clipRRect] call are ignored. /// [Canvas.clipRRect] call are ignored.
void clipRRect({ RRect rrect }); void clipRRect({ RRect? rrect });
/// Indicates that a rounded rectangle is expected next. /// Indicates that a rounded rectangle is expected next.
/// ///
@ -225,7 +223,7 @@ abstract class PaintPattern {
/// painting has completed, not at the time of the call. If the same [Paint] /// painting has completed, not at the time of the call. If the same [Paint]
/// object is reused multiple times, then this may not match the actual /// object is reused multiple times, then this may not match the actual
/// arguments as they were seen by the method. /// arguments as they were seen by the method.
void rrect({ RRect rrect, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }); void rrect({ RRect? rrect, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style });
/// Indicates that a rounded rectangle outline is expected next. /// Indicates that a rounded rectangle outline is expected next.
/// ///
@ -243,7 +241,7 @@ abstract class PaintPattern {
/// painting has completed, not at the time of the call. If the same [Paint] /// painting has completed, not at the time of the call. If the same [Paint]
/// object is reused multiple times, then this may not match the actual /// object is reused multiple times, then this may not match the actual
/// arguments as they were seen by the method. /// arguments as they were seen by the method.
void drrect({ RRect outer, RRect inner, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }); void drrect({ RRect? outer, RRect? inner, Color? color, double strokeWidth, bool hasMaskFilter, PaintingStyle style });
/// Indicates that a circle is expected next. /// Indicates that a circle is expected next.
/// ///
@ -261,7 +259,7 @@ abstract class PaintPattern {
/// painting has completed, not at the time of the call. If the same [Paint] /// painting has completed, not at the time of the call. If the same [Paint]
/// object is reused multiple times, then this may not match the actual /// object is reused multiple times, then this may not match the actual
/// arguments as they were seen by the method. /// arguments as they were seen by the method.
void circle({ double x, double y, double radius, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }); void circle({ double? x, double? y, double? radius, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style });
/// Indicates that a path is expected next. /// Indicates that a path is expected next.
/// ///
@ -284,7 +282,7 @@ abstract class PaintPattern {
/// painting has completed, not at the time of the call. If the same [Paint] /// painting has completed, not at the time of the call. If the same [Paint]
/// object is reused multiple times, then this may not match the actual /// object is reused multiple times, then this may not match the actual
/// arguments as they were seen by the method. /// arguments as they were seen by the method.
void path({ Iterable<Offset> includes, Iterable<Offset> excludes, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }); void path({ Iterable<Offset>? includes, Iterable<Offset>? excludes, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style });
/// Indicates that a line is expected next. /// Indicates that a line is expected next.
/// ///
@ -302,7 +300,7 @@ abstract class PaintPattern {
/// painting has completed, not at the time of the call. If the same [Paint] /// painting has completed, not at the time of the call. If the same [Paint]
/// object is reused multiple times, then this may not match the actual /// object is reused multiple times, then this may not match the actual
/// arguments as they were seen by the method. /// arguments as they were seen by the method.
void line({ Offset p1, Offset p2, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }); void line({ Offset? p1, Offset? p2, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style });
/// Indicates that an arc is expected next. /// Indicates that an arc is expected next.
/// ///
@ -320,7 +318,7 @@ abstract class PaintPattern {
/// painting has completed, not at the time of the call. If the same [Paint] /// painting has completed, not at the time of the call. If the same [Paint]
/// object is reused multiple times, then this may not match the actual /// object is reused multiple times, then this may not match the actual
/// arguments as they were seen by the method. /// arguments as they were seen by the method.
void arc({ Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }); void arc({ Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style });
/// Indicates that a paragraph is expected next. /// Indicates that a paragraph is expected next.
/// ///
@ -336,7 +334,7 @@ abstract class PaintPattern {
/// offset. /// offset.
/// ///
/// If no call to [Canvas.drawParagraph] was made, then this results in failure. /// If no call to [Canvas.drawParagraph] was made, then this results in failure.
void paragraph({ ui.Paragraph paragraph, dynamic offset }); void paragraph({ ui.Paragraph? paragraph, dynamic offset });
/// Indicates that a shadow is expected next. /// Indicates that a shadow is expected next.
/// ///
@ -357,7 +355,7 @@ abstract class PaintPattern {
/// ///
/// Any calls made between the last matched call (if any) and the /// Any calls made between the last matched call (if any) and the
/// [Canvas.drawShadow] call are ignored. /// [Canvas.drawShadow] call are ignored.
void shadow({ Iterable<Offset> includes, Iterable<Offset> excludes, Color color, double elevation, bool transparentOccluder }); void shadow({ Iterable<Offset>? includes, Iterable<Offset>? excludes, Color? color, double? elevation, bool? transparentOccluder });
/// Indicates that an image is expected next. /// Indicates that an image is expected next.
/// ///
@ -375,7 +373,7 @@ abstract class PaintPattern {
/// painting has completed, not at the time of the call. If the same [Paint] /// painting has completed, not at the time of the call. If the same [Paint]
/// object is reused multiple times, then this may not match the actual /// object is reused multiple times, then this may not match the actual
/// arguments as they were seen by the method. /// arguments as they were seen by the method.
void image({ ui.Image image, double x, double y, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }); void image({ ui.Image? image, double? x, double? y, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style });
/// Indicates that an image subsection is expected next. /// Indicates that an image subsection is expected next.
/// ///
@ -393,7 +391,7 @@ abstract class PaintPattern {
/// painting has completed, not at the time of the call. If the same [Paint] /// painting has completed, not at the time of the call. If the same [Paint]
/// object is reused multiple times, then this may not match the actual /// object is reused multiple times, then this may not match the actual
/// arguments as they were seen by the method. /// arguments as they were seen by the method.
void drawImageRect({ ui.Image image, Rect source, Rect destination, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }); void drawImageRect({ ui.Image? image, Rect? source, Rect? destination, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style });
/// Provides a custom matcher. /// Provides a custom matcher.
/// ///
@ -451,12 +449,12 @@ class _PathMatcher extends Matcher {
List<Offset> excludes; List<Offset> excludes;
@override @override
bool matches(Object object, Map<dynamic, dynamic> matchState) { bool matches(Object? object, Map<dynamic, dynamic> matchState) {
if (object is! Path) { if (object is! Path) {
matchState[this] = 'The given object ($object) was not a Path.'; matchState[this] = 'The given object ($object) was not a Path.';
return false; return false;
} }
final Path path = object as Path; final Path path = object;
final List<String> errors = <String>[ final List<String> errors = <String>[
for (final Offset offset in includes) for (final Offset offset in includes)
if (!path.contains(offset)) if (!path.contains(offset))
@ -500,7 +498,7 @@ class _MismatchedCall {
final RecordedInvocation call; final RecordedInvocation call;
} }
bool _evaluatePainter(Object object, Canvas canvas, PaintingContext context) { bool _evaluatePainter(Object? object, Canvas canvas, PaintingContext context) {
if (object is _ContextPainterFunction) { if (object is _ContextPainterFunction) {
final _ContextPainterFunction function = object; final _ContextPainterFunction function = object;
function(context, Offset.zero); function(context, Offset.zero);
@ -510,7 +508,7 @@ bool _evaluatePainter(Object object, Canvas canvas, PaintingContext context) {
} else { } else {
if (object is Finder) { if (object is Finder) {
TestAsyncUtils.guardSync(); TestAsyncUtils.guardSync();
final Finder finder = object as Finder; final Finder finder = object;
object = finder.evaluate().single.renderObject; object = finder.evaluate().single.renderObject;
} }
if (object is RenderObject) { if (object is RenderObject) {
@ -525,7 +523,7 @@ bool _evaluatePainter(Object object, Canvas canvas, PaintingContext context) {
abstract class _TestRecordingCanvasMatcher extends Matcher { abstract class _TestRecordingCanvasMatcher extends Matcher {
@override @override
bool matches(Object object, Map<dynamic, dynamic> matchState) { bool matches(Object? object, Map<dynamic, dynamic> matchState) {
final TestRecordingCanvas canvas = TestRecordingCanvas(); final TestRecordingCanvas canvas = TestRecordingCanvas();
final TestRecordingPaintingContext context = TestRecordingPaintingContext(canvas); final TestRecordingPaintingContext context = TestRecordingPaintingContext(canvas);
final StringBuffer description = StringBuffer(); final StringBuffer description = StringBuffer();
@ -630,7 +628,7 @@ class _TestRecordingCanvasPaintsNothingMatcher extends _TestRecordingCanvasMatch
class _TestRecordingCanvasPaintsAssertionMatcher extends Matcher { class _TestRecordingCanvasPaintsAssertionMatcher extends Matcher {
@override @override
bool matches(Object object, Map<dynamic, dynamic> matchState) { bool matches(Object? object, Map<dynamic, dynamic> matchState) {
final TestRecordingCanvas canvas = TestRecordingCanvas(); final TestRecordingCanvas canvas = TestRecordingCanvas();
final TestRecordingPaintingContext context = TestRecordingPaintingContext(canvas); final TestRecordingPaintingContext context = TestRecordingPaintingContext(canvas);
final StringBuffer description = StringBuffer(); final StringBuffer description = StringBuffer();
@ -686,17 +684,17 @@ class _TestRecordingCanvasPatternMatcher extends _TestRecordingCanvasMatcher imp
} }
@override @override
void translate({ double x, double y }) { void translate({ double? x, double? y }) {
_predicates.add(_FunctionPaintPredicate(#translate, <dynamic>[x, y])); _predicates.add(_FunctionPaintPredicate(#translate, <dynamic>[x, y]));
} }
@override @override
void scale({ double x, double y }) { void scale({ double? x, double? y }) {
_predicates.add(_FunctionPaintPredicate(#scale, <dynamic>[x, y])); _predicates.add(_FunctionPaintPredicate(#scale, <dynamic>[x, y]));
} }
@override @override
void rotate({ double angle }) { void rotate({ double? angle }) {
_predicates.add(_FunctionPaintPredicate(#rotate, <dynamic>[angle])); _predicates.add(_FunctionPaintPredicate(#rotate, <dynamic>[angle]));
} }
@ -716,72 +714,72 @@ class _TestRecordingCanvasPatternMatcher extends _TestRecordingCanvasMatcher imp
} }
@override @override
void clipRect({ Rect rect }) { void clipRect({ Rect? rect }) {
_predicates.add(_FunctionPaintPredicate(#clipRect, <dynamic>[rect])); _predicates.add(_FunctionPaintPredicate(#clipRect, <dynamic>[rect]));
} }
@override @override
void clipPath({ Matcher pathMatcher }) { void clipPath({ Matcher? pathMatcher }) {
_predicates.add(_FunctionPaintPredicate(#clipPath, <dynamic>[pathMatcher])); _predicates.add(_FunctionPaintPredicate(#clipPath, <dynamic>[pathMatcher]));
} }
@override @override
void rect({ Rect rect, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) { void rect({ Rect? rect, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style }) {
_predicates.add(_RectPaintPredicate(rect: rect, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style)); _predicates.add(_RectPaintPredicate(rect: rect, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style));
} }
@override @override
void clipRRect({ RRect rrect }) { void clipRRect({ RRect? rrect }) {
_predicates.add(_FunctionPaintPredicate(#clipRRect, <dynamic>[rrect])); _predicates.add(_FunctionPaintPredicate(#clipRRect, <dynamic>[rrect]));
} }
@override @override
void rrect({ RRect rrect, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) { void rrect({ RRect? rrect, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style }) {
_predicates.add(_RRectPaintPredicate(rrect: rrect, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style)); _predicates.add(_RRectPaintPredicate(rrect: rrect, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style));
} }
@override @override
void drrect({ RRect outer, RRect inner, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) { void drrect({ RRect? outer, RRect? inner, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style }) {
_predicates.add(_DRRectPaintPredicate(outer: outer, inner: inner, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style)); _predicates.add(_DRRectPaintPredicate(outer: outer, inner: inner, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style));
} }
@override @override
void circle({ double x, double y, double radius, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) { void circle({ double? x, double? y, double? radius, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style }) {
_predicates.add(_CirclePaintPredicate(x: x, y: y, radius: radius, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style)); _predicates.add(_CirclePaintPredicate(x: x, y: y, radius: radius, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style));
} }
@override @override
void path({ Iterable<Offset> includes, Iterable<Offset> excludes, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) { void path({ Iterable<Offset>? includes, Iterable<Offset>? excludes, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style }) {
_predicates.add(_PathPaintPredicate(includes: includes, excludes: excludes, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style)); _predicates.add(_PathPaintPredicate(includes: includes, excludes: excludes, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style));
} }
@override @override
void line({ Offset p1, Offset p2, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) { void line({ Offset? p1, Offset? p2, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style }) {
_predicates.add(_LinePaintPredicate(p1: p1, p2: p2, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style)); _predicates.add(_LinePaintPredicate(p1: p1, p2: p2, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style));
} }
@override @override
void arc({ Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) { void arc({ Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style }) {
_predicates.add(_ArcPaintPredicate(color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style)); _predicates.add(_ArcPaintPredicate(color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style));
} }
@override @override
void paragraph({ ui.Paragraph paragraph, dynamic offset }) { void paragraph({ ui.Paragraph? paragraph, dynamic offset }) {
_predicates.add(_FunctionPaintPredicate(#drawParagraph, <dynamic>[paragraph, offset])); _predicates.add(_FunctionPaintPredicate(#drawParagraph, <dynamic>[paragraph, offset]));
} }
@override @override
void shadow({ Iterable<Offset> includes, Iterable<Offset> excludes, Color color, double elevation, bool transparentOccluder }) { void shadow({ Iterable<Offset>? includes, Iterable<Offset>? excludes, Color? color, double? elevation, bool? transparentOccluder }) {
_predicates.add(_ShadowPredicate(includes: includes, excludes: excludes, color: color, elevation: elevation, transparentOccluder: transparentOccluder)); _predicates.add(_ShadowPredicate(includes: includes, excludes: excludes, color: color, elevation: elevation, transparentOccluder: transparentOccluder));
} }
@override @override
void image({ ui.Image image, double x, double y, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) { void image({ ui.Image? image, double? x, double? y, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style }) {
_predicates.add(_DrawImagePaintPredicate(image: image, x: x, y: y, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style)); _predicates.add(_DrawImagePaintPredicate(image: image, x: x, y: y, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style));
} }
@override @override
void drawImageRect({ ui.Image image, Rect source, Rect destination, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) { void drawImageRect({ ui.Image? image, Rect? source, Rect? destination, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style }) {
_predicates.add(_DrawImageRectPaintPredicate(image: image, source: source, destination: destination, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style)); _predicates.add(_DrawImageRectPaintPredicate(image: image, source: source, destination: destination, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style));
} }
@ -892,10 +890,10 @@ abstract class _DrawCommandPaintPredicate extends _PaintPredicate {
final String name; final String name;
final int argumentCount; final int argumentCount;
final int paintArgumentIndex; final int paintArgumentIndex;
final Color color; final Color? color;
final double strokeWidth; final double? strokeWidth;
final bool hasMaskFilter; final bool? hasMaskFilter;
final PaintingStyle style; final PaintingStyle? style;
String get methodName => _symbolName(symbol); String get methodName => _symbolName(symbol);
@ -918,7 +916,7 @@ abstract class _DrawCommandPaintPredicate extends _PaintPredicate {
if (strokeWidth != null && paintArgument.strokeWidth != strokeWidth) if (strokeWidth != null && paintArgument.strokeWidth != strokeWidth)
throw 'It called $methodName with a paint whose strokeWidth, ${paintArgument.strokeWidth}, was not exactly the expected strokeWidth ($strokeWidth).'; throw 'It called $methodName with a paint whose strokeWidth, ${paintArgument.strokeWidth}, was not exactly the expected strokeWidth ($strokeWidth).';
if (hasMaskFilter != null && (paintArgument.maskFilter != null) != hasMaskFilter) { if (hasMaskFilter != null && (paintArgument.maskFilter != null) != hasMaskFilter) {
if (hasMaskFilter) if (hasMaskFilter!)
throw 'It called $methodName with a paint that did not have a mask filter, despite expecting one.'; throw 'It called $methodName with a paint that did not have a mask filter, despite expecting one.';
else else
throw 'It called $methodName with a paint that did have a mask filter, despite not expecting one.'; throw 'It called $methodName with a paint that did have a mask filter, despite not expecting one.';
@ -945,7 +943,7 @@ abstract class _DrawCommandPaintPredicate extends _PaintPredicate {
if (strokeWidth != null) if (strokeWidth != null)
description.add('strokeWidth: $strokeWidth'); description.add('strokeWidth: $strokeWidth');
if (hasMaskFilter != null) if (hasMaskFilter != null)
description.add(hasMaskFilter ? 'a mask filter' : 'no mask filter'); description.add(hasMaskFilter! ? 'a mask filter' : 'no mask filter');
if (style != null) if (style != null)
description.add('$style'); description.add('$style');
} }
@ -955,15 +953,15 @@ class _OneParameterPaintPredicate<T> extends _DrawCommandPaintPredicate {
_OneParameterPaintPredicate( _OneParameterPaintPredicate(
Symbol symbol, Symbol symbol,
String name, { String name, {
@required this.expected, required this.expected,
@required Color color, required Color? color,
@required double strokeWidth, required double? strokeWidth,
@required bool hasMaskFilter, required bool? hasMaskFilter,
@required PaintingStyle style, required PaintingStyle? style,
}) : super( }) : super(
symbol, name, 2, 1, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style); symbol, name, 2, 1, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style);
final T expected; final T? expected;
@override @override
void verifyArguments(List<dynamic> arguments) { void verifyArguments(List<dynamic> arguments) {
@ -990,18 +988,18 @@ class _TwoParameterPaintPredicate<T1, T2> extends _DrawCommandPaintPredicate {
_TwoParameterPaintPredicate( _TwoParameterPaintPredicate(
Symbol symbol, Symbol symbol,
String name, { String name, {
@required this.expected1, required this.expected1,
@required this.expected2, required this.expected2,
@required Color color, required Color? color,
@required double strokeWidth, required double? strokeWidth,
@required bool hasMaskFilter, required bool? hasMaskFilter,
@required PaintingStyle style, required PaintingStyle? style,
}) : super( }) : super(
symbol, name, 3, 2, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style); symbol, name, 3, 2, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style);
final T1 expected1; final T1? expected1;
final T2 expected2; final T2? expected2;
@override @override
void verifyArguments(List<dynamic> arguments) { void verifyArguments(List<dynamic> arguments) {
@ -1035,7 +1033,7 @@ class _TwoParameterPaintPredicate<T1, T2> extends _DrawCommandPaintPredicate {
} }
class _RectPaintPredicate extends _OneParameterPaintPredicate<Rect> { class _RectPaintPredicate extends _OneParameterPaintPredicate<Rect> {
_RectPaintPredicate({ Rect rect, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) : super( _RectPaintPredicate({ Rect? rect, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style }) : super(
#drawRect, #drawRect,
'a rectangle', 'a rectangle',
expected: rect, expected: rect,
@ -1047,7 +1045,7 @@ class _RectPaintPredicate extends _OneParameterPaintPredicate<Rect> {
} }
class _RRectPaintPredicate extends _DrawCommandPaintPredicate { class _RRectPaintPredicate extends _DrawCommandPaintPredicate {
_RRectPaintPredicate({ this.rrect, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) : super( _RRectPaintPredicate({ this.rrect, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style }) : super(
#drawRRect, #drawRRect,
'a rounded rectangle', 'a rounded rectangle',
2, 2,
@ -1058,7 +1056,7 @@ class _RRectPaintPredicate extends _DrawCommandPaintPredicate {
style: style, style: style,
); );
final RRect rrect; final RRect? rrect;
@override @override
void verifyArguments(List<dynamic> arguments) { void verifyArguments(List<dynamic> arguments) {
@ -1066,18 +1064,18 @@ class _RRectPaintPredicate extends _DrawCommandPaintPredicate {
const double eps = .0001; const double eps = .0001;
final RRect actual = arguments[0] as RRect; final RRect actual = arguments[0] as RRect;
if (rrect != null && if (rrect != null &&
((actual.left - rrect.left).abs() > eps || ((actual.left - rrect!.left).abs() > eps ||
(actual.right - rrect.right).abs() > eps || (actual.right - rrect!.right).abs() > eps ||
(actual.top - rrect.top).abs() > eps || (actual.top - rrect!.top).abs() > eps ||
(actual.bottom - rrect.bottom).abs() > eps || (actual.bottom - rrect!.bottom).abs() > eps ||
(actual.blRadiusX - rrect.blRadiusX).abs() > eps || (actual.blRadiusX - rrect!.blRadiusX).abs() > eps ||
(actual.blRadiusY - rrect.blRadiusY).abs() > eps || (actual.blRadiusY - rrect!.blRadiusY).abs() > eps ||
(actual.brRadiusX - rrect.brRadiusX).abs() > eps || (actual.brRadiusX - rrect!.brRadiusX).abs() > eps ||
(actual.brRadiusY - rrect.brRadiusY).abs() > eps || (actual.brRadiusY - rrect!.brRadiusY).abs() > eps ||
(actual.tlRadiusX - rrect.tlRadiusX).abs() > eps || (actual.tlRadiusX - rrect!.tlRadiusX).abs() > eps ||
(actual.tlRadiusY - rrect.tlRadiusY).abs() > eps || (actual.tlRadiusY - rrect!.tlRadiusY).abs() > eps ||
(actual.trRadiusX - rrect.trRadiusX).abs() > eps || (actual.trRadiusX - rrect!.trRadiusX).abs() > eps ||
(actual.trRadiusY - rrect.trRadiusY).abs() > eps)) { (actual.trRadiusY - rrect!.trRadiusY).abs() > eps)) {
throw 'It called $methodName with RRect, $actual, which was not exactly the expected RRect ($rrect).'; throw 'It called $methodName with RRect, $actual, which was not exactly the expected RRect ($rrect).';
} }
} }
@ -1092,7 +1090,7 @@ class _RRectPaintPredicate extends _DrawCommandPaintPredicate {
} }
class _DRRectPaintPredicate extends _TwoParameterPaintPredicate<RRect, RRect> { class _DRRectPaintPredicate extends _TwoParameterPaintPredicate<RRect, RRect> {
_DRRectPaintPredicate({ RRect inner, RRect outer, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) : super( _DRRectPaintPredicate({ RRect? inner, RRect? outer, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style }) : super(
#drawDRRect, #drawDRRect,
'a rounded rectangle outline', 'a rounded rectangle outline',
expected1: outer, expected1: outer,
@ -1105,69 +1103,69 @@ class _DRRectPaintPredicate extends _TwoParameterPaintPredicate<RRect, RRect> {
} }
class _CirclePaintPredicate extends _DrawCommandPaintPredicate { class _CirclePaintPredicate extends _DrawCommandPaintPredicate {
_CirclePaintPredicate({ this.x, this.y, this.radius, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) : super( _CirclePaintPredicate({ this.x, this.y, this.radius, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style }) : super(
#drawCircle, 'a circle', 3, 2, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style, #drawCircle, 'a circle', 3, 2, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style,
); );
final double x; final double? x;
final double y; final double? y;
final double radius; final double? radius;
@override @override
void verifyArguments(List<dynamic> arguments) { void verifyArguments(List<dynamic> arguments) {
super.verifyArguments(arguments); super.verifyArguments(arguments);
final Offset pointArgument = arguments[0] as Offset; final Offset pointArgument = arguments[0] as Offset;
if (x != null && y != null) { if (x != null && y != null) {
final Offset point = Offset(x, y); final Offset point = Offset(x!, y!);
if (point != pointArgument) if (point != pointArgument)
throw 'It called $methodName with a center coordinate, $pointArgument, which was not exactly the expected coordinate ($point).'; throw 'It called $methodName with a center coordinate, $pointArgument, which was not exactly the expected coordinate ($point).';
} else { } else {
if (x != null && pointArgument.dx != x) if (x != null && pointArgument.dx != x)
throw 'It called $methodName with a center coordinate, $pointArgument, whose x-coordinate not exactly the expected coordinate (${x.toStringAsFixed(1)}).'; throw 'It called $methodName with a center coordinate, $pointArgument, whose x-coordinate not exactly the expected coordinate (${x!.toStringAsFixed(1)}).';
if (y != null && pointArgument.dy != y) if (y != null && pointArgument.dy != y)
throw 'It called $methodName with a center coordinate, $pointArgument, whose y-coordinate not exactly the expected coordinate (${y.toStringAsFixed(1)}).'; throw 'It called $methodName with a center coordinate, $pointArgument, whose y-coordinate not exactly the expected coordinate (${y!.toStringAsFixed(1)}).';
} }
final double radiusArgument = arguments[1] as double; final double radiusArgument = arguments[1] as double;
if (radius != null && radiusArgument != radius) if (radius != null && radiusArgument != radius)
throw 'It called $methodName with radius, ${radiusArgument.toStringAsFixed(1)}, which was not exactly the expected radius (${radius.toStringAsFixed(1)}).'; throw 'It called $methodName with radius, ${radiusArgument.toStringAsFixed(1)}, which was not exactly the expected radius (${radius!.toStringAsFixed(1)}).';
} }
@override @override
void debugFillDescription(List<String> description) { void debugFillDescription(List<String> description) {
super.debugFillDescription(description); super.debugFillDescription(description);
if (x != null && y != null) { if (x != null && y != null) {
description.add('point ${Offset(x, y)}'); description.add('point ${Offset(x!, y!)}');
} else { } else {
if (x != null) if (x != null)
description.add('x-coordinate ${x.toStringAsFixed(1)}'); description.add('x-coordinate ${x!.toStringAsFixed(1)}');
if (y != null) if (y != null)
description.add('y-coordinate ${y.toStringAsFixed(1)}'); description.add('y-coordinate ${y!.toStringAsFixed(1)}');
} }
if (radius != null) if (radius != null)
description.add('radius ${radius.toStringAsFixed(1)}'); description.add('radius ${radius!.toStringAsFixed(1)}');
} }
} }
class _PathPaintPredicate extends _DrawCommandPaintPredicate { class _PathPaintPredicate extends _DrawCommandPaintPredicate {
_PathPaintPredicate({ this.includes, this.excludes, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) : super( _PathPaintPredicate({ this.includes, this.excludes, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style }) : super(
#drawPath, 'a path', 2, 1, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style, #drawPath, 'a path', 2, 1, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style,
); );
final Iterable<Offset> includes; final Iterable<Offset>? includes;
final Iterable<Offset> excludes; final Iterable<Offset>? excludes;
@override @override
void verifyArguments(List<dynamic> arguments) { void verifyArguments(List<dynamic> arguments) {
super.verifyArguments(arguments); super.verifyArguments(arguments);
final Path pathArgument = arguments[0] as Path; final Path pathArgument = arguments[0] as Path;
if (includes != null) { if (includes != null) {
for (final Offset offset in includes) { for (final Offset offset in includes!) {
if (!pathArgument.contains(offset)) if (!pathArgument.contains(offset))
throw 'It called $methodName with a path that unexpectedly did not contain $offset.'; throw 'It called $methodName with a path that unexpectedly did not contain $offset.';
} }
} }
if (excludes != null) { if (excludes != null) {
for (final Offset offset in excludes) { for (final Offset offset in excludes!) {
if (pathArgument.contains(offset)) if (pathArgument.contains(offset))
throw 'It called $methodName with a path that unexpectedly contained $offset.'; throw 'It called $methodName with a path that unexpectedly contained $offset.';
} }
@ -1189,12 +1187,12 @@ class _PathPaintPredicate extends _DrawCommandPaintPredicate {
// TODO(ianh): add arguments to test the length, angle, that kind of thing // TODO(ianh): add arguments to test the length, angle, that kind of thing
class _LinePaintPredicate extends _DrawCommandPaintPredicate { class _LinePaintPredicate extends _DrawCommandPaintPredicate {
_LinePaintPredicate({ this.p1, this.p2, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) : super( _LinePaintPredicate({ this.p1, this.p2, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style }) : super(
#drawLine, 'a line', 3, 2, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style, #drawLine, 'a line', 3, 2, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style,
); );
final Offset p1; final Offset? p1;
final Offset p2; final Offset? p2;
@override @override
void verifyArguments(List<dynamic> arguments) { void verifyArguments(List<dynamic> arguments) {
@ -1222,7 +1220,7 @@ class _LinePaintPredicate extends _DrawCommandPaintPredicate {
} }
class _ArcPaintPredicate extends _DrawCommandPaintPredicate { class _ArcPaintPredicate extends _DrawCommandPaintPredicate {
_ArcPaintPredicate({ Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) : super( _ArcPaintPredicate({ Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style }) : super(
#drawArc, 'an arc', 5, 4, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style, #drawArc, 'an arc', 5, 4, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style,
); );
} }
@ -1230,11 +1228,11 @@ class _ArcPaintPredicate extends _DrawCommandPaintPredicate {
class _ShadowPredicate extends _PaintPredicate { class _ShadowPredicate extends _PaintPredicate {
_ShadowPredicate({ this.includes, this.excludes, this.color, this.elevation, this.transparentOccluder }); _ShadowPredicate({ this.includes, this.excludes, this.color, this.elevation, this.transparentOccluder });
final Iterable<Offset> includes; final Iterable<Offset>? includes;
final Iterable<Offset> excludes; final Iterable<Offset>? excludes;
final Color color; final Color? color;
final double elevation; final double? elevation;
final bool transparentOccluder; final bool? transparentOccluder;
static const Symbol symbol = #drawShadow; static const Symbol symbol = #drawShadow;
String get methodName => _symbolName(symbol); String get methodName => _symbolName(symbol);
@ -1245,13 +1243,13 @@ class _ShadowPredicate extends _PaintPredicate {
throw 'It called $methodName with ${arguments.length} arguments; expected 4.'; throw 'It called $methodName with ${arguments.length} arguments; expected 4.';
final Path pathArgument = arguments[0] as Path; final Path pathArgument = arguments[0] as Path;
if (includes != null) { if (includes != null) {
for (final Offset offset in includes) { for (final Offset offset in includes!) {
if (!pathArgument.contains(offset)) if (!pathArgument.contains(offset))
throw 'It called $methodName with a path that unexpectedly did not contain $offset.'; throw 'It called $methodName with a path that unexpectedly did not contain $offset.';
} }
} }
if (excludes != null) { if (excludes != null) {
for (final Offset offset in excludes) { for (final Offset offset in excludes!) {
if (pathArgument.contains(offset)) if (pathArgument.contains(offset))
throw 'It called $methodName with a path that unexpectedly contained $offset.'; throw 'It called $methodName with a path that unexpectedly contained $offset.';
} }
@ -1303,13 +1301,13 @@ class _ShadowPredicate extends _PaintPredicate {
} }
class _DrawImagePaintPredicate extends _DrawCommandPaintPredicate { class _DrawImagePaintPredicate extends _DrawCommandPaintPredicate {
_DrawImagePaintPredicate({ this.image, this.x, this.y, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) : super( _DrawImagePaintPredicate({ this.image, this.x, this.y, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style }) : super(
#drawImage, 'an image', 3, 2, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style, #drawImage, 'an image', 3, 2, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style,
); );
final ui.Image image; final ui.Image? image;
final double x; final double? x;
final double y; final double? y;
@override @override
void verifyArguments(List<dynamic> arguments) { void verifyArguments(List<dynamic> arguments) {
@ -1319,14 +1317,14 @@ class _DrawImagePaintPredicate extends _DrawCommandPaintPredicate {
throw 'It called $methodName with an image, $imageArgument, which was not exactly the expected image ($image).'; throw 'It called $methodName with an image, $imageArgument, which was not exactly the expected image ($image).';
final Offset pointArgument = arguments[0] as Offset; final Offset pointArgument = arguments[0] as Offset;
if (x != null && y != null) { if (x != null && y != null) {
final Offset point = Offset(x, y); final Offset point = Offset(x!, y!);
if (point != pointArgument) if (point != pointArgument)
throw 'It called $methodName with an offset coordinate, $pointArgument, which was not exactly the expected coordinate ($point).'; throw 'It called $methodName with an offset coordinate, $pointArgument, which was not exactly the expected coordinate ($point).';
} else { } else {
if (x != null && pointArgument.dx != x) if (x != null && pointArgument.dx != x)
throw 'It called $methodName with an offset coordinate, $pointArgument, whose x-coordinate not exactly the expected coordinate (${x.toStringAsFixed(1)}).'; throw 'It called $methodName with an offset coordinate, $pointArgument, whose x-coordinate not exactly the expected coordinate (${x!.toStringAsFixed(1)}).';
if (y != null && pointArgument.dy != y) if (y != null && pointArgument.dy != y)
throw 'It called $methodName with an offset coordinate, $pointArgument, whose y-coordinate not exactly the expected coordinate (${y.toStringAsFixed(1)}).'; throw 'It called $methodName with an offset coordinate, $pointArgument, whose y-coordinate not exactly the expected coordinate (${y!.toStringAsFixed(1)}).';
} }
} }
@ -1336,24 +1334,24 @@ class _DrawImagePaintPredicate extends _DrawCommandPaintPredicate {
if (image != null) if (image != null)
description.add('image $image'); description.add('image $image');
if (x != null && y != null) { if (x != null && y != null) {
description.add('point ${Offset(x, y)}'); description.add('point ${Offset(x!, y!)}');
} else { } else {
if (x != null) if (x != null)
description.add('x-coordinate ${x.toStringAsFixed(1)}'); description.add('x-coordinate ${x!.toStringAsFixed(1)}');
if (y != null) if (y != null)
description.add('y-coordinate ${y.toStringAsFixed(1)}'); description.add('y-coordinate ${y!.toStringAsFixed(1)}');
} }
} }
} }
class _DrawImageRectPaintPredicate extends _DrawCommandPaintPredicate { class _DrawImageRectPaintPredicate extends _DrawCommandPaintPredicate {
_DrawImageRectPaintPredicate({ this.image, this.source, this.destination, Color color, double strokeWidth, bool hasMaskFilter, PaintingStyle style }) : super( _DrawImageRectPaintPredicate({ this.image, this.source, this.destination, Color? color, double? strokeWidth, bool? hasMaskFilter, PaintingStyle? style }) : super(
#drawImageRect, 'an image', 4, 3, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style, #drawImageRect, 'an image', 4, 3, color: color, strokeWidth: strokeWidth, hasMaskFilter: hasMaskFilter, style: style,
); );
final ui.Image image; final ui.Image? image;
final Rect source; final Rect? source;
final Rect destination; final Rect? destination;
@override @override
void verifyArguments(List<dynamic> arguments) { void verifyArguments(List<dynamic> arguments) {
@ -1500,7 +1498,7 @@ class _SaveRestorePairPaintPredicate extends _PaintPredicate {
String toString() => 'a matching save/restore pair'; String toString() => 'a matching save/restore pair';
} }
String _valueName(Object value) { String _valueName(Object? value) {
if (value is double) if (value is double)
return value.toStringAsFixed(1); return value.toStringAsFixed(1);
return value.toString(); return value.toString();

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
@ -20,7 +18,7 @@ class _TestHitTester extends RenderBox {
final BoxHitTest hitTestOverride; final BoxHitTest hitTestOverride;
@override @override
bool hitTest(BoxHitTestResult result, {ui.Offset position}) { bool hitTest(BoxHitTestResult result, {required ui.Offset position}) {
return hitTestOverride(result, position); return hitTestOverride(result, position);
} }
} }
@ -39,7 +37,7 @@ class TestMouseTrackerFlutterBinding extends BindingBase
renderView.child = _TestHitTester(hitTest); renderView.child = _TestHitTester(hitTest);
} }
SchedulerPhase _overridePhase; SchedulerPhase? _overridePhase;
@override @override
SchedulerPhase get schedulerPhase => _overridePhase ?? super.schedulerPhase; SchedulerPhase get schedulerPhase => _overridePhase ?? super.schedulerPhase;
@ -48,7 +46,7 @@ class TestMouseTrackerFlutterBinding extends BindingBase
// In real apps this is done by the renderer binding, but in tests we have to // In real apps this is done by the renderer binding, but in tests we have to
// bypass the phase assertion of [MouseTracker.schedulePostFrameCheck]. // bypass the phase assertion of [MouseTracker.schedulePostFrameCheck].
void scheduleMouseTrackerPostFrameCheck() { void scheduleMouseTrackerPostFrameCheck() {
final SchedulerPhase lastPhase = _overridePhase; final SchedulerPhase? lastPhase = _overridePhase;
_overridePhase = SchedulerPhase.persistentCallbacks; _overridePhase = SchedulerPhase.persistentCallbacks;
addPostFrameCallback((_) { addPostFrameCallback((_) {
mouseTracker.updateAllDevices(renderView.hitTestMouseTrackers); mouseTracker.updateAllDevices(renderView.hitTestMouseTrackers);
@ -77,13 +75,13 @@ class TestAnnotationTarget with Diagnosticable implements MouseTrackerAnnotation
const TestAnnotationTarget({this.onEnter, this.onHover, this.onExit, this.cursor = MouseCursor.defer}); const TestAnnotationTarget({this.onEnter, this.onHover, this.onExit, this.cursor = MouseCursor.defer});
@override @override
final PointerEnterEventListener onEnter; final PointerEnterEventListener? onEnter;
@override @override
final PointerHoverEventListener onHover; final PointerHoverEventListener? onHover;
@override @override
final PointerExitEventListener onExit; final PointerExitEventListener? onExit;
@override @override
final MouseCursor cursor; final MouseCursor cursor;
@ -92,14 +90,14 @@ class TestAnnotationTarget with Diagnosticable implements MouseTrackerAnnotation
void handleEvent(PointerEvent event, HitTestEntry entry) { void handleEvent(PointerEvent event, HitTestEntry entry) {
if (event is PointerHoverEvent) if (event is PointerHoverEvent)
if (onHover != null) if (onHover != null)
onHover(event); onHover!(event);
} }
} }
// A hit test entry that can be assigned with a [TestAnnotationTarget] and an // A hit test entry that can be assigned with a [TestAnnotationTarget] and an
// optional transform matrix. // optional transform matrix.
class TestAnnotationEntry extends HitTestEntry { class TestAnnotationEntry extends HitTestEntry {
TestAnnotationEntry(TestAnnotationTarget target, [Matrix4 transform]) TestAnnotationEntry(TestAnnotationTarget target, [Matrix4? transform])
: transform = transform ?? Matrix4.identity(), super(target); : transform = transform ?? Matrix4.identity(), super(target);
@override @override

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/src/rendering/layer.dart'; import 'package:flutter/src/rendering/layer.dart';
@ -13,7 +11,7 @@ import 'package:flutter/src/rendering/layer.dart';
/// Used by [TestRecordingCanvas] to trace canvas calls. /// Used by [TestRecordingCanvas] to trace canvas calls.
class RecordedInvocation { class RecordedInvocation {
/// Create a record for an invocation list. /// Create a record for an invocation list.
const RecordedInvocation(this.invocation, { this.stack }); const RecordedInvocation(this.invocation, { required this.stack });
/// The method that was called and its arguments. /// The method that was called and its arguments.
/// ///
@ -74,7 +72,7 @@ class TestRecordingCanvas implements Canvas {
} }
@override @override
void saveLayer(Rect bounds, Paint paint) { void saveLayer(Rect? bounds, Paint paint) {
_saveCount += 1; _saveCount += 1;
invocations.add(RecordedInvocation(_MethodCall(#saveLayer, <dynamic>[bounds, paint]), stack: StackTrace.current)); invocations.add(RecordedInvocation(_MethodCall(#saveLayer, <dynamic>[bounds, paint]), stack: StackTrace.current));
} }
@ -106,27 +104,27 @@ class TestRecordingPaintingContext extends ClipContext implements PaintingContex
} }
@override @override
ClipRectLayer pushClipRect( ClipRectLayer? pushClipRect(
bool needsCompositing, bool needsCompositing,
Offset offset, Offset offset,
Rect clipRect, Rect clipRect,
PaintingContextCallback painter, { PaintingContextCallback painter, {
Clip clipBehavior = Clip.hardEdge, Clip clipBehavior = Clip.hardEdge,
ClipRectLayer oldLayer, ClipRectLayer? oldLayer,
}) { }) {
clipRectAndPaint(clipRect.shift(offset), clipBehavior, clipRect.shift(offset), () => painter(this, offset)); clipRectAndPaint(clipRect.shift(offset), clipBehavior, clipRect.shift(offset), () => painter(this, offset));
return null; return null;
} }
@override @override
ClipRRectLayer pushClipRRect( ClipRRectLayer? pushClipRRect(
bool needsCompositing, bool needsCompositing,
Offset offset, Offset offset,
Rect bounds, Rect bounds,
RRect clipRRect, RRect clipRRect,
PaintingContextCallback painter, { PaintingContextCallback painter, {
Clip clipBehavior = Clip.antiAlias, Clip clipBehavior = Clip.antiAlias,
ClipRRectLayer oldLayer, ClipRRectLayer? oldLayer,
}) { }) {
assert(clipBehavior != null); assert(clipBehavior != null);
clipRRectAndPaint(clipRRect.shift(offset), clipBehavior, bounds.shift(offset), () => painter(this, offset)); clipRRectAndPaint(clipRRect.shift(offset), clipBehavior, bounds.shift(offset), () => painter(this, offset));
@ -134,26 +132,26 @@ class TestRecordingPaintingContext extends ClipContext implements PaintingContex
} }
@override @override
ClipPathLayer pushClipPath( ClipPathLayer? pushClipPath(
bool needsCompositing, bool needsCompositing,
Offset offset, Offset offset,
Rect bounds, Rect bounds,
Path clipPath, Path clipPath,
PaintingContextCallback painter, { PaintingContextCallback painter, {
Clip clipBehavior = Clip.antiAlias, Clip clipBehavior = Clip.antiAlias,
ClipPathLayer oldLayer, ClipPathLayer? oldLayer,
}) { }) {
clipPathAndPaint(clipPath.shift(offset), clipBehavior, bounds.shift(offset), () => painter(this, offset)); clipPathAndPaint(clipPath.shift(offset), clipBehavior, bounds.shift(offset), () => painter(this, offset));
return null; return null;
} }
@override @override
TransformLayer pushTransform( TransformLayer? pushTransform(
bool needsCompositing, bool needsCompositing,
Offset offset, Offset offset,
Matrix4 transform, Matrix4 transform,
PaintingContextCallback painter, { PaintingContextCallback painter, {
TransformLayer oldLayer, TransformLayer? oldLayer,
}) { }) {
canvas.save(); canvas.save();
canvas.transform(transform.storage); canvas.transform(transform.storage);
@ -163,17 +161,25 @@ class TestRecordingPaintingContext extends ClipContext implements PaintingContex
} }
@override @override
OpacityLayer pushOpacity(Offset offset, int alpha, PaintingContextCallback painter, OpacityLayer pushOpacity(
{ OpacityLayer oldLayer }) { Offset offset,
canvas.saveLayer(null, null); // TODO(ianh): Expose the alpha somewhere. int alpha,
PaintingContextCallback painter, {
OpacityLayer? oldLayer,
}) {
canvas.saveLayer(null, Paint()); // TODO(ianh): Expose the alpha somewhere.
painter(this, offset); painter(this, offset);
canvas.restore(); canvas.restore();
return null; return OpacityLayer();
} }
@override @override
void pushLayer(Layer childLayer, PaintingContextCallback painter, Offset offset, void pushLayer(
{ Rect childPaintBounds }) { Layer childLayer,
PaintingContextCallback painter,
Offset offset, {
Rect? childPaintBounds,
}) {
painter(this, offset); painter(this, offset);
} }
@ -204,7 +210,7 @@ class _MethodCall implements Invocation {
List<Type> get typeArguments => _typeArguments; List<Type> get typeArguments => _typeArguments;
} }
String _valueName(Object value) { String _valueName(Object? value) {
if (value is double) if (value is double)
return value.toStringAsFixed(1); return value.toStringAsFixed(1);
return value.toString(); return value.toString();
@ -228,7 +234,7 @@ String _describeInvocation(Invocation call) {
buffer.write('('); buffer.write('(');
buffer.writeAll(call.positionalArguments.map<String>(_valueName), ', '); buffer.writeAll(call.positionalArguments.map<String>(_valueName), ', ');
String separator = call.positionalArguments.isEmpty ? '' : ', '; String separator = call.positionalArguments.isEmpty ? '' : ', ';
call.namedArguments.forEach((Symbol name, Object value) { call.namedArguments.forEach((Symbol name, Object? value) {
buffer.write(separator); buffer.write(separator);
buffer.write(_symbolName(name)); buffer.write(_symbolName(name));
buffer.write(': '); buffer.write(': ');

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:async'; import 'dart:async';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -29,7 +27,7 @@ class TestRenderingFlutterBinding extends BindingBase with SchedulerBinding, Ser
TestRenderingFlutterBinding({ this.onErrors }) { TestRenderingFlutterBinding({ this.onErrors }) {
FlutterError.onError = (FlutterErrorDetails details) { FlutterError.onError = (FlutterErrorDetails details) {
FlutterError.dumpErrorToConsole(details); FlutterError.dumpErrorToConsole(details);
Zone.current.parent.handleUncaughtError(details.exception, details.stack); Zone.current.parent!.handleUncaughtError(details.exception as Object, details.stack!);
}; };
} }
@ -40,14 +38,14 @@ class TestRenderingFlutterBinding extends BindingBase with SchedulerBinding, Ser
/// This function is expected to inspect these errors and decide whether they /// This function is expected to inspect these errors and decide whether they
/// are expected or not. Use [takeFlutterErrorDetails] to take one error at a /// are expected or not. Use [takeFlutterErrorDetails] to take one error at a
/// time, or [takeAllFlutterErrorDetails] to iterate over all errors. /// time, or [takeAllFlutterErrorDetails] to iterate over all errors.
VoidCallback onErrors; VoidCallback? onErrors;
/// Returns the error least recently caught by [FlutterError] and removes it /// Returns the error least recently caught by [FlutterError] and removes it
/// from the list of captured errors. /// from the list of captured errors.
/// ///
/// Returns null if no errors were captures, or if the list was exhausted by /// Returns null if no errors were captures, or if the list was exhausted by
/// calling this method repeatedly. /// calling this method repeatedly.
FlutterErrorDetails takeFlutterErrorDetails() { FlutterErrorDetails? takeFlutterErrorDetails() {
if (_errors.isEmpty) { if (_errors.isEmpty) {
return null; return null;
} }
@ -87,7 +85,7 @@ class TestRenderingFlutterBinding extends BindingBase with SchedulerBinding, Ser
@override @override
void drawFrame() { void drawFrame() {
assert(phase != EnginePhase.build, 'rendering_tester does not support testing the build phase; use flutter_test instead'); assert(phase != EnginePhase.build, 'rendering_tester does not support testing the build phase; use flutter_test instead');
final FlutterExceptionHandler oldErrorHandler = FlutterError.onError; final FlutterExceptionHandler? oldErrorHandler = FlutterError.onError;
FlutterError.onError = (FlutterErrorDetails details) { FlutterError.onError = (FlutterErrorDetails details) {
_errors.add(details); _errors.add(details);
}; };
@ -113,7 +111,7 @@ class TestRenderingFlutterBinding extends BindingBase with SchedulerBinding, Ser
FlutterError.onError = oldErrorHandler; FlutterError.onError = oldErrorHandler;
if (_errors.isNotEmpty) { if (_errors.isNotEmpty) {
if (onErrors != null) { if (onErrors != null) {
onErrors(); onErrors!();
if (_errors.isNotEmpty) { if (_errors.isNotEmpty) {
_errors.forEach(FlutterError.dumpErrorToConsole); _errors.forEach(FlutterError.dumpErrorToConsole);
fail('There are more errors than the test inspected using TestRenderingFlutterBinding.takeFlutterErrorDetails.'); fail('There are more errors than the test inspected using TestRenderingFlutterBinding.takeFlutterErrorDetails.');
@ -127,11 +125,9 @@ class TestRenderingFlutterBinding extends BindingBase with SchedulerBinding, Ser
} }
} }
TestRenderingFlutterBinding _renderer; late final TestRenderingFlutterBinding _renderer = TestRenderingFlutterBinding();
TestRenderingFlutterBinding get renderer { TestRenderingFlutterBinding get renderer => _renderer;
_renderer ??= TestRenderingFlutterBinding();
return _renderer;
}
/// Place the box in the render tree, at the given size and with the given /// Place the box in the render tree, at the given size and with the given
/// alignment on the screen. /// alignment on the screen.
@ -149,10 +145,10 @@ TestRenderingFlutterBinding get renderer {
/// If `onErrors` is not null, it is set as [TestRenderingFlutterBinding.onError]. /// If `onErrors` is not null, it is set as [TestRenderingFlutterBinding.onError].
void layout( void layout(
RenderBox box, { RenderBox box, {
BoxConstraints constraints, BoxConstraints? constraints,
Alignment alignment = Alignment.center, Alignment alignment = Alignment.center,
EnginePhase phase = EnginePhase.layout, EnginePhase phase = EnginePhase.layout,
VoidCallback onErrors, VoidCallback? onErrors,
}) { }) {
assert(box != null); // If you want to just repump the last box, call pumpFrame(). assert(box != null); // If you want to just repump the last box, call pumpFrame().
assert(box.parent == null); // We stick the box in another, so you can't reuse it easily, sorry. assert(box.parent == null); // We stick the box in another, so you can't reuse it easily, sorry.
@ -175,7 +171,7 @@ void layout(
/// Pumps a single frame. /// Pumps a single frame.
/// ///
/// If `onErrors` is not null, it is set as [TestRenderingFlutterBinding.onError]. /// If `onErrors` is not null, it is set as [TestRenderingFlutterBinding.onError].
void pumpFrame({ EnginePhase phase = EnginePhase.layout, VoidCallback onErrors }) { void pumpFrame({ EnginePhase phase = EnginePhase.layout, VoidCallback? onErrors }) {
assert(renderer != null); assert(renderer != null);
assert(renderer.renderView != null); assert(renderer.renderView != null);
assert(renderer.renderView.child != null); // call layout() first! assert(renderer.renderView.child != null); // call layout() first!
@ -189,7 +185,7 @@ void pumpFrame({ EnginePhase phase = EnginePhase.layout, VoidCallback onErrors }
} }
class TestCallbackPainter extends CustomPainter { class TestCallbackPainter extends CustomPainter {
const TestCallbackPainter({ this.onPaint }); const TestCallbackPainter({ required this.onPaint });
final VoidCallback onPaint; final VoidCallback onPaint;
@ -251,25 +247,25 @@ class FakeTickerProvider implements TickerProvider {
class FakeTicker implements Ticker { class FakeTicker implements Ticker {
@override @override
bool muted; bool muted = false;
@override @override
void absorbTicker(Ticker originalTicker) { } void absorbTicker(Ticker originalTicker) { }
@override @override
String get debugLabel => null; String? get debugLabel => null;
@override @override
bool get isActive => null; bool get isActive => throw UnimplementedError();
@override @override
bool get isTicking => null; bool get isTicking => throw UnimplementedError();
@override @override
bool get scheduled => null; bool get scheduled => throw UnimplementedError();
@override @override
bool get shouldScheduleTick => null; bool get shouldScheduleTick => throw UnimplementedError();
@override @override
void dispose() { } void dispose() { }
@ -279,7 +275,7 @@ class FakeTicker implements Ticker {
@override @override
TickerFuture start() { TickerFuture start() {
return null; throw UnimplementedError();
} }
@override @override
@ -301,7 +297,14 @@ class TestClipPaintingContext extends PaintingContext {
TestClipPaintingContext() : super(ContainerLayer(), Rect.zero); TestClipPaintingContext() : super(ContainerLayer(), Rect.zero);
@override @override
ClipRectLayer pushClipRect(bool needsCompositing, Offset offset, Rect clipRect, PaintingContextCallback painter, {Clip clipBehavior = Clip.hardEdge, ClipRectLayer oldLayer}) { ClipRectLayer? pushClipRect(
bool needsCompositing,
Offset offset,
Rect clipRect,
PaintingContextCallback painter, {
Clip clipBehavior = Clip.hardEdge,
ClipRectLayer? oldLayer,
}) {
this.clipBehavior = clipBehavior; this.clipBehavior = clipBehavior;
return null; return null;
} }
@ -310,7 +313,7 @@ class TestClipPaintingContext extends PaintingContext {
} }
void expectOverflowedErrors() { void expectOverflowedErrors() {
final FlutterErrorDetails errorDetails = renderer.takeFlutterErrorDetails(); final FlutterErrorDetails errorDetails = renderer.takeFlutterErrorDetails()!;
final bool overflowed = errorDetails.toString().contains('overflowed'); final bool overflowed = errorDetails.toString().contains('overflowed');
if (!overflowed) { if (!overflowed) {
FlutterError.reportError(errorDetails); FlutterError.reportError(errorDetails);

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -53,15 +51,15 @@ class MockRestorationManager extends TestRestorationManager {
int rootBucketAccessed = 0; int rootBucketAccessed = 0;
@override @override
Future<RestorationBucket> get rootBucket { Future<RestorationBucket?> get rootBucket {
rootBucketAccessed++; rootBucketAccessed++;
return _rootBucket; return _rootBucket;
} }
Future<RestorationBucket> _rootBucket; late Future<RestorationBucket?> _rootBucket;
set rootBucket(Future<RestorationBucket> value) { set rootBucket(Future<RestorationBucket?> value) {
_rootBucket = value; _rootBucket = value;
_isRestoring = true; _isRestoring = true;
ServicesBinding.instance.addPostFrameCallback((Duration _) { ServicesBinding.instance!.addPostFrameCallback((Duration _) {
_isRestoring = false; _isRestoring = false;
}); });
notifyListeners(); notifyListeners();
@ -69,7 +67,7 @@ class MockRestorationManager extends TestRestorationManager {
@override @override
bool get isReplacing => _isRestoring; bool get isReplacing => _isRestoring;
bool _isRestoring; bool _isRestoring = false;
@override @override
Future<void> sendToEngine(Uint8List encodedData) { Future<void> sendToEngine(Uint8List encodedData) {

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -13,7 +11,7 @@ RenderEditable findRenderEditable(WidgetTester tester) {
final RenderObject root = tester.renderObject(find.byType(EditableText)); final RenderObject root = tester.renderObject(find.byType(EditableText));
expect(root, isNotNull); expect(root, isNotNull);
RenderEditable renderEditable; late RenderEditable renderEditable;
void recursiveFinder(RenderObject child) { void recursiveFinder(RenderObject child) {
if (child is RenderEditable) { if (child is RenderEditable) {
renderEditable = child; renderEditable = child;

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';

View File

@ -2,49 +2,47 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
typedef OnObservation = void Function(Route<dynamic> route, Route<dynamic> previousRoute); typedef OnObservation = void Function(Route<dynamic>? route, Route<dynamic>? previousRoute);
/// A trivial observer for testing the navigator. /// A trivial observer for testing the navigator.
class TestObserver extends NavigatorObserver { class TestObserver extends NavigatorObserver {
OnObservation onPushed; OnObservation? onPushed;
OnObservation onPopped; OnObservation? onPopped;
OnObservation onRemoved; OnObservation? onRemoved;
OnObservation onReplaced; OnObservation? onReplaced;
OnObservation onStartUserGesture; OnObservation? onStartUserGesture;
@override @override
void didPush(Route<dynamic> route, Route<dynamic> previousRoute) { void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
if (onPushed != null) { if (onPushed != null) {
onPushed(route, previousRoute); onPushed!(route, previousRoute);
} }
} }
@override @override
void didPop(Route<dynamic> route, Route<dynamic> previousRoute) { void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
if (onPopped != null) { if (onPopped != null) {
onPopped(route, previousRoute); onPopped!(route, previousRoute);
} }
} }
@override @override
void didRemove(Route<dynamic> route, Route<dynamic> previousRoute) { void didRemove(Route<dynamic> route, Route<dynamic>? previousRoute) {
if (onRemoved != null) if (onRemoved != null)
onRemoved(route, previousRoute); onRemoved!(route, previousRoute);
} }
@override @override
void didReplace({ Route<dynamic> oldRoute, Route<dynamic> newRoute }) { void didReplace({ Route<dynamic>? oldRoute, Route<dynamic>? newRoute }) {
if (onReplaced != null) if (onReplaced != null)
onReplaced(newRoute, oldRoute); onReplaced!(newRoute, oldRoute);
} }
@override @override
void didStartUserGesture(Route<dynamic> route, Route<dynamic> previousRoute) { void didStartUserGesture(Route<dynamic> route, Route<dynamic>? previousRoute) {
if (onStartUserGesture != null) if (onStartUserGesture != null)
onStartUserGesture(route, previousRoute); onStartUserGesture!(route, previousRoute);
} }
} }

View File

@ -2,24 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
export '../services/restoration.dart'; export '../services/restoration.dart';
class BucketSpy extends StatefulWidget { class BucketSpy extends StatefulWidget {
const BucketSpy({Key key, this.child}) : super(key: key); const BucketSpy({Key? key, this.child}) : super(key: key);
final Widget child; final Widget? child;
@override @override
State<BucketSpy> createState() => BucketSpyState(); State<BucketSpy> createState() => BucketSpyState();
} }
class BucketSpyState extends State<BucketSpy> { class BucketSpyState extends State<BucketSpy> {
RestorationBucket bucket; RestorationBucket? bucket;
@override @override
void didChangeDependencies() { void didChangeDependencies() {

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:ui' show SemanticsFlag; import 'dart:ui' show SemanticsFlag;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -54,7 +52,7 @@ class TestSemantics {
this.children = const <TestSemantics>[], this.children = const <TestSemantics>[],
this.scrollIndex, this.scrollIndex,
this.scrollChildren, this.scrollChildren,
Iterable<SemanticsTag> tags, Iterable<SemanticsTag>? tags,
}) : assert(flags is int || flags is List<SemanticsFlag>), }) : assert(flags is int || flags is List<SemanticsFlag>),
assert(actions is int || actions is List<SemanticsAction>), assert(actions is int || actions is List<SemanticsAction>),
assert(label != null), assert(label != null),
@ -81,7 +79,7 @@ class TestSemantics {
this.children = const <TestSemantics>[], this.children = const <TestSemantics>[],
this.scrollIndex, this.scrollIndex,
this.scrollChildren, this.scrollChildren,
Iterable<SemanticsTag> tags, Iterable<SemanticsTag>? tags,
}) : id = 0, }) : id = 0,
assert(flags is int || flags is List<SemanticsFlag>), assert(flags is int || flags is List<SemanticsFlag>),
assert(actions is int || actions is List<SemanticsAction>), assert(actions is int || actions is List<SemanticsAction>),
@ -116,14 +114,14 @@ class TestSemantics {
this.decreasedValue = '', this.decreasedValue = '',
this.textDirection, this.textDirection,
this.rect, this.rect,
Matrix4 transform, Matrix4? transform,
this.elevation, this.elevation,
this.thickness, this.thickness,
this.textSelection, this.textSelection,
this.children = const <TestSemantics>[], this.children = const <TestSemantics>[],
this.scrollIndex, this.scrollIndex,
this.scrollChildren, this.scrollChildren,
Iterable<SemanticsTag> tags, Iterable<SemanticsTag>? tags,
}) : assert(flags is int || flags is List<SemanticsFlag>), }) : assert(flags is int || flags is List<SemanticsFlag>),
assert(actions is int || actions is List<SemanticsAction>), assert(actions is int || actions is List<SemanticsAction>),
assert(label != null), assert(label != null),
@ -139,7 +137,7 @@ class TestSemantics {
/// ///
/// The root node has an id of zero. Other nodes are given a unique id when /// The root node has an id of zero. Other nodes are given a unique id when
/// they are created. /// they are created.
final int id; final int? id;
/// The [SemanticsFlag]s set on this node. /// The [SemanticsFlag]s set on this node.
/// ///
@ -183,7 +181,7 @@ class TestSemantics {
/// Even if this is not set, the [hasSemantics] matcher will verify that if a /// Even if this is not set, the [hasSemantics] matcher will verify that if a
/// label is present on the [SemanticsNode], a [SemanticsNode.textDirection] /// label is present on the [SemanticsNode], a [SemanticsNode.textDirection]
/// is also set. /// is also set.
final TextDirection textDirection; final TextDirection? textDirection;
/// The bounding box for this node in its coordinate system. /// The bounding box for this node in its coordinate system.
/// ///
@ -194,7 +192,7 @@ class TestSemantics {
/// ///
/// * [TestSemantics.fullScreen] 800x600, the test screen's size in logical /// * [TestSemantics.fullScreen] 800x600, the test screen's size in logical
/// pixels, useful for other full-screen widgets. /// pixels, useful for other full-screen widgets.
final Rect rect; final Rect? rect;
/// The test screen's size in physical pixels, typically used as the [rect] /// The test screen's size in physical pixels, typically used as the [rect]
/// for the node with id zero. /// for the node with id zero.
@ -214,7 +212,7 @@ class TestSemantics {
/// By default, the transform is null, which represents the identity /// By default, the transform is null, which represents the identity
/// transformation (i.e., that this node has the same coordinate system as its /// transformation (i.e., that this node has the same coordinate system as its
/// parent). /// parent).
final Matrix4 transform; final Matrix4? transform;
/// The elevation of this node relative to the parent node. /// The elevation of this node relative to the parent node.
/// ///
@ -222,24 +220,24 @@ class TestSemantics {
/// ///
/// * [SemanticsConfiguration.elevation] for a detailed discussion regarding /// * [SemanticsConfiguration.elevation] for a detailed discussion regarding
/// elevation and semantics. /// elevation and semantics.
final double elevation; final double? elevation;
/// The extend that this node occupies in z-direction starting at [elevation]. /// The extend that this node occupies in z-direction starting at [elevation].
/// ///
/// See also: /// See also:
/// ///
/// * [SemanticsConfiguration.thickness] for a more detailed definition. /// * [SemanticsConfiguration.thickness] for a more detailed definition.
final double thickness; final double? thickness;
/// The index of the first visible semantic node within a scrollable. /// The index of the first visible semantic node within a scrollable.
final int scrollIndex; final int? scrollIndex;
/// The total number of semantic nodes within a scrollable. /// The total number of semantic nodes within a scrollable.
final int scrollChildren; final int? scrollChildren;
final TextSelection textSelection; final TextSelection? textSelection;
static Matrix4 _applyRootChildScale(Matrix4 transform) { static Matrix4 _applyRootChildScale(Matrix4? transform) {
final Matrix4 result = Matrix4.diagonal3Values(3.0, 3.0, 1.0); final Matrix4 result = Matrix4.diagonal3Values(3.0, 3.0, 1.0);
if (transform != null) if (transform != null)
result.multiply(transform); result.multiply(transform);
@ -253,7 +251,7 @@ class TestSemantics {
final Set<SemanticsTag> tags; final Set<SemanticsTag> tags;
bool _matches( bool _matches(
SemanticsNode node, SemanticsNode? node,
Map<dynamic, dynamic> matchState, { Map<dynamic, dynamic> matchState, {
bool ignoreRect = false, bool ignoreRect = false,
bool ignoreTransform = false, bool ignoreTransform = false,
@ -370,7 +368,7 @@ class TestSemantics {
if (textDirection != null) if (textDirection != null)
buf.writeln('$indent textDirection: $textDirection,'); buf.writeln('$indent textDirection: $textDirection,');
if (textSelection?.isValid == true) if (textSelection?.isValid == true)
buf.writeln('$indent textSelection:\n[${textSelection.start}, ${textSelection.end}],'); buf.writeln('$indent textSelection:\n[${textSelection!.start}, ${textSelection!.end}],');
if (scrollIndex != null) if (scrollIndex != null)
buf.writeln('$indent scrollIndex: $scrollIndex,'); buf.writeln('$indent scrollIndex: $scrollIndex,');
if (rect != null) if (rect != null)
@ -413,7 +411,7 @@ class SemanticsTester {
/// The widget tester that this object is testing the semantics of. /// The widget tester that this object is testing the semantics of.
final WidgetTester tester; final WidgetTester tester;
SemanticsHandle _semanticsHandle; SemanticsHandle? _semanticsHandle;
/// Release resources held by this semantics tester. /// Release resources held by this semantics tester.
/// ///
@ -437,18 +435,18 @@ class SemanticsTester {
/// ///
/// If `ancestor` is not null, only the descendants of it are returned. /// If `ancestor` is not null, only the descendants of it are returned.
Iterable<SemanticsNode> nodesWith({ Iterable<SemanticsNode> nodesWith({
String label, String? label,
String value, String? value,
String hint, String? hint,
TextDirection textDirection, TextDirection? textDirection,
List<SemanticsAction> actions, List<SemanticsAction>? actions,
List<SemanticsFlag> flags, List<SemanticsFlag>? flags,
double scrollPosition, double? scrollPosition,
double scrollExtentMax, double? scrollExtentMax,
double scrollExtentMin, double? scrollExtentMin,
int currentValueLength, int? currentValueLength,
int maxValueLength, int? maxValueLength,
SemanticsNode ancestor, SemanticsNode? ancestor,
}) { }) {
bool checkNode(SemanticsNode node) { bool checkNode(SemanticsNode node) {
if (label != null && node.label != label) if (label != null && node.label != label)
@ -497,7 +495,7 @@ class SemanticsTester {
if (ancestor != null) { if (ancestor != null) {
visit(ancestor); visit(ancestor);
} else { } else {
visit(tester.binding.pipelineOwner.semanticsOwner.rootSemanticsNode); visit(tester.binding.pipelineOwner.semanticsOwner!.rootSemanticsNode!);
} }
return result; return result;
} }
@ -551,7 +549,7 @@ class SemanticsTester {
/// over-test. Prefer breaking your widgets into smaller widgets and test them /// over-test. Prefer breaking your widgets into smaller widgets and test them
/// individually. /// individually.
String generateTestSemanticsExpressionForCurrentSemanticsTree(DebugSemanticsDumpOrder childOrder) { String generateTestSemanticsExpressionForCurrentSemanticsTree(DebugSemanticsDumpOrder childOrder) {
final SemanticsNode node = tester.binding.pipelineOwner.semanticsOwner?.rootSemanticsNode; final SemanticsNode? node = tester.binding.pipelineOwner.semanticsOwner?.rootSemanticsNode;
return _generateSemanticsTestForNode(node, 0, childOrder); return _generateSemanticsTestForNode(node, 0, childOrder);
} }
@ -583,7 +581,7 @@ class SemanticsTester {
/// Recursively generates [TestSemantics] code for [node] and its children, /// Recursively generates [TestSemantics] code for [node] and its children,
/// indenting the expression by `indentAmount`. /// indenting the expression by `indentAmount`.
static String _generateSemanticsTestForNode(SemanticsNode node, int indentAmount, DebugSemanticsDumpOrder childOrder) { static String _generateSemanticsTestForNode(SemanticsNode? node, int indentAmount, DebugSemanticsDumpOrder childOrder) {
if (node == null) if (node == null)
return 'null'; return 'null';
final String indent = ' ' * indentAmount; final String indent = ' ' * indentAmount;
@ -594,7 +592,7 @@ class SemanticsTester {
if (!isRoot) if (!isRoot)
buf.writeln(' id: ${node.id},'); buf.writeln(' id: ${node.id},');
if (nodeData.tags != null) if (nodeData.tags != null)
buf.writeln(' tags: ${_tagsToSemanticsTagExpression(nodeData.tags)},'); buf.writeln(' tags: ${_tagsToSemanticsTagExpression(nodeData.tags!)},');
if (nodeData.flags != 0) if (nodeData.flags != 0)
buf.writeln(' flags: ${_flagsToSemanticsFlagExpression(nodeData.flags)},'); buf.writeln(' flags: ${_flagsToSemanticsFlagExpression(nodeData.flags)},');
if (nodeData.actions != 0) if (nodeData.actions != 0)
@ -635,10 +633,10 @@ class SemanticsTester {
class _HasSemantics extends Matcher { class _HasSemantics extends Matcher {
const _HasSemantics( const _HasSemantics(
this._semantics, { this._semantics, {
@required this.ignoreRect, required this.ignoreRect,
@required this.ignoreTransform, required this.ignoreTransform,
@required this.ignoreId, required this.ignoreId,
@required this.childOrder, required this.childOrder,
}) : assert(_semantics != null), }) : assert(_semantics != null),
assert(ignoreRect != null), assert(ignoreRect != null),
assert(ignoreId != null), assert(ignoreId != null),
@ -675,7 +673,7 @@ class _HasSemantics extends Matcher {
return description.add('semantics node matching:\n$_semantics'); return description.add('semantics node matching:\n$_semantics');
} }
String _indent(String text) { String _indent(String? text) {
return text.toString().trimRight().split('\n').map<String>((String line) => ' $line').join('\n'); return text.toString().trimRight().split('\n').map<String>((String line) => ' $line').join('\n');
} }
@ -684,7 +682,7 @@ class _HasSemantics extends Matcher {
Description result = mismatchDescription Description result = mismatchDescription
.add('${matchState[TestSemantics]}\n') .add('${matchState[TestSemantics]}\n')
.add('Current SemanticsNode tree:\n') .add('Current SemanticsNode tree:\n')
.add(_indent(RendererBinding.instance?.renderView?.debugSemantics?.toStringDeep(childOrder: childOrder))) .add(_indent(RendererBinding.instance?.renderView.debugSemantics?.toStringDeep(childOrder: childOrder)))
.add('\n') .add('\n')
.add('The semantics tree would have matched the following configuration:\n') .add('The semantics tree would have matched the following configuration:\n')
.add(_indent(matchState['would-match'] as String)); .add(_indent(matchState['would-match'] as String));
@ -739,17 +737,17 @@ class _IncludesNodeWith extends Matcher {
currentValueLength != null currentValueLength != null
); );
final String label; final String? label;
final String value; final String? value;
final String hint; final String? hint;
final TextDirection textDirection; final TextDirection? textDirection;
final List<SemanticsAction> actions; final List<SemanticsAction>? actions;
final List<SemanticsFlag> flags; final List<SemanticsFlag>? flags;
final double scrollPosition; final double? scrollPosition;
final double scrollExtentMax; final double? scrollExtentMax;
final double scrollExtentMin; final double? scrollExtentMin;
final int currentValueLength; final int? currentValueLength;
final int maxValueLength; final int? maxValueLength;
@override @override
bool matches(covariant SemanticsTester item, Map<dynamic, dynamic> matchState) { bool matches(covariant SemanticsTester item, Map<dynamic, dynamic> matchState) {
@ -783,9 +781,9 @@ class _IncludesNodeWith extends Matcher {
if (label != null) 'label "$label"', if (label != null) 'label "$label"',
if (value != null) 'value "$value"', if (value != null) 'value "$value"',
if (hint != null) 'hint "$hint"', if (hint != null) 'hint "$hint"',
if (textDirection != null) ' (${describeEnum(textDirection)})', if (textDirection != null) ' (${describeEnum(textDirection!)})',
if (actions != null) 'actions "${actions.join(', ')}"', if (actions != null) 'actions "${actions!.join(', ')}"',
if (flags != null) 'flags "${flags.join(', ')}"', if (flags != null) 'flags "${flags!.join(', ')}"',
if (scrollPosition != null) 'scrollPosition "$scrollPosition"', if (scrollPosition != null) 'scrollPosition "$scrollPosition"',
if (scrollExtentMax != null) 'scrollExtentMax "$scrollExtentMax"', if (scrollExtentMax != null) 'scrollExtentMax "$scrollExtentMax"',
if (scrollExtentMin != null) 'scrollExtentMin "$scrollExtentMin"', if (scrollExtentMin != null) 'scrollExtentMin "$scrollExtentMin"',
@ -801,17 +799,17 @@ class _IncludesNodeWith extends Matcher {
/// ///
/// If null is provided for an argument, it will match against any value. /// If null is provided for an argument, it will match against any value.
Matcher includesNodeWith({ Matcher includesNodeWith({
String label, String? label,
String value, String? value,
String hint, String? hint,
TextDirection textDirection, TextDirection? textDirection,
List<SemanticsAction> actions, List<SemanticsAction>? actions,
List<SemanticsFlag> flags, List<SemanticsFlag>? flags,
double scrollPosition, double? scrollPosition,
double scrollExtentMax, double? scrollExtentMax,
double scrollExtentMin, double? scrollExtentMin,
int maxValueLength, int? maxValueLength,
int currentValueLength, int? currentValueLength,
}) { }) {
return _IncludesNodeWith( return _IncludesNodeWith(
label: label, label: label,

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
const List<String> kStates = <String>[ const List<String> kStates = <String>[
'Alabama', 'Alabama',
'Alaska', 'Alaska',

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
typedef Logger = void Function(String caller); typedef Logger = void Function(String caller);
@ -20,19 +18,19 @@ class TestBorder extends ShapeBorder {
ShapeBorder scale(double t) => TestBorder(onLog); ShapeBorder scale(double t) => TestBorder(onLog);
@override @override
Path getInnerPath(Rect rect, { TextDirection textDirection }) { Path getInnerPath(Rect rect, { TextDirection? textDirection }) {
onLog('getInnerPath $rect $textDirection'); onLog('getInnerPath $rect $textDirection');
return Path(); return Path();
} }
@override @override
Path getOuterPath(Rect rect, { TextDirection textDirection }) { Path getOuterPath(Rect rect, { TextDirection? textDirection }) {
onLog('getOuterPath $rect $textDirection'); onLog('getOuterPath $rect $textDirection');
return Path(); return Path();
} }
@override @override
void paint(Canvas canvas, Rect rect, { TextDirection textDirection }) { void paint(Canvas canvas, Rect rect, { TextDirection? textDirection }) {
onLog('paint $rect $textDirection'); onLog('paint $rect $textDirection');
} }
} }

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
@ -21,7 +19,7 @@ const BoxDecoration kBoxDecorationC = BoxDecoration(
); );
class TestBuildCounter extends StatelessWidget { class TestBuildCounter extends StatelessWidget {
const TestBuildCounter({ Key key }) : super(key: key); const TestBuildCounter({ Key? key }) : super(key: key);
static int buildCount = 0; static int buildCount = 0;
@ -34,7 +32,7 @@ class TestBuildCounter extends StatelessWidget {
class FlipWidget extends StatefulWidget { class FlipWidget extends StatefulWidget {
const FlipWidget({ Key key, this.left, this.right }) : super(key: key); const FlipWidget({ Key? key, required this.left, required this.right }) : super(key: key);
final Widget left; final Widget left;
final Widget right; final Widget right;

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
@ -14,7 +12,7 @@ RenderEditable findRenderEditable(WidgetTester tester) {
final RenderObject root = tester.renderObject(find.byType(EditableText)); final RenderObject root = tester.renderObject(find.byType(EditableText));
expect(root, isNotNull); expect(root, isNotNull);
RenderEditable renderEditable; late RenderEditable renderEditable;
void recursiveFinder(RenderObject child) { void recursiveFinder(RenderObject child) {
if (child is RenderEditable) { if (child is RenderEditable) {
renderEditable = child; renderEditable = child;

View File

@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
@ -12,48 +10,46 @@ import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
typedef InspectorServiceExtensionCallback = FutureOr<Map<String, Object>> Function(Map<String, String> parameters);
class TestWidgetInspectorService extends Object with WidgetInspectorService { class TestWidgetInspectorService extends Object with WidgetInspectorService {
final Map<String, InspectorServiceExtensionCallback> extensions = <String, InspectorServiceExtensionCallback>{}; final Map<String, ServiceExtensionCallback> extensions = <String, ServiceExtensionCallback>{};
final Map<String, List<Map<Object, Object>>> eventsDispatched = <String, List<Map<Object, Object>>>{}; final Map<String, List<Map<Object, Object?>>> eventsDispatched = <String, List<Map<Object, Object?>>>{};
@override @override
void registerServiceExtension({ void registerServiceExtension({
@required String name, required String name,
@required FutureOr<Map<String, Object>> callback(Map<String, String> parameters), required ServiceExtensionCallback callback,
}) { }) {
assert(!extensions.containsKey(name)); assert(!extensions.containsKey(name));
extensions[name] = callback; extensions[name] = callback;
} }
@override @override
void postEvent(String eventKind, Map<Object, Object> eventData) { void postEvent(String eventKind, Map<Object, Object?> eventData) {
getEventsDispatched(eventKind).add(eventData); getEventsDispatched(eventKind).add(eventData);
} }
List<Map<Object, Object>> getEventsDispatched(String eventKind) { List<Map<Object, Object?>> getEventsDispatched(String eventKind) {
return eventsDispatched.putIfAbsent(eventKind, () => <Map<Object, Object>>[]); return eventsDispatched.putIfAbsent(eventKind, () => <Map<Object, Object>>[]);
} }
Iterable<Map<Object, Object>> getServiceExtensionStateChangedEvents(String extensionName) { Iterable<Map<Object, Object?>> getServiceExtensionStateChangedEvents(String extensionName) {
return getEventsDispatched('Flutter.ServiceExtensionStateChanged') return getEventsDispatched('Flutter.ServiceExtensionStateChanged')
.where((Map<Object, Object> event) => event['extension'] == extensionName); .where((Map<Object, Object?> event) => event['extension'] == extensionName);
} }
Future<Object> testExtension(String name, Map<String, String> arguments) async { Future<Object?> testExtension(String name, Map<String, String> arguments) async {
expect(extensions, contains(name)); expect(extensions, contains(name));
// Encode and decode to JSON to match behavior using a real service // Encode and decode to JSON to match behavior using a real service
// extension where only JSON is allowed. // extension where only JSON is allowed.
return json.decode(json.encode(await extensions[name](arguments)))['result']; return json.decode(json.encode(await extensions[name]!(arguments)))['result'];
} }
Future<String> testBoolExtension(String name, Map<String, String> arguments) async { Future<String> testBoolExtension(String name, Map<String, String> arguments) async {
expect(extensions, contains(name)); expect(extensions, contains(name));
// Encode and decode to JSON to match behavior using a real service // Encode and decode to JSON to match behavior using a real service
// extension where only JSON is allowed. // extension where only JSON is allowed.
return json.decode(json.encode(await extensions[name](arguments)))['enabled'] as String; return json.decode(json.encode(await extensions[name]!(arguments)))['enabled'] as String;
} }
int rebuildCount = 0; int rebuildCount = 0;
@ -61,10 +57,10 @@ class TestWidgetInspectorService extends Object with WidgetInspectorService {
@override @override
Future<void> forceRebuild() async { Future<void> forceRebuild() async {
rebuildCount++; rebuildCount++;
final WidgetsBinding binding = WidgetsBinding.instance; final WidgetsBinding binding = WidgetsBinding.instance!;
if (binding.renderViewElement != null) { if (binding.renderViewElement != null) {
binding.buildOwner.reassemble(binding.renderViewElement); binding.buildOwner!.reassemble(binding.renderViewElement!);
} }
} }
} }