Unverified Commit 19e07d2b authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

Migrate flutter_test (#66663)

parent 0ca0c132
...@@ -620,7 +620,7 @@ Future<void> _runFrameworkTests() async { ...@@ -620,7 +620,7 @@ Future<void> _runFrameworkTests() async {
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_driver'), tableData: bigqueryApi?.tabledata, tests: <String>[path.join('test', 'src', 'real_tests')]); await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_driver'), tableData: bigqueryApi?.tabledata, tests: <String>[path.join('test', 'src', 'real_tests')]);
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_goldens'), tableData: bigqueryApi?.tabledata); await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_goldens'), tableData: bigqueryApi?.tabledata);
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_localizations'), tableData: bigqueryApi?.tabledata); await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_localizations'), tableData: bigqueryApi?.tabledata);
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_test'), tableData: bigqueryApi?.tabledata); await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_test'), tableData: bigqueryApi?.tabledata, options: nullSafetyOptions);
await _runFlutterTest(path.join(flutterRoot, 'packages', 'fuchsia_remote_debug_protocol'), tableData: bigqueryApi?.tabledata); await _runFlutterTest(path.join(flutterRoot, 'packages', 'fuchsia_remote_debug_protocol'), tableData: bigqueryApi?.tabledata);
await _runFlutterTest(path.join(flutterRoot, 'dev', 'integration_tests', 'non_nullable'), options: nullSafetyOptions); await _runFlutterTest(path.join(flutterRoot, 'dev', 'integration_tests', 'non_nullable'), options: nullSafetyOptions);
await _runFlutterTest( await _runFlutterTest(
......
...@@ -3216,8 +3216,8 @@ void main() { ...@@ -3216,8 +3216,8 @@ void main() {
), ),
); );
tester.binding.window.physicalSizeTestValue = null; tester.binding.window.clearPhysicalSizeTestValue();
tester.binding.window.devicePixelRatioTestValue = null; tester.binding.window.clearDevicePixelRatioTestValue();
}); });
testWidgets('selecting multiple words works', (WidgetTester tester) async { testWidgets('selecting multiple words works', (WidgetTester tester) async {
...@@ -3287,8 +3287,8 @@ void main() { ...@@ -3287,8 +3287,8 @@ void main() {
), ),
); );
tester.binding.window.physicalSizeTestValue = null; tester.binding.window.clearPhysicalSizeTestValue();
tester.binding.window.devicePixelRatioTestValue = null; tester.binding.window.clearDevicePixelRatioTestValue();
}); });
testWidgets('selecting multiline works', (WidgetTester tester) async { testWidgets('selecting multiline works', (WidgetTester tester) async {
...@@ -3362,8 +3362,8 @@ void main() { ...@@ -3362,8 +3362,8 @@ void main() {
), ),
); );
tester.binding.window.physicalSizeTestValue = null; tester.binding.window.clearPhysicalSizeTestValue();
tester.binding.window.devicePixelRatioTestValue = null; tester.binding.window.clearDevicePixelRatioTestValue();
}); });
// This is a regression test for // This is a regression test for
......
...@@ -778,7 +778,7 @@ void main() { ...@@ -778,7 +778,7 @@ void main() {
); );
expect(appliedTheme.primaryColor, Colors.blue); expect(appliedTheme.primaryColor, Colors.blue);
tester.binding.window.accessibilityFeaturesTestValue = null; tester.binding.window.clearAccessibilityFeaturesTestValue();
}); });
testWidgets('MaterialApp uses high contrast dark theme when appropriate', (WidgetTester tester) async { testWidgets('MaterialApp uses high contrast dark theme when appropriate', (WidgetTester tester) async {
...@@ -811,7 +811,7 @@ void main() { ...@@ -811,7 +811,7 @@ void main() {
); );
expect(appliedTheme.primaryColor, Colors.green); expect(appliedTheme.primaryColor, Colors.green);
tester.binding.window.accessibilityFeaturesTestValue = null; tester.binding.window.clearAccessibilityFeaturesTestValue();
}); });
testWidgets('MaterialApp uses dark theme when no high contrast dark theme is provided', (WidgetTester tester) async { testWidgets('MaterialApp uses dark theme when no high contrast dark theme is provided', (WidgetTester tester) async {
...@@ -838,8 +838,8 @@ void main() { ...@@ -838,8 +838,8 @@ void main() {
); );
expect(appliedTheme.primaryColor, Colors.lightGreen); expect(appliedTheme.primaryColor, Colors.lightGreen);
tester.binding.window.accessibilityFeaturesTestValue = null; tester.binding.window.clearAccessibilityFeaturesTestValue();
tester.binding.window.platformBrightnessTestValue = null; tester.binding.window.clearPlatformBrightnessTestValue();
}); });
testWidgets('MaterialApp switches themes when the Window platformBrightness changes.', (WidgetTester tester) async { testWidgets('MaterialApp switches themes when the Window platformBrightness changes.', (WidgetTester tester) async {
......
...@@ -486,8 +486,8 @@ void _tests() { ...@@ -486,8 +486,8 @@ void _tests() {
expect(minuteSize.width, greaterThanOrEqualTo(48.0)); expect(minuteSize.width, greaterThanOrEqualTo(48.0));
expect(minuteSize.height, greaterThanOrEqualTo(48.0)); expect(minuteSize.height, greaterThanOrEqualTo(48.0));
tester.binding.window.physicalSizeTestValue = null; tester.binding.window.clearPhysicalSizeTestValue();
tester.binding.window.devicePixelRatioTestValue = null; tester.binding.window.clearDevicePixelRatioTestValue();
}); });
testWidgets('builder parameter', (WidgetTester tester) async { testWidgets('builder parameter', (WidgetTester tester) async {
......
# Use the parent analysis options settings and enable null-experiment.
include: ../analysis_options.yaml
analyzer:
enable-experiment:
- non-nullable
errors:
always_require_non_null_named_parameters: false # not needed with nnbd
unrelated_type_equality_checks: false # https://github.com/dart-lang/linter/issues/2196
void_checks: false # https://github.com/dart-lang/linter/issues/2185
unnecessary_null_comparison: false # https://github.com/dart-lang/language/issues/1018
...@@ -7,12 +7,12 @@ import 'package:flutter/widgets.dart'; ...@@ -7,12 +7,12 @@ import 'package:flutter/widgets.dart';
import 'binding.dart'; import 'binding.dart';
/// Ensure the [WidgetsBinding] is initialized. /// Ensure the [WidgetsBinding] is initialized.
WidgetsBinding ensureInitialized([@visibleForTesting Map<String, String> environment]) { WidgetsBinding ensureInitialized([@visibleForTesting Map<String, String>? environment]) {
if (WidgetsBinding.instance == null) { if (WidgetsBinding.instance == null) {
AutomatedTestWidgetsFlutterBinding(); AutomatedTestWidgetsFlutterBinding();
} }
assert(WidgetsBinding.instance is TestWidgetsFlutterBinding); assert(WidgetsBinding.instance is TestWidgetsFlutterBinding);
return WidgetsBinding.instance; return WidgetsBinding.instance!;
} }
/// This method is a noop on the web. /// This method is a noop on the web.
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +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.10
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'dart:math' as math; import 'dart:math' as math;
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +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.10
import 'dart:convert'; import 'dart:convert';
import 'dart:html' as html; import 'dart:html' as html;
import 'dart:typed_data'; import 'dart:typed_data';
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
import 'dart:typed_data'; import 'dart:typed_data';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:test_api/src/frontend/async_matcher.dart'; // ignore: implementation_imports import 'package:test_api/src/frontend/async_matcher.dart'; // ignore: implementation_imports
...@@ -22,7 +22,8 @@ import 'goldens.dart'; ...@@ -22,7 +22,8 @@ import 'goldens.dart';
/// ///
/// * [OffsetLayer.toImage] which is the actual method being called. /// * [OffsetLayer.toImage] which is the actual method being called.
Future<ui.Image> captureImage(Element element) { Future<ui.Image> captureImage(Element element) {
RenderObject renderObject = element.renderObject; assert(element.renderObject != null);
RenderObject renderObject = element.renderObject!;
while (!renderObject.isRepaintBoundary) { while (!renderObject.isRepaintBoundary) {
renderObject = renderObject.parent as RenderObject; renderObject = renderObject.parent as RenderObject;
assert(renderObject != null); assert(renderObject != null);
...@@ -45,10 +46,10 @@ class MatchesGoldenFile extends AsyncMatcher { ...@@ -45,10 +46,10 @@ class MatchesGoldenFile extends AsyncMatcher {
final Uri key; final Uri key;
/// The [version] of the golden image. /// The [version] of the golden image.
final int version; final int? version;
@override @override
Future<String> matchAsync(dynamic item) async { Future<String?> matchAsync(dynamic item) async {
Future<ui.Image> imageFuture; Future<ui.Image> imageFuture;
if (item is Future<ui.Image>) { if (item is Future<ui.Image>) {
imageFuture = item; imageFuture = item;
...@@ -68,9 +69,9 @@ class MatchesGoldenFile extends AsyncMatcher { ...@@ -68,9 +69,9 @@ class MatchesGoldenFile extends AsyncMatcher {
final Uri testNameUri = goldenFileComparator.getTestUri(key, version); final Uri testNameUri = goldenFileComparator.getTestUri(key, version);
final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized() as TestWidgetsFlutterBinding; final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized() as TestWidgetsFlutterBinding;
return binding.runAsync<String>(() async { return binding.runAsync<String?>(() async {
final ui.Image image = await imageFuture; final ui.Image image = await imageFuture;
final ByteData bytes = await image.toByteData(format: ui.ImageByteFormat.png); final ByteData? bytes = await image.toByteData(format: ui.ImageByteFormat.png);
if (bytes == null) if (bytes == null)
return 'could not encode screenshot.'; return 'could not encode screenshot.';
if (autoUpdateGoldenFiles) { if (autoUpdateGoldenFiles) {
......
...@@ -32,15 +32,14 @@ class MatchesGoldenFile extends AsyncMatcher { ...@@ -32,15 +32,14 @@ class MatchesGoldenFile extends AsyncMatcher {
final Uri key; final Uri key;
/// The [version] of the golden image. /// The [version] of the golden image.
final int version; final int? version;
@override @override
Future<String> matchAsync(dynamic item) async { Future<String?> matchAsync(dynamic item) async {
if (item is! Finder) { if (item is! Finder) {
return 'web goldens only supports matching finders.'; return 'web goldens only supports matching finders.';
} }
final Finder finder = item as Finder; final Iterable<Element> elements = item.evaluate();
final Iterable<Element> elements = finder.evaluate();
if (elements.isEmpty) { if (elements.isEmpty) {
return 'could not be rendered because no widget was found'; return 'could not be rendered because no widget was found';
} else if (elements.length > 1) { } else if (elements.length > 1) {
...@@ -50,14 +49,14 @@ class MatchesGoldenFile extends AsyncMatcher { ...@@ -50,14 +49,14 @@ class MatchesGoldenFile extends AsyncMatcher {
final RenderObject renderObject = _findRepaintBoundary(element); final RenderObject renderObject = _findRepaintBoundary(element);
final Size size = renderObject.paintBounds.size; final Size size = renderObject.paintBounds.size;
final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized() as TestWidgetsFlutterBinding; final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized() as TestWidgetsFlutterBinding;
final Element e = binding.renderViewElement; final Element e = binding.renderViewElement!;
// Unlike `flutter_tester`, we don't have the ability to render an element // Unlike `flutter_tester`, we don't have the ability to render an element
// to an image directly. Instead, we will use `window.render()` to render // to an image directly. Instead, we will use `window.render()` to render
// only the element being requested, and send a request to the test server // only the element being requested, and send a request to the test server
// requesting it to take a screenshot through the browser's debug interface. // requesting it to take a screenshot through the browser's debug interface.
_renderElement(binding.window, renderObject); _renderElement(binding.window, renderObject);
final String result = await binding.runAsync<String>(() async { final String? result = await binding.runAsync<String?>(() async {
if (autoUpdateGoldenFiles) { if (autoUpdateGoldenFiles) {
await webGoldenComparator.update(size.width, size.height, key); await webGoldenComparator.update(size.width, size.height, key);
return null; return null;
...@@ -81,7 +80,8 @@ class MatchesGoldenFile extends AsyncMatcher { ...@@ -81,7 +80,8 @@ class MatchesGoldenFile extends AsyncMatcher {
} }
RenderObject _findRepaintBoundary(Element element) { RenderObject _findRepaintBoundary(Element element) {
RenderObject renderObject = element.renderObject; assert(element.renderObject != null);
RenderObject renderObject = element.renderObject!;
while (!renderObject.isRepaintBoundary) { while (!renderObject.isRepaintBoundary) {
renderObject = renderObject.parent as RenderObject; renderObject = renderObject.parent as RenderObject;
assert(renderObject != null); assert(renderObject != null);
...@@ -90,7 +90,8 @@ RenderObject _findRepaintBoundary(Element element) { ...@@ -90,7 +90,8 @@ RenderObject _findRepaintBoundary(Element element) {
} }
void _renderElement(ui.Window window, RenderObject renderObject) { void _renderElement(ui.Window window, RenderObject renderObject) {
final Layer layer = renderObject.debugLayer; assert(renderObject.debugLayer != null);
final Layer layer = renderObject.debugLayer!;
final ui.SceneBuilder sceneBuilder = ui.SceneBuilder(); final ui.SceneBuilder sceneBuilder = ui.SceneBuilder();
if (layer is OffsetLayer) { if (layer is OffsetLayer) {
sceneBuilder.pushOffset(-layer.offset.dx, -layer.offset.dy); sceneBuilder.pushOffset(-layer.offset.dx, -layer.offset.dy);
......
...@@ -18,7 +18,7 @@ import 'package:flutter/widgets.dart'; ...@@ -18,7 +18,7 @@ import 'package:flutter/widgets.dart';
/// are also cached. /// are also cached.
Iterable<Element> collectAllElementsFrom( Iterable<Element> collectAllElementsFrom(
Element rootElement, { Element rootElement, {
@required bool skipOffstage, required bool skipOffstage,
}) { }) {
return CachingIterable<Element>(_DepthFirstChildIterator(rootElement, skipOffstage)); return CachingIterable<Element>(_DepthFirstChildIterator(rootElement, skipOffstage));
} }
...@@ -29,7 +29,7 @@ class _DepthFirstChildIterator implements Iterator<Element> { ...@@ -29,7 +29,7 @@ class _DepthFirstChildIterator implements Iterator<Element> {
final bool skipOffstage; final bool skipOffstage;
Element _current; late Element _current;
final List<Element> _stack; final List<Element> _stack;
......
...@@ -8,7 +8,6 @@ import 'dart:ui' as ui; ...@@ -8,7 +8,6 @@ import 'dart:ui' as ui;
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
/// Records the frames of an animating widget, and later displays the frames as a /// Records the frames of an animating widget, and later displays the frames as a
/// grid in an animation sheet. /// grid in an animation sheet.
...@@ -92,7 +91,7 @@ class AnimationSheetBuilder { ...@@ -92,7 +91,7 @@ class AnimationSheetBuilder {
/// ///
/// The [frameSize] is a tight constraint for the child to be recorded, and must not /// The [frameSize] is a tight constraint for the child to be recorded, and must not
/// be null. /// be null.
AnimationSheetBuilder({@required this.frameSize}) : assert(frameSize != null); AnimationSheetBuilder({required this.frameSize}) : assert(frameSize != null);
/// The size of the child to be recorded. /// The size of the child to be recorded.
/// ///
...@@ -133,7 +132,7 @@ class AnimationSheetBuilder { ...@@ -133,7 +132,7 @@ class AnimationSheetBuilder {
/// * [WidgetTester.pumpFrames], which renders a widget in a series of frames /// * [WidgetTester.pumpFrames], which renders a widget in a series of frames
/// with a fixed time interval. /// with a fixed time interval.
Widget record(Widget child, { Widget record(Widget child, {
Key key, Key? key,
bool recording = true, bool recording = true,
}) { }) {
assert(child != null); assert(child != null);
...@@ -160,7 +159,7 @@ class AnimationSheetBuilder { ...@@ -160,7 +159,7 @@ class AnimationSheetBuilder {
/// The `key` is applied to the root widget. /// The `key` is applied to the root widget.
/// ///
/// This method can only be called if at least one frame has been recorded. /// This method can only be called if at least one frame has been recorded.
Future<Widget> display({Key key}) async { Future<Widget> display({Key? key}) async {
assert(_recordedFrames.isNotEmpty); assert(_recordedFrames.isNotEmpty);
final List<ui.Image> frames = await _frames; final List<ui.Image> frames = await _frames;
return _CellSheet( return _CellSheet(
...@@ -209,12 +208,12 @@ typedef _RecordedHandler = void Function(Future<ui.Image> image); ...@@ -209,12 +208,12 @@ typedef _RecordedHandler = void Function(Future<ui.Image> image);
class _AnimationSheetRecorder extends StatefulWidget { class _AnimationSheetRecorder extends StatefulWidget {
const _AnimationSheetRecorder({ const _AnimationSheetRecorder({
this.handleRecorded, this.handleRecorded,
this.child, required this.child,
this.size, required this.size,
Key key, Key? key,
}) : super(key: key); }) : super(key: key);
final _RecordedHandler handleRecorded; final _RecordedHandler? handleRecorded;
final Widget child; final Widget child;
final Size size; final Size size;
...@@ -226,8 +225,9 @@ class _AnimationSheetRecorderState extends State<_AnimationSheetRecorder> { ...@@ -226,8 +225,9 @@ class _AnimationSheetRecorderState extends State<_AnimationSheetRecorder> {
GlobalKey boundaryKey = GlobalKey(); GlobalKey boundaryKey = GlobalKey();
void _record(Duration duration) { void _record(Duration duration) {
final RenderRepaintBoundary boundary = boundaryKey.currentContext.findRenderObject() as RenderRepaintBoundary; assert(widget.handleRecorded != null);
widget.handleRecorded(boundary.toImage()); final RenderRepaintBoundary boundary = boundaryKey.currentContext!.findRenderObject()! as RenderRepaintBoundary;
widget.handleRecorded!(boundary.toImage());
} }
@override @override
...@@ -258,12 +258,12 @@ class _AnimationSheetRecorderState extends State<_AnimationSheetRecorder> { ...@@ -258,12 +258,12 @@ class _AnimationSheetRecorderState extends State<_AnimationSheetRecorder> {
// If `callback` is null, `_PostFrameCallbacker` is equivalent to a proxy box. // If `callback` is null, `_PostFrameCallbacker` is equivalent to a proxy box.
class _PostFrameCallbacker extends SingleChildRenderObjectWidget { class _PostFrameCallbacker extends SingleChildRenderObjectWidget {
const _PostFrameCallbacker({ const _PostFrameCallbacker({
Key key, Key? key,
Widget child, Widget? child,
this.callback, this.callback,
}) : super(key: key, child: child); }) : super(key: key, child: child);
final FrameCallback callback; final FrameCallback? callback;
@override @override
_RenderPostFrameCallbacker createRenderObject(BuildContext context) => _RenderPostFrameCallbacker( _RenderPostFrameCallbacker createRenderObject(BuildContext context) => _RenderPostFrameCallbacker(
...@@ -278,12 +278,12 @@ class _PostFrameCallbacker extends SingleChildRenderObjectWidget { ...@@ -278,12 +278,12 @@ class _PostFrameCallbacker extends SingleChildRenderObjectWidget {
class _RenderPostFrameCallbacker extends RenderProxyBox { class _RenderPostFrameCallbacker extends RenderProxyBox {
_RenderPostFrameCallbacker({ _RenderPostFrameCallbacker({
FrameCallback callback, FrameCallback? callback,
}) : _callback = callback; }) : _callback = callback;
FrameCallback get callback => _callback; FrameCallback? get callback => _callback;
FrameCallback _callback; FrameCallback? _callback;
set callback(FrameCallback value) { set callback(FrameCallback? value) {
_callback = value; _callback = value;
if (value != null) { if (value != null) {
markNeedsPaint(); markNeedsPaint();
...@@ -293,8 +293,8 @@ class _RenderPostFrameCallbacker extends RenderProxyBox { ...@@ -293,8 +293,8 @@ class _RenderPostFrameCallbacker extends RenderProxyBox {
@override @override
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
if (callback != null) { if (callback != null) {
SchedulerBinding.instance.addPostFrameCallback(callback == null ? null : (Duration duration) { SchedulerBinding.instance!.addPostFrameCallback((Duration duration) {
callback(duration); callback!(duration);
markNeedsPaint(); markNeedsPaint();
}); });
} }
...@@ -314,9 +314,9 @@ class _RenderPostFrameCallbacker extends RenderProxyBox { ...@@ -314,9 +314,9 @@ class _RenderPostFrameCallbacker extends RenderProxyBox {
// positioned from top left to bottom right in a row-major order. // positioned from top left to bottom right in a row-major order.
class _CellSheet extends StatelessWidget { class _CellSheet extends StatelessWidget {
_CellSheet({ _CellSheet({
Key key, Key? key,
@required this.cellSize, required this.cellSize,
@required this.children, required this.children,
}) : assert(cellSize != null), }) : assert(cellSize != null),
assert(children != null && children.isNotEmpty), assert(children != null && children.isNotEmpty),
super(key: key); super(key: key);
......
This diff is collapsed.
...@@ -19,10 +19,10 @@ class _BufferGoldenMatcher extends AsyncMatcher { ...@@ -19,10 +19,10 @@ class _BufferGoldenMatcher extends AsyncMatcher {
final Uri key; final Uri key;
/// The [version] of the golden image. /// The [version] of the golden image.
final int version; final int? version;
@override @override
Future<String> matchAsync(dynamic item) async { Future<String?> matchAsync(dynamic item) async {
Uint8List buffer; Uint8List buffer;
if (item is List<int>) { if (item is List<int>) {
buffer = Uint8List.fromList(item); buffer = Uint8List.fromList(item);
...@@ -69,6 +69,6 @@ class _BufferGoldenMatcher extends AsyncMatcher { ...@@ -69,6 +69,6 @@ class _BufferGoldenMatcher extends AsyncMatcher {
/// ); /// );
/// ``` /// ```
/// {@end-tool} /// {@end-tool}
AsyncMatcher bufferMatchesGoldenFile(String key, {int version}) { AsyncMatcher bufferMatchesGoldenFile(String key, {int? version}) {
return _BufferGoldenMatcher(Uri.parse(key), version); return _BufferGoldenMatcher(Uri.parse(key), version);
} }
...@@ -96,7 +96,7 @@ abstract class WidgetController { ...@@ -96,7 +96,7 @@ abstract class WidgetController {
/// using [Iterator.moveNext]. /// using [Iterator.moveNext].
Iterable<Element> get allElements { Iterable<Element> get allElements {
TestAsyncUtils.guardSync(); TestAsyncUtils.guardSync();
return collectAllElementsFrom(binding.renderViewElement, skipOffstage: false); return collectAllElementsFrom(binding.renderViewElement!, skipOffstage: false);
} }
/// The matching element in the widget tree. /// The matching element in the widget tree.
...@@ -193,7 +193,7 @@ abstract class WidgetController { ...@@ -193,7 +193,7 @@ abstract class WidgetController {
/// their own render object. /// their own render object.
Iterable<RenderObject> get allRenderObjects { Iterable<RenderObject> get allRenderObjects {
TestAsyncUtils.guardSync(); TestAsyncUtils.guardSync();
return allElements.map<RenderObject>((Element element) => element.renderObject); return allElements.map<RenderObject>((Element element) => element.renderObject!);
} }
/// The render object of the matching widget in the widget tree. /// The render object of the matching widget in the widget tree.
...@@ -232,13 +232,13 @@ abstract class WidgetController { ...@@ -232,13 +232,13 @@ abstract class WidgetController {
} }
/// Returns a list of all the [Layer] objects in the rendering. /// Returns a list of all the [Layer] objects in the rendering.
List<Layer> get layers => _walkLayers(binding.renderView.debugLayer).toList(); List<Layer> get layers => _walkLayers(binding.renderView.debugLayer!).toList();
Iterable<Layer> _walkLayers(Layer layer) sync* { Iterable<Layer> _walkLayers(Layer layer) sync* {
TestAsyncUtils.guardSync(); TestAsyncUtils.guardSync();
yield layer; yield layer;
if (layer is ContainerLayer) { if (layer is ContainerLayer) {
final ContainerLayer root = layer; final ContainerLayer root = layer;
Layer child = root.firstChild; Layer? child = root.firstChild;
while (child != null) { while (child != null) {
yield* _walkLayers(child); yield* _walkLayers(child);
child = child.nextSibling; child = child.nextSibling;
...@@ -253,12 +253,12 @@ abstract class WidgetController { ...@@ -253,12 +253,12 @@ abstract class WidgetController {
/// ///
/// If the center of the widget is not exposed, this might send events to /// If the center of the widget is not exposed, this might send events to
/// another object. /// another object.
Future<void> tap(Finder finder, {int pointer, int buttons = kPrimaryButton}) { Future<void> tap(Finder finder, {int? pointer, int buttons = kPrimaryButton}) {
return tapAt(getCenter(finder), pointer: pointer, buttons: buttons); return tapAt(getCenter(finder), pointer: pointer, buttons: buttons);
} }
/// Dispatch a pointer down / pointer up sequence at the given location. /// Dispatch a pointer down / pointer up sequence at the given location.
Future<void> tapAt(Offset location, {int pointer, int buttons = kPrimaryButton}) { Future<void> tapAt(Offset location, {int? pointer, int buttons = kPrimaryButton}) {
return TestAsyncUtils.guard<void>(() async { return TestAsyncUtils.guard<void>(() async {
final TestGesture gesture = await startGesture(location, pointer: pointer, buttons: buttons); final TestGesture gesture = await startGesture(location, pointer: pointer, buttons: buttons);
await gesture.up(); await gesture.up();
...@@ -270,7 +270,7 @@ abstract class WidgetController { ...@@ -270,7 +270,7 @@ abstract class WidgetController {
/// ///
/// If the center of the widget is not exposed, this might send events to /// If the center of the widget is not exposed, this might send events to
/// another object. /// another object.
Future<TestGesture> press(Finder finder, {int pointer, int buttons = kPrimaryButton}) { Future<TestGesture> press(Finder finder, {int? pointer, int buttons = kPrimaryButton}) {
return TestAsyncUtils.guard<TestGesture>(() { return TestAsyncUtils.guard<TestGesture>(() {
return startGesture(getCenter(finder), pointer: pointer, buttons: buttons); return startGesture(getCenter(finder), pointer: pointer, buttons: buttons);
}); });
...@@ -282,13 +282,13 @@ abstract class WidgetController { ...@@ -282,13 +282,13 @@ abstract class WidgetController {
/// ///
/// If the center of the widget is not exposed, this might send events to /// If the center of the widget is not exposed, this might send events to
/// another object. /// another object.
Future<void> longPress(Finder finder, {int pointer, int buttons = kPrimaryButton}) { Future<void> longPress(Finder finder, {int? pointer, int buttons = kPrimaryButton}) {
return longPressAt(getCenter(finder), pointer: pointer, buttons: buttons); return longPressAt(getCenter(finder), pointer: pointer, buttons: buttons);
} }
/// Dispatch a pointer down / pointer up sequence at the given location with /// Dispatch a pointer down / pointer up sequence at the given location with
/// a delay of [kLongPressTimeout] + [kPressTimeout] between the two events. /// a delay of [kLongPressTimeout] + [kPressTimeout] between the two events.
Future<void> longPressAt(Offset location, {int pointer, int buttons = kPrimaryButton}) { Future<void> longPressAt(Offset location, {int? pointer, int buttons = kPrimaryButton}) {
return TestAsyncUtils.guard<void>(() async { return TestAsyncUtils.guard<void>(() async {
final TestGesture gesture = await startGesture(location, pointer: pointer, buttons: buttons); final TestGesture gesture = await startGesture(location, pointer: pointer, buttons: buttons);
await pump(kLongPressTimeout + kPressTimeout); await pump(kLongPressTimeout + kPressTimeout);
...@@ -337,7 +337,7 @@ abstract class WidgetController { ...@@ -337,7 +337,7 @@ abstract class WidgetController {
Finder finder, Finder finder,
Offset offset, Offset offset,
double speed, { double speed, {
int pointer, int? pointer,
int buttons = kPrimaryButton, int buttons = kPrimaryButton,
Duration frameInterval = const Duration(milliseconds: 16), Duration frameInterval = const Duration(milliseconds: 16),
Offset initialOffset = Offset.zero, Offset initialOffset = Offset.zero,
...@@ -366,7 +366,7 @@ abstract class WidgetController { ...@@ -366,7 +366,7 @@ abstract class WidgetController {
Offset startLocation, Offset startLocation,
Offset offset, Offset offset,
double speed, { double speed, {
int pointer, int? pointer,
int buttons = kPrimaryButton, int buttons = kPrimaryButton,
Duration frameInterval = const Duration(milliseconds: 16), Duration frameInterval = const Duration(milliseconds: 16),
Offset initialOffset = Offset.zero, Offset initialOffset = Offset.zero,
...@@ -387,7 +387,7 @@ abstract class WidgetController { ...@@ -387,7 +387,7 @@ abstract class WidgetController {
await pump(initialOffsetDelay); await pump(initialOffsetDelay);
} }
for (int i = 0; i <= kMoveCount; i += 1) { for (int i = 0; i <= kMoveCount; i += 1) {
final Offset location = startLocation + initialOffset + Offset.lerp(Offset.zero, offset, i / kMoveCount); final Offset location = startLocation + initialOffset + Offset.lerp(Offset.zero, offset, i / kMoveCount)!;
await sendEventToBinding(testPointer.move(location, timeStamp: Duration(microseconds: timeStamp.round()))); await sendEventToBinding(testPointer.move(location, timeStamp: Duration(microseconds: timeStamp.round())));
timeStamp += timeStampDelta; timeStamp += timeStampDelta;
if (timeStamp - lastTimeStamp > frameInterval.inMicroseconds) { if (timeStamp - lastTimeStamp > frameInterval.inMicroseconds) {
...@@ -496,7 +496,7 @@ abstract class WidgetController { ...@@ -496,7 +496,7 @@ abstract class WidgetController {
Future<void> drag( Future<void> drag(
Finder finder, Finder finder,
Offset offset, { Offset offset, {
int pointer, int? pointer,
int buttons = kPrimaryButton, int buttons = kPrimaryButton,
double touchSlopX = kDragSlopDefault, double touchSlopX = kDragSlopDefault,
double touchSlopY = kDragSlopDefault, double touchSlopY = kDragSlopDefault,
...@@ -525,7 +525,7 @@ abstract class WidgetController { ...@@ -525,7 +525,7 @@ abstract class WidgetController {
Future<void> dragFrom( Future<void> dragFrom(
Offset startLocation, Offset startLocation,
Offset offset, { Offset offset, {
int pointer, int? pointer,
int buttons = kPrimaryButton, int buttons = kPrimaryButton,
double touchSlopX = kDragSlopDefault, double touchSlopX = kDragSlopDefault,
double touchSlopY = kDragSlopDefault, double touchSlopY = kDragSlopDefault,
...@@ -626,7 +626,7 @@ abstract class WidgetController { ...@@ -626,7 +626,7 @@ abstract class WidgetController {
Finder finder, Finder finder,
Offset offset, Offset offset,
Duration duration, { Duration duration, {
int pointer, int? pointer,
int buttons = kPrimaryButton, int buttons = kPrimaryButton,
double frequency = 60.0, double frequency = 60.0,
}) { }) {
...@@ -652,7 +652,7 @@ abstract class WidgetController { ...@@ -652,7 +652,7 @@ abstract class WidgetController {
Offset startLocation, Offset startLocation,
Offset offset, Offset offset,
Duration duration, { Duration duration, {
int pointer, int? pointer,
int buttons = kPrimaryButton, int buttons = kPrimaryButton,
double frequency = 60.0, double frequency = 60.0,
}) { }) {
...@@ -707,7 +707,7 @@ abstract class WidgetController { ...@@ -707,7 +707,7 @@ abstract class WidgetController {
]), ]),
]; ];
return TestAsyncUtils.guard<void>(() async { return TestAsyncUtils.guard<void>(() async {
return handlePointerEventRecord(records); await handlePointerEventRecord(records);
}); });
} }
...@@ -731,7 +731,7 @@ abstract class WidgetController { ...@@ -731,7 +731,7 @@ abstract class WidgetController {
/// You can use [startGesture] instead if your gesture begins with a down /// You can use [startGesture] instead if your gesture begins with a down
/// event. /// event.
Future<TestGesture> createGesture({ Future<TestGesture> createGesture({
int pointer, int? pointer,
PointerDeviceKind kind = PointerDeviceKind.touch, PointerDeviceKind kind = PointerDeviceKind.touch,
int buttons = kPrimaryButton, int buttons = kPrimaryButton,
}) async { }) async {
...@@ -751,7 +751,7 @@ abstract class WidgetController { ...@@ -751,7 +751,7 @@ abstract class WidgetController {
/// down gesture. /// down gesture.
Future<TestGesture> startGesture( Future<TestGesture> startGesture(
Offset downLocation, { Offset downLocation, {
int pointer, int? pointer,
PointerDeviceKind kind = PointerDeviceKind.touch, PointerDeviceKind kind = PointerDeviceKind.touch,
int buttons = kPrimaryButton, int buttons = kPrimaryButton,
}) async { }) async {
...@@ -924,10 +924,10 @@ abstract class WidgetController { ...@@ -924,10 +924,10 @@ abstract class WidgetController {
throw StateError('Finder returned more than one element.'); throw StateError('Finder returned more than one element.');
} }
final Element element = candidates.single; final Element element = candidates.single;
RenderObject renderObject = element.findRenderObject(); RenderObject? renderObject = element.findRenderObject();
SemanticsNode result = renderObject.debugSemantics; SemanticsNode? result = renderObject?.debugSemantics;
while (renderObject != null && (result == null || result.isMergedIntoParent)) { while (renderObject != null && (result == null || result.isMergedIntoParent)) {
renderObject = renderObject?.parent as RenderObject; renderObject = renderObject.parent as RenderObject?;
result = renderObject?.debugSemantics; result = renderObject?.debugSemantics;
} }
if (result == null) if (result == null)
...@@ -978,7 +978,7 @@ abstract class WidgetController { ...@@ -978,7 +978,7 @@ abstract class WidgetController {
Future<void> scrollUntilVisible( Future<void> scrollUntilVisible(
Finder finder, Finder finder,
double delta, { double delta, {
Finder scrollable, Finder? scrollable,
int maxScrolls = 50, int maxScrolls = 50,
Duration duration = const Duration(milliseconds: 50), Duration duration = const Duration(milliseconds: 50),
} }
...@@ -987,7 +987,7 @@ abstract class WidgetController { ...@@ -987,7 +987,7 @@ abstract class WidgetController {
scrollable ??= find.byType(Scrollable); scrollable ??= find.byType(Scrollable);
return TestAsyncUtils.guard<void>(() async { return TestAsyncUtils.guard<void>(() async {
Offset moveStep; Offset moveStep;
switch(widget<Scrollable>(scrollable).axisDirection) { switch (widget<Scrollable>(scrollable!).axisDirection) {
case AxisDirection.up: case AxisDirection.up:
moveStep = Offset(0, delta); moveStep = Offset(0, delta);
break; break;
...@@ -1043,7 +1043,7 @@ class LiveWidgetController extends WidgetController { ...@@ -1043,7 +1043,7 @@ class LiveWidgetController extends WidgetController {
LiveWidgetController(WidgetsBinding binding) : super(binding); LiveWidgetController(WidgetsBinding binding) : super(binding);
@override @override
Future<void> pump([Duration duration]) async { Future<void> pump([Duration? duration]) async {
if (duration != null) if (duration != null)
await Future<void>.delayed(duration); await Future<void>.delayed(duration);
binding.scheduleFrame(); binding.scheduleFrame();
...@@ -1075,7 +1075,7 @@ class LiveWidgetController extends WidgetController { ...@@ -1075,7 +1075,7 @@ class LiveWidgetController extends WidgetController {
// used as state for all pointers which are currently down. // used as state for all pointers which are currently down.
final Map<int, HitTestResult> hitTestHistory = <int, HitTestResult>{}; final Map<int, HitTestResult> hitTestHistory = <int, HitTestResult>{};
final List<Duration> handleTimeStampDiff = <Duration>[]; final List<Duration> handleTimeStampDiff = <Duration>[];
DateTime startTime; DateTime? startTime;
for (final PointerEventRecord record in records) { for (final PointerEventRecord record in records) {
final DateTime now = clock.now(); final DateTime now = clock.now();
startTime ??= now; startTime ??= now;
......
...@@ -47,8 +47,7 @@ class KeyEventSimulator { ...@@ -47,8 +47,7 @@ class KeyEventSimulator {
static int _getScanCode(PhysicalKeyboardKey key, String platform) { static int _getScanCode(PhysicalKeyboardKey key, String platform) {
assert(_osIsSupported(platform), 'Platform $platform not supported for key simulation'); assert(_osIsSupported(platform), 'Platform $platform not supported for key simulation');
int scanCode; late Map<int, PhysicalKeyboardKey> map;
Map<int, PhysicalKeyboardKey> map;
switch (platform) { switch (platform) {
case 'android': case 'android':
map = kAndroidToPhysicalKey; map = kAndroidToPhysicalKey;
...@@ -66,22 +65,23 @@ class KeyEventSimulator { ...@@ -66,22 +65,23 @@ class KeyEventSimulator {
map = kWindowsToPhysicalKey; map = kWindowsToPhysicalKey;
break; break;
case 'web': case 'web':
// web doesn't have int type code // web doesn't have int type code
return null; return -1;
} }
int? scanCode;
for (final int code in map.keys) { for (final int code in map.keys) {
if (key.usbHidUsage == map[code].usbHidUsage) { if (key.usbHidUsage == map[code]!.usbHidUsage) {
scanCode = code; scanCode = code;
break; break;
} }
} }
return scanCode; assert(scanCode != null, 'Physical key for $key not found in $platform scanCode map');
return scanCode!;
} }
static int _getKeyCode(LogicalKeyboardKey key, String platform) { static int _getKeyCode(LogicalKeyboardKey key, String platform) {
assert(_osIsSupported(platform), 'Platform $platform not supported for key simulation'); assert(_osIsSupported(platform), 'Platform $platform not supported for key simulation');
int keyCode; late Map<int, LogicalKeyboardKey> map;
Map<int, LogicalKeyboardKey> map;
switch (platform) { switch (platform) {
case 'android': case 'android':
map = kAndroidToLogicalKey; map = kAndroidToLogicalKey;
...@@ -90,11 +90,11 @@ class KeyEventSimulator { ...@@ -90,11 +90,11 @@ class KeyEventSimulator {
map = kFuchsiaToLogicalKey; map = kFuchsiaToLogicalKey;
break; break;
case 'macos': case 'macos':
// macOS doesn't do key codes, just scan codes. // macOS doesn't do key codes, just scan codes.
return null; return -1;
case 'web': case 'web':
// web doesn't have int type code // web doesn't have int type code
return null; return -1;
case 'linux': case 'linux':
map = kGlfwToLogicalKey; map = kGlfwToLogicalKey;
break; break;
...@@ -102,26 +102,31 @@ class KeyEventSimulator { ...@@ -102,26 +102,31 @@ class KeyEventSimulator {
map = kWindowsToLogicalKey; map = kWindowsToLogicalKey;
break; break;
} }
int? keyCode;
for (final int code in map.keys) { for (final int code in map.keys) {
if (key.keyId == map[code].keyId) { if (key.keyId == map[code]!.keyId) {
keyCode = code; keyCode = code;
break; break;
} }
} }
return keyCode; assert(keyCode != null, 'Key $key not found in $platform keyCode map');
return keyCode!;
} }
static String _getWebKeyCode(LogicalKeyboardKey key) { static String _getWebKeyCode(LogicalKeyboardKey key) {
String? result;
for (final String code in kWebToLogicalKey.keys) { for (final String code in kWebToLogicalKey.keys) {
if (key.keyId == kWebToLogicalKey[code].keyId) { if (key.keyId == kWebToLogicalKey[code]!.keyId) {
return code; result = code;
break;
} }
} }
return null; assert(result != null, 'Key $key not found in web keyCode map');
return result!;
} }
static PhysicalKeyboardKey _findPhysicalKey(LogicalKeyboardKey key, String platform) { static PhysicalKeyboardKey _findPhysicalKey(LogicalKeyboardKey key, String platform) {
assert(_osIsSupported(platform), 'Platform $platform not supported for key simulation'); assert(_osIsSupported(platform), 'Platform $platform not supported for key simulation');
Map<dynamic, PhysicalKeyboardKey> map; late Map<dynamic, PhysicalKeyboardKey> map;
switch (platform) { switch (platform) {
case 'android': case 'android':
map = kAndroidToPhysicalKey; map = kAndroidToPhysicalKey;
...@@ -142,20 +147,23 @@ class KeyEventSimulator { ...@@ -142,20 +147,23 @@ class KeyEventSimulator {
map = kWindowsToPhysicalKey; map = kWindowsToPhysicalKey;
break; break;
} }
PhysicalKeyboardKey? result;
for (final PhysicalKeyboardKey physicalKey in map.values) { for (final PhysicalKeyboardKey physicalKey in map.values) {
if (key.debugName == physicalKey.debugName) { if (key.debugName == physicalKey.debugName) {
return physicalKey; result = physicalKey;
break;
} }
} }
return null; assert(result != null, 'Physical key for $key not found in $platform physical key map');
return result!;
} }
/// Get a raw key data map given a [LogicalKeyboardKey] and a platform. /// Get a raw key data map given a [LogicalKeyboardKey] and a platform.
static Map<String, dynamic> getKeyData( static Map<String, dynamic> getKeyData(
LogicalKeyboardKey key, { LogicalKeyboardKey key, {
String platform, required String platform,
bool isDown = true, bool isDown = true,
PhysicalKeyboardKey physicalKey, PhysicalKeyboardKey? physicalKey,
}) { }) {
assert(_osIsSupported(platform), 'Platform $platform not supported for key simulation'); assert(_osIsSupported(platform), 'Platform $platform not supported for key simulation');
...@@ -165,10 +173,8 @@ class KeyEventSimulator { ...@@ -165,10 +173,8 @@ class KeyEventSimulator {
physicalKey ??= _findPhysicalKey(key, platform); physicalKey ??= _findPhysicalKey(key, platform);
assert(key.debugName != null); assert(key.debugName != null);
final int keyCode = platform == 'macos' || platform == 'web' ? -1 : _getKeyCode(key, platform); final int keyCode = _getKeyCode(key, platform);
assert(platform == 'macos' || platform == 'web' || keyCode != null, 'Key $key not found in $platform keyCode map'); final int scanCode = _getScanCode(physicalKey, platform);
final int scanCode = platform == 'web' ? -1 : _getScanCode(physicalKey, platform);
assert(platform == 'web' || scanCode != null, 'Physical key for $key not found in $platform scanCode map');
final Map<String, dynamic> result = <String, dynamic>{ final Map<String, dynamic> result = <String, dynamic>{
'type': isDown ? 'keydown' : 'keyup', 'type': isDown ? 'keydown' : 'keyup',
...@@ -186,7 +192,7 @@ class KeyEventSimulator { ...@@ -186,7 +192,7 @@ class KeyEventSimulator {
result['metaState'] = _getAndroidModifierFlags(key, isDown); result['metaState'] = _getAndroidModifierFlags(key, isDown);
break; break;
case 'fuchsia': case 'fuchsia':
result['hidUsage'] = physicalKey?.usbHidUsage ?? (key.keyId & LogicalKeyboardKey.hidPlane != 0 ? key.keyId & LogicalKeyboardKey.valueMask : null); result['hidUsage'] = physicalKey.usbHidUsage;
if (key.keyLabel.isNotEmpty) { if (key.keyLabel.isNotEmpty) {
result['codePoint'] = key.keyLabel.codeUnitAt(0); result['codePoint'] = key.keyLabel.codeUnitAt(0);
} }
...@@ -513,16 +519,16 @@ class KeyEventSimulator { ...@@ -513,16 +519,16 @@ class KeyEventSimulator {
/// See also: /// See also:
/// ///
/// - [simulateKeyUpEvent] to simulate the corresponding key up event. /// - [simulateKeyUpEvent] to simulate the corresponding key up event.
static Future<void> simulateKeyDownEvent(LogicalKeyboardKey key, {String platform, PhysicalKeyboardKey physicalKey}) async { static Future<void> simulateKeyDownEvent(LogicalKeyboardKey key, {String? platform, PhysicalKeyboardKey? physicalKey}) async {
return TestAsyncUtils.guard<void>(() async { return TestAsyncUtils.guard<void>(() async {
platform ??= Platform.operatingSystem; platform ??= Platform.operatingSystem;
assert(_osIsSupported(platform), 'Platform $platform not supported for key simulation'); assert(_osIsSupported(platform!), 'Platform $platform not supported for key simulation');
final Map<String, dynamic> data = getKeyData(key, platform: platform, isDown: true, physicalKey: physicalKey); final Map<String, dynamic> data = getKeyData(key, platform: platform!, isDown: true, physicalKey: physicalKey);
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage( await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name, SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data), SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData data) {}, (ByteData? data) { },
); );
}); });
} }
...@@ -540,16 +546,16 @@ class KeyEventSimulator { ...@@ -540,16 +546,16 @@ class KeyEventSimulator {
/// See also: /// See also:
/// ///
/// - [simulateKeyDownEvent] to simulate the corresponding key down event. /// - [simulateKeyDownEvent] to simulate the corresponding key down event.
static Future<void> simulateKeyUpEvent(LogicalKeyboardKey key, {String platform, PhysicalKeyboardKey physicalKey}) async { static Future<void> simulateKeyUpEvent(LogicalKeyboardKey key, {String? platform, PhysicalKeyboardKey? physicalKey}) async {
return TestAsyncUtils.guard<void>(() async { return TestAsyncUtils.guard<void>(() async {
platform ??= Platform.operatingSystem; platform ??= Platform.operatingSystem;
assert(_osIsSupported(platform), 'Platform $platform not supported for key simulation'); assert(_osIsSupported(platform!), 'Platform $platform not supported for key simulation');
final Map<String, dynamic> data = getKeyData(key, platform: platform, isDown: false, physicalKey: physicalKey); final Map<String, dynamic> data = getKeyData(key, platform: platform!, isDown: false, physicalKey: physicalKey);
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage( await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name, SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data), SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData data) {}, (ByteData? data) { },
); );
}); });
} }
...@@ -573,7 +579,7 @@ class KeyEventSimulator { ...@@ -573,7 +579,7 @@ class KeyEventSimulator {
/// See also: /// See also:
/// ///
/// - [simulateKeyUpEvent] to simulate the corresponding key up event. /// - [simulateKeyUpEvent] to simulate the corresponding key up event.
Future<void> simulateKeyDownEvent(LogicalKeyboardKey key, {String platform, PhysicalKeyboardKey physicalKey}) { Future<void> simulateKeyDownEvent(LogicalKeyboardKey key, {String? platform, PhysicalKeyboardKey? physicalKey}) {
return KeyEventSimulator.simulateKeyDownEvent(key, platform: platform, physicalKey: physicalKey); return KeyEventSimulator.simulateKeyDownEvent(key, platform: platform, physicalKey: physicalKey);
} }
...@@ -593,6 +599,6 @@ Future<void> simulateKeyDownEvent(LogicalKeyboardKey key, {String platform, Phys ...@@ -593,6 +599,6 @@ Future<void> simulateKeyDownEvent(LogicalKeyboardKey key, {String platform, Phys
/// See also: /// See also:
/// ///
/// - [simulateKeyDownEvent] to simulate the corresponding key down event. /// - [simulateKeyDownEvent] to simulate the corresponding key down event.
Future<void> simulateKeyUpEvent(LogicalKeyboardKey key, {String platform, PhysicalKeyboardKey physicalKey}) { Future<void> simulateKeyUpEvent(LogicalKeyboardKey key, {String? platform, PhysicalKeyboardKey? physicalKey}) {
return KeyEventSimulator.simulateKeyUpEvent(key, platform: platform, physicalKey: physicalKey); return KeyEventSimulator.simulateKeyUpEvent(key, platform: platform, physicalKey: physicalKey);
} }
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart' show Tooltip;
import 'package:flutter/widgets.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'all_elements.dart'; import 'all_elements.dart';
...@@ -196,7 +197,7 @@ class CommonFinders { ...@@ -196,7 +197,7 @@ class CommonFinders {
/// ///
/// If the `skipOffstage` argument is true (the default), then this skips /// If the `skipOffstage` argument is true (the default), then this skips
/// nodes that are [Offstage] or that are from inactive [Route]s. /// nodes that are [Offstage] or that are from inactive [Route]s.
Finder byWidgetPredicate(WidgetPredicate predicate, { String description, bool skipOffstage = true }) { Finder byWidgetPredicate(WidgetPredicate predicate, { String? description, bool skipOffstage = true }) {
return _WidgetPredicateFinder(predicate, description: description, skipOffstage: skipOffstage); return _WidgetPredicateFinder(predicate, description: description, skipOffstage: skipOffstage);
} }
...@@ -238,7 +239,7 @@ class CommonFinders { ...@@ -238,7 +239,7 @@ class CommonFinders {
/// ///
/// If the `skipOffstage` argument is true (the default), then this skips /// If the `skipOffstage` argument is true (the default), then this skips
/// nodes that are [Offstage] or that are from inactive [Route]s. /// nodes that are [Offstage] or that are from inactive [Route]s.
Finder byElementPredicate(ElementPredicate predicate, { String description, bool skipOffstage = true }) { Finder byElementPredicate(ElementPredicate predicate, { String? description, bool skipOffstage = true }) {
return _ElementPredicateFinder(predicate, description: description, skipOffstage: skipOffstage); return _ElementPredicateFinder(predicate, description: description, skipOffstage: skipOffstage);
} }
...@@ -259,8 +260,8 @@ class CommonFinders { ...@@ -259,8 +260,8 @@ class CommonFinders {
/// If the [skipOffstage] argument is true (the default), then nodes that are /// If the [skipOffstage] argument is true (the default), then nodes that are
/// [Offstage] or that are from inactive [Route]s are skipped. /// [Offstage] or that are from inactive [Route]s are skipped.
Finder descendant({ Finder descendant({
@required Finder of, required Finder of,
@required Finder matching, required Finder matching,
bool matchRoot = false, bool matchRoot = false,
bool skipOffstage = true, bool skipOffstage = true,
}) { }) {
...@@ -289,8 +290,8 @@ class CommonFinders { ...@@ -289,8 +290,8 @@ class CommonFinders {
/// If the [matchRoot] argument is true then the widget(s) specified by [of] /// If the [matchRoot] argument is true then the widget(s) specified by [of]
/// will be matched along with the ancestors. /// will be matched along with the ancestors.
Finder ancestor({ Finder ancestor({
@required Finder of, required Finder of,
@required Finder matching, required Finder matching,
bool matchRoot = false, bool matchRoot = false,
}) { }) {
return _AncestorFinder(of, matching, matchRoot: matchRoot); return _AncestorFinder(of, matching, matchRoot: matchRoot);
...@@ -318,7 +319,7 @@ class CommonFinders { ...@@ -318,7 +319,7 @@ class CommonFinders {
/// If the `skipOffstage` argument is true (the default), then this skips /// If the `skipOffstage` argument is true (the default), then this skips
/// nodes that are [Offstage] or that are from inactive [Route]s. /// nodes that are [Offstage] or that are from inactive [Route]s.
Finder bySemanticsLabel(Pattern label, { bool skipOffstage = true }) { Finder bySemanticsLabel(Pattern label, { bool skipOffstage = true }) {
if (WidgetsBinding.instance.pipelineOwner.semanticsOwner == null) if (WidgetsBinding.instance!.pipelineOwner.semanticsOwner == null)
throw StateError('Semantics are not enabled. ' throw StateError('Semantics are not enabled. '
'Make sure to call tester.ensureSemantics() before using ' 'Make sure to call tester.ensureSemantics() before using '
'this finder, and call dispose on its return value after.'); 'this finder, and call dispose on its return value after.');
...@@ -329,7 +330,7 @@ class CommonFinders { ...@@ -329,7 +330,7 @@ class CommonFinders {
if (element is! RenderObjectElement) { if (element is! RenderObjectElement) {
return false; return false;
} }
final String semanticsLabel = element.renderObject?.debugSemantics?.label; final String? semanticsLabel = element.renderObject.debugSemantics?.label;
if (semanticsLabel == null) { if (semanticsLabel == null) {
return false; return false;
} }
...@@ -375,12 +376,12 @@ abstract class Finder { ...@@ -375,12 +376,12 @@ abstract class Finder {
@protected @protected
Iterable<Element> get allCandidates { Iterable<Element> get allCandidates {
return collectAllElementsFrom( return collectAllElementsFrom(
WidgetsBinding.instance.renderViewElement, WidgetsBinding.instance!.renderViewElement!,
skipOffstage: skipOffstage, skipOffstage: skipOffstage,
); );
} }
Iterable<Element> _cachedResult; Iterable<Element>? _cachedResult;
/// Returns the current result. If [precache] was called and returned true, this will /// Returns the current result. If [precache] was called and returned true, this will
/// cheaply return the result that was computed then. Otherwise, it creates a new /// cheaply return the result that was computed then. Otherwise, it creates a new
...@@ -519,7 +520,7 @@ class _HitTestableFinder extends ChainedFinder { ...@@ -519,7 +520,7 @@ class _HitTestableFinder extends ChainedFinder {
assert(box != null); assert(box != null);
final Offset absoluteOffset = box.localToGlobal(alignment.alongSize(box.size)); final Offset absoluteOffset = box.localToGlobal(alignment.alongSize(box.size));
final HitTestResult hitResult = HitTestResult(); final HitTestResult hitResult = HitTestResult();
WidgetsBinding.instance.hitTest(hitResult, absoluteOffset); WidgetsBinding.instance!.hitTest(hitResult, absoluteOffset);
for (final HitTestEntry entry in hitResult.path) { for (final HitTestEntry entry in hitResult.path) {
if (entry.target == candidate.renderObject) { if (entry.target == candidate.renderObject) {
yield candidate; yield candidate;
...@@ -562,7 +563,8 @@ class _TextFinder extends MatchFinder { ...@@ -562,7 +563,8 @@ class _TextFinder extends MatchFinder {
if (widget is Text) { if (widget is Text) {
if (widget.data != null) if (widget.data != null)
return widget.data == text; return widget.data == text;
return widget.textSpan.toPlainText() == text; assert(widget.textSpan != null);
return widget.textSpan!.toPlainText() == text;
} else if (widget is EditableText) { } else if (widget is EditableText) {
return widget.controller.text == text; return widget.controller.text == text;
} }
...@@ -584,8 +586,9 @@ class _TextContainingFinder extends MatchFinder { ...@@ -584,8 +586,9 @@ class _TextContainingFinder extends MatchFinder {
final Widget widget = candidate.widget; final Widget widget = candidate.widget;
if (widget is Text) { if (widget is Text) {
if (widget.data != null) if (widget.data != null)
return widget.data.contains(pattern); return widget.data!.contains(pattern);
return widget.textSpan.toPlainText().contains(pattern); assert(widget.textSpan != null);
return widget.textSpan!.toPlainText().contains(pattern);
} else if (widget is EditableText) { } else if (widget is EditableText) {
return widget.controller.text.contains(pattern); return widget.controller.text.contains(pattern);
} }
...@@ -665,12 +668,12 @@ class _WidgetFinder extends MatchFinder { ...@@ -665,12 +668,12 @@ class _WidgetFinder extends MatchFinder {
} }
class _WidgetPredicateFinder extends MatchFinder { class _WidgetPredicateFinder extends MatchFinder {
_WidgetPredicateFinder(this.predicate, { String description, bool skipOffstage = true }) _WidgetPredicateFinder(this.predicate, { String? description, bool skipOffstage = true })
: _description = description, : _description = description,
super(skipOffstage: skipOffstage); super(skipOffstage: skipOffstage);
final WidgetPredicate predicate; final WidgetPredicate predicate;
final String _description; final String? _description;
@override @override
String get description => _description ?? 'widget matching predicate ($predicate)'; String get description => _description ?? 'widget matching predicate ($predicate)';
...@@ -682,12 +685,12 @@ class _WidgetPredicateFinder extends MatchFinder { ...@@ -682,12 +685,12 @@ class _WidgetPredicateFinder extends MatchFinder {
} }
class _ElementPredicateFinder extends MatchFinder { class _ElementPredicateFinder extends MatchFinder {
_ElementPredicateFinder(this.predicate, { String description, bool skipOffstage = true }) _ElementPredicateFinder(this.predicate, { String? description, bool skipOffstage = true })
: _description = description, : _description = description,
super(skipOffstage: skipOffstage); super(skipOffstage: skipOffstage);
final ElementPredicate predicate; final ElementPredicate predicate;
final String _description; final String? _description;
@override @override
String get description => _description ?? 'element matching predicate ($predicate)'; String get description => _description ?? 'element matching predicate ($predicate)';
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:ui'; import 'dart:ui';
import 'package:meta/meta.dart';
/// The maximum amount of time considered safe to spend for a frame's build /// The maximum amount of time considered safe to spend for a frame's build
/// phase. Anything past that is in the danger of missing the frame as 60FPS. /// phase. Anything past that is in the danger of missing the frame as 60FPS.
...@@ -64,23 +63,23 @@ class FrameTimingSummarizer { ...@@ -64,23 +63,23 @@ class FrameTimingSummarizer {
} }
const FrameTimingSummarizer._({ const FrameTimingSummarizer._({
@required this.frameBuildTime, required this.frameBuildTime,
@required this.frameRasterizerTime, required this.frameRasterizerTime,
@required this.averageFrameBuildTime, required this.averageFrameBuildTime,
@required this.p90FrameBuildTime, required this.p90FrameBuildTime,
@required this.p99FrameBuildTime, required this.p99FrameBuildTime,
@required this.worstFrameBuildTime, required this.worstFrameBuildTime,
@required this.missedFrameBuildBudget, required this.missedFrameBuildBudget,
@required this.averageFrameRasterizerTime, required this.averageFrameRasterizerTime,
@required this.p90FrameRasterizerTime, required this.p90FrameRasterizerTime,
@required this.p99FrameRasterizerTime, required this.p99FrameRasterizerTime,
@required this.worstFrameRasterizerTime, required this.worstFrameRasterizerTime,
@required this.missedFrameRasterizerBudget, required this.missedFrameRasterizerBudget,
@required this.vsyncOverhead, required this.vsyncOverhead,
@required this.averageVsyncOverhead, required this.averageVsyncOverhead,
@required this.p90VsyncOverhead, required this.p90VsyncOverhead,
@required this.p99VsyncOverhead, required this.p99VsyncOverhead,
@required this.worstVsyncOverhead, required this.worstVsyncOverhead,
}); });
/// List of frame build time in microseconds /// List of frame build time in microseconds
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +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.10
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:path/path.dart' as path; import 'package:path/path.dart' as path;
......
...@@ -38,7 +38,7 @@ Future<ui.Image> createTestImage({ ...@@ -38,7 +38,7 @@ Future<ui.Image> createTestImage({
final int cacheKey = hashValues(width, height); final int cacheKey = hashValues(width, height);
if (cache && _cache.containsKey(cacheKey)) { if (cache && _cache.containsKey(cacheKey)) {
return _cache[cacheKey]; return _cache[cacheKey]!;
} }
final ui.Image image = await _createImage(width, height); final ui.Image image = await _createImage(width, height);
...@@ -74,8 +74,8 @@ Future<ui.Image> _createImage(int width, int height) async { ...@@ -74,8 +74,8 @@ Future<ui.Image> _createImage(int width, int height) async {
// TODO(dnfield): Remove this when https://github.com/flutter/flutter/issues/49244 // TODO(dnfield): Remove this when https://github.com/flutter/flutter/issues/49244
// is resolved. // is resolved.
Future<ui.Image> _webCreateTestImage({ Future<ui.Image> _webCreateTestImage({
int width, required int width,
int height, required int height,
}) async { }) async {
// See https://en.wikipedia.org/wiki/BMP_file_format for format examples. // See https://en.wikipedia.org/wiki/BMP_file_format for format examples.
final int bufferSize = 0x36 + (width * height); final int bufferSize = 0x36 + (width * height);
......
This diff is collapsed.
...@@ -20,7 +20,7 @@ class TestRestorationManager extends RestorationManager { ...@@ -20,7 +20,7 @@ class TestRestorationManager extends RestorationManager {
} }
@override @override
Future<RestorationBucket> get rootBucket { Future<RestorationBucket?> get rootBucket {
_debugRootBucketAccessed = true; _debugRootBucketAccessed = true;
return super.rootBucket; return super.rootBucket;
} }
...@@ -35,7 +35,7 @@ class TestRestorationManager extends RestorationManager { ...@@ -35,7 +35,7 @@ class TestRestorationManager extends RestorationManager {
/// * [WidgetTester.getRestorationData], which makes this data available /// * [WidgetTester.getRestorationData], which makes this data available
/// in a widget test. /// in a widget test.
TestRestorationData get restorationData => _restorationData; TestRestorationData get restorationData => _restorationData;
TestRestorationData _restorationData; late TestRestorationData _restorationData;
/// Whether the [rootBucket] has been obtained. /// Whether the [rootBucket] has been obtained.
bool get debugRootBucketAccessed => _debugRootBucketAccessed; bool get debugRootBucketAccessed => _debugRootBucketAccessed;
...@@ -59,7 +59,7 @@ class TestRestorationManager extends RestorationManager { ...@@ -59,7 +59,7 @@ class TestRestorationManager extends RestorationManager {
/// ///
/// To turn restoration back on call [restoreFrom]. /// To turn restoration back on call [restoreFrom].
void disableRestoration() { void disableRestoration() {
_restorationData = null; _restorationData = TestRestorationData.empty;
handleRestorationUpdateFromEngine(enabled: false, data: null); handleRestorationUpdateFromEngine(enabled: false, data: null);
} }
...@@ -89,5 +89,5 @@ class TestRestorationData { ...@@ -89,5 +89,5 @@ class TestRestorationData {
/// ///
/// Should only be accessed by the test framework. /// Should only be accessed by the test framework.
@protected @protected
final Uint8List binary; final Uint8List? binary;
} }
...@@ -25,7 +25,7 @@ int reportExpectCall(StackTrace stack, List<DiagnosticsNode> information) { ...@@ -25,7 +25,7 @@ int reportExpectCall(StackTrace stack, List<DiagnosticsNode> information) {
line1.firstMatch(stackLines[1]) != null && line1.firstMatch(stackLines[1]) != null &&
line2.firstMatch(stackLines[2]) != null && line2.firstMatch(stackLines[2]) != null &&
line3.firstMatch(stackLines[3]) != null) { line3.firstMatch(stackLines[3]) != null) {
final Match expectMatch = line4.firstMatch(stackLines[4]); final Match expectMatch = line4.firstMatch(stackLines[4])!;
assert(expectMatch != null); assert(expectMatch != null);
assert(expectMatch.groupCount == 2); assert(expectMatch.groupCount == 2);
information.add(DiagnosticsStackTrace.singleFrame( information.add(DiagnosticsStackTrace.singleFrame(
......
...@@ -70,8 +70,8 @@ class TestAsyncUtils { ...@@ -70,8 +70,8 @@ class TestAsyncUtils {
final _AsyncScope scope = _AsyncScope(StackTrace.current, zone); final _AsyncScope scope = _AsyncScope(StackTrace.current, zone);
_scopeStack.add(scope); _scopeStack.add(scope);
final Future<T> result = scope.zone.run<Future<T>>(body); final Future<T> result = scope.zone.run<Future<T>>(body);
T resultValue; // This is set when the body of work completes with a result value. late T resultValue; // This is set when the body of work completes with a result value.
Future<T> completionHandler(dynamic error, StackTrace stack) { Future<T> completionHandler(dynamic error, StackTrace? stack) {
assert(_scopeStack.isNotEmpty); assert(_scopeStack.isNotEmpty);
assert(_scopeStack.contains(scope)); assert(_scopeStack.contains(scope));
bool leaked = false; bool leaked = false;
...@@ -86,7 +86,7 @@ class TestAsyncUtils { ...@@ -86,7 +86,7 @@ class TestAsyncUtils {
information.add(ErrorHint('You must use "await" with all Future-returning test APIs.')); information.add(ErrorHint('You must use "await" with all Future-returning test APIs.'));
leaked = true; leaked = true;
} }
final _StackEntry originalGuarder = _findResponsibleMethod(closedScope.creationStack, 'guard', information); final _StackEntry? originalGuarder = _findResponsibleMethod(closedScope.creationStack, 'guard', information);
if (originalGuarder != null) { if (originalGuarder != null) {
information.add(ErrorDescription( information.add(ErrorDescription(
'The test API method "${originalGuarder.methodName}" ' 'The test API method "${originalGuarder.methodName}" '
...@@ -109,7 +109,7 @@ class TestAsyncUtils { ...@@ -109,7 +109,7 @@ class TestAsyncUtils {
throw FlutterError.fromParts(information); throw FlutterError.fromParts(information);
} }
if (error != null) if (error != null)
return Future<T>.error(error, stack); return Future<T>.error(error! as Object, stack);
return Future<T>.value(resultValue); return Future<T>.value(resultValue);
} }
return result.then<T>( return result.then<T>(
...@@ -121,8 +121,8 @@ class TestAsyncUtils { ...@@ -121,8 +121,8 @@ class TestAsyncUtils {
); );
} }
static Zone get _currentScopeZone { static Zone? get _currentScopeZone {
Zone zone = Zone.current; Zone? zone = Zone.current;
while (zone != null) { while (zone != null) {
if (zone[_scopeStack] == true) if (zone[_scopeStack] == true)
return zone; return zone;
...@@ -142,7 +142,7 @@ class TestAsyncUtils { ...@@ -142,7 +142,7 @@ class TestAsyncUtils {
return; return;
} }
// Find the current TestAsyncUtils scope zone so we can see if it's the one we expect. // Find the current TestAsyncUtils scope zone so we can see if it's the one we expect.
final Zone zone = _currentScopeZone; final Zone? zone = _currentScopeZone;
if (zone == _scopeStack.last.zone) { if (zone == _scopeStack.last.zone) {
// We're still in the current scope zone. All good. // We're still in the current scope zone. All good.
return; return;
...@@ -192,8 +192,8 @@ class TestAsyncUtils { ...@@ -192,8 +192,8 @@ class TestAsyncUtils {
ErrorSummary('Guarded function conflict.'), ErrorSummary('Guarded function conflict.'),
ErrorHint('You must use "await" with all Future-returning test APIs.'), ErrorHint('You must use "await" with all Future-returning test APIs.'),
]; ];
final _StackEntry originalGuarder = _findResponsibleMethod(scope.creationStack, 'guard', information); final _StackEntry? originalGuarder = _findResponsibleMethod(scope.creationStack, 'guard', information);
final _StackEntry collidingGuarder = _findResponsibleMethod(StackTrace.current, 'guardSync', information); final _StackEntry? collidingGuarder = _findResponsibleMethod(StackTrace.current, 'guardSync', information);
if (originalGuarder != null && collidingGuarder != null) { if (originalGuarder != null && collidingGuarder != null) {
final String originalKind = originalGuarder.className == null ? 'function' : 'method'; final String originalKind = originalGuarder.className == null ? 'function' : 'method';
String originalName; String originalName;
...@@ -278,7 +278,7 @@ class TestAsyncUtils { ...@@ -278,7 +278,7 @@ class TestAsyncUtils {
ErrorHint('You must use "await" with all Future-returning test APIs.') ErrorHint('You must use "await" with all Future-returning test APIs.')
]; ];
for (final _AsyncScope scope in _scopeStack) { for (final _AsyncScope scope in _scopeStack) {
final _StackEntry guarder = _findResponsibleMethod(scope.creationStack, 'guard', information); final _StackEntry? guarder = _findResponsibleMethod(scope.creationStack, 'guard', information);
if (guarder != null) { if (guarder != null) {
information.add(ErrorDescription( information.add(ErrorDescription(
'The guarded method "${guarder.methodName}" ' 'The guarded method "${guarder.methodName}" '
...@@ -297,29 +297,29 @@ class TestAsyncUtils { ...@@ -297,29 +297,29 @@ class TestAsyncUtils {
return line != '<asynchronous suspension>'; return line != '<asynchronous suspension>';
} }
static _StackEntry _findResponsibleMethod(StackTrace rawStack, String method, List<DiagnosticsNode> information) { static _StackEntry? _findResponsibleMethod(StackTrace rawStack, String method, List<DiagnosticsNode> information) {
assert(method == 'guard' || method == 'guardSync'); assert(method == 'guard' || method == 'guardSync');
final List<String> stack = rawStack.toString().split('\n').where(_stripAsynchronousSuspensions).toList(); final List<String> stack = rawStack.toString().split('\n').where(_stripAsynchronousSuspensions).toList();
assert(stack.last == ''); assert(stack.last == '');
stack.removeLast(); stack.removeLast();
final RegExp getClassPattern = RegExp(r'^#[0-9]+ +([^. ]+)'); final RegExp getClassPattern = RegExp(r'^#[0-9]+ +([^. ]+)');
Match lineMatch; Match? lineMatch;
int index = -1; int index = -1;
do { // skip past frames that are from this class do { // skip past frames that are from this class
index += 1; index += 1;
assert(index < stack.length); assert(index < stack.length);
lineMatch = getClassPattern.matchAsPrefix(stack[index]); lineMatch = getClassPattern.matchAsPrefix(stack[index])!;
assert(lineMatch != null); assert(lineMatch != null);
assert(lineMatch.groupCount == 1); assert(lineMatch.groupCount == 1);
} while (lineMatch.group(1) == _className); } while (lineMatch.group(1) == _className);
// try to parse the stack to find the interesting frame // try to parse the stack to find the interesting frame
if (index < stack.length) { if (index < stack.length) {
final RegExp guardPattern = RegExp(r'^#[0-9]+ +(?:([^. ]+)\.)?([^. ]+)'); final RegExp guardPattern = RegExp(r'^#[0-9]+ +(?:([^. ]+)\.)?([^. ]+)');
final Match guardMatch = guardPattern.matchAsPrefix(stack[index]); // find the class that called us final Match? guardMatch = guardPattern.matchAsPrefix(stack[index]); // find the class that called us
if (guardMatch != null) { if (guardMatch != null) {
assert(guardMatch.groupCount == 2); assert(guardMatch.groupCount == 2);
final String guardClass = guardMatch.group(1); // might be null final String? guardClass = guardMatch.group(1); // might be null
final String guardMethod = guardMatch.group(2); final String? guardMethod = guardMatch.group(2);
while (index < stack.length) { // find the last stack frame that called the class that called us while (index < stack.length) { // find the last stack frame that called the class that called us
lineMatch = getClassPattern.matchAsPrefix(stack[index]); lineMatch = getClassPattern.matchAsPrefix(stack[index]);
if (lineMatch != null) { if (lineMatch != null) {
...@@ -333,11 +333,11 @@ class TestAsyncUtils { ...@@ -333,11 +333,11 @@ class TestAsyncUtils {
} }
if (index < stack.length) { if (index < stack.length) {
final RegExp callerPattern = RegExp(r'^#[0-9]+ .* \((.+?):([0-9]+)(?::[0-9]+)?\)$'); final RegExp callerPattern = RegExp(r'^#[0-9]+ .* \((.+?):([0-9]+)(?::[0-9]+)?\)$');
final Match callerMatch = callerPattern.matchAsPrefix(stack[index]); // extract the caller's info final Match? callerMatch = callerPattern.matchAsPrefix(stack[index]); // extract the caller's info
if (callerMatch != null) { if (callerMatch != null) {
assert(callerMatch.groupCount == 2); assert(callerMatch.groupCount == 2);
final String callerFile = callerMatch.group(1); final String? callerFile = callerMatch.group(1);
final String callerLine = callerMatch.group(2); final String? callerLine = callerMatch.group(2);
return _StackEntry(guardClass, guardMethod, callerFile, callerLine); return _StackEntry(guardClass, guardMethod, callerFile, callerLine);
} else { } else {
// One reason you might get here is if the guarding method was called directly from // One reason you might get here is if the guarding method was called directly from
...@@ -362,8 +362,8 @@ class TestAsyncUtils { ...@@ -362,8 +362,8 @@ class TestAsyncUtils {
class _StackEntry { class _StackEntry {
const _StackEntry(this.className, this.methodName, this.callerFile, this.callerLine); const _StackEntry(this.className, this.methodName, this.callerFile, this.callerLine);
final String className; final String? className;
final String methodName; final String? methodName;
final String callerFile; final String? callerFile;
final String callerLine; final String? callerLine;
} }
...@@ -21,9 +21,9 @@ import 'package:test_api/src/backend/state.dart'; // ignore: implementation_impo ...@@ -21,9 +21,9 @@ import 'package:test_api/src/backend/state.dart'; // ignore: implementation_impo
// ignore: deprecated_member_use // ignore: deprecated_member_use
import 'package:test_api/test_api.dart'; import 'package:test_api/test_api.dart';
Declarer _localDeclarer; Declarer? _localDeclarer;
Declarer get _declarer { Declarer get _declarer {
final Declarer declarer = Zone.current[#test.declarer] as Declarer; final Declarer? declarer = Zone.current[#test.declarer] as Declarer?;
if (declarer != null) { if (declarer != null) {
return declarer; return declarer;
} }
...@@ -40,7 +40,7 @@ Declarer get _declarer { ...@@ -40,7 +40,7 @@ Declarer get _declarer {
}); });
}); });
} }
return _localDeclarer; return _localDeclarer!;
} }
Future<void> _runGroup(Suite suiteConfig, Group group, List<Group> parents, _Reporter reporter) async { Future<void> _runGroup(Suite suiteConfig, Group group, List<Group> parents, _Reporter reporter) async {
...@@ -49,7 +49,7 @@ Future<void> _runGroup(Suite suiteConfig, Group group, List<Group> parents, _Rep ...@@ -49,7 +49,7 @@ Future<void> _runGroup(Suite suiteConfig, Group group, List<Group> parents, _Rep
final bool skipGroup = group.metadata.skip; final bool skipGroup = group.metadata.skip;
bool setUpAllSucceeded = true; bool setUpAllSucceeded = true;
if (!skipGroup && group.setUpAll != null) { if (!skipGroup && group.setUpAll != null) {
final LiveTest liveTest = group.setUpAll.load(suiteConfig, groups: parents); final LiveTest liveTest = group.setUpAll!.load(suiteConfig, groups: parents);
await _runLiveTest(suiteConfig, liveTest, reporter, countSuccess: false); await _runLiveTest(suiteConfig, liveTest, reporter, countSuccess: false);
setUpAllSucceeded = liveTest.state.result.isPassing; setUpAllSucceeded = liveTest.state.result.isPassing;
} }
...@@ -68,7 +68,7 @@ Future<void> _runGroup(Suite suiteConfig, Group group, List<Group> parents, _Rep ...@@ -68,7 +68,7 @@ Future<void> _runGroup(Suite suiteConfig, Group group, List<Group> parents, _Rep
// Even if we're closed or setUpAll failed, we want to run all the // Even if we're closed or setUpAll failed, we want to run all the
// teardowns to ensure that any state is properly cleaned up. // teardowns to ensure that any state is properly cleaned up.
if (!skipGroup && group.tearDownAll != null) { if (!skipGroup && group.tearDownAll != null) {
final LiveTest liveTest = group.tearDownAll.load(suiteConfig, groups: parents); final LiveTest liveTest = group.tearDownAll!.load(suiteConfig, groups: parents);
await _runLiveTest(suiteConfig, liveTest, reporter, countSuccess: false); await _runLiveTest(suiteConfig, liveTest, reporter, countSuccess: false);
} }
} finally { } finally {
...@@ -155,12 +155,12 @@ Future<void> _runSkippedTest(Suite suiteConfig, Test test, List<Group> parents, ...@@ -155,12 +155,12 @@ Future<void> _runSkippedTest(Suite suiteConfig, Test test, List<Group> parents,
void test( void test(
Object description, Object description,
dynamic Function() body, { dynamic Function() body, {
String testOn, String? testOn,
Timeout timeout, Timeout? timeout,
dynamic skip, dynamic skip,
dynamic tags, dynamic tags,
Map<String, dynamic> onPlatform, Map<String, dynamic>? onPlatform,
int retry, int? retry,
}) { }) {
_declarer.test( _declarer.test(
description.toString(), description.toString(),
...@@ -300,21 +300,21 @@ class _Reporter { ...@@ -300,21 +300,21 @@ class _Reporter {
/// The size of `_engine.passed` last time a progress notification was /// The size of `_engine.passed` last time a progress notification was
/// printed. /// printed.
int _lastProgressPassed; int? _lastProgressPassed;
/// The size of `_engine.skipped` last time a progress notification was /// The size of `_engine.skipped` last time a progress notification was
/// printed. /// printed.
int _lastProgressSkipped; int? _lastProgressSkipped;
/// The size of `_engine.failed` last time a progress notification was /// The size of `_engine.failed` last time a progress notification was
/// printed. /// printed.
int _lastProgressFailed; int? _lastProgressFailed;
/// The message printed for the last progress notification. /// The message printed for the last progress notification.
String _lastProgressMessage; String? _lastProgressMessage;
/// The suffix added to the last progress notification. /// The suffix added to the last progress notification.
String _lastProgressSuffix; String? _lastProgressSuffix;
/// The set of all subscriptions to various streams. /// The set of all subscriptions to various streams.
final Set<StreamSubscription<void>> _subscriptions = <StreamSubscription<void>>{}; final Set<StreamSubscription<void>> _subscriptions = <StreamSubscription<void>>{};
...@@ -355,14 +355,8 @@ class _Reporter { ...@@ -355,14 +355,8 @@ class _Reporter {
} }
/// A callback called when the engine is finished running tests. /// A callback called when the engine is finished running tests.
///
/// [success] will be `true` if all tests passed, `false` if some tests
/// failed, and `null` if the engine was closed prematurely.
void _onDone() { void _onDone() {
final bool success = failed.isEmpty; final bool success = failed.isEmpty;
if (success == null) {
return;
}
if (!success) { if (!success) {
_progressLine('Some tests failed.', color: _red); _progressLine('Some tests failed.', color: _red);
} else if (passed.isEmpty) { } else if (passed.isEmpty) {
...@@ -377,7 +371,7 @@ class _Reporter { ...@@ -377,7 +371,7 @@ class _Reporter {
/// [message] goes after the progress report. If [color] is passed, it's used /// [message] goes after the progress report. If [color] is passed, it's used
/// as the color for [message]. If [suffix] is passed, it's added to the end /// as the color for [message]. If [suffix] is passed, it's added to the end
/// of [message]. /// of [message].
void _progressLine(String message, { String color, String suffix }) { void _progressLine(String message, { String? color, String? suffix }) {
// Print nothing if nothing has changed since the last progress line. // Print nothing if nothing has changed since the last progress line.
if (passed.length == _lastProgressPassed && if (passed.length == _lastProgressPassed &&
skipped.length == _lastProgressSkipped && skipped.length == _lastProgressSkipped &&
...@@ -449,15 +443,15 @@ class _Reporter { ...@@ -449,15 +443,15 @@ class _Reporter {
} }
} }
String _indent(String string, { int size, String first }) { String _indent(String string, { int? size, String? first }) {
size ??= first == null ? 2 : first.length; size ??= first == null ? 2 : first.length;
return _prefixLines(string, ' ' * size, first: first); return _prefixLines(string, ' ' * size, first: first);
} }
String _prefixLines(String text, String prefix, { String first, String last, String single }) { String _prefixLines(String text, String prefix, { String? first, String? last, String? single }) {
first ??= prefix; first ??= prefix;
last ??= prefix; last ??= prefix;
single ??= first ?? last ?? prefix; single ??= first;
final List<String> lines = text.split('\n'); final List<String> lines = text.split('\n');
if (lines.length == 1) { if (lines.length == 1) {
return '$single$text'; return '$single$text';
......
...@@ -23,7 +23,7 @@ class TestPointer { ...@@ -23,7 +23,7 @@ class TestPointer {
TestPointer([ TestPointer([
this.pointer = 1, this.pointer = 1,
this.kind = PointerDeviceKind.touch, this.kind = PointerDeviceKind.touch,
this._device, int? device,
int buttons = kPrimaryButton, int buttons = kPrimaryButton,
]) ])
: assert(kind != null), : assert(kind != null),
...@@ -32,13 +32,13 @@ class TestPointer { ...@@ -32,13 +32,13 @@ class TestPointer {
_buttons = buttons { _buttons = buttons {
switch (kind) { switch (kind) {
case PointerDeviceKind.mouse: case PointerDeviceKind.mouse:
_device ??= 1; _device = device ?? 1;
break; break;
case PointerDeviceKind.stylus: case PointerDeviceKind.stylus:
case PointerDeviceKind.invertedStylus: case PointerDeviceKind.invertedStylus:
case PointerDeviceKind.touch: case PointerDeviceKind.touch:
case PointerDeviceKind.unknown: case PointerDeviceKind.unknown:
_device ??= 0; _device = device ?? 0;
break; break;
} }
} }
...@@ -48,7 +48,7 @@ class TestPointer { ...@@ -48,7 +48,7 @@ class TestPointer {
/// Set when the object is constructed. Defaults to 1 if the [kind] is /// Set when the object is constructed. Defaults to 1 if the [kind] is
/// [PointerDeviceKind.mouse], and 0 otherwise. /// [PointerDeviceKind.mouse], and 0 otherwise.
int get device => _device; int get device => _device;
int _device; late int _device;
/// The pointer identifier used for events generated by this object. /// The pointer identifier used for events generated by this object.
/// ///
...@@ -75,15 +75,15 @@ class TestPointer { ...@@ -75,15 +75,15 @@ class TestPointer {
/// The position of the last event sent by this object. /// The position of the last event sent by this object.
/// ///
/// If no event has ever been sent by this object, returns null. /// If no event has ever been sent by this object, returns null.
Offset get location => _location; Offset? get location => _location;
Offset _location; Offset? _location;
/// If a custom event is created outside of this class, this function is used /// If a custom event is created outside of this class, this function is used
/// to set the [isDown]. /// to set the [isDown].
bool setDownInfo( bool setDownInfo(
PointerEvent event, PointerEvent event,
Offset newLocation, { Offset newLocation, {
int buttons, int? buttons,
}) { }) {
_location = newLocation; _location = newLocation;
if (buttons != null) if (buttons != null)
...@@ -114,7 +114,7 @@ class TestPointer { ...@@ -114,7 +114,7 @@ class TestPointer {
PointerDownEvent down( PointerDownEvent down(
Offset newLocation, { Offset newLocation, {
Duration timeStamp = Duration.zero, Duration timeStamp = Duration.zero,
int buttons, int? buttons,
}) { }) {
assert(!isDown); assert(!isDown);
_isDown = true; _isDown = true;
...@@ -126,7 +126,7 @@ class TestPointer { ...@@ -126,7 +126,7 @@ class TestPointer {
kind: kind, kind: kind,
device: _device, device: _device,
pointer: pointer, pointer: pointer,
position: location, position: location!,
buttons: _buttons, buttons: _buttons,
); );
} }
...@@ -144,14 +144,14 @@ class TestPointer { ...@@ -144,14 +144,14 @@ class TestPointer {
PointerMoveEvent move( PointerMoveEvent move(
Offset newLocation, { Offset newLocation, {
Duration timeStamp = Duration.zero, Duration timeStamp = Duration.zero,
int buttons, int? buttons,
}) { }) {
assert( assert(
isDown, isDown,
'Move events can only be generated when the pointer is down. To ' 'Move events can only be generated when the pointer is down. To '
'create a movement event simulating a pointer move when the pointer is ' 'create a movement event simulating a pointer move when the pointer is '
'up, use hover() instead.'); 'up, use hover() instead.');
final Offset delta = newLocation - location; final Offset delta = newLocation - location!;
_location = newLocation; _location = newLocation;
if (buttons != null) if (buttons != null)
_buttons = buttons; _buttons = buttons;
...@@ -180,7 +180,7 @@ class TestPointer { ...@@ -180,7 +180,7 @@ class TestPointer {
kind: kind, kind: kind,
device: _device, device: _device,
pointer: pointer, pointer: pointer,
position: location, position: location!,
); );
} }
...@@ -198,7 +198,7 @@ class TestPointer { ...@@ -198,7 +198,7 @@ class TestPointer {
kind: kind, kind: kind,
device: _device, device: _device,
pointer: pointer, pointer: pointer,
position: location, position: location!,
); );
} }
...@@ -209,7 +209,7 @@ class TestPointer { ...@@ -209,7 +209,7 @@ class TestPointer {
/// specific time stamp by passing the `timeStamp` argument. /// specific time stamp by passing the `timeStamp` argument.
PointerAddedEvent addPointer({ PointerAddedEvent addPointer({
Duration timeStamp = Duration.zero, Duration timeStamp = Duration.zero,
Offset location, Offset? location,
}) { }) {
assert(timeStamp != null); assert(timeStamp != null);
_location = location ?? _location; _location = location ?? _location;
...@@ -228,7 +228,7 @@ class TestPointer { ...@@ -228,7 +228,7 @@ class TestPointer {
/// specific time stamp by passing the `timeStamp` argument. /// specific time stamp by passing the `timeStamp` argument.
PointerRemovedEvent removePointer({ PointerRemovedEvent removePointer({
Duration timeStamp = Duration.zero, Duration timeStamp = Duration.zero,
Offset location, Offset? location,
}) { }) {
assert(timeStamp != null); assert(timeStamp != null);
_location = location ?? _location; _location = location ?? _location;
...@@ -258,7 +258,7 @@ class TestPointer { ...@@ -258,7 +258,7 @@ class TestPointer {
'Hover events can only be generated when the pointer is up. To ' 'Hover events can only be generated when the pointer is up. To '
'simulate movement when the pointer is down, use move() instead.'); 'simulate movement when the pointer is down, use move() instead.');
assert(kind != PointerDeviceKind.touch, "Touch pointers can't generate hover events"); assert(kind != PointerDeviceKind.touch, "Touch pointers can't generate hover events");
final Offset delta = location != null ? newLocation - location : Offset.zero; final Offset delta = location != null ? newLocation - location! : Offset.zero;
_location = newLocation; _location = newLocation;
return PointerHoverEvent( return PointerHoverEvent(
timeStamp: timeStamp, timeStamp: timeStamp,
...@@ -281,11 +281,12 @@ class TestPointer { ...@@ -281,11 +281,12 @@ class TestPointer {
assert(scrollDelta != null); assert(scrollDelta != null);
assert(timeStamp != null); assert(timeStamp != null);
assert(kind != PointerDeviceKind.touch, "Touch pointers can't generate pointer signal events"); assert(kind != PointerDeviceKind.touch, "Touch pointers can't generate pointer signal events");
assert(location != null);
return PointerScrollEvent( return PointerScrollEvent(
timeStamp: timeStamp, timeStamp: timeStamp,
kind: kind, kind: kind,
device: _device, device: _device,
position: location, position: location!,
scrollDelta: scrollDelta, scrollDelta: scrollDelta,
); );
} }
...@@ -321,10 +322,10 @@ class TestGesture { ...@@ -321,10 +322,10 @@ class TestGesture {
/// None of the arguments may be null. The `dispatcher` and `hitTester` /// None of the arguments may be null. The `dispatcher` and `hitTester`
/// arguments are required. /// arguments are required.
TestGesture({ TestGesture({
@required EventDispatcher dispatcher, required EventDispatcher dispatcher,
int pointer = 1, int pointer = 1,
PointerDeviceKind kind = PointerDeviceKind.touch, PointerDeviceKind kind = PointerDeviceKind.touch,
int device, int? device,
int buttons = kPrimaryButton, int buttons = kPrimaryButton,
}) : assert(dispatcher != null), }) : assert(dispatcher != null),
assert(pointer != null), assert(pointer != null),
...@@ -363,14 +364,14 @@ class TestGesture { ...@@ -363,14 +364,14 @@ class TestGesture {
} }
/// In a test, send a pointer add event for this pointer. /// In a test, send a pointer add event for this pointer.
Future<void> addPointer({ Duration timeStamp = Duration.zero, Offset location }) { Future<void> addPointer({ Duration timeStamp = Duration.zero, Offset? location }) {
return TestAsyncUtils.guard<void>(() { return TestAsyncUtils.guard<void>(() {
return _dispatcher(_pointer.addPointer(timeStamp: timeStamp, location: location ?? _pointer.location)); return _dispatcher(_pointer.addPointer(timeStamp: timeStamp, location: location ?? _pointer.location));
}); });
} }
/// In a test, send a pointer remove event for this pointer. /// In a test, send a pointer remove event for this pointer.
Future<void> removePointer({ Duration timeStamp = Duration.zero, Offset location }) { Future<void> removePointer({ Duration timeStamp = Duration.zero, Offset? location }) {
return TestAsyncUtils.guard<void>(() { return TestAsyncUtils.guard<void>(() {
return _dispatcher(_pointer.removePointer(timeStamp: timeStamp, location: location ?? _pointer.location)); return _dispatcher(_pointer.removePointer(timeStamp: timeStamp, location: location ?? _pointer.location));
}); });
...@@ -382,7 +383,8 @@ class TestGesture { ...@@ -382,7 +383,8 @@ class TestGesture {
/// up, then a hover event is dispatched. Touch devices are not able to send /// up, then a hover event is dispatched. Touch devices are not able to send
/// hover events. /// hover events.
Future<void> moveBy(Offset offset, { Duration timeStamp = Duration.zero }) { Future<void> moveBy(Offset offset, { Duration timeStamp = Duration.zero }) {
return moveTo(_pointer.location + offset, timeStamp: timeStamp); assert(_pointer.location != null);
return moveTo(_pointer.location! + offset, timeStamp: timeStamp);
} }
/// Send a move event moving the pointer to the given location. /// Send a move event moving the pointer to the given location.
......
...@@ -34,10 +34,10 @@ class TestTextInput { ...@@ -34,10 +34,10 @@ class TestTextInput {
/// To use the methods on this API that send fake keyboard messages (such as /// To use the methods on this API that send fake keyboard messages (such as
/// [updateEditingValue], [enterText], or [receiveAction]), the keyboard must /// [updateEditingValue], [enterText], or [receiveAction]), the keyboard must
/// first be requested, e.g. using [WidgetTester.showKeyboard]. /// first be requested, e.g. using [WidgetTester.showKeyboard].
final VoidCallback onCleared; final VoidCallback? onCleared;
/// The messenger which sends the bytes for this channel, not null. /// The messenger which sends the bytes for this channel, not null.
BinaryMessenger get _binaryMessenger => ServicesBinding.instance.defaultBinaryMessenger; BinaryMessenger get _binaryMessenger => ServicesBinding.instance!.defaultBinaryMessenger;
/// Resets any internal state of this object and calls [register]. /// Resets any internal state of this object and calls [register].
/// ///
...@@ -81,7 +81,7 @@ class TestTextInput { ...@@ -81,7 +81,7 @@ class TestTextInput {
int _client = 0; int _client = 0;
/// Arguments supplied to the TextInput.setClient method call. /// Arguments supplied to the TextInput.setClient method call.
Map<String, dynamic> setClientArgs; Map<String, dynamic>? setClientArgs;
/// The last set of arguments that [TextInputConnection.setEditingState] sent /// The last set of arguments that [TextInputConnection.setEditingState] sent
/// to the embedder. /// to the embedder.
...@@ -89,7 +89,7 @@ class TestTextInput { ...@@ -89,7 +89,7 @@ class TestTextInput {
/// This is a map representation of a [TextEditingValue] object. For example, /// This is a map representation of a [TextEditingValue] object. For example,
/// it will have a `text` entry whose value matches the most recent /// it will have a `text` entry whose value matches the most recent
/// [TextEditingValue.text] that was sent to the embedder. /// [TextEditingValue.text] that was sent to the embedder.
Map<String, dynamic> editingState; Map<String, dynamic>? editingState;
Future<dynamic> _handleTextInputCall(MethodCall methodCall) async { Future<dynamic> _handleTextInputCall(MethodCall methodCall) async {
log.add(methodCall); log.add(methodCall);
...@@ -105,7 +105,7 @@ class TestTextInput { ...@@ -105,7 +105,7 @@ class TestTextInput {
_client = 0; _client = 0;
_isVisible = false; _isVisible = false;
if (onCleared != null) if (onCleared != null)
onCleared(); onCleared!();
break; break;
case 'TextInput.setEditingState': case 'TextInput.setEditingState':
editingState = methodCall.arguments as Map<String, dynamic>; editingState = methodCall.arguments as Map<String, dynamic>;
...@@ -141,7 +141,7 @@ class TestTextInput { ...@@ -141,7 +141,7 @@ class TestTextInput {
<dynamic>[_client, value.toJSON()], <dynamic>[_client, value.toJSON()],
), ),
), ),
(ByteData data) { /* response from framework is discarded */ }, (ByteData? data) { /* response from framework is discarded */ },
); );
} }
...@@ -164,7 +164,7 @@ class TestTextInput { ...@@ -164,7 +164,7 @@ class TestTextInput {
<dynamic>[_client,] <dynamic>[_client,]
), ),
), ),
(ByteData data) { /* response from framework is discarded */ }, (ByteData? data) { /* response from framework is discarded */ },
); );
} }
...@@ -198,11 +198,12 @@ class TestTextInput { ...@@ -198,11 +198,12 @@ class TestTextInput {
<dynamic>[_client, action.toString()], <dynamic>[_client, action.toString()],
), ),
), ),
(ByteData data) { (ByteData? data) {
assert(data != null);
try { try {
// Decoding throws a PlatformException if the data represents an // Decoding throws a PlatformException if the data represents an
// error, and that's all we care about here. // error, and that's all we care about here.
SystemChannels.textInput.codec.decodeEnvelope(data); SystemChannels.textInput.codec.decodeEnvelope(data!);
// No error was found. Complete without issue. // No error was found. Complete without issue.
completer.complete(); completer.complete();
......
This diff is collapsed.
...@@ -2,7 +2,7 @@ name: flutter_test ...@@ -2,7 +2,7 @@ name: flutter_test
environment: environment:
# The pub client defaults to an <2.0.0 sdk constraint which we need to explicitly overwrite. # The pub client defaults to an <2.0.0 sdk constraint which we need to explicitly overwrite.
sdk: ">=2.2.2 <3.0.0" sdk: ">=2.10.0-0.0.dev <3.0.0"
dependencies: dependencies:
# To update these, use "flutter update-packages --force-upgrade". # To update these, use "flutter update-packages --force-upgrade".
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'dart:async'; import 'dart:async';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
...@@ -38,7 +40,7 @@ Future<void> main() async { ...@@ -38,7 +40,7 @@ Future<void> main() async {
); );
completer.completeError(const CustomException()); completer.completeError(const CustomException());
}, null); }, () { });
final FlutterErrorDetails details = await errorCompleter.future; final FlutterErrorDetails details = await errorCompleter.future;
expect(details, isNotNull); expect(details, isNotNull);
...@@ -49,4 +51,4 @@ Future<void> main() async { ...@@ -49,4 +51,4 @@ Future<void> main() async {
class CustomException implements Exception { class CustomException implements Exception {
const CustomException(); const CustomException();
} }
\ No newline at end of file
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'package:flutter/material.dart'; 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';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'package:flutter/material.dart'; 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';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'package:flutter/material.dart'; 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';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'package:flutter/material.dart'; 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';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'package:flutter/material.dart'; 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';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'dart:io'; import 'dart:io';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'dart:ui'; import 'dart:ui';
import 'package:flutter/semantics.dart'; import 'package:flutter/semantics.dart';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'dart:async'; import 'dart:async';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'flutter_test_config.dart' as real_test; import 'flutter_test_config.dart' as real_test;
void main() => real_test.runTest(); void main() => real_test.runTest();
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'dart:async'; import 'dart:async';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'package:flutter/services.dart'; import 'package:flutter/services.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';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'dart:ui'; import 'dart:ui';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'dart:async'; import 'dart:async';
import 'dart:io' as io; import 'dart:io' as io;
import 'dart:typed_data'; import 'dart:typed_data';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'dart:io'; import 'dart:io';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'dart:ui'; import 'dart:ui';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'dart:ui'; import 'dart:ui';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'dart:typed_data'; import 'dart:typed_data';
import 'dart:ui'; import 'dart:ui';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'package:flutter/services.dart'; import 'package:flutter/services.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';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.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';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import '../config_test_utils.dart'; import '../config_test_utils.dart';
void main() { void main() {
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import '../../config_test_utils.dart'; import '../../config_test_utils.dart';
void main() { void main() {
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'config_test_utils.dart'; import 'config_test_utils.dart';
void main() { void main() {
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'dart:async'; import 'dart:async';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'dart:async'; import 'dart:async';
Future<void> main(FutureOr<void> testMain()) async { Future<void> main(FutureOr<void> testMain()) async {
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import '../config_test_utils.dart'; import '../config_test_utils.dart';
void main() { void main() {
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'dart:async'; import 'dart:async';
Future<void> main(FutureOr<void> testMain()) async { Future<void> main(FutureOr<void> testMain()) async {
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import '../config_test_utils.dart'; import '../config_test_utils.dart';
void main() { void main() {
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'dart:ui'; import 'dart:ui';
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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.9
import 'dart:ui' as ui show window; import 'dart:ui' as ui show window;
import 'dart:ui' show Size, Locale, WindowPadding, AccessibilityFeatures, Brightness; import 'dart:ui' show Size, Locale, WindowPadding, AccessibilityFeatures, Brightness;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment