Migrate flutter_test (#66663)

This commit is contained in:
Michael Goderbauer 2020-09-30 17:03:40 -07:00 committed by GitHub
parent 0ca0c132a5
commit 19e07d2beb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
69 changed files with 752 additions and 643 deletions

View File

@ -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(

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -0,0 +1,12 @@
# 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

View File

@ -18,7 +18,7 @@ import 'package:test_api/test_api.dart' as test_package;
import 'binding.dart';
/// Ensure the [WidgetsBinding] is initialized.
WidgetsBinding ensureInitialized([@visibleForTesting Map<String, String> environment]) {
WidgetsBinding ensureInitialized([@visibleForTesting Map<String, String>? environment]) {
environment ??= Platform.environment;
if (WidgetsBinding.instance == null) {
if (environment.containsKey('FLUTTER_TEST') && environment['FLUTTER_TEST'] != 'false') {
@ -28,7 +28,7 @@ WidgetsBinding ensureInitialized([@visibleForTesting Map<String, String> environ
}
}
assert(WidgetsBinding.instance is TestWidgetsFlutterBinding);
return WidgetsBinding.instance;
return WidgetsBinding.instance!;
}
/// Setup mocking of the global [HttpClient].
@ -41,15 +41,17 @@ void mockFlutterAssets() {
if (!Platform.environment.containsKey('UNIT_TEST_ASSETS')) {
return;
}
final String assetFolderPath = Platform.environment['UNIT_TEST_ASSETS'];
final String prefix = 'packages/${Platform.environment['APP_NAME']}/';
final String assetFolderPath = Platform.environment['UNIT_TEST_ASSETS']!;
assert(Platform.environment['APP_NAME'] != null);
final String prefix = 'packages/${Platform.environment['APP_NAME']!}/';
/// Navigation related actions (pop, push, replace) broadcasts these actions via
/// platform messages.
SystemChannels.navigation.setMockMethodCallHandler((MethodCall methodCall) async {});
ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler('flutter/assets', (ByteData message) {
String key = utf8.decode(message.buffer.asUint8List());
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('flutter/assets', (ByteData? message) async {
assert(message != null);
String key = utf8.decode(message!.buffer.asUint8List());
File asset = File(path.join(assetFolderPath, key));
if (!asset.existsSync()) {
@ -78,7 +80,7 @@ void mockFlutterAssets() {
class _MockHttpOverrides extends HttpOverrides {
bool warningPrinted = false;
@override
HttpClient createHttpClient(SecurityContext _) {
HttpClient createHttpClient(SecurityContext? _) {
if (!warningPrinted) {
test_package.printOnFailure(
'Warning: At least one test in this suite creates an HttpClient. When\n'
@ -98,19 +100,19 @@ class _MockHttpOverrides extends HttpOverrides {
/// A mocked [HttpClient] which always returns a [_MockHttpRequest].
class _MockHttpClient implements HttpClient {
@override
bool autoUncompress;
bool autoUncompress = true;
@override
Duration connectionTimeout;
Duration? connectionTimeout;
@override
Duration idleTimeout;
Duration idleTimeout = const Duration(seconds: 15);
@override
int maxConnectionsPerHost;
int? maxConnectionsPerHost;
@override
String userAgent;
String? userAgent;
@override
void addCredentials(Uri url, String realm, HttpClientCredentials credentials) { }
@ -119,13 +121,13 @@ class _MockHttpClient implements HttpClient {
void addProxyCredentials(String host, int port, String realm, HttpClientCredentials credentials) { }
@override
set authenticate(Future<bool> Function(Uri url, String scheme, String realm) f) { }
set authenticate(Future<bool> Function(Uri url, String scheme, String realm)? f) { }
@override
set authenticateProxy(Future<bool> Function(String host, int port, String scheme, String realm) f) { }
set authenticateProxy(Future<bool> Function(String host, int port, String scheme, String realm)? f) { }
@override
set badCertificateCallback(bool Function(X509Certificate cert, String host, int port) callback) { }
set badCertificateCallback(bool Function(X509Certificate cert, String host, int port)? callback) { }
@override
void close({ bool force = false }) { }
@ -141,7 +143,7 @@ class _MockHttpClient implements HttpClient {
}
@override
set findProxy(String Function(Uri url) f) { }
set findProxy(String Function(Uri url)? f) { }
@override
Future<HttpClientRequest> get(String host, int port, String path) {
@ -207,7 +209,7 @@ class _MockHttpClient implements HttpClient {
/// A mocked [HttpClientRequest] which always returns a [_MockHttpClientResponse].
class _MockHttpRequest extends HttpClientRequest {
@override
Encoding encoding;
late Encoding encoding;
@override
final HttpHeaders headers = _MockHttpHeaders();
@ -216,7 +218,7 @@ class _MockHttpRequest extends HttpClientRequest {
void add(List<int> data) { }
@override
void addError(Object error, [ StackTrace stackTrace ]) { }
void addError(Object error, [ StackTrace? stackTrace ]) { }
@override
Future<void> addStream(Stream<List<int>> stream) {
@ -228,19 +230,17 @@ class _MockHttpRequest extends HttpClientRequest {
return Future<HttpClientResponse>.value(_MockHttpResponse());
}
// TODO(zichangguo): remove the ignore after the change in dart:io lands.
@override
// ignore: override_on_non_overriding_member
void abort([Object exception, StackTrace stackTrace]) {}
void abort([Object? exception, StackTrace? stackTrace]) {}
@override
HttpConnectionInfo get connectionInfo => null;
HttpConnectionInfo? get connectionInfo => null;
@override
List<Cookie> get cookies => null;
List<Cookie> get cookies => <Cookie>[];
@override
Future<HttpClientResponse> get done async => null;
Future<HttpClientResponse> get done async => _MockHttpResponse();
@override
Future<void> flush() {
@ -248,22 +248,22 @@ class _MockHttpRequest extends HttpClientRequest {
}
@override
String get method => null;
String get method => '';
@override
Uri get uri => null;
Uri get uri => Uri();
@override
void write(Object obj) { }
void write(Object? obj) { }
@override
void writeAll(Iterable<Object> objects, [ String separator = '' ]) { }
void writeAll(Iterable<dynamic> objects, [ String separator = '' ]) { }
@override
void writeCharCode(int charCode) { }
@override
void writeln([ Object obj = '' ]) { }
void writeln([ Object? obj = '' ]) { }
}
/// A mocked [HttpClientResponse] which is empty and has a [statusCode] of 400.
@ -276,10 +276,10 @@ class _MockHttpResponse implements HttpClientResponse {
final HttpHeaders headers = _MockHttpHeaders();
@override
X509Certificate get certificate => null;
X509Certificate? get certificate => null;
@override
HttpConnectionInfo get connectionInfo => null;
HttpConnectionInfo? get connectionInfo => null;
@override
int get contentLength => -1;
@ -290,7 +290,7 @@ class _MockHttpResponse implements HttpClientResponse {
}
@override
List<Cookie> get cookies => null;
List<Cookie> get cookies => <Cookie>[];
@override
Future<Socket> detachSocket() {
@ -301,18 +301,18 @@ class _MockHttpResponse implements HttpClientResponse {
bool get isRedirect => false;
@override
StreamSubscription<Uint8List> listen(void Function(Uint8List event) onData, { Function onError, void Function() onDone, bool cancelOnError }) {
StreamSubscription<Uint8List> listen(void Function(Uint8List event)? onData, { Function? onError, void Function()? onDone, bool? cancelOnError }) {
return const Stream<Uint8List>.empty().listen(onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError);
}
@override
bool get persistentConnection => null;
bool get persistentConnection => false;
@override
String get reasonPhrase => null;
String get reasonPhrase => '';
@override
Future<HttpClientResponse> redirect([ String method, Uri url, bool followLoops ]) {
Future<HttpClientResponse> redirect([ String? method, Uri? url, bool? followLoops ]) {
return Future<HttpClientResponse>.error(UnsupportedError('Mocked response'));
}
@ -329,14 +329,14 @@ class _MockHttpResponse implements HttpClientResponse {
@override
Stream<Uint8List> asBroadcastStream({
void Function(StreamSubscription<Uint8List> subscription) onListen,
void Function(StreamSubscription<Uint8List> subscription) onCancel,
void Function(StreamSubscription<Uint8List> subscription)? onListen,
void Function(StreamSubscription<Uint8List> subscription)? onCancel,
}) {
return _delegate.asBroadcastStream(onListen: onListen, onCancel: onCancel);
}
@override
Stream<E> asyncExpand<E>(Stream<E> Function(Uint8List event) convert) {
Stream<E> asyncExpand<E>(Stream<E>? Function(Uint8List event) convert) {
return _delegate.asyncExpand<E>(convert);
}
@ -351,17 +351,17 @@ class _MockHttpResponse implements HttpClientResponse {
}
@override
Future<bool> contains(Object needle) {
Future<bool> contains(Object? needle) {
return _delegate.contains(needle);
}
@override
Stream<Uint8List> distinct([bool Function(Uint8List previous, Uint8List next) equals]) {
Stream<Uint8List> distinct([bool Function(Uint8List previous, Uint8List next)? equals]) {
return _delegate.distinct(equals);
}
@override
Future<E> drain<E>([E futureValue]) {
Future<E> drain<E>([E? futureValue]) {
return _delegate.drain<E>(futureValue);
}
@ -386,9 +386,9 @@ class _MockHttpResponse implements HttpClientResponse {
@override
Future<Uint8List> firstWhere(
bool Function(Uint8List element) test, {
List<int> Function() orElse,
List<int> Function()? orElse,
}) {
return _delegate.firstWhere(test, orElse: () {
return _delegate.firstWhere(test, orElse: orElse == null ? null : () {
return Uint8List.fromList(orElse());
});
}
@ -406,7 +406,7 @@ class _MockHttpResponse implements HttpClientResponse {
@override
Stream<Uint8List> handleError(
Function onError, {
bool Function(dynamic error) test,
bool Function(dynamic error)? test,
}) {
return _delegate.handleError(onError, test: test);
}
@ -428,9 +428,9 @@ class _MockHttpResponse implements HttpClientResponse {
@override
Future<Uint8List> lastWhere(
bool Function(Uint8List element) test, {
List<int> Function() orElse,
List<int> Function()? orElse,
}) {
return _delegate.lastWhere(test, orElse: () {
return _delegate.lastWhere(test, orElse: orElse == null ? null : () {
return Uint8List.fromList(orElse());
});
}
@ -459,8 +459,8 @@ class _MockHttpResponse implements HttpClientResponse {
Future<Uint8List> get single => _delegate.single;
@override
Future<Uint8List> singleWhere(bool Function(Uint8List element) test, {List<int> Function() orElse}) {
return _delegate.singleWhere(test, orElse: () {
Future<Uint8List> singleWhere(bool Function(Uint8List element) test, {List<int> Function()? orElse}) {
return _delegate.singleWhere(test, orElse: orElse == null ? null : () {
return Uint8List.fromList(orElse());
});
}
@ -488,7 +488,7 @@ class _MockHttpResponse implements HttpClientResponse {
@override
Stream<Uint8List> timeout(
Duration timeLimit, {
void Function(EventSink<Uint8List> sink) onTimeout,
void Function(EventSink<Uint8List> sink)? onTimeout,
}) {
return _delegate.timeout(timeLimit, onTimeout: onTimeout);
}
@ -517,7 +517,7 @@ class _MockHttpResponse implements HttpClientResponse {
/// A mocked [HttpHeaders] that ignores all writes.
class _MockHttpHeaders extends HttpHeaders {
@override
List<String> operator [](String name) => <String>[];
List<String>? operator [](String name) => <String>[];
@override
void add(String name, Object value, {bool preserveHeaderCase = false}) { }
@ -541,5 +541,5 @@ class _MockHttpHeaders extends HttpHeaders {
void set(String name, Object value, {bool preserveHeaderCase = false}) { }
@override
String value(String name) => null;
String? value(String name) => null;
}

View File

@ -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.

View File

@ -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;

View File

@ -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';

View File

@ -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) {

View File

@ -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);

View File

@ -7,7 +7,6 @@ import 'dart:math' as math;
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/material.dart' as flutter_material;
import 'package:flutter/rendering.dart';
import 'package:flutter/semantics.dart';
import 'package:flutter/widgets.dart';
@ -33,13 +32,13 @@ class Evaluation {
final bool passed;
/// If [passed] is false, contains the reason for failure.
final String reason;
final String? reason;
/// Combines two evaluation results.
///
/// The [reason] will be concatenated with a newline, and [passed] will be
/// combined with an `&&` operator.
Evaluation operator +(Evaluation other) {
Evaluation operator +(Evaluation? other) {
if (other == null)
return this;
final StringBuffer buffer = StringBuffer();
@ -82,7 +81,7 @@ class MinimumTapTargetGuideline extends AccessibilityGuideline {
@override
FutureOr<Evaluation> evaluate(WidgetTester tester) {
final SemanticsNode root = tester.binding.pipelineOwner.semanticsOwner.rootSemanticsNode;
final SemanticsNode root = tester.binding.pipelineOwner.semanticsOwner!.rootSemanticsNode!;
Evaluation traverse(SemanticsNode node) {
Evaluation result = const Evaluation.pass();
node.visitChildren((SemanticsNode child) {
@ -98,10 +97,10 @@ class MinimumTapTargetGuideline extends AccessibilityGuideline {
|| data.hasFlag(ui.SemanticsFlag.isHidden))
return result;
Rect paintBounds = node.rect;
SemanticsNode current = node;
SemanticsNode? current = node;
while (current != null) {
if (current.transform != null)
paintBounds = MatrixUtils.transformRect(current.transform, paintBounds);
paintBounds = MatrixUtils.transformRect(current.transform!, paintBounds);
current = current.parent;
}
// skip node if it is touching the edge of the screen, since it might
@ -139,7 +138,7 @@ class LabeledTapTargetGuideline extends AccessibilityGuideline {
@override
FutureOr<Evaluation> evaluate(WidgetTester tester) {
final SemanticsNode root = tester.binding.pipelineOwner.semanticsOwner.rootSemanticsNode;
final SemanticsNode root = tester.binding.pipelineOwner.semanticsOwner!.rootSemanticsNode!;
Evaluation traverse(SemanticsNode node) {
Evaluation result = const Evaluation.pass();
node.visitChildren((SemanticsNode child) {
@ -193,18 +192,21 @@ class MinimumTextContrastGuideline extends AccessibilityGuideline {
/// Defined by http://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html
static const double kMinimumRatioLargeText = 3.0;
static const double _kDefaultFontSize = 12.0;
@override
Future<Evaluation> evaluate(WidgetTester tester) async {
final SemanticsNode root = tester.binding.pipelineOwner.semanticsOwner.rootSemanticsNode;
final SemanticsNode root = tester.binding.pipelineOwner.semanticsOwner!.rootSemanticsNode!;
final RenderView renderView = tester.binding.renderView;
final OffsetLayer layer = renderView.debugLayer as OffsetLayer;
ui.Image image;
final ByteData byteData = await tester.binding.runAsync<ByteData>(() async {
ui.Image? image;
final ByteData byteData = (await tester.binding.runAsync<ByteData?>(() async {
// Needs to be the same pixel ratio otherwise our dimensions won't match the
// last transform layer.
image = await layer.toImage(renderView.paintBounds, pixelRatio: 1 / tester.binding.window.devicePixelRatio);
return image.toByteData();
});
return image!.toByteData();
}))!;
assert(image != null);
Future<Evaluation> evaluateNode(SemanticsNode node) async {
Evaluation result = const Evaluation.pass();
@ -225,33 +227,32 @@ class MinimumTextContrastGuideline extends AccessibilityGuideline {
// We need to look up the inherited text properties to determine the
// contrast ratio based on text size/weight.
double fontSize;
double? fontSize;
bool isBold;
final String text = (data.label?.isEmpty == true) ? data.value : data.label;
final String text = data.label.isEmpty ? data.value : data.label;
final List<Element> elements = find.text(text).hitTestable().evaluate().toList();
Rect paintBounds;
if (elements.length == 1) {
final Element element = elements.single;
final RenderBox renderObject = element.renderObject as RenderBox;
element.renderObject.paintBounds;
assert(element.renderObject != null && element.renderObject is RenderBox);
final RenderBox renderObject = element.renderObject! as RenderBox;
paintBounds = Rect.fromPoints(
renderObject.localToGlobal(element.renderObject.paintBounds.topLeft - const Offset(4.0, 4.0)),
renderObject.localToGlobal(element.renderObject.paintBounds.bottomRight + const Offset(4.0, 4.0)),
renderObject.localToGlobal(renderObject.paintBounds.topLeft - const Offset(4.0, 4.0)),
renderObject.localToGlobal(renderObject.paintBounds.bottomRight + const Offset(4.0, 4.0)),
);
final Widget widget = element.widget;
final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(element);
if (widget is Text) {
TextStyle effectiveTextStyle = widget.style;
if (widget.style == null || widget.style.inherit) {
effectiveTextStyle = defaultTextStyle.style.merge(widget.style);
}
final TextStyle effectiveTextStyle = widget.style == null || widget.style!.inherit
? defaultTextStyle.style!.merge(widget.style)
: widget.style!;
fontSize = effectiveTextStyle.fontSize;
isBold = effectiveTextStyle.fontWeight == FontWeight.bold;
} else if (widget is EditableText) {
isBold = widget.style.fontWeight == FontWeight.bold;
fontSize = widget.style.fontSize;
} else {
assert(false);
throw StateError('Unexpected widget type: ${widget.runtimeType}');
}
} else if (elements.length > 1) {
return Evaluation.fail('Multiple nodes with the same label: ${data.label}\n');
@ -264,7 +265,7 @@ class MinimumTextContrastGuideline extends AccessibilityGuideline {
if (_isNodeOffScreen(paintBounds, tester.binding.window)) {
return result;
}
final List<int> subset = _colorsWithinRect(byteData, paintBounds, image.width, image.height);
final List<int> subset = _colorsWithinRect(byteData, paintBounds, image!.width, image!.height);
// Node was too far off screen.
if (subset.isEmpty) {
return result;
@ -277,7 +278,7 @@ class MinimumTextContrastGuideline extends AccessibilityGuideline {
final double contrastRatio = report.contrastRatio();
const double delta = -0.01;
double targetContrastRatio;
if ((isBold && fontSize > kBoldTextMinimumSize) || (fontSize ?? 12.0) > kLargeTextMinimumSize) {
if ((isBold && (fontSize ?? _kDefaultFontSize) > kBoldTextMinimumSize) || (fontSize ?? _kDefaultFontSize) > kLargeTextMinimumSize) {
targetContrastRatio = kMinimumRatioLargeText;
} else {
targetContrastRatio = kMinimumRatioNormalText;
@ -300,7 +301,7 @@ class MinimumTextContrastGuideline extends AccessibilityGuideline {
bool _shouldSkipNode(SemanticsData data) {
if (data.hasFlag(ui.SemanticsFlag.scopesRoute))
return true;
if (data.label?.trim()?.isEmpty == true && data.value?.trim()?.isEmpty == true)
if (data.label.trim().isEmpty && data.value.trim().isEmpty)
return true;
return false;
}
@ -329,7 +330,7 @@ class CustomMinimumContrastGuideline extends AccessibilityGuideline {
///
/// An optional description string can be given using the [description] parameter.
const CustomMinimumContrastGuideline({
@required this.finder,
required this.finder,
this.minimumRatio = 4.5,
this.tolerance = 0.01,
String description = 'Contrast should follow custom guidelines',
@ -370,13 +371,14 @@ class CustomMinimumContrastGuideline extends AccessibilityGuideline {
final RenderView renderView = tester.binding.renderView;
final OffsetLayer layer = renderView.debugLayer as OffsetLayer;
ui.Image image;
final ByteData byteData = await tester.binding.runAsync<ByteData>(() async {
ui.Image? image;
final ByteData byteData = (await tester.binding.runAsync<ByteData?>(() async {
// Needs to be the same pixel ratio otherwise our dimensions won't match the
// last transform layer.
image = await layer.toImage(renderView.paintBounds, pixelRatio: 1 / tester.binding.window.devicePixelRatio);
return image.toByteData();
});
return image!.toByteData();
}))!;
assert(image != null);
// How to evaluate a single element.
@ -392,7 +394,7 @@ class CustomMinimumContrastGuideline extends AccessibilityGuideline {
renderObject.localToGlobal(inflatedPaintBounds.bottomRight),
);
final List<int> subset = _colorsWithinRect(byteData, paintBounds, image.width, image.height);
final List<int> subset = _colorsWithinRect(byteData, paintBounds, image!.width, image!.height);
if (subset.isEmpty) {
return const Evaluation.pass();
@ -455,7 +457,7 @@ class _ContrastReport {
double averageLightness = 0.0;
for (final int color in colorHistogram.keys) {
final HSLColor hslColor = HSLColor.fromColor(Color(color));
averageLightness += hslColor.lightness * colorHistogram[color];
averageLightness += hslColor.lightness * colorHistogram[color]!;
}
averageLightness /= colors.length;
assert(averageLightness != double.nan);
@ -499,11 +501,13 @@ class _ContrastReport {
isEmptyRect = false;
const _ContrastReport.emptyRect()
: lightColor = flutter_material.Colors.transparent,
darkColor = flutter_material.Colors.transparent,
: lightColor = _transparent,
darkColor = _transparent,
isSingleColor = false,
isEmptyRect = true;
static const Color _transparent = Color(0x00000000);
/// The most frequently occurring light color. Uses [Colors.transparent] if
/// the rectangle is empty.
final Color lightColor;

View File

@ -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;

View File

@ -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);

View File

@ -95,14 +95,14 @@ class TestDefaultBinaryMessenger extends BinaryMessenger {
/// The delegate [BinaryMessenger].
final BinaryMessenger delegate;
final List<Future<ByteData>> _pendingMessages = <Future<ByteData>>[];
final List<Future<ByteData?>> _pendingMessages = <Future<ByteData?>>[];
/// The number of incomplete/pending calls sent to the platform channels.
int get pendingMessageCount => _pendingMessages.length;
@override
Future<ByteData> send(String channel, ByteData message) {
final Future<ByteData> resultFuture = delegate.send(channel, message);
Future<ByteData?> send(String channel, ByteData? message) {
final Future<ByteData?> resultFuture = delegate.send(channel, message);
// Removes the future itself from the [_pendingMessages] list when it
// completes.
if (resultFuture != null) {
@ -124,29 +124,29 @@ class TestDefaultBinaryMessenger extends BinaryMessenger {
@override
Future<void> handlePlatformMessage(
String channel,
ByteData data,
ui.PlatformMessageResponseCallback callback,
ByteData? data,
ui.PlatformMessageResponseCallback? callback,
) {
return delegate.handlePlatformMessage(channel, data, callback);
}
@override
void setMessageHandler(String channel, MessageHandler handler) {
void setMessageHandler(String channel, MessageHandler? handler) {
delegate.setMessageHandler(channel, handler);
}
@override
bool checkMessageHandler(String channel, MessageHandler handler) {
bool checkMessageHandler(String channel, MessageHandler? handler) {
return delegate.checkMessageHandler(channel, handler);
}
@override
void setMockMessageHandler(String channel, MessageHandler handler) {
void setMockMessageHandler(String channel, MessageHandler? handler) {
delegate.setMockMessageHandler(channel, handler);
}
@override
bool checkMockMessageHandler(String channel, MessageHandler handler) {
bool checkMockMessageHandler(String channel, MessageHandler? handler) {
return delegate.checkMockMessageHandler(channel, handler);
}
}
@ -190,7 +190,7 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
@override
TestRestorationManager get restorationManager => _restorationManager;
TestRestorationManager _restorationManager;
late TestRestorationManager _restorationManager;
/// Called by the test framework at the beginning of a widget test to
/// prepare the binding for the next test.
@ -312,7 +312,7 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
///
/// The parameter `environment` is exposed to test different environment
/// variable values, and should not be used.
static WidgetsBinding ensureInitialized([@visibleForTesting Map<String, String> environment]) => binding.ensureInitialized(environment);
static WidgetsBinding ensureInitialized([@visibleForTesting Map<String, String>? environment]) => binding.ensureInitialized(environment);
@override
void initInstances() {
@ -377,7 +377,7 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
///
/// See also [LiveTestWidgetsFlutterBindingFramePolicy], which affects how
/// this method works when the test is run with `flutter run`.
Future<void> pump([ Duration duration, EnginePhase newPhase = EnginePhase.sendSemanticsUpdate ]);
Future<void> pump([ Duration? duration, EnginePhase newPhase = EnginePhase.sendSemanticsUpdate ]);
/// Runs a `callback` that performs real asynchronous work.
///
@ -385,6 +385,9 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
/// the methods spawn isolates or OS threads and thus cannot be executed
/// synchronously by calling [pump].
///
/// The `callback` must return a [Future] that completes to a value of type
/// `T`.
///
/// If `callback` completes successfully, this will return the future
/// returned by `callback`.
///
@ -401,7 +404,7 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
/// [AutomatedTestWidgetsFlutterBinding] implementation to increase the
/// current timeout, if any. See [AutomatedTestWidgetsFlutterBinding.addTime]
/// for details.
Future<T> runAsync<T>(
Future<T?> runAsync<T>(
Future<T> callback(), {
Duration additionalTime = const Duration(milliseconds: 1000),
});
@ -434,13 +437,13 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
readInitialLifecycleStateFromNativeWindow();
}
Size _surfaceSize;
Size? _surfaceSize;
/// Artificially changes the surface size to `size` on the Widget binding,
/// then flushes microtasks.
///
/// Set to null to use the default surface size.
Future<void> setSurfaceSize(Size size) {
Future<void> setSurfaceSize(Size? size) {
return TestAsyncUtils.guard<void>(() async {
assert(inTest);
if (_surfaceSize == size)
@ -513,7 +516,7 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
/// A stub for the system's onscreen keyboard. Callers must set the
/// [focusedEditable] before using this value.
TestTextInput get testTextInput => _testTextInput;
TestTextInput _testTextInput;
late TestTextInput _testTextInput;
/// The current client of the onscreen keyboard. Callers must pump
/// an additional frame after setting this property to complete the
@ -521,9 +524,9 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
///
/// Instead of setting this directly, consider using
/// [WidgetTester.showKeyboard].
EditableTextState get focusedEditable => _focusedEditable;
EditableTextState _focusedEditable;
set focusedEditable(EditableTextState value) {
EditableTextState? get focusedEditable => _focusedEditable;
EditableTextState? _focusedEditable;
set focusedEditable(EditableTextState? value) {
if (_focusedEditable != value) {
_focusedEditable = value;
value?.requestKeyboard();
@ -554,9 +557,9 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
_pendingExceptionDetails = null;
return result;
}
FlutterExceptionHandler _oldExceptionHandler;
StackTraceDemangler _oldStackTraceDemangler;
FlutterErrorDetails _pendingExceptionDetails;
FlutterExceptionHandler? _oldExceptionHandler;
late StackTraceDemangler _oldStackTraceDemangler;
FlutterErrorDetails? _pendingExceptionDetails;
static const TextStyle _messageStyle = TextStyle(
color: Color(0xFF917FFF),
@ -600,7 +603,7 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
///
/// The `timeout` argument sets the initial timeout, if any. It can
/// be increased with [addTime]. By default there is no timeout.
Future<void> runTest(Future<void> testBody(), VoidCallback invariantTester, { String description = '', Duration timeout });
Future<void> runTest(Future<void> testBody(), VoidCallback invariantTester, { String description = '', Duration? timeout });
/// This is called during test execution before and after the body has been
/// executed.
@ -611,7 +614,7 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
TestAsyncUtils.verifyAllScopesClosed();
}
Zone _parentZone;
Zone? _parentZone;
VoidCallback _createTestCompletionHandler(String testDescription, Completer<void> completer) {
return () {
@ -620,7 +623,7 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
assert(Zone.current == _parentZone);
if (_pendingExceptionDetails != null) {
debugPrint = debugPrintOverride; // just in case the test overrides it -- otherwise we won't see the error!
reportTestException(_pendingExceptionDetails, testDescription);
reportTestException(_pendingExceptionDetails!, testDescription);
_pendingExceptionDetails = null;
}
if (!completer.isCompleted)
@ -644,7 +647,7 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
Future<void> testBody(),
VoidCallback invariantTester,
String description, {
Future<void> timeout,
Future<void>? timeout,
}) {
assert(description != null);
assert(inTest);
@ -656,7 +659,7 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
debugPrint = debugPrintOverride; // just in case the test overrides it -- otherwise we won't see the errors!
if (_exceptionCount == 0) {
_exceptionCount = 2;
FlutterError.dumpErrorToConsole(_pendingExceptionDetails, forceReport: true);
FlutterError.dumpErrorToConsole(_pendingExceptionDetails!, forceReport: true);
} else {
_exceptionCount += 1;
}
@ -759,7 +762,7 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
));
assert(_parentZone != null);
assert(_pendingExceptionDetails != null, 'A test overrode FlutterError.onError but either failed to return it to its original state, or had unexpected additional errors that it could not handle. Typically, this is caused by using expect() before restoring FlutterError.onError.');
_parentZone.run<void>(testCompletionHandler);
_parentZone!.run<void>(testCompletionHandler);
}
final ZoneSpecification errorHandlingZoneSpecification = ZoneSpecification(
handleUncaughtError: (Zone self, ZoneDelegate parent, Zone zone, dynamic exception, StackTrace stack) {
@ -767,7 +770,7 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
}
);
_parentZone = Zone.current;
final Zone testZone = _parentZone.fork(specification: errorHandlingZoneSpecification);
final Zone testZone = _parentZone!.fork(specification: errorHandlingZoneSpecification);
testZone.runBinary<Future<void>, Future<void> Function(), VoidCallback>(_runTestBody, testBody, invariantTester)
.whenComplete(testCompletionHandler);
timeout?.catchError(handleUncaughtError);
@ -892,18 +895,18 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
FlutterError.demangleStackTrace = _oldStackTraceDemangler;
_pendingExceptionDetails = null;
_parentZone = null;
buildOwner.focusManager = FocusManager();
buildOwner!.focusManager = FocusManager();
// Disabling the warning because @visibleForTesting doesn't take the testing
// framework itself into account, but we don't want it visible outside of
// tests.
// ignore: invalid_use_of_visible_for_testing_member
RawKeyboard.instance.clearKeysPressed();
assert(!RendererBinding.instance.mouseTracker.mouseIsConnected,
assert(!RendererBinding.instance!.mouseTracker.mouseIsConnected,
'The MouseTracker thinks that there is still a mouse connected, which indicates that a '
'test has not removed the mouse pointer which it added. Call removePointer on the '
'active mouse gesture to remove the mouse pointer.');
// ignore: invalid_use_of_visible_for_testing_member
RendererBinding.instance.initMouseTracker();
RendererBinding.instance!.initMouseTracker();
}
}
@ -922,12 +925,15 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
binding.mockFlutterAssets();
}
FakeAsync _currentFakeAsync; // set in runTest; cleared in postTest
Completer<void> _pendingAsyncTasks;
FakeAsync? _currentFakeAsync; // set in runTest; cleared in postTest
Completer<void>? _pendingAsyncTasks;
@override
Clock get clock => _clock;
Clock _clock;
Clock get clock {
assert(inTest);
return _clock!;
}
Clock? _clock;
@override
DebugPrintCallback get debugPrintOverride => debugPrintSynchronously;
@ -948,32 +954,32 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
bool get inTest => _currentFakeAsync != null;
@override
int get microtaskCount => _currentFakeAsync.microtaskCount;
int get microtaskCount => _currentFakeAsync!.microtaskCount;
@override
Future<void> pump([ Duration duration, EnginePhase newPhase = EnginePhase.sendSemanticsUpdate ]) {
Future<void> pump([ Duration? duration, EnginePhase newPhase = EnginePhase.sendSemanticsUpdate ]) {
return TestAsyncUtils.guard<void>(() {
assert(inTest);
assert(_clock != null);
if (duration != null)
_currentFakeAsync.elapse(duration);
_currentFakeAsync!.elapse(duration);
_phase = newPhase;
if (hasScheduledFrame) {
addTime(const Duration(milliseconds: 500));
_currentFakeAsync.flushMicrotasks();
_currentFakeAsync!.flushMicrotasks();
handleBeginFrame(Duration(
milliseconds: _clock.now().millisecondsSinceEpoch,
milliseconds: _clock!.now().millisecondsSinceEpoch,
));
_currentFakeAsync.flushMicrotasks();
_currentFakeAsync!.flushMicrotasks();
handleDrawFrame();
}
_currentFakeAsync.flushMicrotasks();
_currentFakeAsync!.flushMicrotasks();
return Future<void>.value();
});
}
@override
Future<T> runAsync<T>(
Future<T?> runAsync<T>(
Future<T> callback(), {
Duration additionalTime = const Duration(milliseconds: 1000),
}) {
@ -1021,7 +1027,7 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
// we already reported the exception to FlutterError. Moreover,
// completing the future with an error would trigger an unhandled
// exception due to zone error boundaries.
_pendingAsyncTasks.complete();
_pendingAsyncTasks!.complete();
_pendingAsyncTasks = null;
});
});
@ -1038,24 +1044,27 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
void scheduleWarmUpFrame() {
// We override the default version of this so that the application-startup warm-up frame
// does not schedule timers which we might never get around to running.
assert(inTest);
handleBeginFrame(null);
_currentFakeAsync.flushMicrotasks();
_currentFakeAsync!.flushMicrotasks();
handleDrawFrame();
_currentFakeAsync.flushMicrotasks();
_currentFakeAsync!.flushMicrotasks();
}
@override
void scheduleAttachRootWidget(Widget rootWidget) {
// We override the default version of this so that the application-startup widget tree
// build does not schedule timers which we might never get around to running.
assert(inTest);
attachRootWidget(rootWidget);
_currentFakeAsync.flushMicrotasks();
_currentFakeAsync!.flushMicrotasks();
}
@override
Future<void> idle() {
assert(inTest);
final Future<void> result = super.idle();
_currentFakeAsync.elapse(Duration.zero);
_currentFakeAsync!.elapse(Duration.zero);
return result;
}
@ -1092,7 +1101,7 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
assert(inTest);
try {
debugBuildingDirtyElements = true;
buildOwner.buildScope(renderViewElement);
buildOwner!.buildScope(renderViewElement!);
if (_phase != EnginePhase.build) {
assert(renderView != null);
pipelineOwner.flushLayout();
@ -1112,22 +1121,24 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
}
}
}
buildOwner.finalizeTree();
buildOwner!.finalizeTree();
} finally {
debugBuildingDirtyElements = false;
}
}
Duration _timeout;
Stopwatch _timeoutStopwatch;
Timer _timeoutTimer;
Completer<void> _timeoutCompleter;
Duration? _timeout;
Stopwatch? _timeoutStopwatch;
Timer? _timeoutTimer;
Completer<void>? _timeoutCompleter;
void _checkTimeout(Timer timer) {
assert(_timeoutTimer == timer);
assert(_timeout != null);
if (_timeoutStopwatch.elapsed > _timeout) {
_timeoutCompleter.completeError(
assert(_timeoutCompleter != null);
assert(_timeoutStopwatch != null);
if (_timeoutStopwatch!.elapsed > _timeout!) {
_timeoutCompleter!.completeError(
TimeoutException(
'The test exceeded the timeout. It may have hung.\n'
'Consider using "tester.binding.addTime" to increase the timeout before expensive operations.',
@ -1140,14 +1151,14 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
@override
void addTime(Duration duration) {
if (_timeout != null)
_timeout += duration;
_timeout = _timeout! + duration;
}
@override
Future<void> delayed(Duration duration) {
assert(_currentFakeAsync != null);
addTime(duration);
_currentFakeAsync.elapse(duration);
_currentFakeAsync!.elapse(duration);
return Future<void>.value();
}
@ -1156,7 +1167,7 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
Future<void> testBody(),
VoidCallback invariantTester, {
String description = '',
Duration timeout,
Duration? timeout,
}) {
assert(description != null);
assert(!inTest);
@ -1173,7 +1184,7 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
final FakeAsync fakeAsync = FakeAsync();
_currentFakeAsync = fakeAsync; // reset in postTest
_clock = fakeAsync.getClock(DateTime.utc(2015, 1, 1));
Future<void> testBodyResult;
late Future<void> testBodyResult;
fakeAsync.run((FakeAsync localFakeAsync) {
assert(fakeAsync == _currentFakeAsync);
assert(fakeAsync == localFakeAsync);
@ -1188,6 +1199,7 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
// by calling '.then' in the current zone. While flushing the microtasks
// of the fake-zone below, the new future will be completed and can then
// be used without fakeAsync.
final Future<void> resultFuture = testBodyResult.then<void>((_) {
// Do nothing.
});
@ -1195,7 +1207,7 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
// Resolve interplay between fake async and real async calls.
fakeAsync.flushMicrotasks();
while (_pendingAsyncTasks != null) {
await _pendingAsyncTasks.future;
await _pendingAsyncTasks!.future;
fakeAsync.flushMicrotasks();
}
return resultFuture;
@ -1205,7 +1217,7 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
@override
void asyncBarrier() {
assert(_currentFakeAsync != null);
_currentFakeAsync.flushMicrotasks();
_currentFakeAsync!.flushMicrotasks();
super.asyncBarrier();
}
@ -1213,11 +1225,13 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
void _verifyInvariants() {
super._verifyInvariants();
assert(inTest);
bool timersPending = false;
if (_currentFakeAsync.periodicTimerCount != 0 ||
_currentFakeAsync.nonPeriodicTimerCount != 0) {
if (_currentFakeAsync!.periodicTimerCount != 0 ||
_currentFakeAsync!.nonPeriodicTimerCount != 0) {
debugPrint('Pending timers:');
for (final FakeTimer timer in _currentFakeAsync.pendingTimers) {
for (final FakeTimer timer in _currentFakeAsync!.pendingTimers) {
debugPrint(
'Timer (duration: ${timer.duration}, '
'periodic: ${timer.isPeriodic}), created:');
@ -1227,7 +1241,7 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
timersPending = true;
}
assert(!timersPending, 'A Timer is still pending even after the widget tree was disposed.');
assert(_currentFakeAsync.microtaskCount == 0); // Shouldn't be possible.
assert(_currentFakeAsync!.microtaskCount == 0); // Shouldn't be possible.
}
@override
@ -1387,7 +1401,7 @@ class LiveTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
@override
test_package.Timeout get defaultTestTimeout => test_package.Timeout.none;
Completer<void> _pendingFrame;
Completer<void>? _pendingFrame;
bool _expectingFrame = false;
bool _viewNeedsPaint = false;
bool _runningAsyncTasks = false;
@ -1430,10 +1444,10 @@ class LiveTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
super.scheduleForcedFrame();
}
bool _doDrawThisFrame;
bool? _doDrawThisFrame;
@override
void handleBeginFrame(Duration rawTimeStamp) {
void handleBeginFrame(Duration? rawTimeStamp) {
assert(_doDrawThisFrame == null);
if (_expectingFrame ||
(framePolicy == LiveTestWidgetsFlutterBindingFramePolicy.fullyLive) ||
@ -1450,13 +1464,13 @@ class LiveTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
@override
void handleDrawFrame() {
assert(_doDrawThisFrame != null);
if (_doDrawThisFrame)
if (_doDrawThisFrame!)
super.handleDrawFrame();
_doDrawThisFrame = null;
_viewNeedsPaint = false;
if (_expectingFrame) { // set during pump
assert(_pendingFrame != null);
_pendingFrame.complete(); // unlocks the test API
_pendingFrame!.complete(); // unlocks the test API
_pendingFrame = null;
_expectingFrame = false;
} else if (framePolicy != LiveTestWidgetsFlutterBindingFramePolicy.benchmark) {
@ -1489,7 +1503,7 @@ class LiveTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
/// [HitTestDispatcher.dispatchEvent] method instead.
///
/// Events dispatched by [TestGesture] are not affected by this.
HitTestDispatcher deviceEventDispatcher;
HitTestDispatcher? deviceEventDispatcher;
/// Dispatch an event to the targets found by a hit test on its position.
@ -1503,10 +1517,11 @@ class LiveTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
}) {
switch (source) {
case TestBindingEventSource.test:
if (renderView._pointers.containsKey(event.pointer)) {
renderView._pointers[event.pointer].position = event.position;
final _LiveTestPointerRecord? record = renderView._pointers[event.pointer];
if (record != null) {
record.position = event.position;
if (!event.down)
renderView._pointers[event.pointer].decay = _kPointerDecay;
record.decay = _kPointerDecay;
_handleViewNeedsPaint();
} else if (event.down) {
renderView._pointers[event.pointer] = _LiveTestPointerRecord(
@ -1525,19 +1540,21 @@ class LiveTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
}
@override
void dispatchEvent(PointerEvent event, HitTestResult hitTestResult) {
void dispatchEvent(PointerEvent event, HitTestResult? hitTestResult) {
switch (_pointerEventSource) {
case TestBindingEventSource.test:
super.dispatchEvent(event, hitTestResult);
break;
case TestBindingEventSource.device:
deviceEventDispatcher.dispatchEvent(event, hitTestResult);
assert(hitTestResult != null);
assert(deviceEventDispatcher != null);
deviceEventDispatcher!.dispatchEvent(event, hitTestResult!);
break;
}
}
@override
Future<void> pump([ Duration duration, EnginePhase newPhase = EnginePhase.sendSemanticsUpdate ]) {
Future<void> pump([ Duration? duration, EnginePhase newPhase = EnginePhase.sendSemanticsUpdate ]) {
assert(newPhase == EnginePhase.sendSemanticsUpdate);
assert(inTest);
assert(!_expectingFrame);
@ -1557,12 +1574,12 @@ class LiveTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
scheduleFrame();
}
_pendingFrame = Completer<void>();
return _pendingFrame.future;
return _pendingFrame!.future;
});
}
@override
Future<T> runAsync<T>(
Future<T?> runAsync<T>(
Future<T> callback(), {
Duration additionalTime = const Duration(milliseconds: 1000),
}) async {
@ -1596,7 +1613,7 @@ class LiveTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
}
@override
Future<void> runTest(Future<void> testBody(), VoidCallback invariantTester, { String description = '', Duration timeout }) async {
Future<void> runTest(Future<void> testBody(), VoidCallback invariantTester, { String description = '', Duration? timeout }) async {
assert(description != null);
assert(!inTest);
_inTest = true;
@ -1664,7 +1681,7 @@ class TestViewConfiguration extends ViewConfiguration {
/// If a [window] instance is not provided it defaults to [ui.window].
factory TestViewConfiguration({
Size size = _kDefaultTestViewportSize,
ui.Window window,
ui.Window? window,
}) {
return TestViewConfiguration._(size, window ?? ui.window);
}
@ -1734,9 +1751,9 @@ class _LiveTestPointerRecord {
class _LiveTestRenderView extends RenderView {
_LiveTestRenderView({
ViewConfiguration configuration,
this.onNeedPaint,
@required ui.Window window,
required ViewConfiguration configuration,
required this.onNeedPaint,
required ui.Window window,
}) : super(configuration: configuration, window: window);
@override
@ -1748,7 +1765,7 @@ class _LiveTestRenderView extends RenderView {
final Map<int, _LiveTestPointerRecord> _pointers = <int, _LiveTestPointerRecord>{};
TextPainter _label;
TextPainter? _label;
static const TextStyle _labelStyle = TextStyle(
fontFamily: 'sans-serif',
fontSize: 10.0,
@ -1761,14 +1778,14 @@ class _LiveTestRenderView extends RenderView {
}
// TODO(ianh): Figure out if the test name is actually RTL.
_label ??= TextPainter(textAlign: TextAlign.left, textDirection: TextDirection.ltr);
_label.text = TextSpan(text: value, style: _labelStyle);
_label.layout();
_label!.text = TextSpan(text: value, style: _labelStyle);
_label!.layout();
if (onNeedPaint != null)
onNeedPaint();
}
@override
bool hitTest(HitTestResult result, { Offset position }) {
bool hitTest(HitTestResult result, { required Offset position }) {
final Matrix4 transform = configuration.toHitTestMatrix();
final double det = transform.invert();
assert(det != 0.0);
@ -1794,7 +1811,7 @@ class _LiveTestRenderView extends RenderView {
..style = PaintingStyle.stroke;
bool dirty = false;
for (final int pointer in _pointers.keys) {
final _LiveTestPointerRecord record = _pointers[pointer];
final _LiveTestPointerRecord record = _pointers[pointer]!;
paint.color = record.color.withOpacity(record.decay < 0 ? (record.decay / (_kPointerDecay - 1)) : 1.0);
canvas.drawPath(path.shift(record.position), paint);
if (record.decay < 0)
@ -1803,7 +1820,7 @@ class _LiveTestRenderView extends RenderView {
}
_pointers
.keys
.where((int pointer) => _pointers[pointer].decay == 0)
.where((int pointer) => _pointers[pointer]!.decay == 0)
.toList()
.forEach(_pointers.remove);
if (dirty && onNeedPaint != null)

View File

@ -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);
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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)';

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -7,7 +7,6 @@ import 'dart:typed_data';
import 'dart:ui' as ui;
import 'dart:ui';
import 'package:meta/meta.dart';
// ignore: deprecated_member_use
import 'package:test_api/test_api.dart' hide TypeMatcher, isInstanceOf;
// ignore: deprecated_member_use
@ -15,7 +14,8 @@ import 'package:test_api/test_api.dart' as test_package show TypeMatcher;
import 'package:test_api/src/frontend/async_matcher.dart'; // ignore: implementation_imports
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/material.dart' show Card;
import 'package:flutter/widgets.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
@ -284,7 +284,7 @@ Matcher equalsIgnoringHashCodes(String value) {
/// method [name] and [arguments].
///
/// Arguments checking implements deep equality for [List] and [Map] types.
Matcher isMethodCall(String name, { @required dynamic arguments }) {
Matcher isMethodCall(String name, { required dynamic arguments }) {
return _IsMethodCall(name, arguments);
}
@ -297,7 +297,7 @@ Matcher isMethodCall(String name, { @required dynamic arguments }) {
/// When using this matcher you typically want to use a rectangle larger than
/// the area you expect to paint in for [areaToCompare] to catch errors where
/// the path draws outside the expected area.
Matcher coversSameAreaAs(Path expectedPath, { @required Rect areaToCompare, int sampleSize = 20 })
Matcher coversSameAreaAs(Path expectedPath, { required Rect areaToCompare, int sampleSize = 20 })
=> _CoversSameAreaAs(expectedPath, areaToCompare: areaToCompare, sampleSize: sampleSize);
/// Asserts that a [Finder], [Future<ui.Image>], or [ui.Image] matches the
@ -364,7 +364,7 @@ Matcher coversSameAreaAs(Path expectedPath, { @required Rect areaToCompare, int
/// verify that two different code paths create identical images.
/// * [flutter_test] for a discussion of test configurations, whereby callers
/// may swap out the backend for this matcher.
AsyncMatcher matchesGoldenFile(dynamic key, {int version}) {
AsyncMatcher matchesGoldenFile(Object key, {int? version}) {
if (key is Uri) {
return MatchesGoldenFile(key, version);
} else if (key is String) {
@ -431,19 +431,19 @@ AsyncMatcher matchesReferenceImage(ui.Image image) {
///
/// * [WidgetTester.getSemantics], the tester method which retrieves semantics.
Matcher matchesSemantics({
String label,
String hint,
String value,
String increasedValue,
String decreasedValue,
TextDirection textDirection,
Rect rect,
Size size,
double elevation,
double thickness,
int platformViewId,
int maxValueLength,
int currentValueLength,
String? label,
String? hint,
String? value,
String? increasedValue,
String? decreasedValue,
TextDirection? textDirection,
Rect? rect,
Size? size,
double? elevation,
double? thickness,
int? platformViewId,
int? maxValueLength,
int? currentValueLength,
// Flags //
bool hasCheckedState = false,
bool isChecked = false,
@ -490,10 +490,10 @@ Matcher matchesSemantics({
bool hasDidLoseAccessibilityFocusAction = false,
bool hasDismissAction = false,
// Custom actions and overrides
String onTapHint,
String onLongPressHint,
List<CustomSemanticsAction> customActions,
List<Matcher> children,
String? onTapHint,
String? onLongPressHint,
List<CustomSemanticsAction>? customActions,
List<Matcher>? children,
}) {
final List<SemanticsFlag> flags = <SemanticsFlag>[
if (hasCheckedState) SemanticsFlag.hasCheckedState,
@ -544,7 +544,7 @@ Matcher matchesSemantics({
if (hasMoveCursorForwardByWordAction) SemanticsAction.moveCursorForwardByWord,
if (hasMoveCursorBackwardByWordAction) SemanticsAction.moveCursorBackwardByWord,
];
SemanticsHintOverrides hintOverrides;
SemanticsHintOverrides? hintOverrides;
if (onTapHint != null || onLongPressHint != null)
hintOverrides = SemanticsHintOverrides(
onTapHint: onTapHint,
@ -607,26 +607,26 @@ AsyncMatcher doesNotMeetGuideline(AccessibilityGuideline guideline) {
class _FindsWidgetMatcher extends Matcher {
const _FindsWidgetMatcher(this.min, this.max);
final int min;
final int max;
final int? min;
final int? max;
@override
bool matches(covariant Finder finder, Map<dynamic, dynamic> matchState) {
assert(min != null || max != null);
assert(min == null || max == null || min <= max);
assert(min == null || max == null || min! <= max!);
matchState[Finder] = finder;
int count = 0;
final Iterator<Element> iterator = finder.evaluate().iterator;
if (min != null) {
while (count < min && iterator.moveNext())
while (count < min! && iterator.moveNext())
count += 1;
if (count < min)
if (count < min!)
return false;
}
if (max != null) {
while (count <= max && iterator.moveNext())
while (count <= max! && iterator.moveNext())
count += 1;
if (count > max)
if (count > max!)
return false;
}
return true;
@ -665,7 +665,7 @@ class _FindsWidgetMatcher extends Matcher {
final Finder finder = matchState[Finder] as Finder;
final int count = finder.evaluate().length;
if (count == 0) {
assert(min != null && min > 0);
assert(min != null && min! > 0);
if (min == 1 && max == 1)
return mismatchDescription.add('means none were found but one was expected');
return mismatchDescription.add('means none were found but some were expected');
@ -675,9 +675,9 @@ class _FindsWidgetMatcher extends Matcher {
return mismatchDescription.add('means one was found but none were expected');
return mismatchDescription.add('means some were found but none were expected');
}
if (min != null && count < min)
if (min != null && count < min!)
return mismatchDescription.add('is not enough');
assert(max != null && count > min);
assert(max != null && count > min!);
return mismatchDescription.add('is too many');
}
}
@ -765,7 +765,7 @@ class _HasOneLineDescription extends Matcher {
const _HasOneLineDescription();
@override
bool matches(Object object, Map<dynamic, dynamic> matchState) {
bool matches(dynamic object, Map<dynamic, dynamic> matchState) {
final String description = object.toString();
return description.isNotEmpty
&& !description.contains('\n')
@ -975,13 +975,13 @@ typedef DistanceFunction<T> = num Function(T a, T b);
///
/// This type is used to describe a collection of [DistanceFunction<T>]
/// functions which have (potentially) unrelated argument types. Since the
/// argument types of the functions may be unrelated, the only thing that the
/// type system can statically assume about them is that they accept null (since
/// all types in Dart are nullable).
/// argument types of the functions may be unrelated, their type is declared as
/// `Never`, which is the bottom type in dart to which all other types can be
/// assigned to.
///
/// Calling an instance of this type must either be done dynamically, or by
/// first casting it to a [DistanceFunction<T>] for some concrete T.
typedef AnyDistanceFunction = num Function(Null a, Null b);
typedef AnyDistanceFunction = num Function(Never a, Never b);
const Map<Type, AnyDistanceFunction> _kStandardDistanceFunctions = <Type, AnyDistanceFunction>{
Color: _maxComponentColorDistance,
@ -1060,11 +1060,11 @@ double _sizeDistance(Size a, Size b) {
/// specializes in [Rect]s and has an optional `epsilon` parameter.
/// * [closeTo], which specializes in numbers only.
Matcher within<T>({
@required num distance,
@required T from,
DistanceFunction<T> distanceFunction,
required num distance,
required T from,
DistanceFunction<T>? distanceFunction,
}) {
distanceFunction ??= _kStandardDistanceFunctions[T] as DistanceFunction<T>;
distanceFunction ??= _kStandardDistanceFunctions[T] as DistanceFunction<T>?;
if (distanceFunction == null) {
throw ArgumentError(
@ -1085,13 +1085,12 @@ class _IsWithinDistance<T> extends Matcher {
final num epsilon;
@override
bool matches(Object object, Map<dynamic, dynamic> matchState) {
bool matches(dynamic object, Map<dynamic, dynamic> matchState) {
if (object is! T)
return false;
if (object == value)
return true;
final T test = object as T;
final num distance = distanceFunction(test, value);
final num distance = distanceFunction(object, value);
if (distance < 0) {
throw ArgumentError(
'Invalid distance function was used to compare a ${value.runtimeType} '
@ -1108,7 +1107,7 @@ class _IsWithinDistance<T> extends Matcher {
@override
Description describeMismatch(
Object object,
dynamic object,
Description mismatchDescription,
Map<dynamic, dynamic> matchState,
bool verbose,
@ -1126,20 +1125,19 @@ class _MoreOrLessEquals extends Matcher {
final double epsilon;
@override
bool matches(Object object, Map<dynamic, dynamic> matchState) {
bool matches(dynamic object, Map<dynamic, dynamic> matchState) {
if (object is! double)
return false;
if (object == value)
return true;
final double test = object as double;
return (test - value).abs() <= epsilon;
return (object - value).abs() <= epsilon;
}
@override
Description describe(Description description) => description.add('$value$epsilon)');
@override
Description describeMismatch(Object item, Description mismatchDescription, Map<dynamic, dynamic> matchState, bool verbose) {
Description describeMismatch(dynamic item, Description mismatchDescription, Map<dynamic, dynamic> matchState, bool verbose) {
return super.describeMismatch(item, mismatchDescription, matchState, verbose)
..add('$item is not in the range of $value$epsilon).');
}
@ -1211,14 +1209,14 @@ const Matcher hasNoImmediateClip = _MatchAnythingExceptClip();
/// Asserts that a [Finder] locates a single object whose root RenderObject
/// is a [RenderClipRRect] with no clipper set, and border radius equals to
/// [borderRadius], or an equivalent [RenderClipPath].
Matcher clipsWithBoundingRRect({ @required BorderRadius borderRadius }) {
Matcher clipsWithBoundingRRect({ required BorderRadius borderRadius }) {
return _ClipsWithBoundingRRect(borderRadius: borderRadius);
}
/// Asserts that a [Finder] locates a single object whose root RenderObject
/// is a [RenderClipPath] with a [ShapeBorderClipper] that clips to
/// [shape].
Matcher clipsWithShapeBorder({ @required ShapeBorder shape }) {
Matcher clipsWithShapeBorder({ required ShapeBorder shape }) {
return _ClipsWithShapeBorder(shape: shape);
}
@ -1240,9 +1238,9 @@ Matcher clipsWithShapeBorder({ @required ShapeBorder shape }) {
/// - If [elevation] is non null asserts that [RenderPhysicalModel.elevation] is equal to
/// [elevation].
Matcher rendersOnPhysicalModel({
BoxShape shape,
BorderRadius borderRadius,
double elevation,
BoxShape? shape,
BorderRadius? borderRadius,
double? elevation,
}) {
return _RendersOnPhysicalModel(
shape: shape,
@ -1257,8 +1255,8 @@ Matcher rendersOnPhysicalModel({
/// If [elevation] is non null asserts that [RenderPhysicalShape.elevation] is
/// equal to [elevation].
Matcher rendersOnPhysicalShape({
ShapeBorder shape,
double elevation,
required ShapeBorder shape,
double? elevation,
}) {
return _RendersOnPhysicalShape(
shape: shape,
@ -1293,7 +1291,7 @@ class _MatchAnythingExceptClip extends _FailWithDescriptionMatcher {
final Iterable<Element> nodes = finder.evaluate();
if (nodes.length != 1)
return failWithDescription(matchState, 'did not have a exactly one child element');
final RenderObject renderObject = nodes.single.renderObject;
final RenderObject renderObject = nodes.single.renderObject!;
switch (renderObject.runtimeType) {
case RenderClipPath:
@ -1323,7 +1321,7 @@ abstract class _MatchRenderObject<M extends RenderObject, T extends RenderObject
final Iterable<Element> nodes = finder.evaluate();
if (nodes.length != 1)
return failWithDescription(matchState, 'did not have a exactly one child element');
final RenderObject renderObject = nodes.single.renderObject;
final RenderObject renderObject = nodes.single.renderObject!;
if (renderObject.runtimeType == T)
return renderObjectMatchesT(matchState, renderObject as T);
@ -1342,9 +1340,9 @@ class _RendersOnPhysicalModel extends _MatchRenderObject<RenderPhysicalShape, Re
this.elevation,
});
final BoxShape shape;
final BorderRadius borderRadius;
final double elevation;
final BoxShape? shape;
final BorderRadius? borderRadius;
final double? elevation;
@override
bool renderObjectMatchesT(Map<dynamic, dynamic> matchState, RenderPhysicalModel renderObject) {
@ -1366,7 +1364,7 @@ class _RendersOnPhysicalModel extends _MatchRenderObject<RenderPhysicalShape, Re
return failWithDescription(matchState, 'clipper was: ${renderObject.clipper}');
final ShapeBorderClipper shapeClipper = renderObject.clipper as ShapeBorderClipper;
if (borderRadius != null && !assertRoundedRectangle(shapeClipper, borderRadius, matchState))
if (borderRadius != null && !assertRoundedRectangle(shapeClipper, borderRadius!, matchState))
return false;
if (
@ -1421,12 +1419,12 @@ class _RendersOnPhysicalModel extends _MatchRenderObject<RenderPhysicalShape, Re
class _RendersOnPhysicalShape extends _MatchRenderObject<RenderPhysicalShape, RenderPhysicalModel> {
const _RendersOnPhysicalShape({
this.shape,
required this.shape,
this.elevation,
});
final ShapeBorder shape;
final double elevation;
final double? elevation;
@override
bool renderObjectMatchesM(Map<dynamic, dynamic> matchState, RenderPhysicalShape renderObject) {
@ -1486,7 +1484,7 @@ class _ClipsWithBoundingRect extends _MatchRenderObject<RenderClipPath, RenderCl
}
class _ClipsWithBoundingRRect extends _MatchRenderObject<RenderClipPath, RenderClipRRect> {
const _ClipsWithBoundingRRect({@required this.borderRadius});
const _ClipsWithBoundingRRect({required this.borderRadius});
final BorderRadius borderRadius;
@ -1521,7 +1519,7 @@ class _ClipsWithBoundingRRect extends _MatchRenderObject<RenderClipPath, RenderC
}
class _ClipsWithShapeBorder extends _MatchRenderObject<RenderClipPath, RenderClipRRect> {
const _ClipsWithShapeBorder({@required this.shape});
const _ClipsWithShapeBorder({required this.shape});
final ShapeBorder shape;
@ -1549,7 +1547,7 @@ class _ClipsWithShapeBorder extends _MatchRenderObject<RenderClipPath, RenderCli
class _CoversSameAreaAs extends Matcher {
_CoversSameAreaAs(
this.expectedPath, {
@required this.areaToCompare,
required this.areaToCompare,
this.sampleSize = 20,
}) : maxHorizontalNoise = areaToCompare.width / sampleSize,
maxVerticalNoise = areaToCompare.height / sampleSize {
@ -1562,7 +1560,7 @@ class _CoversSameAreaAs extends Matcher {
final int sampleSize;
final double maxHorizontalNoise;
final double maxVerticalNoise;
math.Random random;
late math.Random random;
@override
bool matches(covariant Path actualPath, Map<dynamic, dynamic> matchState) {
@ -1620,7 +1618,7 @@ class _CoversSameAreaAs extends Matcher {
class _ColorMatcher extends Matcher {
const _ColorMatcher({
@required this.targetColor,
required this.targetColor,
}) : assert(targetColor != null);
final Color targetColor;
@ -1656,7 +1654,7 @@ class _MatchesReferenceImage extends AsyncMatcher {
final ui.Image referenceImage;
@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;
@ -1674,13 +1672,13 @@ class _MatchesReferenceImage extends AsyncMatcher {
}
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();
final ByteData? bytes = await image.toByteData();
if (bytes == null)
return 'could not be encoded.';
final ByteData referenceBytes = await referenceImage.toByteData();
final ByteData? referenceBytes = await referenceImage.toByteData();
if (referenceBytes == null)
return 'could not have its reference image encoded.';
@ -1723,24 +1721,24 @@ class _MatchesSemanticsData extends Matcher {
this.children,
});
final String label;
final String value;
final String hint;
final String increasedValue;
final String decreasedValue;
final SemanticsHintOverrides hintOverrides;
final List<SemanticsAction> actions;
final List<CustomSemanticsAction> customActions;
final List<SemanticsFlag> flags;
final TextDirection textDirection;
final Rect rect;
final Size size;
final double elevation;
final double thickness;
final int platformViewId;
final int maxValueLength;
final int currentValueLength;
final List<Matcher> children;
final String? label;
final String? value;
final String? hint;
final String? increasedValue;
final String? decreasedValue;
final SemanticsHintOverrides? hintOverrides;
final List<SemanticsAction>? actions;
final List<CustomSemanticsAction>? customActions;
final List<SemanticsFlag>? flags;
final TextDirection? textDirection;
final Rect? rect;
final Size? size;
final double? elevation;
final double? thickness;
final int? platformViewId;
final int? maxValueLength;
final int? currentValueLength;
final List<Matcher>? children;
@override
Description describe(Description description) {
@ -1781,7 +1779,7 @@ class _MatchesSemanticsData extends Matcher {
description.add(' with custom hints: $hintOverrides');
if (children != null) {
description.add(' with children:\n');
for (final _MatchesSemanticsData child in children.cast<_MatchesSemanticsData>())
for (final _MatchesSemanticsData child in children!.cast<_MatchesSemanticsData>())
child.describe(description);
}
return description;
@ -1823,7 +1821,7 @@ class _MatchesSemanticsData extends Matcher {
return failWithDescription(matchState, 'maxValueLength was: ${data.maxValueLength}');
if (actions != null) {
int actionBits = 0;
for (final SemanticsAction action in actions)
for (final SemanticsAction action in actions!)
actionBits |= action.index;
if (actionBits != data.actions) {
final List<String> actionSummary = <String>[
@ -1835,14 +1833,14 @@ class _MatchesSemanticsData extends Matcher {
}
}
if (customActions != null || hintOverrides != null) {
final List<CustomSemanticsAction> providedCustomActions = data.customSemanticsActionIds.map((int id) {
return CustomSemanticsAction.getAction(id);
}).toList();
final List<CustomSemanticsAction> providedCustomActions = data.customSemanticsActionIds?.map<CustomSemanticsAction>((int id) {
return CustomSemanticsAction.getAction(id)!;
}).toList() ?? <CustomSemanticsAction>[];
final List<CustomSemanticsAction> expectedCustomActions = customActions?.toList() ?? <CustomSemanticsAction>[];
if (hintOverrides?.onTapHint != null)
expectedCustomActions.add(CustomSemanticsAction.overridingAction(hint: hintOverrides.onTapHint, action: SemanticsAction.tap));
expectedCustomActions.add(CustomSemanticsAction.overridingAction(hint: hintOverrides!.onTapHint!, action: SemanticsAction.tap));
if (hintOverrides?.onLongPressHint != null)
expectedCustomActions.add(CustomSemanticsAction.overridingAction(hint: hintOverrides.onLongPressHint, action: SemanticsAction.longPress));
expectedCustomActions.add(CustomSemanticsAction.overridingAction(hint: hintOverrides!.onLongPressHint!, action: SemanticsAction.longPress));
if (expectedCustomActions.length != providedCustomActions.length)
return failWithDescription(matchState, 'custom actions where: $providedCustomActions');
int sortActions(CustomSemanticsAction left, CustomSemanticsAction right) {
@ -1857,7 +1855,7 @@ class _MatchesSemanticsData extends Matcher {
}
if (flags != null) {
int flagBits = 0;
for (final SemanticsFlag flag in flags)
for (final SemanticsFlag flag in flags!)
flagBits |= flag.index;
if (flagBits != data.flags) {
final List<String> flagSummary = <String>[
@ -1872,7 +1870,7 @@ class _MatchesSemanticsData extends Matcher {
if (children != null) {
int i = 0;
node.visitChildren((SemanticsNode child) {
allMatched = children[i].matches(child, matchState) && allMatched;
allMatched = children![i].matches(child, matchState) && allMatched;
i += 1;
return allMatched;
});
@ -1907,7 +1905,7 @@ class _MatchesAccessibilityGuideline extends AsyncMatcher {
}
@override
Future<String> matchAsync(covariant WidgetTester tester) async {
Future<String?> matchAsync(covariant WidgetTester tester) async {
final Evaluation result = await guideline.evaluate(tester);
if (result.passed)
return null;
@ -1926,7 +1924,7 @@ class _DoesNotMatchAccessibilityGuideline extends AsyncMatcher {
}
@override
Future<String> matchAsync(covariant WidgetTester tester) async {
Future<String?> matchAsync(covariant WidgetTester tester) async {
final Evaluation result = await guideline.evaluate(tester);
if (result.passed)
return 'Failed';

View File

@ -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;
}

View File

@ -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(

View File

@ -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;
}

View File

@ -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';

View File

@ -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.

View File

@ -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();

View File

@ -5,7 +5,7 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/material.dart' show Tooltip;
import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
@ -110,10 +110,10 @@ void testWidgets(
String description,
WidgetTesterCallback callback, {
bool skip = false,
test_package.Timeout timeout,
Duration initialTimeout,
test_package.Timeout? timeout,
Duration? initialTimeout,
bool semanticsEnabled = true,
TestVariant<Object> variant = const DefaultTestVariant(),
TestVariant<Object?> variant = const DefaultTestVariant(),
dynamic tags,
}) {
assert(variant != null);
@ -127,7 +127,7 @@ void testWidgets(
combinedDescription,
() {
tester._testDescription = combinedDescription;
SemanticsHandle semanticsHandle;
SemanticsHandle? semanticsHandle;
if (semanticsEnabled == true) {
semanticsHandle = tester.ensureSemantics();
}
@ -138,7 +138,7 @@ void testWidgets(
binding.reset();
debugResetSemanticsIdCounter();
tester.resetTestTextInput();
Object memento;
Object? memento;
try {
memento = await variant.setUp(value);
await callback(tester);
@ -148,7 +148,7 @@ void testWidgets(
semanticsHandle?.dispose();
},
tester._endOfTestVerifications,
description: combinedDescription ?? '',
description: combinedDescription,
timeout: initialTimeout,
);
},
@ -187,7 +187,7 @@ abstract class TestVariant<T> {
/// environment back to its base state when [tearDown] is called in the
/// `Object` that is returned. The returned object will then be passed to
/// [tearDown] as a `memento` when the test is complete.
Future<Object> setUp(T value);
Future<Object?> setUp(T value);
/// A function that is guaranteed to be called after a value is tested, even
/// if it throws an exception.
@ -195,7 +195,7 @@ abstract class TestVariant<T> {
/// Calling this function must return the testing environment back to the base
/// state it was in before [setUp] was called. The [memento] is the object
/// returned from [setUp] when it was called.
Future<void> tearDown(T value, covariant Object memento);
Future<void> tearDown(T value, covariant Object? memento);
}
/// The [TestVariant] that represents the "default" test that is run if no
@ -257,14 +257,14 @@ class TargetPlatformVariant extends TestVariant<TargetPlatform> {
String describeValue(TargetPlatform value) => value.toString();
@override
Future<TargetPlatform> setUp(TargetPlatform value) async {
final TargetPlatform previousTargetPlatform = debugDefaultTargetPlatformOverride;
Future<TargetPlatform?> setUp(TargetPlatform value) async {
final TargetPlatform? previousTargetPlatform = debugDefaultTargetPlatformOverride;
debugDefaultTargetPlatformOverride = value;
return previousTargetPlatform;
}
@override
Future<void> tearDown(TargetPlatform value, TargetPlatform memento) async {
Future<void> tearDown(TargetPlatform value, TargetPlatform? memento) async {
debugDefaultTargetPlatformOverride = memento;
}
}
@ -308,8 +308,8 @@ class ValueVariant<T> extends TestVariant<T> {
ValueVariant(this.values);
/// Returns the value currently under test.
T get currentValue => _currentValue;
T _currentValue;
T? get currentValue => _currentValue;
T? _currentValue;
@override
final Set<T> values;
@ -396,7 +396,7 @@ Future<void> benchmarkWidgets(
final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized() as TestWidgetsFlutterBinding;
assert(binding is! AutomatedTestWidgetsFlutterBinding);
final WidgetTester tester = WidgetTester._(binding);
SemanticsHandle semanticsHandle;
SemanticsHandle? semanticsHandle;
if (semanticsEnabled == true) {
semanticsHandle = tester.ensureSemantics();
}
@ -407,7 +407,7 @@ Future<void> benchmarkWidgets(
semanticsHandle?.dispose();
},
tester._endOfTestVerifications,
) ?? Future<void>.value();
);
}
/// Assert that `actual` matches `matcher`.
@ -422,7 +422,7 @@ Future<void> benchmarkWidgets(
void expect(
dynamic actual,
dynamic matcher, {
String reason,
String? reason,
dynamic skip, // true or a String
}) {
TestAsyncUtils.guardSync();
@ -441,7 +441,7 @@ void expect(
void expectSync(
dynamic actual,
dynamic matcher, {
String reason,
String? reason,
}) {
test_package.expect(actual, matcher, reason: reason);
}
@ -457,7 +457,7 @@ void expectSync(
Future<void> expectLater(
dynamic actual,
dynamic matcher, {
String reason,
String? reason,
dynamic skip, // true or a String
}) {
// We can't wrap the delegate in a guard, or we'll hit async barriers in
@ -513,7 +513,7 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker
/// this method works when the test is run with `flutter run`.
Future<void> pumpWidget(
Widget widget, [
Duration duration,
Duration? duration,
EnginePhase phase = EnginePhase.sendSemanticsUpdate,
]) {
return TestAsyncUtils.guard<void>(() {
@ -529,7 +529,7 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker
assert(records.isNotEmpty);
return TestAsyncUtils.guard<List<Duration>>(() async {
final List<Duration> handleTimeStampDiff = <Duration>[];
DateTime startTime;
DateTime? startTime;
for (final PointerEventRecord record in records) {
final DateTime now = binding.clock.now();
startTime ??= now;
@ -576,7 +576,7 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker
/// this method works when the test is run with `flutter run`.
@override
Future<void> pump([
Duration duration,
Duration? duration,
EnginePhase phase = EnginePhase.sendSemanticsUpdate,
]) {
return TestAsyncUtils.guard<void>(() => binding.pump(duration, phase));
@ -606,7 +606,7 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker
await idle();
if (caughtException != null) {
throw caughtException;
throw caughtException as Object;
}
}
@ -681,7 +681,7 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker
'therefore no restoration data has been collected to restore from. Did you forget to wrap '
'your widget tree in a RootRestorationScope?',
);
final Widget widget = (binding.renderViewElement as RenderObjectToWidgetElement<RenderObject>).widget.child;
final Widget widget = (binding.renderViewElement as RenderObjectToWidgetElement<RenderObject>).widget.child!;
final TestRestorationData restorationData = binding.restorationManager.restorationData;
runApp(Container(key: UniqueKey()));
await pump();
@ -746,10 +746,10 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker
///
/// * Expose a [Future] in your application code that signals the readiness of
/// your widget tree, then await that future inside [callback].
Future<T> runAsync<T>(
Future<T?> runAsync<T>(
Future<T> callback(), {
Duration additionalTime = const Duration(milliseconds: 1000),
}) => binding.runAsync<T>(callback, additionalTime: additionalTime);
}) => binding.runAsync<T?>(callback, additionalTime: additionalTime);
/// Whether there are any any transient callbacks scheduled.
///
@ -789,11 +789,11 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker
.map((HitTestEntry candidate) => candidate.target)
.whereType<RenderObject>()
.first;
final Element innerTargetElement = collectAllElementsFrom(
binding.renderViewElement,
final Element? innerTargetElement = collectAllElementsFrom(
binding.renderViewElement!,
skipOffstage: true,
).lastWhere(
(Element element) => element.renderObject == innerTarget,
).cast<Element?>().lastWhere(
(Element? element) => element!.renderObject == innerTarget,
orElse: () => null,
);
if (innerTargetElement == null) {
@ -806,7 +806,7 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker
return true;
});
assert(candidates.isNotEmpty);
String descendantText;
String? descendantText;
int numberOfWithTexts = 0;
int numberOfTypes = 0;
int totalNumber = 0;
@ -827,17 +827,19 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker
if (widget is Text) {
assert(descendantText == null);
final Iterable<Element> matches = find.text(widget.data).evaluate();
assert(widget.data != null || widget.textSpan != null);
final String text = widget.data ?? widget.textSpan!.toPlainText();
final Iterable<Element> matches = find.text(text).evaluate();
descendantText = widget.data;
if (matches.length == 1) {
debugPrint(" find.text('${widget.data}')");
debugPrint(" find.text('$text')");
continue;
}
}
final Key key = widget.key;
final Key? key = widget.key;
if (key is ValueKey<dynamic>) {
String keyLabel;
String? keyLabel;
if (key is ValueKey<int> ||
key is ValueKey<double> ||
key is ValueKey<bool>) {
@ -912,20 +914,20 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker
return TestAsyncUtils.guard<void>(() => binding.idle());
}
Set<Ticker> _tickers;
Set<Ticker>? _tickers;
@override
Ticker createTicker(TickerCallback onTick) {
_tickers ??= <_TestTicker>{};
final _TestTicker result = _TestTicker(onTick, _removeTicker);
_tickers.add(result);
_tickers!.add(result);
return result;
}
void _removeTicker(_TestTicker ticker) {
assert(_tickers != null);
assert(_tickers.contains(ticker));
_tickers.remove(ticker);
assert(_tickers!.contains(ticker));
_tickers!.remove(ticker);
}
/// Throws an exception if any tickers created by the [WidgetTester] are still
@ -937,7 +939,7 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker
void verifyTickersWereDisposed([ String when = 'when none should have been' ]) {
assert(when != null);
if (_tickers != null) {
for (final Ticker ticker in _tickers) {
for (final Ticker ticker in _tickers!) {
if (ticker.isActive) {
throw FlutterError.fromParts(<DiagnosticsNode>[
ErrorSummary('A Ticker was active $when.'),
@ -961,7 +963,7 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker
void _verifySemanticsHandlesWereDisposed() {
assert(_lastRecordedSemanticsHandles != null);
if (binding.pipelineOwner.debugOutstandingSemanticsHandles > _lastRecordedSemanticsHandles) {
if (binding.pipelineOwner.debugOutstandingSemanticsHandles > _lastRecordedSemanticsHandles!) {
throw FlutterError.fromParts(<DiagnosticsNode>[
ErrorSummary('A SemanticsHandle was active at the end of the test.'),
ErrorDescription(
@ -978,7 +980,7 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker
_lastRecordedSemanticsHandles = null;
}
int _lastRecordedSemanticsHandles;
int? _lastRecordedSemanticsHandles;
void _recordNumberOfSemanticsHandles() {
_lastRecordedSemanticsHandles = binding.pipelineOwner.debugOutstandingSemanticsHandles;

View File

@ -5,8 +5,6 @@
import 'dart:typed_data' show ByteData;
import 'dart:ui' hide window;
import 'package:meta/meta.dart';
/// [Window] that wraps another [Window] and allows faking of some properties
/// for testing purposes.
///
@ -48,7 +46,7 @@ class TestWindow implements Window {
/// Constructs a [TestWindow] that defers all behavior to the given [Window]
/// unless explicitly overridden for test purposes.
TestWindow({
@required Window window,
required Window window,
}) : _window = window;
/// The [Window] that is wrapped by this [TestWindow].
@ -56,135 +54,135 @@ class TestWindow implements Window {
@override
double get devicePixelRatio => _devicePixelRatio ?? _window.devicePixelRatio;
double _devicePixelRatio;
double? _devicePixelRatio;
/// Hides the real device pixel ratio and reports the given [devicePixelRatio]
/// instead.
set devicePixelRatioTestValue(double devicePixelRatio) {
_devicePixelRatio = devicePixelRatio;
onMetricsChanged();
onMetricsChanged?.call();
}
/// Deletes any existing test device pixel ratio and returns to using the real
/// device pixel ratio.
void clearDevicePixelRatioTestValue() {
_devicePixelRatio = null;
onMetricsChanged();
onMetricsChanged?.call();
}
@override
Size get physicalSize => _physicalSizeTestValue ?? _window.physicalSize;
Size _physicalSizeTestValue;
Size? _physicalSizeTestValue;
/// Hides the real physical size and reports the given [physicalSizeTestValue]
/// instead.
set physicalSizeTestValue (Size physicalSizeTestValue) {
_physicalSizeTestValue = physicalSizeTestValue;
onMetricsChanged();
onMetricsChanged?.call();
}
/// Deletes any existing test physical size and returns to using the real
/// physical size.
void clearPhysicalSizeTestValue() {
_physicalSizeTestValue = null;
onMetricsChanged();
onMetricsChanged?.call();
}
@override
WindowPadding get viewInsets => _viewInsetsTestValue ?? _window.viewInsets;
WindowPadding _viewInsetsTestValue;
WindowPadding? _viewInsetsTestValue;
/// Hides the real view insets and reports the given [viewInsetsTestValue]
/// instead.
set viewInsetsTestValue(WindowPadding viewInsetsTestValue) {
_viewInsetsTestValue = viewInsetsTestValue;
onMetricsChanged();
onMetricsChanged?.call();
}
/// Deletes any existing test view insets and returns to using the real view
/// insets.
void clearViewInsetsTestValue() {
_viewInsetsTestValue = null;
onMetricsChanged();
onMetricsChanged?.call();
}
@override
WindowPadding get viewPadding => _viewPaddingTestValue ?? _window.padding;
WindowPadding _viewPaddingTestValue;
WindowPadding? _viewPaddingTestValue;
/// Hides the real view padding and reports the given [paddingTestValue]
/// instead.
set viewPaddingTestValue(WindowPadding viewPaddingTestValue) {
_viewPaddingTestValue = viewPaddingTestValue;
onMetricsChanged();
onMetricsChanged?.call();
}
/// Deletes any existing test view padding and returns to using the real
/// viewPadding.
void clearViewPaddingTestValue() {
_viewPaddingTestValue = null;
onMetricsChanged();
onMetricsChanged?.call();
}
@override
WindowPadding get padding => _paddingTestValue ?? _window.padding;
WindowPadding _paddingTestValue;
WindowPadding? _paddingTestValue;
/// Hides the real padding and reports the given [paddingTestValue] instead.
set paddingTestValue(WindowPadding paddingTestValue) {
_paddingTestValue = paddingTestValue;
onMetricsChanged();
onMetricsChanged?.call();
}
/// Deletes any existing test padding and returns to using the real padding.
void clearPaddingTestValue() {
_paddingTestValue = null;
onMetricsChanged();
onMetricsChanged?.call();
}
@override
WindowPadding get systemGestureInsets => _systemGestureInsetsTestValue ?? _window.systemGestureInsets;
WindowPadding _systemGestureInsetsTestValue;
WindowPadding? _systemGestureInsetsTestValue;
/// Hides the real system gesture insets and reports the given [systemGestureInsetsTestValue] instead.
set systemGestureInsetsTestValue(WindowPadding systemGestureInsetsTestValue) {
_systemGestureInsetsTestValue = systemGestureInsetsTestValue;
onMetricsChanged();
onMetricsChanged?.call();
}
/// Deletes any existing test system gesture insets and returns to using the real system gesture insets.
void clearSystemGestureInsetsTestValue() {
_systemGestureInsetsTestValue = null;
onMetricsChanged();
onMetricsChanged?.call();
}
@override
VoidCallback get onMetricsChanged => _window.onMetricsChanged;
VoidCallback? get onMetricsChanged => _window.onMetricsChanged;
@override
set onMetricsChanged(VoidCallback callback) {
set onMetricsChanged(VoidCallback? callback) {
_window.onMetricsChanged = callback;
}
@override
Locale get locale => _localeTestValue ?? _window.locale;
Locale _localeTestValue;
Locale? get locale => _localeTestValue ?? _window.locale;
Locale? _localeTestValue;
/// Hides the real locale and reports the given [localeTestValue] instead.
set localeTestValue(Locale localeTestValue) {
_localeTestValue = localeTestValue;
onLocaleChanged();
onLocaleChanged?.call();
}
/// Deletes any existing test locale and returns to using the real locale.
void clearLocaleTestValue() {
_localeTestValue = null;
onLocaleChanged();
onLocaleChanged?.call();
}
@override
List<Locale> get locales => _localesTestValue ?? _window.locales;
List<Locale> _localesTestValue;
List<Locale>? get locales => _localesTestValue ?? _window.locales;
List<Locale>? _localesTestValue;
/// Hides the real locales and reports the given [localesTestValue] instead.
set localesTestValue(List<Locale> localesTestValue) {
_localesTestValue = localesTestValue;
onLocaleChanged();
onLocaleChanged?.call();
}
/// Deletes any existing test locales and returns to using the real locales.
void clearLocalesTestValue() {
_localesTestValue = null;
onLocaleChanged();
onLocaleChanged?.call();
}
@override
VoidCallback get onLocaleChanged => _window.onLocaleChanged;
VoidCallback? get onLocaleChanged => _window.onLocaleChanged;
@override
set onLocaleChanged(VoidCallback callback) {
set onLocaleChanged(VoidCallback? callback) {
_window.onLocaleChanged = callback;
}
@ -198,45 +196,45 @@ class TestWindow implements Window {
@override
double get textScaleFactor => _textScaleFactorTestValue ?? _window.textScaleFactor;
double _textScaleFactorTestValue;
double? _textScaleFactorTestValue;
/// Hides the real text scale factor and reports the given
/// [textScaleFactorTestValue] instead.
set textScaleFactorTestValue(double textScaleFactorTestValue) {
_textScaleFactorTestValue = textScaleFactorTestValue;
onTextScaleFactorChanged();
onTextScaleFactorChanged?.call();
}
/// Deletes any existing test text scale factor and returns to using the real
/// text scale factor.
void clearTextScaleFactorTestValue() {
_textScaleFactorTestValue = null;
onTextScaleFactorChanged();
onTextScaleFactorChanged?.call();
}
@override
Brightness get platformBrightness => _platformBrightnessTestValue ?? _window.platformBrightness;
Brightness _platformBrightnessTestValue;
Brightness? _platformBrightnessTestValue;
@override
VoidCallback get onPlatformBrightnessChanged => _window.onPlatformBrightnessChanged;
VoidCallback? get onPlatformBrightnessChanged => _window.onPlatformBrightnessChanged;
@override
set onPlatformBrightnessChanged(VoidCallback callback) {
set onPlatformBrightnessChanged(VoidCallback? callback) {
_window.onPlatformBrightnessChanged = callback;
}
/// Hides the real text scale factor and reports the given
/// [platformBrightnessTestValue] instead.
set platformBrightnessTestValue(Brightness platformBrightnessTestValue) {
_platformBrightnessTestValue = platformBrightnessTestValue;
onPlatformBrightnessChanged();
onPlatformBrightnessChanged?.call();
}
/// Deletes any existing test platform brightness and returns to using the
/// real platform brightness.
void clearPlatformBrightnessTestValue() {
_platformBrightnessTestValue = null;
onPlatformBrightnessChanged();
onPlatformBrightnessChanged?.call();
}
@override
bool get alwaysUse24HourFormat => _alwaysUse24HourFormatTestValue ?? _window.alwaysUse24HourFormat;
bool _alwaysUse24HourFormatTestValue;
bool? _alwaysUse24HourFormatTestValue;
/// Hides the real clock format and reports the given
/// [alwaysUse24HourFormatTestValue] instead.
set alwaysUse24HourFormatTestValue(bool alwaysUse24HourFormatTestValue) {
@ -249,43 +247,43 @@ class TestWindow implements Window {
}
@override
VoidCallback get onTextScaleFactorChanged => _window.onTextScaleFactorChanged;
VoidCallback? get onTextScaleFactorChanged => _window.onTextScaleFactorChanged;
@override
set onTextScaleFactorChanged(VoidCallback callback) {
set onTextScaleFactorChanged(VoidCallback? callback) {
_window.onTextScaleFactorChanged = callback;
}
@override
FrameCallback get onBeginFrame => _window.onBeginFrame;
FrameCallback? get onBeginFrame => _window.onBeginFrame;
@override
set onBeginFrame(FrameCallback callback) {
set onBeginFrame(FrameCallback? callback) {
_window.onBeginFrame = callback;
}
@override
VoidCallback get onDrawFrame => _window.onDrawFrame;
VoidCallback? get onDrawFrame => _window.onDrawFrame;
@override
set onDrawFrame(VoidCallback callback) {
set onDrawFrame(VoidCallback? callback) {
_window.onDrawFrame = callback;
}
@override
TimingsCallback get onReportTimings => _window.onReportTimings;
TimingsCallback? get onReportTimings => _window.onReportTimings;
@override
set onReportTimings(TimingsCallback callback) {
set onReportTimings(TimingsCallback? callback) {
_window.onReportTimings = callback;
}
@override
PointerDataPacketCallback get onPointerDataPacket => _window.onPointerDataPacket;
PointerDataPacketCallback? get onPointerDataPacket => _window.onPointerDataPacket;
@override
set onPointerDataPacket(PointerDataPacketCallback callback) {
set onPointerDataPacket(PointerDataPacketCallback? callback) {
_window.onPointerDataPacket = callback;
}
@override
String get defaultRouteName => _defaultRouteNameTestValue ?? _window.defaultRouteName;
String _defaultRouteNameTestValue;
String? _defaultRouteNameTestValue;
/// Hides the real default route name and reports the given
/// [defaultRouteNameTestValue] instead.
set defaultRouteNameTestValue(String defaultRouteNameTestValue) {
@ -309,54 +307,54 @@ class TestWindow implements Window {
@override
bool get semanticsEnabled => _semanticsEnabledTestValue ?? _window.semanticsEnabled;
bool _semanticsEnabledTestValue;
bool? _semanticsEnabledTestValue;
/// Hides the real semantics enabled and reports the given
/// [semanticsEnabledTestValue] instead.
set semanticsEnabledTestValue(bool semanticsEnabledTestValue) {
_semanticsEnabledTestValue = semanticsEnabledTestValue;
onSemanticsEnabledChanged();
onSemanticsEnabledChanged?.call();
}
/// Deletes any existing test semantics enabled and returns to using the real
/// semantics enabled.
void clearSemanticsEnabledTestValue() {
_semanticsEnabledTestValue = null;
onSemanticsEnabledChanged();
onSemanticsEnabledChanged?.call();
}
@override
VoidCallback get onSemanticsEnabledChanged => _window.onSemanticsEnabledChanged;
VoidCallback? get onSemanticsEnabledChanged => _window.onSemanticsEnabledChanged;
@override
set onSemanticsEnabledChanged(VoidCallback callback) {
set onSemanticsEnabledChanged(VoidCallback? callback) {
_window.onSemanticsEnabledChanged = callback;
}
@override
SemanticsActionCallback get onSemanticsAction => _window.onSemanticsAction;
SemanticsActionCallback? get onSemanticsAction => _window.onSemanticsAction;
@override
set onSemanticsAction(SemanticsActionCallback callback) {
set onSemanticsAction(SemanticsActionCallback? callback) {
_window.onSemanticsAction = callback;
}
@override
AccessibilityFeatures get accessibilityFeatures => _accessibilityFeaturesTestValue ?? _window.accessibilityFeatures;
AccessibilityFeatures _accessibilityFeaturesTestValue;
AccessibilityFeatures? _accessibilityFeaturesTestValue;
/// Hides the real accessibility features and reports the given
/// [accessibilityFeaturesTestValue] instead.
set accessibilityFeaturesTestValue(AccessibilityFeatures accessibilityFeaturesTestValue) {
_accessibilityFeaturesTestValue = accessibilityFeaturesTestValue;
onAccessibilityFeaturesChanged();
onAccessibilityFeaturesChanged?.call();
}
/// Deletes any existing test accessibility features and returns to using the
/// real accessibility features.
void clearAccessibilityFeaturesTestValue() {
_accessibilityFeaturesTestValue = null;
onAccessibilityFeaturesChanged();
onAccessibilityFeaturesChanged?.call();
}
@override
VoidCallback get onAccessibilityFeaturesChanged => _window.onAccessibilityFeaturesChanged;
VoidCallback? get onAccessibilityFeaturesChanged => _window.onAccessibilityFeaturesChanged;
@override
set onAccessibilityFeaturesChanged(VoidCallback callback) {
set onAccessibilityFeaturesChanged(VoidCallback? callback) {
_window.onAccessibilityFeaturesChanged = callback;
}
@ -373,16 +371,16 @@ class TestWindow implements Window {
@override
void sendPlatformMessage(
String name,
ByteData data,
PlatformMessageResponseCallback callback,
ByteData? data,
PlatformMessageResponseCallback? callback,
) {
_window.sendPlatformMessage(name, data, callback);
}
@override
PlatformMessageCallback get onPlatformMessage => _window.onPlatformMessage;
PlatformMessageCallback? get onPlatformMessage => _window.onPlatformMessage;
@override
set onPlatformMessage(PlatformMessageCallback callback) {
set onPlatformMessage(PlatformMessageCallback? callback) {
_window.onPlatformMessage = callback;
}

View File

@ -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".

View 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_test/flutter_test.dart';

View 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_test/flutter_test.dart';

View 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 '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();
}
}

View 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';

View 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';

View 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';

View 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';

View 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';

View 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 'dart:io';
import 'package:flutter/material.dart';

View 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 'dart:io';
import 'package:flutter_test/flutter_test.dart';

View 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 'dart:ui';
import 'package:flutter/semantics.dart';

View 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 'dart:async';
import 'package:flutter/foundation.dart';

View 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 'flutter_test_config.dart' as real_test;
void main() => real_test.runTest();

View 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 'dart:async';
import 'package:flutter/foundation.dart';

View 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/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

View 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/rendering.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

View 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 'dart:ui';
import 'package:flutter_test/flutter_test.dart';

View 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 'dart:async';
import 'dart:io' as io;
import 'dart:typed_data';

View 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 'dart:io';
import 'package:flutter/widgets.dart';

View 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 'dart:ui';
import 'package:flutter/material.dart';

View 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 'dart:ui';
import 'package:flutter/material.dart';

View 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 'dart:typed_data';
import 'dart:ui';

View 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 'dart:ui' as ui;
import 'package:flutter_test/flutter_test.dart';

View 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/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

View 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/foundation.dart';
import 'package:flutter_test/flutter_test.dart';

View 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/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

View 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 '../config_test_utils.dart';
void main() {

View 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 '../../config_test_utils.dart';
void main() {

View 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 'config_test_utils.dart';
void main() {

View 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 'dart:async';
import 'package:flutter_test/flutter_test.dart';

View 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 'dart:async';
Future<void> main(FutureOr<void> testMain()) async {

View 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 '../config_test_utils.dart';
void main() {

View 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 'dart:async';
Future<void> main(FutureOr<void> testMain()) async {

View 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 '../config_test_utils.dart';
void main() {

View 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/services.dart';
import 'package:flutter_test/flutter_test.dart';

View 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 'dart:async';
import 'dart:io';
import 'dart:ui';

View 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 'dart:ui' as ui show window;
import 'dart:ui' show Size, Locale, WindowPadding, AccessibilityFeatures, Brightness;