Sound null safety for framework and flutter_test (#68642)
This commit is contained in:
parent
955e07461b
commit
42f3709a5a
@ -528,7 +528,8 @@ Future<void> _runAddToAppLifeCycleTests() async {
|
|||||||
|
|
||||||
Future<void> _runFrameworkTests() async {
|
Future<void> _runFrameworkTests() async {
|
||||||
final bq.BigqueryApi bigqueryApi = await _getBigqueryApi();
|
final bq.BigqueryApi bigqueryApi = await _getBigqueryApi();
|
||||||
final List<String> nullSafetyOptions = <String>['--null-assertions', '--no-sound-null-safety'];
|
final List<String> soundNullSafetyOptions = <String>['--enable-experiment=non-nullable', '--null-assertions', '--sound-null-safety'];
|
||||||
|
final List<String> mixedModeNullSafetyOptions = <String>['--enable-experiment=non-nullable', '--null-assertions', '--no-sound-null-safety'];
|
||||||
final List<String> trackWidgetCreationAlternatives = <String>['--track-widget-creation', '--no-track-widget-creation'];
|
final List<String> trackWidgetCreationAlternatives = <String>['--track-widget-creation', '--no-track-widget-creation'];
|
||||||
|
|
||||||
Future<void> runWidgets() async {
|
Future<void> runWidgets() async {
|
||||||
@ -536,7 +537,7 @@ Future<void> _runFrameworkTests() async {
|
|||||||
for (final String trackWidgetCreationOption in trackWidgetCreationAlternatives) {
|
for (final String trackWidgetCreationOption in trackWidgetCreationAlternatives) {
|
||||||
await _runFlutterTest(
|
await _runFlutterTest(
|
||||||
path.join(flutterRoot, 'packages', 'flutter'),
|
path.join(flutterRoot, 'packages', 'flutter'),
|
||||||
options: <String>[trackWidgetCreationOption, ...nullSafetyOptions],
|
options: <String>[trackWidgetCreationOption, ...soundNullSafetyOptions],
|
||||||
tableData: bigqueryApi?.tabledata,
|
tableData: bigqueryApi?.tabledata,
|
||||||
tests: <String>[ path.join('test', 'widgets') + path.separator ],
|
tests: <String>[ path.join('test', 'widgets') + path.separator ],
|
||||||
);
|
);
|
||||||
@ -562,7 +563,7 @@ Future<void> _runFrameworkTests() async {
|
|||||||
for (final String trackWidgetCreationOption in trackWidgetCreationAlternatives) {
|
for (final String trackWidgetCreationOption in trackWidgetCreationAlternatives) {
|
||||||
await _runFlutterTest(
|
await _runFlutterTest(
|
||||||
path.join(flutterRoot, 'packages', 'flutter'),
|
path.join(flutterRoot, 'packages', 'flutter'),
|
||||||
options: <String>[trackWidgetCreationOption, ...nullSafetyOptions],
|
options: <String>[trackWidgetCreationOption, ...soundNullSafetyOptions],
|
||||||
tableData: bigqueryApi?.tabledata,
|
tableData: bigqueryApi?.tabledata,
|
||||||
tests: tests,
|
tests: tests,
|
||||||
);
|
);
|
||||||
@ -613,14 +614,14 @@ Future<void> _runFrameworkTests() async {
|
|||||||
await _runFlutterTest(path.join(flutterRoot, 'dev', 'manual_tests'), tableData: bigqueryApi?.tabledata);
|
await _runFlutterTest(path.join(flutterRoot, 'dev', 'manual_tests'), tableData: bigqueryApi?.tabledata);
|
||||||
await _runFlutterTest(path.join(flutterRoot, 'dev', 'tools', 'vitool'), tableData: bigqueryApi?.tabledata);
|
await _runFlutterTest(path.join(flutterRoot, 'dev', 'tools', 'vitool'), tableData: bigqueryApi?.tabledata);
|
||||||
await _runFlutterTest(path.join(flutterRoot, 'examples', 'hello_world'), tableData: bigqueryApi?.tabledata);
|
await _runFlutterTest(path.join(flutterRoot, 'examples', 'hello_world'), tableData: bigqueryApi?.tabledata);
|
||||||
await _runFlutterTest(path.join(flutterRoot, 'examples', 'layers'), tableData: bigqueryApi?.tabledata);
|
await _runFlutterTest(path.join(flutterRoot, 'examples', 'layers'), tableData: bigqueryApi?.tabledata, options: mixedModeNullSafetyOptions);
|
||||||
await _runFlutterTest(path.join(flutterRoot, 'dev', 'benchmarks', 'test_apps', 'stocks'), tableData: bigqueryApi?.tabledata);
|
await _runFlutterTest(path.join(flutterRoot, 'dev', 'benchmarks', 'test_apps', 'stocks'), tableData: bigqueryApi?.tabledata);
|
||||||
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_driver'), tableData: bigqueryApi?.tabledata, tests: <String>[path.join('test', 'src', 'real_tests')]);
|
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_driver'), tableData: bigqueryApi?.tabledata, tests: <String>[path.join('test', 'src', 'real_tests')]);
|
||||||
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_goldens'), tableData: bigqueryApi?.tabledata);
|
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_goldens'), tableData: bigqueryApi?.tabledata);
|
||||||
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_localizations'), tableData: bigqueryApi?.tabledata);
|
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_localizations'), tableData: bigqueryApi?.tabledata);
|
||||||
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_test'), tableData: bigqueryApi?.tabledata, options: nullSafetyOptions);
|
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_test'), tableData: bigqueryApi?.tabledata, options: soundNullSafetyOptions);
|
||||||
await _runFlutterTest(path.join(flutterRoot, 'packages', 'fuchsia_remote_debug_protocol'), tableData: bigqueryApi?.tabledata);
|
await _runFlutterTest(path.join(flutterRoot, 'packages', 'fuchsia_remote_debug_protocol'), tableData: bigqueryApi?.tabledata);
|
||||||
await _runFlutterTest(path.join(flutterRoot, 'dev', 'integration_tests', 'non_nullable'), options: nullSafetyOptions);
|
await _runFlutterTest(path.join(flutterRoot, 'dev', 'integration_tests', 'non_nullable'), options: mixedModeNullSafetyOptions);
|
||||||
await _runFlutterTest(
|
await _runFlutterTest(
|
||||||
path.join(flutterRoot, 'dev', 'tracing_tests'),
|
path.join(flutterRoot, 'dev', 'tracing_tests'),
|
||||||
options: <String>['--enable-vmservice'],
|
options: <String>['--enable-vmservice'],
|
||||||
|
13
examples/layers/analysis_options.yaml
Normal file
13
examples/layers/analysis_options.yaml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# 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
|
||||||
|
type_init_formals: false # https://github.com/dart-lang/linter/issues/2192
|
||||||
|
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 # Turned off until null-safe rollout is complete.
|
@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
// @dart = 2.8
|
// @dart = 2.10
|
||||||
|
|
||||||
// This example shows how to build a render tree with a non-cartesian coordinate
|
// This example shows how to build a render tree with a non-cartesian coordinate
|
||||||
// system. Most of the guts of this examples are in src/sector_layout.dart.
|
// system. Most of the guts of this examples are in src/sector_layout.dart.
|
||||||
|
@ -2,13 +2,12 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
// @dart = 2.8
|
// @dart = 2.10
|
||||||
|
|
||||||
import 'dart:math' as math;
|
import 'dart:math' as math;
|
||||||
|
|
||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
const double kTwoPi = 2 * math.pi;
|
const double kTwoPi = 2 * math.pi;
|
||||||
|
|
||||||
@ -33,11 +32,11 @@ class SectorConstraints extends Constraints {
|
|||||||
final double maxDeltaTheta;
|
final double maxDeltaTheta;
|
||||||
|
|
||||||
double constrainDeltaRadius(double deltaRadius) {
|
double constrainDeltaRadius(double deltaRadius) {
|
||||||
return deltaRadius.clamp(minDeltaRadius, maxDeltaRadius) as double;
|
return deltaRadius.clamp(minDeltaRadius, maxDeltaRadius);
|
||||||
}
|
}
|
||||||
|
|
||||||
double constrainDeltaTheta(double deltaTheta) {
|
double constrainDeltaTheta(double deltaTheta) {
|
||||||
return deltaTheta.clamp(minDeltaTheta, maxDeltaTheta) as double;
|
return deltaTheta.clamp(minDeltaTheta, maxDeltaTheta);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -49,7 +48,7 @@ class SectorConstraints extends Constraints {
|
|||||||
@override
|
@override
|
||||||
bool debugAssertIsValid({
|
bool debugAssertIsValid({
|
||||||
bool isAppliedConstraint = false,
|
bool isAppliedConstraint = false,
|
||||||
InformationCollector informationCollector,
|
InformationCollector? informationCollector,
|
||||||
}) {
|
}) {
|
||||||
assert(isNormalized);
|
assert(isNormalized);
|
||||||
return isNormalized;
|
return isNormalized;
|
||||||
@ -102,7 +101,7 @@ abstract class RenderSector extends RenderObject {
|
|||||||
// RenderSectors always use SectorParentData subclasses, as they need to be
|
// RenderSectors always use SectorParentData subclasses, as they need to be
|
||||||
// able to read their position information for painting and hit testing.
|
// able to read their position information for painting and hit testing.
|
||||||
@override
|
@override
|
||||||
SectorParentData get parentData => super.parentData as SectorParentData;
|
SectorParentData? get parentData => super.parentData as SectorParentData?;
|
||||||
|
|
||||||
SectorDimensions getIntrinsicDimensions(SectorConstraints constraints, double radius) {
|
SectorDimensions getIntrinsicDimensions(SectorConstraints constraints, double radius) {
|
||||||
return SectorDimensions.withConstraints(constraints);
|
return SectorDimensions.withConstraints(constraints);
|
||||||
@ -145,27 +144,27 @@ abstract class RenderSector extends RenderObject {
|
|||||||
@override
|
@override
|
||||||
Rect get semanticBounds => Rect.fromLTWH(-deltaRadius, -deltaRadius, 2.0 * deltaRadius, 2.0 * deltaRadius);
|
Rect get semanticBounds => Rect.fromLTWH(-deltaRadius, -deltaRadius, 2.0 * deltaRadius, 2.0 * deltaRadius);
|
||||||
|
|
||||||
bool hitTest(SectorHitTestResult result, { double radius, double theta }) {
|
bool hitTest(SectorHitTestResult result, { required double radius, required double theta }) {
|
||||||
if (radius < parentData.radius || radius >= parentData.radius + deltaRadius ||
|
if (radius < parentData!.radius || radius >= parentData!.radius + deltaRadius ||
|
||||||
theta < parentData.theta || theta >= parentData.theta + deltaTheta)
|
theta < parentData!.theta || theta >= parentData!.theta + deltaTheta)
|
||||||
return false;
|
return false;
|
||||||
hitTestChildren(result, radius: radius, theta: theta);
|
hitTestChildren(result, radius: radius, theta: theta);
|
||||||
result.add(SectorHitTestEntry(this, radius: radius, theta: theta));
|
result.add(SectorHitTestEntry(this, radius: radius, theta: theta));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void hitTestChildren(SectorHitTestResult result, { double radius, double theta }) { }
|
void hitTestChildren(SectorHitTestResult result, { required double radius, required double theta }) { }
|
||||||
|
|
||||||
double deltaRadius;
|
late double deltaRadius;
|
||||||
double deltaTheta;
|
late double deltaTheta;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class RenderDecoratedSector extends RenderSector {
|
abstract class RenderDecoratedSector extends RenderSector {
|
||||||
|
|
||||||
RenderDecoratedSector(BoxDecoration decoration) : _decoration = decoration;
|
RenderDecoratedSector(BoxDecoration? decoration) : _decoration = decoration;
|
||||||
|
|
||||||
BoxDecoration _decoration;
|
BoxDecoration? _decoration;
|
||||||
BoxDecoration get decoration => _decoration;
|
BoxDecoration? get decoration => _decoration;
|
||||||
set decoration(BoxDecoration value) {
|
set decoration(BoxDecoration? value) {
|
||||||
if (value == _decoration)
|
if (value == _decoration)
|
||||||
return;
|
return;
|
||||||
_decoration = value;
|
_decoration = value;
|
||||||
@ -182,16 +181,16 @@ abstract class RenderDecoratedSector extends RenderSector {
|
|||||||
if (_decoration == null)
|
if (_decoration == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_decoration.color != null) {
|
if (_decoration!.color != null) {
|
||||||
final Canvas canvas = context.canvas;
|
final Canvas canvas = context.canvas;
|
||||||
final Paint paint = Paint()..color = _decoration.color;
|
final Paint paint = Paint()..color = _decoration!.color!;
|
||||||
final Path path = Path();
|
final Path path = Path();
|
||||||
final double outerRadius = parentData.radius + deltaRadius;
|
final double outerRadius = parentData!.radius + deltaRadius;
|
||||||
final Rect outerBounds = Rect.fromLTRB(offset.dx-outerRadius, offset.dy-outerRadius, offset.dx+outerRadius, offset.dy+outerRadius);
|
final Rect outerBounds = Rect.fromLTRB(offset.dx-outerRadius, offset.dy-outerRadius, offset.dx+outerRadius, offset.dy+outerRadius);
|
||||||
path.arcTo(outerBounds, parentData.theta, deltaTheta, true);
|
path.arcTo(outerBounds, parentData!.theta, deltaTheta, true);
|
||||||
final double innerRadius = parentData.radius;
|
final double innerRadius = parentData!.radius;
|
||||||
final Rect innerBounds = Rect.fromLTRB(offset.dx-innerRadius, offset.dy-innerRadius, offset.dx+innerRadius, offset.dy+innerRadius);
|
final Rect innerBounds = Rect.fromLTRB(offset.dx-innerRadius, offset.dy-innerRadius, offset.dx+innerRadius, offset.dy+innerRadius);
|
||||||
path.arcTo(innerBounds, parentData.theta + deltaTheta, -deltaTheta, false);
|
path.arcTo(innerBounds, parentData!.theta + deltaTheta, -deltaTheta, false);
|
||||||
path.close();
|
path.close();
|
||||||
canvas.drawPath(path, paint);
|
canvas.drawPath(path, paint);
|
||||||
}
|
}
|
||||||
@ -202,25 +201,25 @@ abstract class RenderDecoratedSector extends RenderSector {
|
|||||||
class SectorChildListParentData extends SectorParentData with ContainerParentDataMixin<RenderSector> { }
|
class SectorChildListParentData extends SectorParentData with ContainerParentDataMixin<RenderSector> { }
|
||||||
|
|
||||||
class RenderSectorWithChildren extends RenderDecoratedSector with ContainerRenderObjectMixin<RenderSector, SectorChildListParentData> {
|
class RenderSectorWithChildren extends RenderDecoratedSector with ContainerRenderObjectMixin<RenderSector, SectorChildListParentData> {
|
||||||
RenderSectorWithChildren(BoxDecoration decoration) : super(decoration);
|
RenderSectorWithChildren(BoxDecoration? decoration) : super(decoration);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void hitTestChildren(SectorHitTestResult result, { double radius, double theta }) {
|
void hitTestChildren(SectorHitTestResult result, { required double radius, required double theta }) {
|
||||||
RenderSector child = lastChild;
|
RenderSector? child = lastChild;
|
||||||
while (child != null) {
|
while (child != null) {
|
||||||
if (child.hitTest(result, radius: radius, theta: theta))
|
if (child.hitTest(result, radius: radius, theta: theta))
|
||||||
return;
|
return;
|
||||||
final SectorChildListParentData childParentData = child.parentData as SectorChildListParentData;
|
final SectorChildListParentData childParentData = child.parentData! as SectorChildListParentData;
|
||||||
child = childParentData.previousSibling;
|
child = childParentData.previousSibling;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void visitChildren(RenderObjectVisitor visitor) {
|
void visitChildren(RenderObjectVisitor visitor) {
|
||||||
RenderSector child = lastChild;
|
RenderSector? child = lastChild;
|
||||||
while (child != null) {
|
while (child != null) {
|
||||||
visitor(child);
|
visitor(child);
|
||||||
final SectorChildListParentData childParentData = child.parentData as SectorChildListParentData;
|
final SectorChildListParentData childParentData = child.parentData! as SectorChildListParentData;
|
||||||
child = childParentData.previousSibling;
|
child = childParentData.previousSibling;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -230,7 +229,7 @@ class RenderSectorRing extends RenderSectorWithChildren {
|
|||||||
// lays out RenderSector children in a ring
|
// lays out RenderSector children in a ring
|
||||||
|
|
||||||
RenderSectorRing({
|
RenderSectorRing({
|
||||||
BoxDecoration decoration,
|
BoxDecoration? decoration,
|
||||||
double deltaRadius = double.infinity,
|
double deltaRadius = double.infinity,
|
||||||
double padding = 0.0,
|
double padding = 0.0,
|
||||||
}) : _padding = padding,
|
}) : _padding = padding,
|
||||||
@ -275,7 +274,7 @@ class RenderSectorRing extends RenderSectorWithChildren {
|
|||||||
final double paddingTheta = math.atan(padding / (radius + outerDeltaRadius));
|
final double paddingTheta = math.atan(padding / (radius + outerDeltaRadius));
|
||||||
double innerTheta = paddingTheta; // increments with each child
|
double innerTheta = paddingTheta; // increments with each child
|
||||||
double remainingDeltaTheta = math.max(0.0, constraints.maxDeltaTheta - (innerTheta + paddingTheta));
|
double remainingDeltaTheta = math.max(0.0, constraints.maxDeltaTheta - (innerTheta + paddingTheta));
|
||||||
RenderSector child = firstChild;
|
RenderSector? child = firstChild;
|
||||||
while (child != null) {
|
while (child != null) {
|
||||||
final SectorConstraints innerConstraints = SectorConstraints(
|
final SectorConstraints innerConstraints = SectorConstraints(
|
||||||
maxDeltaRadius: innerDeltaRadius,
|
maxDeltaRadius: innerDeltaRadius,
|
||||||
@ -284,7 +283,7 @@ class RenderSectorRing extends RenderSectorWithChildren {
|
|||||||
final SectorDimensions childDimensions = child.getIntrinsicDimensions(innerConstraints, childRadius);
|
final SectorDimensions childDimensions = child.getIntrinsicDimensions(innerConstraints, childRadius);
|
||||||
innerTheta += childDimensions.deltaTheta;
|
innerTheta += childDimensions.deltaTheta;
|
||||||
remainingDeltaTheta -= childDimensions.deltaTheta;
|
remainingDeltaTheta -= childDimensions.deltaTheta;
|
||||||
final SectorChildListParentData childParentData = child.parentData as SectorChildListParentData;
|
final SectorChildListParentData childParentData = child.parentData! as SectorChildListParentData;
|
||||||
child = childParentData.nextSibling;
|
child = childParentData.nextSibling;
|
||||||
if (child != null) {
|
if (child != null) {
|
||||||
innerTheta += paddingTheta;
|
innerTheta += paddingTheta;
|
||||||
@ -302,23 +301,23 @@ class RenderSectorRing extends RenderSectorWithChildren {
|
|||||||
deltaRadius = constraints.constrainDeltaRadius(desiredDeltaRadius);
|
deltaRadius = constraints.constrainDeltaRadius(desiredDeltaRadius);
|
||||||
assert(deltaRadius < double.infinity);
|
assert(deltaRadius < double.infinity);
|
||||||
final double innerDeltaRadius = deltaRadius - padding * 2.0;
|
final double innerDeltaRadius = deltaRadius - padding * 2.0;
|
||||||
final double childRadius = parentData.radius + padding;
|
final double childRadius = parentData!.radius + padding;
|
||||||
final double paddingTheta = math.atan(padding / (parentData.radius + deltaRadius));
|
final double paddingTheta = math.atan(padding / (parentData!.radius + deltaRadius));
|
||||||
double innerTheta = paddingTheta; // increments with each child
|
double innerTheta = paddingTheta; // increments with each child
|
||||||
double remainingDeltaTheta = constraints.maxDeltaTheta - (innerTheta + paddingTheta);
|
double remainingDeltaTheta = constraints.maxDeltaTheta - (innerTheta + paddingTheta);
|
||||||
RenderSector child = firstChild;
|
RenderSector? child = firstChild;
|
||||||
while (child != null) {
|
while (child != null) {
|
||||||
final SectorConstraints innerConstraints = SectorConstraints(
|
final SectorConstraints innerConstraints = SectorConstraints(
|
||||||
maxDeltaRadius: innerDeltaRadius,
|
maxDeltaRadius: innerDeltaRadius,
|
||||||
maxDeltaTheta: remainingDeltaTheta,
|
maxDeltaTheta: remainingDeltaTheta,
|
||||||
);
|
);
|
||||||
assert(child.parentData is SectorParentData);
|
assert(child.parentData is SectorParentData);
|
||||||
child.parentData.theta = innerTheta;
|
child.parentData!.theta = innerTheta;
|
||||||
child.parentData.radius = childRadius;
|
child.parentData!.radius = childRadius;
|
||||||
child.layout(innerConstraints, parentUsesSize: true);
|
child.layout(innerConstraints, parentUsesSize: true);
|
||||||
innerTheta += child.deltaTheta;
|
innerTheta += child.deltaTheta;
|
||||||
remainingDeltaTheta -= child.deltaTheta;
|
remainingDeltaTheta -= child.deltaTheta;
|
||||||
final SectorChildListParentData childParentData = child.parentData as SectorChildListParentData;
|
final SectorChildListParentData childParentData = child.parentData! as SectorChildListParentData;
|
||||||
child = childParentData.nextSibling;
|
child = childParentData.nextSibling;
|
||||||
if (child != null) {
|
if (child != null) {
|
||||||
innerTheta += paddingTheta;
|
innerTheta += paddingTheta;
|
||||||
@ -334,10 +333,10 @@ class RenderSectorRing extends RenderSectorWithChildren {
|
|||||||
void paint(PaintingContext context, Offset offset) {
|
void paint(PaintingContext context, Offset offset) {
|
||||||
// TODO(ianh): avoid code duplication
|
// TODO(ianh): avoid code duplication
|
||||||
super.paint(context, offset);
|
super.paint(context, offset);
|
||||||
RenderSector child = firstChild;
|
RenderSector? child = firstChild;
|
||||||
while (child != null) {
|
while (child != null) {
|
||||||
context.paintChild(child, offset);
|
context.paintChild(child, offset);
|
||||||
final SectorChildListParentData childParentData = child.parentData as SectorChildListParentData;
|
final SectorChildListParentData childParentData = child.parentData! as SectorChildListParentData;
|
||||||
child = childParentData.nextSibling;
|
child = childParentData.nextSibling;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -348,7 +347,7 @@ class RenderSectorSlice extends RenderSectorWithChildren {
|
|||||||
// lays out RenderSector children in a stack
|
// lays out RenderSector children in a stack
|
||||||
|
|
||||||
RenderSectorSlice({
|
RenderSectorSlice({
|
||||||
BoxDecoration decoration,
|
BoxDecoration? decoration,
|
||||||
double deltaTheta = kTwoPi,
|
double deltaTheta = kTwoPi,
|
||||||
double padding = 0.0,
|
double padding = 0.0,
|
||||||
}) : _padding = padding, _desiredDeltaTheta = deltaTheta, super(decoration);
|
}) : _padding = padding, _desiredDeltaTheta = deltaTheta, super(decoration);
|
||||||
@ -384,12 +383,12 @@ class RenderSectorSlice extends RenderSectorWithChildren {
|
|||||||
@override
|
@override
|
||||||
SectorDimensions getIntrinsicDimensions(SectorConstraints constraints, double radius) {
|
SectorDimensions getIntrinsicDimensions(SectorConstraints constraints, double radius) {
|
||||||
assert(parentData is SectorParentData);
|
assert(parentData is SectorParentData);
|
||||||
final double paddingTheta = math.atan(padding / parentData.radius);
|
final double paddingTheta = math.atan(padding / parentData!.radius);
|
||||||
final double outerDeltaTheta = constraints.constrainDeltaTheta(desiredDeltaTheta);
|
final double outerDeltaTheta = constraints.constrainDeltaTheta(desiredDeltaTheta);
|
||||||
final double innerDeltaTheta = outerDeltaTheta - paddingTheta * 2.0;
|
final double innerDeltaTheta = outerDeltaTheta - paddingTheta * 2.0;
|
||||||
double childRadius = parentData.radius + padding;
|
double childRadius = parentData!.radius + padding;
|
||||||
double remainingDeltaRadius = constraints.maxDeltaRadius - (padding * 2.0);
|
double remainingDeltaRadius = constraints.maxDeltaRadius - (padding * 2.0);
|
||||||
RenderSector child = firstChild;
|
RenderSector? child = firstChild;
|
||||||
while (child != null) {
|
while (child != null) {
|
||||||
final SectorConstraints innerConstraints = SectorConstraints(
|
final SectorConstraints innerConstraints = SectorConstraints(
|
||||||
maxDeltaRadius: remainingDeltaRadius,
|
maxDeltaRadius: remainingDeltaRadius,
|
||||||
@ -398,13 +397,13 @@ class RenderSectorSlice extends RenderSectorWithChildren {
|
|||||||
final SectorDimensions childDimensions = child.getIntrinsicDimensions(innerConstraints, childRadius);
|
final SectorDimensions childDimensions = child.getIntrinsicDimensions(innerConstraints, childRadius);
|
||||||
childRadius += childDimensions.deltaRadius;
|
childRadius += childDimensions.deltaRadius;
|
||||||
remainingDeltaRadius -= childDimensions.deltaRadius;
|
remainingDeltaRadius -= childDimensions.deltaRadius;
|
||||||
final SectorChildListParentData childParentData = child.parentData as SectorChildListParentData;
|
final SectorChildListParentData childParentData = child.parentData! as SectorChildListParentData;
|
||||||
child = childParentData.nextSibling;
|
child = childParentData.nextSibling;
|
||||||
childRadius += padding;
|
childRadius += padding;
|
||||||
remainingDeltaRadius -= padding;
|
remainingDeltaRadius -= padding;
|
||||||
}
|
}
|
||||||
return SectorDimensions.withConstraints(constraints,
|
return SectorDimensions.withConstraints(constraints,
|
||||||
deltaRadius: childRadius - parentData.radius,
|
deltaRadius: childRadius - parentData!.radius,
|
||||||
deltaTheta: outerDeltaTheta);
|
deltaTheta: outerDeltaTheta);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,28 +412,28 @@ class RenderSectorSlice extends RenderSectorWithChildren {
|
|||||||
assert(parentData is SectorParentData);
|
assert(parentData is SectorParentData);
|
||||||
deltaTheta = constraints.constrainDeltaTheta(desiredDeltaTheta);
|
deltaTheta = constraints.constrainDeltaTheta(desiredDeltaTheta);
|
||||||
assert(deltaTheta <= kTwoPi);
|
assert(deltaTheta <= kTwoPi);
|
||||||
final double paddingTheta = math.atan(padding / parentData.radius);
|
final double paddingTheta = math.atan(padding / parentData!.radius);
|
||||||
final double innerTheta = parentData.theta + paddingTheta;
|
final double innerTheta = parentData!.theta + paddingTheta;
|
||||||
final double innerDeltaTheta = deltaTheta - paddingTheta * 2.0;
|
final double innerDeltaTheta = deltaTheta - paddingTheta * 2.0;
|
||||||
double childRadius = parentData.radius + padding;
|
double childRadius = parentData!.radius + padding;
|
||||||
double remainingDeltaRadius = constraints.maxDeltaRadius - (padding * 2.0);
|
double remainingDeltaRadius = constraints.maxDeltaRadius - (padding * 2.0);
|
||||||
RenderSector child = firstChild;
|
RenderSector? child = firstChild;
|
||||||
while (child != null) {
|
while (child != null) {
|
||||||
final SectorConstraints innerConstraints = SectorConstraints(
|
final SectorConstraints innerConstraints = SectorConstraints(
|
||||||
maxDeltaRadius: remainingDeltaRadius,
|
maxDeltaRadius: remainingDeltaRadius,
|
||||||
maxDeltaTheta: innerDeltaTheta,
|
maxDeltaTheta: innerDeltaTheta,
|
||||||
);
|
);
|
||||||
child.parentData.theta = innerTheta;
|
child.parentData!.theta = innerTheta;
|
||||||
child.parentData.radius = childRadius;
|
child.parentData!.radius = childRadius;
|
||||||
child.layout(innerConstraints, parentUsesSize: true);
|
child.layout(innerConstraints, parentUsesSize: true);
|
||||||
childRadius += child.deltaRadius;
|
childRadius += child.deltaRadius;
|
||||||
remainingDeltaRadius -= child.deltaRadius;
|
remainingDeltaRadius -= child.deltaRadius;
|
||||||
final SectorChildListParentData childParentData = child.parentData as SectorChildListParentData;
|
final SectorChildListParentData childParentData = child.parentData! as SectorChildListParentData;
|
||||||
child = childParentData.nextSibling;
|
child = childParentData.nextSibling;
|
||||||
childRadius += padding;
|
childRadius += padding;
|
||||||
remainingDeltaRadius -= padding;
|
remainingDeltaRadius -= padding;
|
||||||
}
|
}
|
||||||
deltaRadius = childRadius - parentData.radius;
|
deltaRadius = childRadius - parentData!.radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
// offset must point to the center of our circle
|
// offset must point to the center of our circle
|
||||||
@ -443,11 +442,11 @@ class RenderSectorSlice extends RenderSectorWithChildren {
|
|||||||
void paint(PaintingContext context, Offset offset) {
|
void paint(PaintingContext context, Offset offset) {
|
||||||
// TODO(ianh): avoid code duplication
|
// TODO(ianh): avoid code duplication
|
||||||
super.paint(context, offset);
|
super.paint(context, offset);
|
||||||
RenderSector child = firstChild;
|
RenderSector? child = firstChild;
|
||||||
while (child != null) {
|
while (child != null) {
|
||||||
assert(child.parentData is SectorChildListParentData);
|
assert(child.parentData is SectorChildListParentData);
|
||||||
context.paintChild(child, offset);
|
context.paintChild(child, offset);
|
||||||
final SectorChildListParentData childParentData = child.parentData as SectorChildListParentData;
|
final SectorChildListParentData childParentData = child.parentData! as SectorChildListParentData;
|
||||||
child = childParentData.nextSibling;
|
child = childParentData.nextSibling;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -456,7 +455,7 @@ class RenderSectorSlice extends RenderSectorWithChildren {
|
|||||||
|
|
||||||
class RenderBoxToRenderSectorAdapter extends RenderBox with RenderObjectWithChildMixin<RenderSector> {
|
class RenderBoxToRenderSectorAdapter extends RenderBox with RenderObjectWithChildMixin<RenderSector> {
|
||||||
|
|
||||||
RenderBoxToRenderSectorAdapter({ double innerRadius = 0.0, RenderSector child })
|
RenderBoxToRenderSectorAdapter({ double innerRadius = 0.0, RenderSector? child })
|
||||||
: _innerRadius = innerRadius {
|
: _innerRadius = innerRadius {
|
||||||
this.child = child;
|
this.child = child;
|
||||||
}
|
}
|
||||||
@ -507,13 +506,13 @@ class RenderBoxToRenderSectorAdapter extends RenderBox with RenderObjectWithChil
|
|||||||
double height = double.infinity,
|
double height = double.infinity,
|
||||||
}) {
|
}) {
|
||||||
assert(child is RenderSector);
|
assert(child is RenderSector);
|
||||||
assert(child.parentData is SectorParentData);
|
assert(child!.parentData is SectorParentData);
|
||||||
assert(width != null);
|
assert(width != null);
|
||||||
assert(height != null);
|
assert(height != null);
|
||||||
if (!width.isFinite && !height.isFinite)
|
if (!width.isFinite && !height.isFinite)
|
||||||
return Size.zero;
|
return Size.zero;
|
||||||
final double maxChildDeltaRadius = math.max(0.0, math.min(width, height) / 2.0 - innerRadius);
|
final double maxChildDeltaRadius = math.max(0.0, math.min(width, height) / 2.0 - innerRadius);
|
||||||
final SectorDimensions childDimensions = child.getIntrinsicDimensions(SectorConstraints(maxDeltaRadius: maxChildDeltaRadius), innerRadius);
|
final SectorDimensions childDimensions = child!.getIntrinsicDimensions(SectorConstraints(maxDeltaRadius: maxChildDeltaRadius), innerRadius);
|
||||||
final double dimension = (innerRadius + childDimensions.deltaRadius) * 2.0;
|
final double dimension = (innerRadius + childDimensions.deltaRadius) * 2.0;
|
||||||
return Size.square(dimension);
|
return Size.square(dimension);
|
||||||
}
|
}
|
||||||
@ -526,12 +525,12 @@ class RenderBoxToRenderSectorAdapter extends RenderBox with RenderObjectWithChil
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
assert(child is RenderSector);
|
assert(child is RenderSector);
|
||||||
assert(child.parentData is SectorParentData);
|
assert(child!.parentData is SectorParentData);
|
||||||
final double maxChildDeltaRadius = math.min(constraints.maxWidth, constraints.maxHeight) / 2.0 - innerRadius;
|
final double maxChildDeltaRadius = math.min(constraints.maxWidth, constraints.maxHeight) / 2.0 - innerRadius;
|
||||||
child.parentData.radius = innerRadius;
|
child!.parentData!.radius = innerRadius;
|
||||||
child.parentData.theta = 0.0;
|
child!.parentData!.theta = 0.0;
|
||||||
child.layout(SectorConstraints(maxDeltaRadius: maxChildDeltaRadius), parentUsesSize: true);
|
child!.layout(SectorConstraints(maxDeltaRadius: maxChildDeltaRadius), parentUsesSize: true);
|
||||||
final double dimension = (innerRadius + child.deltaRadius) * 2.0;
|
final double dimension = (innerRadius + child!.deltaRadius) * 2.0;
|
||||||
size = constraints.constrain(Size(dimension, dimension));
|
size = constraints.constrain(Size(dimension, dimension));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,12 +540,12 @@ class RenderBoxToRenderSectorAdapter extends RenderBox with RenderObjectWithChil
|
|||||||
if (child != null) {
|
if (child != null) {
|
||||||
final Rect bounds = offset & size;
|
final Rect bounds = offset & size;
|
||||||
// we move the offset to the center of the circle for the RenderSectors
|
// we move the offset to the center of the circle for the RenderSectors
|
||||||
context.paintChild(child, bounds.center);
|
context.paintChild(child!, bounds.center);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool hitTest(BoxHitTestResult result, { Offset position }) {
|
bool hitTest(BoxHitTestResult result, { required Offset position }) {
|
||||||
if (child == null)
|
if (child == null)
|
||||||
return false;
|
return false;
|
||||||
double x = position.dx;
|
double x = position.dx;
|
||||||
@ -559,11 +558,11 @@ class RenderBoxToRenderSectorAdapter extends RenderBox with RenderObjectWithChil
|
|||||||
final double theta = (math.atan2(x, -y) - math.pi / 2.0) % kTwoPi;
|
final double theta = (math.atan2(x, -y) - math.pi / 2.0) % kTwoPi;
|
||||||
if (radius < innerRadius)
|
if (radius < innerRadius)
|
||||||
return false;
|
return false;
|
||||||
if (radius >= innerRadius + child.deltaRadius)
|
if (radius >= innerRadius + child!.deltaRadius)
|
||||||
return false;
|
return false;
|
||||||
if (theta > child.deltaTheta)
|
if (theta > child!.deltaTheta)
|
||||||
return false;
|
return false;
|
||||||
child.hitTest(SectorHitTestResult.wrap(result), radius: radius, theta: theta);
|
child!.hitTest(SectorHitTestResult.wrap(result), radius: radius, theta: theta);
|
||||||
result.add(BoxHitTestEntry(this, position));
|
result.add(BoxHitTestEntry(this, position));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -634,7 +633,7 @@ class SectorHitTestEntry extends HitTestEntry {
|
|||||||
/// Creates a box hit test entry.
|
/// Creates a box hit test entry.
|
||||||
///
|
///
|
||||||
/// The [radius] and [theta] argument must not be null.
|
/// The [radius] and [theta] argument must not be null.
|
||||||
SectorHitTestEntry(RenderSector target, { @required this.radius, @required this.theta })
|
SectorHitTestEntry(RenderSector target, { required this.radius, required this.theta })
|
||||||
: assert(radius != null),
|
: assert(radius != null),
|
||||||
assert(theta != null),
|
assert(theta != null),
|
||||||
super(target);
|
super(target);
|
||||||
|
@ -731,7 +731,7 @@ class _ContextMenuRoute<T> extends PopupRoute<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool didPop(T result) {
|
bool didPop(T? result) {
|
||||||
_updateTweenRects();
|
_updateTweenRects();
|
||||||
return super.didPop(result);
|
return super.didPop(result);
|
||||||
}
|
}
|
||||||
|
@ -1049,7 +1049,7 @@ class _CupertinoModalPopupRoute<T> extends PopupRoute<T> {
|
|||||||
/// * [CupertinoActionSheet], which is the widget usually returned by the
|
/// * [CupertinoActionSheet], which is the widget usually returned by the
|
||||||
/// `builder` argument to [showCupertinoModalPopup].
|
/// `builder` argument to [showCupertinoModalPopup].
|
||||||
/// * <https://developer.apple.com/design/human-interface-guidelines/ios/views/action-sheets/>
|
/// * <https://developer.apple.com/design/human-interface-guidelines/ios/views/action-sheets/>
|
||||||
Future<T> showCupertinoModalPopup<T>({
|
Future<T?> showCupertinoModalPopup<T>({
|
||||||
required BuildContext context,
|
required BuildContext context,
|
||||||
required WidgetBuilder builder,
|
required WidgetBuilder builder,
|
||||||
ImageFilter? filter,
|
ImageFilter? filter,
|
||||||
@ -1134,7 +1134,7 @@ Widget _buildCupertinoDialogTransitions(BuildContext context, Animation<double>
|
|||||||
/// * [showDialog], which displays a Material-style dialog.
|
/// * [showDialog], which displays a Material-style dialog.
|
||||||
/// * [showGeneralDialog], which allows for customization of the dialog popup.
|
/// * [showGeneralDialog], which allows for customization of the dialog popup.
|
||||||
/// * <https://developer.apple.com/ios/human-interface-guidelines/views/alerts/>
|
/// * <https://developer.apple.com/ios/human-interface-guidelines/views/alerts/>
|
||||||
Future<T> showCupertinoDialog<T>({
|
Future<T?> showCupertinoDialog<T>({
|
||||||
required BuildContext context,
|
required BuildContext context,
|
||||||
required WidgetBuilder builder,
|
required WidgetBuilder builder,
|
||||||
bool useRootNavigator = true,
|
bool useRootNavigator = true,
|
||||||
|
@ -619,8 +619,9 @@ class RestorableCupertinoTabController extends RestorableChangeNotifier<Cupertin
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
CupertinoTabController fromPrimitives(Object data) {
|
CupertinoTabController fromPrimitives(Object? data) {
|
||||||
return CupertinoTabController(initialIndex: data as int);
|
assert(data != null);
|
||||||
|
return CupertinoTabController(initialIndex: data! as int);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -781,7 +781,7 @@ class _CupertinoTextSelectionToolbarItemsElement extends RenderObjectElement {
|
|||||||
}
|
}
|
||||||
if (slot is IndexedSlot) {
|
if (slot is IndexedSlot) {
|
||||||
assert(renderObject.debugValidateChild(child));
|
assert(renderObject.debugValidateChild(child));
|
||||||
renderObject.insert(child as RenderBox, after: slot.value?.renderObject as RenderBox);
|
renderObject.insert(child as RenderBox, after: slot.value?.renderObject as RenderBox?);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
assert(false, 'slot must be _CupertinoTextSelectionToolbarItemsSlot or IndexedSlot');
|
assert(false, 'slot must be _CupertinoTextSelectionToolbarItemsSlot or IndexedSlot');
|
||||||
@ -1255,4 +1255,4 @@ class _NullElement extends Element {
|
|||||||
class _NullWidget extends Widget {
|
class _NullWidget extends Widget {
|
||||||
@override
|
@override
|
||||||
Element createElement() => throw UnimplementedError();
|
Element createElement() => throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,7 @@ void mergeSort<T>(
|
|||||||
final int firstLength = middle - start;
|
final int firstLength = middle - start;
|
||||||
final int secondLength = end - middle;
|
final int secondLength = end - middle;
|
||||||
// secondLength is always the same as firstLength, or one greater.
|
// secondLength is always the same as firstLength, or one greater.
|
||||||
final List<T?> scratchSpace = List<T?>.filled(secondLength, null, growable: false);
|
final List<T> scratchSpace = List<T>.filled(secondLength, list[start]);
|
||||||
_mergeSort<T>(list, compare, middle, end, scratchSpace, 0);
|
_mergeSort<T>(list, compare, middle, end, scratchSpace, 0);
|
||||||
final int firstTarget = end - firstLength;
|
final int firstTarget = end - firstLength;
|
||||||
_mergeSort<T>(list, compare, start, middle, list, firstTarget);
|
_mergeSort<T>(list, compare, start, middle, list, firstTarget);
|
||||||
@ -273,7 +273,7 @@ void _mergeSort<T>(
|
|||||||
int Function(T, T) compare,
|
int Function(T, T) compare,
|
||||||
int start,
|
int start,
|
||||||
int end,
|
int end,
|
||||||
List<T?> target,
|
List<T> target,
|
||||||
int targetOffset,
|
int targetOffset,
|
||||||
) {
|
) {
|
||||||
final int length = end - start;
|
final int length = end - start;
|
||||||
@ -316,10 +316,10 @@ void _merge<T>(
|
|||||||
List<T> firstList,
|
List<T> firstList,
|
||||||
int firstStart,
|
int firstStart,
|
||||||
int firstEnd,
|
int firstEnd,
|
||||||
List<T?> secondList,
|
List<T> secondList,
|
||||||
int secondStart,
|
int secondStart,
|
||||||
int secondEnd,
|
int secondEnd,
|
||||||
List<T?> target,
|
List<T> target,
|
||||||
int targetOffset,
|
int targetOffset,
|
||||||
) {
|
) {
|
||||||
// No empty lists reaches here.
|
// No empty lists reaches here.
|
||||||
@ -328,7 +328,7 @@ void _merge<T>(
|
|||||||
int cursor1 = firstStart;
|
int cursor1 = firstStart;
|
||||||
int cursor2 = secondStart;
|
int cursor2 = secondStart;
|
||||||
T firstElement = firstList[cursor1++];
|
T firstElement = firstList[cursor1++];
|
||||||
T secondElement = secondList[cursor2++] as T;
|
T secondElement = secondList[cursor2++];
|
||||||
while (true) {
|
while (true) {
|
||||||
if (compare(firstElement, secondElement) <= 0) {
|
if (compare(firstElement, secondElement) <= 0) {
|
||||||
target[targetOffset++] = firstElement;
|
target[targetOffset++] = firstElement;
|
||||||
@ -340,7 +340,7 @@ void _merge<T>(
|
|||||||
} else {
|
} else {
|
||||||
target[targetOffset++] = secondElement;
|
target[targetOffset++] = secondElement;
|
||||||
if (cursor2 != secondEnd) {
|
if (cursor2 != secondEnd) {
|
||||||
secondElement = secondList[cursor2++] as T;
|
secondElement = secondList[cursor2++];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Second list empties first. Flushing first list here.
|
// Second list empties first. Flushing first list here.
|
||||||
|
@ -644,7 +644,7 @@ class _BottomSheetSuspendedCurve extends ParametricCurve<double> {
|
|||||||
/// * [DraggableScrollableSheet], which allows you to create a bottom sheet
|
/// * [DraggableScrollableSheet], which allows you to create a bottom sheet
|
||||||
/// that grows and then becomes scrollable once it reaches its maximum size.
|
/// that grows and then becomes scrollable once it reaches its maximum size.
|
||||||
/// * <https://material.io/design/components/sheets-bottom.html#modal-bottom-sheet>
|
/// * <https://material.io/design/components/sheets-bottom.html#modal-bottom-sheet>
|
||||||
Future<T> showModalBottomSheet<T>({
|
Future<T?> showModalBottomSheet<T>({
|
||||||
required BuildContext context,
|
required BuildContext context,
|
||||||
required WidgetBuilder builder,
|
required WidgetBuilder builder,
|
||||||
Color? backgroundColor,
|
Color? backgroundColor,
|
||||||
|
@ -955,7 +955,7 @@ Widget _buildMaterialDialogTransitions(BuildContext context, Animation<double> a
|
|||||||
/// * [showCupertinoDialog], which displays an iOS-style dialog.
|
/// * [showCupertinoDialog], which displays an iOS-style dialog.
|
||||||
/// * [showGeneralDialog], which allows for customization of the dialog popup.
|
/// * [showGeneralDialog], which allows for customization of the dialog popup.
|
||||||
/// * <https://material.io/design/components/dialogs.html>
|
/// * <https://material.io/design/components/dialogs.html>
|
||||||
Future<T> showDialog<T>({
|
Future<T?> showDialog<T>({
|
||||||
required BuildContext context,
|
required BuildContext context,
|
||||||
WidgetBuilder? builder,
|
WidgetBuilder? builder,
|
||||||
bool barrierDismissible = true,
|
bool barrierDismissible = true,
|
||||||
|
@ -120,7 +120,7 @@ typedef MaterialPropertyResolver<T> = T Function(Set<MaterialState> states);
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
/// {@end-tool}
|
/// {@end-tool}
|
||||||
abstract class MaterialStateColor extends Color implements MaterialStateProperty<Color?> {
|
abstract class MaterialStateColor extends Color implements MaterialStateProperty<Color> {
|
||||||
/// Creates a [MaterialStateColor].
|
/// Creates a [MaterialStateColor].
|
||||||
const MaterialStateColor(int defaultValue) : super(defaultValue);
|
const MaterialStateColor(int defaultValue) : super(defaultValue);
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ const double _inputFormLandscapeHeight = 108.0;
|
|||||||
/// * [CalendarDatePicker], which provides the calendar grid used by the date picker dialog.
|
/// * [CalendarDatePicker], which provides the calendar grid used by the date picker dialog.
|
||||||
/// * [InputDatePickerFormField], which provides a text input field for entering dates.
|
/// * [InputDatePickerFormField], which provides a text input field for entering dates.
|
||||||
///
|
///
|
||||||
Future<DateTime> showDatePicker({
|
Future<DateTime?> showDatePicker({
|
||||||
required BuildContext context,
|
required BuildContext context,
|
||||||
required DateTime initialDate,
|
required DateTime initialDate,
|
||||||
required DateTime firstDate,
|
required DateTime firstDate,
|
||||||
|
@ -105,7 +105,7 @@ const double _inputFormLandscapeHeight = 108.0;
|
|||||||
/// select a single date.
|
/// select a single date.
|
||||||
/// * [DateTimeRange], which is used to describe a date range.
|
/// * [DateTimeRange], which is used to describe a date range.
|
||||||
///
|
///
|
||||||
Future<DateTimeRange> showDateRangePicker({
|
Future<DateTimeRange?> showDateRangePicker({
|
||||||
required BuildContext context,
|
required BuildContext context,
|
||||||
DateTimeRange? initialDateRange,
|
DateTimeRange? initialDateRange,
|
||||||
required DateTime firstDate,
|
required DateTime firstDate,
|
||||||
|
@ -829,7 +829,7 @@ class _PopupMenuRoute<T> extends PopupRoute<T> {
|
|||||||
/// calling this method automatically.
|
/// calling this method automatically.
|
||||||
/// * [SemanticsConfiguration.namesRoute], for a description of edge triggered
|
/// * [SemanticsConfiguration.namesRoute], for a description of edge triggered
|
||||||
/// semantics.
|
/// semantics.
|
||||||
Future<T> showMenu<T>({
|
Future<T?> showMenu<T>({
|
||||||
required BuildContext context,
|
required BuildContext context,
|
||||||
required RelativeRect position,
|
required RelativeRect position,
|
||||||
required List<PopupMenuEntry<T>> items,
|
required List<PopupMenuEntry<T>> items,
|
||||||
@ -1088,7 +1088,7 @@ class PopupMenuButtonState<T> extends State<PopupMenuButton<T>> {
|
|||||||
final List<PopupMenuEntry<T>> items = widget.itemBuilder(context);
|
final List<PopupMenuEntry<T>> items = widget.itemBuilder(context);
|
||||||
// Only show the menu if there is something to show
|
// Only show the menu if there is something to show
|
||||||
if (items.isNotEmpty) {
|
if (items.isNotEmpty) {
|
||||||
showMenu<T>(
|
showMenu<T?>(
|
||||||
context: context,
|
context: context,
|
||||||
elevation: widget.elevation ?? popupMenuTheme.elevation,
|
elevation: widget.elevation ?? popupMenuTheme.elevation,
|
||||||
items: items,
|
items: items,
|
||||||
@ -1098,7 +1098,7 @@ class PopupMenuButtonState<T> extends State<PopupMenuButton<T>> {
|
|||||||
color: widget.color ?? popupMenuTheme.color,
|
color: widget.color ?? popupMenuTheme.color,
|
||||||
captureInheritedThemes: widget.captureInheritedThemes,
|
captureInheritedThemes: widget.captureInheritedThemes,
|
||||||
)
|
)
|
||||||
.then<void>((T newValue) {
|
.then<void>((T? newValue) {
|
||||||
if (!mounted)
|
if (!mounted)
|
||||||
return null;
|
return null;
|
||||||
if (newValue == null) {
|
if (newValue == null) {
|
||||||
|
@ -49,7 +49,7 @@ import 'theme.dart';
|
|||||||
/// See also:
|
/// See also:
|
||||||
///
|
///
|
||||||
/// * [SearchDelegate] to define the content of the search page.
|
/// * [SearchDelegate] to define the content of the search page.
|
||||||
Future<T> showSearch<T>({
|
Future<T?> showSearch<T>({
|
||||||
required BuildContext context,
|
required BuildContext context,
|
||||||
required SearchDelegate<T> delegate,
|
required SearchDelegate<T> delegate,
|
||||||
String? query = '',
|
String? query = '',
|
||||||
@ -387,7 +387,7 @@ class _SearchPageRoute<T> extends PageRoute<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didComplete(T result) {
|
void didComplete(T? result) {
|
||||||
super.didComplete(result);
|
super.didComplete(result);
|
||||||
assert(delegate._route == this);
|
assert(delegate._route == this);
|
||||||
delegate._route = null;
|
delegate._route = null;
|
||||||
|
@ -2175,7 +2175,7 @@ class _TimePickerDialogState extends State<_TimePickerDialog> {
|
|||||||
/// date picker.
|
/// date picker.
|
||||||
/// * [TimePickerThemeData], which allows you to customize the colors,
|
/// * [TimePickerThemeData], which allows you to customize the colors,
|
||||||
/// typography, and shape of the time picker.
|
/// typography, and shape of the time picker.
|
||||||
Future<TimeOfDay> showTimePicker({
|
Future<TimeOfDay?> showTimePicker({
|
||||||
required BuildContext context,
|
required BuildContext context,
|
||||||
required TimeOfDay initialTime,
|
required TimeOfDay initialTime,
|
||||||
TransitionBuilder? builder,
|
TransitionBuilder? builder,
|
||||||
|
@ -379,12 +379,12 @@ abstract class ImageProvider<T extends Object> {
|
|||||||
/// [FlutterError.onError], and the method will return null.
|
/// [FlutterError.onError], and the method will return null.
|
||||||
///
|
///
|
||||||
/// A completed return value of null indicates that an error has occurred.
|
/// A completed return value of null indicates that an error has occurred.
|
||||||
Future<ImageCacheStatus> obtainCacheStatus({
|
Future<ImageCacheStatus?> obtainCacheStatus({
|
||||||
required ImageConfiguration configuration,
|
required ImageConfiguration configuration,
|
||||||
ImageErrorListener? handleError,
|
ImageErrorListener? handleError,
|
||||||
}) {
|
}) {
|
||||||
assert(configuration != null);
|
assert(configuration != null);
|
||||||
final Completer<ImageCacheStatus> completer = Completer<ImageCacheStatus>();
|
final Completer<ImageCacheStatus?> completer = Completer<ImageCacheStatus?>();
|
||||||
_createErrorHandlerAndKey(
|
_createErrorHandlerAndKey(
|
||||||
configuration,
|
configuration,
|
||||||
(T key, ImageErrorListener innerHandleError) {
|
(T key, ImageErrorListener innerHandleError) {
|
||||||
|
@ -390,7 +390,7 @@ class RenderTable extends RenderBox {
|
|||||||
_textBaseline = textBaseline,
|
_textBaseline = textBaseline,
|
||||||
_defaultVerticalAlignment = defaultVerticalAlignment,
|
_defaultVerticalAlignment = defaultVerticalAlignment,
|
||||||
_configuration = configuration {
|
_configuration = configuration {
|
||||||
_children = <RenderBox>[]..length = _columns * _rows;
|
_children = <RenderBox?>[]..length = _columns * _rows;
|
||||||
this.rowDecorations = rowDecorations; // must use setter to initialize box painters array
|
this.rowDecorations = rowDecorations; // must use setter to initialize box painters array
|
||||||
children?.forEach(addRow);
|
children?.forEach(addRow);
|
||||||
}
|
}
|
||||||
@ -645,7 +645,7 @@ class RenderTable extends RenderBox {
|
|||||||
// update our internal values
|
// update our internal values
|
||||||
_columns = columns;
|
_columns = columns;
|
||||||
_rows = cells.length ~/ columns;
|
_rows = cells.length ~/ columns;
|
||||||
_children = cells.toList();
|
_children = List<RenderBox?>.from(cells);
|
||||||
assert(_children.length == rows * columns);
|
assert(_children.length == rows * columns);
|
||||||
markNeedsLayout();
|
markNeedsLayout();
|
||||||
}
|
}
|
||||||
|
@ -151,13 +151,13 @@ class RestorationManager extends ChangeNotifier {
|
|||||||
return SynchronousFuture<RestorationBucket?>(_rootBucket);
|
return SynchronousFuture<RestorationBucket?>(_rootBucket);
|
||||||
}
|
}
|
||||||
if (_pendingRootBucket == null) {
|
if (_pendingRootBucket == null) {
|
||||||
_pendingRootBucket = Completer<RestorationBucket>();
|
_pendingRootBucket = Completer<RestorationBucket?>();
|
||||||
_getRootBucketFromEngine();
|
_getRootBucketFromEngine();
|
||||||
}
|
}
|
||||||
return _pendingRootBucket!.future;
|
return _pendingRootBucket!.future;
|
||||||
}
|
}
|
||||||
RestorationBucket? _rootBucket; // May be null to indicate that restoration is turned off.
|
RestorationBucket? _rootBucket; // May be null to indicate that restoration is turned off.
|
||||||
Completer<RestorationBucket>? _pendingRootBucket;
|
Completer<RestorationBucket?>? _pendingRootBucket;
|
||||||
bool _rootBucketIsValid = false;
|
bool _rootBucketIsValid = false;
|
||||||
|
|
||||||
/// Returns true for the frame after [rootBucket] has been replaced with a
|
/// Returns true for the frame after [rootBucket] has been replaced with a
|
||||||
@ -186,7 +186,7 @@ class RestorationManager extends ChangeNotifier {
|
|||||||
void _parseAndHandleRestorationUpdateFromEngine(Map<dynamic, dynamic>? update) {
|
void _parseAndHandleRestorationUpdateFromEngine(Map<dynamic, dynamic>? update) {
|
||||||
handleRestorationUpdateFromEngine(
|
handleRestorationUpdateFromEngine(
|
||||||
enabled: update != null && update['enabled'] as bool,
|
enabled: update != null && update['enabled'] as bool,
|
||||||
data: update == null ? null : update['data'] as Uint8List,
|
data: update == null ? null : update['data'] as Uint8List?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -580,10 +580,10 @@ class RestorationBucket {
|
|||||||
/// * [remove], which removes a value from the bucket.
|
/// * [remove], which removes a value from the bucket.
|
||||||
/// * [contains], which checks whether any value is stored under a given
|
/// * [contains], which checks whether any value is stored under a given
|
||||||
/// restoration ID.
|
/// restoration ID.
|
||||||
P read<P>(String restorationId) {
|
P? read<P>(String restorationId) {
|
||||||
assert(_debugAssertNotDisposed());
|
assert(_debugAssertNotDisposed());
|
||||||
assert(restorationId != null);
|
assert(restorationId != null);
|
||||||
return _rawValues[restorationId] as P;
|
return _rawValues[restorationId] as P?;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stores the provided `value` of type `P` under the provided `restorationId`
|
/// Stores the provided `value` of type `P` under the provided `restorationId`
|
||||||
@ -624,11 +624,11 @@ class RestorationBucket {
|
|||||||
/// * [write], which stores a value in the bucket.
|
/// * [write], which stores a value in the bucket.
|
||||||
/// * [contains], which checks whether any value is stored under a given
|
/// * [contains], which checks whether any value is stored under a given
|
||||||
/// restoration ID.
|
/// restoration ID.
|
||||||
P remove<P>(String restorationId) {
|
P? remove<P>(String restorationId) {
|
||||||
assert(_debugAssertNotDisposed());
|
assert(_debugAssertNotDisposed());
|
||||||
assert(restorationId != null);
|
assert(restorationId != null);
|
||||||
final bool needsUpdate = _rawValues.containsKey(restorationId);
|
final bool needsUpdate = _rawValues.containsKey(restorationId);
|
||||||
final P result = _rawValues.remove(restorationId) as P;
|
final P? result = _rawValues.remove(restorationId) as P?;
|
||||||
if (_rawValues.isEmpty) {
|
if (_rawValues.isEmpty) {
|
||||||
_rawData.remove(_valuesMapKey);
|
_rawData.remove(_valuesMapKey);
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ typedef DismissDirectionCallback = void Function(DismissDirection direction);
|
|||||||
/// confirm or veto a dismiss gesture.
|
/// confirm or veto a dismiss gesture.
|
||||||
///
|
///
|
||||||
/// Used by [Dismissible.confirmDismiss].
|
/// Used by [Dismissible.confirmDismiss].
|
||||||
typedef ConfirmDismissCallback = Future<bool> Function(DismissDirection direction);
|
typedef ConfirmDismissCallback = Future<bool?> Function(DismissDirection direction);
|
||||||
|
|
||||||
/// The direction in which a [Dismissible] can be dismissed.
|
/// The direction in which a [Dismissible] can be dismissed.
|
||||||
enum DismissDirection {
|
enum DismissDirection {
|
||||||
@ -120,7 +120,7 @@ class Dismissible extends StatefulWidget {
|
|||||||
/// If the returned Future<bool> completes true, then this widget will be
|
/// If the returned Future<bool> completes true, then this widget will be
|
||||||
/// dismissed, otherwise it will be moved back to its original location.
|
/// dismissed, otherwise it will be moved back to its original location.
|
||||||
///
|
///
|
||||||
/// If the returned Future<bool> completes to false or null the [onResize]
|
/// If the returned Future<bool?> completes to false or null the [onResize]
|
||||||
/// and [onDismissed] callbacks will not run.
|
/// and [onDismissed] callbacks will not run.
|
||||||
final ConfirmDismissCallback? confirmDismiss;
|
final ConfirmDismissCallback? confirmDismiss;
|
||||||
|
|
||||||
@ -458,7 +458,7 @@ class _DismissibleState extends State<Dismissible> with TickerProviderStateMixin
|
|||||||
updateKeepAlive();
|
updateKeepAlive();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> _confirmStartResizeAnimation() async {
|
Future<bool?> _confirmStartResizeAnimation() async {
|
||||||
if (widget.confirmDismiss != null) {
|
if (widget.confirmDismiss != null) {
|
||||||
final DismissDirection direction = _dismissDirection!;
|
final DismissDirection direction = _dismissDirection!;
|
||||||
assert(direction != null);
|
assert(direction != null);
|
||||||
|
@ -300,7 +300,7 @@ class Hero extends StatefulWidget {
|
|||||||
// the Hero is inside a nested Navigator and should only be
|
// the Hero is inside a nested Navigator and should only be
|
||||||
// considered for animation if it is part of the top-most route in
|
// considered for animation if it is part of the top-most route in
|
||||||
// that nested Navigator and if that route is also a PageRoute.
|
// that nested Navigator and if that route is also a PageRoute.
|
||||||
final ModalRoute<Object>? heroRoute = ModalRoute.of(hero);
|
final ModalRoute<Object?>? heroRoute = ModalRoute.of(hero);
|
||||||
if (heroRoute != null && heroRoute is PageRoute && heroRoute.isCurrent) {
|
if (heroRoute != null && heroRoute is PageRoute && heroRoute.isCurrent) {
|
||||||
inviteHero(hero, tag);
|
inviteHero(hero, tag);
|
||||||
}
|
}
|
||||||
|
@ -450,7 +450,7 @@ class Localizations extends StatefulWidget {
|
|||||||
assert(context != null);
|
assert(context != null);
|
||||||
assert(type != null);
|
assert(type != null);
|
||||||
final _LocalizationsScope? scope = context.dependOnInheritedWidgetOfExactType<_LocalizationsScope>();
|
final _LocalizationsScope? scope = context.dependOnInheritedWidgetOfExactType<_LocalizationsScope>();
|
||||||
return scope?.localizationsState.resourcesFor<T>(type);
|
return scope?.localizationsState.resourcesFor<T?>(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -159,7 +159,7 @@ class AnimatedModalBarrier extends AnimatedWidget {
|
|||||||
///
|
///
|
||||||
/// * [ModalRoute.barrierColor], which controls this property for the
|
/// * [ModalRoute.barrierColor], which controls this property for the
|
||||||
/// [AnimatedModalBarrier] built by [ModalRoute] pages.
|
/// [AnimatedModalBarrier] built by [ModalRoute] pages.
|
||||||
Animation<Color> get color => listenable as Animation<Color>;
|
Animation<Color?> get color => listenable as Animation<Color?>;
|
||||||
|
|
||||||
/// Whether touching the barrier will pop the current route off the [Navigator].
|
/// Whether touching the barrier will pop the current route off the [Navigator].
|
||||||
///
|
///
|
||||||
|
@ -306,8 +306,8 @@ abstract class Route<T> {
|
|||||||
/// The future completes with the value given to [Navigator.pop], if any, or
|
/// The future completes with the value given to [Navigator.pop], if any, or
|
||||||
/// else the value of [currentResult]. See [didComplete] for more discussion
|
/// else the value of [currentResult]. See [didComplete] for more discussion
|
||||||
/// on this topic.
|
/// on this topic.
|
||||||
Future<T> get popped => _popCompleter.future;
|
Future<T?> get popped => _popCompleter.future;
|
||||||
final Completer<T> _popCompleter = Completer<T>();
|
final Completer<T?> _popCompleter = Completer<T?>();
|
||||||
|
|
||||||
/// A request was made to pop this route. If the route can handle it
|
/// A request was made to pop this route. If the route can handle it
|
||||||
/// internally (e.g. because it has its own stack of internal state) then
|
/// internally (e.g. because it has its own stack of internal state) then
|
||||||
@ -329,7 +329,7 @@ abstract class Route<T> {
|
|||||||
/// See [popped], [didComplete], and [currentResult] for a discussion of the
|
/// See [popped], [didComplete], and [currentResult] for a discussion of the
|
||||||
/// `result` argument.
|
/// `result` argument.
|
||||||
@mustCallSuper
|
@mustCallSuper
|
||||||
bool didPop(T result) {
|
bool didPop(T? result) {
|
||||||
didComplete(result);
|
didComplete(result);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -351,7 +351,7 @@ abstract class Route<T> {
|
|||||||
/// iOS-style back gesture. See [NavigatorState.didStartUserGesture].
|
/// iOS-style back gesture. See [NavigatorState.didStartUserGesture].
|
||||||
@protected
|
@protected
|
||||||
@mustCallSuper
|
@mustCallSuper
|
||||||
void didComplete(T result) {
|
void didComplete(T? result) {
|
||||||
_popCompleter.complete(result ?? currentResult);
|
_popCompleter.complete(result ?? currentResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1693,7 +1693,7 @@ class Navigator extends StatefulWidget {
|
|||||||
/// * [restorablePushNamed], which pushes a route that can be restored
|
/// * [restorablePushNamed], which pushes a route that can be restored
|
||||||
/// during state restoration.
|
/// during state restoration.
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
static Future<T> pushNamed<T extends Object?>(
|
static Future<T?> pushNamed<T extends Object?>(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
String routeName, {
|
String routeName, {
|
||||||
Object? arguments,
|
Object? arguments,
|
||||||
@ -1810,7 +1810,7 @@ class Navigator extends StatefulWidget {
|
|||||||
/// * [restorablePushReplacementNamed], which pushes a replacement route that
|
/// * [restorablePushReplacementNamed], which pushes a replacement route that
|
||||||
/// can be restored during state restoration.
|
/// can be restored during state restoration.
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
static Future<T> pushReplacementNamed<T extends Object?, TO extends Object?>(
|
static Future<T?> pushReplacementNamed<T extends Object?, TO extends Object?>(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
String routeName, {
|
String routeName, {
|
||||||
TO? result,
|
TO? result,
|
||||||
@ -1904,7 +1904,7 @@ class Navigator extends StatefulWidget {
|
|||||||
/// * [restorablePopAndPushNamed], which pushes a new route that can be
|
/// * [restorablePopAndPushNamed], which pushes a new route that can be
|
||||||
/// restored during state restoration.
|
/// restored during state restoration.
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
static Future<T> popAndPushNamed<T extends Object?, TO extends Object?>(
|
static Future<T?> popAndPushNamed<T extends Object?, TO extends Object?>(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
String routeName, {
|
String routeName, {
|
||||||
TO? result,
|
TO? result,
|
||||||
@ -2008,7 +2008,7 @@ class Navigator extends StatefulWidget {
|
|||||||
/// * [restorablePushNamedAndRemoveUntil], which pushes a new route that can
|
/// * [restorablePushNamedAndRemoveUntil], which pushes a new route that can
|
||||||
/// be restored during state restoration.
|
/// be restored during state restoration.
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
static Future<T> pushNamedAndRemoveUntil<T extends Object?>(
|
static Future<T?> pushNamedAndRemoveUntil<T extends Object?>(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
String newRouteName,
|
String newRouteName,
|
||||||
RoutePredicate predicate, {
|
RoutePredicate predicate, {
|
||||||
@ -2087,7 +2087,7 @@ class Navigator extends StatefulWidget {
|
|||||||
/// * [restorablePush], which pushes a route that can be restored during
|
/// * [restorablePush], which pushes a route that can be restored during
|
||||||
/// state restoration.
|
/// state restoration.
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
static Future<T> push<T extends Object?>(BuildContext context, Route<T> route) {
|
static Future<T?> push<T extends Object?>(BuildContext context, Route<T> route) {
|
||||||
return Navigator.of(context)!.push(route);
|
return Navigator.of(context)!.push(route);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2190,7 +2190,7 @@ class Navigator extends StatefulWidget {
|
|||||||
/// * [restorablePushReplacement], which pushes a replacement route that can
|
/// * [restorablePushReplacement], which pushes a replacement route that can
|
||||||
/// be restored during state restoration.
|
/// be restored during state restoration.
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
static Future<T> pushReplacement<T extends Object?, TO extends Object?>(BuildContext context, Route<T> newRoute, { TO? result }) {
|
static Future<T?> pushReplacement<T extends Object?, TO extends Object?>(BuildContext context, Route<T> newRoute, { TO? result }) {
|
||||||
return Navigator.of(context)!.pushReplacement<T, TO>(newRoute, result: result);
|
return Navigator.of(context)!.pushReplacement<T, TO>(newRoute, result: result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2295,7 +2295,7 @@ class Navigator extends StatefulWidget {
|
|||||||
/// * [restorablePushAndRemoveUntil], which pushes a route that can be
|
/// * [restorablePushAndRemoveUntil], which pushes a route that can be
|
||||||
/// restored during state restoration.
|
/// restored during state restoration.
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
static Future<T> pushAndRemoveUntil<T extends Object?>(BuildContext context, Route<T> newRoute, RoutePredicate predicate) {
|
static Future<T?> pushAndRemoveUntil<T extends Object?>(BuildContext context, Route<T> newRoute, RoutePredicate predicate) {
|
||||||
return Navigator.of(context)!.pushAndRemoveUntil<T>(newRoute, predicate);
|
return Navigator.of(context)!.pushAndRemoveUntil<T>(newRoute, predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2876,7 +2876,7 @@ class _RouteEntry extends RouteTransitionRecord {
|
|||||||
// User-provided restoration ids of Pages are prefixed with 'p+'. Generated
|
// User-provided restoration ids of Pages are prefixed with 'p+'. Generated
|
||||||
// ids for pageless routes are prefixed with 'r+' to avoid clashes.
|
// ids for pageless routes are prefixed with 'r+' to avoid clashes.
|
||||||
if (hasPage) {
|
if (hasPage) {
|
||||||
final Page<Object> page = route.settings as Page<Object>;
|
final Page<Object?> page = route.settings as Page<Object?>;
|
||||||
return page.restorationId != null ? 'p+${page.restorationId}' : null;
|
return page.restorationId != null ? 'p+${page.restorationId}' : null;
|
||||||
}
|
}
|
||||||
if (restorationInformation != null) {
|
if (restorationInformation != null) {
|
||||||
@ -4000,7 +4000,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
|
|||||||
/// * [restorablePushNamed], which pushes a route that can be restored
|
/// * [restorablePushNamed], which pushes a route that can be restored
|
||||||
/// during state restoration.
|
/// during state restoration.
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
Future<T> pushNamed<T extends Object?>(
|
Future<T?> pushNamed<T extends Object?>(
|
||||||
String routeName, {
|
String routeName, {
|
||||||
Object? arguments,
|
Object? arguments,
|
||||||
}) {
|
}) {
|
||||||
@ -4067,7 +4067,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
|
|||||||
/// * [restorablePushReplacementNamed], which pushes a replacement route that
|
/// * [restorablePushReplacementNamed], which pushes a replacement route that
|
||||||
/// can be restored during state restoration.
|
/// can be restored during state restoration.
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
Future<T> pushReplacementNamed<T extends Object?, TO extends Object?>(
|
Future<T?> pushReplacementNamed<T extends Object?, TO extends Object?>(
|
||||||
String routeName, {
|
String routeName, {
|
||||||
TO? result,
|
TO? result,
|
||||||
Object? arguments,
|
Object? arguments,
|
||||||
@ -4137,7 +4137,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
|
|||||||
/// * [restorablePopAndPushNamed], which pushes a new route that can be
|
/// * [restorablePopAndPushNamed], which pushes a new route that can be
|
||||||
/// restored during state restoration.
|
/// restored during state restoration.
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
Future<T> popAndPushNamed<T extends Object?, TO extends Object?>(
|
Future<T?> popAndPushNamed<T extends Object?, TO extends Object?>(
|
||||||
String routeName, {
|
String routeName, {
|
||||||
TO? result,
|
TO? result,
|
||||||
Object? arguments,
|
Object? arguments,
|
||||||
@ -4200,7 +4200,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
|
|||||||
/// * [restorablePushNamedAndRemoveUntil], which pushes a new route that can
|
/// * [restorablePushNamedAndRemoveUntil], which pushes a new route that can
|
||||||
/// be restored during state restoration.
|
/// be restored during state restoration.
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
Future<T> pushNamedAndRemoveUntil<T extends Object?>(
|
Future<T?> pushNamedAndRemoveUntil<T extends Object?>(
|
||||||
String newRouteName,
|
String newRouteName,
|
||||||
RoutePredicate predicate, {
|
RoutePredicate predicate, {
|
||||||
Object? arguments,
|
Object? arguments,
|
||||||
@ -4266,7 +4266,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
|
|||||||
/// * [restorablePush], which pushes a route that can be restored during
|
/// * [restorablePush], which pushes a route that can be restored during
|
||||||
/// state restoration.
|
/// state restoration.
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
Future<T> push<T extends Object?>(Route<T> route) {
|
Future<T?> push<T extends Object?>(Route<T> route) {
|
||||||
_pushEntry(_RouteEntry(route, initialState: _RouteLifecycle.push));
|
_pushEntry(_RouteEntry(route, initialState: _RouteLifecycle.push));
|
||||||
return route.popped;
|
return route.popped;
|
||||||
}
|
}
|
||||||
@ -4410,7 +4410,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
|
|||||||
/// * [restorablePushReplacement], which pushes a replacement route that can
|
/// * [restorablePushReplacement], which pushes a replacement route that can
|
||||||
/// be restored during state restoration.
|
/// be restored during state restoration.
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
Future<T> pushReplacement<T extends Object?, TO extends Object?>(Route<T> newRoute, { TO? result }) {
|
Future<T?> pushReplacement<T extends Object?, TO extends Object?>(Route<T> newRoute, { TO? result }) {
|
||||||
assert(newRoute != null);
|
assert(newRoute != null);
|
||||||
assert(newRoute._navigator == null);
|
assert(newRoute._navigator == null);
|
||||||
_pushReplacementEntry(_RouteEntry(newRoute, initialState: _RouteLifecycle.pushReplace), result);
|
_pushReplacementEntry(_RouteEntry(newRoute, initialState: _RouteLifecycle.pushReplace), result);
|
||||||
@ -4516,7 +4516,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
|
|||||||
/// * [restorablePushAndRemoveUntil], which pushes a route that can be
|
/// * [restorablePushAndRemoveUntil], which pushes a route that can be
|
||||||
/// restored during state restoration.
|
/// restored during state restoration.
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
Future<T> pushAndRemoveUntil<T extends Object?>(Route<T> newRoute, RoutePredicate predicate) {
|
Future<T?> pushAndRemoveUntil<T extends Object?>(Route<T> newRoute, RoutePredicate predicate) {
|
||||||
assert(newRoute != null);
|
assert(newRoute != null);
|
||||||
assert(newRoute._navigator == null);
|
assert(newRoute._navigator == null);
|
||||||
assert(newRoute.overlayEntries.isEmpty);
|
assert(newRoute.overlayEntries.isEmpty);
|
||||||
@ -5116,9 +5116,9 @@ abstract class _RestorationInformation {
|
|||||||
|
|
||||||
factory _RestorationInformation.fromSerializableData(Object data) {
|
factory _RestorationInformation.fromSerializableData(Object data) {
|
||||||
assert(data != null);
|
assert(data != null);
|
||||||
final List<Object> casted = data as List<Object>;
|
final List<Object?> casted = data as List<Object?>;
|
||||||
assert(casted.isNotEmpty);
|
assert(casted.isNotEmpty);
|
||||||
final _RouteRestorationType type = _RouteRestorationType.values[casted[0] as int];
|
final _RouteRestorationType type = _RouteRestorationType.values[casted[0]! as int];
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case _RouteRestorationType.named:
|
case _RouteRestorationType.named:
|
||||||
return _NamedRestorationInformation.fromSerializableData(casted.sublist(1));
|
return _NamedRestorationInformation.fromSerializableData(casted.sublist(1));
|
||||||
@ -5167,11 +5167,11 @@ class _NamedRestorationInformation extends _RestorationInformation {
|
|||||||
required this.restorationScopeId,
|
required this.restorationScopeId,
|
||||||
}) : assert(name != null), super(_RouteRestorationType.named);
|
}) : assert(name != null), super(_RouteRestorationType.named);
|
||||||
|
|
||||||
factory _NamedRestorationInformation.fromSerializableData(List<Object> data) {
|
factory _NamedRestorationInformation.fromSerializableData(List<Object?> data) {
|
||||||
assert(data.length >= 2);
|
assert(data.length >= 2);
|
||||||
return _NamedRestorationInformation(
|
return _NamedRestorationInformation(
|
||||||
restorationScopeId: data[0] as int,
|
restorationScopeId: data[0]! as int,
|
||||||
name: data[1] as String,
|
name: data[1]! as String,
|
||||||
arguments: data.length > 2 ? data[2] : null,
|
arguments: data.length > 2 ? data[2] : null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -5206,11 +5206,11 @@ class _AnonymousRestorationInformation extends _RestorationInformation {
|
|||||||
required this.restorationScopeId,
|
required this.restorationScopeId,
|
||||||
}) : assert(routeBuilder != null), super(_RouteRestorationType.anonymous);
|
}) : assert(routeBuilder != null), super(_RouteRestorationType.anonymous);
|
||||||
|
|
||||||
factory _AnonymousRestorationInformation.fromSerializableData(List<Object> data) {
|
factory _AnonymousRestorationInformation.fromSerializableData(List<Object?> data) {
|
||||||
assert(data.length > 1);
|
assert(data.length > 1);
|
||||||
final RestorableRouteBuilder routeBuilder = ui.PluginUtilities.getCallbackFromHandle(ui.CallbackHandle.fromRawHandle(data[1] as int))! as RestorableRouteBuilder;
|
final RestorableRouteBuilder routeBuilder = ui.PluginUtilities.getCallbackFromHandle(ui.CallbackHandle.fromRawHandle(data[1]! as int))! as RestorableRouteBuilder;
|
||||||
return _AnonymousRestorationInformation(
|
return _AnonymousRestorationInformation(
|
||||||
restorationScopeId: data[0] as int,
|
restorationScopeId: data[0]! as int,
|
||||||
routeBuilder: routeBuilder,
|
routeBuilder: routeBuilder,
|
||||||
arguments: data.length > 2 ? data[2] : null,
|
arguments: data.length > 2 ? data[2] : null,
|
||||||
);
|
);
|
||||||
@ -5383,10 +5383,10 @@ class _HistoryProperty extends RestorableProperty<Map<String?, List<Object>>?> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String?, List<Object>>? fromPrimitives(Object data) {
|
Map<String?, List<Object>>? fromPrimitives(Object? data) {
|
||||||
final Map<dynamic, dynamic> casted = data as Map<dynamic, dynamic>;
|
final Map<dynamic, dynamic> casted = data! as Map<dynamic, dynamic>;
|
||||||
return casted.map<String, List<Object>>((dynamic key, dynamic value) => MapEntry<String, List<Object>>(
|
return casted.map<String?, List<Object>>((dynamic key, dynamic value) => MapEntry<String?, List<Object>>(
|
||||||
key as String,
|
key as String?,
|
||||||
List<Object>.from(value as List<dynamic>, growable: true),
|
List<Object>.from(value as List<dynamic>, growable: true),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -5694,9 +5694,9 @@ class RestorableRouteFuture<T> extends RestorableProperty<String?> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String fromPrimitives(Object data) {
|
String fromPrimitives(Object? data) {
|
||||||
assert(data != null);
|
assert(data != null);
|
||||||
return data as String;
|
return data! as String;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _disposed = false;
|
bool _disposed = false;
|
||||||
|
@ -425,7 +425,7 @@ abstract class RestorableProperty<T> extends ChangeNotifier {
|
|||||||
/// [RestorableProperty]. Whenever new restoration data has been provided to
|
/// [RestorableProperty]. Whenever new restoration data has been provided to
|
||||||
/// the [RestorationMixin] the property is registered to, either this method
|
/// the [RestorationMixin] the property is registered to, either this method
|
||||||
/// or [createDefaultValue] is called before [initWithValue] is invoked.
|
/// or [createDefaultValue] is called before [initWithValue] is invoked.
|
||||||
T fromPrimitives(Object data);
|
T fromPrimitives(Object? data);
|
||||||
|
|
||||||
/// Called by the [RestorationMixin] with the `value` returned by either
|
/// Called by the [RestorationMixin] with the `value` returned by either
|
||||||
/// [createDefaultValue] or [fromPrimitives] to set the value that this
|
/// [createDefaultValue] or [fromPrimitives] to set the value that this
|
||||||
@ -884,7 +884,7 @@ mixin RestorationMixin<S extends StatefulWidget> on State<S> {
|
|||||||
/// restore the internal state of a [State] object, it may be removed from the
|
/// restore the internal state of a [State] object, it may be removed from the
|
||||||
/// restoration data by calling this method.
|
/// restoration data by calling this method.
|
||||||
@protected
|
@protected
|
||||||
void unregisterFromRestoration(RestorableProperty<Object> property) {
|
void unregisterFromRestoration(RestorableProperty<Object?> property) {
|
||||||
assert(property != null);
|
assert(property != null);
|
||||||
assert(property._owner == this);
|
assert(property._owner == this);
|
||||||
_bucket?.remove<Object?>(property._restorationId!);
|
_bucket?.remove<Object?>(property._restorationId!);
|
||||||
|
@ -173,9 +173,9 @@ class _RestorablePrimitiveValue<T extends Object> extends RestorableValue<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
T fromPrimitives(Object serialized) {
|
T fromPrimitives(Object? serialized) {
|
||||||
assert(serialized != null);
|
assert(serialized != null);
|
||||||
return serialized as T;
|
return serialized! as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -360,8 +360,8 @@ class RestorableTextEditingController extends RestorableChangeNotifier<TextEditi
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
TextEditingController fromPrimitives(Object data) {
|
TextEditingController fromPrimitives(Object? data) {
|
||||||
return TextEditingController(text: data as String);
|
return TextEditingController(text: data! as String);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -62,7 +62,7 @@ abstract class OverlayRoute<T> extends Route<T> {
|
|||||||
bool get finishedWhenPopped => true;
|
bool get finishedWhenPopped => true;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool didPop(T result) {
|
bool didPop(T? result) {
|
||||||
final bool returnValue = super.didPop(result);
|
final bool returnValue = super.didPop(result);
|
||||||
assert(returnValue);
|
assert(returnValue);
|
||||||
if (finishedWhenPopped)
|
if (finishedWhenPopped)
|
||||||
@ -90,8 +90,8 @@ abstract class TransitionRoute<T> extends OverlayRoute<T> {
|
|||||||
/// This future completes once the animation has been dismissed. That will be
|
/// This future completes once the animation has been dismissed. That will be
|
||||||
/// after [popped], because [popped] typically completes before the animation
|
/// after [popped], because [popped] typically completes before the animation
|
||||||
/// even starts, as soon as the route is popped.
|
/// even starts, as soon as the route is popped.
|
||||||
Future<T> get completed => _transitionCompleter.future;
|
Future<T?> get completed => _transitionCompleter.future;
|
||||||
final Completer<T> _transitionCompleter = Completer<T>();
|
final Completer<T?> _transitionCompleter = Completer<T?>();
|
||||||
|
|
||||||
/// {@template flutter.widgets.transitionRoute.transitionDuration}
|
/// {@template flutter.widgets.transitionRoute.transitionDuration}
|
||||||
/// The duration the transition going forwards.
|
/// The duration the transition going forwards.
|
||||||
@ -235,7 +235,7 @@ abstract class TransitionRoute<T> extends OverlayRoute<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool didPop(T result) {
|
bool didPop(T? result) {
|
||||||
assert(_controller != null, '$runtimeType.didPop called before calling install() or after calling dispose().');
|
assert(_controller != null, '$runtimeType.didPop called before calling install() or after calling dispose().');
|
||||||
assert(!_transitionCompleter.isCompleted, 'Cannot reuse a $runtimeType after disposing it.');
|
assert(!_transitionCompleter.isCompleted, 'Cannot reuse a $runtimeType after disposing it.');
|
||||||
_result = result;
|
_result = result;
|
||||||
@ -631,7 +631,7 @@ mixin LocalHistoryRoute<T> on Route<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool didPop(T result) {
|
bool didPop(T? result) {
|
||||||
if (_localHistory != null && _localHistory!.isNotEmpty) {
|
if (_localHistory != null && _localHistory!.isNotEmpty) {
|
||||||
final LocalHistoryEntry entry = _localHistory!.removeLast();
|
final LocalHistoryEntry entry = _localHistory!.removeLast();
|
||||||
assert(entry._owner == this);
|
assert(entry._owner == this);
|
||||||
@ -1818,7 +1818,7 @@ class _DialogRoute<T> extends PopupRoute<T> {
|
|||||||
///
|
///
|
||||||
/// * [showDialog], which displays a Material-style dialog.
|
/// * [showDialog], which displays a Material-style dialog.
|
||||||
/// * [showCupertinoDialog], which displays an iOS-style dialog.
|
/// * [showCupertinoDialog], which displays an iOS-style dialog.
|
||||||
Future<T> showGeneralDialog<T extends Object?>({
|
Future<T?> showGeneralDialog<T extends Object?>({
|
||||||
required BuildContext context,
|
required BuildContext context,
|
||||||
required RoutePageBuilder pageBuilder,
|
required RoutePageBuilder pageBuilder,
|
||||||
bool barrierDismissible = false,
|
bool barrierDismissible = false,
|
||||||
|
@ -1084,8 +1084,8 @@ class _RestorableScrollOffset extends RestorableValue<double?> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
double fromPrimitives(Object data) {
|
double fromPrimitives(Object? data) {
|
||||||
return data as double;
|
return data! as double;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -303,16 +303,16 @@ class _TableElement extends RenderObjectElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void insertRenderObjectChild(RenderObject child, IndexedSlot<Element>? slot) {
|
void insertRenderObjectChild(RenderObject child, dynamic slot) {
|
||||||
renderObject.setupParentData(child);
|
renderObject.setupParentData(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void moveRenderObjectChild(RenderObject child, IndexedSlot<Element>? oldSlot, IndexedSlot<Element>? newSlot) {
|
void moveRenderObjectChild(RenderObject child, dynamic oldSlot, dynamic newSlot) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void removeRenderObjectChild(RenderObject child, IndexedSlot<Element>? slot) {
|
void removeRenderObjectChild(RenderObject child, dynamic slot) {
|
||||||
final TableCellParentData childParentData = child.parentData! as TableCellParentData;
|
final TableCellParentData childParentData = child.parentData! as TableCellParentData;
|
||||||
renderObject.setChild(childParentData.x!, childParentData.y!, null);
|
renderObject.setChild(childParentData.x!, childParentData.y!, null);
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ void main() {
|
|||||||
|
|
||||||
test('Notifies onBytesReceived with gzipped numbers', () async {
|
test('Notifies onBytesReceived with gzipped numbers', () async {
|
||||||
response.contentLength = gzipped.length;
|
response.contentLength = gzipped.length;
|
||||||
final List<int?> records = <int>[];
|
final List<int?> records = <int?>[];
|
||||||
await consolidateHttpClientResponseBytes(
|
await consolidateHttpClientResponseBytes(
|
||||||
response,
|
response,
|
||||||
onBytesReceived: (int cumulative, int? total) {
|
onBytesReceived: (int cumulative, int? total) {
|
||||||
|
@ -76,7 +76,7 @@ void main() {
|
|||||||
test('subtreeDepth 1', () {
|
test('subtreeDepth 1', () {
|
||||||
final Map<String, Object?> result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate(subtreeDepth: 1));
|
final Map<String, Object?> result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate(subtreeDepth: 1));
|
||||||
expect(result.containsKey('properties'), isFalse);
|
expect(result.containsKey('properties'), isFalse);
|
||||||
final List<Map<String, Object>> children = result['children']! as List<Map<String, Object>>;
|
final List<Map<String, Object?>> children = result['children']! as List<Map<String, Object?>>;
|
||||||
expect(children[0].containsKey('children'), isFalse);
|
expect(children[0].containsKey('children'), isFalse);
|
||||||
expect(children[1].containsKey('children'), isFalse);
|
expect(children[1].containsKey('children'), isFalse);
|
||||||
expect(children[2].containsKey('children'), isFalse);
|
expect(children[2].containsKey('children'), isFalse);
|
||||||
@ -85,7 +85,7 @@ void main() {
|
|||||||
test('subtreeDepth 5', () {
|
test('subtreeDepth 5', () {
|
||||||
final Map<String, Object?> result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate(subtreeDepth: 5));
|
final Map<String, Object?> result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate(subtreeDepth: 5));
|
||||||
expect(result.containsKey('properties'), isFalse);
|
expect(result.containsKey('properties'), isFalse);
|
||||||
final List<Map<String, Object>> children = result['children']! as List<Map<String, Object>>;
|
final List<Map<String, Object?>> children = result['children']! as List<Map<String, Object?>>;
|
||||||
expect(children[0]['children'], hasLength(0));
|
expect(children[0]['children'], hasLength(0));
|
||||||
expect(children[1]['children'], hasLength(3));
|
expect(children[1]['children'], hasLength(3));
|
||||||
expect(children[2]['children'], hasLength(0));
|
expect(children[2]['children'], hasLength(0));
|
||||||
@ -103,7 +103,7 @@ void main() {
|
|||||||
subtreeDepth: 1,
|
subtreeDepth: 1,
|
||||||
));
|
));
|
||||||
expect(result['properties'], hasLength(7));
|
expect(result['properties'], hasLength(7));
|
||||||
final List<Map<String, Object>> children = result['children']! as List<Map<String, Object>>;
|
final List<Map<String, Object?>> children = result['children']! as List<Map<String, Object?>>;
|
||||||
expect(children, hasLength(3));
|
expect(children, hasLength(3));
|
||||||
expect(children[0]['properties'], hasLength(0));
|
expect(children[0]['properties'], hasLength(0));
|
||||||
expect(children[1]['properties'], hasLength(2));
|
expect(children[1]['properties'], hasLength(2));
|
||||||
@ -119,13 +119,13 @@ void main() {
|
|||||||
},
|
},
|
||||||
));
|
));
|
||||||
expect(result['foo'], isTrue);
|
expect(result['foo'], isTrue);
|
||||||
final List<Map<String, Object>> properties = result['properties']! as List<Map<String, Object>>;
|
final List<Map<String, Object?>> properties = result['properties']! as List<Map<String, Object?>>;
|
||||||
expect(properties, hasLength(7));
|
expect(properties, hasLength(7));
|
||||||
expect(properties.every((Map<String, Object> property) => property['foo'] == true), isTrue);
|
expect(properties.every((Map<String, Object?> property) => property['foo'] == true), isTrue);
|
||||||
|
|
||||||
final List<Map<String, Object>> children = result['children']! as List<Map<String, Object>>;
|
final List<Map<String, Object?>> children = result['children']! as List<Map<String, Object?>>;
|
||||||
expect(children, hasLength(3));
|
expect(children, hasLength(3));
|
||||||
expect(children.every((Map<String, Object> child) => child['foo'] == true), isTrue);
|
expect(children.every((Map<String, Object?> child) => child['foo'] == true), isTrue);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('filterProperties - sublist', () {
|
test('filterProperties - sublist', () {
|
||||||
@ -135,9 +135,9 @@ void main() {
|
|||||||
return nodes.whereType<StringProperty>().toList();
|
return nodes.whereType<StringProperty>().toList();
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
final List<Map<String, Object>> properties = result['properties']! as List<Map<String, Object>>;
|
final List<Map<String, Object?>> properties = result['properties']! as List<Map<String, Object?>>;
|
||||||
expect(properties, hasLength(3));
|
expect(properties, hasLength(3));
|
||||||
expect(properties.every((Map<String, Object> property) => property['type'] == 'StringProperty'), isTrue);
|
expect(properties.every((Map<String, Object?> property) => property['type'] == 'StringProperty'), isTrue);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('filterProperties - replace', () {
|
test('filterProperties - replace', () {
|
||||||
@ -154,7 +154,7 @@ void main() {
|
|||||||
];
|
];
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
final List<Map<String, Object>> properties = result['properties']! as List<Map<String, Object>>;
|
final List<Map<String, Object?>> properties = result['properties']! as List<Map<String, Object?>>;
|
||||||
expect(properties, hasLength(1));
|
expect(properties, hasLength(1));
|
||||||
expect(properties.single['name'], 'foo');
|
expect(properties.single['name'], 'foo');
|
||||||
});
|
});
|
||||||
@ -166,7 +166,7 @@ void main() {
|
|||||||
return nodes.where((DiagnosticsNode node) => node.getProperties().isEmpty).toList();
|
return nodes.where((DiagnosticsNode node) => node.getProperties().isEmpty).toList();
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
final List<Map<String, Object>> children = result['children']! as List<Map<String, Object>>;
|
final List<Map<String, Object?>> children = result['children']! as List<Map<String, Object?>>;
|
||||||
expect(children, hasLength(1));
|
expect(children, hasLength(1));
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -177,7 +177,7 @@ void main() {
|
|||||||
return nodes.expand((DiagnosticsNode node) => node.getChildren()).toList();
|
return nodes.expand((DiagnosticsNode node) => node.getChildren()).toList();
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
final List<Map<String, Object>> children = result['children']! as List<Map<String, Object>>;
|
final List<Map<String, Object?>> children = result['children']! as List<Map<String, Object?>>;
|
||||||
expect(children, hasLength(3));
|
expect(children, hasLength(3));
|
||||||
expect(children.first['name'], 'child node B1');
|
expect(children.first['name'], 'child node B1');
|
||||||
});
|
});
|
||||||
@ -190,11 +190,11 @@ void main() {
|
|||||||
return nodes.take(2).toList();
|
return nodes.take(2).toList();
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
final List<Map<String, Object>> children = result['children']! as List<Map<String, Object>>;
|
final List<Map<String, Object?>> children = result['children']! as List<Map<String, Object?>>;
|
||||||
expect(children, hasLength(3));
|
expect(children, hasLength(3));
|
||||||
expect(children.last['truncated'], isTrue);
|
expect(children.last['truncated'], isTrue);
|
||||||
|
|
||||||
final List<Map<String, Object>> properties = result['properties']! as List<Map<String, Object>>;
|
final List<Map<String, Object?>> properties = result['properties']! as List<Map<String, Object?>>;
|
||||||
expect(properties, hasLength(3));
|
expect(properties, hasLength(3));
|
||||||
expect(properties.last['truncated'], isTrue);
|
expect(properties.last['truncated'], isTrue);
|
||||||
});
|
});
|
||||||
@ -207,13 +207,13 @@ void main() {
|
|||||||
return delegate.copyWith(includeProperties: false);
|
return delegate.copyWith(includeProperties: false);
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
final List<Map<String, Object>> properties = result['properties']! as List<Map<String, Object>>;
|
final List<Map<String, Object?>> properties = result['properties']! as List<Map<String, Object?>>;
|
||||||
expect(properties, hasLength(7));
|
expect(properties, hasLength(7));
|
||||||
expect(properties.every((Map<String, Object> property) => !property.containsKey('properties')), isTrue);
|
expect(properties.every((Map<String, Object?> property) => !property.containsKey('properties')), isTrue);
|
||||||
|
|
||||||
final List<Map<String, Object>> children = result['children']! as List<Map<String, Object>>;
|
final List<Map<String, Object?>> children = result['children']! as List<Map<String, Object?>>;
|
||||||
expect(children, hasLength(3));
|
expect(children, hasLength(3));
|
||||||
expect(children.every((Map<String, Object> child) => !child.containsKey('properties')), isTrue);
|
expect(children.every((Map<String, Object?> child) => !child.containsKey('properties')), isTrue);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -47,15 +47,15 @@ enum ExampleEnum {
|
|||||||
|
|
||||||
/// Encode and decode to JSON to make sure all objects in the JSON for the
|
/// Encode and decode to JSON to make sure all objects in the JSON for the
|
||||||
/// [DiagnosticsNode] are valid JSON.
|
/// [DiagnosticsNode] are valid JSON.
|
||||||
Map<String, Object> simulateJsonSerialization(DiagnosticsNode node) {
|
Map<String, Object?> simulateJsonSerialization(DiagnosticsNode node) {
|
||||||
return json.decode(json.encode(node.toJsonMap(const DiagnosticsSerializationDelegate()))) as Map<String, Object>;
|
return json.decode(json.encode(node.toJsonMap(const DiagnosticsSerializationDelegate()))) as Map<String, Object?>;
|
||||||
}
|
}
|
||||||
|
|
||||||
void validateNodeJsonSerialization(DiagnosticsNode node) {
|
void validateNodeJsonSerialization(DiagnosticsNode node) {
|
||||||
validateNodeJsonSerializationHelper(simulateJsonSerialization(node), node);
|
validateNodeJsonSerializationHelper(simulateJsonSerialization(node), node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void validateNodeJsonSerializationHelper(Map<String, Object> json, DiagnosticsNode node) {
|
void validateNodeJsonSerializationHelper(Map<String, Object?> json, DiagnosticsNode node) {
|
||||||
expect(json['name'], equals(node.name));
|
expect(json['name'], equals(node.name));
|
||||||
expect(json['showSeparator'] ?? true, equals(node.showSeparator));
|
expect(json['showSeparator'] ?? true, equals(node.showSeparator));
|
||||||
expect(json['description'], equals(node.toDescription()));
|
expect(json['description'], equals(node.toDescription()));
|
||||||
@ -67,18 +67,18 @@ void validateNodeJsonSerializationHelper(Map<String, Object> json, DiagnosticsNo
|
|||||||
expect(json['hasChildren'] ?? false, equals(node.getChildren().isNotEmpty));
|
expect(json['hasChildren'] ?? false, equals(node.getChildren().isNotEmpty));
|
||||||
}
|
}
|
||||||
|
|
||||||
void validatePropertyJsonSerialization(DiagnosticsProperty<Object> property) {
|
void validatePropertyJsonSerialization(DiagnosticsProperty<Object?> property) {
|
||||||
validatePropertyJsonSerializationHelper(simulateJsonSerialization(property), property);
|
validatePropertyJsonSerializationHelper(simulateJsonSerialization(property), property);
|
||||||
}
|
}
|
||||||
|
|
||||||
void validateStringPropertyJsonSerialization(StringProperty property) {
|
void validateStringPropertyJsonSerialization(StringProperty property) {
|
||||||
final Map<String, Object> json = simulateJsonSerialization(property);
|
final Map<String, Object?> json = simulateJsonSerialization(property);
|
||||||
expect(json['quoted'], equals(property.quoted));
|
expect(json['quoted'], equals(property.quoted));
|
||||||
validatePropertyJsonSerializationHelper(json, property);
|
validatePropertyJsonSerializationHelper(json, property);
|
||||||
}
|
}
|
||||||
|
|
||||||
void validateFlagPropertyJsonSerialization(FlagProperty property) {
|
void validateFlagPropertyJsonSerialization(FlagProperty property) {
|
||||||
final Map<String, Object> json = simulateJsonSerialization(property);
|
final Map<String, Object?> json = simulateJsonSerialization(property);
|
||||||
expect(json['ifTrue'], equals(property.ifTrue));
|
expect(json['ifTrue'], equals(property.ifTrue));
|
||||||
|
|
||||||
if (property.ifTrue != null) {
|
if (property.ifTrue != null) {
|
||||||
@ -96,7 +96,7 @@ void validateFlagPropertyJsonSerialization(FlagProperty property) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void validateDoublePropertyJsonSerialization(DoubleProperty property) {
|
void validateDoublePropertyJsonSerialization(DoubleProperty property) {
|
||||||
final Map<String, Object> json = simulateJsonSerialization(property);
|
final Map<String, Object?> json = simulateJsonSerialization(property);
|
||||||
if (property.unit != null) {
|
if (property.unit != null) {
|
||||||
expect(json['unit'], equals(property.unit));
|
expect(json['unit'], equals(property.unit));
|
||||||
} else {
|
} else {
|
||||||
@ -109,7 +109,7 @@ void validateDoublePropertyJsonSerialization(DoubleProperty property) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void validateObjectFlagPropertyJsonSerialization(ObjectFlagProperty<Object> property) {
|
void validateObjectFlagPropertyJsonSerialization(ObjectFlagProperty<Object> property) {
|
||||||
final Map<String, Object> json = simulateJsonSerialization(property);
|
final Map<String, Object?> json = simulateJsonSerialization(property);
|
||||||
if (property.ifPresent != null) {
|
if (property.ifPresent != null) {
|
||||||
expect(json['ifPresent'], equals(property.ifPresent));
|
expect(json['ifPresent'], equals(property.ifPresent));
|
||||||
} else {
|
} else {
|
||||||
@ -120,7 +120,7 @@ void validateObjectFlagPropertyJsonSerialization(ObjectFlagProperty<Object> prop
|
|||||||
}
|
}
|
||||||
|
|
||||||
void validateIterableFlagsPropertyJsonSerialization(FlagsSummary<Object?> property) {
|
void validateIterableFlagsPropertyJsonSerialization(FlagsSummary<Object?> property) {
|
||||||
final Map<String, Object> json = simulateJsonSerialization(property);
|
final Map<String, Object?> json = simulateJsonSerialization(property);
|
||||||
if (property.value.isNotEmpty) {
|
if (property.value.isNotEmpty) {
|
||||||
expect(json['values'], equals(
|
expect(json['values'], equals(
|
||||||
property.value.entries
|
property.value.entries
|
||||||
@ -135,9 +135,9 @@ void validateIterableFlagsPropertyJsonSerialization(FlagsSummary<Object?> proper
|
|||||||
}
|
}
|
||||||
|
|
||||||
void validateIterablePropertyJsonSerialization(IterableProperty<Object> property) {
|
void validateIterablePropertyJsonSerialization(IterableProperty<Object> property) {
|
||||||
final Map<String, Object> json = simulateJsonSerialization(property);
|
final Map<String, Object?> json = simulateJsonSerialization(property);
|
||||||
if (property.value != null) {
|
if (property.value != null) {
|
||||||
final List<Object> valuesJson = json['values']! as List<Object>;
|
final List<Object?> valuesJson = json['values']! as List<Object?>;
|
||||||
final List<String> expectedValues = property.value!.map<String>((Object value) => value.toString()).toList();
|
final List<String> expectedValues = property.value!.map<String>((Object value) => value.toString()).toList();
|
||||||
expect(listEquals(valuesJson, expectedValues), isTrue);
|
expect(listEquals(valuesJson, expectedValues), isTrue);
|
||||||
} else {
|
} else {
|
||||||
@ -147,7 +147,7 @@ void validateIterablePropertyJsonSerialization(IterableProperty<Object> property
|
|||||||
validatePropertyJsonSerializationHelper(json, property);
|
validatePropertyJsonSerializationHelper(json, property);
|
||||||
}
|
}
|
||||||
|
|
||||||
void validatePropertyJsonSerializationHelper(final Map<String, Object> json, DiagnosticsProperty<Object> property) {
|
void validatePropertyJsonSerializationHelper(final Map<String, Object?> json, DiagnosticsProperty<Object?> property) {
|
||||||
if (property.defaultValue != kNoDefaultValue) {
|
if (property.defaultValue != kNoDefaultValue) {
|
||||||
expect(json['defaultValue'], equals(property.defaultValue.toString()));
|
expect(json['defaultValue'], equals(property.defaultValue.toString()));
|
||||||
} else {
|
} else {
|
||||||
@ -1919,7 +1919,7 @@ void main() {
|
|||||||
expect(messageProperty.name, equals('diagnostics'));
|
expect(messageProperty.name, equals('diagnostics'));
|
||||||
expect(messageProperty.value, isNull);
|
expect(messageProperty.value, isNull);
|
||||||
expect(messageProperty.showName, isTrue);
|
expect(messageProperty.showName, isTrue);
|
||||||
validatePropertyJsonSerialization(messageProperty as DiagnosticsProperty<Object>);
|
validatePropertyJsonSerialization(messageProperty as DiagnosticsProperty<Object?>);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('error message style wrap test', () {
|
test('error message style wrap test', () {
|
||||||
@ -2246,7 +2246,7 @@ void main() {
|
|||||||
|
|
||||||
test('DiagnosticsProperty for basic types has value in json', () {
|
test('DiagnosticsProperty for basic types has value in json', () {
|
||||||
DiagnosticsProperty<int> intProperty = DiagnosticsProperty<int>('int1', 10);
|
DiagnosticsProperty<int> intProperty = DiagnosticsProperty<int>('int1', 10);
|
||||||
Map<String, Object> json = simulateJsonSerialization(intProperty);
|
Map<String, Object?> json = simulateJsonSerialization(intProperty);
|
||||||
expect(json['name'], 'int1');
|
expect(json['name'], 'int1');
|
||||||
expect(json['value'], 10);
|
expect(json['value'], 10);
|
||||||
|
|
||||||
|
@ -249,7 +249,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Return value from pop is correct', (WidgetTester tester) async {
|
testWidgets('Return value from pop is correct', (WidgetTester tester) async {
|
||||||
late Future<Object> result;
|
late Future<Object?> result;
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
home: Builder(
|
home: Builder(
|
||||||
@ -258,7 +258,7 @@ void main() {
|
|||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
child: const Text('X'),
|
child: const Text('X'),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
result = Navigator.of(context)!.pushNamed('/a');
|
result = Navigator.of(context)!.pushNamed<Object?>('/a');
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -83,7 +83,7 @@ void main() {
|
|||||||
|
|
||||||
Future<void> prepareDatePicker(
|
Future<void> prepareDatePicker(
|
||||||
WidgetTester tester,
|
WidgetTester tester,
|
||||||
Future<void> callback(Future<DateTime> date),
|
Future<void> callback(Future<DateTime?> date),
|
||||||
{ TextDirection textDirection = TextDirection.ltr }
|
{ TextDirection textDirection = TextDirection.ltr }
|
||||||
) async {
|
) async {
|
||||||
late BuildContext buttonContext;
|
late BuildContext buttonContext;
|
||||||
@ -105,7 +105,7 @@ void main() {
|
|||||||
await tester.tap(find.text('Go'));
|
await tester.tap(find.text('Go'));
|
||||||
expect(buttonContext, isNotNull);
|
expect(buttonContext, isNotNull);
|
||||||
|
|
||||||
final Future<DateTime> date = showDatePicker(
|
final Future<DateTime?> date = showDatePicker(
|
||||||
context: buttonContext,
|
context: buttonContext,
|
||||||
initialDate: initialDate,
|
initialDate: initialDate,
|
||||||
firstDate: firstDate,
|
firstDate: firstDate,
|
||||||
@ -138,7 +138,7 @@ void main() {
|
|||||||
cancelText = 'nope';
|
cancelText = 'nope';
|
||||||
confirmText = 'yep';
|
confirmText = 'yep';
|
||||||
helpText = 'help';
|
helpText = 'help';
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
expect(find.text(cancelText!), findsOneWidget);
|
expect(find.text(cancelText!), findsOneWidget);
|
||||||
expect(find.text(confirmText!), findsOneWidget);
|
expect(find.text(confirmText!), findsOneWidget);
|
||||||
expect(find.text(helpText!), findsOneWidget);
|
expect(find.text(helpText!), findsOneWidget);
|
||||||
@ -146,21 +146,21 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Initial date is the default', (WidgetTester tester) async {
|
testWidgets('Initial date is the default', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.tap(find.text('OK'));
|
await tester.tap(find.text('OK'));
|
||||||
expect(await date, DateTime(2016, DateTime.january, 15));
|
expect(await date, DateTime(2016, DateTime.january, 15));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Can cancel', (WidgetTester tester) async {
|
testWidgets('Can cancel', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.tap(find.text('CANCEL'));
|
await tester.tap(find.text('CANCEL'));
|
||||||
expect(await date, isNull);
|
expect(await date, isNull);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Can toggle to input entry mode', (WidgetTester tester) async {
|
testWidgets('Can toggle to input entry mode', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
expect(find.byType(TextField), findsNothing);
|
expect(find.byType(TextField), findsNothing);
|
||||||
await tester.tap(find.byIcon(Icons.edit));
|
await tester.tap(find.byIcon(Icons.edit));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
@ -169,7 +169,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Toggle to input mode keeps selected date', (WidgetTester tester) async {
|
testWidgets('Toggle to input mode keeps selected date', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.tap(find.text('12'));
|
await tester.tap(find.text('12'));
|
||||||
await tester.tap(find.byIcon(Icons.edit));
|
await tester.tap(find.byIcon(Icons.edit));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
@ -179,7 +179,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Switching to input mode resets input error state', (WidgetTester tester) async {
|
testWidgets('Switching to input mode resets input error state', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
// Enter text input mode and type an invalid date to get error.
|
// Enter text input mode and type an invalid date to get error.
|
||||||
await tester.tap(find.byIcon(Icons.edit));
|
await tester.tap(find.byIcon(Icons.edit));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
@ -438,7 +438,7 @@ void main() {
|
|||||||
|
|
||||||
group('Calendar mode', () {
|
group('Calendar mode', () {
|
||||||
testWidgets('Can select a day', (WidgetTester tester) async {
|
testWidgets('Can select a day', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.tap(find.text('12'));
|
await tester.tap(find.text('12'));
|
||||||
await tester.tap(find.text('OK'));
|
await tester.tap(find.text('OK'));
|
||||||
expect(await date, equals(DateTime(2016, DateTime.january, 12)));
|
expect(await date, equals(DateTime(2016, DateTime.january, 12)));
|
||||||
@ -446,7 +446,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Can select a month', (WidgetTester tester) async {
|
testWidgets('Can select a month', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.tap(previousMonthIcon);
|
await tester.tap(previousMonthIcon);
|
||||||
await tester.pumpAndSettle(const Duration(seconds: 1));
|
await tester.pumpAndSettle(const Duration(seconds: 1));
|
||||||
await tester.tap(find.text('25'));
|
await tester.tap(find.text('25'));
|
||||||
@ -456,7 +456,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Can select a year', (WidgetTester tester) async {
|
testWidgets('Can select a year', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.tap(find.text('January 2016')); // Switch to year mode.
|
await tester.tap(find.text('January 2016')); // Switch to year mode.
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.tap(find.text('2018'));
|
await tester.tap(find.text('2018'));
|
||||||
@ -467,7 +467,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('Selecting date does not change displayed month', (WidgetTester tester) async {
|
testWidgets('Selecting date does not change displayed month', (WidgetTester tester) async {
|
||||||
initialDate = DateTime(2020, DateTime.march, 15);
|
initialDate = DateTime(2020, DateTime.march, 15);
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.tap(nextMonthIcon);
|
await tester.tap(nextMonthIcon);
|
||||||
await tester.pumpAndSettle(const Duration(seconds: 1));
|
await tester.pumpAndSettle(const Duration(seconds: 1));
|
||||||
expect(find.text('April 2020'), findsOneWidget);
|
expect(find.text('April 2020'), findsOneWidget);
|
||||||
@ -480,7 +480,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Changing year does not change selected date', (WidgetTester tester) async {
|
testWidgets('Changing year does not change selected date', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.tap(find.text('January 2016'));
|
await tester.tap(find.text('January 2016'));
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.tap(find.text('2018'));
|
await tester.tap(find.text('2018'));
|
||||||
@ -491,7 +491,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Changing year does not change the month', (WidgetTester tester) async {
|
testWidgets('Changing year does not change the month', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.tap(nextMonthIcon);
|
await tester.tap(nextMonthIcon);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
await tester.tap(nextMonthIcon);
|
await tester.tap(nextMonthIcon);
|
||||||
@ -505,7 +505,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Can select a year and then a day', (WidgetTester tester) async {
|
testWidgets('Can select a year and then a day', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.tap(find.text('January 2016')); // Switch to year mode.
|
await tester.tap(find.text('January 2016')); // Switch to year mode.
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.tap(find.text('2017'));
|
await tester.tap(find.text('2017'));
|
||||||
@ -517,7 +517,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Current year is visible in year picker', (WidgetTester tester) async {
|
testWidgets('Current year is visible in year picker', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.tap(find.text('January 2016')); // Switch to year mode.
|
await tester.tap(find.text('January 2016')); // Switch to year mode.
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(find.text('2016'), findsOneWidget);
|
expect(find.text('2016'), findsOneWidget);
|
||||||
@ -528,7 +528,7 @@ void main() {
|
|||||||
initialDate = DateTime(2017, DateTime.january, 15);
|
initialDate = DateTime(2017, DateTime.january, 15);
|
||||||
firstDate = initialDate;
|
firstDate = initialDate;
|
||||||
lastDate = initialDate;
|
lastDate = initialDate;
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
// Earlier than firstDate. Should be ignored.
|
// Earlier than firstDate. Should be ignored.
|
||||||
await tester.tap(find.text('10'));
|
await tester.tap(find.text('10'));
|
||||||
// Later than lastDate. Should be ignored.
|
// Later than lastDate. Should be ignored.
|
||||||
@ -543,7 +543,7 @@ void main() {
|
|||||||
initialDate = DateTime(2017, DateTime.january, 15);
|
initialDate = DateTime(2017, DateTime.january, 15);
|
||||||
firstDate = initialDate;
|
firstDate = initialDate;
|
||||||
lastDate = DateTime(2017, DateTime.february, 20);
|
lastDate = DateTime(2017, DateTime.february, 20);
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.tap(nextMonthIcon);
|
await tester.tap(nextMonthIcon);
|
||||||
await tester.pumpAndSettle(const Duration(seconds: 1));
|
await tester.pumpAndSettle(const Duration(seconds: 1));
|
||||||
// Shouldn't be possible to keep going into March.
|
// Shouldn't be possible to keep going into March.
|
||||||
@ -555,7 +555,7 @@ void main() {
|
|||||||
initialDate = DateTime(2017, DateTime.january, 15);
|
initialDate = DateTime(2017, DateTime.january, 15);
|
||||||
firstDate = DateTime(2016, DateTime.december, 10);
|
firstDate = DateTime(2016, DateTime.december, 10);
|
||||||
lastDate = initialDate;
|
lastDate = initialDate;
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.tap(previousMonthIcon);
|
await tester.tap(previousMonthIcon);
|
||||||
await tester.pumpAndSettle(const Duration(seconds: 1));
|
await tester.pumpAndSettle(const Duration(seconds: 1));
|
||||||
// Shouldn't be possible to keep going into November.
|
// Shouldn't be possible to keep going into November.
|
||||||
@ -567,7 +567,7 @@ void main() {
|
|||||||
initialDate = DateTime(2018, DateTime.july, 4);
|
initialDate = DateTime(2018, DateTime.july, 4);
|
||||||
firstDate = DateTime(2018, DateTime.june, 9);
|
firstDate = DateTime(2018, DateTime.june, 9);
|
||||||
lastDate = DateTime(2018, DateTime.december, 15);
|
lastDate = DateTime(2018, DateTime.december, 15);
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.tap(find.text('July 2018')); // Switch to year mode.
|
await tester.tap(find.text('July 2018')); // Switch to year mode.
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
await tester.tap(find.text('2016')); // Disabled, doesn't change the year.
|
await tester.tap(find.text('2016')); // Disabled, doesn't change the year.
|
||||||
@ -582,7 +582,7 @@ void main() {
|
|||||||
initialDate = DateTime(2018, DateTime.may, 4);
|
initialDate = DateTime(2018, DateTime.may, 4);
|
||||||
firstDate = DateTime(2016, DateTime.june, 9);
|
firstDate = DateTime(2016, DateTime.june, 9);
|
||||||
lastDate = DateTime(2019, DateTime.january, 15);
|
lastDate = DateTime(2019, DateTime.january, 15);
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.tap(find.text('May 2018'));
|
await tester.tap(find.text('May 2018'));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
await tester.tap(find.text('2016'));
|
await tester.tap(find.text('2016'));
|
||||||
@ -596,7 +596,7 @@ void main() {
|
|||||||
initialDate = DateTime(2018, DateTime.may, 4);
|
initialDate = DateTime(2018, DateTime.may, 4);
|
||||||
firstDate = DateTime(2016, DateTime.june, 9);
|
firstDate = DateTime(2016, DateTime.june, 9);
|
||||||
lastDate = DateTime(2019, DateTime.january, 15);
|
lastDate = DateTime(2019, DateTime.january, 15);
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.tap(find.text('May 2018'));
|
await tester.tap(find.text('May 2018'));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
await tester.tap(find.text('2019'));
|
await tester.tap(find.text('2019'));
|
||||||
@ -611,7 +611,7 @@ void main() {
|
|||||||
firstDate = DateTime(2017, DateTime.january, 10);
|
firstDate = DateTime(2017, DateTime.january, 10);
|
||||||
lastDate = DateTime(2017, DateTime.january, 20);
|
lastDate = DateTime(2017, DateTime.january, 20);
|
||||||
selectableDayPredicate = (DateTime day) => day.day.isEven;
|
selectableDayPredicate = (DateTime day) => day.day.isEven;
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.tap(find.text('13')); // Odd, doesn't work.
|
await tester.tap(find.text('13')); // Odd, doesn't work.
|
||||||
await tester.tap(find.text('10')); // Even, works.
|
await tester.tap(find.text('10')); // Even, works.
|
||||||
await tester.tap(find.text('17')); // Odd, doesn't work.
|
await tester.tap(find.text('17')); // Odd, doesn't work.
|
||||||
@ -623,7 +623,7 @@ void main() {
|
|||||||
testWidgets('Can select initial calendar picker mode', (WidgetTester tester) async {
|
testWidgets('Can select initial calendar picker mode', (WidgetTester tester) async {
|
||||||
initialDate = DateTime(2014, DateTime.january, 15);
|
initialDate = DateTime(2014, DateTime.january, 15);
|
||||||
initialCalendarMode = DatePickerMode.year;
|
initialCalendarMode = DatePickerMode.year;
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
// 2018 wouldn't be available if the year picker wasn't showing.
|
// 2018 wouldn't be available if the year picker wasn't showing.
|
||||||
// The initial current year is 2014.
|
// The initial current year is 2014.
|
||||||
@ -635,7 +635,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('currentDate is highlighted', (WidgetTester tester) async {
|
testWidgets('currentDate is highlighted', (WidgetTester tester) async {
|
||||||
today = DateTime(2016, 1, 2);
|
today = DateTime(2016, 1, 2);
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
const Color todayColor = Color(0xff2196f3); // default primary color
|
const Color todayColor = Color(0xff2196f3); // default primary color
|
||||||
expect(
|
expect(
|
||||||
@ -649,7 +649,7 @@ void main() {
|
|||||||
testWidgets('Selecting date does not switch picker to year selection', (WidgetTester tester) async {
|
testWidgets('Selecting date does not switch picker to year selection', (WidgetTester tester) async {
|
||||||
initialDate = DateTime(2020, DateTime.may, 10);
|
initialDate = DateTime(2020, DateTime.may, 10);
|
||||||
initialCalendarMode = DatePickerMode.year;
|
initialCalendarMode = DatePickerMode.year;
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
await tester.tap(find.text('2017'));
|
await tester.tap(find.text('2017'));
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
@ -671,7 +671,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Initial entry mode is used', (WidgetTester tester) async {
|
testWidgets('Initial entry mode is used', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
expect(find.byType(TextField), findsOneWidget);
|
expect(find.byType(TextField), findsOneWidget);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -682,7 +682,7 @@ void main() {
|
|||||||
fieldHintText = 'hint';
|
fieldHintText = 'hint';
|
||||||
fieldLabelText = 'label';
|
fieldLabelText = 'label';
|
||||||
helpText = 'help';
|
helpText = 'help';
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
expect(find.text(cancelText!), findsOneWidget);
|
expect(find.text(cancelText!), findsOneWidget);
|
||||||
expect(find.text(confirmText!), findsOneWidget);
|
expect(find.text(confirmText!), findsOneWidget);
|
||||||
expect(find.text(fieldHintText!), findsOneWidget);
|
expect(find.text(fieldHintText!), findsOneWidget);
|
||||||
@ -692,14 +692,14 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Initial date is the default', (WidgetTester tester) async {
|
testWidgets('Initial date is the default', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.tap(find.text('OK'));
|
await tester.tap(find.text('OK'));
|
||||||
expect(await date, DateTime(2016, DateTime.january, 15));
|
expect(await date, DateTime(2016, DateTime.january, 15));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Can toggle to calendar entry mode', (WidgetTester tester) async {
|
testWidgets('Can toggle to calendar entry mode', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
expect(find.byType(TextField), findsOneWidget);
|
expect(find.byType(TextField), findsOneWidget);
|
||||||
await tester.tap(find.byIcon(Icons.calendar_today));
|
await tester.tap(find.byIcon(Icons.calendar_today));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
@ -708,7 +708,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Toggle to calendar mode keeps selected date', (WidgetTester tester) async {
|
testWidgets('Toggle to calendar mode keeps selected date', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
final TextField field = textField(tester);
|
final TextField field = textField(tester);
|
||||||
field.controller!.clear();
|
field.controller!.clear();
|
||||||
|
|
||||||
@ -721,7 +721,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Entered text returns date', (WidgetTester tester) async {
|
testWidgets('Entered text returns date', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
final TextField field = textField(tester);
|
final TextField field = textField(tester);
|
||||||
field.controller!.clear();
|
field.controller!.clear();
|
||||||
|
|
||||||
@ -733,7 +733,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('Too short entered text shows error', (WidgetTester tester) async {
|
testWidgets('Too short entered text shows error', (WidgetTester tester) async {
|
||||||
errorFormatText = 'oops';
|
errorFormatText = 'oops';
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
final TextField field = textField(tester);
|
final TextField field = textField(tester);
|
||||||
field.controller!.clear();
|
field.controller!.clear();
|
||||||
|
|
||||||
@ -749,7 +749,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('Bad format entered text shows error', (WidgetTester tester) async {
|
testWidgets('Bad format entered text shows error', (WidgetTester tester) async {
|
||||||
errorFormatText = 'oops';
|
errorFormatText = 'oops';
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
final TextField field = textField(tester);
|
final TextField field = textField(tester);
|
||||||
field.controller!.clear();
|
field.controller!.clear();
|
||||||
|
|
||||||
@ -766,7 +766,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('Invalid entered text shows error', (WidgetTester tester) async {
|
testWidgets('Invalid entered text shows error', (WidgetTester tester) async {
|
||||||
errorInvalidText = 'oops';
|
errorInvalidText = 'oops';
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
final TextField field = textField(tester);
|
final TextField field = textField(tester);
|
||||||
field.controller!.clear();
|
field.controller!.clear();
|
||||||
|
|
||||||
@ -912,7 +912,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Selecting date vibrates', (WidgetTester tester) async {
|
testWidgets('Selecting date vibrates', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.tap(find.text('10'));
|
await tester.tap(find.text('10'));
|
||||||
await tester.pump(hapticFeedbackInterval);
|
await tester.pump(hapticFeedbackInterval);
|
||||||
expect(feedback.hapticCount, 1);
|
expect(feedback.hapticCount, 1);
|
||||||
@ -926,7 +926,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Tapping unselectable date does not vibrate', (WidgetTester tester) async {
|
testWidgets('Tapping unselectable date does not vibrate', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.tap(find.text('11'));
|
await tester.tap(find.text('11'));
|
||||||
await tester.pump(hapticFeedbackInterval);
|
await tester.pump(hapticFeedbackInterval);
|
||||||
expect(feedback.hapticCount, 0);
|
expect(feedback.hapticCount, 0);
|
||||||
@ -940,7 +940,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Changing modes and year vibrates', (WidgetTester tester) async {
|
testWidgets('Changing modes and year vibrates', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.tap(find.text('January 2017'));
|
await tester.tap(find.text('January 2017'));
|
||||||
await tester.pump(hapticFeedbackInterval);
|
await tester.pump(hapticFeedbackInterval);
|
||||||
expect(feedback.hapticCount, 1);
|
expect(feedback.hapticCount, 1);
|
||||||
@ -956,7 +956,7 @@ void main() {
|
|||||||
final SemanticsHandle semantics = tester.ensureSemantics();
|
final SemanticsHandle semantics = tester.ensureSemantics();
|
||||||
addTearDown(semantics.dispose);
|
addTearDown(semantics.dispose);
|
||||||
|
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
// Header
|
// Header
|
||||||
expect(tester.getSemantics(find.text('SELECT DATE')), matchesSemantics(
|
expect(tester.getSemantics(find.text('SELECT DATE')), matchesSemantics(
|
||||||
label: 'SELECT DATE\nFri, Jan 15',
|
label: 'SELECT DATE\nFri, Jan 15',
|
||||||
@ -1174,7 +1174,7 @@ void main() {
|
|||||||
addTearDown(semantics.dispose);
|
addTearDown(semantics.dispose);
|
||||||
|
|
||||||
initialCalendarMode = DatePickerMode.year;
|
initialCalendarMode = DatePickerMode.year;
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
// Header
|
// Header
|
||||||
expect(tester.getSemantics(find.text('SELECT DATE')), matchesSemantics(
|
expect(tester.getSemantics(find.text('SELECT DATE')), matchesSemantics(
|
||||||
label: 'SELECT DATE\nFri, Jan 15',
|
label: 'SELECT DATE\nFri, Jan 15',
|
||||||
@ -1231,7 +1231,7 @@ void main() {
|
|||||||
addTearDown(semantics.dispose);
|
addTearDown(semantics.dispose);
|
||||||
|
|
||||||
initialEntryMode = DatePickerEntryMode.input;
|
initialEntryMode = DatePickerEntryMode.input;
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
// Header
|
// Header
|
||||||
expect(tester.getSemantics(find.text('SELECT DATE')), matchesSemantics(
|
expect(tester.getSemantics(find.text('SELECT DATE')), matchesSemantics(
|
||||||
label: 'SELECT DATE\nFri, Jan 15',
|
label: 'SELECT DATE\nFri, Jan 15',
|
||||||
@ -1285,7 +1285,7 @@ void main() {
|
|||||||
|
|
||||||
group('Keyboard navigation', () {
|
group('Keyboard navigation', () {
|
||||||
testWidgets('Can toggle to calendar entry mode', (WidgetTester tester) async {
|
testWidgets('Can toggle to calendar entry mode', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
expect(find.byType(TextField), findsNothing);
|
expect(find.byType(TextField), findsNothing);
|
||||||
// Navigate to the entry toggle button and activate it
|
// Navigate to the entry toggle button and activate it
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
@ -1301,7 +1301,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Can toggle to year mode', (WidgetTester tester) async {
|
testWidgets('Can toggle to year mode', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
expect(find.text('2016'), findsNothing);
|
expect(find.text('2016'), findsNothing);
|
||||||
// Navigate to the year selector and activate it
|
// Navigate to the year selector and activate it
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
@ -1313,7 +1313,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Can navigate next/previous months', (WidgetTester tester) async {
|
testWidgets('Can navigate next/previous months', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
expect(find.text('January 2016'), findsOneWidget);
|
expect(find.text('January 2016'), findsOneWidget);
|
||||||
// Navigate to the previous month button and activate it twice
|
// Navigate to the previous month button and activate it twice
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
@ -1341,7 +1341,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Can navigate date grid with arrow keys', (WidgetTester tester) async {
|
testWidgets('Can navigate date grid with arrow keys', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
// Navigate to the grid
|
// Navigate to the grid
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
@ -1377,7 +1377,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Navigating with arrow keys scrolls months', (WidgetTester tester) async {
|
testWidgets('Navigating with arrow keys scrolls months', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
// Navigate to the grid
|
// Navigate to the grid
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
@ -1425,7 +1425,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('RTL text direction reverses the horizontal arrow key navigation', (WidgetTester tester) async {
|
testWidgets('RTL text direction reverses the horizontal arrow key navigation', (WidgetTester tester) async {
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
// Navigate to the grid
|
// Navigate to the grid
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
@ -1484,7 +1484,7 @@ void main() {
|
|||||||
addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
|
addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
|
||||||
tester.binding.window.devicePixelRatioTestValue = 1.0;
|
tester.binding.window.devicePixelRatioTestValue = 1.0;
|
||||||
addTearDown(tester.binding.window.clearDevicePixelRatioTestValue);
|
addTearDown(tester.binding.window.clearDevicePixelRatioTestValue);
|
||||||
await prepareDatePicker(tester, (Future<DateTime> date) async {
|
await prepareDatePicker(tester, (Future<DateTime?> date) async {
|
||||||
await tester.tap(find.text('OK'));
|
await tester.tap(find.text('OK'));
|
||||||
});
|
});
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
@ -52,7 +52,7 @@ void main() {
|
|||||||
|
|
||||||
Future<void> preparePicker(
|
Future<void> preparePicker(
|
||||||
WidgetTester tester,
|
WidgetTester tester,
|
||||||
Future<void> callback(Future<DateTimeRange> date),
|
Future<void> callback(Future<DateTimeRange?> date),
|
||||||
{ TextDirection textDirection = TextDirection.ltr }
|
{ TextDirection textDirection = TextDirection.ltr }
|
||||||
) async {
|
) async {
|
||||||
late BuildContext buttonContext;
|
late BuildContext buttonContext;
|
||||||
@ -74,7 +74,7 @@ void main() {
|
|||||||
await tester.tap(find.text('Go'));
|
await tester.tap(find.text('Go'));
|
||||||
expect(buttonContext, isNotNull);
|
expect(buttonContext, isNotNull);
|
||||||
|
|
||||||
final Future<DateTimeRange> range = showDateRangePicker(
|
final Future<DateTimeRange?> range = showDateRangePicker(
|
||||||
context: buttonContext,
|
context: buttonContext,
|
||||||
initialDateRange: initialDateRange,
|
initialDateRange: initialDateRange,
|
||||||
firstDate: firstDate,
|
firstDate: firstDate,
|
||||||
@ -107,14 +107,14 @@ void main() {
|
|||||||
testWidgets('Save and help text is used', (WidgetTester tester) async {
|
testWidgets('Save and help text is used', (WidgetTester tester) async {
|
||||||
helpText = 'help';
|
helpText = 'help';
|
||||||
saveText = 'make it so';
|
saveText = 'make it so';
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
expect(find.text(helpText!), findsOneWidget);
|
expect(find.text(helpText!), findsOneWidget);
|
||||||
expect(find.text(saveText!), findsOneWidget);
|
expect(find.text(saveText!), findsOneWidget);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Initial date is the default', (WidgetTester tester) async {
|
testWidgets('Initial date is the default', (WidgetTester tester) async {
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
await tester.tap(find.text('SAVE'));
|
await tester.tap(find.text('SAVE'));
|
||||||
expect(await range, DateTimeRange(
|
expect(await range, DateTimeRange(
|
||||||
start: DateTime(2016, DateTime.january, 15),
|
start: DateTime(2016, DateTime.january, 15),
|
||||||
@ -131,7 +131,7 @@ void main() {
|
|||||||
start: lastDate,
|
start: lastDate,
|
||||||
end: lastDate,
|
end: lastDate,
|
||||||
);
|
);
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
// December header should be showing, but no November
|
// December header should be showing, but no November
|
||||||
expect(find.text('December 2016'), findsOneWidget);
|
expect(find.text('December 2016'), findsOneWidget);
|
||||||
expect(find.text('November 2016'), findsNothing);
|
expect(find.text('November 2016'), findsNothing);
|
||||||
@ -146,7 +146,7 @@ void main() {
|
|||||||
start: firstDate,
|
start: firstDate,
|
||||||
end: firstDate,
|
end: firstDate,
|
||||||
);
|
);
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
// January and February headers should be showing, but no March
|
// January and February headers should be showing, but no March
|
||||||
expect(find.text('January 2015'), findsOneWidget);
|
expect(find.text('January 2015'), findsOneWidget);
|
||||||
expect(find.text('February 2015'), findsOneWidget);
|
expect(find.text('February 2015'), findsOneWidget);
|
||||||
@ -161,7 +161,7 @@ void main() {
|
|||||||
currentDate = DateTime(2016, DateTime.september, 1);
|
currentDate = DateTime(2016, DateTime.september, 1);
|
||||||
initialDateRange = null;
|
initialDateRange = null;
|
||||||
|
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
// September and October headers should be showing, but no August
|
// September and October headers should be showing, but no August
|
||||||
expect(find.text('September 2016'), findsOneWidget);
|
expect(find.text('September 2016'), findsOneWidget);
|
||||||
expect(find.text('October 2016'), findsOneWidget);
|
expect(find.text('October 2016'), findsOneWidget);
|
||||||
@ -170,14 +170,14 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Can cancel', (WidgetTester tester) async {
|
testWidgets('Can cancel', (WidgetTester tester) async {
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
await tester.tap(find.byIcon(Icons.close));
|
await tester.tap(find.byIcon(Icons.close));
|
||||||
expect(await range, isNull);
|
expect(await range, isNull);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Can select a range', (WidgetTester tester) async {
|
testWidgets('Can select a range', (WidgetTester tester) async {
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
await tester.tap(find.text('12').first);
|
await tester.tap(find.text('12').first);
|
||||||
await tester.tap(find.text('14').first);
|
await tester.tap(find.text('14').first);
|
||||||
await tester.tap(find.text('SAVE'));
|
await tester.tap(find.text('SAVE'));
|
||||||
@ -189,7 +189,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Tapping earlier date resets selected range', (WidgetTester tester) async {
|
testWidgets('Tapping earlier date resets selected range', (WidgetTester tester) async {
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
await tester.tap(find.text('12').first);
|
await tester.tap(find.text('12').first);
|
||||||
await tester.tap(find.text('11').first);
|
await tester.tap(find.text('11').first);
|
||||||
await tester.tap(find.text('15').first);
|
await tester.tap(find.text('15').first);
|
||||||
@ -202,7 +202,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Can select single day range', (WidgetTester tester) async {
|
testWidgets('Can select single day range', (WidgetTester tester) async {
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
await tester.tap(find.text('12').first);
|
await tester.tap(find.text('12').first);
|
||||||
await tester.tap(find.text('12').first);
|
await tester.tap(find.text('12').first);
|
||||||
await tester.tap(find.text('SAVE'));
|
await tester.tap(find.text('SAVE'));
|
||||||
@ -220,7 +220,7 @@ void main() {
|
|||||||
);
|
);
|
||||||
firstDate = DateTime(2017, DateTime.january, 12);
|
firstDate = DateTime(2017, DateTime.january, 12);
|
||||||
lastDate = DateTime(2017, DateTime.january, 16);
|
lastDate = DateTime(2017, DateTime.january, 16);
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
// Earlier than firstDate. Should be ignored.
|
// Earlier than firstDate. Should be ignored.
|
||||||
await tester.tap(find.text('10'));
|
await tester.tap(find.text('10'));
|
||||||
// Later than lastDate. Should be ignored.
|
// Later than lastDate. Should be ignored.
|
||||||
@ -232,7 +232,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Can toggle to input entry mode', (WidgetTester tester) async {
|
testWidgets('Can toggle to input entry mode', (WidgetTester tester) async {
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
expect(find.byType(TextField), findsNothing);
|
expect(find.byType(TextField), findsNothing);
|
||||||
await tester.tap(find.byIcon(Icons.edit));
|
await tester.tap(find.byIcon(Icons.edit));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
@ -241,7 +241,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Toggle to input mode keeps selected date', (WidgetTester tester) async {
|
testWidgets('Toggle to input mode keeps selected date', (WidgetTester tester) async {
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
await tester.tap(find.text('12').first);
|
await tester.tap(find.text('12').first);
|
||||||
await tester.tap(find.text('14').first);
|
await tester.tap(find.text('14').first);
|
||||||
await tester.tap(find.byIcon(Icons.edit));
|
await tester.tap(find.byIcon(Icons.edit));
|
||||||
@ -262,7 +262,7 @@ void main() {
|
|||||||
testWidgets('Invalid start date', (WidgetTester tester) async {
|
testWidgets('Invalid start date', (WidgetTester tester) async {
|
||||||
// Invalid start date should have neither a start nor end date selected in
|
// Invalid start date should have neither a start nor end date selected in
|
||||||
// calendar mode
|
// calendar mode
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
await tester.enterText(find.byType(TextField).at(0), '12/27/1918');
|
await tester.enterText(find.byType(TextField).at(0), '12/27/1918');
|
||||||
await tester.enterText(find.byType(TextField).at(1), '12/25/2016');
|
await tester.enterText(find.byType(TextField).at(1), '12/25/2016');
|
||||||
await tester.tap(find.byIcon(Icons.calendar_today));
|
await tester.tap(find.byIcon(Icons.calendar_today));
|
||||||
@ -275,7 +275,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('Invalid end date', (WidgetTester tester) async {
|
testWidgets('Invalid end date', (WidgetTester tester) async {
|
||||||
// Invalid end date should only have a start date selected
|
// Invalid end date should only have a start date selected
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
await tester.enterText(find.byType(TextField).at(0), '12/24/2016');
|
await tester.enterText(find.byType(TextField).at(0), '12/24/2016');
|
||||||
await tester.enterText(find.byType(TextField).at(1), '12/25/2050');
|
await tester.enterText(find.byType(TextField).at(1), '12/25/2050');
|
||||||
await tester.tap(find.byIcon(Icons.calendar_today));
|
await tester.tap(find.byIcon(Icons.calendar_today));
|
||||||
@ -288,7 +288,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('Invalid range', (WidgetTester tester) async {
|
testWidgets('Invalid range', (WidgetTester tester) async {
|
||||||
// Start date after end date should just use the start date
|
// Start date after end date should just use the start date
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
await tester.enterText(find.byType(TextField).at(0), '12/25/2016');
|
await tester.enterText(find.byType(TextField).at(0), '12/25/2016');
|
||||||
await tester.enterText(find.byType(TextField).at(1), '12/24/2016');
|
await tester.enterText(find.byType(TextField).at(1), '12/24/2016');
|
||||||
await tester.tap(find.byIcon(Icons.calendar_today));
|
await tester.tap(find.byIcon(Icons.calendar_today));
|
||||||
@ -375,7 +375,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Selecting dates vibrates', (WidgetTester tester) async {
|
testWidgets('Selecting dates vibrates', (WidgetTester tester) async {
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
await tester.tap(find.text('10').first);
|
await tester.tap(find.text('10').first);
|
||||||
await tester.pump(hapticFeedbackInterval);
|
await tester.pump(hapticFeedbackInterval);
|
||||||
expect(feedback.hapticCount, 1);
|
expect(feedback.hapticCount, 1);
|
||||||
@ -389,7 +389,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Tapping unselectable date does not vibrate', (WidgetTester tester) async {
|
testWidgets('Tapping unselectable date does not vibrate', (WidgetTester tester) async {
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
await tester.tap(find.text('8').first);
|
await tester.tap(find.text('8').first);
|
||||||
await tester.pump(hapticFeedbackInterval);
|
await tester.pump(hapticFeedbackInterval);
|
||||||
expect(feedback.hapticCount, 0);
|
expect(feedback.hapticCount, 0);
|
||||||
@ -399,7 +399,7 @@ void main() {
|
|||||||
|
|
||||||
group('Keyboard navigation', () {
|
group('Keyboard navigation', () {
|
||||||
testWidgets('Can toggle to calendar entry mode', (WidgetTester tester) async {
|
testWidgets('Can toggle to calendar entry mode', (WidgetTester tester) async {
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
expect(find.byType(TextField), findsNothing);
|
expect(find.byType(TextField), findsNothing);
|
||||||
// Navigate to the entry toggle button and activate it
|
// Navigate to the entry toggle button and activate it
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
@ -412,7 +412,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Can navigate date grid with arrow keys', (WidgetTester tester) async {
|
testWidgets('Can navigate date grid with arrow keys', (WidgetTester tester) async {
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
// Navigate to the grid
|
// Navigate to the grid
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
@ -464,7 +464,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Navigating with arrow keys scrolls as needed', (WidgetTester tester) async {
|
testWidgets('Navigating with arrow keys scrolls as needed', (WidgetTester tester) async {
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
// Jan and Feb headers should be showing, but no March
|
// Jan and Feb headers should be showing, but no March
|
||||||
expect(find.text('January 2016'), findsOneWidget);
|
expect(find.text('January 2016'), findsOneWidget);
|
||||||
expect(find.text('February 2016'), findsOneWidget);
|
expect(find.text('February 2016'), findsOneWidget);
|
||||||
@ -529,7 +529,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('RTL text direction reverses the horizontal arrow key navigation', (WidgetTester tester) async {
|
testWidgets('RTL text direction reverses the horizontal arrow key navigation', (WidgetTester tester) async {
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
// Navigate to the grid
|
// Navigate to the grid
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
await tester.sendKeyEvent(LogicalKeyboardKey.tab);
|
||||||
@ -589,7 +589,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Initial entry mode is used', (WidgetTester tester) async {
|
testWidgets('Initial entry mode is used', (WidgetTester tester) async {
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
expect(find.byType(TextField), findsNWidgets(2));
|
expect(find.byType(TextField), findsNWidgets(2));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -603,7 +603,7 @@ void main() {
|
|||||||
fieldStartLabelText = 'label1';
|
fieldStartLabelText = 'label1';
|
||||||
fieldEndLabelText = 'label2';
|
fieldEndLabelText = 'label2';
|
||||||
helpText = 'help';
|
helpText = 'help';
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
expect(find.text(cancelText!), findsOneWidget);
|
expect(find.text(cancelText!), findsOneWidget);
|
||||||
expect(find.text(confirmText!), findsOneWidget);
|
expect(find.text(confirmText!), findsOneWidget);
|
||||||
expect(find.text(fieldStartHintText!), findsOneWidget);
|
expect(find.text(fieldStartHintText!), findsOneWidget);
|
||||||
@ -615,7 +615,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Initial date is the default', (WidgetTester tester) async {
|
testWidgets('Initial date is the default', (WidgetTester tester) async {
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
await tester.tap(find.text('OK'));
|
await tester.tap(find.text('OK'));
|
||||||
expect(await range, DateTimeRange(
|
expect(await range, DateTimeRange(
|
||||||
start: DateTime(2017, DateTime.january, 15),
|
start: DateTime(2017, DateTime.january, 15),
|
||||||
@ -625,7 +625,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Can toggle to calendar entry mode', (WidgetTester tester) async {
|
testWidgets('Can toggle to calendar entry mode', (WidgetTester tester) async {
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
expect(find.byType(TextField), findsNWidgets(2));
|
expect(find.byType(TextField), findsNWidgets(2));
|
||||||
await tester.tap(find.byIcon(Icons.calendar_today));
|
await tester.tap(find.byIcon(Icons.calendar_today));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
@ -635,7 +635,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('Toggle to calendar mode keeps selected date', (WidgetTester tester) async {
|
testWidgets('Toggle to calendar mode keeps selected date', (WidgetTester tester) async {
|
||||||
initialDateRange = null;
|
initialDateRange = null;
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
await tester.enterText(find.byType(TextField).at(0), '12/25/2016');
|
await tester.enterText(find.byType(TextField).at(0), '12/25/2016');
|
||||||
await tester.enterText(find.byType(TextField).at(1), '12/27/2016');
|
await tester.enterText(find.byType(TextField).at(1), '12/27/2016');
|
||||||
await tester.tap(find.byIcon(Icons.calendar_today));
|
await tester.tap(find.byIcon(Icons.calendar_today));
|
||||||
@ -651,7 +651,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('Entered text returns range', (WidgetTester tester) async {
|
testWidgets('Entered text returns range', (WidgetTester tester) async {
|
||||||
initialDateRange = null;
|
initialDateRange = null;
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
await tester.enterText(find.byType(TextField).at(0), '12/25/2016');
|
await tester.enterText(find.byType(TextField).at(0), '12/25/2016');
|
||||||
await tester.enterText(find.byType(TextField).at(1), '12/27/2016');
|
await tester.enterText(find.byType(TextField).at(1), '12/27/2016');
|
||||||
await tester.tap(find.text('OK'));
|
await tester.tap(find.text('OK'));
|
||||||
@ -666,7 +666,7 @@ void main() {
|
|||||||
testWidgets('Too short entered text shows error', (WidgetTester tester) async {
|
testWidgets('Too short entered text shows error', (WidgetTester tester) async {
|
||||||
initialDateRange = null;
|
initialDateRange = null;
|
||||||
errorFormatText = 'oops';
|
errorFormatText = 'oops';
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
await tester.enterText(find.byType(TextField).at(0), '12/25');
|
await tester.enterText(find.byType(TextField).at(0), '12/25');
|
||||||
await tester.enterText(find.byType(TextField).at(1), '12/25');
|
await tester.enterText(find.byType(TextField).at(1), '12/25');
|
||||||
expect(find.text(errorFormatText!), findsNothing);
|
expect(find.text(errorFormatText!), findsNothing);
|
||||||
@ -680,7 +680,7 @@ void main() {
|
|||||||
testWidgets('Bad format entered text shows error', (WidgetTester tester) async {
|
testWidgets('Bad format entered text shows error', (WidgetTester tester) async {
|
||||||
initialDateRange = null;
|
initialDateRange = null;
|
||||||
errorFormatText = 'oops';
|
errorFormatText = 'oops';
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
await tester.enterText(find.byType(TextField).at(0), '20202014');
|
await tester.enterText(find.byType(TextField).at(0), '20202014');
|
||||||
await tester.enterText(find.byType(TextField).at(1), '20212014');
|
await tester.enterText(find.byType(TextField).at(1), '20212014');
|
||||||
expect(find.text(errorFormatText!), findsNothing);
|
expect(find.text(errorFormatText!), findsNothing);
|
||||||
@ -694,7 +694,7 @@ void main() {
|
|||||||
testWidgets('Invalid entered text shows error', (WidgetTester tester) async {
|
testWidgets('Invalid entered text shows error', (WidgetTester tester) async {
|
||||||
initialDateRange = null;
|
initialDateRange = null;
|
||||||
errorInvalidText = 'oops';
|
errorInvalidText = 'oops';
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
await tester.enterText(find.byType(TextField).at(0), '08/08/2014');
|
await tester.enterText(find.byType(TextField).at(0), '08/08/2014');
|
||||||
await tester.enterText(find.byType(TextField).at(1), '08/08/2014');
|
await tester.enterText(find.byType(TextField).at(1), '08/08/2014');
|
||||||
expect(find.text(errorInvalidText!), findsNothing);
|
expect(find.text(errorInvalidText!), findsNothing);
|
||||||
@ -708,7 +708,7 @@ void main() {
|
|||||||
testWidgets('End before start date shows error', (WidgetTester tester) async {
|
testWidgets('End before start date shows error', (WidgetTester tester) async {
|
||||||
initialDateRange = null;
|
initialDateRange = null;
|
||||||
errorInvalidRangeText = 'oops';
|
errorInvalidRangeText = 'oops';
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
await tester.enterText(find.byType(TextField).at(0), '12/27/2016');
|
await tester.enterText(find.byType(TextField).at(0), '12/27/2016');
|
||||||
await tester.enterText(find.byType(TextField).at(1), '12/25/2016');
|
await tester.enterText(find.byType(TextField).at(1), '12/25/2016');
|
||||||
expect(find.text(errorInvalidRangeText!), findsNothing);
|
expect(find.text(errorInvalidRangeText!), findsNothing);
|
||||||
@ -722,7 +722,7 @@ void main() {
|
|||||||
testWidgets('Error text only displayed for invalid date', (WidgetTester tester) async {
|
testWidgets('Error text only displayed for invalid date', (WidgetTester tester) async {
|
||||||
initialDateRange = null;
|
initialDateRange = null;
|
||||||
errorInvalidText = 'oops';
|
errorInvalidText = 'oops';
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
await tester.enterText(find.byType(TextField).at(0), '12/27/2016');
|
await tester.enterText(find.byType(TextField).at(0), '12/27/2016');
|
||||||
await tester.enterText(find.byType(TextField).at(1), '01/01/2018');
|
await tester.enterText(find.byType(TextField).at(1), '01/01/2018');
|
||||||
expect(find.text(errorInvalidText!), findsNothing);
|
expect(find.text(errorInvalidText!), findsNothing);
|
||||||
@ -735,7 +735,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('End before start date does not get passed to calendar mode', (WidgetTester tester) async {
|
testWidgets('End before start date does not get passed to calendar mode', (WidgetTester tester) async {
|
||||||
initialDateRange = null;
|
initialDateRange = null;
|
||||||
await preparePicker(tester, (Future<DateTimeRange> range) async {
|
await preparePicker(tester, (Future<DateTimeRange?> range) async {
|
||||||
await tester.enterText(find.byType(TextField).at(0), '12/27/2016');
|
await tester.enterText(find.byType(TextField).at(0), '12/27/2016');
|
||||||
await tester.enterText(find.byType(TextField).at(1), '12/25/2016');
|
await tester.enterText(find.byType(TextField).at(1), '12/25/2016');
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ void main() {
|
|||||||
|
|
||||||
final BuildContext context = tester.element(find.text('Go'));
|
final BuildContext context = tester.element(find.text('Go'));
|
||||||
|
|
||||||
final Future<int> result = showDialog<int>(
|
final Future<int?> result = showDialog<int>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return SimpleDialog(
|
return SimpleDialog(
|
||||||
@ -273,7 +273,7 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
final Future<int> result = showDialog<int>(
|
final Future<int?> result = showDialog<int>(
|
||||||
context: navigator.currentContext!,
|
context: navigator.currentContext!,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return SimpleDialog(
|
return SimpleDialog(
|
||||||
@ -1382,7 +1382,7 @@ void main() {
|
|||||||
final List<int> dismissedItems = <int>[];
|
final List<int> dismissedItems = <int>[];
|
||||||
|
|
||||||
// Dismiss is confirmed IFF confirmDismiss() returns true.
|
// Dismiss is confirmed IFF confirmDismiss() returns true.
|
||||||
Future<bool> confirmDismiss (DismissDirection dismissDirection) {
|
Future<bool?> confirmDismiss (DismissDirection dismissDirection) async {
|
||||||
return showDialog<bool>(
|
return showDialog<bool>(
|
||||||
context: _scaffoldKey.currentContext!,
|
context: _scaffoldKey.currentContext!,
|
||||||
barrierDismissible: true, // showDialog() returns null if tapped outside the dialog
|
barrierDismissible: true, // showDialog() returns null if tapped outside the dialog
|
||||||
@ -1762,7 +1762,7 @@ void main() {
|
|||||||
final BuildContext context = tester.element(find.text('Go'));
|
final BuildContext context = tester.element(find.text('Go'));
|
||||||
const RouteSettings exampleSetting = RouteSettings(name: 'simple');
|
const RouteSettings exampleSetting = RouteSettings(name: 'simple');
|
||||||
|
|
||||||
final Future<int> result = showDialog<int>(
|
final Future<int?> result = showDialog<int>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return SimpleDialog(
|
return SimpleDialog(
|
||||||
|
@ -465,7 +465,7 @@ void main() {
|
|||||||
final WidgetPredicate popupMenu = (Widget widget) {
|
final WidgetPredicate popupMenu = (Widget widget) {
|
||||||
final String widgetType = widget.runtimeType.toString();
|
final String widgetType = widget.runtimeType.toString();
|
||||||
// TODO(mraleph): Remove the old case below.
|
// TODO(mraleph): Remove the old case below.
|
||||||
return widgetType == '_PopupMenu<int>' // normal case
|
return widgetType == '_PopupMenu<int?>' // normal case
|
||||||
|| widgetType == '_PopupMenu'; // for old versions of Dart that don't reify method type arguments
|
|| widgetType == '_PopupMenu'; // for old versions of Dart that don't reify method type arguments
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -794,7 +794,7 @@ void main() {
|
|||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
// The position is different than the offset because the default position isn't at the origin.
|
// The position is different than the offset because the default position isn't at the origin.
|
||||||
expect(tester.getTopLeft(find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_PopupMenu<int>')), const Offset(364.0, 324.0));
|
expect(tester.getTopLeft(find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_PopupMenu<int?>')), const Offset(364.0, 324.0));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('open PopupMenu has correct semantics', (WidgetTester tester) async {
|
testWidgets('open PopupMenu has correct semantics', (WidgetTester tester) async {
|
||||||
|
@ -80,7 +80,7 @@ void main() {
|
|||||||
// regression test for https://github.com/flutter/flutter/issues/18145
|
// regression test for https://github.com/flutter/flutter/issues/18145
|
||||||
|
|
||||||
final _TestSearchDelegate delegate = _TestSearchDelegate();
|
final _TestSearchDelegate delegate = _TestSearchDelegate();
|
||||||
final List<String> selectedResults = <String>[];
|
final List<String?> selectedResults = <String?>[];
|
||||||
|
|
||||||
await tester.pumpWidget(TestHomePage(
|
await tester.pumpWidget(TestHomePage(
|
||||||
delegate: delegate,
|
delegate: delegate,
|
||||||
@ -105,7 +105,7 @@ void main() {
|
|||||||
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(selectedResults, <void>[null]);
|
expect(selectedResults, <String?>[null]);
|
||||||
|
|
||||||
// We are on the homepage again
|
// We are on the homepage again
|
||||||
expect(find.text('HomeBody'), findsOneWidget);
|
expect(find.text('HomeBody'), findsOneWidget);
|
||||||
@ -374,7 +374,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Closing nested search returns to search', (WidgetTester tester) async {
|
testWidgets('Closing nested search returns to search', (WidgetTester tester) async {
|
||||||
final List<String> nestedSearchResults = <String>[];
|
final List<String?> nestedSearchResults = <String?>[];
|
||||||
final _TestSearchDelegate nestedSearchDelegate = _TestSearchDelegate(
|
final _TestSearchDelegate nestedSearchDelegate = _TestSearchDelegate(
|
||||||
suggestions: 'Nested Suggestions',
|
suggestions: 'Nested Suggestions',
|
||||||
result: 'Nested Result',
|
result: 'Nested Result',
|
||||||
@ -389,7 +389,7 @@ void main() {
|
|||||||
tooltip: 'Nested Search',
|
tooltip: 'Nested Search',
|
||||||
icon: const Icon(Icons.search),
|
icon: const Icon(Icons.search),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final String result = await showSearch(
|
final String? result = await showSearch(
|
||||||
context: context,
|
context: context,
|
||||||
delegate: nestedSearchDelegate,
|
delegate: nestedSearchDelegate,
|
||||||
);
|
);
|
||||||
@ -467,7 +467,7 @@ void main() {
|
|||||||
tooltip: 'Nested Search',
|
tooltip: 'Nested Search',
|
||||||
icon: const Icon(Icons.search),
|
icon: const Icon(Icons.search),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final String result = await showSearch(
|
final String? result = await showSearch(
|
||||||
context: context,
|
context: context,
|
||||||
delegate: nestedSearchDelegate,
|
delegate: nestedSearchDelegate,
|
||||||
);
|
);
|
||||||
@ -702,7 +702,7 @@ class TestHomePage extends StatelessWidget {
|
|||||||
this.initialQuery,
|
this.initialQuery,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final List<String>? results;
|
final List<String?>? results;
|
||||||
final SearchDelegate<String> delegate;
|
final SearchDelegate<String> delegate;
|
||||||
final bool passInInitialQuery;
|
final bool passInInitialQuery;
|
||||||
final String? initialQuery;
|
final String? initialQuery;
|
||||||
@ -719,7 +719,7 @@ class TestHomePage extends StatelessWidget {
|
|||||||
tooltip: 'Search',
|
tooltip: 'Search',
|
||||||
icon: const Icon(Icons.search),
|
icon: const Icon(Icons.search),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
String selectedResult;
|
String? selectedResult;
|
||||||
if (passInInitialQuery) {
|
if (passInInitialQuery) {
|
||||||
selectedResult = await showSearch<String>(
|
selectedResult = await showSearch<String>(
|
||||||
context: context,
|
context: context,
|
||||||
|
@ -23,7 +23,7 @@ class _TimePickerLauncher extends StatelessWidget {
|
|||||||
this.entryMode = TimePickerEntryMode.dial,
|
this.entryMode = TimePickerEntryMode.dial,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final ValueChanged<TimeOfDay> onChanged;
|
final ValueChanged<TimeOfDay?> onChanged;
|
||||||
final Locale? locale;
|
final Locale? locale;
|
||||||
final TimePickerEntryMode entryMode;
|
final TimePickerEntryMode entryMode;
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ class _TimePickerLauncher extends StatelessWidget {
|
|||||||
|
|
||||||
Future<Offset?> startPicker(
|
Future<Offset?> startPicker(
|
||||||
WidgetTester tester,
|
WidgetTester tester,
|
||||||
ValueChanged<TimeOfDay> onChanged, {
|
ValueChanged<TimeOfDay?> onChanged, {
|
||||||
TimePickerEntryMode entryMode = TimePickerEntryMode.dial,
|
TimePickerEntryMode entryMode = TimePickerEntryMode.dial,
|
||||||
}) async {
|
}) async {
|
||||||
await tester.pumpWidget(_TimePickerLauncher(onChanged: onChanged, locale: const Locale('en', 'US'), entryMode: entryMode));
|
await tester.pumpWidget(_TimePickerLauncher(onChanged: onChanged, locale: const Locale('en', 'US'), entryMode: entryMode));
|
||||||
@ -82,24 +82,24 @@ void main() {
|
|||||||
|
|
||||||
void _tests() {
|
void _tests() {
|
||||||
testWidgets('tap-select an hour', (WidgetTester tester) async {
|
testWidgets('tap-select an hour', (WidgetTester tester) async {
|
||||||
late TimeOfDay result;
|
TimeOfDay? result;
|
||||||
|
|
||||||
Offset center = (await startPicker(tester, (TimeOfDay time) { result = time; }))!;
|
Offset center = (await startPicker(tester, (TimeOfDay? time) { result = time; }))!;
|
||||||
await tester.tapAt(Offset(center.dx, center.dy - 50.0)); // 12:00 AM
|
await tester.tapAt(Offset(center.dx, center.dy - 50.0)); // 12:00 AM
|
||||||
await finishPicker(tester);
|
await finishPicker(tester);
|
||||||
expect(result, equals(const TimeOfDay(hour: 0, minute: 0)));
|
expect(result, equals(const TimeOfDay(hour: 0, minute: 0)));
|
||||||
|
|
||||||
center = (await startPicker(tester, (TimeOfDay time) { result = time; }))!;
|
center = (await startPicker(tester, (TimeOfDay? time) { result = time; }))!;
|
||||||
await tester.tapAt(Offset(center.dx + 50.0, center.dy));
|
await tester.tapAt(Offset(center.dx + 50.0, center.dy));
|
||||||
await finishPicker(tester);
|
await finishPicker(tester);
|
||||||
expect(result, equals(const TimeOfDay(hour: 3, minute: 0)));
|
expect(result, equals(const TimeOfDay(hour: 3, minute: 0)));
|
||||||
|
|
||||||
center = (await startPicker(tester, (TimeOfDay time) { result = time; }))!;
|
center = (await startPicker(tester, (TimeOfDay? time) { result = time; }))!;
|
||||||
await tester.tapAt(Offset(center.dx, center.dy + 50.0));
|
await tester.tapAt(Offset(center.dx, center.dy + 50.0));
|
||||||
await finishPicker(tester);
|
await finishPicker(tester);
|
||||||
expect(result, equals(const TimeOfDay(hour: 6, minute: 0)));
|
expect(result, equals(const TimeOfDay(hour: 6, minute: 0)));
|
||||||
|
|
||||||
center = (await startPicker(tester, (TimeOfDay time) { result = time; }))!;
|
center = (await startPicker(tester, (TimeOfDay? time) { result = time; }))!;
|
||||||
await tester.tapAt(Offset(center.dx, center.dy + 50.0));
|
await tester.tapAt(Offset(center.dx, center.dy + 50.0));
|
||||||
await tester.tapAt(Offset(center.dx - 50, center.dy));
|
await tester.tapAt(Offset(center.dx - 50, center.dy));
|
||||||
await finishPicker(tester);
|
await finishPicker(tester);
|
||||||
@ -109,7 +109,7 @@ void _tests() {
|
|||||||
testWidgets('drag-select an hour', (WidgetTester tester) async {
|
testWidgets('drag-select an hour', (WidgetTester tester) async {
|
||||||
late TimeOfDay result;
|
late TimeOfDay result;
|
||||||
|
|
||||||
final Offset center = (await startPicker(tester, (TimeOfDay time) { result = time; }))!;
|
final Offset center = (await startPicker(tester, (TimeOfDay? time) { result = time!; }))!;
|
||||||
final Offset hour0 = Offset(center.dx, center.dy - 50.0); // 12:00 AM
|
final Offset hour0 = Offset(center.dx, center.dy - 50.0); // 12:00 AM
|
||||||
final Offset hour3 = Offset(center.dx + 50.0, center.dy);
|
final Offset hour3 = Offset(center.dx + 50.0, center.dy);
|
||||||
final Offset hour6 = Offset(center.dx, center.dy + 50.0);
|
final Offset hour6 = Offset(center.dx, center.dy + 50.0);
|
||||||
@ -123,21 +123,21 @@ void _tests() {
|
|||||||
await finishPicker(tester);
|
await finishPicker(tester);
|
||||||
expect(result.hour, 0);
|
expect(result.hour, 0);
|
||||||
|
|
||||||
expect(await startPicker(tester, (TimeOfDay time) { result = time; }), equals(center));
|
expect(await startPicker(tester, (TimeOfDay? time) { result = time!; }), equals(center));
|
||||||
gesture = await tester.startGesture(hour0);
|
gesture = await tester.startGesture(hour0);
|
||||||
await gesture.moveBy(hour3 - hour0);
|
await gesture.moveBy(hour3 - hour0);
|
||||||
await gesture.up();
|
await gesture.up();
|
||||||
await finishPicker(tester);
|
await finishPicker(tester);
|
||||||
expect(result.hour, 3);
|
expect(result.hour, 3);
|
||||||
|
|
||||||
expect(await startPicker(tester, (TimeOfDay time) { result = time; }), equals(center));
|
expect(await startPicker(tester, (TimeOfDay? time) { result = time!; }), equals(center));
|
||||||
gesture = await tester.startGesture(hour3);
|
gesture = await tester.startGesture(hour3);
|
||||||
await gesture.moveBy(hour6 - hour3);
|
await gesture.moveBy(hour6 - hour3);
|
||||||
await gesture.up();
|
await gesture.up();
|
||||||
await finishPicker(tester);
|
await finishPicker(tester);
|
||||||
expect(result.hour, equals(6));
|
expect(result.hour, equals(6));
|
||||||
|
|
||||||
expect(await startPicker(tester, (TimeOfDay time) { result = time; }), equals(center));
|
expect(await startPicker(tester, (TimeOfDay? time) { result = time!; }), equals(center));
|
||||||
gesture = await tester.startGesture(hour6);
|
gesture = await tester.startGesture(hour6);
|
||||||
await gesture.moveBy(hour9 - hour6);
|
await gesture.moveBy(hour9 - hour6);
|
||||||
await gesture.up();
|
await gesture.up();
|
||||||
@ -148,7 +148,7 @@ void _tests() {
|
|||||||
testWidgets('tap-select switches from hour to minute', (WidgetTester tester) async {
|
testWidgets('tap-select switches from hour to minute', (WidgetTester tester) async {
|
||||||
late TimeOfDay result;
|
late TimeOfDay result;
|
||||||
|
|
||||||
final Offset center = (await startPicker(tester, (TimeOfDay time) { result = time; }))!;
|
final Offset center = (await startPicker(tester, (TimeOfDay? time) { result = time!; }))!;
|
||||||
final Offset hour6 = Offset(center.dx, center.dy + 50.0); // 6:00
|
final Offset hour6 = Offset(center.dx, center.dy + 50.0); // 6:00
|
||||||
final Offset min45 = Offset(center.dx - 50.0, center.dy); // 45 mins (or 9:00 hours)
|
final Offset min45 = Offset(center.dx - 50.0, center.dy); // 45 mins (or 9:00 hours)
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ void _tests() {
|
|||||||
testWidgets('drag-select switches from hour to minute', (WidgetTester tester) async {
|
testWidgets('drag-select switches from hour to minute', (WidgetTester tester) async {
|
||||||
late TimeOfDay result;
|
late TimeOfDay result;
|
||||||
|
|
||||||
final Offset center = (await startPicker(tester, (TimeOfDay time) { result = time; }))!;
|
final Offset center = (await startPicker(tester, (TimeOfDay? time) { result = time!; }))!;
|
||||||
final Offset hour3 = Offset(center.dx + 50.0, center.dy);
|
final Offset hour3 = Offset(center.dx + 50.0, center.dy);
|
||||||
final Offset hour6 = Offset(center.dx, center.dy + 50.0);
|
final Offset hour6 = Offset(center.dx, center.dy + 50.0);
|
||||||
final Offset hour9 = Offset(center.dx - 50.0, center.dy);
|
final Offset hour9 = Offset(center.dx - 50.0, center.dy);
|
||||||
@ -181,7 +181,7 @@ void _tests() {
|
|||||||
testWidgets('tap-select rounds down to nearest 5 minute increment', (WidgetTester tester) async {
|
testWidgets('tap-select rounds down to nearest 5 minute increment', (WidgetTester tester) async {
|
||||||
late TimeOfDay result;
|
late TimeOfDay result;
|
||||||
|
|
||||||
final Offset center = (await startPicker(tester, (TimeOfDay time) { result = time; }))!;
|
final Offset center = (await startPicker(tester, (TimeOfDay? time) { result = time!; }))!;
|
||||||
final Offset hour6 = Offset(center.dx, center.dy + 50.0); // 6:00
|
final Offset hour6 = Offset(center.dx, center.dy + 50.0); // 6:00
|
||||||
final Offset min46 = Offset(center.dx - 50.0, center.dy - 5); // 46 mins
|
final Offset min46 = Offset(center.dx - 50.0, center.dy - 5); // 46 mins
|
||||||
|
|
||||||
@ -195,7 +195,7 @@ void _tests() {
|
|||||||
testWidgets('tap-select rounds up to nearest 5 minute increment', (WidgetTester tester) async {
|
testWidgets('tap-select rounds up to nearest 5 minute increment', (WidgetTester tester) async {
|
||||||
late TimeOfDay result;
|
late TimeOfDay result;
|
||||||
|
|
||||||
final Offset center = (await startPicker(tester, (TimeOfDay time) { result = time; }))!;
|
final Offset center = (await startPicker(tester, (TimeOfDay? time) { result = time!; }))!;
|
||||||
final Offset hour6 = Offset(center.dx, center.dy + 50.0); // 6:00
|
final Offset hour6 = Offset(center.dx, center.dy + 50.0); // 6:00
|
||||||
final Offset min48 = Offset(center.dx - 50.0, center.dy - 15); // 48 mins
|
final Offset min48 = Offset(center.dx - 50.0, center.dy - 15); // 48 mins
|
||||||
|
|
||||||
@ -220,14 +220,14 @@ void _tests() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('tap-select vibrates once', (WidgetTester tester) async {
|
testWidgets('tap-select vibrates once', (WidgetTester tester) async {
|
||||||
final Offset center = (await startPicker(tester, (TimeOfDay time) { }))!;
|
final Offset center = (await startPicker(tester, (TimeOfDay? time) { }))!;
|
||||||
await tester.tapAt(Offset(center.dx, center.dy - 50.0));
|
await tester.tapAt(Offset(center.dx, center.dy - 50.0));
|
||||||
await finishPicker(tester);
|
await finishPicker(tester);
|
||||||
expect(feedback.hapticCount, 1);
|
expect(feedback.hapticCount, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('quick successive tap-selects vibrate once', (WidgetTester tester) async {
|
testWidgets('quick successive tap-selects vibrate once', (WidgetTester tester) async {
|
||||||
final Offset center = (await startPicker(tester, (TimeOfDay time) { }))!;
|
final Offset center = (await startPicker(tester, (TimeOfDay? time) { }))!;
|
||||||
await tester.tapAt(Offset(center.dx, center.dy - 50.0));
|
await tester.tapAt(Offset(center.dx, center.dy - 50.0));
|
||||||
await tester.pump(kFastFeedbackInterval);
|
await tester.pump(kFastFeedbackInterval);
|
||||||
await tester.tapAt(Offset(center.dx, center.dy + 50.0));
|
await tester.tapAt(Offset(center.dx, center.dy + 50.0));
|
||||||
@ -236,7 +236,7 @@ void _tests() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('slow successive tap-selects vibrate once per tap', (WidgetTester tester) async {
|
testWidgets('slow successive tap-selects vibrate once per tap', (WidgetTester tester) async {
|
||||||
final Offset center = (await startPicker(tester, (TimeOfDay time) { }))!;
|
final Offset center = (await startPicker(tester, (TimeOfDay? time) { }))!;
|
||||||
await tester.tapAt(Offset(center.dx, center.dy - 50.0));
|
await tester.tapAt(Offset(center.dx, center.dy - 50.0));
|
||||||
await tester.pump(kSlowFeedbackInterval);
|
await tester.pump(kSlowFeedbackInterval);
|
||||||
await tester.tapAt(Offset(center.dx, center.dy + 50.0));
|
await tester.tapAt(Offset(center.dx, center.dy + 50.0));
|
||||||
@ -247,7 +247,7 @@ void _tests() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('drag-select vibrates once', (WidgetTester tester) async {
|
testWidgets('drag-select vibrates once', (WidgetTester tester) async {
|
||||||
final Offset center = (await startPicker(tester, (TimeOfDay time) { }))!;
|
final Offset center = (await startPicker(tester, (TimeOfDay? time) { }))!;
|
||||||
final Offset hour0 = Offset(center.dx, center.dy - 50.0);
|
final Offset hour0 = Offset(center.dx, center.dy - 50.0);
|
||||||
final Offset hour3 = Offset(center.dx + 50.0, center.dy);
|
final Offset hour3 = Offset(center.dx + 50.0, center.dy);
|
||||||
|
|
||||||
@ -259,7 +259,7 @@ void _tests() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('quick drag-select vibrates once', (WidgetTester tester) async {
|
testWidgets('quick drag-select vibrates once', (WidgetTester tester) async {
|
||||||
final Offset center = (await startPicker(tester, (TimeOfDay time) { }))!;
|
final Offset center = (await startPicker(tester, (TimeOfDay? time) { }))!;
|
||||||
final Offset hour0 = Offset(center.dx, center.dy - 50.0);
|
final Offset hour0 = Offset(center.dx, center.dy - 50.0);
|
||||||
final Offset hour3 = Offset(center.dx + 50.0, center.dy);
|
final Offset hour3 = Offset(center.dx + 50.0, center.dy);
|
||||||
|
|
||||||
@ -275,7 +275,7 @@ void _tests() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('slow drag-select vibrates once', (WidgetTester tester) async {
|
testWidgets('slow drag-select vibrates once', (WidgetTester tester) async {
|
||||||
final Offset center = (await startPicker(tester, (TimeOfDay time) { }))!;
|
final Offset center = (await startPicker(tester, (TimeOfDay? time) { }))!;
|
||||||
final Offset hour0 = Offset(center.dx, center.dy - 50.0);
|
final Offset hour0 = Offset(center.dx, center.dy - 50.0);
|
||||||
final Offset hour3 = Offset(center.dx + 50.0, center.dy);
|
final Offset hour3 = Offset(center.dx + 50.0, center.dy);
|
||||||
|
|
||||||
@ -794,7 +794,7 @@ void _testsInput() {
|
|||||||
|
|
||||||
testWidgets('Initial time is the default', (WidgetTester tester) async {
|
testWidgets('Initial time is the default', (WidgetTester tester) async {
|
||||||
late TimeOfDay result;
|
late TimeOfDay result;
|
||||||
await startPicker(tester, (TimeOfDay time) { result = time; }, entryMode: TimePickerEntryMode.input);
|
await startPicker(tester, (TimeOfDay? time) { result = time!; }, entryMode: TimePickerEntryMode.input);
|
||||||
await finishPicker(tester);
|
await finishPicker(tester);
|
||||||
expect(result, equals(const TimeOfDay(hour: 7, minute: 0)));
|
expect(result, equals(const TimeOfDay(hour: 7, minute: 0)));
|
||||||
});
|
});
|
||||||
@ -898,7 +898,7 @@ void _testsInput() {
|
|||||||
|
|
||||||
testWidgets('Entered text returns time', (WidgetTester tester) async {
|
testWidgets('Entered text returns time', (WidgetTester tester) async {
|
||||||
late TimeOfDay result;
|
late TimeOfDay result;
|
||||||
await startPicker(tester, (TimeOfDay time) { result = time; }, entryMode: TimePickerEntryMode.input);
|
await startPicker(tester, (TimeOfDay? time) { result = time!; }, entryMode: TimePickerEntryMode.input);
|
||||||
await tester.enterText(find.byType(TextField).first, '9');
|
await tester.enterText(find.byType(TextField).first, '9');
|
||||||
await tester.enterText(find.byType(TextField).last, '12');
|
await tester.enterText(find.byType(TextField).last, '12');
|
||||||
await finishPicker(tester);
|
await finishPicker(tester);
|
||||||
@ -907,7 +907,7 @@ void _testsInput() {
|
|||||||
|
|
||||||
testWidgets('Toggle to dial mode keeps selected time', (WidgetTester tester) async {
|
testWidgets('Toggle to dial mode keeps selected time', (WidgetTester tester) async {
|
||||||
late TimeOfDay result;
|
late TimeOfDay result;
|
||||||
await startPicker(tester, (TimeOfDay time) { result = time; }, entryMode: TimePickerEntryMode.input);
|
await startPicker(tester, (TimeOfDay? time) { result = time!; }, entryMode: TimePickerEntryMode.input);
|
||||||
await tester.enterText(find.byType(TextField).first, '8');
|
await tester.enterText(find.byType(TextField).first, '8');
|
||||||
await tester.enterText(find.byType(TextField).last, '15');
|
await tester.enterText(find.byType(TextField).last, '15');
|
||||||
await tester.tap(find.byIcon(Icons.access_time));
|
await tester.tap(find.byIcon(Icons.access_time));
|
||||||
@ -917,7 +917,7 @@ void _testsInput() {
|
|||||||
|
|
||||||
testWidgets('Invalid text prevents dismissing', (WidgetTester tester) async {
|
testWidgets('Invalid text prevents dismissing', (WidgetTester tester) async {
|
||||||
TimeOfDay? result;
|
TimeOfDay? result;
|
||||||
await startPicker(tester, (TimeOfDay time) { result = time; }, entryMode: TimePickerEntryMode.input);
|
await startPicker(tester, (TimeOfDay? time) { result = time; }, entryMode: TimePickerEntryMode.input);
|
||||||
|
|
||||||
// Invalid hour.
|
// Invalid hour.
|
||||||
await tester.enterText(find.byType(TextField).first, '88');
|
await tester.enterText(find.byType(TextField).first, '88');
|
||||||
@ -939,7 +939,7 @@ void _testsInput() {
|
|||||||
|
|
||||||
// Fixes regression that was reverted in https://github.com/flutter/flutter/pull/64094#pullrequestreview-469836378.
|
// Fixes regression that was reverted in https://github.com/flutter/flutter/pull/64094#pullrequestreview-469836378.
|
||||||
testWidgets('Ensure hour/minute fields are top-aligned with the separator', (WidgetTester tester) async {
|
testWidgets('Ensure hour/minute fields are top-aligned with the separator', (WidgetTester tester) async {
|
||||||
await startPicker(tester, (TimeOfDay time) { }, entryMode: TimePickerEntryMode.input);
|
await startPicker(tester, (TimeOfDay? time) { }, entryMode: TimePickerEntryMode.input);
|
||||||
final double hourFieldTop = tester.getTopLeft(find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_HourTextField')).dy;
|
final double hourFieldTop = tester.getTopLeft(find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_HourTextField')).dy;
|
||||||
final double minuteFieldTop = tester.getTopLeft(find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_MinuteTextField')).dy;
|
final double minuteFieldTop = tester.getTopLeft(find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_MinuteTextField')).dy;
|
||||||
final double separatorTop = tester.getTopLeft(find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_StringFragment')).dy;
|
final double separatorTop = tester.getTopLeft(find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_StringFragment')).dy;
|
||||||
|
@ -222,8 +222,8 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Form.willPop callbacks do not accumulate', (WidgetTester tester) async {
|
testWidgets('Form.willPop callbacks do not accumulate', (WidgetTester tester) async {
|
||||||
Future<bool> showYesNoAlert(BuildContext context) {
|
Future<bool> showYesNoAlert(BuildContext context) async {
|
||||||
return showDialog<bool>(
|
return (await showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
@ -239,7 +239,7 @@ void main() {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
))!;
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildFrame() {
|
Widget buildFrame() {
|
||||||
|
@ -823,7 +823,6 @@ class _TestRecordingCanvasPatternMatcher extends _TestRecordingCanvasMatcher imp
|
|||||||
while (predicate.moveNext()) {
|
while (predicate.moveNext()) {
|
||||||
predicate.current.match(call);
|
predicate.current.match(call);
|
||||||
}
|
}
|
||||||
assert(predicate.current == null);
|
|
||||||
// We allow painting more than expected.
|
// We allow painting more than expected.
|
||||||
} on _MismatchedCall catch (data) {
|
} on _MismatchedCall catch (data) {
|
||||||
description.writeln(data.message);
|
description.writeln(data.message);
|
||||||
|
@ -174,11 +174,11 @@ class FakeAndroidPlatformViewsController {
|
|||||||
final Map<dynamic, dynamic> args = call.arguments as Map<dynamic, dynamic>;
|
final Map<dynamic, dynamic> args = call.arguments as Map<dynamic, dynamic>;
|
||||||
final int id = args['id'] as int;
|
final int id = args['id'] as int;
|
||||||
final String viewType = args['viewType'] as String;
|
final String viewType = args['viewType'] as String;
|
||||||
final double width = args['width'] as double;
|
final double? width = args['width'] as double?;
|
||||||
final double height = args['height'] as double;
|
final double? height = args['height'] as double?;
|
||||||
final int layoutDirection = args['direction'] as int;
|
final int layoutDirection = args['direction'] as int;
|
||||||
final bool hybrid = args['hybrid'] as bool;
|
final bool? hybrid = args['hybrid'] as bool?;
|
||||||
final Uint8List creationParams = args['params'] as Uint8List;
|
final Uint8List? creationParams = args['params'] as Uint8List?;
|
||||||
|
|
||||||
if (_views.containsKey(id))
|
if (_views.containsKey(id))
|
||||||
throw PlatformException(
|
throw PlatformException(
|
||||||
@ -197,7 +197,7 @@ class FakeAndroidPlatformViewsController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_views[id] = FakeAndroidPlatformView(id, viewType,
|
_views[id] = FakeAndroidPlatformView(id, viewType,
|
||||||
width != null || height != null ? Size(width, height) : null,
|
width != null && height != null ? Size(width, height) : null,
|
||||||
layoutDirection,
|
layoutDirection,
|
||||||
hybrid,
|
hybrid,
|
||||||
creationParams,
|
creationParams,
|
||||||
@ -344,7 +344,7 @@ class FakeIosPlatformViewsController {
|
|||||||
final Map<dynamic, dynamic> args = call.arguments as Map<dynamic, dynamic>;
|
final Map<dynamic, dynamic> args = call.arguments as Map<dynamic, dynamic>;
|
||||||
final int id = args['id'] as int;
|
final int id = args['id'] as int;
|
||||||
final String viewType = args['viewType'] as String;
|
final String viewType = args['viewType'] as String;
|
||||||
final Uint8List creationParams = args['params'] as Uint8List;
|
final Uint8List? creationParams = args['params'] as Uint8List?;
|
||||||
|
|
||||||
if (_views.containsKey(id)) {
|
if (_views.containsKey(id)) {
|
||||||
throw PlatformException(
|
throw PlatformException(
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
|
||||||
import 'package:flutter/painting.dart';
|
import 'package:flutter/painting.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart' show TestWidgetsFlutterBinding;
|
import 'package:flutter_test/flutter_test.dart' show TestWidgetsFlutterBinding;
|
||||||
|
@ -58,7 +58,7 @@ class MockPaintingContext extends Fake implements PaintingContext {
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
testWidgets('Control test for custom painting', (WidgetTester tester) async {
|
testWidgets('Control test for custom painting', (WidgetTester tester) async {
|
||||||
final List<String> log = <String>[];
|
final List<String?> log = <String?>[];
|
||||||
await tester.pumpWidget(CustomPaint(
|
await tester.pumpWidget(CustomPaint(
|
||||||
painter: TestCustomPainter(
|
painter: TestCustomPainter(
|
||||||
log: log,
|
log: log,
|
||||||
@ -82,7 +82,7 @@ void main() {
|
|||||||
testWidgets('Throws FlutterError on custom painter incorrect restore/save calls', (
|
testWidgets('Throws FlutterError on custom painter incorrect restore/save calls', (
|
||||||
WidgetTester tester) async {
|
WidgetTester tester) async {
|
||||||
final GlobalKey target = GlobalKey();
|
final GlobalKey target = GlobalKey();
|
||||||
final List<String> log = <String>[];
|
final List<String?> log = <String?>[];
|
||||||
await tester.pumpWidget(CustomPaint(
|
await tester.pumpWidget(CustomPaint(
|
||||||
key: target,
|
key: target,
|
||||||
isComplex: true,
|
isComplex: true,
|
||||||
@ -174,7 +174,7 @@ void main() {
|
|||||||
testWidgets('Raster cache hints', (WidgetTester tester) async {
|
testWidgets('Raster cache hints', (WidgetTester tester) async {
|
||||||
final GlobalKey target = GlobalKey();
|
final GlobalKey target = GlobalKey();
|
||||||
|
|
||||||
final List<String> log = <String>[];
|
final List<String?> log = <String?>[];
|
||||||
await tester.pumpWidget(CustomPaint(
|
await tester.pumpWidget(CustomPaint(
|
||||||
key: target,
|
key: target,
|
||||||
isComplex: true,
|
isComplex: true,
|
||||||
|
@ -18,7 +18,7 @@ const double crossAxisEndOffset = 0.5;
|
|||||||
Widget buildTest({
|
Widget buildTest({
|
||||||
double? startToEndThreshold,
|
double? startToEndThreshold,
|
||||||
TextDirection textDirection = TextDirection.ltr,
|
TextDirection textDirection = TextDirection.ltr,
|
||||||
Future<bool> Function(BuildContext context, DismissDirection direction)? confirmDismiss,
|
Future<bool?> Function(BuildContext context, DismissDirection direction)? confirmDismiss,
|
||||||
}) {
|
}) {
|
||||||
return Directionality(
|
return Directionality(
|
||||||
textDirection: textDirection,
|
textDirection: textDirection,
|
||||||
@ -679,7 +679,7 @@ void main() {
|
|||||||
return buildTest(
|
return buildTest(
|
||||||
confirmDismiss: (BuildContext context, DismissDirection dismissDirection) {
|
confirmDismiss: (BuildContext context, DismissDirection dismissDirection) {
|
||||||
confirmDismissDirection = dismissDirection;
|
confirmDismissDirection = dismissDirection;
|
||||||
return Future<bool>.value(confirmDismissValue);
|
return Future<bool?>.value(confirmDismissValue);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1516,7 +1516,7 @@ void main() {
|
|||||||
expect(imageCache!.liveImageCount, 1);
|
expect(imageCache!.liveImageCount, 1);
|
||||||
expect(imageCache!.containsKey(provider), false);
|
expect(imageCache!.containsKey(provider), false);
|
||||||
|
|
||||||
final ImageCacheStatus providerLocation = await provider.obtainCacheStatus(configuration: ImageConfiguration.empty);
|
final ImageCacheStatus providerLocation = (await provider.obtainCacheStatus(configuration: ImageConfiguration.empty))!;
|
||||||
|
|
||||||
expect(providerLocation, isNotNull);
|
expect(providerLocation, isNotNull);
|
||||||
expect(providerLocation.live, true);
|
expect(providerLocation.live, true);
|
||||||
|
@ -957,7 +957,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('replaceNamed returned value', (WidgetTester tester) async {
|
testWidgets('replaceNamed returned value', (WidgetTester tester) async {
|
||||||
late Future<String> value;
|
late Future<String?> value;
|
||||||
|
|
||||||
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
|
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
|
||||||
'/' : (BuildContext context) => OnTapPage(id: '/', onTap: () { Navigator.pushNamed(context, '/A'); }),
|
'/' : (BuildContext context) => OnTapPage(id: '/', onTap: () { Navigator.pushNamed(context, '/A'); }),
|
||||||
@ -1001,7 +1001,7 @@ void main() {
|
|||||||
expect(find.text('A'), findsNothing);
|
expect(find.text('A'), findsNothing);
|
||||||
expect(find.text('B'), findsNothing);
|
expect(find.text('B'), findsNothing);
|
||||||
|
|
||||||
final String replaceNamedValue = await value; // replaceNamed result was 'B'
|
final String? replaceNamedValue = await value; // replaceNamed result was 'B'
|
||||||
expect(replaceNamedValue, 'B');
|
expect(replaceNamedValue, 'B');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1092,7 +1092,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('remove a route whose value is awaited', (WidgetTester tester) async {
|
testWidgets('remove a route whose value is awaited', (WidgetTester tester) async {
|
||||||
late Future<String> pageValue;
|
late Future<String?> pageValue;
|
||||||
final Map<String, WidgetBuilder> pageBuilders = <String, WidgetBuilder>{
|
final Map<String, WidgetBuilder> pageBuilders = <String, WidgetBuilder>{
|
||||||
'/': (BuildContext context) => OnTapPage(id: '/', onTap: () { pageValue = Navigator.pushNamed(context, '/A'); }),
|
'/': (BuildContext context) => OnTapPage(id: '/', onTap: () { pageValue = Navigator.pushNamed(context, '/A'); }),
|
||||||
'/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.pop(context, 'A'); }),
|
'/A': (BuildContext context) => OnTapPage(id: 'A', onTap: () { Navigator.pop(context, 'A'); }),
|
||||||
@ -1113,7 +1113,7 @@ void main() {
|
|||||||
|
|
||||||
await tester.tap(find.text('/')); // pushNamed('/A'), stack becomes /, /A
|
await tester.tap(find.text('/')); // pushNamed('/A'), stack becomes /, /A
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
pageValue.then((String value) { assert(false); });
|
pageValue.then((String? value) { assert(false); });
|
||||||
|
|
||||||
final NavigatorState navigator = tester.state<NavigatorState>(find.byType(Navigator));
|
final NavigatorState navigator = tester.state<NavigatorState>(find.byType(Navigator));
|
||||||
navigator.removeRoute(routes['/A']!); // stack becomes /, pageValue will not complete
|
navigator.removeRoute(routes['/A']!); // stack becomes /, pageValue will not complete
|
||||||
|
@ -285,7 +285,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TestRestorableValue extends RestorableValue<Object> {
|
class _TestRestorableValue extends RestorableValue<Object?> {
|
||||||
@override
|
@override
|
||||||
Object createDefaultValue() {
|
Object createDefaultValue() {
|
||||||
return 55;
|
return 55;
|
||||||
@ -300,12 +300,12 @@ class _TestRestorableValue extends RestorableValue<Object> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Object fromPrimitives(Object data) {
|
Object? fromPrimitives(Object? data) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Object toPrimitives() {
|
Object? toPrimitives() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -632,7 +632,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('RestorableProperty throws after disposed', () {
|
test('RestorableProperty throws after disposed', () {
|
||||||
final RestorableProperty<Object> property = _TestRestorableProperty(10);
|
final RestorableProperty<Object?> property = _TestRestorableProperty(10);
|
||||||
property.dispose();
|
property.dispose();
|
||||||
expect(() => property.dispose(), throwsFlutterError);
|
expect(() => property.dispose(), throwsFlutterError);
|
||||||
});
|
});
|
||||||
@ -660,8 +660,8 @@ class _TestRestorableWidgetState extends State<_TestRestorableWidget> with Resto
|
|||||||
_TestRestorableProperty? additionalProperty;
|
_TestRestorableProperty? additionalProperty;
|
||||||
bool _rerigisterAdditionalProperty = false;
|
bool _rerigisterAdditionalProperty = false;
|
||||||
|
|
||||||
final List<RestorationBucket?> restoreStateLog = <RestorationBucket>[];
|
final List<RestorationBucket?> restoreStateLog = <RestorationBucket?>[];
|
||||||
final List<RestorationBucket?> toggleBucketLog = <RestorationBucket>[];
|
final List<RestorationBucket?> toggleBucketLog = <RestorationBucket?>[];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
|
void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
|
||||||
@ -737,7 +737,7 @@ Map<String, dynamic> _createRawDataSet() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TestRestorableProperty extends RestorableProperty<Object> {
|
class _TestRestorableProperty extends RestorableProperty<Object?> {
|
||||||
_TestRestorableProperty(this._value);
|
_TestRestorableProperty(this._value);
|
||||||
|
|
||||||
List<String> log = <String>[];
|
List<String> log = <String>[];
|
||||||
@ -751,35 +751,35 @@ class _TestRestorableProperty extends RestorableProperty<Object> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Object createDefaultValue() {
|
Object? createDefaultValue() {
|
||||||
log.add('createDefaultValue');
|
log.add('createDefaultValue');
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Object fromPrimitives(Object data) {
|
Object? fromPrimitives(Object? data) {
|
||||||
log.add('fromPrimitives');
|
log.add('fromPrimitives');
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object get value {
|
Object? get value {
|
||||||
assert(isRegistered);
|
assert(isRegistered);
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
Object _value;
|
Object? _value;
|
||||||
set value(Object value) {
|
set value(Object? value) {
|
||||||
_value = value;
|
_value = value;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initWithValue(Object v) {
|
void initWithValue(Object? v) {
|
||||||
log.add('initWithValue');
|
log.add('initWithValue');
|
||||||
_value = v;
|
_value = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Object toPrimitives() {
|
Object? toPrimitives() {
|
||||||
log.add('toPrimitives');
|
log.add('toPrimitives');
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,7 @@ class TestWidget extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class TestWidgetState extends State<TestWidget> with RestorationMixin {
|
class TestWidgetState extends State<TestWidget> with RestorationMixin {
|
||||||
List<RestorationBucket?> buckets = <RestorationBucket>[];
|
List<RestorationBucket?> buckets = <RestorationBucket?>[];
|
||||||
List<bool> flags = <bool>[];
|
List<bool> flags = <bool>[];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -302,7 +302,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('injects null when rootBucket is null', (WidgetTester tester) async {
|
testWidgets('injects null when rootBucket is null', (WidgetTester tester) async {
|
||||||
final Completer<RestorationBucket> completer = Completer<RestorationBucket>();
|
final Completer<RestorationBucket?> completer = Completer<RestorationBucket?>();
|
||||||
binding.restorationManager.rootBucket = completer.future;
|
binding.restorationManager.rootBucket = completer.future;
|
||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
|
@ -1319,28 +1319,28 @@ void main() {
|
|||||||
final Finder animatedModalBarrier = find.byType(AnimatedModalBarrier);
|
final Finder animatedModalBarrier = find.byType(AnimatedModalBarrier);
|
||||||
expect(animatedModalBarrier, findsOneWidget);
|
expect(animatedModalBarrier, findsOneWidget);
|
||||||
|
|
||||||
Animation<Color> modalBarrierAnimation;
|
Animation<Color?> modalBarrierAnimation;
|
||||||
modalBarrierAnimation = tester.widget<AnimatedModalBarrier>(animatedModalBarrier).color;
|
modalBarrierAnimation = tester.widget<AnimatedModalBarrier>(animatedModalBarrier).color;
|
||||||
expect(modalBarrierAnimation.value, Colors.transparent);
|
expect(modalBarrierAnimation.value, Colors.transparent);
|
||||||
|
|
||||||
await tester.pump(const Duration(milliseconds: 25));
|
await tester.pump(const Duration(milliseconds: 25));
|
||||||
modalBarrierAnimation = tester.widget<AnimatedModalBarrier>(animatedModalBarrier).color;
|
modalBarrierAnimation = tester.widget<AnimatedModalBarrier>(animatedModalBarrier).color;
|
||||||
expect(
|
expect(
|
||||||
modalBarrierAnimation.value.alpha,
|
modalBarrierAnimation.value!.alpha,
|
||||||
closeTo(_getExpectedBarrierTweenAlphaValue(0.25), 1),
|
closeTo(_getExpectedBarrierTweenAlphaValue(0.25), 1),
|
||||||
);
|
);
|
||||||
|
|
||||||
await tester.pump(const Duration(milliseconds: 25));
|
await tester.pump(const Duration(milliseconds: 25));
|
||||||
modalBarrierAnimation = tester.widget<AnimatedModalBarrier>(animatedModalBarrier).color;
|
modalBarrierAnimation = tester.widget<AnimatedModalBarrier>(animatedModalBarrier).color;
|
||||||
expect(
|
expect(
|
||||||
modalBarrierAnimation.value.alpha,
|
modalBarrierAnimation.value!.alpha,
|
||||||
closeTo(_getExpectedBarrierTweenAlphaValue(0.50), 1),
|
closeTo(_getExpectedBarrierTweenAlphaValue(0.50), 1),
|
||||||
);
|
);
|
||||||
|
|
||||||
await tester.pump(const Duration(milliseconds: 25));
|
await tester.pump(const Duration(milliseconds: 25));
|
||||||
modalBarrierAnimation = tester.widget<AnimatedModalBarrier>(animatedModalBarrier).color;
|
modalBarrierAnimation = tester.widget<AnimatedModalBarrier>(animatedModalBarrier).color;
|
||||||
expect(
|
expect(
|
||||||
modalBarrierAnimation.value.alpha,
|
modalBarrierAnimation.value!.alpha,
|
||||||
closeTo(_getExpectedBarrierTweenAlphaValue(0.75), 1),
|
closeTo(_getExpectedBarrierTweenAlphaValue(0.75), 1),
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1382,28 +1382,28 @@ void main() {
|
|||||||
final Finder animatedModalBarrier = find.byType(AnimatedModalBarrier);
|
final Finder animatedModalBarrier = find.byType(AnimatedModalBarrier);
|
||||||
expect(animatedModalBarrier, findsOneWidget);
|
expect(animatedModalBarrier, findsOneWidget);
|
||||||
|
|
||||||
Animation<Color> modalBarrierAnimation;
|
Animation<Color?> modalBarrierAnimation;
|
||||||
modalBarrierAnimation = tester.widget<AnimatedModalBarrier>(animatedModalBarrier).color;
|
modalBarrierAnimation = tester.widget<AnimatedModalBarrier>(animatedModalBarrier).color;
|
||||||
expect(modalBarrierAnimation.value, Colors.transparent);
|
expect(modalBarrierAnimation.value, Colors.transparent);
|
||||||
|
|
||||||
await tester.pump(const Duration(milliseconds: 25));
|
await tester.pump(const Duration(milliseconds: 25));
|
||||||
modalBarrierAnimation = tester.widget<AnimatedModalBarrier>(animatedModalBarrier).color;
|
modalBarrierAnimation = tester.widget<AnimatedModalBarrier>(animatedModalBarrier).color;
|
||||||
expect(
|
expect(
|
||||||
modalBarrierAnimation.value.alpha,
|
modalBarrierAnimation.value!.alpha,
|
||||||
closeTo(_getExpectedBarrierTweenAlphaValue(0.25), 1),
|
closeTo(_getExpectedBarrierTweenAlphaValue(0.25), 1),
|
||||||
);
|
);
|
||||||
|
|
||||||
await tester.pump(const Duration(milliseconds: 25));
|
await tester.pump(const Duration(milliseconds: 25));
|
||||||
modalBarrierAnimation = tester.widget<AnimatedModalBarrier>(animatedModalBarrier).color;
|
modalBarrierAnimation = tester.widget<AnimatedModalBarrier>(animatedModalBarrier).color;
|
||||||
expect(
|
expect(
|
||||||
modalBarrierAnimation.value.alpha,
|
modalBarrierAnimation.value!.alpha,
|
||||||
closeTo(_getExpectedBarrierTweenAlphaValue(0.50), 1),
|
closeTo(_getExpectedBarrierTweenAlphaValue(0.50), 1),
|
||||||
);
|
);
|
||||||
|
|
||||||
await tester.pump(const Duration(milliseconds: 25));
|
await tester.pump(const Duration(milliseconds: 25));
|
||||||
modalBarrierAnimation = tester.widget<AnimatedModalBarrier>(animatedModalBarrier).color;
|
modalBarrierAnimation = tester.widget<AnimatedModalBarrier>(animatedModalBarrier).color;
|
||||||
expect(
|
expect(
|
||||||
modalBarrierAnimation.value.alpha,
|
modalBarrierAnimation.value!.alpha,
|
||||||
closeTo(_getExpectedBarrierTweenAlphaValue(0.75), 1),
|
closeTo(_getExpectedBarrierTweenAlphaValue(0.75), 1),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -49,27 +49,31 @@ class MatchesGoldenFile extends AsyncMatcher {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<String?> matchAsync(dynamic item) async {
|
Future<String?> matchAsync(dynamic item) async {
|
||||||
Future<ui.Image> imageFuture;
|
Future<ui.Image?> imageFuture;
|
||||||
if (item is Future<ui.Image>) {
|
if (item is Future<ui.Image?>) {
|
||||||
imageFuture = item;
|
imageFuture = item;
|
||||||
} else if (item is ui.Image) {
|
} else if (item is ui.Image) {
|
||||||
imageFuture = Future<ui.Image>.value(item);
|
imageFuture = Future<ui.Image>.value(item);
|
||||||
} else {
|
} else if (item is Finder) {
|
||||||
final Finder finder = item as Finder;
|
final Iterable<Element> elements = item.evaluate();
|
||||||
final Iterable<Element> elements = finder.evaluate();
|
|
||||||
if (elements.isEmpty) {
|
if (elements.isEmpty) {
|
||||||
return 'could not be rendered because no widget was found';
|
return 'could not be rendered because no widget was found';
|
||||||
} else if (elements.length > 1) {
|
} else if (elements.length > 1) {
|
||||||
return 'matched too many widgets';
|
return 'matched too many widgets';
|
||||||
}
|
}
|
||||||
imageFuture = captureImage(elements.single);
|
imageFuture = captureImage(elements.single);
|
||||||
|
} else {
|
||||||
|
throw 'must provide a Finder, Image, or Future<Image>';
|
||||||
}
|
}
|
||||||
|
|
||||||
final Uri testNameUri = goldenFileComparator.getTestUri(key, version);
|
final Uri testNameUri = goldenFileComparator.getTestUri(key, version);
|
||||||
|
|
||||||
final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized() as TestWidgetsFlutterBinding;
|
final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized() as TestWidgetsFlutterBinding;
|
||||||
return binding.runAsync<String?>(() async {
|
return binding.runAsync<String?>(() async {
|
||||||
final ui.Image image = await imageFuture;
|
final ui.Image? image = await imageFuture;
|
||||||
|
if (image == null) {
|
||||||
|
throw 'Future<Image> completed to null';
|
||||||
|
}
|
||||||
final ByteData? bytes = await image.toByteData(format: ui.ImageByteFormat.png);
|
final ByteData? bytes = await image.toByteData(format: ui.ImageByteFormat.png);
|
||||||
if (bytes == null)
|
if (bytes == null)
|
||||||
return 'could not encode screenshot.';
|
return 'could not encode screenshot.';
|
||||||
|
@ -1011,17 +1011,19 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
|
|||||||
|
|
||||||
addTime(additionalTime);
|
addTime(additionalTime);
|
||||||
|
|
||||||
return realAsyncZone.run<Future<T>>(() {
|
return realAsyncZone.run<Future<T?>>(() async {
|
||||||
_pendingAsyncTasks = Completer<void>();
|
_pendingAsyncTasks = Completer<void>();
|
||||||
return callback().catchError((Object exception, StackTrace stack) {
|
T? result;
|
||||||
|
try {
|
||||||
|
result = await callback();
|
||||||
|
} catch (exception, stack) {
|
||||||
FlutterError.reportError(FlutterErrorDetails(
|
FlutterError.reportError(FlutterErrorDetails(
|
||||||
exception: exception,
|
exception: exception,
|
||||||
stack: stack,
|
stack: stack,
|
||||||
library: 'Flutter test framework',
|
library: 'Flutter test framework',
|
||||||
context: ErrorDescription('while running async test code'),
|
context: ErrorDescription('while running async test code'),
|
||||||
));
|
));
|
||||||
return null;
|
} finally {
|
||||||
}).whenComplete(() {
|
|
||||||
// We complete the _pendingAsyncTasks future successfully regardless of
|
// We complete the _pendingAsyncTasks future successfully regardless of
|
||||||
// whether an exception occurred because in the case of an exception,
|
// whether an exception occurred because in the case of an exception,
|
||||||
// we already reported the exception to FlutterError. Moreover,
|
// we already reported the exception to FlutterError. Moreover,
|
||||||
@ -1029,7 +1031,8 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
|
|||||||
// exception due to zone error boundaries.
|
// exception due to zone error boundaries.
|
||||||
_pendingAsyncTasks!.complete();
|
_pendingAsyncTasks!.complete();
|
||||||
_pendingAsyncTasks = null;
|
_pendingAsyncTasks = null;
|
||||||
});
|
}
|
||||||
|
return result;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ void testConfig(
|
|||||||
String? expectedStringValue, {
|
String? expectedStringValue, {
|
||||||
Map<Type, dynamic> otherExpectedValues = const <Type, dynamic>{int: isNull},
|
Map<Type, dynamic> otherExpectedValues = const <Type, dynamic>{int: isNull},
|
||||||
}) {
|
}) {
|
||||||
final String actualStringValue = Zone.current[String] as String;
|
final String? actualStringValue = Zone.current[String] as String?;
|
||||||
final Map<Type, dynamic> otherActualValues = otherExpectedValues.map<Type, dynamic>(
|
final Map<Type, dynamic> otherActualValues = otherExpectedValues.map<Type, dynamic>(
|
||||||
(Type key, dynamic value) {
|
(Type key, dynamic value) {
|
||||||
return MapEntry<Type, dynamic>(key, Zone.current[key]);
|
return MapEntry<Type, dynamic>(key, Zone.current[key]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user