
Reverts flutter/flutter#131998 Reverting for https://github.com/flutter/flutter/issues/132222
449 lines
17 KiB
Dart
449 lines
17 KiB
Dart
// 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 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
import '../foundation/leak_tracking.dart';
|
|
|
|
void main() {
|
|
Finder findMenuPanels() {
|
|
return find.byWidgetPredicate((Widget widget) => widget.runtimeType.toString() == '_MenuPanel');
|
|
}
|
|
|
|
Material getMenuBarMaterial(WidgetTester tester) {
|
|
return tester.widget<Material>(
|
|
find.descendant(of: findMenuPanels(), matching: find.byType(Material)).first,
|
|
);
|
|
}
|
|
|
|
Padding getMenuBarPadding(WidgetTester tester) {
|
|
return tester.widget<Padding>(
|
|
find.descendant(of: findMenuPanels(), matching: find.byType(Padding)).first,
|
|
);
|
|
}
|
|
|
|
Material getMenuMaterial(WidgetTester tester) {
|
|
return tester.widget<Material>(
|
|
find.descendant(of: findMenuPanels().at(1), matching: find.byType(Material)).first,
|
|
);
|
|
}
|
|
|
|
Padding getMenuPadding(WidgetTester tester) {
|
|
return tester.widget<Padding>(
|
|
find.descendant(of: findMenuPanels().at(1), matching: find.byType(Padding)).first,
|
|
);
|
|
}
|
|
|
|
group('MenuStyle', () {
|
|
test('MenuStyle lerp special cases', () {
|
|
expect(MenuStyle.lerp(null, null, 0), null);
|
|
const MenuStyle data = MenuStyle();
|
|
expect(identical(MenuStyle.lerp(data, data, 0.5), data), true);
|
|
});
|
|
|
|
testWidgetsWithLeakTracking('fixedSize affects geometry', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Material(
|
|
child: Column(
|
|
children: <Widget>[
|
|
MenuBarTheme(
|
|
data: const MenuBarThemeData(
|
|
style: MenuStyle(
|
|
fixedSize: MaterialStatePropertyAll<Size>(Size(600, 60)),
|
|
),
|
|
),
|
|
child: MenuTheme(
|
|
data: const MenuThemeData(
|
|
style: MenuStyle(
|
|
fixedSize: MaterialStatePropertyAll<Size>(Size(100, 100)),
|
|
),
|
|
),
|
|
child: MenuBar(
|
|
children: createTestMenus(onPressed: (TestMenu menu) {}),
|
|
),
|
|
),
|
|
),
|
|
const Expanded(child: Placeholder()),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
// Have to open a menu initially to start things going.
|
|
await tester.tap(find.text(TestMenu.mainMenu0.label));
|
|
await tester.pump();
|
|
|
|
// MenuBarTheme affects MenuBar.
|
|
expect(tester.getRect(findMenuPanels().first), equals(const Rect.fromLTRB(100.0, 0.0, 700.0, 60.0)));
|
|
expect(tester.getRect(findMenuPanels().first).size, equals(const Size(600.0, 60.0)));
|
|
|
|
// MenuTheme affects menus.
|
|
expect(tester.getRect(findMenuPanels().at(1)), equals(const Rect.fromLTRB(104.0, 54.0, 204.0, 154.0)));
|
|
expect(tester.getRect(findMenuPanels().at(1)).size, equals(const Size(100.0, 100.0)));
|
|
});
|
|
|
|
testWidgetsWithLeakTracking('maximumSize affects geometry', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Material(
|
|
child: Column(
|
|
children: <Widget>[
|
|
MenuBarTheme(
|
|
data: const MenuBarThemeData(
|
|
style: MenuStyle(
|
|
maximumSize: MaterialStatePropertyAll<Size>(Size(250, 40)),
|
|
),
|
|
),
|
|
child: MenuTheme(
|
|
data: const MenuThemeData(
|
|
style: MenuStyle(
|
|
maximumSize: MaterialStatePropertyAll<Size>(Size(100, 100)),
|
|
),
|
|
),
|
|
child: MenuBar(
|
|
children: createTestMenus(onPressed: (TestMenu menu) {}),
|
|
),
|
|
),
|
|
),
|
|
const Expanded(child: Placeholder()),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
// Have to open a menu initially to start things going.
|
|
await tester.tap(find.text(TestMenu.mainMenu0.label));
|
|
await tester.pump();
|
|
|
|
// MenuBarTheme affects MenuBar.
|
|
expect(tester.getRect(findMenuPanels().first), equals(const Rect.fromLTRB(275.0, 0.0, 525.0, 40.0)));
|
|
expect(tester.getRect(findMenuPanels().first).size, equals(const Size(250.0, 40.0)));
|
|
|
|
// MenuTheme affects menus.
|
|
expect(tester.getRect(findMenuPanels().at(1)), equals(const Rect.fromLTRB(279.0, 44.0, 379.0, 144.0)));
|
|
expect(tester.getRect(findMenuPanels().at(1)).size, equals(const Size(100.0, 100.0)));
|
|
});
|
|
|
|
testWidgetsWithLeakTracking('minimumSize affects geometry', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Material(
|
|
child: Column(
|
|
children: <Widget>[
|
|
MenuBarTheme(
|
|
data: const MenuBarThemeData(
|
|
style: MenuStyle(
|
|
minimumSize: MaterialStatePropertyAll<Size>(Size(400, 60)),
|
|
),
|
|
),
|
|
child: MenuTheme(
|
|
data: const MenuThemeData(
|
|
style: MenuStyle(
|
|
minimumSize: MaterialStatePropertyAll<Size>(Size(300, 300)),
|
|
),
|
|
),
|
|
child: MenuBar(
|
|
children: createTestMenus(onPressed: (TestMenu menu) {}),
|
|
),
|
|
),
|
|
),
|
|
const Expanded(child: Placeholder()),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
// Have to open a menu initially to start things going.
|
|
await tester.tap(find.text(TestMenu.mainMenu0.label));
|
|
await tester.pump();
|
|
|
|
// MenuBarTheme affects MenuBar.
|
|
expect(tester.getRect(findMenuPanels().first), equals(const Rect.fromLTRB(200.0, 0.0, 600.0, 60.0)));
|
|
expect(tester.getRect(findMenuPanels().first).size, equals(const Size(400.0, 60.0)));
|
|
|
|
// MenuTheme affects menus.
|
|
expect(tester.getRect(findMenuPanels().at(1)), equals(const Rect.fromLTRB(204.0, 54.0, 504.0, 354.0)));
|
|
expect(tester.getRect(findMenuPanels().at(1)).size, equals(const Size(300.0, 300.0)));
|
|
});
|
|
|
|
testWidgetsWithLeakTracking('Material parameters are honored', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Material(
|
|
child: Column(
|
|
children: <Widget>[
|
|
MenuBarTheme(
|
|
data: const MenuBarThemeData(
|
|
style: MenuStyle(
|
|
backgroundColor: MaterialStatePropertyAll<Color>(Colors.red),
|
|
shadowColor: MaterialStatePropertyAll<Color>(Colors.green),
|
|
surfaceTintColor: MaterialStatePropertyAll<Color>(Colors.blue),
|
|
padding: MaterialStatePropertyAll<EdgeInsetsGeometry>(EdgeInsets.all(10)),
|
|
elevation: MaterialStatePropertyAll<double>(10),
|
|
side: MaterialStatePropertyAll<BorderSide>(BorderSide(color: Colors.redAccent)),
|
|
shape: MaterialStatePropertyAll<OutlinedBorder>(StadiumBorder()),
|
|
),
|
|
),
|
|
child: MenuTheme(
|
|
data: const MenuThemeData(
|
|
style: MenuStyle(
|
|
backgroundColor: MaterialStatePropertyAll<Color>(Colors.cyan),
|
|
shadowColor: MaterialStatePropertyAll<Color>(Colors.purple),
|
|
surfaceTintColor: MaterialStatePropertyAll<Color>(Colors.yellow),
|
|
padding: MaterialStatePropertyAll<EdgeInsetsGeometry>(EdgeInsets.all(20)),
|
|
elevation: MaterialStatePropertyAll<double>(20),
|
|
side: MaterialStatePropertyAll<BorderSide>(BorderSide(color: Colors.cyanAccent)),
|
|
shape: MaterialStatePropertyAll<OutlinedBorder>(StarBorder()),
|
|
),
|
|
),
|
|
child: MenuBar(
|
|
children: createTestMenus(onPressed: (TestMenu menu) {}),
|
|
),
|
|
),
|
|
),
|
|
const Expanded(child: Placeholder()),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
// Have to open a menu initially to start things going.
|
|
await tester.tap(find.text(TestMenu.mainMenu0.label));
|
|
await tester.pump();
|
|
|
|
final Material menuBarMaterial = getMenuBarMaterial(tester);
|
|
final Padding menuBarPadding = getMenuBarPadding(tester);
|
|
final Material panelMaterial = getMenuMaterial(tester);
|
|
final Padding panelPadding = getMenuPadding(tester);
|
|
|
|
// MenuBarTheme affects MenuBar.
|
|
expect(menuBarMaterial.color, equals(Colors.red));
|
|
expect(menuBarMaterial.shadowColor, equals(Colors.green));
|
|
expect(menuBarMaterial.surfaceTintColor, equals(Colors.blue));
|
|
expect(menuBarMaterial.shape, equals(const StadiumBorder(side: BorderSide(color: Colors.redAccent))));
|
|
expect(menuBarPadding.padding, equals(const EdgeInsets.all(10)));
|
|
|
|
// MenuBarTheme affects menus.
|
|
expect(panelMaterial.color, equals(Colors.cyan));
|
|
expect(panelMaterial.shadowColor, equals(Colors.purple));
|
|
expect(panelMaterial.surfaceTintColor, equals(Colors.yellow));
|
|
expect(panelMaterial.shape, equals(const StarBorder(side: BorderSide(color: Colors.cyanAccent))));
|
|
expect(panelPadding.padding, equals(const EdgeInsets.all(20)));
|
|
});
|
|
|
|
testWidgetsWithLeakTracking('visual density', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: ThemeData(useMaterial3: false),
|
|
home: Material(
|
|
child: Column(
|
|
children: <Widget>[
|
|
MenuBarTheme(
|
|
data: const MenuBarThemeData(
|
|
style: MenuStyle(
|
|
visualDensity: VisualDensity(horizontal: 1.5, vertical: -1.5),
|
|
),
|
|
),
|
|
child: MenuTheme(
|
|
data: const MenuThemeData(
|
|
style: MenuStyle(
|
|
visualDensity: VisualDensity(horizontal: 0.5, vertical: -0.5),
|
|
),
|
|
),
|
|
child: MenuBar(
|
|
children: createTestMenus(onPressed: (TestMenu menu) {}),
|
|
),
|
|
),
|
|
),
|
|
const Expanded(child: Placeholder()),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
await tester.pump();
|
|
|
|
expect(tester.getRect(find.byType(MenuBar)), equals(const Rect.fromLTRB(228.0, 0.0, 572.0, 48.0)));
|
|
|
|
// Open and make sure things are the right size.
|
|
await tester.tap(find.text(TestMenu.mainMenu1.label));
|
|
await tester.pump();
|
|
|
|
expect(tester.getRect(find.byType(MenuBar)), equals(const Rect.fromLTRB(228.0, 0.0, 572.0, 48.0)));
|
|
expect(
|
|
tester.getRect(find.text(TestMenu.subMenu10.label)),
|
|
equals(const Rect.fromLTRB(366.0, 68.0, 520.0, 82.0)),
|
|
);
|
|
expect(
|
|
tester.getRect(find.ancestor(of: find.text(TestMenu.subMenu10.label), matching: find.byType(Material)).at(1)),
|
|
equals(const Rect.fromLTRB(346.0, 48.0, 579.0, 186.0)),
|
|
);
|
|
});
|
|
});
|
|
}
|
|
|
|
List<Widget> createTestMenus({
|
|
void Function(TestMenu)? onPressed,
|
|
void Function(TestMenu)? onOpen,
|
|
void Function(TestMenu)? onClose,
|
|
Map<TestMenu, MenuSerializableShortcut> shortcuts = const <TestMenu, MenuSerializableShortcut>{},
|
|
bool includeStandard = false,
|
|
bool includeExtraGroups = false,
|
|
}) {
|
|
final List<Widget> result = <Widget>[
|
|
SubmenuButton(
|
|
onOpen: onOpen != null ? () => onOpen(TestMenu.mainMenu0) : null,
|
|
onClose: onClose != null ? () => onClose(TestMenu.mainMenu0) : null,
|
|
menuChildren: <Widget>[
|
|
MenuItemButton(
|
|
onPressed: onPressed != null ? () => onPressed(TestMenu.subMenu00) : null,
|
|
shortcut: shortcuts[TestMenu.subMenu00],
|
|
child: Text(TestMenu.subMenu00.label),
|
|
),
|
|
MenuItemButton(
|
|
onPressed: onPressed != null ? () => onPressed(TestMenu.subMenu01) : null,
|
|
shortcut: shortcuts[TestMenu.subMenu01],
|
|
child: Text(TestMenu.subMenu01.label),
|
|
),
|
|
MenuItemButton(
|
|
onPressed: onPressed != null ? () => onPressed(TestMenu.subMenu02) : null,
|
|
shortcut: shortcuts[TestMenu.subMenu02],
|
|
child: Text(TestMenu.subMenu02.label),
|
|
),
|
|
],
|
|
child: Text(TestMenu.mainMenu0.label),
|
|
),
|
|
SubmenuButton(
|
|
onOpen: onOpen != null ? () => onOpen(TestMenu.mainMenu1) : null,
|
|
onClose: onClose != null ? () => onClose(TestMenu.mainMenu1) : null,
|
|
menuChildren: <Widget>[
|
|
MenuItemButton(
|
|
onPressed: onPressed != null ? () => onPressed(TestMenu.subMenu10) : null,
|
|
shortcut: shortcuts[TestMenu.subMenu10],
|
|
child: Text(TestMenu.subMenu10.label),
|
|
),
|
|
SubmenuButton(
|
|
onOpen: onOpen != null ? () => onOpen(TestMenu.subMenu11) : null,
|
|
onClose: onClose != null ? () => onClose(TestMenu.subMenu11) : null,
|
|
menuChildren: <Widget>[
|
|
MenuItemButton(
|
|
key: UniqueKey(),
|
|
onPressed: onPressed != null ? () => onPressed(TestMenu.subSubMenu110) : null,
|
|
shortcut: shortcuts[TestMenu.subSubMenu110],
|
|
child: Text(TestMenu.subSubMenu110.label),
|
|
),
|
|
MenuItemButton(
|
|
onPressed: onPressed != null ? () => onPressed(TestMenu.subSubMenu111) : null,
|
|
shortcut: shortcuts[TestMenu.subSubMenu111],
|
|
child: Text(TestMenu.subSubMenu111.label),
|
|
),
|
|
MenuItemButton(
|
|
onPressed: onPressed != null ? () => onPressed(TestMenu.subSubMenu112) : null,
|
|
shortcut: shortcuts[TestMenu.subSubMenu112],
|
|
child: Text(TestMenu.subSubMenu112.label),
|
|
),
|
|
MenuItemButton(
|
|
onPressed: onPressed != null ? () => onPressed(TestMenu.subSubMenu113) : null,
|
|
shortcut: shortcuts[TestMenu.subSubMenu113],
|
|
child: Text(TestMenu.subSubMenu113.label),
|
|
),
|
|
],
|
|
child: Text(TestMenu.subMenu11.label),
|
|
),
|
|
MenuItemButton(
|
|
onPressed: onPressed != null ? () => onPressed(TestMenu.subMenu12) : null,
|
|
shortcut: shortcuts[TestMenu.subMenu12],
|
|
child: Text(TestMenu.subMenu12.label),
|
|
),
|
|
],
|
|
child: Text(TestMenu.mainMenu1.label),
|
|
),
|
|
SubmenuButton(
|
|
onOpen: onOpen != null ? () => onOpen(TestMenu.mainMenu2) : null,
|
|
onClose: onClose != null ? () => onClose(TestMenu.mainMenu2) : null,
|
|
menuChildren: <Widget>[
|
|
MenuItemButton(
|
|
// Always disabled.
|
|
shortcut: shortcuts[TestMenu.subMenu20],
|
|
child: Text(TestMenu.subMenu20.label),
|
|
),
|
|
],
|
|
child: Text(TestMenu.mainMenu2.label),
|
|
),
|
|
if (includeExtraGroups)
|
|
SubmenuButton(
|
|
onOpen: onOpen != null ? () => onOpen(TestMenu.mainMenu3) : null,
|
|
onClose: onClose != null ? () => onClose(TestMenu.mainMenu3) : null,
|
|
menuChildren: <Widget>[
|
|
MenuItemButton(
|
|
// Always disabled.
|
|
shortcut: shortcuts[TestMenu.subMenu30],
|
|
// Always disabled.
|
|
child: Text(TestMenu.subMenu30.label),
|
|
),
|
|
],
|
|
child: Text(TestMenu.mainMenu3.label),
|
|
),
|
|
if (includeExtraGroups)
|
|
SubmenuButton(
|
|
onOpen: onOpen != null ? () => onOpen(TestMenu.mainMenu4) : null,
|
|
onClose: onClose != null ? () => onClose(TestMenu.mainMenu4) : null,
|
|
menuChildren: <Widget>[
|
|
MenuItemButton(
|
|
// Always disabled.
|
|
shortcut: shortcuts[TestMenu.subMenu40],
|
|
// Always disabled.
|
|
child: Text(TestMenu.subMenu40.label),
|
|
),
|
|
MenuItemButton(
|
|
// Always disabled.
|
|
shortcut: shortcuts[TestMenu.subMenu41],
|
|
// Always disabled.
|
|
child: Text(TestMenu.subMenu41.label),
|
|
),
|
|
MenuItemButton(
|
|
// Always disabled.
|
|
shortcut: shortcuts[TestMenu.subMenu42],
|
|
// Always disabled.
|
|
child: Text(TestMenu.subMenu42.label),
|
|
),
|
|
],
|
|
child: Text(TestMenu.mainMenu4.label),
|
|
),
|
|
];
|
|
return result;
|
|
}
|
|
|
|
enum TestMenu {
|
|
mainMenu0('Menu 0'),
|
|
mainMenu1('Menu 1'),
|
|
mainMenu2('Menu 2'),
|
|
mainMenu3('Menu 3'),
|
|
mainMenu4('Menu 4'),
|
|
subMenu00('Sub Menu 00'),
|
|
subMenu01('Sub Menu 01'),
|
|
subMenu02('Sub Menu 02'),
|
|
subMenu10('Sub Menu 10'),
|
|
subMenu11('Sub Menu 11'),
|
|
subMenu12('Sub Menu 12'),
|
|
subMenu20('Sub Menu 20'),
|
|
subMenu30('Sub Menu 30'),
|
|
subMenu40('Sub Menu 40'),
|
|
subMenu41('Sub Menu 41'),
|
|
subMenu42('Sub Menu 42'),
|
|
subSubMenu110('Sub Sub Menu 110'),
|
|
subSubMenu111('Sub Sub Menu 111'),
|
|
subSubMenu112('Sub Sub Menu 112'),
|
|
subSubMenu113('Sub Sub Menu 113');
|
|
|
|
const TestMenu(this.label);
|
|
final String label;
|
|
}
|