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