Unverified Commit 3c8700c2 authored by Taha Tesser's avatar Taha Tesser Committed by GitHub

Update `Tooltip` tests for Material 3 (#139145)

Updated unit tests for `Tooltip` to have M2 and M3 versions.

More info in #139076
parent 2f95a5a3
...@@ -30,9 +30,8 @@ void main() { ...@@ -30,9 +30,8 @@ void main() {
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Directionality( MaterialApp(
textDirection: TextDirection.ltr, home: Overlay(
child: Overlay(
initialEntries: <OverlayEntry>[ initialEntries: <OverlayEntry>[
entry = OverlayEntry( entry = OverlayEntry(
builder: (BuildContext context) { builder: (BuildContext context) {
...@@ -87,9 +86,8 @@ void main() { ...@@ -87,9 +86,8 @@ void main() {
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Directionality( MaterialApp(
textDirection: TextDirection.ltr, home: Padding(
child: Padding(
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
child: Overlay( child: Overlay(
initialEntries: <OverlayEntry>[ initialEntries: <OverlayEntry>[
...@@ -143,41 +141,38 @@ void main() { ...@@ -143,41 +141,38 @@ void main() {
expect(tipInGlobal.dy, 40.0); expect(tipInGlobal.dy, 40.0);
}); });
testWidgetsWithLeakTracking('Does tooltip end up in the right place - top left', (WidgetTester tester) async { testWidgetsWithLeakTracking('Material2 - Does tooltip end up in the right place - top left', (WidgetTester tester) async {
final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>(); final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>();
late final OverlayEntry entry; late final OverlayEntry entry;
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Theme( MaterialApp(
data: ThemeData(useMaterial3: false), theme: ThemeData(useMaterial3: false),
child: Directionality( home: Overlay(
textDirection: TextDirection.ltr, initialEntries: <OverlayEntry>[
child: Overlay( entry = OverlayEntry(
initialEntries: <OverlayEntry>[ builder: (BuildContext context) {
entry = OverlayEntry( return Stack(
builder: (BuildContext context) { children: <Widget>[
return Stack( Positioned(
children: <Widget>[ left: 0.0,
Positioned( top: 0.0,
left: 0.0, child: Tooltip(
top: 0.0, key: tooltipKey,
child: Tooltip( message: tooltipText,
key: tooltipKey, height: 20.0,
message: tooltipText, padding: const EdgeInsets.all(5.0),
height: 20.0, verticalOffset: 20.0,
padding: const EdgeInsets.all(5.0), preferBelow: false,
verticalOffset: 20.0, child: const SizedBox.shrink(),
preferBelow: false,
child: const SizedBox.shrink(),
),
), ),
], ),
); ],
}, );
), },
], ),
), ],
), ),
), ),
); );
...@@ -198,7 +193,60 @@ void main() { ...@@ -198,7 +193,60 @@ void main() {
); );
expect(tip.size.height, equals(24.0)); // 14.0 height + 5.0 padding * 2 (top, bottom) expect(tip.size.height, equals(24.0)); // 14.0 height + 5.0 padding * 2 (top, bottom)
expect(tip.localToGlobal(tip.size.topLeft(Offset.zero)), equals(const Offset(10.0, 20.0))); expect(tip.localToGlobal(tip.size.topLeft(Offset.zero)), equals(const Offset(10.0, 20.0)));
}); }, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/99933
testWidgetsWithLeakTracking('Material3 - Does tooltip end up in the right place - top left', (WidgetTester tester) async {
final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>();
late final OverlayEntry entry;
addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget(
MaterialApp(
home: Overlay(
initialEntries: <OverlayEntry>[
entry = OverlayEntry(
builder: (BuildContext context) {
return Stack(
children: <Widget>[
Positioned(
left: 0.0,
top: 0.0,
child: Tooltip(
key: tooltipKey,
message: tooltipText,
height: 20.0,
padding: const EdgeInsets.all(5.0),
verticalOffset: 20.0,
preferBelow: false,
child: const SizedBox.shrink(),
),
),
],
);
},
),
],
),
),
);
tooltipKey.currentState?.ensureTooltipVisible();
await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0)
/********************* 800x600 screen
*o * y=0
*| * }- 20.0 vertical offset, of which 10.0 is in the screen edge margin
*+----+ * \- (5.0 padding in height)
*| | * |- 20 height
*+----+ * /- (5.0 padding in height)
* *
*********************/
final RenderBox tip = tester.renderObject(
_findTooltipContainer(tooltipText),
);
expect(tip.size.height, equals(30.0)); // 20.0 height + 5.0 padding * 2 (top, bottom)
expect(tip.localToGlobal(tip.size.topLeft(Offset.zero)), equals(const Offset(10.0, 20.0)));
}, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/99933
testWidgetsWithLeakTracking('Does tooltip end up in the right place - center prefer above fits', (WidgetTester tester) async { testWidgetsWithLeakTracking('Does tooltip end up in the right place - center prefer above fits', (WidgetTester tester) async {
final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>(); final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>();
...@@ -206,9 +254,8 @@ void main() { ...@@ -206,9 +254,8 @@ void main() {
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Directionality( MaterialApp(
textDirection: TextDirection.ltr, home: Overlay(
child: Overlay(
initialEntries: <OverlayEntry>[ initialEntries: <OverlayEntry>[
entry = OverlayEntry( entry = OverlayEntry(
builder: (BuildContext context) { builder: (BuildContext context) {
...@@ -262,9 +309,8 @@ void main() { ...@@ -262,9 +309,8 @@ void main() {
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Directionality( MaterialApp(
textDirection: TextDirection.ltr, home: Overlay(
child: Overlay(
initialEntries: <OverlayEntry>[ initialEntries: <OverlayEntry>[
entry = OverlayEntry( entry = OverlayEntry(
builder: (BuildContext context) { builder: (BuildContext context) {
...@@ -329,9 +375,8 @@ void main() { ...@@ -329,9 +375,8 @@ void main() {
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Directionality( MaterialApp(
textDirection: TextDirection.ltr, home: Overlay(
child: Overlay(
initialEntries: <OverlayEntry>[ initialEntries: <OverlayEntry>[
entry = OverlayEntry( entry = OverlayEntry(
builder: (BuildContext context) { builder: (BuildContext context) {
...@@ -378,41 +423,38 @@ void main() { ...@@ -378,41 +423,38 @@ void main() {
expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dy, equals(590.0)); expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dy, equals(590.0));
}); });
testWidgetsWithLeakTracking('Does tooltip end up in the right place - way off to the right', (WidgetTester tester) async { testWidgetsWithLeakTracking('Material2 - Does tooltip end up in the right place - way off to the right', (WidgetTester tester) async {
final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>(); final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>();
late final OverlayEntry entry; late final OverlayEntry entry;
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Theme( MaterialApp(
data: ThemeData(useMaterial3: false), theme: ThemeData(useMaterial3: false),
child: Directionality( home: Overlay(
textDirection: TextDirection.ltr, initialEntries: <OverlayEntry>[
child: Overlay( entry = OverlayEntry(
initialEntries: <OverlayEntry>[ builder: (BuildContext context) {
entry = OverlayEntry( return Stack(
builder: (BuildContext context) { children: <Widget>[
return Stack( Positioned(
children: <Widget>[ left: 1600.0,
Positioned( top: 300.0,
left: 1600.0, child: Tooltip(
top: 300.0, key: tooltipKey,
child: Tooltip( message: tooltipText,
key: tooltipKey, height: 10.0,
message: tooltipText, padding: EdgeInsets.zero,
height: 10.0, verticalOffset: 10.0,
padding: EdgeInsets.zero, preferBelow: true,
verticalOffset: 10.0, child: const SizedBox.shrink(),
preferBelow: true,
child: const SizedBox.shrink(),
),
), ),
], ),
); ],
}, );
), },
], ),
), ],
), ),
), ),
); );
...@@ -438,41 +480,94 @@ void main() { ...@@ -438,41 +480,94 @@ void main() {
expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dy, equals(324.0)); expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dy, equals(324.0));
}); });
testWidgetsWithLeakTracking('Does tooltip end up in the right place - near the edge', (WidgetTester tester) async { testWidgetsWithLeakTracking('Material3 - Does tooltip end up in the right place - way off to the right', (WidgetTester tester) async {
final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>(); final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>();
late final OverlayEntry entry; late final OverlayEntry entry;
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Theme( MaterialApp(
data: ThemeData(useMaterial3: false), home: Overlay(
child: Directionality( initialEntries: <OverlayEntry>[
textDirection: TextDirection.ltr, entry = OverlayEntry(
child: Overlay( builder: (BuildContext context) {
initialEntries: <OverlayEntry>[ return Stack(
entry = OverlayEntry( children: <Widget>[
builder: (BuildContext context) { Positioned(
return Stack( left: 1600.0,
children: <Widget>[ top: 300.0,
Positioned( child: Tooltip(
left: 780.0, key: tooltipKey,
top: 300.0, message: tooltipText,
child: Tooltip( height: 10.0,
key: tooltipKey, padding: EdgeInsets.zero,
message: tooltipText, verticalOffset: 10.0,
height: 10.0, preferBelow: true,
padding: EdgeInsets.zero, child: const SizedBox.shrink(),
verticalOffset: 10.0,
preferBelow: true,
child: const SizedBox.shrink(),
),
), ),
], ),
); ],
}, );
), },
], ),
), ],
),
),
);
tooltipKey.currentState?.ensureTooltipVisible();
await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0)
/********************* 800x600 screen
* *
* *
* * y=300.0; target --> o
* ___| * }-10.0 vertical offset
* |___| * }-10.0 height
* *
* * }-10.0 margin
*********************/
final RenderBox tip = tester.renderObject(
_findTooltipContainer(tooltipText),
);
expect(tip.size.height, equals(20.0));
expect(tip.localToGlobal(tip.size.topLeft(Offset.zero)).dy, equals(310.0));
expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dx, equals(790.0));
expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dy, equals(330.0));
}, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/99933
testWidgetsWithLeakTracking('Material2 - Does tooltip end up in the right place - near the edge', (WidgetTester tester) async {
final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>();
late final OverlayEntry entry;
addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(useMaterial3: false),
home: Overlay(
initialEntries: <OverlayEntry>[
entry = OverlayEntry(
builder: (BuildContext context) {
return Stack(
children: <Widget>[
Positioned(
left: 780.0,
top: 300.0,
child: Tooltip(
key: tooltipKey,
message: tooltipText,
height: 10.0,
padding: EdgeInsets.zero,
verticalOffset: 10.0,
preferBelow: true,
child: const SizedBox.shrink(),
),
),
],
);
},
),
],
), ),
), ),
); );
...@@ -498,6 +593,62 @@ void main() { ...@@ -498,6 +593,62 @@ void main() {
expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dy, equals(324.0)); expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dy, equals(324.0));
}); });
testWidgetsWithLeakTracking('Material3 - Does tooltip end up in the right place - near the edge', (WidgetTester tester) async {
final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>();
late final OverlayEntry entry;
addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget(
MaterialApp(
home: Overlay(
initialEntries: <OverlayEntry>[
entry = OverlayEntry(
builder: (BuildContext context) {
return Stack(
children: <Widget>[
Positioned(
left: 780.0,
top: 300.0,
child: Tooltip(
key: tooltipKey,
message: tooltipText,
height: 10.0,
padding: EdgeInsets.zero,
verticalOffset: 10.0,
preferBelow: true,
child: const SizedBox.shrink(),
),
),
],
);
},
),
],
),
),
);
tooltipKey.currentState?.ensureTooltipVisible();
await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0)
/********************* 800x600 screen
* *
* *
* o * y=300.0
* __| * }-10.0 vertical offset
* |___| * }-10.0 height
* *
* * }-10.0 margin
*********************/
final RenderBox tip = tester.renderObject(
_findTooltipContainer(tooltipText),
);
expect(tip.size.height, equals(20.0));
expect(tip.localToGlobal(tip.size.topLeft(Offset.zero)).dy, equals(310.0));
expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dx, equals(790.0));
expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dy, equals(330.0));
}, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/99933
testWidgetsWithLeakTracking('Tooltip should be fully visible when MediaQuery.viewInsets > 0', (WidgetTester tester) async { testWidgetsWithLeakTracking('Tooltip should be fully visible when MediaQuery.viewInsets > 0', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/23666 // Regression test for https://github.com/flutter/flutter/issues/23666
Widget materialAppWithViewInsets(double viewInsetsHeight) { Widget materialAppWithViewInsets(double viewInsetsHeight) {
...@@ -560,9 +711,8 @@ void main() { ...@@ -560,9 +711,8 @@ void main() {
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Directionality( MaterialApp(
textDirection: TextDirection.ltr, home: Overlay(
child: Overlay(
initialEntries: <OverlayEntry>[ initialEntries: <OverlayEntry>[
entry = OverlayEntry( entry = OverlayEntry(
builder: (BuildContext context) { builder: (BuildContext context) {
...@@ -611,7 +761,7 @@ void main() { ...@@ -611,7 +761,7 @@ void main() {
expect(bottomRightTooltipContentInGlobal.dy, bottomRightTipInGlobal.dy - customMarginValue); expect(bottomRightTooltipContentInGlobal.dy, bottomRightTipInGlobal.dy - customMarginValue);
}); });
testWidgetsWithLeakTracking('Default tooltip message textStyle - light', (WidgetTester tester) async { testWidgetsWithLeakTracking('Material2 - Default tooltip message textStyle - light', (WidgetTester tester) async {
final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>(); final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>();
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
theme: ThemeData(useMaterial3: false), theme: ThemeData(useMaterial3: false),
...@@ -635,7 +785,33 @@ void main() { ...@@ -635,7 +785,33 @@ void main() {
expect(textStyle.debugLabel, '((englishLike bodyMedium 2014).merge(blackMountainView bodyMedium)).copyWith'); expect(textStyle.debugLabel, '((englishLike bodyMedium 2014).merge(blackMountainView bodyMedium)).copyWith');
}); });
testWidgetsWithLeakTracking('Default tooltip message textStyle - dark', (WidgetTester tester) async { testWidgetsWithLeakTracking('Material3 - Default tooltip message textStyle - light', (WidgetTester tester) async {
final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>();
await tester.pumpWidget(MaterialApp(
home: Tooltip(
key: tooltipKey,
message: tooltipText,
child: Container(
width: 100.0,
height: 100.0,
color: Colors.green[500],
),
),
));
tooltipKey.currentState?.ensureTooltipVisible();
await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0)
final TextStyle textStyle = tester.widget<Text>(find.text(tooltipText)).style!;
expect(textStyle.color, Colors.white);
expect(textStyle.fontFamily, 'Roboto');
expect(textStyle.decoration, TextDecoration.none);
expect(
textStyle.debugLabel,
'((englishLike bodyMedium 2021).merge((blackMountainView bodyMedium).apply)).copyWith',
);
});
testWidgetsWithLeakTracking('Material2 - Default tooltip message textStyle - dark', (WidgetTester tester) async {
final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>(); final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>();
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
theme: ThemeData( theme: ThemeData(
...@@ -662,6 +838,30 @@ void main() { ...@@ -662,6 +838,30 @@ void main() {
expect(textStyle.debugLabel, '((englishLike bodyMedium 2014).merge(whiteMountainView bodyMedium)).copyWith'); expect(textStyle.debugLabel, '((englishLike bodyMedium 2014).merge(whiteMountainView bodyMedium)).copyWith');
}); });
testWidgetsWithLeakTracking('Material3 - Default tooltip message textStyle - dark', (WidgetTester tester) async {
final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>();
await tester.pumpWidget(MaterialApp(
theme: ThemeData(brightness: Brightness.dark),
home: Tooltip(
key: tooltipKey,
message: tooltipText,
child: Container(
width: 100.0,
height: 100.0,
color: Colors.green[500],
),
),
));
tooltipKey.currentState?.ensureTooltipVisible();
await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0)
final TextStyle textStyle = tester.widget<Text>(find.text(tooltipText)).style!;
expect(textStyle.color, Colors.black);
expect(textStyle.fontFamily, 'Roboto');
expect(textStyle.decoration, TextDecoration.none);
expect(textStyle.debugLabel, '((englishLike bodyMedium 2021).merge((whiteMountainView bodyMedium).apply)).copyWith');
});
testWidgetsWithLeakTracking('Custom tooltip message textStyle', (WidgetTester tester) async { testWidgetsWithLeakTracking('Custom tooltip message textStyle', (WidgetTester tester) async {
final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>(); final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>();
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
...@@ -793,29 +993,26 @@ void main() { ...@@ -793,29 +993,26 @@ void main() {
expect(textStyle.decorationStyle, isNot(TextDecorationStyle.double)); expect(textStyle.decorationStyle, isNot(TextDecorationStyle.double));
}); });
testWidgetsWithLeakTracking('Does tooltip end up with the right default size, shape, and color', (WidgetTester tester) async { testWidgetsWithLeakTracking('Material2 - Does tooltip end up with the right default size, shape, and color', (WidgetTester tester) async {
final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>(); final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>();
late final OverlayEntry entry; late final OverlayEntry entry;
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Theme( MaterialApp(
data: ThemeData(useMaterial3: false), theme: ThemeData(useMaterial3: false),
child: Directionality( home: Overlay(
textDirection: TextDirection.ltr, initialEntries: <OverlayEntry>[
child: Overlay( entry = OverlayEntry(
initialEntries: <OverlayEntry>[ builder: (BuildContext context) {
entry = OverlayEntry( return Tooltip(
builder: (BuildContext context) { key: tooltipKey,
return Tooltip( message: tooltipText,
key: tooltipKey, child: const SizedBox.shrink(),
message: tooltipText, );
child: const SizedBox.shrink(), },
); ),
}, ],
),
],
),
), ),
), ),
); );
...@@ -834,7 +1031,44 @@ void main() { ...@@ -834,7 +1031,44 @@ void main() {
expect(tooltipContainer.padding, const EdgeInsets.symmetric(horizontal: 16.0, vertical: 4.0)); expect(tooltipContainer.padding, const EdgeInsets.symmetric(horizontal: 16.0, vertical: 4.0));
}); });
testWidgetsWithLeakTracking('Tooltip default size, shape, and color test for Desktop', (WidgetTester tester) async { testWidgetsWithLeakTracking('Material3 - Does tooltip end up with the right default size, shape, and color', (WidgetTester tester) async {
final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>();
late final OverlayEntry entry;
addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget(
MaterialApp(
home: Overlay(
initialEntries: <OverlayEntry>[
entry = OverlayEntry(
builder: (BuildContext context) {
return Tooltip(
key: tooltipKey,
message: tooltipText,
child: const SizedBox.shrink(),
);
},
),
],
),
),
);
tooltipKey.currentState?.ensureTooltipVisible();
await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0)
final RenderBox tip = tester.renderObject(_findTooltipContainer(tooltipText));
expect(tip.size.height, equals(32.0));
expect(tip.size.width, equals(74.75));
expect(tip, paints..rrect(
rrect: RRect.fromRectAndRadius(tip.paintBounds, const Radius.circular(4.0)),
color: const Color(0xe6616161),
));
final Container tooltipContainer = tester.firstWidget<Container>(_findTooltipContainer(tooltipText));
expect(tooltipContainer.padding, const EdgeInsets.symmetric(horizontal: 16.0, vertical: 4.0));
});
testWidgetsWithLeakTracking('Material2 - Tooltip default size, shape, and color test for Desktop', (WidgetTester tester) async {
// Regressing test for https://github.com/flutter/flutter/issues/68601 // Regressing test for https://github.com/flutter/flutter/issues/68601
final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>(); final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>();
await tester.pumpWidget( await tester.pumpWidget(
...@@ -864,7 +1098,38 @@ void main() { ...@@ -864,7 +1098,38 @@ void main() {
expect(tooltipContainer.padding, const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0)); expect(tooltipContainer.padding, const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0));
}, variant: const TargetPlatformVariant(<TargetPlatform>{TargetPlatform.macOS, TargetPlatform.linux, TargetPlatform.windows})); }, variant: const TargetPlatformVariant(<TargetPlatform>{TargetPlatform.macOS, TargetPlatform.linux, TargetPlatform.windows}));
testWidgetsWithLeakTracking('Can tooltip decoration be customized', (WidgetTester tester) async { testWidgetsWithLeakTracking('Material3 - Tooltip default size, shape, and color test for Desktop', (WidgetTester tester) async {
// Regressing test for https://github.com/flutter/flutter/issues/68601
final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>();
await tester.pumpWidget(
MaterialApp(
home: Tooltip(
key: tooltipKey,
message: tooltipText,
child: const SizedBox.shrink(),
),
),
);
tooltipKey.currentState?.ensureTooltipVisible();
await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0)
final RenderParagraph tooltipRenderParagraph = tester.renderObject<RenderParagraph>(find.text(tooltipText));
expect(tooltipRenderParagraph.textSize.height, equals(17.0));
final RenderBox tooltipRenderBox = tester.renderObject(_findTooltipContainer(tooltipText));
expect(tooltipRenderBox.size.height, equals(25.0));
expect(tooltipRenderBox, paints..rrect(
rrect: RRect.fromRectAndRadius(tooltipRenderBox.paintBounds, const Radius.circular(4.0)),
color: const Color(0xe6616161),
));
final Container tooltipContainer = tester.firstWidget<Container>(_findTooltipContainer(tooltipText));
expect(tooltipContainer.padding, const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0));
}, variant: const TargetPlatformVariant(<TargetPlatform>{TargetPlatform.macOS, TargetPlatform.linux, TargetPlatform.windows}),
skip: kIsWeb && !isCanvasKit, // https://github.com/flutter/flutter/issues/99933
);
testWidgetsWithLeakTracking('Material2 - Can tooltip decoration be customized', (WidgetTester tester) async {
final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>(); final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>();
const Decoration customDecoration = ShapeDecoration( const Decoration customDecoration = ShapeDecoration(
shape: StadiumBorder(), shape: StadiumBorder(),
...@@ -874,24 +1139,21 @@ void main() { ...@@ -874,24 +1139,21 @@ void main() {
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Theme( MaterialApp(
data: ThemeData(useMaterial3: false), theme: ThemeData(useMaterial3: false),
child: Directionality( home: Overlay(
textDirection: TextDirection.ltr, initialEntries: <OverlayEntry>[
child: Overlay( entry = OverlayEntry(
initialEntries: <OverlayEntry>[ builder: (BuildContext context) {
entry = OverlayEntry( return Tooltip(
builder: (BuildContext context) { key: tooltipKey,
return Tooltip( decoration: customDecoration,
key: tooltipKey, message: tooltipText,
decoration: customDecoration, child: const SizedBox.shrink(),
message: tooltipText, );
child: const SizedBox.shrink(), },
); ),
}, ],
),
],
),
), ),
), ),
); );
...@@ -906,6 +1168,44 @@ void main() { ...@@ -906,6 +1168,44 @@ void main() {
expect(tip, paints..rrect(color: const Color(0x80800000))); expect(tip, paints..rrect(color: const Color(0x80800000)));
}); });
testWidgetsWithLeakTracking('Material3 - Can tooltip decoration be customized', (WidgetTester tester) async {
final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>();
const Decoration customDecoration = ShapeDecoration(
shape: StadiumBorder(),
color: Color(0x80800000),
);
late final OverlayEntry entry;
addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget(
MaterialApp(
home: Overlay(
initialEntries: <OverlayEntry>[
entry = OverlayEntry(
builder: (BuildContext context) {
return Tooltip(
key: tooltipKey,
decoration: customDecoration,
message: tooltipText,
child: const SizedBox.shrink(),
);
},
),
],
),
),
);
tooltipKey.currentState?.ensureTooltipVisible();
await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0)
final RenderBox tip = tester.renderObject(
_findTooltipContainer(tooltipText),
);
expect(tip.size.height, equals(32.0));
expect(tip.size.width, equals(74.75));
expect(tip, paints..rrect(color: const Color(0x80800000)));
});
testWidgetsWithLeakTracking('Tooltip stays after long press', (WidgetTester tester) async { testWidgetsWithLeakTracking('Tooltip stays after long press', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -1577,11 +1877,11 @@ void main() { ...@@ -1577,11 +1877,11 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgetsWithLeakTracking('Tooltip text scales with textScaleFactor', (WidgetTester tester) async { testWidgetsWithLeakTracking('Material2 - Tooltip text scales with textScaleFactor', (WidgetTester tester) async {
Widget buildApp(String text, { required double textScaleFactor }) { Widget buildApp(String text, { required double textScaleFactor }) {
return Theme( return MaterialApp(
data: ThemeData(useMaterial3: false), theme: ThemeData(useMaterial3: false),
child: MediaQuery( home: MediaQuery(
data: MediaQueryData(textScaleFactor: textScaleFactor), data: MediaQueryData(textScaleFactor: textScaleFactor),
child: Directionality( child: Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -1627,6 +1927,54 @@ void main() { ...@@ -1627,6 +1927,54 @@ void main() {
expect(tip.size.height, equals(64.0)); expect(tip.size.height, equals(64.0));
}); });
testWidgetsWithLeakTracking('Material3 - Tooltip text scales with textScaleFactor', (WidgetTester tester) async {
Widget buildApp(String text, { required double textScaleFactor }) {
return MaterialApp(
home: MediaQuery(
data: MediaQueryData(textScaleFactor: textScaleFactor),
child: Navigator(
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute<void>(
builder: (BuildContext context) {
return Center(
child: Tooltip(
message: text,
child: Container(
width: 100.0,
height: 100.0,
color: Colors.green[500],
),
),
);
},
);
},
),
),
);
}
await tester.pumpWidget(buildApp(tooltipText, textScaleFactor: 1.0));
await tester.longPress(find.byType(Tooltip));
expect(find.text(tooltipText), findsOneWidget);
expect(tester.getSize(find.text(tooltipText)).width, equals(42.75));
expect(tester.getSize(find.text(tooltipText)).height, equals(20.0));
RenderBox tip = tester.renderObject(
_findTooltipContainer(tooltipText),
);
expect(tip.size.height, equals(32.0));
await tester.pumpWidget(buildApp(tooltipText, textScaleFactor: 4.0));
await tester.longPress(find.byType(Tooltip));
expect(find.text(tooltipText), findsOneWidget);
expect(tester.getSize(find.text(tooltipText)).width, equals(168.75));
expect(tester.getSize(find.text(tooltipText)).height, equals(80.0));
tip = tester.renderObject(
_findTooltipContainer(tooltipText),
);
expect(tip.size.height, equals(88.0));
}, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/99933
testWidgetsWithLeakTracking('Tooltip text displays with richMessage', (WidgetTester tester) async { testWidgetsWithLeakTracking('Tooltip text displays with richMessage', (WidgetTester tester) async {
final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>(); final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>();
const String textSpan1Text = 'I am a rich tooltip message. '; const String textSpan1Text = 'I am a rich tooltip message. ';
......
...@@ -100,38 +100,35 @@ void main() { ...@@ -100,38 +100,35 @@ void main() {
late final OverlayEntry entry; late final OverlayEntry entry;
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Directionality( MaterialApp(
textDirection: TextDirection.ltr, theme: ThemeData(
child: Theme( tooltipTheme: const TooltipThemeData(
data: ThemeData( height: 100.0,
tooltipTheme: const TooltipThemeData( padding: EdgeInsets.zero,
height: 100.0, verticalOffset: 100.0,
padding: EdgeInsets.zero, preferBelow: false,
verticalOffset: 100.0,
preferBelow: false,
),
), ),
child: Overlay( ),
initialEntries: <OverlayEntry>[ home: Overlay(
entry = OverlayEntry( initialEntries: <OverlayEntry>[
builder: (BuildContext context) { entry = OverlayEntry(
return Stack( builder: (BuildContext context) {
children: <Widget>[ return Stack(
Positioned( children: <Widget>[
left: 400.0, Positioned(
top: 300.0, left: 400.0,
child: Tooltip( top: 300.0,
key: key, child: Tooltip(
message: tooltipText, key: key,
child: const SizedBox.shrink(), message: tooltipText,
), child: const SizedBox.shrink(),
), ),
], ),
); ],
}, );
), },
], ),
), ],
), ),
), ),
); );
...@@ -161,9 +158,8 @@ void main() { ...@@ -161,9 +158,8 @@ void main() {
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Directionality( MaterialApp(
textDirection: TextDirection.ltr, home: TooltipTheme(
child: TooltipTheme(
data: const TooltipThemeData( data: const TooltipThemeData(
height: 100.0, height: 100.0,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
...@@ -219,38 +215,35 @@ void main() { ...@@ -219,38 +215,35 @@ void main() {
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Directionality( MaterialApp(
textDirection: TextDirection.ltr, theme: ThemeData(
child: Theme( tooltipTheme: const TooltipThemeData(
data: ThemeData( height: 190.0,
tooltipTheme: const TooltipThemeData( padding: EdgeInsets.zero,
height: 190.0, verticalOffset: 100.0,
padding: EdgeInsets.zero, preferBelow: false,
verticalOffset: 100.0,
preferBelow: false,
),
), ),
child: Overlay( ),
initialEntries: <OverlayEntry>[ home: Overlay(
entry = OverlayEntry( initialEntries: <OverlayEntry>[
builder: (BuildContext context) { entry = OverlayEntry(
return Stack( builder: (BuildContext context) {
children: <Widget>[ return Stack(
Positioned( children: <Widget>[
left: 400.0, Positioned(
top: 299.0, left: 400.0,
child: Tooltip( top: 299.0,
key: key, child: Tooltip(
message: tooltipText, key: key,
child: const SizedBox.shrink(), message: tooltipText,
), child: const SizedBox.shrink(),
), ),
], ),
); ],
}, );
), },
], ),
), ],
), ),
), ),
); );
...@@ -291,9 +284,8 @@ void main() { ...@@ -291,9 +284,8 @@ void main() {
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Directionality( MaterialApp(
textDirection: TextDirection.ltr, home: TooltipTheme(
child: TooltipTheme(
data: const TooltipThemeData( data: const TooltipThemeData(
height: 190.0, height: 190.0,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
...@@ -359,38 +351,35 @@ void main() { ...@@ -359,38 +351,35 @@ void main() {
late final OverlayEntry entry; late final OverlayEntry entry;
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Directionality( MaterialApp(
textDirection: TextDirection.ltr, theme: ThemeData(
child: Theme( tooltipTheme: const TooltipThemeData(
data: ThemeData( height: 190.0,
tooltipTheme: const TooltipThemeData( padding: EdgeInsets.zero,
height: 190.0, verticalOffset: 100.0,
padding: EdgeInsets.zero, preferBelow: true,
verticalOffset: 100.0,
preferBelow: true,
),
), ),
child: Overlay( ),
initialEntries: <OverlayEntry>[ home: Overlay(
entry = OverlayEntry( initialEntries: <OverlayEntry>[
builder: (BuildContext context) { entry = OverlayEntry(
return Stack( builder: (BuildContext context) {
children: <Widget>[ return Stack(
Positioned( children: <Widget>[
left: 400.0, Positioned(
top: 300.0, left: 400.0,
child: Tooltip( top: 300.0,
key: key, child: Tooltip(
message: tooltipText, key: key,
child: const SizedBox.shrink(), message: tooltipText,
), child: const SizedBox.shrink(),
), ),
], ),
); ],
}, );
), },
], ),
), ],
), ),
), ),
); );
...@@ -419,9 +408,8 @@ void main() { ...@@ -419,9 +408,8 @@ void main() {
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Directionality( MaterialApp(
textDirection: TextDirection.ltr, home: TooltipTheme(
child: TooltipTheme(
data: const TooltipThemeData( data: const TooltipThemeData(
height: 190.0, height: 190.0,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
...@@ -477,9 +465,8 @@ void main() { ...@@ -477,9 +465,8 @@ void main() {
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Directionality( MaterialApp(
textDirection: TextDirection.ltr, home: Overlay(
child: Overlay(
initialEntries: <OverlayEntry>[ initialEntries: <OverlayEntry>[
entry = OverlayEntry( entry = OverlayEntry(
builder: (BuildContext context) { builder: (BuildContext context) {
...@@ -535,9 +522,8 @@ void main() { ...@@ -535,9 +522,8 @@ void main() {
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Directionality( MaterialApp(
textDirection: TextDirection.ltr, home: Overlay(
child: Overlay(
initialEntries: <OverlayEntry>[ initialEntries: <OverlayEntry>[
entry = OverlayEntry( entry = OverlayEntry(
builder: (BuildContext context) { builder: (BuildContext context) {
...@@ -683,7 +669,7 @@ void main() { ...@@ -683,7 +669,7 @@ void main() {
expect(textAlign, TextAlign.end); expect(textAlign, TextAlign.end);
}); });
testWidgetsWithLeakTracking('Tooltip decoration - ThemeData.tooltipTheme', (WidgetTester tester) async { testWidgetsWithLeakTracking('Material2 - Tooltip decoration - ThemeData.tooltipTheme', (WidgetTester tester) async {
final GlobalKey<TooltipState> key = GlobalKey<TooltipState>(); final GlobalKey<TooltipState> key = GlobalKey<TooltipState>();
const Decoration customDecoration = ShapeDecoration( const Decoration customDecoration = ShapeDecoration(
shape: StadiumBorder(), shape: StadiumBorder(),
...@@ -692,15 +678,93 @@ void main() { ...@@ -692,15 +678,93 @@ void main() {
late final OverlayEntry entry; late final OverlayEntry entry;
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Directionality( MaterialApp(
textDirection: TextDirection.ltr, theme: ThemeData(
child: Theme( useMaterial3: false,
data: ThemeData( tooltipTheme: const TooltipThemeData(
useMaterial3: false, decoration: customDecoration,
tooltipTheme: const TooltipThemeData( ),
decoration: customDecoration, ),
home: Overlay(
initialEntries: <OverlayEntry>[
entry = OverlayEntry(
builder: (BuildContext context) {
return Tooltip(
key: key,
message: tooltipText,
child: const SizedBox.shrink(),
);
},
), ),
],
),
),
);
key.currentState!.ensureTooltipVisible();
await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0)
final RenderBox tip = tester.renderObject(find.text(tooltipText)).parent!.parent!.parent!.parent! as RenderBox;
expect(tip.size.height, equals(32.0));
expect(tip.size.width, equals(74.0));
expect(tip, paints..rrect(color: const Color(0x80800000)));
});
testWidgetsWithLeakTracking('Material3 - Tooltip decoration - ThemeData.tooltipTheme', (WidgetTester tester) async {
final GlobalKey<TooltipState> key = GlobalKey<TooltipState>();
const Decoration customDecoration = ShapeDecoration(
shape: StadiumBorder(),
color: Color(0x80800000),
);
late final OverlayEntry entry;
addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(
tooltipTheme: const TooltipThemeData(
decoration: customDecoration,
), ),
),
home: Overlay(
initialEntries: <OverlayEntry>[
entry = OverlayEntry(
builder: (BuildContext context) {
return Tooltip(
key: key,
message: tooltipText,
child: const SizedBox.shrink(),
);
},
),
],
),
),
);
key.currentState!.ensureTooltipVisible();
await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0)
final RenderBox tip = tester.renderObject(find.text(tooltipText)).parent!.parent!.parent!.parent! as RenderBox;
expect(tip.size.height, equals(32.0));
expect(tip.size.width, equals(74.75));
expect(tip, paints..rrect(color: const Color(0x80800000)));
});
testWidgetsWithLeakTracking('Material2 - Tooltip decoration - TooltipTheme', (WidgetTester tester) async {
final GlobalKey<TooltipState> key = GlobalKey<TooltipState>();
const Decoration customDecoration = ShapeDecoration(
shape: StadiumBorder(),
color: Color(0x80800000),
);
late final OverlayEntry entry;
addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(useMaterial3: false),
home: TooltipTheme(
data: const TooltipThemeData(decoration: customDecoration),
child: Overlay( child: Overlay(
initialEntries: <OverlayEntry>[ initialEntries: <OverlayEntry>[
entry = OverlayEntry( entry = OverlayEntry(
...@@ -727,7 +791,7 @@ void main() { ...@@ -727,7 +791,7 @@ void main() {
expect(tip, paints..rrect(color: const Color(0x80800000))); expect(tip, paints..rrect(color: const Color(0x80800000)));
}); });
testWidgetsWithLeakTracking('Tooltip decoration - TooltipTheme', (WidgetTester tester) async { testWidgetsWithLeakTracking('Material3 - Tooltip decoration - TooltipTheme', (WidgetTester tester) async {
final GlobalKey<TooltipState> key = GlobalKey<TooltipState>(); final GlobalKey<TooltipState> key = GlobalKey<TooltipState>();
const Decoration customDecoration = ShapeDecoration( const Decoration customDecoration = ShapeDecoration(
shape: StadiumBorder(), shape: StadiumBorder(),
...@@ -738,25 +802,21 @@ void main() { ...@@ -738,25 +802,21 @@ void main() {
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Theme( MaterialApp(
data: ThemeData(useMaterial3: false), home: TooltipTheme(
child: Directionality( data: const TooltipThemeData(decoration: customDecoration),
textDirection: TextDirection.ltr, child: Overlay(
child: TooltipTheme( initialEntries: <OverlayEntry>[
data: const TooltipThemeData(decoration: customDecoration), entry = OverlayEntry(
child: Overlay( builder: (BuildContext context) {
initialEntries: <OverlayEntry>[ return Tooltip(
entry = OverlayEntry( key: key,
builder: (BuildContext context) { message: tooltipText,
return Tooltip( child: const SizedBox.shrink(),
key: key, );
message: tooltipText, },
child: const SizedBox.shrink(), ),
); ],
},
),
],
),
), ),
), ),
), ),
...@@ -767,7 +827,7 @@ void main() { ...@@ -767,7 +827,7 @@ void main() {
final RenderBox tip = tester.renderObject(find.text(tooltipText)).parent!.parent!.parent!.parent! as RenderBox; final RenderBox tip = tester.renderObject(find.text(tooltipText)).parent!.parent!.parent!.parent! as RenderBox;
expect(tip.size.height, equals(32.0)); expect(tip.size.height, equals(32.0));
expect(tip.size.width, equals(74.0)); expect(tip.size.width, equals(74.75));
expect(tip, paints..rrect(color: const Color(0x80800000))); expect(tip, paints..rrect(color: const Color(0x80800000)));
}); });
...@@ -780,28 +840,25 @@ void main() { ...@@ -780,28 +840,25 @@ void main() {
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Directionality( MaterialApp(
textDirection: TextDirection.ltr, theme: ThemeData(
child: Theme( tooltipTheme: const TooltipThemeData(
data: ThemeData( height: customTooltipHeight,
tooltipTheme: const TooltipThemeData( padding: EdgeInsets.all(customPaddingVal),
height: customTooltipHeight,
padding: EdgeInsets.all(customPaddingVal),
),
),
child: Overlay(
initialEntries: <OverlayEntry>[
entry = OverlayEntry(
builder: (BuildContext context) {
return Tooltip(
key: key,
message: tooltipText,
);
},
),
],
), ),
), ),
home: Overlay(
initialEntries: <OverlayEntry>[
entry = OverlayEntry(
builder: (BuildContext context) {
return Tooltip(
key: key,
message: tooltipText,
);
},
),
],
),
), ),
); );
key.currentState!.ensureTooltipVisible(); key.currentState!.ensureTooltipVisible();
...@@ -829,9 +886,8 @@ void main() { ...@@ -829,9 +886,8 @@ void main() {
addTearDown(() => entry..remove()..dispose()); addTearDown(() => entry..remove()..dispose());
await tester.pumpWidget( await tester.pumpWidget(
Directionality( MaterialApp(
textDirection: TextDirection.ltr, home: TooltipTheme(
child: TooltipTheme(
data: const TooltipThemeData( data: const TooltipThemeData(
height: customTooltipHeight, height: customTooltipHeight,
padding: EdgeInsets.all(customPaddingValue), padding: EdgeInsets.all(customPaddingValue),
......
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