Skip to content

Commit 98fb56f

Browse files
authored
Remove reference to MaterialApp and showCupertinoModalPopup from CupertinoAlertDialog (flutter#150725)
This PR removes the usage of Material widgets from unit tests of `CupertinoAlertDialog`. Other than it being just wrong, it also introduces bad behavior, such as the scroll view can't be overscrolled so that the overscroll behavior can't be tested. * Since there are no longer M2 or M3 variants of tests, I straight up rewrote the unit tests for "default look" with similar tests as those of `CupertinoActionSheet` ([here](https://github.com/flutter/flutter/blob/master/packages/flutter/test/cupertino/action_sheet_test.dart#L21)) This PR also replaces `showCupertinoModalPopup` with `showCupertinoDialog` in `CupertinoAlertDialog`'s example code. The former should only be used by `CupertinoActionSheet`, which has a different animation from the correct `showCupertinoDialog`.
1 parent a6a8caa commit 98fb56f

File tree

2 files changed

+138
-97
lines changed

2 files changed

+138
-97
lines changed

examples/api/lib/cupertino/dialog/cupertino_alert_dialog.0.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@ class AlertDialogApp extends StatelessWidget {
2323
class AlertDialogExample extends StatelessWidget {
2424
const AlertDialogExample({super.key});
2525

26-
// This shows a CupertinoModalPopup which hosts a CupertinoAlertDialog.
2726
void _showAlertDialog(BuildContext context) {
28-
showCupertinoModalPopup<void>(
27+
showCupertinoDialog<void>(
2928
context: context,
3029
builder: (BuildContext context) => CupertinoAlertDialog(
3130
title: const Text('Alert'),

packages/flutter/test/cupertino/dialog_test.dart

Lines changed: 137 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,69 @@ import 'package:flutter_test/flutter_test.dart';
1919
import '../widgets/semantics_tester.dart';
2020

2121
void main() {
22+
testWidgets('Overall appearance is correct for the light theme', (WidgetTester tester) async {
23+
await tester.pumpWidget(
24+
TestScaffoldApp(
25+
theme: const CupertinoThemeData(brightness: Brightness.light),
26+
dialog: CupertinoAlertDialog(
27+
content: const Text('The content'),
28+
actions: <Widget>[
29+
CupertinoDialogAction(child: const Text('One'), onPressed: () {}),
30+
CupertinoDialogAction(child: const Text('Two'), onPressed: () {}),
31+
],
32+
),
33+
),
34+
);
35+
36+
await tester.tap(find.text('Go'));
37+
await tester.pumpAndSettle();
38+
39+
final TestGesture gesture = await tester.startGesture(tester.getCenter(find.text('One')));
40+
await tester.pumpAndSettle();
41+
// This golden file also verifies the structure of an alert dialog that
42+
// has a content, no title, and no overscroll for any sections (in contrast
43+
// to cupertinoAlertDialog.dark-theme.png).
44+
await expectLater(
45+
find.byType(CupertinoApp),
46+
matchesGoldenFile('cupertinoAlertDialog.overall-light-theme.png'),
47+
);
48+
49+
await gesture.up();
50+
});
51+
52+
testWidgets('Overall appearance is correct for the dark theme', (WidgetTester tester) async {
53+
await tester.pumpWidget(
54+
TestScaffoldApp(
55+
theme: const CupertinoThemeData(brightness: Brightness.dark),
56+
dialog: CupertinoAlertDialog(
57+
title: const Text('The title'),
58+
content: const Text('The content'),
59+
actions: List<Widget>.generate(20, (int i) =>
60+
CupertinoDialogAction(
61+
onPressed: () {},
62+
child: Text('Button $i'),
63+
),
64+
),
65+
),
66+
),
67+
);
68+
69+
await tester.tap(find.text('Go'));
70+
await tester.pumpAndSettle();
71+
72+
final TestGesture gesture = await tester.startGesture(tester.getCenter(find.text('Button 0')));
73+
await tester.pumpAndSettle();
74+
// This golden file also verifies the structure of an action sheet that
75+
// has both a message and a title, and an overscrolled action section (in
76+
// contrast to cupertinoAlertDialog.light-theme.png).
77+
await expectLater(
78+
find.byType(CupertinoApp),
79+
matchesGoldenFile('cupertinoAlertDialog.overall-dark-theme.png'),
80+
);
81+
82+
await gesture.up();
83+
});
84+
2285
testWidgets('Alert dialog control test', (WidgetTester tester) async {
2386
bool didDelete = false;
2487

@@ -181,16 +244,16 @@ void main() {
181244

182245
testWidgets('Has semantic annotations', (WidgetTester tester) async {
183246
final SemanticsTester semantics = SemanticsTester(tester);
184-
await tester.pumpWidget(const MaterialApp(home: Material(
185-
child: CupertinoAlertDialog(
247+
await tester.pumpWidget(const CupertinoApp(
248+
home: CupertinoAlertDialog(
186249
title: Text('The Title'),
187250
content: Text('Content'),
188251
actions: <Widget>[
189252
CupertinoDialogAction(child: Text('Cancel')),
190253
CupertinoDialogAction(child: Text('OK')),
191254
],
192255
),
193-
)));
256+
));
194257

195258
expect(
196259
semantics,
@@ -506,7 +569,7 @@ void main() {
506569

507570
// Check that the title/message section is not displayed
508571
expect(actionScrollController.offset, 0.0);
509-
expect(tester.getTopLeft(find.widgetWithText(CupertinoDialogAction, 'One')).dy, equals(277.5));
572+
expect(tester.getTopLeft(find.widgetWithText(CupertinoDialogAction, 'One')).dy, equals(270.75));
510573

511574
// Check that the button's vertical size is the same.
512575
expect(
@@ -1160,7 +1223,7 @@ void main() {
11601223

11611224
testWidgets('Dialog widget insets by MediaQuery viewInsets', (WidgetTester tester) async {
11621225
await tester.pumpWidget(
1163-
const MaterialApp(
1226+
const CupertinoApp(
11641227
home: MediaQuery(
11651228
data: MediaQueryData(),
11661229
child: CupertinoAlertDialog(content: Placeholder(fallbackHeight: 200.0)),
@@ -1171,7 +1234,7 @@ void main() {
11711234
final Rect placeholderRectWithoutInsets = tester.getRect(find.byType(Placeholder));
11721235

11731236
await tester.pumpWidget(
1174-
const MaterialApp(
1237+
const CupertinoApp(
11751238
home: MediaQuery(
11761239
data: MediaQueryData(viewInsets: EdgeInsets.fromLTRB(40.0, 30.0, 20.0, 10.0)),
11771240
child: CupertinoAlertDialog(content: Placeholder(fallbackHeight: 200.0)),
@@ -1188,70 +1251,6 @@ void main() {
11881251
expect(tester.getRect(find.byType(Placeholder)), placeholderRectWithoutInsets.translate(10, 10));
11891252
});
11901253

1191-
testWidgets('Material2 - Default cupertino dialog golden', (WidgetTester tester) async {
1192-
await tester.pumpWidget(
1193-
createAppWithButtonThatLaunchesDialog(
1194-
useMaterial3: false,
1195-
dialogBuilder: (BuildContext context) {
1196-
return MediaQuery.withClampedTextScaling(
1197-
minScaleFactor: 3.0,
1198-
maxScaleFactor: 3.0,
1199-
child: const RepaintBoundary(
1200-
child: CupertinoAlertDialog(
1201-
title: Text('Title'),
1202-
content: Text('text'),
1203-
actions: <Widget>[
1204-
CupertinoDialogAction(child: Text('No')),
1205-
CupertinoDialogAction(child: Text('OK')),
1206-
],
1207-
),
1208-
),
1209-
);
1210-
},
1211-
),
1212-
);
1213-
1214-
await tester.tap(find.text('Go'));
1215-
await tester.pumpAndSettle();
1216-
1217-
await expectLater(
1218-
find.byType(CupertinoAlertDialog),
1219-
matchesGoldenFile('m2_dialog_test.cupertino.default.png'),
1220-
);
1221-
});
1222-
1223-
testWidgets('Material3 - Default cupertino dialog golden', (WidgetTester tester) async {
1224-
await tester.pumpWidget(
1225-
createAppWithButtonThatLaunchesDialog(
1226-
useMaterial3: true,
1227-
dialogBuilder: (BuildContext context) {
1228-
return MediaQuery.withClampedTextScaling(
1229-
minScaleFactor: 3.0,
1230-
maxScaleFactor: 3.0,
1231-
child: const RepaintBoundary(
1232-
child: CupertinoAlertDialog(
1233-
title: Text('Title'),
1234-
content: Text('text'),
1235-
actions: <Widget>[
1236-
CupertinoDialogAction(child: Text('No')),
1237-
CupertinoDialogAction(child: Text('OK')),
1238-
],
1239-
),
1240-
),
1241-
);
1242-
},
1243-
),
1244-
);
1245-
1246-
await tester.tap(find.text('Go'));
1247-
await tester.pumpAndSettle();
1248-
1249-
await expectLater(
1250-
find.byType(CupertinoAlertDialog),
1251-
matchesGoldenFile('m3_dialog_test.cupertino.default.png'),
1252-
);
1253-
});
1254-
12551254
testWidgets('showCupertinoDialog - custom barrierLabel', (WidgetTester tester) async {
12561255
final SemanticsTester semantics = SemanticsTester(tester);
12571256

@@ -1363,7 +1362,7 @@ void main() {
13631362
testWidgets('CupertinoAlertDialog scrollbars controllers should be different', (WidgetTester tester) async {
13641363
// https://github.com/flutter/flutter/pull/81278
13651364
await tester.pumpWidget(
1366-
const MaterialApp(
1365+
const CupertinoApp(
13671366
home: MediaQuery(
13681367
data: MediaQueryData(),
13691368
child: CupertinoAlertDialog(
@@ -1565,24 +1564,20 @@ RenderBox findScrollableActionsSectionRenderBox(WidgetTester tester) {
15651564

15661565
Widget createAppWithButtonThatLaunchesDialog({
15671566
required WidgetBuilder dialogBuilder,
1568-
bool? useMaterial3,
15691567
}) {
1570-
return MaterialApp(
1571-
theme: ThemeData(useMaterial3: useMaterial3),
1572-
home: Material(
1573-
child: Center(
1574-
child: Builder(builder: (BuildContext context) {
1575-
return ElevatedButton(
1576-
onPressed: () {
1577-
showDialog<void>(
1578-
context: context,
1579-
builder: dialogBuilder,
1580-
);
1581-
},
1582-
child: const Text('Go'),
1583-
);
1584-
}),
1585-
),
1568+
return CupertinoApp(
1569+
home: Center(
1570+
child: Builder(builder: (BuildContext context) {
1571+
return CupertinoButton(
1572+
onPressed: () {
1573+
showCupertinoDialog<void>(
1574+
context: context,
1575+
builder: dialogBuilder,
1576+
);
1577+
},
1578+
child: const Text('Go'),
1579+
);
1580+
}),
15861581
),
15871582
);
15881583
}
@@ -1595,13 +1590,11 @@ Widget boilerplate(Widget child) {
15951590
}
15961591

15971592
Widget createAppWithCenteredButton(Widget child) {
1598-
return MaterialApp(
1599-
home: Material(
1600-
child: Center(
1601-
child: ElevatedButton(
1602-
onPressed: null,
1603-
child: child,
1604-
),
1593+
return CupertinoApp(
1594+
home: Center(
1595+
child: CupertinoButton(
1596+
onPressed: null,
1597+
child: child,
16051598
),
16061599
),
16071600
);
@@ -1643,3 +1636,52 @@ class _RestorableDialogTestWidget extends StatelessWidget {
16431636
);
16441637
}
16451638
}
1639+
1640+
// Shows an app that has a button with text "Go", and clicking this button
1641+
// displays the `dialog` and hides the button.
1642+
//
1643+
// The `theme` will be applied to the app and determines the background.
1644+
class TestScaffoldApp extends StatefulWidget {
1645+
const TestScaffoldApp({super.key, required this.theme, required this.dialog});
1646+
final CupertinoThemeData theme;
1647+
final Widget dialog;
1648+
1649+
@override
1650+
TestScaffoldAppState createState() => TestScaffoldAppState();
1651+
}
1652+
1653+
class TestScaffoldAppState extends State<TestScaffoldApp> {
1654+
bool _pressedButton = false;
1655+
1656+
@override
1657+
Widget build(BuildContext context) {
1658+
return CupertinoApp(
1659+
// Hide the debug banner. Because this CupertinoApp is captured in golden
1660+
// test as a whole. The debug banner contains tilted text, whose
1661+
// anti-alias might cause false negative result.
1662+
// https://github.com/flutter/flutter/pull/150442
1663+
debugShowCheckedModeBanner: false,
1664+
theme: widget.theme,
1665+
home: Builder(builder: (BuildContext context) =>
1666+
CupertinoPageScaffold(
1667+
child: Center(
1668+
child: _pressedButton ? Container() : CupertinoButton(
1669+
onPressed: () {
1670+
setState(() {
1671+
_pressedButton = true;
1672+
});
1673+
showCupertinoDialog<void>(
1674+
context: context,
1675+
builder: (BuildContext context) {
1676+
return widget.dialog;
1677+
},
1678+
);
1679+
},
1680+
child: const Text('Go'),
1681+
),
1682+
),
1683+
),
1684+
),
1685+
);
1686+
}
1687+
}

0 commit comments

Comments
 (0)