| // Copyright 2016 The Chromium 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 'package:flutter_test/flutter_test.dart'; |
| import 'package:flutter/widgets.dart'; |
| |
| void main() { |
| testWidgets('OverflowEntries context contains Overlay', (WidgetTester tester) async { |
| final GlobalKey overlayKey = GlobalKey(); |
| bool didBuild = false; |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: Overlay( |
| key: overlayKey, |
| initialEntries: <OverlayEntry>[ |
| OverlayEntry( |
| builder: (BuildContext context) { |
| didBuild = true; |
| final Overlay overlay = context.ancestorWidgetOfExactType(Overlay); |
| expect(overlay, isNotNull); |
| expect(overlay.key, equals(overlayKey)); |
| return Container(); |
| }, |
| ), |
| ], |
| ), |
| ), |
| ); |
| expect(didBuild, isTrue); |
| final RenderObject theater = overlayKey.currentContext.findRenderObject(); |
| |
| expect(theater, hasAGoodToStringDeep); |
| expect( |
| theater.toStringDeep(minLevel: DiagnosticLevel.info), |
| equalsIgnoringHashCodes( |
| '_RenderTheatre#f5cf2\n' |
| ' │ parentData: <none>\n' |
| ' │ constraints: BoxConstraints(w=800.0, h=600.0)\n' |
| ' │ size: Size(800.0, 600.0)\n' |
| ' │\n' |
| ' ├─onstage: RenderStack#39819\n' |
| ' ╎ │ parentData: not positioned; offset=Offset(0.0, 0.0) (can use\n' |
| ' ╎ │ size)\n' |
| ' ╎ │ constraints: BoxConstraints(w=800.0, h=600.0)\n' |
| ' ╎ │ size: Size(800.0, 600.0)\n' |
| ' ╎ │ alignment: AlignmentDirectional.topStart\n' |
| ' ╎ │ textDirection: ltr\n' |
| ' ╎ │ fit: expand\n' |
| ' ╎ │ overflow: clip\n' |
| ' ╎ │\n' |
| ' ╎ └─child 1: RenderLimitedBox#d1448\n' |
| ' ╎ │ parentData: not positioned; offset=Offset(0.0, 0.0) (can use\n' |
| ' ╎ │ size)\n' |
| ' ╎ │ constraints: BoxConstraints(w=800.0, h=600.0)\n' |
| ' ╎ │ size: Size(800.0, 600.0)\n' |
| ' ╎ │ maxWidth: 0.0\n' |
| ' ╎ │ maxHeight: 0.0\n' |
| ' ╎ │\n' |
| ' ╎ └─child: RenderConstrainedBox#e8b87\n' |
| ' ╎ parentData: <none> (can use size)\n' |
| ' ╎ constraints: BoxConstraints(w=800.0, h=600.0)\n' |
| ' ╎ size: Size(800.0, 600.0)\n' |
| ' ╎ additionalConstraints: BoxConstraints(biggest)\n' |
| ' ╎\n' |
| ' └╌no offstage children\n' |
| ), |
| ); |
| }); |
| |
| testWidgets('Offstage overlay', (WidgetTester tester) async { |
| final GlobalKey overlayKey = GlobalKey(); |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: Overlay( |
| key: overlayKey, |
| initialEntries: <OverlayEntry>[ |
| OverlayEntry( |
| opaque: true, |
| maintainState: true, |
| builder: (BuildContext context) => Container(), |
| ), |
| OverlayEntry( |
| opaque: true, |
| maintainState: true, |
| builder: (BuildContext context) => Container(), |
| ), |
| OverlayEntry( |
| opaque: true, |
| maintainState: true, |
| builder: (BuildContext context) => Container(), |
| ), |
| ], |
| ), |
| ), |
| ); |
| final RenderObject theater = overlayKey.currentContext.findRenderObject(); |
| |
| expect(theater, hasAGoodToStringDeep); |
| expect( |
| theater.toStringDeep(minLevel: DiagnosticLevel.info), |
| equalsIgnoringHashCodes( |
| '_RenderTheatre#b22a8\n' |
| ' │ parentData: <none>\n' |
| ' │ constraints: BoxConstraints(w=800.0, h=600.0)\n' |
| ' │ size: Size(800.0, 600.0)\n' |
| ' │\n' |
| ' ├─onstage: RenderStack#eab87\n' |
| ' ╎ │ parentData: not positioned; offset=Offset(0.0, 0.0) (can use\n' |
| ' ╎ │ size)\n' |
| ' ╎ │ constraints: BoxConstraints(w=800.0, h=600.0)\n' |
| ' ╎ │ size: Size(800.0, 600.0)\n' |
| ' ╎ │ alignment: AlignmentDirectional.topStart\n' |
| ' ╎ │ textDirection: ltr\n' |
| ' ╎ │ fit: expand\n' |
| ' ╎ │ overflow: clip\n' |
| ' ╎ │\n' |
| ' ╎ └─child 1: RenderLimitedBox#ca15b\n' |
| ' ╎ │ parentData: not positioned; offset=Offset(0.0, 0.0) (can use\n' |
| ' ╎ │ size)\n' |
| ' ╎ │ constraints: BoxConstraints(w=800.0, h=600.0)\n' |
| ' ╎ │ size: Size(800.0, 600.0)\n' |
| ' ╎ │ maxWidth: 0.0\n' |
| ' ╎ │ maxHeight: 0.0\n' |
| ' ╎ │\n' |
| ' ╎ └─child: RenderConstrainedBox#dffe5\n' |
| ' ╎ parentData: <none> (can use size)\n' |
| ' ╎ constraints: BoxConstraints(w=800.0, h=600.0)\n' |
| ' ╎ size: Size(800.0, 600.0)\n' |
| ' ╎ additionalConstraints: BoxConstraints(biggest)\n' |
| ' ╎\n' |
| ' ╎╌offstage 1: RenderLimitedBox#b6f09 NEEDS-LAYOUT NEEDS-PAINT\n' |
| ' ╎ │ parentData: not positioned; offset=Offset(0.0, 0.0)\n' |
| ' ╎ │ constraints: MISSING\n' |
| ' ╎ │ size: MISSING\n' |
| ' ╎ │ maxWidth: 0.0\n' |
| ' ╎ │ maxHeight: 0.0\n' |
| ' ╎ │\n' |
| ' ╎ └─child: RenderConstrainedBox#5a057 NEEDS-LAYOUT NEEDS-PAINT\n' |
| ' ╎ parentData: <none>\n' |
| ' ╎ constraints: MISSING\n' |
| ' ╎ size: MISSING\n' |
| ' ╎ additionalConstraints: BoxConstraints(biggest)\n' |
| ' ╎\n' |
| ' └╌offstage 2: RenderLimitedBox#f689e NEEDS-LAYOUT NEEDS-PAINT\n' |
| ' │ parentData: not positioned; offset=Offset(0.0, 0.0)\n' |
| ' │ constraints: MISSING\n' |
| ' │ size: MISSING\n' |
| ' │ maxWidth: 0.0\n' |
| ' │ maxHeight: 0.0\n' |
| ' │\n' |
| ' └─child: RenderConstrainedBox#c15f0 NEEDS-LAYOUT NEEDS-PAINT\n' |
| ' parentData: <none>\n' |
| ' constraints: MISSING\n' |
| ' size: MISSING\n' |
| ' additionalConstraints: BoxConstraints(biggest)\n' |
| ), |
| ); |
| }); |
| |
| testWidgets('insert top', (WidgetTester tester) async { |
| final GlobalKey overlayKey = GlobalKey(); |
| final List<String> buildOrder = <String>[]; |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: Overlay( |
| key: overlayKey, |
| initialEntries: <OverlayEntry>[ |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add('Base'); |
| return Container(); |
| }, |
| ), |
| ], |
| ), |
| ), |
| ); |
| |
| expect(buildOrder, <String>['Base']); |
| |
| buildOrder.clear(); |
| final OverlayState overlay = overlayKey.currentState; |
| overlay.insert( |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add('New'); |
| return Container(); |
| } |
| ), |
| ); |
| await tester.pump(); |
| |
| expect(buildOrder, <String>['Base', 'New']); |
| }); |
| |
| testWidgets('insert below', (WidgetTester tester) async { |
| final GlobalKey overlayKey = GlobalKey(); |
| OverlayEntry base; |
| final List<String> buildOrder = <String>[]; |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: Overlay( |
| key: overlayKey, |
| initialEntries: <OverlayEntry>[ |
| base = OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add('Base'); |
| return Container(); |
| }, |
| ), |
| ], |
| ), |
| ), |
| ); |
| |
| expect(buildOrder, <String>['Base']); |
| |
| buildOrder.clear(); |
| final OverlayState overlay = overlayKey.currentState; |
| overlay.insert( |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add('New'); |
| return Container(); |
| } |
| ), |
| below: base, |
| ); |
| await tester.pump(); |
| |
| expect(buildOrder, <String>['New', 'Base']); |
| }); |
| |
| testWidgets('insert above', (WidgetTester tester) async { |
| final GlobalKey overlayKey = GlobalKey(); |
| OverlayEntry base; |
| final List<String> buildOrder = <String>[]; |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: Overlay( |
| key: overlayKey, |
| initialEntries: <OverlayEntry>[ |
| base = OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add('Base'); |
| return Container(); |
| }, |
| ), |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add('Top'); |
| return Container(); |
| }, |
| ), |
| ], |
| ), |
| ), |
| ); |
| |
| expect(buildOrder, <String>['Base', 'Top']); |
| |
| buildOrder.clear(); |
| final OverlayState overlay = overlayKey.currentState; |
| overlay.insert( |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add('New'); |
| return Container(); |
| } |
| ), |
| above: base, |
| ); |
| await tester.pump(); |
| |
| expect(buildOrder, <String>['Base', 'New', 'Top']); |
| }); |
| |
| testWidgets('insertAll top', (WidgetTester tester) async { |
| final GlobalKey overlayKey = GlobalKey(); |
| final List<String> buildOrder = <String>[]; |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: Overlay( |
| key: overlayKey, |
| initialEntries: <OverlayEntry>[ |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add('Base'); |
| return Container(); |
| }, |
| ), |
| ], |
| ), |
| ), |
| ); |
| |
| expect(buildOrder, <String>['Base']); |
| |
| final List<OverlayEntry> entries = <OverlayEntry>[ |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add('New1'); |
| return Container(); |
| }, |
| ), |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add('New2'); |
| return Container(); |
| }, |
| ), |
| ]; |
| |
| buildOrder.clear(); |
| final OverlayState overlay = overlayKey.currentState; |
| overlay.insertAll(entries); |
| await tester.pump(); |
| |
| expect(buildOrder, <String>['Base', 'New1', 'New2']); |
| }); |
| |
| testWidgets('insertAll below', (WidgetTester tester) async { |
| final GlobalKey overlayKey = GlobalKey(); |
| OverlayEntry base; |
| final List<String> buildOrder = <String>[]; |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: Overlay( |
| key: overlayKey, |
| initialEntries: <OverlayEntry>[ |
| base = OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add('Base'); |
| return Container(); |
| }, |
| ), |
| ], |
| ), |
| ), |
| ); |
| |
| expect(buildOrder, <String>['Base']); |
| |
| final List<OverlayEntry> entries = <OverlayEntry>[ |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add('New1'); |
| return Container(); |
| }, |
| ), |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add('New2'); |
| return Container(); |
| }, |
| ), |
| ]; |
| |
| buildOrder.clear(); |
| final OverlayState overlay = overlayKey.currentState; |
| overlay.insertAll(entries, below: base); |
| await tester.pump(); |
| |
| expect(buildOrder, <String>['New1', 'New2','Base']); |
| }); |
| |
| testWidgets('insertAll above', (WidgetTester tester) async { |
| final GlobalKey overlayKey = GlobalKey(); |
| final List<String> buildOrder = <String>[]; |
| OverlayEntry base; |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: Overlay( |
| key: overlayKey, |
| initialEntries: <OverlayEntry>[ |
| base = OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add('Base'); |
| return Container(); |
| }, |
| ), |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add('Top'); |
| return Container(); |
| }, |
| ), |
| ], |
| ), |
| ), |
| ); |
| |
| expect(buildOrder, <String>['Base', 'Top']); |
| |
| final List<OverlayEntry> entries = <OverlayEntry>[ |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add('New1'); |
| return Container(); |
| }, |
| ), |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add('New2'); |
| return Container(); |
| }, |
| ), |
| ]; |
| |
| buildOrder.clear(); |
| final OverlayState overlay = overlayKey.currentState; |
| overlay.insertAll(entries, above: base); |
| await tester.pump(); |
| |
| expect(buildOrder, <String>['Base', 'New1', 'New2', 'Top']); |
| }); |
| |
| testWidgets('rearrange', (WidgetTester tester) async { |
| final GlobalKey overlayKey = GlobalKey(); |
| final List<int> buildOrder = <int>[]; |
| final List<OverlayEntry> initialEntries = <OverlayEntry>[ |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add(0); |
| return Container(); |
| }, |
| ), |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add(1); |
| return Container(); |
| }, |
| ), |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add(2); |
| return Container(); |
| }, |
| ), |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add(3); |
| return Container(); |
| }, |
| ), |
| ]; |
| |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: Overlay( |
| key: overlayKey, |
| initialEntries: initialEntries, |
| ), |
| ), |
| ); |
| |
| expect(buildOrder, <int>[0, 1, 2, 3]); |
| |
| final List<OverlayEntry> rearranged = <OverlayEntry>[ |
| initialEntries[3], |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add(4); |
| return Container(); |
| }, |
| ), |
| initialEntries[2], |
| // 1 intentionally missing, will end up on top |
| initialEntries[0], |
| ]; |
| |
| buildOrder.clear(); |
| final OverlayState overlay = overlayKey.currentState; |
| overlay.rearrange(rearranged); |
| await tester.pump(); |
| |
| expect(buildOrder, <int>[3, 4, 2, 0, 1]); |
| }); |
| |
| testWidgets('rearrange above', (WidgetTester tester) async { |
| final GlobalKey overlayKey = GlobalKey(); |
| final List<int> buildOrder = <int>[]; |
| final List<OverlayEntry> initialEntries = <OverlayEntry>[ |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add(0); |
| return Container(); |
| }, |
| ), |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add(1); |
| return Container(); |
| }, |
| ), |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add(2); |
| return Container(); |
| }, |
| ), |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add(3); |
| return Container(); |
| }, |
| ), |
| ]; |
| |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: Overlay( |
| key: overlayKey, |
| initialEntries: initialEntries, |
| ), |
| ), |
| ); |
| |
| expect(buildOrder, <int>[0, 1, 2, 3]); |
| |
| final List<OverlayEntry> rearranged = <OverlayEntry>[ |
| initialEntries[3], |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add(4); |
| return Container(); |
| }, |
| ), |
| initialEntries[2], |
| // 1 intentionally missing |
| initialEntries[0], |
| ]; |
| |
| buildOrder.clear(); |
| final OverlayState overlay = overlayKey.currentState; |
| overlay.rearrange(rearranged, above: initialEntries[2]); |
| await tester.pump(); |
| |
| expect(buildOrder, <int>[3, 4, 2, 1, 0]); |
| }); |
| |
| testWidgets('rearrange below', (WidgetTester tester) async { |
| final GlobalKey overlayKey = GlobalKey(); |
| final List<int> buildOrder = <int>[]; |
| final List<OverlayEntry> initialEntries = <OverlayEntry>[ |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add(0); |
| return Container(); |
| }, |
| ), |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add(1); |
| return Container(); |
| }, |
| ), |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add(2); |
| return Container(); |
| }, |
| ), |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add(3); |
| return Container(); |
| }, |
| ), |
| ]; |
| |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: Overlay( |
| key: overlayKey, |
| initialEntries: initialEntries, |
| ), |
| ), |
| ); |
| |
| expect(buildOrder, <int>[0, 1, 2, 3]); |
| |
| final List<OverlayEntry> rearranged = <OverlayEntry>[ |
| initialEntries[3], |
| OverlayEntry( |
| builder: (BuildContext context) { |
| buildOrder.add(4); |
| return Container(); |
| }, |
| ), |
| initialEntries[2], |
| // 1 intentionally missing |
| initialEntries[0], |
| ]; |
| |
| buildOrder.clear(); |
| final OverlayState overlay = overlayKey.currentState; |
| overlay.rearrange(rearranged, below: initialEntries[2]); |
| await tester.pump(); |
| |
| expect(buildOrder, <int>[3, 4, 1, 2, 0]); |
| }); |
| } |