Unverified Commit 1f426123 authored by Casey Hillers's avatar Casey Hillers Committed by GitHub

Revert PRs relating to single window assumption (#122369)

* Revert "Remove references to BindingBase.window (#122119)"

This reverts commit c7681f00.

* Revert "Remove another reference to BindingBase.window (#122341)"

This reverts commit 6ec44450.

* Revert "Reland (2): Removes single window assumptions from `flutter_test` (#122233)"

This reverts commit eb3d317e.

* Revert "Remove single view assumption from TestViewConfiguration (#122352)"

This reverts commit 927289fb.

* Revert "Updates `flutter/test/cupertino` to no longer use `TestWindow` (#122325)"

This reverts commit 67e17e45.

* Revert "Updates `flutter/test/gestures` to no longer reference `TestWindow` (#122327)"

This reverts commit c2a5111c.

* Revert "Updates `flutter/test/rendering` to no longer use `TestWindow` (#122347)"

This reverts commit 28b65e08.

* Revert "Updates `flutter_localizations/test` to stop using `TestWindow` (#122321)"

This reverts commit 01367d52.
parent ac550c63
...@@ -31,13 +31,13 @@ Future<void> main() async { ...@@ -31,13 +31,13 @@ Future<void> main() async {
await tester.pump(); // Start drawer animation await tester.pump(); // Start drawer animation
await tester.pump(const Duration(seconds: 1)); // Complete drawer animation await tester.pump(const Duration(seconds: 1)); // Complete drawer animation
final TestViewConfiguration big = TestViewConfiguration.fromView( final TestViewConfiguration big = TestViewConfiguration(
size: const Size(360.0, 640.0), size: const Size(360.0, 640.0),
view: tester.view, window: RendererBinding.instance.window,
); );
final TestViewConfiguration small = TestViewConfiguration.fromView( final TestViewConfiguration small = TestViewConfiguration(
size: const Size(355.0, 635.0), size: const Size(355.0, 635.0),
view: tester.view, window: RendererBinding.instance.window,
); );
final RenderView renderView = WidgetsBinding.instance.renderView; final RenderView renderView = WidgetsBinding.instance.renderView;
binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.benchmark; binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.benchmark;
......
...@@ -58,8 +58,8 @@ void main() { ...@@ -58,8 +58,8 @@ void main() {
expect(find.text('Account Balance'), findsNothing); expect(find.text('Account Balance'), findsNothing);
// drag the drawer out // drag the drawer out
final Offset left = Offset(0.0, (tester.view.physicalSize / tester.view.devicePixelRatio).height / 2.0); final Offset left = Offset(0.0, (WidgetsBinding.instance.window.physicalSize / WidgetsBinding.instance.window.devicePixelRatio).height / 2.0);
final Offset right = Offset((tester.view.physicalSize / tester.view.devicePixelRatio).width, left.dy); final Offset right = Offset((WidgetsBinding.instance.window.physicalSize / WidgetsBinding.instance.window.devicePixelRatio).width, left.dy);
final TestGesture gesture = await tester.startGesture(left); final TestGesture gesture = await tester.startGesture(left);
await tester.pump(); await tester.pump();
await gesture.moveTo(right); await gesture.moveTo(right);
......
...@@ -901,13 +901,15 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB ...@@ -901,13 +901,15 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
/// Used by [runApp] to wrap the provided `rootWidget` in the default [View]. /// Used by [runApp] to wrap the provided `rootWidget` in the default [View].
/// ///
/// The [View] determines into what [FlutterView] the app is rendered into. /// The [View] determines into what [FlutterView] the app is rendered into.
/// This is currently [PlatformDispatcher.implicitView] from [platformDispatcher]. /// For backwards-compatibility reasons, this method currently chooses
/// [window] (which is a [FlutterView]) as the rendering target. This will
/// change in a future version of Flutter.
/// ///
/// The `rootWidget` widget provided to this method must not already be /// The `rootWidget` widget provided to this method must not already be
/// wrapped in a [View]. /// wrapped in a [View].
Widget wrapWithDefaultView(Widget rootWidget) { Widget wrapWithDefaultView(Widget rootWidget) {
return View( return View(
view: platformDispatcher.implicitView!, view: window,
child: rootWidget, child: rootWidget,
); );
} }
......
...@@ -1702,7 +1702,6 @@ void main() { ...@@ -1702,7 +1702,6 @@ void main() {
]; ];
await tester.pumpWidget( await tester.pumpWidget(
buildNavigator( buildNavigator(
view: tester.view,
pages: myPages, pages: myPages,
onPopPage: (Route<dynamic> route, dynamic result) { onPopPage: (Route<dynamic> route, dynamic result) {
assert(false); // The test shouldn't call this. assert(false); // The test shouldn't call this.
...@@ -1729,7 +1728,6 @@ void main() { ...@@ -1729,7 +1728,6 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildNavigator( buildNavigator(
view: tester.view,
pages: myPages, pages: myPages,
onPopPage: (Route<dynamic> route, dynamic result) { onPopPage: (Route<dynamic> route, dynamic result) {
assert(false); // The test shouldn't call this. assert(false); // The test shouldn't call this.
...@@ -1758,7 +1756,6 @@ void main() { ...@@ -1758,7 +1756,6 @@ void main() {
]; ];
await tester.pumpWidget( await tester.pumpWidget(
buildNavigator( buildNavigator(
view: tester.view,
pages: myPages, pages: myPages,
onPopPage: (Route<dynamic> route, dynamic result) { onPopPage: (Route<dynamic> route, dynamic result) {
assert(false); // The test shouldn't call this. assert(false); // The test shouldn't call this.
...@@ -1780,7 +1777,6 @@ void main() { ...@@ -1780,7 +1777,6 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildNavigator( buildNavigator(
view: tester.view,
pages: myPages, pages: myPages,
onPopPage: (Route<dynamic> route, dynamic result) { onPopPage: (Route<dynamic> route, dynamic result) {
assert(false); // The test shouldn't call this. assert(false); // The test shouldn't call this.
...@@ -2217,13 +2213,12 @@ class TransitionDetector extends DefaultTransitionDelegate<void> { ...@@ -2217,13 +2213,12 @@ class TransitionDetector extends DefaultTransitionDelegate<void> {
Widget buildNavigator({ Widget buildNavigator({
required List<Page<dynamic>> pages, required List<Page<dynamic>> pages,
required FlutterView view,
PopPageCallback? onPopPage, PopPageCallback? onPopPage,
GlobalKey<NavigatorState>? key, GlobalKey<NavigatorState>? key,
TransitionDelegate<dynamic>? transitionDelegate, TransitionDelegate<dynamic>? transitionDelegate,
}) { }) {
return MediaQuery( return MediaQuery(
data: MediaQueryData.fromView(view), data: MediaQueryData.fromView(WidgetsBinding.instance.window),
child: Localizations( child: Localizations(
locale: const Locale('en', 'US'), locale: const Locale('en', 'US'),
delegates: const <LocalizationsDelegate<dynamic>>[ delegates: const <LocalizationsDelegate<dynamic>>[
......
...@@ -251,7 +251,7 @@ void main() { ...@@ -251,7 +251,7 @@ void main() {
const double inset = 3; const double inset = 3;
const double scaleFactor = 2; const double scaleFactor = 2;
final Size screenSize = tester.view.physicalSize / tester.view.devicePixelRatio; final Size screenSize = tester.binding.window.physicalSize / tester.binding.window.devicePixelRatio;
final ScrollController scrollController = ScrollController(); final ScrollController scrollController = ScrollController();
await tester.pumpWidget( await tester.pumpWidget(
......
...@@ -2,10 +2,15 @@ ...@@ -2,10 +2,15 @@
// 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.
// no-shuffle:
// //TODO(gspencergoog): Remove this tag once this test's state leaks/test
// dependencies have been fixed.
// https://github.com/flutter/flutter/issues/85160
// Fails with "flutter test --test-randomize-ordering-seed=456"
// reduced-test-set: // reduced-test-set:
// This file is run as part of a reduced test set in CI on Mac and Windows // This file is run as part of a reduced test set in CI on Mac and Windows
// machines. // machines.
@Tags(<String>['reduced-test-set']) @Tags(<String>['reduced-test-set', 'no-shuffle'])
library; library;
import 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle, Color; import 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle, Color;
...@@ -4998,11 +5003,9 @@ void main() { ...@@ -4998,11 +5003,9 @@ void main() {
group('Text selection toolbar', () { group('Text selection toolbar', () {
testWidgets('Collapsed selection works', (WidgetTester tester) async { testWidgets('Collapsed selection works', (WidgetTester tester) async {
tester.view.physicalSize = const Size(400, 400);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.reset);
EditableText.debugDeterministicCursor = true; EditableText.debugDeterministicCursor = true;
tester.binding.window.physicalSizeTestValue = const Size(400, 400);
tester.binding.window.devicePixelRatioTestValue = 1;
TextEditingController controller; TextEditingController controller;
EditableTextState state; EditableTextState state;
Offset bottomLeftSelectionPosition; Offset bottomLeftSelectionPosition;
...@@ -5180,14 +5183,15 @@ void main() { ...@@ -5180,14 +5183,15 @@ void main() {
), ),
), ),
); );
tester.binding.window.clearPhysicalSizeTestValue();
tester.binding.window.clearDevicePixelRatioTestValue();
}); });
testWidgets('selecting multiple words works', (WidgetTester tester) async { testWidgets('selecting multiple words works', (WidgetTester tester) async {
tester.view.physicalSize = const Size(400, 400);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.reset);
EditableText.debugDeterministicCursor = true; EditableText.debugDeterministicCursor = true;
tester.binding.window.physicalSizeTestValue = const Size(400, 400);
tester.binding.window.devicePixelRatioTestValue = 1;
final TextEditingController controller; final TextEditingController controller;
final EditableTextState state; final EditableTextState state;
...@@ -5249,14 +5253,15 @@ void main() { ...@@ -5249,14 +5253,15 @@ void main() {
), ),
), ),
); );
tester.binding.window.clearPhysicalSizeTestValue();
tester.binding.window.clearDevicePixelRatioTestValue();
}); });
testWidgets('selecting multiline works', (WidgetTester tester) async { testWidgets('selecting multiline works', (WidgetTester tester) async {
tester.view.physicalSize = const Size(400, 400);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.reset);
EditableText.debugDeterministicCursor = true; EditableText.debugDeterministicCursor = true;
tester.binding.window.physicalSizeTestValue = const Size(400, 400);
tester.binding.window.devicePixelRatioTestValue = 1;
final TextEditingController controller; final TextEditingController controller;
final EditableTextState state; final EditableTextState state;
...@@ -5322,6 +5327,9 @@ void main() { ...@@ -5322,6 +5327,9 @@ void main() {
), ),
), ),
); );
tester.binding.window.clearPhysicalSizeTestValue();
tester.binding.window.clearDevicePixelRatioTestValue();
}); });
// This is a regression test for // This is a regression test for
......
...@@ -246,8 +246,8 @@ void main() { ...@@ -246,8 +246,8 @@ void main() {
testWidgets("When a menu item doesn't fit, a second page is used.", (WidgetTester tester) async { testWidgets("When a menu item doesn't fit, a second page is used.", (WidgetTester tester) async {
// Set the screen size to more narrow, so that Paste can't fit. // Set the screen size to more narrow, so that Paste can't fit.
tester.view.physicalSize = const Size(800, 800); tester.binding.window.physicalSizeTestValue = const Size(800, 800);
addTearDown(tester.view.reset); addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
final TextEditingController controller = TextEditingController(text: 'abc def ghi'); final TextEditingController controller = TextEditingController(text: 'abc def ghi');
await tester.pumpWidget(CupertinoApp( await tester.pumpWidget(CupertinoApp(
...@@ -318,8 +318,8 @@ void main() { ...@@ -318,8 +318,8 @@ void main() {
testWidgets('A smaller menu puts each button on its own page.', (WidgetTester tester) async { testWidgets('A smaller menu puts each button on its own page.', (WidgetTester tester) async {
// Set the screen size to more narrow, so that two buttons can't fit on // Set the screen size to more narrow, so that two buttons can't fit on
// the same page. // the same page.
tester.view.physicalSize = const Size(640, 800); tester.binding.window.physicalSizeTestValue = const Size(640, 800);
addTearDown(tester.view.reset); addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
final TextEditingController controller = TextEditingController(text: 'abc def ghi'); final TextEditingController controller = TextEditingController(text: 'abc def ghi');
await tester.pumpWidget(CupertinoApp( await tester.pumpWidget(CupertinoApp(
......
...@@ -188,8 +188,8 @@ void main() { ...@@ -188,8 +188,8 @@ void main() {
testWidgets('does not paginate if children fit with zero margin', (WidgetTester tester) async { testWidgets('does not paginate if children fit with zero margin', (WidgetTester tester) async {
final List<Widget> children = List<Widget>.generate(7, (int i) => const TestBox()); final List<Widget> children = List<Widget>.generate(7, (int i) => const TestBox());
final double spacerWidth = 1.0 / tester.view.devicePixelRatio; final double spacerWidth = 1.0 / tester.binding.window.devicePixelRatio;
final double dividerWidth = 1.0 / tester.view.devicePixelRatio; final double dividerWidth = 1.0 / tester.binding.window.devicePixelRatio;
const double borderRadius = 8.0; // Should match _kToolbarBorderRadius const double borderRadius = 8.0; // Should match _kToolbarBorderRadius
final double width = 7 * TestBox.itemWidth + 6 * (dividerWidth + 2 * spacerWidth) + 2 * borderRadius; final double width = 7 * TestBox.itemWidth + 6 * (dividerWidth + 2 * spacerWidth) + 2 * borderRadius;
await tester.pumpWidget( await tester.pumpWidget(
......
...@@ -101,7 +101,7 @@ void main() { ...@@ -101,7 +101,7 @@ void main() {
expect(events.length, 1); expect(events.length, 1);
expect(events[0], isA<PointerDownEvent>()); expect(events[0], isA<PointerDownEvent>());
expect(events[0].timeStamp, currentTestFrameTime() + kSamplingOffset); expect(events[0].timeStamp, currentTestFrameTime() + kSamplingOffset);
expect(events[0].position, Offset(7.5 / tester.view.devicePixelRatio, 0.0)); expect(events[0].position, Offset(7.5 / GestureBinding.instance.window.devicePixelRatio, 0.0));
// Now the system time is epoch + 20ms // Now the system time is epoch + 20ms
requestFrame(); requestFrame();
...@@ -109,8 +109,8 @@ void main() { ...@@ -109,8 +109,8 @@ void main() {
expect(events.length, 2); expect(events.length, 2);
expect(events[1].timeStamp, currentTestFrameTime() + kSamplingOffset); expect(events[1].timeStamp, currentTestFrameTime() + kSamplingOffset);
expect(events[1], isA<PointerMoveEvent>()); expect(events[1], isA<PointerMoveEvent>());
expect(events[1].position, Offset(22.5 / tester.view.devicePixelRatio, 0.0)); expect(events[1].position, Offset(22.5 / GestureBinding.instance.window.devicePixelRatio, 0.0));
expect(events[1].delta, Offset(15.0 / tester.view.devicePixelRatio, 0.0)); expect(events[1].delta, Offset(15.0 / GestureBinding.instance.window.devicePixelRatio, 0.0));
// Now the system time is epoch + 30ms // Now the system time is epoch + 30ms
requestFrame(); requestFrame();
...@@ -118,8 +118,8 @@ void main() { ...@@ -118,8 +118,8 @@ void main() {
expect(events.length, 4); expect(events.length, 4);
expect(events[2].timeStamp, currentTestFrameTime() + kSamplingOffset); expect(events[2].timeStamp, currentTestFrameTime() + kSamplingOffset);
expect(events[2], isA<PointerMoveEvent>()); expect(events[2], isA<PointerMoveEvent>());
expect(events[2].position, Offset(37.5 / tester.view.devicePixelRatio, 0.0)); expect(events[2].position, Offset(37.5 / GestureBinding.instance.window.devicePixelRatio, 0.0));
expect(events[2].delta, Offset(15.0 / tester.view.devicePixelRatio, 0.0)); expect(events[2].delta, Offset(15.0 / GestureBinding.instance.window.devicePixelRatio, 0.0));
expect(events[3].timeStamp, currentTestFrameTime() + kSamplingOffset); expect(events[3].timeStamp, currentTestFrameTime() + kSamplingOffset);
expect(events[3], isA<PointerUpEvent>()); expect(events[3], isA<PointerUpEvent>());
}); });
......
...@@ -162,8 +162,6 @@ void main() { ...@@ -162,8 +162,6 @@ void main() {
expect(events[1], isA<PointerCancelEvent>()); expect(events[1], isA<PointerCancelEvent>());
}); });
const double devicePixelRatio = 2.5;
test('Can expand add and hover pointers', () { test('Can expand add and hover pointers', () {
const ui.PointerDataPacket packet = ui.PointerDataPacket( const ui.PointerDataPacket packet = ui.PointerDataPacket(
data: <ui.PointerData>[ data: <ui.PointerData>[
...@@ -175,7 +173,7 @@ void main() { ...@@ -175,7 +173,7 @@ void main() {
], ],
); );
final List<PointerEvent> events = PointerEventConverter.expand(packet.data, devicePixelRatio).toList(); final List<PointerEvent> events = PointerEventConverter.expand(packet.data, GestureBinding.instance.window.devicePixelRatio).toList();
expect(events.length, 5); expect(events.length, 5);
expect(events[0], isA<PointerAddedEvent>()); expect(events[0], isA<PointerAddedEvent>());
...@@ -191,7 +189,7 @@ void main() { ...@@ -191,7 +189,7 @@ void main() {
ui.PointerData(change: ui.PointerChange.add, device: 24), ui.PointerData(change: ui.PointerChange.add, device: 24),
], ],
); );
List<PointerEvent> events = PointerEventConverter.expand(packet.data, devicePixelRatio).toList(); List<PointerEvent> events = PointerEventConverter.expand(packet.data, GestureBinding.instance.window.devicePixelRatio).toList();
expect(events.length, 1); expect(events.length, 1);
expect(events[0], isA<PointerAddedEvent>()); expect(events[0], isA<PointerAddedEvent>());
...@@ -207,7 +205,7 @@ void main() { ...@@ -207,7 +205,7 @@ void main() {
ui.PointerData(signalKind: ui.PointerSignalKind.scroll, device: 24, scrollDeltaY: double.negativeInfinity, scrollDeltaX: 10), ui.PointerData(signalKind: ui.PointerSignalKind.scroll, device: 24, scrollDeltaY: double.negativeInfinity, scrollDeltaX: 10),
], ],
); );
events = PointerEventConverter.expand(packet.data, devicePixelRatio).toList(); events = PointerEventConverter.expand(packet.data, GestureBinding.instance.window.devicePixelRatio).toList();
expect(events.length, 0); expect(events.length, 0);
// Send packet with a valid scroll event. // Send packet with a valid scroll event.
...@@ -217,7 +215,7 @@ void main() { ...@@ -217,7 +215,7 @@ void main() {
], ],
); );
// Make sure PointerEventConverter can expand when device pixel ratio is valid. // Make sure PointerEventConverter can expand when device pixel ratio is valid.
events = PointerEventConverter.expand(packet.data, devicePixelRatio).toList(); events = PointerEventConverter.expand(packet.data, GestureBinding.instance.window.devicePixelRatio).toList();
expect(events.length, 1); expect(events.length, 1);
expect(events[0], isA<PointerScrollEvent>()); expect(events[0], isA<PointerScrollEvent>());
...@@ -234,7 +232,7 @@ void main() { ...@@ -234,7 +232,7 @@ void main() {
], ],
); );
final List<PointerEvent> events = PointerEventConverter.expand(packet.data, devicePixelRatio).toList(); final List<PointerEvent> events = PointerEventConverter.expand(packet.data, GestureBinding.instance.window.devicePixelRatio).toList();
expect(events.length, 2); expect(events.length, 2);
expect(events[0], isA<PointerAddedEvent>()); expect(events[0], isA<PointerAddedEvent>());
...@@ -242,7 +240,7 @@ void main() { ...@@ -242,7 +240,7 @@ void main() {
}); });
test('Should synthesize kPrimaryButton for touch when no button is set', () { test('Should synthesize kPrimaryButton for touch when no button is set', () {
final Offset location = const Offset(10.0, 10.0) * devicePixelRatio; final Offset location = const Offset(10.0, 10.0) * GestureBinding.instance.window.devicePixelRatio;
final ui.PointerDataPacket packet = ui.PointerDataPacket( final ui.PointerDataPacket packet = ui.PointerDataPacket(
data: <ui.PointerData>[ data: <ui.PointerData>[
ui.PointerData(change: ui.PointerChange.add, physicalX: location.dx, physicalY: location.dy), ui.PointerData(change: ui.PointerChange.add, physicalX: location.dx, physicalY: location.dy),
...@@ -253,7 +251,7 @@ void main() { ...@@ -253,7 +251,7 @@ void main() {
], ],
); );
final List<PointerEvent> events = PointerEventConverter.expand(packet.data, devicePixelRatio).toList(); final List<PointerEvent> events = PointerEventConverter.expand(packet.data, GestureBinding.instance.window.devicePixelRatio).toList();
expect(events.length, 5); expect(events.length, 5);
expect(events[0], isA<PointerAddedEvent>()); expect(events[0], isA<PointerAddedEvent>());
...@@ -269,7 +267,7 @@ void main() { ...@@ -269,7 +267,7 @@ void main() {
}); });
test('Should not synthesize kPrimaryButton for touch when a button is set', () { test('Should not synthesize kPrimaryButton for touch when a button is set', () {
final Offset location = const Offset(10.0, 10.0) * devicePixelRatio; final Offset location = const Offset(10.0, 10.0) * GestureBinding.instance.window.devicePixelRatio;
final ui.PointerDataPacket packet = ui.PointerDataPacket( final ui.PointerDataPacket packet = ui.PointerDataPacket(
data: <ui.PointerData>[ data: <ui.PointerData>[
ui.PointerData(change: ui.PointerChange.add, physicalX: location.dx, physicalY: location.dy), ui.PointerData(change: ui.PointerChange.add, physicalX: location.dx, physicalY: location.dy),
...@@ -280,7 +278,7 @@ void main() { ...@@ -280,7 +278,7 @@ void main() {
], ],
); );
final List<PointerEvent> events = PointerEventConverter.expand(packet.data, devicePixelRatio).toList(); final List<PointerEvent> events = PointerEventConverter.expand(packet.data, GestureBinding.instance.window.devicePixelRatio).toList();
expect(events.length, 5); expect(events.length, 5);
expect(events[0], isA<PointerAddedEvent>()); expect(events[0], isA<PointerAddedEvent>());
...@@ -296,7 +294,7 @@ void main() { ...@@ -296,7 +294,7 @@ void main() {
}); });
test('Should synthesize kPrimaryButton for stylus when no button is set', () { test('Should synthesize kPrimaryButton for stylus when no button is set', () {
final Offset location = const Offset(10.0, 10.0) * devicePixelRatio; final Offset location = const Offset(10.0, 10.0) * GestureBinding.instance.window.devicePixelRatio;
for (final PointerDeviceKind kind in <PointerDeviceKind>[ for (final PointerDeviceKind kind in <PointerDeviceKind>[
PointerDeviceKind.stylus, PointerDeviceKind.stylus,
PointerDeviceKind.invertedStylus, PointerDeviceKind.invertedStylus,
...@@ -312,7 +310,7 @@ void main() { ...@@ -312,7 +310,7 @@ void main() {
], ],
); );
final List<PointerEvent> events = PointerEventConverter.expand(packet.data, devicePixelRatio).toList(); final List<PointerEvent> events = PointerEventConverter.expand(packet.data, GestureBinding.instance.window.devicePixelRatio).toList();
expect(events.length, 5); expect(events.length, 5);
expect(events[0], isA<PointerAddedEvent>()); expect(events[0], isA<PointerAddedEvent>());
...@@ -329,7 +327,7 @@ void main() { ...@@ -329,7 +327,7 @@ void main() {
}); });
test('Should synthesize kPrimaryButton for unknown devices when no button is set', () { test('Should synthesize kPrimaryButton for unknown devices when no button is set', () {
final Offset location = const Offset(10.0, 10.0) * devicePixelRatio; final Offset location = const Offset(10.0, 10.0) * GestureBinding.instance.window.devicePixelRatio;
const PointerDeviceKind kind = PointerDeviceKind.unknown; const PointerDeviceKind kind = PointerDeviceKind.unknown;
final ui.PointerDataPacket packet = ui.PointerDataPacket( final ui.PointerDataPacket packet = ui.PointerDataPacket(
data: <ui.PointerData>[ data: <ui.PointerData>[
...@@ -341,7 +339,7 @@ void main() { ...@@ -341,7 +339,7 @@ void main() {
], ],
); );
final List<PointerEvent> events = PointerEventConverter.expand(packet.data, devicePixelRatio).toList(); final List<PointerEvent> events = PointerEventConverter.expand(packet.data, GestureBinding.instance.window.devicePixelRatio).toList();
expect(events.length, 5); expect(events.length, 5);
expect(events[0], isA<PointerAddedEvent>()); expect(events[0], isA<PointerAddedEvent>());
...@@ -357,7 +355,7 @@ void main() { ...@@ -357,7 +355,7 @@ void main() {
}); });
test('Should not synthesize kPrimaryButton for mouse', () { test('Should not synthesize kPrimaryButton for mouse', () {
final Offset location = const Offset(10.0, 10.0) * devicePixelRatio; final Offset location = const Offset(10.0, 10.0) * GestureBinding.instance.window.devicePixelRatio;
for (final PointerDeviceKind kind in <PointerDeviceKind>[ for (final PointerDeviceKind kind in <PointerDeviceKind>[
PointerDeviceKind.mouse, PointerDeviceKind.mouse,
]) { ]) {
...@@ -371,7 +369,7 @@ void main() { ...@@ -371,7 +369,7 @@ void main() {
], ],
); );
final List<PointerEvent> events = PointerEventConverter.expand(packet.data, devicePixelRatio).toList(); final List<PointerEvent> events = PointerEventConverter.expand(packet.data, GestureBinding.instance.window.devicePixelRatio).toList();
expect(events.length, 5); expect(events.length, 5);
expect(events[0], isA<PointerAddedEvent>()); expect(events[0], isA<PointerAddedEvent>());
......
...@@ -90,9 +90,7 @@ class NestedDraggableCase extends StatelessWidget { ...@@ -90,9 +90,7 @@ class NestedDraggableCase extends StatelessWidget {
void main() { void main() {
testWidgets('Scroll Views get the same ScrollConfiguration as GestureDetectors', (WidgetTester tester) async { testWidgets('Scroll Views get the same ScrollConfiguration as GestureDetectors', (WidgetTester tester) async {
tester.view.gestureSettings = const ui.GestureSettings(physicalTouchSlop: 4); tester.binding.window.gestureSettingsTestValue = const ui.GestureSettings(physicalTouchSlop: 4);
addTearDown(tester.view.reset);
final TestResult result = TestResult(); final TestResult result = TestResult();
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
...@@ -110,11 +108,11 @@ void main() { ...@@ -110,11 +108,11 @@ void main() {
expect(result.dragStarted, true); expect(result.dragStarted, true);
expect(result.dragUpdate, true); expect(result.dragUpdate, true);
tester.binding.window.clearGestureSettingsTestValue();
}); });
testWidgets('Scroll Views get the same ScrollConfiguration as Draggables', (WidgetTester tester) async { testWidgets('Scroll Views get the same ScrollConfiguration as Draggables', (WidgetTester tester) async {
tester.view.gestureSettings = const ui.GestureSettings(physicalTouchSlop: 4); tester.binding.window.gestureSettingsTestValue = const ui.GestureSettings(physicalTouchSlop: 4);
addTearDown(tester.view.reset);
final TestResult result = TestResult(); final TestResult result = TestResult();
...@@ -133,5 +131,6 @@ void main() { ...@@ -133,5 +131,6 @@ void main() {
expect(result.dragStarted, true); expect(result.dragStarted, true);
expect(result.dragUpdate, true); expect(result.dragUpdate, true);
tester.binding.window.clearGestureSettingsTestValue();
}); });
} }
...@@ -235,7 +235,7 @@ void main() { ...@@ -235,7 +235,7 @@ void main() {
' MediaQuery\n' ' MediaQuery\n'
' _MediaQueryFromView\n' ' _MediaQueryFromView\n'
' _ViewScope\n' ' _ViewScope\n'
' View-[GlobalObjectKey TestFlutterView#00000]\n' ' View-[GlobalObjectKey TestWindow#00000]\n'
' [root]\n' ' [root]\n'
' Typically, the Scaffold widget is introduced by the MaterialApp\n' ' Typically, the Scaffold widget is introduced by the MaterialApp\n'
' or WidgetsApp widget at the top of your application widget tree.\n' ' or WidgetsApp widget at the top of your application widget tree.\n'
...@@ -376,7 +376,7 @@ void main() { ...@@ -376,7 +376,7 @@ void main() {
' MediaQuery\n' ' MediaQuery\n'
' _MediaQueryFromView\n' ' _MediaQueryFromView\n'
' _ViewScope\n' ' _ViewScope\n'
' View-[GlobalObjectKey TestFlutterView#00000]\n' ' View-[GlobalObjectKey TestWindow#00000]\n'
' [root]\n' ' [root]\n'
' Typically, the ScaffoldMessenger widget is introduced by the\n' ' Typically, the ScaffoldMessenger widget is introduced by the\n'
' MaterialApp at the top of your application widget tree.\n' ' MaterialApp at the top of your application widget tree.\n'
......
...@@ -1042,7 +1042,6 @@ void main() { ...@@ -1042,7 +1042,6 @@ void main() {
]; ];
await tester.pumpWidget( await tester.pumpWidget(
buildNavigator( buildNavigator(
view: tester.view,
pages: myPages, pages: myPages,
onPopPage: (Route<dynamic> route, dynamic result) { onPopPage: (Route<dynamic> route, dynamic result) {
assert(false); // The test should never execute this. assert(false); // The test should never execute this.
...@@ -1061,7 +1060,6 @@ void main() { ...@@ -1061,7 +1060,6 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildNavigator( buildNavigator(
view: tester.view,
pages: myPages, pages: myPages,
onPopPage: (Route<dynamic> route, dynamic result) { onPopPage: (Route<dynamic> route, dynamic result) {
assert(false); // The test should never execute this. assert(false); // The test should never execute this.
...@@ -1087,7 +1085,6 @@ void main() { ...@@ -1087,7 +1085,6 @@ void main() {
]; ];
await tester.pumpWidget( await tester.pumpWidget(
buildNavigator( buildNavigator(
view: tester.view,
pages: myPages, pages: myPages,
onPopPage: (Route<dynamic> route, dynamic result) { onPopPage: (Route<dynamic> route, dynamic result) {
assert(false); // The test should never execute this. assert(false); // The test should never execute this.
...@@ -1109,7 +1106,6 @@ void main() { ...@@ -1109,7 +1106,6 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
buildNavigator( buildNavigator(
view: tester.view,
pages: myPages, pages: myPages,
onPopPage: (Route<dynamic> route, dynamic result) { onPopPage: (Route<dynamic> route, dynamic result) {
assert(false); // The test should never execute this. assert(false); // The test should never execute this.
...@@ -1218,12 +1214,11 @@ class TransitionDetector extends DefaultTransitionDelegate<void> { ...@@ -1218,12 +1214,11 @@ class TransitionDetector extends DefaultTransitionDelegate<void> {
Widget buildNavigator({ Widget buildNavigator({
required List<Page<dynamic>> pages, required List<Page<dynamic>> pages,
required PopPageCallback onPopPage, required PopPageCallback onPopPage,
required ui.FlutterView view,
GlobalKey<NavigatorState>? key, GlobalKey<NavigatorState>? key,
TransitionDelegate<dynamic>? transitionDelegate, TransitionDelegate<dynamic>? transitionDelegate,
}) { }) {
return MediaQuery( return MediaQuery(
data: MediaQueryData.fromView(view), data: MediaQueryData.fromView(WidgetsBinding.instance.window),
child: Localizations( child: Localizations(
locale: const Locale('en', 'US'), locale: const Locale('en', 'US'),
delegates: const <LocalizationsDelegate<dynamic>>[ delegates: const <LocalizationsDelegate<dynamic>>[
......
...@@ -2454,7 +2454,7 @@ void main() { ...@@ -2454,7 +2454,7 @@ void main() {
' MediaQuery\n' ' MediaQuery\n'
' _MediaQueryFromView\n' ' _MediaQueryFromView\n'
' _ViewScope\n' ' _ViewScope\n'
' View-[GlobalObjectKey TestFlutterView#e6136]\n' ' View-[GlobalObjectKey TestWindow#e6136]\n'
' [root]\n' ' [root]\n'
' Typically, the ScaffoldMessenger widget is introduced by the\n' ' Typically, the ScaffoldMessenger widget is introduced by the\n'
' MaterialApp at the top of your application widget tree.\n', ' MaterialApp at the top of your application widget tree.\n',
......
...@@ -52,7 +52,7 @@ void main() { ...@@ -52,7 +52,7 @@ void main() {
test('debugInvertOversizedImages', () async { test('debugInvertOversizedImages', () async {
debugInvertOversizedImages = true; debugInvertOversizedImages = true;
expect(PaintingBinding.instance.platformDispatcher.views.any((ui. FlutterView view) => view.devicePixelRatio > 1.0), isTrue); expect(PaintingBinding.instance.window.devicePixelRatio != 1.0, true);
final FlutterExceptionHandler? oldFlutterError = FlutterError.onError; final FlutterExceptionHandler? oldFlutterError = FlutterError.onError;
final List<String> messages = <String>[]; final List<String> messages = <String>[];
...@@ -180,7 +180,7 @@ void main() { ...@@ -180,7 +180,7 @@ void main() {
expect(imageSizeInfo, isNotNull); expect(imageSizeInfo, isNotNull);
expect(imageSizeInfo.source, 'test.png'); expect(imageSizeInfo.source, 'test.png');
expect(imageSizeInfo.imageSize, const Size(300, 300)); expect(imageSizeInfo.imageSize, const Size(300, 300));
expect(imageSizeInfo.displaySize, const Size(200, 100) * tester.view.devicePixelRatio); expect(imageSizeInfo.displaySize, const Size(200, 100) * PaintingBinding.instance.window.devicePixelRatio);
// Make sure that we don't report an identical image size info if we // Make sure that we don't report an identical image size info if we
// redraw in the next frame. // redraw in the next frame.
...@@ -219,7 +219,7 @@ void main() { ...@@ -219,7 +219,7 @@ void main() {
expect(imageSizeInfo, isNotNull); expect(imageSizeInfo, isNotNull);
expect(imageSizeInfo.source, 'test.png'); expect(imageSizeInfo.source, 'test.png');
expect(imageSizeInfo.imageSize, const Size(300, 300)); expect(imageSizeInfo.imageSize, const Size(300, 300));
expect(imageSizeInfo.displaySize, const Size(200, 100) * tester.view.devicePixelRatio); expect(imageSizeInfo.displaySize, const Size(200, 100) * PaintingBinding.instance.window.devicePixelRatio);
// Make sure that we don't report an identical image size info if we // Make sure that we don't report an identical image size info if we
// redraw in the next frame. // redraw in the next frame.
...@@ -237,7 +237,7 @@ void main() { ...@@ -237,7 +237,7 @@ void main() {
expect(imageSizeInfo, isNotNull); expect(imageSizeInfo, isNotNull);
expect(imageSizeInfo.source, 'test.png'); expect(imageSizeInfo.source, 'test.png');
expect(imageSizeInfo.imageSize, const Size(300, 300)); expect(imageSizeInfo.imageSize, const Size(300, 300));
expect(imageSizeInfo.displaySize, const Size(200, 150) * tester.view.devicePixelRatio); expect(imageSizeInfo.displaySize, const Size(200, 150) * PaintingBinding.instance.window.devicePixelRatio);
debugOnPaintImage = null; debugOnPaintImage = null;
}); });
...@@ -261,7 +261,7 @@ void main() { ...@@ -261,7 +261,7 @@ void main() {
expect(imageSizeInfo, isNotNull); expect(imageSizeInfo, isNotNull);
expect(imageSizeInfo.source, '<Unknown Image(300×200)>'); expect(imageSizeInfo.source, '<Unknown Image(300×200)>');
expect(imageSizeInfo.imageSize, const Size(300, 200)); expect(imageSizeInfo.imageSize, const Size(300, 200));
expect(imageSizeInfo.displaySize, const Size(200, 100) * tester.view.devicePixelRatio); expect(imageSizeInfo.displaySize, const Size(200, 100) * PaintingBinding.instance.window.devicePixelRatio);
debugOnPaintImage = null; debugOnPaintImage = null;
}); });
......
...@@ -44,7 +44,7 @@ void main() { ...@@ -44,7 +44,7 @@ void main() {
expect(offscreen.child.hasSize, isFalse); expect(offscreen.child.hasSize, isFalse);
expect(offscreen.painted, isFalse); expect(offscreen.painted, isFalse);
// Attach the offscreen to a custom render view and owner // Attach the offscreen to a custom render view and owner
final RenderView renderView = RenderView(configuration: testConfiguration, window: RendererBinding.instance.platformDispatcher.views.single); final RenderView renderView = RenderView(configuration: testConfiguration, window: RendererBinding.instance.window);
final PipelineOwner pipelineOwner = PipelineOwner(); final PipelineOwner pipelineOwner = PipelineOwner();
renderView.attach(pipelineOwner); renderView.attach(pipelineOwner);
renderView.child = offscreen.root; renderView.child = offscreen.root;
...@@ -66,7 +66,6 @@ void main() { ...@@ -66,7 +66,6 @@ void main() {
pipelineOwner.flushPaint(); pipelineOwner.flushPaint();
expect(offscreen.painted, isTrue); expect(offscreen.painted, isTrue);
}); });
test('offscreen layout does not affect onscreen', () { test('offscreen layout does not affect onscreen', () {
final TestLayout onscreen = TestLayout(); final TestLayout onscreen = TestLayout();
final TestLayout offscreen = TestLayout(); final TestLayout offscreen = TestLayout();
...@@ -75,7 +74,7 @@ void main() { ...@@ -75,7 +74,7 @@ void main() {
expect(offscreen.child.hasSize, isFalse); expect(offscreen.child.hasSize, isFalse);
expect(offscreen.painted, isFalse); expect(offscreen.painted, isFalse);
// Attach the offscreen to a custom render view and owner // Attach the offscreen to a custom render view and owner
final RenderView renderView = RenderView(configuration: testConfiguration, window: RendererBinding.instance.platformDispatcher.views.single); final RenderView renderView = RenderView(configuration: testConfiguration, window: RendererBinding.instance.window);
final PipelineOwner pipelineOwner = PipelineOwner(); final PipelineOwner pipelineOwner = PipelineOwner();
renderView.attach(pipelineOwner); renderView.attach(pipelineOwner);
renderView.child = offscreen.root; renderView.child = offscreen.root;
......
...@@ -169,7 +169,7 @@ void main() { ...@@ -169,7 +169,7 @@ void main() {
test('switching layer link of an attached leader layer should not crash', () { test('switching layer link of an attached leader layer should not crash', () {
final LayerLink link = LayerLink(); final LayerLink link = LayerLink();
final LeaderLayer leaderLayer = LeaderLayer(link: link); final LeaderLayer leaderLayer = LeaderLayer(link: link);
final RenderView view = RenderView(configuration: const ViewConfiguration(), window: RendererBinding.instance.platformDispatcher.views.single); final RenderView view = RenderView(configuration: const ViewConfiguration(), window: RendererBinding.instance.window);
leaderLayer.attach(view); leaderLayer.attach(view);
final LayerLink link2 = LayerLink(); final LayerLink link2 = LayerLink();
leaderLayer.link = link2; leaderLayer.link = link2;
...@@ -182,7 +182,7 @@ void main() { ...@@ -182,7 +182,7 @@ void main() {
final LayerLink link = LayerLink(); final LayerLink link = LayerLink();
final LeaderLayer leaderLayer1 = LeaderLayer(link: link); final LeaderLayer leaderLayer1 = LeaderLayer(link: link);
final LeaderLayer leaderLayer2 = LeaderLayer(link: link); final LeaderLayer leaderLayer2 = LeaderLayer(link: link);
final RenderView view = RenderView(configuration: const ViewConfiguration(), window: RendererBinding.instance.platformDispatcher.views.single); final RenderView view = RenderView(configuration: const ViewConfiguration(), window: RendererBinding.instance.window);
leaderLayer1.attach(view); leaderLayer1.attach(view);
leaderLayer2.attach(view); leaderLayer2.attach(view);
leaderLayer2.detach(); leaderLayer2.detach();
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:ui';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
...@@ -14,18 +16,18 @@ void main() { ...@@ -14,18 +16,18 @@ void main() {
const double deviceWidth = 480.0; const double deviceWidth = 480.0;
const double devicePixelRatio = 2.0; const double devicePixelRatio = 2.0;
void setupTestDevice(WidgetTester tester) { void setupTestDevice() {
final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized();
const FakeViewPadding padding = FakeViewPadding( const FakeViewPadding padding = FakeViewPadding(
top: statusBarHeight * devicePixelRatio, top: statusBarHeight * devicePixelRatio,
bottom: navigationBarHeight * devicePixelRatio, bottom: navigationBarHeight * devicePixelRatio,
); );
addTearDown(tester.view.reset); binding.window
tester.view ..viewPaddingTestValue = padding
..viewPadding = padding ..paddingTestValue = padding
..padding = padding ..devicePixelRatioTestValue = devicePixelRatio
..devicePixelRatio = devicePixelRatio ..physicalSizeTestValue = const Size(
..physicalSize = const Size(
deviceWidth * devicePixelRatio, deviceWidth * devicePixelRatio,
deviceHeight * devicePixelRatio, deviceHeight * devicePixelRatio,
); );
...@@ -50,7 +52,7 @@ void main() { ...@@ -50,7 +52,7 @@ void main() {
testWidgets( testWidgets(
'statusBarColor is set for annotated view', 'statusBarColor is set for annotated view',
(WidgetTester tester) async { (WidgetTester tester) async {
setupTestDevice(tester); setupTestDevice();
await tester.pumpWidget(const AnnotatedRegion<SystemUiOverlayStyle>( await tester.pumpWidget(const AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle( value: SystemUiOverlayStyle(
statusBarColor: Colors.blue, statusBarColor: Colors.blue,
...@@ -70,7 +72,7 @@ void main() { ...@@ -70,7 +72,7 @@ void main() {
testWidgets( testWidgets(
"statusBarColor isn't set when view covers less than half of the system status bar", "statusBarColor isn't set when view covers less than half of the system status bar",
(WidgetTester tester) async { (WidgetTester tester) async {
setupTestDevice(tester); setupTestDevice();
const double lessThanHalfOfTheStatusBarHeight = const double lessThanHalfOfTheStatusBarHeight =
statusBarHeight / 2.0 - 1; statusBarHeight / 2.0 - 1;
await tester.pumpWidget(const Align( await tester.pumpWidget(const Align(
...@@ -95,7 +97,7 @@ void main() { ...@@ -95,7 +97,7 @@ void main() {
testWidgets( testWidgets(
'statusBarColor is set when view covers more than half of tye system status bar', 'statusBarColor is set when view covers more than half of tye system status bar',
(WidgetTester tester) async { (WidgetTester tester) async {
setupTestDevice(tester); setupTestDevice();
const double moreThanHalfOfTheStatusBarHeight = const double moreThanHalfOfTheStatusBarHeight =
statusBarHeight / 2.0 + 1; statusBarHeight / 2.0 + 1;
await tester.pumpWidget(const Align( await tester.pumpWidget(const Align(
...@@ -125,7 +127,7 @@ void main() { ...@@ -125,7 +127,7 @@ void main() {
testWidgets( testWidgets(
"systemNavigationBarColor isn't set for non Android device", "systemNavigationBarColor isn't set for non Android device",
(WidgetTester tester) async { (WidgetTester tester) async {
setupTestDevice(tester); setupTestDevice();
await tester.pumpWidget(const AnnotatedRegion<SystemUiOverlayStyle>( await tester.pumpWidget(const AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle( value: SystemUiOverlayStyle(
systemNavigationBarColor: Colors.blue, systemNavigationBarColor: Colors.blue,
...@@ -156,7 +158,7 @@ void main() { ...@@ -156,7 +158,7 @@ void main() {
testWidgets( testWidgets(
'systemNavigationBarColor is set for annotated view', 'systemNavigationBarColor is set for annotated view',
(WidgetTester tester) async { (WidgetTester tester) async {
setupTestDevice(tester); setupTestDevice();
await tester.pumpWidget(const AnnotatedRegion<SystemUiOverlayStyle>( await tester.pumpWidget(const AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle( value: SystemUiOverlayStyle(
systemNavigationBarColor: Colors.blue, systemNavigationBarColor: Colors.blue,
...@@ -176,7 +178,7 @@ void main() { ...@@ -176,7 +178,7 @@ void main() {
testWidgets( testWidgets(
"systemNavigationBarColor isn't set when view covers less than half of navigation bar", "systemNavigationBarColor isn't set when view covers less than half of navigation bar",
(WidgetTester tester) async { (WidgetTester tester) async {
setupTestDevice(tester); setupTestDevice();
const double lessThanHalfOfTheNavigationBarHeight = const double lessThanHalfOfTheNavigationBarHeight =
navigationBarHeight / 2.0 - 1; navigationBarHeight / 2.0 - 1;
await tester.pumpWidget(const Align( await tester.pumpWidget(const Align(
...@@ -201,7 +203,7 @@ void main() { ...@@ -201,7 +203,7 @@ void main() {
testWidgets( testWidgets(
'systemNavigationBarColor is set when view covers more than half of navigation bar', 'systemNavigationBarColor is set when view covers more than half of navigation bar',
(WidgetTester tester) async { (WidgetTester tester) async {
setupTestDevice(tester); setupTestDevice();
const double moreThanHalfOfTheNavigationBarHeight = const double moreThanHalfOfTheNavigationBarHeight =
navigationBarHeight / 2.0 + 1; navigationBarHeight / 2.0 + 1;
await tester.pumpWidget(const Align( await tester.pumpWidget(const Align(
...@@ -228,7 +230,7 @@ void main() { ...@@ -228,7 +230,7 @@ void main() {
}); });
testWidgets('Top AnnotatedRegion provides status bar overlay style and bottom AnnotatedRegion provides navigation bar overlay style', (WidgetTester tester) async { testWidgets('Top AnnotatedRegion provides status bar overlay style and bottom AnnotatedRegion provides navigation bar overlay style', (WidgetTester tester) async {
setupTestDevice(tester); setupTestDevice();
await tester.pumpWidget( await tester.pumpWidget(
const Column(children: <Widget>[ const Column(children: <Widget>[
Expanded(child: AnnotatedRegion<SystemUiOverlayStyle>( Expanded(child: AnnotatedRegion<SystemUiOverlayStyle>(
...@@ -254,7 +256,7 @@ void main() { ...@@ -254,7 +256,7 @@ void main() {
}, variant: TargetPlatformVariant.only(TargetPlatform.android)); }, variant: TargetPlatformVariant.only(TargetPlatform.android));
testWidgets('Top only AnnotatedRegion provides status bar and navigation bar style properties', (WidgetTester tester) async { testWidgets('Top only AnnotatedRegion provides status bar and navigation bar style properties', (WidgetTester tester) async {
setupTestDevice(tester); setupTestDevice();
await tester.pumpWidget( await tester.pumpWidget(
const Column(children: <Widget>[ const Column(children: <Widget>[
Expanded(child: AnnotatedRegion<SystemUiOverlayStyle>( Expanded(child: AnnotatedRegion<SystemUiOverlayStyle>(
...@@ -274,7 +276,7 @@ void main() { ...@@ -274,7 +276,7 @@ void main() {
}, variant: TargetPlatformVariant.only(TargetPlatform.android)); }, variant: TargetPlatformVariant.only(TargetPlatform.android));
testWidgets('Bottom only AnnotatedRegion provides status bar and navigation bar style properties', (WidgetTester tester) async { testWidgets('Bottom only AnnotatedRegion provides status bar and navigation bar style properties', (WidgetTester tester) async {
setupTestDevice(tester); setupTestDevice();
await tester.pumpWidget( await tester.pumpWidget(
const Column(children: <Widget>[ const Column(children: <Widget>[
Expanded(child: SizedBox.expand()), Expanded(child: SizedBox.expand()),
...@@ -294,3 +296,21 @@ void main() { ...@@ -294,3 +296,21 @@ void main() {
}, variant: TargetPlatformVariant.only(TargetPlatform.android)); }, variant: TargetPlatformVariant.only(TargetPlatform.android));
}); });
} }
class FakeViewPadding implements ViewPadding {
const FakeViewPadding({
this.left = 0.0,
this.top = 0.0,
this.right = 0.0,
this.bottom = 0.0,
});
@override
final double left;
@override
final double top;
@override
final double right;
@override
final double bottom;
}
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:ui' as ui;
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
...@@ -30,9 +32,10 @@ void main() { ...@@ -30,9 +32,10 @@ void main() {
}); });
test('does not replace the root layer unnecessarily', () { test('does not replace the root layer unnecessarily', () {
final ui.FlutterView window = TestWindow(window: RendererBinding.instance.window);
final RenderView view = RenderView( final RenderView view = RenderView(
configuration: createViewConfiguration(), configuration: createViewConfiguration(),
window: RendererBinding.instance.platformDispatcher.views.single, window: window,
); );
final PipelineOwner owner = PipelineOwner(); final PipelineOwner owner = PipelineOwner();
view.attach(owner); view.attach(owner);
...@@ -45,10 +48,11 @@ void main() { ...@@ -45,10 +48,11 @@ void main() {
expect(identical(view.debugLayer, firstLayer), false); expect(identical(view.debugLayer, firstLayer), false);
}); });
test('does not replace the root layer unnecessarily when view resizes', () { test('does not replace the root layer unnecessarily when window resize', () {
final ui.FlutterView window = TestWindow(window: RendererBinding.instance.window);
final RenderView view = RenderView( final RenderView view = RenderView(
configuration: createViewConfiguration(size: const Size(100.0, 100.0)), configuration: createViewConfiguration(size: const Size(100.0, 100.0)),
window: RendererBinding.instance.platformDispatcher.views.single, window: window,
); );
final PipelineOwner owner = PipelineOwner(); final PipelineOwner owner = PipelineOwner();
view.attach(owner); view.attach(owner);
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
@Tags(<String>['reduced-test-set']) @Tags(<String>['reduced-test-set'])
library; library;
import 'dart:ui' as ui;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
...@@ -780,14 +782,19 @@ void main() { ...@@ -780,14 +782,19 @@ void main() {
} }
testWidgets('Reverse List showOnScreen', (WidgetTester tester) async { testWidgets('Reverse List showOnScreen', (WidgetTester tester) async {
addTearDown(tester.view.reset); final ui.Size originalScreenSize = tester.binding.window.physicalSize;
final double originalDevicePixelRatio = tester.binding.window.devicePixelRatio;
addTearDown(() {
tester.binding.window.devicePixelRatioTestValue = originalDevicePixelRatio;
tester.binding.window.physicalSizeTestValue = originalScreenSize;
});
const double screenHeight = 400.0; const double screenHeight = 400.0;
const double screenWidth = 400.0; const double screenWidth = 400.0;
const double itemHeight = screenHeight / 10.0; const double itemHeight = screenHeight / 10.0;
const ValueKey<String> centerKey = ValueKey<String>('center'); const ValueKey<String> centerKey = ValueKey<String>('center');
tester.view.devicePixelRatio = 1.0; tester.binding.window.devicePixelRatioTestValue = 1.0;
tester.view.physicalSize = const Size(screenWidth, screenHeight); tester.binding.window.physicalSizeTestValue = const Size(screenWidth, screenHeight);
await tester.pumpWidget(Directionality( await tester.pumpWidget(Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
......
...@@ -29,13 +29,13 @@ void main() { ...@@ -29,13 +29,13 @@ void main() {
), ),
); );
int? result = RendererBinding.instance.renderView.debugLayer!.find<int>(Offset( int? result = RendererBinding.instance.renderView.debugLayer!.find<int>(Offset(
10.0 * tester.view.devicePixelRatio, 10.0 * RendererBinding.instance.window.devicePixelRatio,
10.0 * tester.view.devicePixelRatio, 10.0 * RendererBinding.instance.window.devicePixelRatio,
)); ));
expect(result, null); expect(result, null);
result = RendererBinding.instance.renderView.debugLayer!.find<int>(Offset( result = RendererBinding.instance.renderView.debugLayer!.find<int>(Offset(
50.0 * tester.view.devicePixelRatio, 50.0 * RendererBinding.instance.window.devicePixelRatio,
50.0 * tester.view.devicePixelRatio, 50.0 * RendererBinding.instance.window.devicePixelRatio,
)); ));
expect(result, 1); expect(result, 1);
}); });
......
...@@ -374,7 +374,7 @@ void main() { ...@@ -374,7 +374,7 @@ void main() {
' creator: ConstrainedBox ← Container ← LayoutWithMissingId ←\n' ' creator: ConstrainedBox ← Container ← LayoutWithMissingId ←\n'
' CustomMultiChildLayout ← Center ← MediaQuery ←\n' ' CustomMultiChildLayout ← Center ← MediaQuery ←\n'
' _MediaQueryFromView ← _ViewScope ← View-[GlobalObjectKey\n' ' _MediaQueryFromView ← _ViewScope ← View-[GlobalObjectKey\n'
' TestFlutterView#00000] ← [root]\n' ' TestWindow#00000] ← [root]\n'
' parentData: offset=Offset(0.0, 0.0); id=null\n' ' parentData: offset=Offset(0.0, 0.0); id=null\n'
' constraints: MISSING\n' ' constraints: MISSING\n'
' size: MISSING\n' ' size: MISSING\n'
......
...@@ -11,7 +11,7 @@ void main() { ...@@ -11,7 +11,7 @@ void main() {
group('DisplayFeatureSubScreen', () { group('DisplayFeatureSubScreen', () {
testWidgets('without Directionality or anchor', (WidgetTester tester) async { testWidgets('without Directionality or anchor', (WidgetTester tester) async {
const Key childKey = Key('childKey'); const Key childKey = Key('childKey');
final MediaQueryData mediaQuery = MediaQueryData.fromView(tester.view).copyWith( final MediaQueryData mediaQuery = MediaQueryData.fromView(WidgetsBinding.instance.window).copyWith(
displayFeatures: <DisplayFeature>[ displayFeatures: <DisplayFeature>[
const DisplayFeature( const DisplayFeature(
bounds: Rect.fromLTRB(390, 0, 410, 600), bounds: Rect.fromLTRB(390, 0, 410, 600),
...@@ -39,7 +39,7 @@ void main() { ...@@ -39,7 +39,7 @@ void main() {
testWidgets('with anchorPoint', (WidgetTester tester) async { testWidgets('with anchorPoint', (WidgetTester tester) async {
const Key childKey = Key('childKey'); const Key childKey = Key('childKey');
final MediaQueryData mediaQuery = MediaQueryData.fromView(tester.view).copyWith( final MediaQueryData mediaQuery = MediaQueryData.fromView(WidgetsBinding.instance.window).copyWith(
displayFeatures: <DisplayFeature>[ displayFeatures: <DisplayFeature>[
const DisplayFeature( const DisplayFeature(
bounds: Rect.fromLTRB(390, 0, 410, 600), bounds: Rect.fromLTRB(390, 0, 410, 600),
...@@ -70,7 +70,7 @@ void main() { ...@@ -70,7 +70,7 @@ void main() {
testWidgets('with infinity anchorpoint', (WidgetTester tester) async { testWidgets('with infinity anchorpoint', (WidgetTester tester) async {
const Key childKey = Key('childKey'); const Key childKey = Key('childKey');
final MediaQueryData mediaQuery = MediaQueryData.fromView(tester.view).copyWith( final MediaQueryData mediaQuery = MediaQueryData.fromView(WidgetsBinding.instance.window).copyWith(
displayFeatures: <DisplayFeature>[ displayFeatures: <DisplayFeature>[
const DisplayFeature( const DisplayFeature(
bounds: Rect.fromLTRB(390, 0, 410, 600), bounds: Rect.fromLTRB(390, 0, 410, 600),
...@@ -101,7 +101,7 @@ void main() { ...@@ -101,7 +101,7 @@ void main() {
testWidgets('with horizontal hinge and anchorPoint', (WidgetTester tester) async { testWidgets('with horizontal hinge and anchorPoint', (WidgetTester tester) async {
const Key childKey = Key('childKey'); const Key childKey = Key('childKey');
final MediaQueryData mediaQuery = MediaQueryData.fromView(tester.view).copyWith( final MediaQueryData mediaQuery = MediaQueryData.fromView(WidgetsBinding.instance.window).copyWith(
displayFeatures: <DisplayFeature>[ displayFeatures: <DisplayFeature>[
const DisplayFeature( const DisplayFeature(
bounds: Rect.fromLTRB(0, 290, 800, 310), bounds: Rect.fromLTRB(0, 290, 800, 310),
...@@ -131,7 +131,7 @@ void main() { ...@@ -131,7 +131,7 @@ void main() {
testWidgets('with multiple display features and anchorPoint', (WidgetTester tester) async { testWidgets('with multiple display features and anchorPoint', (WidgetTester tester) async {
const Key childKey = Key('childKey'); const Key childKey = Key('childKey');
final MediaQueryData mediaQuery = MediaQueryData.fromView(tester.view).copyWith( final MediaQueryData mediaQuery = MediaQueryData.fromView(WidgetsBinding.instance.window).copyWith(
displayFeatures: <DisplayFeature>[ displayFeatures: <DisplayFeature>[
const DisplayFeature( const DisplayFeature(
bounds: Rect.fromLTRB(0, 290, 800, 310), bounds: Rect.fromLTRB(0, 290, 800, 310),
...@@ -166,7 +166,7 @@ void main() { ...@@ -166,7 +166,7 @@ void main() {
testWidgets('with non-splitting display features and anchorPoint', (WidgetTester tester) async { testWidgets('with non-splitting display features and anchorPoint', (WidgetTester tester) async {
const Key childKey = Key('childKey'); const Key childKey = Key('childKey');
final MediaQueryData mediaQuery = MediaQueryData.fromView(tester.view).copyWith( final MediaQueryData mediaQuery = MediaQueryData.fromView(WidgetsBinding.instance.window).copyWith(
displayFeatures: <DisplayFeature>[ displayFeatures: <DisplayFeature>[
// Top notch // Top notch
const DisplayFeature( const DisplayFeature(
...@@ -211,7 +211,7 @@ void main() { ...@@ -211,7 +211,7 @@ void main() {
testWidgets('with size 0 display feature in half-opened posture and anchorPoint', (WidgetTester tester) async { testWidgets('with size 0 display feature in half-opened posture and anchorPoint', (WidgetTester tester) async {
const Key childKey = Key('childKey'); const Key childKey = Key('childKey');
final MediaQueryData mediaQuery = MediaQueryData.fromView(tester.view).copyWith( final MediaQueryData mediaQuery = MediaQueryData.fromView(WidgetsBinding.instance.window).copyWith(
displayFeatures: <DisplayFeature>[ displayFeatures: <DisplayFeature>[
const DisplayFeature( const DisplayFeature(
bounds: Rect.fromLTRB(0, 300, 800, 300), bounds: Rect.fromLTRB(0, 300, 800, 300),
......
...@@ -1230,7 +1230,7 @@ void main() { ...@@ -1230,7 +1230,7 @@ void main() {
' │ primaryFocus: FocusNode#00000(Child 4 [PRIMARY FOCUS])\n' ' │ primaryFocus: FocusNode#00000(Child 4 [PRIMARY FOCUS])\n'
' │ primaryFocusCreator: Container-[GlobalKey#00000] ← MediaQuery ←\n' ' │ primaryFocusCreator: Container-[GlobalKey#00000] ← MediaQuery ←\n'
' │ _MediaQueryFromView ← _ViewScope ← View-[GlobalObjectKey\n' ' │ _MediaQueryFromView ← _ViewScope ← View-[GlobalObjectKey\n'
' │ TestFlutterView#00000] ← [root]\n' ' │ TestWindow#00000] ← [root]\n'
' │\n' ' │\n'
' └─rootScope: FocusScopeNode#00000(Root Focus Scope [IN FOCUS PATH])\n' ' └─rootScope: FocusScopeNode#00000(Root Focus Scope [IN FOCUS PATH])\n'
' │ IN FOCUS PATH\n' ' │ IN FOCUS PATH\n'
......
...@@ -2,16 +2,14 @@ ...@@ -2,16 +2,14 @@
// 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 'dart:ui' show FlutterView;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
const Size _kTestViewSize = Size(800.0, 600.0); const Size _kTestViewSize = Size(800.0, 600.0);
class ScheduledFrameTrackingPlatformDispatcher extends TestPlatformDispatcher { class ScheduledFrameTrackingWindow extends TestWindow {
ScheduledFrameTrackingPlatformDispatcher({ required super.platformDispatcher }); ScheduledFrameTrackingWindow({ required super.window });
int _scheduledFrameCount = 0; int _scheduledFrameCount = 0;
int get scheduledFrameCount => _scheduledFrameCount; int get scheduledFrameCount => _scheduledFrameCount;
...@@ -28,16 +26,16 @@ class ScheduledFrameTrackingPlatformDispatcher extends TestPlatformDispatcher { ...@@ -28,16 +26,16 @@ class ScheduledFrameTrackingPlatformDispatcher extends TestPlatformDispatcher {
} }
class ScheduledFrameTrackingBindings extends AutomatedTestWidgetsFlutterBinding { class ScheduledFrameTrackingBindings extends AutomatedTestWidgetsFlutterBinding {
late final ScheduledFrameTrackingPlatformDispatcher _platformDispatcher = ScheduledFrameTrackingPlatformDispatcher(platformDispatcher: super.platformDispatcher); late final ScheduledFrameTrackingWindow _window = ScheduledFrameTrackingWindow(window: super.window);
@override @override
ScheduledFrameTrackingPlatformDispatcher get platformDispatcher => _platformDispatcher; ScheduledFrameTrackingWindow get window => _window;
} }
class OffscreenRenderView extends RenderView { class OffscreenRenderView extends RenderView {
OffscreenRenderView({required FlutterView view}) : super( OffscreenRenderView() : super(
configuration: const ViewConfiguration(size: _kTestViewSize), configuration: const ViewConfiguration(size: _kTestViewSize),
window: view, window: WidgetsBinding.instance.window,
); );
@override @override
...@@ -47,14 +45,13 @@ class OffscreenRenderView extends RenderView { ...@@ -47,14 +45,13 @@ class OffscreenRenderView extends RenderView {
} }
class OffscreenWidgetTree { class OffscreenWidgetTree {
OffscreenWidgetTree(this.view) { OffscreenWidgetTree() {
renderView.attach(pipelineOwner); renderView.attach(pipelineOwner);
renderView.prepareInitialFrame(); renderView.prepareInitialFrame();
pipelineOwner.requestVisualUpdate(); pipelineOwner.requestVisualUpdate();
} }
final FlutterView view; final RenderView renderView = OffscreenRenderView();
late final RenderView renderView = OffscreenRenderView(view: view);
final BuildOwner buildOwner = BuildOwner(focusManager: FocusManager()); final BuildOwner buildOwner = BuildOwner(focusManager: FocusManager());
final PipelineOwner pipelineOwner = PipelineOwner(); final PipelineOwner pipelineOwner = PipelineOwner();
RenderObjectToWidgetElement<RenderBox>? root; RenderObjectToWidgetElement<RenderBox>? root;
...@@ -171,12 +168,12 @@ void main() { ...@@ -171,12 +168,12 @@ void main() {
testWidgets('RenderObjectToWidgetAdapter.attachToRenderTree does not schedule frame', (WidgetTester tester) async { testWidgets('RenderObjectToWidgetAdapter.attachToRenderTree does not schedule frame', (WidgetTester tester) async {
expect(WidgetsBinding.instance, isA<ScheduledFrameTrackingBindings>()); expect(WidgetsBinding.instance, isA<ScheduledFrameTrackingBindings>());
final ScheduledFrameTrackingPlatformDispatcher platformDispatcher = tester.platformDispatcher as ScheduledFrameTrackingPlatformDispatcher; final ScheduledFrameTrackingWindow window = WidgetsBinding.instance.window as ScheduledFrameTrackingWindow;
platformDispatcher.resetScheduledFrameCount(); window.resetScheduledFrameCount();
expect(platformDispatcher.scheduledFrameCount, isZero); expect(window.scheduledFrameCount, isZero);
final OffscreenWidgetTree tree = OffscreenWidgetTree(tester.view); final OffscreenWidgetTree tree = OffscreenWidgetTree();
tree.pumpWidget(const SizedBox.shrink()); tree.pumpWidget(const SizedBox.shrink());
expect(platformDispatcher.scheduledFrameCount, isZero); expect(window.scheduledFrameCount, isZero);
}); });
testWidgets('no crosstalk between widget build owners', (WidgetTester tester) async { testWidgets('no crosstalk between widget build owners', (WidgetTester tester) async {
...@@ -184,7 +181,7 @@ void main() { ...@@ -184,7 +181,7 @@ void main() {
final Counter counter1 = Counter(); final Counter counter1 = Counter();
final Trigger trigger2 = Trigger(); final Trigger trigger2 = Trigger();
final Counter counter2 = Counter(); final Counter counter2 = Counter();
final OffscreenWidgetTree tree = OffscreenWidgetTree(tester.view); final OffscreenWidgetTree tree = OffscreenWidgetTree();
// Both counts should start at zero // Both counts should start at zero
expect(counter1.count, equals(0)); expect(counter1.count, equals(0));
expect(counter2.count, equals(0)); expect(counter2.count, equals(0));
...@@ -230,7 +227,7 @@ void main() { ...@@ -230,7 +227,7 @@ void main() {
}); });
testWidgets('no crosstalk between focus nodes', (WidgetTester tester) async { testWidgets('no crosstalk between focus nodes', (WidgetTester tester) async {
final OffscreenWidgetTree tree = OffscreenWidgetTree(tester.view); final OffscreenWidgetTree tree = OffscreenWidgetTree();
final FocusNode onscreenFocus = FocusNode(); final FocusNode onscreenFocus = FocusNode();
final FocusNode offscreenFocus = FocusNode(); final FocusNode offscreenFocus = FocusNode();
await tester.pumpWidget( await tester.pumpWidget(
...@@ -253,7 +250,7 @@ void main() { ...@@ -253,7 +250,7 @@ void main() {
}); });
testWidgets('able to tear down offscreen tree', (WidgetTester tester) async { testWidgets('able to tear down offscreen tree', (WidgetTester tester) async {
final OffscreenWidgetTree tree = OffscreenWidgetTree(tester.view); final OffscreenWidgetTree tree = OffscreenWidgetTree();
final List<WidgetState> states = <WidgetState>[]; final List<WidgetState> states = <WidgetState>[];
tree.pumpWidget(SizedBox(child: TestStates(states: states))); tree.pumpWidget(SizedBox(child: TestStates(states: states)));
expect(states, <WidgetState>[WidgetState.initialized]); expect(states, <WidgetState>[WidgetState.initialized]);
......
...@@ -223,7 +223,7 @@ void main() { ...@@ -223,7 +223,7 @@ void main() {
'_RenderDiagonal#00000 relayoutBoundary=up1\n' '_RenderDiagonal#00000 relayoutBoundary=up1\n'
' │ creator: _Diagonal ← Align ← Directionality ← MediaQuery ←\n' ' │ creator: _Diagonal ← Align ← Directionality ← MediaQuery ←\n'
' │ _MediaQueryFromView ← _ViewScope ← View-[GlobalObjectKey\n' ' │ _MediaQueryFromView ← _ViewScope ← View-[GlobalObjectKey\n'
' │ TestFlutterView#00000] ← [root]\n' ' │ TestWindow#00000] ← [root]\n'
' │ parentData: offset=Offset(0.0, 0.0) (can use size)\n' ' │ parentData: offset=Offset(0.0, 0.0) (can use size)\n'
' │ constraints: BoxConstraints(0.0<=w<=800.0, 0.0<=h<=600.0)\n' ' │ constraints: BoxConstraints(0.0<=w<=800.0, 0.0<=h<=600.0)\n'
' │ size: Size(190.0, 220.0)\n' ' │ size: Size(190.0, 220.0)\n'
...@@ -231,7 +231,7 @@ void main() { ...@@ -231,7 +231,7 @@ void main() {
' ├─topLeft: RenderConstrainedBox#00000 relayoutBoundary=up2\n' ' ├─topLeft: RenderConstrainedBox#00000 relayoutBoundary=up2\n'
' │ creator: SizedBox ← _Diagonal ← Align ← Directionality ←\n' ' │ creator: SizedBox ← _Diagonal ← Align ← Directionality ←\n'
' │ MediaQuery ← _MediaQueryFromView ← _ViewScope ←\n' ' │ MediaQuery ← _MediaQueryFromView ← _ViewScope ←\n'
' │ View-[GlobalObjectKey TestFlutterView#00000] ← [root]\n' ' │ View-[GlobalObjectKey TestWindow#00000] ← [root]\n'
' │ parentData: offset=Offset(0.0, 0.0) (can use size)\n' ' │ parentData: offset=Offset(0.0, 0.0) (can use size)\n'
' │ constraints: BoxConstraints(unconstrained)\n' ' │ constraints: BoxConstraints(unconstrained)\n'
' │ size: Size(80.0, 100.0)\n' ' │ size: Size(80.0, 100.0)\n'
...@@ -240,7 +240,7 @@ void main() { ...@@ -240,7 +240,7 @@ void main() {
' └─bottomRight: RenderConstrainedBox#00000 relayoutBoundary=up2\n' ' └─bottomRight: RenderConstrainedBox#00000 relayoutBoundary=up2\n'
' creator: SizedBox ← _Diagonal ← Align ← Directionality ←\n' ' creator: SizedBox ← _Diagonal ← Align ← Directionality ←\n'
' MediaQuery ← _MediaQueryFromView ← _ViewScope ←\n' ' MediaQuery ← _MediaQueryFromView ← _ViewScope ←\n'
' View-[GlobalObjectKey TestFlutterView#00000] ← [root]\n' ' View-[GlobalObjectKey TestWindow#00000] ← [root]\n'
' parentData: offset=Offset(80.0, 100.0) (can use size)\n' ' parentData: offset=Offset(80.0, 100.0) (can use size)\n'
' constraints: BoxConstraints(unconstrained)\n' ' constraints: BoxConstraints(unconstrained)\n'
' size: Size(110.0, 120.0)\n' ' size: Size(110.0, 120.0)\n'
......
...@@ -227,9 +227,10 @@ void main() { ...@@ -227,9 +227,10 @@ void main() {
const Size kCommonScreenSizeLandscape = Size(1770, 1070); const Size kCommonScreenSizeLandscape = Size(1770, 1070);
Future<void> showPicker(WidgetTester tester, Locale locale, Size size) async { Future<void> showPicker(WidgetTester tester, Locale locale, Size size) async {
tester.view.physicalSize = size; tester.binding.window.physicalSizeTestValue = size;
tester.view.devicePixelRatio = 1.0; addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
addTearDown(tester.view.reset); tester.binding.window.devicePixelRatioTestValue = 1.0;
addTearDown(tester.binding.window.clearDevicePixelRatioTestValue);
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Builder( home: Builder(
......
...@@ -9,9 +9,8 @@ import 'package:flutter_test/flutter_test.dart'; ...@@ -9,9 +9,8 @@ import 'package:flutter_test/flutter_test.dart';
void main() { void main() {
testWidgets('can localize the header in all known formats - portrait', (WidgetTester tester) async { testWidgets('can localize the header in all known formats - portrait', (WidgetTester tester) async {
// Ensure picker is displayed in portrait mode. // Ensure picker is displayed in portrait mode.
tester.view.physicalSize = const Size(400, 800); tester.binding.window.physicalSizeTestValue = const Size(400, 800);
tester.view.devicePixelRatio = 1; tester.binding.window.devicePixelRatioTestValue = 1;
addTearDown(tester.view.reset);
final Finder stringFragmentTextFinder = find.descendant( final Finder stringFragmentTextFinder = find.descendant(
of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_StringFragment'), of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_StringFragment'),
...@@ -75,13 +74,15 @@ void main() { ...@@ -75,13 +74,15 @@ void main() {
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);
} }
tester.binding.window.clearPhysicalSizeTestValue();
tester.binding.window.clearDevicePixelRatioTestValue();
}); });
testWidgets('can localize the header in all known formats - landscape', (WidgetTester tester) async { testWidgets('can localize the header in all known formats - landscape', (WidgetTester tester) async {
// Ensure picker is displayed in landscape mode. // Ensure picker is displayed in landscape mode.
tester.view.physicalSize = const Size(800, 400); tester.binding.window.physicalSizeTestValue = const Size(800, 400);
tester.view.devicePixelRatio = 1; tester.binding.window.devicePixelRatioTestValue = 1;
addTearDown(tester.view.reset);
final Finder stringFragmentTextFinder = find.descendant( final Finder stringFragmentTextFinder = find.descendant(
of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_StringFragment'), of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_StringFragment'),
...@@ -150,6 +151,9 @@ void main() { ...@@ -150,6 +151,9 @@ void main() {
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);
} }
tester.binding.window.clearPhysicalSizeTestValue();
tester.binding.window.clearDevicePixelRatioTestValue();
}); });
testWidgets('can localize input mode in all known formats', (WidgetTester tester) async { testWidgets('can localize input mode in all known formats', (WidgetTester tester) async {
......
...@@ -182,18 +182,17 @@ abstract class TestWidgetsFlutterBinding extends BindingBase ...@@ -182,18 +182,17 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
/// ///
/// This constructor overrides the [debugPrint] global hook to point to /// This constructor overrides the [debugPrint] global hook to point to
/// [debugPrintOverride], which can be overridden by subclasses. /// [debugPrintOverride], which can be overridden by subclasses.
TestWidgetsFlutterBinding() : platformDispatcher = TestPlatformDispatcher( TestWidgetsFlutterBinding() : _window = TestWindow(window: ui.window) {
platformDispatcher: PlatformDispatcher.instance,
) {
debugPrint = debugPrintOverride; debugPrint = debugPrintOverride;
debugDisableShadows = disableShadows; debugDisableShadows = disableShadows;
} }
@override @override
late final TestWindow window; TestWindow get window => _window;
final TestWindow _window;
@override @override
final TestPlatformDispatcher platformDispatcher; TestPlatformDispatcher get platformDispatcher => _window.platformDispatcher;
@override @override
TestRestorationManager get restorationManager { TestRestorationManager get restorationManager {
...@@ -347,12 +346,6 @@ abstract class TestWidgetsFlutterBinding extends BindingBase ...@@ -347,12 +346,6 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
@override @override
void initInstances() { void initInstances() {
// This is intialized here because it's needed for the `super.initInstances`
// call. It can't be handled as a ctor initializer because it's dependent
// on `platformDispatcher`. It can't be handled in the ctor itself because
// the base class ctor is called first and calls `initInstances`.
window = TestWindow.fromPlatformDispatcher(platformDispatcher: platformDispatcher);
super.initInstances(); super.initInstances();
_instance = this; _instance = this;
timeDilation = 1.0; // just in case the developer has artificially changed it for development timeDilation = 1.0; // just in case the developer has artificially changed it for development
...@@ -1919,9 +1912,9 @@ class LiveTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding { ...@@ -1919,9 +1912,9 @@ class LiveTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
@override @override
ViewConfiguration createViewConfiguration() { ViewConfiguration createViewConfiguration() {
return TestViewConfiguration.fromView( return TestViewConfiguration(
size: _surfaceSize ?? _kDefaultTestViewportSize, size: _surfaceSize ?? _kDefaultTestViewportSize,
view: window, window: window,
); );
} }
...@@ -1945,31 +1938,20 @@ class LiveTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding { ...@@ -1945,31 +1938,20 @@ class LiveTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
/// size is in logical pixels. The resulting ViewConfiguration maps the given /// size is in logical pixels. The resulting ViewConfiguration maps the given
/// size onto the actual display using the [BoxFit.contain] algorithm. /// size onto the actual display using the [BoxFit.contain] algorithm.
class TestViewConfiguration extends ViewConfiguration { class TestViewConfiguration extends ViewConfiguration {
/// Deprecated. Will be removed in a future version of Flutter. /// Creates a [TestViewConfiguration] with the given size. Defaults to 800x600.
///
/// This property has been deprecated to prepare for Flutter's upcoming
/// support for multiple views and multiple windows.
/// ///
/// Use [TestViewConfiguration.fromView] instead. /// If a [window] instance is not provided it defaults to [ui.window].
@Deprecated(
'Use TestViewConfiguration.fromView instead. '
'Deprecated to prepare for the upcoming multi-window support. '
'This feature was deprecated after v3.7.0-32.0.pre.'
)
factory TestViewConfiguration({ factory TestViewConfiguration({
Size size = _kDefaultTestViewportSize, Size size = _kDefaultTestViewportSize,
ui.FlutterView? window, ui.FlutterView? window,
}) { }) {
return TestViewConfiguration.fromView(size: size, view: window ?? ui.window); return TestViewConfiguration._(size, window ?? ui.window);
} }
/// Creates a [TestViewConfiguration] with the given size and view. TestViewConfiguration._(Size size, ui.FlutterView window)
/// : _paintMatrix = _getMatrix(size, window.devicePixelRatio, window),
/// The [size] defaults to 800x600. _hitTestMatrix = _getMatrix(size, 1.0, window),
TestViewConfiguration.fromView({required ui.FlutterView view, super.size = _kDefaultTestViewportSize}) super(size: size, devicePixelRatio: window.devicePixelRatio);
: _paintMatrix = _getMatrix(size, view.devicePixelRatio, view),
_hitTestMatrix = _getMatrix(size, 1.0, view),
super(devicePixelRatio: view.devicePixelRatio);
static Matrix4 _getMatrix(Size size, double devicePixelRatio, ui.FlutterView window) { static Matrix4 _getMatrix(Size size, double devicePixelRatio, ui.FlutterView window) {
final double inverseRatio = devicePixelRatio / window.devicePixelRatio; final double inverseRatio = devicePixelRatio / window.devicePixelRatio;
......
...@@ -14,7 +14,6 @@ import 'event_simulation.dart'; ...@@ -14,7 +14,6 @@ import 'event_simulation.dart';
import 'finders.dart'; import 'finders.dart';
import 'test_async_utils.dart'; import 'test_async_utils.dart';
import 'test_pointer.dart'; import 'test_pointer.dart';
import 'window.dart';
/// The default drag touch slop used to break up a large drag into multiple /// The default drag touch slop used to break up a large drag into multiple
/// smaller moves. /// smaller moves.
...@@ -235,37 +234,6 @@ abstract class WidgetController { ...@@ -235,37 +234,6 @@ abstract class WidgetController {
/// A reference to the current instance of the binding. /// A reference to the current instance of the binding.
final WidgetsBinding binding; final WidgetsBinding binding;
/// The [TestPlatformDispatcher] that is being used in this test.
///
/// This will be injected into the framework such that calls to
/// [WidgetsBinding.platformDispatcher] will use this. This allows
/// users to change platform specific properties for testing.
///
/// See also:
///
/// * [TestFlutterView] which allows changing view specific properties
/// for testing
/// * [view] and [viewOf] which are used to find
/// [TestFlutterView]s from the widget tree
TestPlatformDispatcher get platformDispatcher => binding.platformDispatcher as TestPlatformDispatcher;
/// The [TestFlutterView] provided by default when testing with
/// [WidgetTester.pumpWidget].
///
/// If the test requires multiple views, it will need to use [viewOf] instead
/// to ensure that the view related to the widget being evaluated is the one
/// that gets updated.
///
/// See also:
///
/// * [viewOf], which can find a [TestFlutterView] related to a given finder.
/// This is how to modify view properties for testing when dealing with
/// multiple views.
TestFlutterView get view {
assert(platformDispatcher.views.length == 1, 'When testing with multiple views, use `viewOf` instead.');
return platformDispatcher.views.single;
}
/// Provides access to a [SemanticsController] for testing anything related to /// Provides access to a [SemanticsController] for testing anything related to
/// the [Semantics] tree. /// the [Semantics] tree.
/// ///
...@@ -289,26 +257,6 @@ abstract class WidgetController { ...@@ -289,26 +257,6 @@ abstract class WidgetController {
// TODO(ianh): verify that the return values are of type T and throw // TODO(ianh): verify that the return values are of type T and throw
// a good message otherwise, in all the generic methods below // a good message otherwise, in all the generic methods below
/// Finds the [TestFlutterView] that is the closest ancestor of the widget
/// found by [finder].
///
/// [TestFlutterView] can be used to modify view specific properties for testing.
///
/// See also:
///
/// * [view] which returns the [TestFlutterView] used when only a single
/// view is being used.
TestFlutterView viewOf(Finder finder) {
final View view = firstWidget<View>(
find.ancestor(
of: finder,
matching: find.byType(View),
)
);
return view.view as TestFlutterView;
}
/// Checks if `finder` exists in the tree. /// Checks if `finder` exists in the tree.
bool any(Finder finder) { bool any(Finder finder) {
TestAsyncUtils.guardSync(); TestAsyncUtils.guardSync();
......
This diff is collapsed.
...@@ -711,25 +711,6 @@ void main() { ...@@ -711,25 +711,6 @@ void main() {
}); });
}); });
testWidgets('platformDispatcher exposes the platformDispatcher from binding', (WidgetTester tester) async {
expect(tester.platformDispatcher, tester.binding.platformDispatcher);
});
testWidgets('view exposes the implicitView from platformDispatcher', (WidgetTester tester) async {
expect(tester.view, tester.platformDispatcher.implicitView);
});
testWidgets('viewOf finds a view when the view is implicit', (WidgetTester tester) async {
await tester.pumpWidget(const MaterialApp(
home: Center(
child: Text('Test'),
)
));
expect(() => tester.viewOf(find.text('Test')), isNot(throwsA(anything)));
expect(tester.viewOf(find.text('Test')), isA<TestFlutterView>());
});
group('SemanticsController', () { group('SemanticsController', () {
group('find', () { group('find', () {
testWidgets('throws when there are no semantics', (WidgetTester tester) async { testWidgets('throws when there are no semantics', (WidgetTester tester) async {
......
...@@ -7,17 +7,15 @@ import 'dart:ui' show AccessibilityFeatures, Brightness, Locale, PlatformDispatc ...@@ -7,17 +7,15 @@ import 'dart:ui' show AccessibilityFeatures, Brightness, Locale, PlatformDispatc
import 'package:flutter/widgets.dart' show WidgetsBinding, WidgetsBindingObserver; import 'package:flutter/widgets.dart' show WidgetsBinding, WidgetsBindingObserver;
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'utils/fake_and_mock_utils.dart';
void main() { void main() {
test('TestPlatformDispatcher can handle new methods without breaking', () { test('TestWindow can handle new methods without breaking', () {
final dynamic testPlatformDispatcher = TestPlatformDispatcher(platformDispatcher: PlatformDispatcher.instance); final dynamic testPlatformDispatcher = TestPlatformDispatcher(platformDispatcher: PlatformDispatcher.instance);
// ignore: avoid_dynamic_calls // ignore: avoid_dynamic_calls
expect(testPlatformDispatcher.someNewProperty, null); expect(testPlatformDispatcher.someNewProperty, null);
}); });
testWidgets('TestPlatformDispatcher can fake locale', (WidgetTester tester) async { testWidgets('TestWindow can fake locale', (WidgetTester tester) async {
verifyPropertyFaked<Locale>( verifyThatTestPlatformDispatcherCanFakeProperty<Locale>(
tester: tester, tester: tester,
realValue: PlatformDispatcher.instance.locale, realValue: PlatformDispatcher.instance.locale,
fakeValue: const Locale('fake_language_code'), fakeValue: const Locale('fake_language_code'),
...@@ -30,8 +28,8 @@ void main() { ...@@ -30,8 +28,8 @@ void main() {
); );
}); });
testWidgets('TestPlatformDispatcher can fake locales', (WidgetTester tester) async { testWidgets('TestWindow can fake locales', (WidgetTester tester) async {
verifyPropertyFaked<List<Locale>>( verifyThatTestPlatformDispatcherCanFakeProperty<List<Locale>>(
tester: tester, tester: tester,
realValue: PlatformDispatcher.instance.locales, realValue: PlatformDispatcher.instance.locales,
fakeValue: <Locale>[const Locale('fake_language_code')], fakeValue: <Locale>[const Locale('fake_language_code')],
...@@ -44,8 +42,8 @@ void main() { ...@@ -44,8 +42,8 @@ void main() {
); );
}); });
testWidgets('TestPlatformDispatcher can fake text scale factor', (WidgetTester tester) async { testWidgets('TestWindow can fake text scale factor', (WidgetTester tester) async {
verifyPropertyFaked<double>( verifyThatTestPlatformDispatcherCanFakeProperty<double>(
tester: tester, tester: tester,
realValue: PlatformDispatcher.instance.textScaleFactor, realValue: PlatformDispatcher.instance.textScaleFactor,
fakeValue: 2.5, fakeValue: 2.5,
...@@ -58,8 +56,8 @@ void main() { ...@@ -58,8 +56,8 @@ void main() {
); );
}); });
testWidgets('TestPlatformDispatcher can fake clock format', (WidgetTester tester) async { testWidgets('TestWindow can fake clock format', (WidgetTester tester) async {
verifyPropertyFaked<bool>( verifyThatTestPlatformDispatcherCanFakeProperty<bool>(
tester: tester, tester: tester,
realValue: PlatformDispatcher.instance.alwaysUse24HourFormat, realValue: PlatformDispatcher.instance.alwaysUse24HourFormat,
fakeValue: !PlatformDispatcher.instance.alwaysUse24HourFormat, fakeValue: !PlatformDispatcher.instance.alwaysUse24HourFormat,
...@@ -72,8 +70,8 @@ void main() { ...@@ -72,8 +70,8 @@ void main() {
); );
}); });
testWidgets('TestPlatformDispatcher can fake brieflyShowPassword', (WidgetTester tester) async { testWidgets('TestWindow can fake brieflyShowPassword', (WidgetTester tester) async {
verifyPropertyFaked<bool>( verifyThatTestPlatformDispatcherCanFakeProperty<bool>(
tester: tester, tester: tester,
realValue: PlatformDispatcher.instance.brieflyShowPassword, realValue: PlatformDispatcher.instance.brieflyShowPassword,
fakeValue: !PlatformDispatcher.instance.brieflyShowPassword, fakeValue: !PlatformDispatcher.instance.brieflyShowPassword,
...@@ -84,8 +82,8 @@ void main() { ...@@ -84,8 +82,8 @@ void main() {
); );
}); });
testWidgets('TestPlatformDispatcher can fake default route name', (WidgetTester tester) async { testWidgets('TestWindow can fake default route name', (WidgetTester tester) async {
verifyPropertyFaked<String>( verifyThatTestPlatformDispatcherCanFakeProperty<String>(
tester: tester, tester: tester,
realValue: PlatformDispatcher.instance.defaultRouteName, realValue: PlatformDispatcher.instance.defaultRouteName,
fakeValue: 'fake_route', fakeValue: 'fake_route',
...@@ -98,8 +96,8 @@ void main() { ...@@ -98,8 +96,8 @@ void main() {
); );
}); });
testWidgets('TestPlatformDispatcher can fake accessibility features', (WidgetTester tester) async { testWidgets('TestWindow can fake accessibility features', (WidgetTester tester) async {
verifyPropertyFaked<AccessibilityFeatures>( verifyThatTestPlatformDispatcherCanFakeProperty<AccessibilityFeatures>(
tester: tester, tester: tester,
realValue: PlatformDispatcher.instance.accessibilityFeatures, realValue: PlatformDispatcher.instance.accessibilityFeatures,
fakeValue: const FakeAccessibilityFeatures(), fakeValue: const FakeAccessibilityFeatures(),
...@@ -112,8 +110,8 @@ void main() { ...@@ -112,8 +110,8 @@ void main() {
); );
}); });
testWidgets('TestPlatformDispatcher can fake platform brightness', (WidgetTester tester) async { testWidgets('TestWindow can fake platform brightness', (WidgetTester tester) async {
verifyPropertyFaked<Brightness>( verifyThatTestPlatformDispatcherCanFakeProperty<Brightness>(
tester: tester, tester: tester,
realValue: Brightness.light, realValue: Brightness.light,
fakeValue: Brightness.dark, fakeValue: Brightness.dark,
...@@ -126,7 +124,7 @@ void main() { ...@@ -126,7 +124,7 @@ void main() {
); );
}); });
testWidgets('TestPlatformDispatcher can clear out fake properties all at once', (WidgetTester tester) async { testWidgets('TestWindow can clear out fake properties all at once', (WidgetTester tester) async {
final Locale originalLocale = PlatformDispatcher.instance.locale; final Locale originalLocale = PlatformDispatcher.instance.locale;
final double originalTextScaleFactor = PlatformDispatcher.instance.textScaleFactor; final double originalTextScaleFactor = PlatformDispatcher.instance.textScaleFactor;
final TestPlatformDispatcher testPlatformDispatcher = retrieveTestBinding(tester).platformDispatcher; final TestPlatformDispatcher testPlatformDispatcher = retrieveTestBinding(tester).platformDispatcher;
...@@ -143,7 +141,7 @@ void main() { ...@@ -143,7 +141,7 @@ void main() {
expect(WidgetsBinding.instance.platformDispatcher.textScaleFactor, originalTextScaleFactor); expect(WidgetsBinding.instance.platformDispatcher.textScaleFactor, originalTextScaleFactor);
}); });
testWidgets('TestPlatformDispatcher sends fake locales when WidgetsBindingObserver notifiers are called', (WidgetTester tester) async { testWidgets('TestWindow sends fake locales when WidgetsBindingObserver notifiers are called', (WidgetTester tester) async {
final List<Locale> defaultLocales = WidgetsBinding.instance.platformDispatcher.locales; final List<Locale> defaultLocales = WidgetsBinding.instance.platformDispatcher.locales;
final TestObserver observer = TestObserver(); final TestObserver observer = TestObserver();
retrieveTestBinding(tester).addObserver(observer); retrieveTestBinding(tester).addObserver(observer);
...@@ -154,8 +152,36 @@ void main() { ...@@ -154,8 +152,36 @@ void main() {
}); });
} }
void verifyThatTestPlatformDispatcherCanFakeProperty<PlatformDispatcherPropertyType>({
required WidgetTester tester,
required PlatformDispatcherPropertyType? realValue,
required PlatformDispatcherPropertyType fakeValue,
required PlatformDispatcherPropertyType? Function() propertyRetriever,
required Function(TestWidgetsFlutterBinding, PlatformDispatcherPropertyType fakeValue) propertyFaker,
}) {
PlatformDispatcherPropertyType? propertyBeforeFaking;
PlatformDispatcherPropertyType? propertyAfterFaking;
propertyBeforeFaking = propertyRetriever();
propertyFaker(retrieveTestBinding(tester), fakeValue);
propertyAfterFaking = propertyRetriever();
expect(propertyBeforeFaking, realValue);
expect(propertyAfterFaking, fakeValue);
}
TestWidgetsFlutterBinding retrieveTestBinding(WidgetTester tester) {
final WidgetsBinding binding = tester.binding;
assert(binding is TestWidgetsFlutterBinding);
final TestWidgetsFlutterBinding testBinding = binding as TestWidgetsFlutterBinding;
return testBinding;
}
class TestObserver with WidgetsBindingObserver { class TestObserver with WidgetsBindingObserver {
List<Locale>? locales; List<Locale>? locales;
Locale? locale;
@override @override
void didChangeLocales(List<Locale>? locales) { void didChangeLocales(List<Locale>? locales) {
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
TestWidgetsFlutterBinding retrieveTestBinding(WidgetTester tester) {
final WidgetsBinding binding = tester.binding;
assert(binding is TestWidgetsFlutterBinding);
final TestWidgetsFlutterBinding testBinding = binding as TestWidgetsFlutterBinding;
return testBinding;
}
void verifyPropertyFaked<TProperty>({
required WidgetTester tester,
required TProperty realValue,
required TProperty fakeValue,
required TProperty Function() propertyRetriever,
required Function(TestWidgetsFlutterBinding, TProperty fakeValue) propertyFaker,
Matcher Function(TProperty) matcher = equals,
}) {
TProperty propertyBeforeFaking;
TProperty propertyAfterFaking;
propertyBeforeFaking = propertyRetriever();
propertyFaker(retrieveTestBinding(tester), fakeValue);
propertyAfterFaking = propertyRetriever();
expect(
realValue == fakeValue,
isFalse,
reason: 'Since the real value and fake value are equal, we cannot validate '
'that a property has been faked. Choose a different fake value to test.',
);
expect(propertyBeforeFaking, matcher(realValue));
expect(propertyAfterFaking, matcher(fakeValue));
}
void verifyPropertyReset<TProperty>({
required WidgetTester tester,
required TProperty fakeValue,
required TProperty Function() propertyRetriever,
required Function() propertyResetter,
required Function(TProperty fakeValue) propertyFaker,
Matcher Function(TProperty) matcher = equals,
}) {
TProperty propertyBeforeFaking;
TProperty propertyAfterFaking;
TProperty propertyAfterReset;
propertyBeforeFaking = propertyRetriever();
propertyFaker(fakeValue);
propertyAfterFaking = propertyRetriever();
propertyResetter();
propertyAfterReset = propertyRetriever();
expect(propertyAfterFaking, matcher(fakeValue));
expect(propertyAfterReset, matcher(propertyBeforeFaking));
}
Matcher matchesViewPadding(ViewPadding expected) => _FakeViewPaddingMatcher(expected);
class _FakeViewPaddingMatcher extends Matcher {
_FakeViewPaddingMatcher(this.expected);
final ViewPadding expected;
@override
Description describe(Description description) {
description.add('two ViewPadding instances match');
return description;
}
@override
Description describeMismatch(dynamic item, Description mismatchDescription, Map<dynamic, dynamic> matchState, bool verbose) {
assert(item is ViewPadding, 'Can only match against implementations of ViewPadding.');
final ViewPadding actual = item as ViewPadding;
if (actual.left != expected.left) {
mismatchDescription.add('actual.left (${actual.left}) did not match expected.left (${expected.left})');
}
if (actual.top != expected.top) {
mismatchDescription.add('actual.top (${actual.top}) did not match expected.top (${expected.top})');
}
if (actual.right != expected.right) {
mismatchDescription.add('actual.right (${actual.right}) did not match expected.right (${expected.right})');
}
if (actual.bottom != expected.bottom) {
mismatchDescription.add('actual.bottom (${actual.bottom}) did not match expected.bottom (${expected.bottom})');
}
return mismatchDescription;
}
@override
bool matches(dynamic item, Map<dynamic, dynamic> matchState) {
assert(item is ViewPadding, 'Can only match against implementations of ViewPadding.');
final ViewPadding actual = item as ViewPadding;
return actual.left == expected.left &&
actual.top == expected.top &&
actual.right == expected.right &&
actual.bottom == expected.bottom;
}
}
This diff is collapsed.
...@@ -3,19 +3,13 @@ ...@@ -3,19 +3,13 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:ui' as ui show window; import 'dart:ui' as ui show window;
import 'dart:ui'; import 'dart:ui' show AccessibilityFeatures, Brightness, Locale, PlatformDispatcher, SemanticsUpdate, SingletonFlutterWindow, Size, ViewPadding;
import 'package:flutter/semantics.dart' show SemanticsUpdateBuilder;
import 'package:flutter/widgets.dart' show WidgetsBinding, WidgetsBindingObserver; import 'package:flutter/widgets.dart' show WidgetsBinding, WidgetsBindingObserver;
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'utils/fake_and_mock_utils.dart';
void main() { void main() {
tearDown(() {
final TestWindow window = WidgetsBinding.instance.window as TestWindow;
window.clearAllTestValues();
});
test('TestWindow can handle new methods without breaking', () { test('TestWindow can handle new methods without breaking', () {
final dynamic testWindow = TestWindow(window: ui.window); final dynamic testWindow = TestWindow(window: ui.window);
// ignore: avoid_dynamic_calls // ignore: avoid_dynamic_calls
...@@ -23,7 +17,7 @@ void main() { ...@@ -23,7 +17,7 @@ void main() {
}); });
testWidgets('TestWindow can fake device pixel ratio', (WidgetTester tester) async { testWidgets('TestWindow can fake device pixel ratio', (WidgetTester tester) async {
verifyPropertyFaked<double>( verifyThatTestWindowCanFakeProperty<double>(
tester: tester, tester: tester,
realValue: ui.window.devicePixelRatio, realValue: ui.window.devicePixelRatio,
fakeValue: 2.5, fakeValue: 2.5,
...@@ -37,7 +31,7 @@ void main() { ...@@ -37,7 +31,7 @@ void main() {
}); });
testWidgets('TestWindow can fake physical size', (WidgetTester tester) async { testWidgets('TestWindow can fake physical size', (WidgetTester tester) async {
verifyPropertyFaked<Size>( verifyThatTestWindowCanFakeProperty<Size>(
tester: tester, tester: tester,
realValue: ui.window.physicalSize, realValue: ui.window.physicalSize,
fakeValue: const Size(50, 50), fakeValue: const Size(50, 50),
...@@ -51,7 +45,7 @@ void main() { ...@@ -51,7 +45,7 @@ void main() {
}); });
testWidgets('TestWindow can fake view insets', (WidgetTester tester) async { testWidgets('TestWindow can fake view insets', (WidgetTester tester) async {
verifyPropertyFaked<ViewPadding>( verifyThatTestWindowCanFakeProperty<ViewPadding>(
tester: tester, tester: tester,
realValue: ui.window.viewInsets, realValue: ui.window.viewInsets,
fakeValue: const FakeViewPadding(), fakeValue: const FakeViewPadding(),
...@@ -61,12 +55,11 @@ void main() { ...@@ -61,12 +55,11 @@ void main() {
propertyFaker: (TestWidgetsFlutterBinding binding, ViewPadding fakeValue) { propertyFaker: (TestWidgetsFlutterBinding binding, ViewPadding fakeValue) {
binding.window.viewInsetsTestValue = fakeValue; binding.window.viewInsetsTestValue = fakeValue;
}, },
matcher: matchesViewPadding,
); );
}); });
testWidgets('TestWindow can fake padding', (WidgetTester tester) async { testWidgets('TestWindow can fake padding', (WidgetTester tester) async {
verifyPropertyFaked<ViewPadding>( verifyThatTestWindowCanFakeProperty<ViewPadding>(
tester: tester, tester: tester,
realValue: ui.window.padding, realValue: ui.window.padding,
fakeValue: const FakeViewPadding(), fakeValue: const FakeViewPadding(),
...@@ -76,12 +69,11 @@ void main() { ...@@ -76,12 +69,11 @@ void main() {
propertyFaker: (TestWidgetsFlutterBinding binding, ViewPadding fakeValue) { propertyFaker: (TestWidgetsFlutterBinding binding, ViewPadding fakeValue) {
binding.window.paddingTestValue = fakeValue; binding.window.paddingTestValue = fakeValue;
}, },
matcher: matchesViewPadding
); );
}); });
testWidgets('TestWindow can fake locale', (WidgetTester tester) async { testWidgets('TestWindow can fake locale', (WidgetTester tester) async {
verifyPropertyFaked<Locale>( verifyThatTestWindowCanFakeProperty<Locale>(
tester: tester, tester: tester,
realValue: ui.window.locale, realValue: ui.window.locale,
fakeValue: const Locale('fake_language_code'), fakeValue: const Locale('fake_language_code'),
...@@ -95,7 +87,7 @@ void main() { ...@@ -95,7 +87,7 @@ void main() {
}); });
testWidgets('TestWindow can fake locales', (WidgetTester tester) async { testWidgets('TestWindow can fake locales', (WidgetTester tester) async {
verifyPropertyFaked<List<Locale>>( verifyThatTestWindowCanFakeProperty<List<Locale>>(
tester: tester, tester: tester,
realValue: ui.window.locales, realValue: ui.window.locales,
fakeValue: <Locale>[const Locale('fake_language_code')], fakeValue: <Locale>[const Locale('fake_language_code')],
...@@ -109,7 +101,7 @@ void main() { ...@@ -109,7 +101,7 @@ void main() {
}); });
testWidgets('TestWindow can fake text scale factor', (WidgetTester tester) async { testWidgets('TestWindow can fake text scale factor', (WidgetTester tester) async {
verifyPropertyFaked<double>( verifyThatTestWindowCanFakeProperty<double>(
tester: tester, tester: tester,
realValue: ui.window.textScaleFactor, realValue: ui.window.textScaleFactor,
fakeValue: 2.5, fakeValue: 2.5,
...@@ -123,7 +115,7 @@ void main() { ...@@ -123,7 +115,7 @@ void main() {
}); });
testWidgets('TestWindow can fake clock format', (WidgetTester tester) async { testWidgets('TestWindow can fake clock format', (WidgetTester tester) async {
verifyPropertyFaked<bool>( verifyThatTestWindowCanFakeProperty<bool>(
tester: tester, tester: tester,
realValue: ui.window.alwaysUse24HourFormat, realValue: ui.window.alwaysUse24HourFormat,
fakeValue: !ui.window.alwaysUse24HourFormat, fakeValue: !ui.window.alwaysUse24HourFormat,
...@@ -137,7 +129,7 @@ void main() { ...@@ -137,7 +129,7 @@ void main() {
}); });
testWidgets('TestWindow can fake brieflyShowPassword', (WidgetTester tester) async { testWidgets('TestWindow can fake brieflyShowPassword', (WidgetTester tester) async {
verifyPropertyFaked<bool>( verifyThatTestWindowCanFakeProperty<bool>(
tester: tester, tester: tester,
realValue: ui.window.brieflyShowPassword, realValue: ui.window.brieflyShowPassword,
fakeValue: !ui.window.brieflyShowPassword, fakeValue: !ui.window.brieflyShowPassword,
...@@ -149,7 +141,7 @@ void main() { ...@@ -149,7 +141,7 @@ void main() {
}); });
testWidgets('TestWindow can fake default route name', (WidgetTester tester) async { testWidgets('TestWindow can fake default route name', (WidgetTester tester) async {
verifyPropertyFaked<String>( verifyThatTestWindowCanFakeProperty<String>(
tester: tester, tester: tester,
realValue: ui.window.defaultRouteName, realValue: ui.window.defaultRouteName,
fakeValue: 'fake_route', fakeValue: 'fake_route',
...@@ -163,7 +155,7 @@ void main() { ...@@ -163,7 +155,7 @@ void main() {
}); });
testWidgets('TestWindow can fake accessibility features', (WidgetTester tester) async { testWidgets('TestWindow can fake accessibility features', (WidgetTester tester) async {
verifyPropertyFaked<AccessibilityFeatures>( verifyThatTestWindowCanFakeProperty<AccessibilityFeatures>(
tester: tester, tester: tester,
realValue: ui.window.accessibilityFeatures, realValue: ui.window.accessibilityFeatures,
fakeValue: const FakeAccessibilityFeatures(), fakeValue: const FakeAccessibilityFeatures(),
...@@ -177,7 +169,7 @@ void main() { ...@@ -177,7 +169,7 @@ void main() {
}); });
testWidgets('TestWindow can fake platform brightness', (WidgetTester tester) async { testWidgets('TestWindow can fake platform brightness', (WidgetTester tester) async {
verifyPropertyFaked<Brightness>( verifyThatTestWindowCanFakeProperty<Brightness>(
tester: tester, tester: tester,
realValue: Brightness.light, realValue: Brightness.light,
fakeValue: Brightness.dark, fakeValue: Brightness.dark,
...@@ -217,27 +209,63 @@ void main() { ...@@ -217,27 +209,63 @@ void main() {
retrieveTestBinding(tester).window.localesTestValue = defaultLocales; retrieveTestBinding(tester).window.localesTestValue = defaultLocales;
}); });
testWidgets('Updates to window also update tester.view', (WidgetTester tester) async { test('Window test', () {
tester.binding.window.devicePixelRatioTestValue = 7; final FakeSingletonWindow fakeWindow = FakeSingletonWindow();
tester.binding.window.displayFeaturesTestValue = <DisplayFeature>[const DisplayFeature(bounds: Rect.fromLTWH(0, 0, 20, 300), type: DisplayFeatureType.unknown, state: DisplayFeatureState.unknown)]; final TestWindow testWindow = TestWindow(window: fakeWindow);
tester.binding.window.paddingTestValue = const FakeViewPadding(); final SemanticsUpdate update = SemanticsUpdateBuilder().build();
tester.binding.window.physicalSizeTestValue = const Size(505, 805); testWindow.updateSemantics(update);
tester.binding.window.systemGestureInsetsTestValue = const FakeViewPadding(); expect(fakeWindow.lastUpdate, update);
tester.binding.window.viewInsetsTestValue = const FakeViewPadding();
tester.binding.window.viewPaddingTestValue = const FakeViewPadding();
tester.binding.window.gestureSettingsTestValue = const GestureSettings(physicalTouchSlop: 4, physicalDoubleTapSlop: 5);
expect(tester.binding.window.devicePixelRatio, tester.view.devicePixelRatio);
expect(tester.binding.window.displayFeatures, tester.view.displayFeatures);
expect(tester.binding.window.padding, tester.view.padding);
expect(tester.binding.window.physicalSize, tester.view.physicalSize);
expect(tester.binding.window.systemGestureInsets, tester.view.systemGestureInsets);
expect(tester.binding.window.viewInsets, tester.view.viewInsets);
expect(tester.binding.window.viewPadding, tester.view.viewPadding);
expect(tester.binding.window.gestureSettings, tester.view.gestureSettings);
}); });
} }
void verifyThatTestWindowCanFakeProperty<WindowPropertyType>({
required WidgetTester tester,
required WindowPropertyType? realValue,
required WindowPropertyType fakeValue,
required WindowPropertyType? Function() propertyRetriever,
required Function(TestWidgetsFlutterBinding, WindowPropertyType fakeValue) propertyFaker,
}) {
WindowPropertyType? propertyBeforeFaking;
WindowPropertyType? propertyAfterFaking;
propertyBeforeFaking = propertyRetriever();
propertyFaker(retrieveTestBinding(tester), fakeValue);
propertyAfterFaking = propertyRetriever();
expect(propertyBeforeFaking, realValue);
expect(propertyAfterFaking, fakeValue);
}
TestWidgetsFlutterBinding retrieveTestBinding(WidgetTester tester) {
final WidgetsBinding binding = tester.binding;
assert(binding is TestWidgetsFlutterBinding);
final TestWidgetsFlutterBinding testBinding = binding as TestWidgetsFlutterBinding;
return testBinding;
}
class FakeViewPadding implements ViewPadding {
const FakeViewPadding({
this.left = 0.0,
this.top = 0.0,
this.right = 0.0,
this.bottom = 0.0,
});
@override
final double left;
@override
final double top;
@override
final double right;
@override
final double bottom;
}
class TestObserver with WidgetsBindingObserver { class TestObserver with WidgetsBindingObserver {
List<Locale>? locales; List<Locale>? locales;
Locale? locale; Locale? locale;
...@@ -247,3 +275,15 @@ class TestObserver with WidgetsBindingObserver { ...@@ -247,3 +275,15 @@ class TestObserver with WidgetsBindingObserver {
this.locales = locales; this.locales = locales;
} }
} }
class FakeSingletonWindow extends Fake implements SingletonFlutterWindow {
SemanticsUpdate? lastUpdate;
@override
PlatformDispatcher get platformDispatcher => PlatformDispatcher.instance;
@override
void updateSemantics(SemanticsUpdate update) {
lastUpdate = update;
}
}
...@@ -120,9 +120,9 @@ https://flutter.dev/docs/testing/integration-tests#testing-on-firebase-test-lab ...@@ -120,9 +120,9 @@ https://flutter.dev/docs/testing/integration-tests#testing-on-firebase-test-lab
ViewConfiguration createViewConfiguration() { ViewConfiguration createViewConfiguration() {
final double devicePixelRatio = window.devicePixelRatio; final double devicePixelRatio = window.devicePixelRatio;
final Size size = _surfaceSize ?? window.physicalSize / devicePixelRatio; final Size size = _surfaceSize ?? window.physicalSize / devicePixelRatio;
return TestViewConfiguration.fromView( return TestViewConfiguration(
size: size, size: size,
view: window, window: window,
); );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment