mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
1359 lines
47 KiB
Dart
1359 lines
47 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/gestures.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/rendering.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
import '../rendering/mock_canvas.dart';
|
|
import '../widgets/semantics_tester.dart';
|
|
|
|
const String tooltipText = 'TIP';
|
|
const double _customPaddingValue = 10.0;
|
|
|
|
void _ensureTooltipVisible(GlobalKey key) {
|
|
// This function uses "as dynamic"to defeat the static analysis. In general
|
|
// you want to avoid using this style in your code, as it will cause the
|
|
// analyzer to be unable to help you catch errors.
|
|
//
|
|
// In this case, we do it because we are trying to call internal methods of
|
|
// the tooltip code in order to test it. Normally, the state of a tooltip is a
|
|
// private class, but by using a GlobalKey we can get a handle to that object
|
|
// and by using "as dynamic" we can bypass the analyzer's type checks and call
|
|
// methods that we aren't supposed to be able to know about.
|
|
//
|
|
// It's ok to do this in tests, but you really don't want to do it in
|
|
// production code.
|
|
// ignore: avoid_dynamic_calls
|
|
(key.currentState as dynamic).ensureTooltipVisible();
|
|
}
|
|
|
|
void main() {
|
|
test('TooltipThemeData copyWith, ==, hashCode basics', () {
|
|
expect(const TooltipThemeData(), const TooltipThemeData().copyWith());
|
|
expect(const TooltipThemeData().hashCode, const TooltipThemeData().copyWith().hashCode);
|
|
});
|
|
|
|
test('TooltipThemeData defaults', () {
|
|
const TooltipThemeData theme = TooltipThemeData();
|
|
expect(theme.height, null);
|
|
expect(theme.padding, null);
|
|
expect(theme.verticalOffset, null);
|
|
expect(theme.preferBelow, null);
|
|
expect(theme.excludeFromSemantics, null);
|
|
expect(theme.decoration, null);
|
|
expect(theme.textStyle, null);
|
|
expect(theme.textAlign, null);
|
|
expect(theme.waitDuration, null);
|
|
expect(theme.showDuration, null);
|
|
expect(theme.triggerMode, null);
|
|
expect(theme.enableFeedback, null);
|
|
});
|
|
|
|
testWidgets('Default TooltipThemeData debugFillProperties', (WidgetTester tester) async {
|
|
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
|
const TooltipThemeData().debugFillProperties(builder);
|
|
|
|
final List<String> description = builder.properties
|
|
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
|
|
.map((DiagnosticsNode node) => node.toString())
|
|
.toList();
|
|
|
|
expect(description, <String>[]);
|
|
});
|
|
|
|
testWidgets('TooltipThemeData implements debugFillProperties', (WidgetTester tester) async {
|
|
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
|
const Duration wait = Duration(milliseconds: 100);
|
|
const Duration show = Duration(milliseconds: 200);
|
|
const TooltipTriggerMode triggerMode = TooltipTriggerMode.longPress;
|
|
const bool enableFeedback = true;
|
|
const TooltipThemeData(
|
|
height: 15.0,
|
|
padding: EdgeInsets.all(20.0),
|
|
verticalOffset: 10.0,
|
|
preferBelow: false,
|
|
excludeFromSemantics: true,
|
|
decoration: BoxDecoration(color: Color(0xffffffff)),
|
|
textStyle: TextStyle(decoration: TextDecoration.underline),
|
|
textAlign: TextAlign.center,
|
|
waitDuration: wait,
|
|
showDuration: show,
|
|
triggerMode: triggerMode,
|
|
enableFeedback: enableFeedback,
|
|
).debugFillProperties(builder);
|
|
|
|
final List<String> description = builder.properties
|
|
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
|
|
.map((DiagnosticsNode node) => node.toString())
|
|
.toList();
|
|
|
|
expect(description, <String>[
|
|
'height: 15.0',
|
|
'padding: EdgeInsets.all(20.0)',
|
|
'vertical offset: 10.0',
|
|
'position: above',
|
|
'semantics: excluded',
|
|
'decoration: BoxDecoration(color: Color(0xffffffff))',
|
|
'textStyle: TextStyle(inherit: true, decoration: TextDecoration.underline)',
|
|
'textAlign: TextAlign.center',
|
|
'wait duration: $wait',
|
|
'show duration: $show',
|
|
'triggerMode: $triggerMode',
|
|
'enableFeedback: true',
|
|
]);
|
|
});
|
|
|
|
testWidgets('Tooltip verticalOffset, preferBelow; center prefer above fits - ThemeData.tooltipTheme', (WidgetTester tester) async {
|
|
final GlobalKey key = GlobalKey();
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Theme(
|
|
data: ThemeData(
|
|
tooltipTheme: const TooltipThemeData(
|
|
height: 100.0,
|
|
padding: EdgeInsets.zero,
|
|
verticalOffset: 100.0,
|
|
preferBelow: false,
|
|
),
|
|
),
|
|
child: Overlay(
|
|
initialEntries: <OverlayEntry>[
|
|
OverlayEntry(
|
|
builder: (BuildContext context) {
|
|
return Stack(
|
|
children: <Widget>[
|
|
Positioned(
|
|
left: 400.0,
|
|
top: 300.0,
|
|
child: Tooltip(
|
|
key: key,
|
|
message: tooltipText,
|
|
child: const SizedBox(
|
|
width: 0.0,
|
|
height: 0.0,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
_ensureTooltipVisible(key);
|
|
await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0)
|
|
|
|
/********************* 800x600 screen
|
|
* ___ * }- 10.0 margin
|
|
* |___| * }-100.0 height
|
|
* | * }-100.0 vertical offset
|
|
* o * y=300.0
|
|
* *
|
|
* *
|
|
* *
|
|
*********************/
|
|
|
|
final RenderBox tip = tester.renderObject(find.text(tooltipText)).parent! as RenderBox;
|
|
expect(tip.size.height, equals(100.0));
|
|
expect(tip.localToGlobal(tip.size.topLeft(Offset.zero)).dy, equals(100.0));
|
|
expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dy, equals(200.0));
|
|
});
|
|
|
|
testWidgets('Tooltip verticalOffset, preferBelow; center prefer above fits - TooltipTheme', (WidgetTester tester) async {
|
|
final GlobalKey key = GlobalKey();
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: TooltipTheme(
|
|
data: const TooltipThemeData(
|
|
height: 100.0,
|
|
padding: EdgeInsets.zero,
|
|
verticalOffset: 100.0,
|
|
preferBelow: false,
|
|
),
|
|
child: Overlay(
|
|
initialEntries: <OverlayEntry>[
|
|
OverlayEntry(
|
|
builder: (BuildContext context) {
|
|
return Stack(
|
|
children: <Widget>[
|
|
Positioned(
|
|
left: 400.0,
|
|
top: 300.0,
|
|
child: Tooltip(
|
|
key: key,
|
|
message: tooltipText,
|
|
child: const SizedBox(
|
|
width: 0.0,
|
|
height: 0.0,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
_ensureTooltipVisible(key);
|
|
await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0)
|
|
|
|
/********************* 800x600 screen
|
|
* ___ * }- 10.0 margin
|
|
* |___| * }-100.0 height
|
|
* | * }-100.0 vertical offset
|
|
* o * y=300.0
|
|
* *
|
|
* *
|
|
* *
|
|
*********************/
|
|
|
|
final RenderBox tip = tester.renderObject(find.text(tooltipText)).parent! as RenderBox;
|
|
expect(tip.size.height, equals(100.0));
|
|
expect(tip.localToGlobal(tip.size.topLeft(Offset.zero)).dy, equals(100.0));
|
|
expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dy, equals(200.0));
|
|
});
|
|
|
|
testWidgets('Tooltip verticalOffset, preferBelow; center prefer above does not fit - ThemeData.tooltipTheme', (WidgetTester tester) async {
|
|
final GlobalKey key = GlobalKey();
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Theme(
|
|
data: ThemeData(
|
|
tooltipTheme: const TooltipThemeData(
|
|
height: 190.0,
|
|
padding: EdgeInsets.zero,
|
|
verticalOffset: 100.0,
|
|
preferBelow: false,
|
|
),
|
|
),
|
|
child: Overlay(
|
|
initialEntries: <OverlayEntry>[
|
|
OverlayEntry(
|
|
builder: (BuildContext context) {
|
|
return Stack(
|
|
children: <Widget>[
|
|
Positioned(
|
|
left: 400.0,
|
|
top: 299.0,
|
|
child: Tooltip(
|
|
key: key,
|
|
message: tooltipText,
|
|
child: const SizedBox(
|
|
width: 0.0,
|
|
height: 0.0,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
_ensureTooltipVisible(key);
|
|
await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0)
|
|
|
|
// we try to put it here but it doesn't fit:
|
|
/********************* 800x600 screen
|
|
* ___ * }- 10.0 margin
|
|
* |___| * }-190.0 height (starts at y=9.0)
|
|
* | * }-100.0 vertical offset
|
|
* o * y=299.0
|
|
* *
|
|
* *
|
|
* *
|
|
*********************/
|
|
|
|
// so we put it here:
|
|
/********************* 800x600 screen
|
|
* *
|
|
* *
|
|
* o * y=299.0
|
|
* _|_ * }-100.0 vertical offset
|
|
* |___| * }-190.0 height
|
|
* * }- 10.0 margin
|
|
*********************/
|
|
|
|
final RenderBox tip = tester.renderObject(find.text(tooltipText)).parent! as RenderBox;
|
|
expect(tip.size.height, equals(190.0));
|
|
expect(tip.localToGlobal(tip.size.topLeft(Offset.zero)).dy, equals(399.0));
|
|
expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dy, equals(589.0));
|
|
});
|
|
|
|
testWidgets('Tooltip verticalOffset, preferBelow; center prefer above does not fit - TooltipTheme', (WidgetTester tester) async {
|
|
final GlobalKey key = GlobalKey();
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: TooltipTheme(
|
|
data: const TooltipThemeData(
|
|
height: 190.0,
|
|
padding: EdgeInsets.zero,
|
|
verticalOffset: 100.0,
|
|
preferBelow: false,
|
|
),
|
|
child: Overlay(
|
|
initialEntries: <OverlayEntry>[
|
|
OverlayEntry(
|
|
builder: (BuildContext context) {
|
|
return Stack(
|
|
children: <Widget>[
|
|
Positioned(
|
|
left: 400.0,
|
|
top: 299.0,
|
|
child: Tooltip(
|
|
key: key,
|
|
message: tooltipText,
|
|
child: const SizedBox(
|
|
width: 0.0,
|
|
height: 0.0,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
_ensureTooltipVisible(key);
|
|
await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0)
|
|
|
|
// we try to put it here but it doesn't fit:
|
|
/********************* 800x600 screen
|
|
* ___ * }- 10.0 margin
|
|
* |___| * }-190.0 height (starts at y=9.0)
|
|
* | * }-100.0 vertical offset
|
|
* o * y=299.0
|
|
* *
|
|
* *
|
|
* *
|
|
*********************/
|
|
|
|
// so we put it here:
|
|
/********************* 800x600 screen
|
|
* *
|
|
* *
|
|
* o * y=299.0
|
|
* _|_ * }-100.0 vertical offset
|
|
* |___| * }-190.0 height
|
|
* * }- 10.0 margin
|
|
*********************/
|
|
|
|
final RenderBox tip = tester.renderObject(find.text(tooltipText)).parent! as RenderBox;
|
|
expect(tip.size.height, equals(190.0));
|
|
expect(tip.localToGlobal(tip.size.topLeft(Offset.zero)).dy, equals(399.0));
|
|
expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dy, equals(589.0));
|
|
});
|
|
|
|
testWidgets('Tooltip verticalOffset, preferBelow; center preferBelow fits - ThemeData.tooltipTheme', (WidgetTester tester) async {
|
|
final GlobalKey key = GlobalKey();
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Theme(
|
|
data: ThemeData(
|
|
tooltipTheme: const TooltipThemeData(
|
|
height: 190.0,
|
|
padding: EdgeInsets.zero,
|
|
verticalOffset: 100.0,
|
|
preferBelow: true,
|
|
),
|
|
),
|
|
child: Overlay(
|
|
initialEntries: <OverlayEntry>[
|
|
OverlayEntry(
|
|
builder: (BuildContext context) {
|
|
return Stack(
|
|
children: <Widget>[
|
|
Positioned(
|
|
left: 400.0,
|
|
top: 300.0,
|
|
child: Tooltip(
|
|
key: key,
|
|
message: tooltipText,
|
|
child: const SizedBox(
|
|
width: 0.0,
|
|
height: 0.0,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
_ensureTooltipVisible(key);
|
|
await tester.pumpAndSettle(); // faded in, show timer started (and at 0.0)
|
|
|
|
/********************* 800x600 screen
|
|
* *
|
|
* *
|
|
* o * y=300.0
|
|
* _|_ * }-100.0 vertical offset
|
|
* |___| * }-190.0 height
|
|
* * }- 10.0 margin
|
|
*********************/
|
|
|
|
final RenderBox tip = tester.renderObject(find.text(tooltipText)).parent! as RenderBox;
|
|
expect(tip.size.height, equals(190.0));
|
|
expect(tip.localToGlobal(tip.size.topLeft(Offset.zero)).dy, equals(400.0));
|
|
expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dy, equals(590.0));
|
|
});
|
|
|
|
testWidgets('Tooltip verticalOffset, preferBelow; center prefer below fits - TooltipTheme', (WidgetTester tester) async {
|
|
final GlobalKey key = GlobalKey();
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: TooltipTheme(
|
|
data: const TooltipThemeData(
|
|
height: 190.0,
|
|
padding: EdgeInsets.zero,
|
|
verticalOffset: 100.0,
|
|
preferBelow: true,
|
|
),
|
|
child: Overlay(
|
|
initialEntries: <OverlayEntry>[
|
|
OverlayEntry(
|
|
builder: (BuildContext context) {
|
|
return Stack(
|
|
children: <Widget>[
|
|
Positioned(
|
|
left: 400.0,
|
|
top: 300.0,
|
|
child: Tooltip(
|
|
key: key,
|
|
message: tooltipText,
|
|
child: const SizedBox(
|
|
width: 0.0,
|
|
height: 0.0,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
_ensureTooltipVisible(key);
|
|
await tester.pumpAndSettle(); // faded in, show timer started (and at 0.0)
|
|
|
|
/********************* 800x600 screen
|
|
* *
|
|
* *
|
|
* o * y=300.0
|
|
* _|_ * }-100.0 vertical offset
|
|
* |___| * }-190.0 height
|
|
* * }- 10.0 margin
|
|
*********************/
|
|
|
|
final RenderBox tip = tester.renderObject(find.text(tooltipText)).parent! as RenderBox;
|
|
expect(tip.size.height, equals(190.0));
|
|
expect(tip.localToGlobal(tip.size.topLeft(Offset.zero)).dy, equals(400.0));
|
|
expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dy, equals(590.0));
|
|
});
|
|
|
|
testWidgets('Tooltip margin - ThemeData', (WidgetTester tester) async {
|
|
final GlobalKey key = GlobalKey();
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Overlay(
|
|
initialEntries: <OverlayEntry>[
|
|
OverlayEntry(
|
|
builder: (BuildContext context) {
|
|
return Theme(
|
|
data: ThemeData(
|
|
tooltipTheme: const TooltipThemeData(
|
|
padding: EdgeInsets.zero,
|
|
margin: EdgeInsets.all(_customPaddingValue),
|
|
),
|
|
),
|
|
child: Tooltip(
|
|
key: key,
|
|
message: tooltipText,
|
|
child: const SizedBox(
|
|
width: 0.0,
|
|
height: 0.0,
|
|
),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
_ensureTooltipVisible(key);
|
|
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!.parent! as RenderBox;
|
|
final RenderBox tooltipContent = tester.renderObject(find.text(tooltipText));
|
|
|
|
final Offset topLeftTipInGlobal = tip.localToGlobal(tip.size.topLeft(Offset.zero));
|
|
final Offset topLeftTooltipContentInGlobal = tooltipContent.localToGlobal(tooltipContent.size.topLeft(Offset.zero));
|
|
expect(topLeftTooltipContentInGlobal.dx, topLeftTipInGlobal.dx + _customPaddingValue);
|
|
expect(topLeftTooltipContentInGlobal.dy, topLeftTipInGlobal.dy + _customPaddingValue);
|
|
|
|
final Offset topRightTipInGlobal = tip.localToGlobal(tip.size.topRight(Offset.zero));
|
|
final Offset topRightTooltipContentInGlobal = tooltipContent.localToGlobal(tooltipContent.size.topRight(Offset.zero));
|
|
expect(topRightTooltipContentInGlobal.dx, topRightTipInGlobal.dx - _customPaddingValue);
|
|
expect(topRightTooltipContentInGlobal.dy, topRightTipInGlobal.dy + _customPaddingValue);
|
|
|
|
final Offset bottomLeftTipInGlobal = tip.localToGlobal(tip.size.bottomLeft(Offset.zero));
|
|
final Offset bottomLeftTooltipContentInGlobal = tooltipContent.localToGlobal(tooltipContent.size.bottomLeft(Offset.zero));
|
|
expect(bottomLeftTooltipContentInGlobal.dx, bottomLeftTipInGlobal.dx + _customPaddingValue);
|
|
expect(bottomLeftTooltipContentInGlobal.dy, bottomLeftTipInGlobal.dy - _customPaddingValue);
|
|
|
|
final Offset bottomRightTipInGlobal = tip.localToGlobal(tip.size.bottomRight(Offset.zero));
|
|
final Offset bottomRightTooltipContentInGlobal = tooltipContent.localToGlobal(tooltipContent.size.bottomRight(Offset.zero));
|
|
expect(bottomRightTooltipContentInGlobal.dx, bottomRightTipInGlobal.dx - _customPaddingValue);
|
|
expect(bottomRightTooltipContentInGlobal.dy, bottomRightTipInGlobal.dy - _customPaddingValue);
|
|
});
|
|
|
|
testWidgets('Tooltip margin - TooltipTheme', (WidgetTester tester) async {
|
|
final GlobalKey key = GlobalKey();
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Overlay(
|
|
initialEntries: <OverlayEntry>[
|
|
OverlayEntry(
|
|
builder: (BuildContext context) {
|
|
return TooltipTheme(
|
|
data: const TooltipThemeData(
|
|
padding: EdgeInsets.zero,
|
|
margin: EdgeInsets.all(_customPaddingValue),
|
|
),
|
|
child: Tooltip(
|
|
key: key,
|
|
message: tooltipText,
|
|
child: const SizedBox(
|
|
width: 0.0,
|
|
height: 0.0,
|
|
),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
_ensureTooltipVisible(key);
|
|
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!.parent! as RenderBox;
|
|
final RenderBox tooltipContent = tester.renderObject(find.text(tooltipText));
|
|
|
|
final Offset topLeftTipInGlobal = tip.localToGlobal(tip.size.topLeft(Offset.zero));
|
|
final Offset topLeftTooltipContentInGlobal = tooltipContent.localToGlobal(tooltipContent.size.topLeft(Offset.zero));
|
|
expect(topLeftTooltipContentInGlobal.dx, topLeftTipInGlobal.dx + _customPaddingValue);
|
|
expect(topLeftTooltipContentInGlobal.dy, topLeftTipInGlobal.dy + _customPaddingValue);
|
|
|
|
final Offset topRightTipInGlobal = tip.localToGlobal(tip.size.topRight(Offset.zero));
|
|
final Offset topRightTooltipContentInGlobal = tooltipContent.localToGlobal(tooltipContent.size.topRight(Offset.zero));
|
|
expect(topRightTooltipContentInGlobal.dx, topRightTipInGlobal.dx - _customPaddingValue);
|
|
expect(topRightTooltipContentInGlobal.dy, topRightTipInGlobal.dy + _customPaddingValue);
|
|
|
|
final Offset bottomLeftTipInGlobal = tip.localToGlobal(tip.size.bottomLeft(Offset.zero));
|
|
final Offset bottomLeftTooltipContentInGlobal = tooltipContent.localToGlobal(tooltipContent.size.bottomLeft(Offset.zero));
|
|
expect(bottomLeftTooltipContentInGlobal.dx, bottomLeftTipInGlobal.dx + _customPaddingValue);
|
|
expect(bottomLeftTooltipContentInGlobal.dy, bottomLeftTipInGlobal.dy - _customPaddingValue);
|
|
|
|
final Offset bottomRightTipInGlobal = tip.localToGlobal(tip.size.bottomRight(Offset.zero));
|
|
final Offset bottomRightTooltipContentInGlobal = tooltipContent.localToGlobal(tooltipContent.size.bottomRight(Offset.zero));
|
|
expect(bottomRightTooltipContentInGlobal.dx, bottomRightTipInGlobal.dx - _customPaddingValue);
|
|
expect(bottomRightTooltipContentInGlobal.dy, bottomRightTipInGlobal.dy - _customPaddingValue);
|
|
});
|
|
|
|
testWidgets('Tooltip message textStyle - ThemeData.tooltipTheme', (WidgetTester tester) async {
|
|
final GlobalKey key = GlobalKey();
|
|
await tester.pumpWidget(MaterialApp(
|
|
theme: ThemeData(
|
|
tooltipTheme: const TooltipThemeData(
|
|
textStyle: TextStyle(
|
|
color: Colors.orange,
|
|
decoration: TextDecoration.underline,
|
|
),
|
|
),
|
|
),
|
|
home: Tooltip(
|
|
key: key,
|
|
message: tooltipText,
|
|
child: Container(
|
|
width: 100.0,
|
|
height: 100.0,
|
|
color: Colors.green[500],
|
|
),
|
|
),
|
|
));
|
|
_ensureTooltipVisible(key);
|
|
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.orange);
|
|
expect(textStyle.fontFamily, null);
|
|
expect(textStyle.decoration, TextDecoration.underline);
|
|
});
|
|
|
|
testWidgets('Tooltip message textStyle - TooltipTheme', (WidgetTester tester) async {
|
|
final GlobalKey key = GlobalKey();
|
|
await tester.pumpWidget(MaterialApp(
|
|
home: TooltipTheme(
|
|
data: const TooltipThemeData(),
|
|
child: Tooltip(
|
|
textStyle: const TextStyle(
|
|
color: Colors.orange,
|
|
decoration: TextDecoration.underline,
|
|
),
|
|
key: key,
|
|
message: tooltipText,
|
|
child: Container(
|
|
width: 100.0,
|
|
height: 100.0,
|
|
color: Colors.green[500],
|
|
),
|
|
),
|
|
),
|
|
));
|
|
_ensureTooltipVisible(key);
|
|
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.orange);
|
|
expect(textStyle.fontFamily, null);
|
|
expect(textStyle.decoration, TextDecoration.underline);
|
|
});
|
|
|
|
testWidgets('Tooltip message textAlign - TooltipTheme', (WidgetTester tester) async {
|
|
Future<void> pumpTooltipWithTextAlign({TextAlign? textAlign}) async {
|
|
final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>();
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: TooltipTheme(
|
|
data: TooltipThemeData(
|
|
textAlign: textAlign,
|
|
),
|
|
child: 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)
|
|
}
|
|
|
|
// Default value should be TextAlign.start
|
|
await pumpTooltipWithTextAlign();
|
|
TextAlign textAlign = tester.widget<Text>(find.text(tooltipText)).textAlign!;
|
|
expect(textAlign, TextAlign.start);
|
|
|
|
await pumpTooltipWithTextAlign(textAlign: TextAlign.center);
|
|
textAlign = tester.widget<Text>(find.text(tooltipText)).textAlign!;
|
|
expect(textAlign, TextAlign.center);
|
|
|
|
await pumpTooltipWithTextAlign(textAlign: TextAlign.end);
|
|
textAlign = tester.widget<Text>(find.text(tooltipText)).textAlign!;
|
|
expect(textAlign, TextAlign.end);
|
|
});
|
|
|
|
testWidgets('Tooltip decoration - ThemeData.tooltipTheme', (WidgetTester tester) async {
|
|
final GlobalKey key = GlobalKey();
|
|
const Decoration customDecoration = ShapeDecoration(
|
|
shape: StadiumBorder(),
|
|
color: Color(0x80800000),
|
|
);
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Theme(
|
|
data: ThemeData(
|
|
tooltipTheme: const TooltipThemeData(
|
|
decoration: customDecoration,
|
|
),
|
|
),
|
|
child: Overlay(
|
|
initialEntries: <OverlayEntry>[
|
|
OverlayEntry(
|
|
builder: (BuildContext context) {
|
|
return Tooltip(
|
|
key: key,
|
|
message: tooltipText,
|
|
child: const SizedBox(
|
|
width: 0.0,
|
|
height: 0.0,
|
|
),
|
|
);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
_ensureTooltipVisible(key);
|
|
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)));
|
|
});
|
|
|
|
testWidgets('Tooltip decoration - TooltipTheme', (WidgetTester tester) async {
|
|
final GlobalKey key = GlobalKey();
|
|
const Decoration customDecoration = ShapeDecoration(
|
|
shape: StadiumBorder(),
|
|
color: Color(0x80800000),
|
|
);
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: TooltipTheme(
|
|
data: const TooltipThemeData(decoration: customDecoration),
|
|
child: Overlay(
|
|
initialEntries: <OverlayEntry>[
|
|
OverlayEntry(
|
|
builder: (BuildContext context) {
|
|
return Tooltip(
|
|
key: key,
|
|
message: tooltipText,
|
|
child: const SizedBox(
|
|
width: 0.0,
|
|
height: 0.0,
|
|
),
|
|
);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
_ensureTooltipVisible(key);
|
|
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)));
|
|
});
|
|
|
|
testWidgets('Tooltip height and padding - ThemeData.tooltipTheme', (WidgetTester tester) async {
|
|
final GlobalKey key = GlobalKey();
|
|
const double customTooltipHeight = 100.0;
|
|
const double customPaddingVal = 20.0;
|
|
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Theme(
|
|
data: ThemeData(
|
|
tooltipTheme: const TooltipThemeData(
|
|
height: customTooltipHeight,
|
|
padding: EdgeInsets.all(customPaddingVal),
|
|
),
|
|
),
|
|
child: Overlay(
|
|
initialEntries: <OverlayEntry>[
|
|
OverlayEntry(
|
|
builder: (BuildContext context) {
|
|
return Tooltip(
|
|
key: key,
|
|
message: tooltipText,
|
|
);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
_ensureTooltipVisible(key);
|
|
await tester.pumpAndSettle();
|
|
|
|
final RenderBox tip = tester.renderObject(find.ancestor(
|
|
of: find.text(tooltipText),
|
|
matching: find.byType(Padding).first, // select [Tooltip.padding] instead of [Tooltip.margin]
|
|
));
|
|
final RenderBox content = tester.renderObject(find.ancestor(
|
|
of: find.text(tooltipText),
|
|
matching: find.byType(Center),
|
|
));
|
|
|
|
expect(tip.size.height, equals(customTooltipHeight));
|
|
expect(content.size.height, equals(customTooltipHeight - 2 * customPaddingVal));
|
|
expect(content.size.width, equals(tip.size.width - 2 * customPaddingVal));
|
|
});
|
|
|
|
testWidgets('Tooltip height and padding - TooltipTheme', (WidgetTester tester) async {
|
|
final GlobalKey key = GlobalKey();
|
|
const double customTooltipHeight = 100.0;
|
|
const double customPaddingValue = 20.0;
|
|
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: TooltipTheme(
|
|
data: const TooltipThemeData(
|
|
height: customTooltipHeight,
|
|
padding: EdgeInsets.all(customPaddingValue),
|
|
),
|
|
child: Overlay(
|
|
initialEntries: <OverlayEntry>[
|
|
OverlayEntry(
|
|
builder: (BuildContext context) {
|
|
return Tooltip(
|
|
key: key,
|
|
message: tooltipText,
|
|
);
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
_ensureTooltipVisible(key);
|
|
await tester.pumpAndSettle();
|
|
|
|
final RenderBox tip = tester.renderObject(find.ancestor(
|
|
of: find.text(tooltipText),
|
|
matching: find.byType(Padding).first, // select [Tooltip.padding] instead of [Tooltip.margin]
|
|
));
|
|
final RenderBox content = tester.renderObject(find.ancestor(
|
|
of: find.text(tooltipText),
|
|
matching: find.byType(Center),
|
|
));
|
|
|
|
expect(tip.size.height, equals(customTooltipHeight));
|
|
expect(content.size.height, equals(customTooltipHeight - 2 * customPaddingValue));
|
|
expect(content.size.width, equals(tip.size.width - 2 * customPaddingValue));
|
|
});
|
|
|
|
testWidgets('Tooltip waitDuration - ThemeData.tooltipTheme', (WidgetTester tester) async {
|
|
const Duration customWaitDuration = Duration(milliseconds: 500);
|
|
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
|
|
await gesture.addPointer();
|
|
await gesture.moveTo(const Offset(1.0, 1.0));
|
|
await tester.pump();
|
|
await gesture.moveTo(Offset.zero);
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Theme(
|
|
data: ThemeData(
|
|
tooltipTheme: const TooltipThemeData(
|
|
waitDuration: customWaitDuration,
|
|
),
|
|
),
|
|
child: const Center(
|
|
child: Tooltip(
|
|
message: tooltipText,
|
|
child: SizedBox(
|
|
width: 100.0,
|
|
height: 100.0,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Finder tooltip = find.byType(Tooltip);
|
|
await gesture.moveTo(Offset.zero);
|
|
await tester.pump();
|
|
await gesture.moveTo(tester.getCenter(tooltip));
|
|
await tester.pump();
|
|
await tester.pump(const Duration(milliseconds: 250));
|
|
expect(find.text(tooltipText), findsNothing); // Should not appear yet
|
|
await tester.pump(const Duration(milliseconds: 250));
|
|
expect(find.text(tooltipText), findsOneWidget); // Should appear after customWaitDuration
|
|
|
|
await gesture.moveTo(Offset.zero);
|
|
await tester.pump();
|
|
|
|
// Wait for it to disappear.
|
|
await tester.pump(customWaitDuration);
|
|
expect(find.text(tooltipText), findsNothing);
|
|
});
|
|
|
|
testWidgets('Tooltip waitDuration - TooltipTheme', (WidgetTester tester) async {
|
|
const Duration customWaitDuration = Duration(milliseconds: 500);
|
|
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
|
|
await gesture.addPointer();
|
|
await gesture.moveTo(const Offset(1.0, 1.0));
|
|
await tester.pump();
|
|
await gesture.moveTo(Offset.zero);
|
|
|
|
await tester.pumpWidget(
|
|
const MaterialApp(
|
|
home: TooltipTheme(
|
|
data: TooltipThemeData(waitDuration: customWaitDuration),
|
|
child: Center(
|
|
child: Tooltip(
|
|
message: tooltipText,
|
|
child: SizedBox(
|
|
width: 100.0,
|
|
height: 100.0,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Finder tooltip = find.byType(Tooltip);
|
|
await gesture.moveTo(Offset.zero);
|
|
await tester.pump();
|
|
await gesture.moveTo(tester.getCenter(tooltip));
|
|
await tester.pump();
|
|
await tester.pump(const Duration(milliseconds: 250));
|
|
expect(find.text(tooltipText), findsNothing); // Should not appear yet
|
|
await tester.pump(const Duration(milliseconds: 250));
|
|
expect(find.text(tooltipText), findsOneWidget); // Should appear after customWaitDuration
|
|
|
|
await gesture.moveTo(Offset.zero);
|
|
await tester.pump();
|
|
|
|
// Wait for it to disappear.
|
|
await tester.pump(customWaitDuration); // Should disappear after customWaitDuration
|
|
expect(find.text(tooltipText), findsNothing);
|
|
});
|
|
|
|
testWidgets('Tooltip showDuration - ThemeData.tooltipTheme', (WidgetTester tester) async {
|
|
const Duration customShowDuration = Duration(milliseconds: 3000);
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Theme(
|
|
data: ThemeData(
|
|
tooltipTheme: const TooltipThemeData(
|
|
showDuration: customShowDuration,
|
|
),
|
|
),
|
|
child: const Center(
|
|
child: Tooltip(
|
|
message: tooltipText,
|
|
child: SizedBox(
|
|
width: 100.0,
|
|
height: 100.0,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Finder tooltip = find.byType(Tooltip);
|
|
final TestGesture gesture = await tester.startGesture(tester.getCenter(tooltip));
|
|
await tester.pump();
|
|
await tester.pump(kLongPressTimeout);
|
|
await gesture.up();
|
|
expect(find.text(tooltipText), findsOneWidget);
|
|
await tester.pump();
|
|
await tester.pump(const Duration(milliseconds: 2000)); // Tooltip should remain
|
|
expect(find.text(tooltipText), findsOneWidget);
|
|
await tester.pump(const Duration(milliseconds: 1000));
|
|
await tester.pumpAndSettle(); // Tooltip should fade out after
|
|
expect(find.text(tooltipText), findsNothing);
|
|
});
|
|
|
|
testWidgets('Tooltip showDuration - TooltipTheme', (WidgetTester tester) async {
|
|
const Duration customShowDuration = Duration(milliseconds: 3000);
|
|
await tester.pumpWidget(
|
|
const MaterialApp(
|
|
home: TooltipTheme(
|
|
data: TooltipThemeData(showDuration: customShowDuration),
|
|
child: Center(
|
|
child: Tooltip(
|
|
message: tooltipText,
|
|
child: SizedBox(
|
|
width: 100.0,
|
|
height: 100.0,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Finder tooltip = find.byType(Tooltip);
|
|
final TestGesture gesture = await tester.startGesture(tester.getCenter(tooltip));
|
|
await tester.pump();
|
|
await tester.pump(kLongPressTimeout);
|
|
await gesture.up();
|
|
expect(find.text(tooltipText), findsOneWidget);
|
|
await tester.pump();
|
|
await tester.pump(const Duration(milliseconds: 2000)); // Tooltip should remain
|
|
expect(find.text(tooltipText), findsOneWidget);
|
|
await tester.pump(const Duration(milliseconds: 1000));
|
|
await tester.pumpAndSettle(); // Tooltip should fade out after
|
|
expect(find.text(tooltipText), findsNothing);
|
|
});
|
|
|
|
testWidgets('Tooltip triggerMode - ThemeData.triggerMode', (WidgetTester tester) async {
|
|
const TooltipTriggerMode triggerMode = TooltipTriggerMode.tap;
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Theme(
|
|
data: ThemeData(
|
|
tooltipTheme: const TooltipThemeData(triggerMode: triggerMode),
|
|
),
|
|
child: const Center(
|
|
child: Tooltip(
|
|
message: tooltipText,
|
|
child: SizedBox(width: 100.0, height: 100.0),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Finder tooltip = find.byType(Tooltip);
|
|
final TestGesture gesture = await tester.startGesture(tester.getCenter(tooltip));
|
|
await gesture.up();
|
|
await tester.pump();
|
|
expect(find.text(tooltipText), findsOneWidget); // Tooltip should show immediately after tap
|
|
});
|
|
|
|
testWidgets('Tooltip triggerMode - TooltipTheme', (WidgetTester tester) async {
|
|
const TooltipTriggerMode triggerMode = TooltipTriggerMode.tap;
|
|
await tester.pumpWidget(
|
|
const MaterialApp(
|
|
home: TooltipTheme(
|
|
data: TooltipThemeData(triggerMode: triggerMode),
|
|
child: Center(
|
|
child: Tooltip(
|
|
message: tooltipText,
|
|
child: SizedBox(width: 100.0, height: 100.0),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Finder tooltip = find.byType(Tooltip);
|
|
final TestGesture gesture = await tester.startGesture(tester.getCenter(tooltip));
|
|
await gesture.up();
|
|
await tester.pump();
|
|
expect(find.text(tooltipText), findsOneWidget); // Tooltip should show immediately after tap
|
|
});
|
|
|
|
testWidgets('Semantics included by default - ThemeData.tooltipTheme', (WidgetTester tester) async {
|
|
final SemanticsTester semantics = SemanticsTester(tester);
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: ThemeData(),
|
|
home: const Center(
|
|
child: Tooltip(
|
|
message: 'Foo',
|
|
child: Text('Bar'),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(semantics, hasSemantics(TestSemantics.root(
|
|
children: <TestSemantics>[
|
|
TestSemantics.rootChild(
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
tooltip: 'Foo',
|
|
label: 'Bar',
|
|
textDirection: TextDirection.ltr,
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
],
|
|
), ignoreRect: true, ignoreId: true, ignoreTransform: true));
|
|
|
|
semantics.dispose();
|
|
});
|
|
|
|
testWidgets('Semantics included by default - TooltipTheme', (WidgetTester tester) async {
|
|
final SemanticsTester semantics = SemanticsTester(tester);
|
|
|
|
await tester.pumpWidget(
|
|
const MaterialApp(
|
|
home: TooltipTheme(
|
|
data: TooltipThemeData(),
|
|
child: Center(
|
|
child: Tooltip(
|
|
message: 'Foo',
|
|
child: Text('Bar'),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(semantics, hasSemantics(TestSemantics.root(
|
|
children: <TestSemantics>[
|
|
TestSemantics.rootChild(
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
tooltip: 'Foo',
|
|
label: 'Bar',
|
|
textDirection: TextDirection.ltr,
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
],
|
|
), ignoreRect: true, ignoreId: true, ignoreTransform: true));
|
|
|
|
semantics.dispose();
|
|
});
|
|
|
|
testWidgets('Semantics excluded - ThemeData.tooltipTheme', (WidgetTester tester) async {
|
|
final SemanticsTester semantics = SemanticsTester(tester);
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: ThemeData(
|
|
tooltipTheme: const TooltipThemeData(
|
|
excludeFromSemantics: true,
|
|
),
|
|
),
|
|
home: const Center(
|
|
child: Tooltip(
|
|
message: 'Foo',
|
|
child: Text('Bar'),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(semantics, hasSemantics(TestSemantics.root(
|
|
children: <TestSemantics>[
|
|
TestSemantics.rootChild(
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
label: 'Bar',
|
|
textDirection: TextDirection.ltr,
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
],
|
|
), ignoreRect: true, ignoreId: true, ignoreTransform: true));
|
|
|
|
semantics.dispose();
|
|
});
|
|
|
|
testWidgets('Semantics excluded - TooltipTheme', (WidgetTester tester) async {
|
|
final SemanticsTester semantics = SemanticsTester(tester);
|
|
|
|
await tester.pumpWidget(
|
|
const MaterialApp(
|
|
home: TooltipTheme(
|
|
data: TooltipThemeData(excludeFromSemantics: true),
|
|
child: Center(
|
|
child: Tooltip(
|
|
message: 'Foo',
|
|
child: Text('Bar'),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(semantics, hasSemantics(TestSemantics.root(
|
|
children: <TestSemantics>[
|
|
TestSemantics.rootChild(
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
|
|
children: <TestSemantics>[
|
|
TestSemantics(
|
|
label: 'Bar',
|
|
textDirection: TextDirection.ltr,
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
],
|
|
), ignoreRect: true, ignoreId: true, ignoreTransform: true));
|
|
|
|
semantics.dispose();
|
|
});
|
|
|
|
testWidgets('has semantic events by default - ThemeData.tooltipTheme', (WidgetTester tester) async {
|
|
final List<dynamic> semanticEvents = <dynamic>[];
|
|
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, (dynamic message) async {
|
|
semanticEvents.add(message);
|
|
});
|
|
final SemanticsTester semantics = SemanticsTester(tester);
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: ThemeData(),
|
|
home: Center(
|
|
child: Tooltip(
|
|
message: 'Foo',
|
|
child: Container(
|
|
width: 100.0,
|
|
height: 100.0,
|
|
color: Colors.green[500],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
await tester.longPress(find.byType(Tooltip));
|
|
final RenderObject object = tester.firstRenderObject(find.byType(Tooltip));
|
|
|
|
expect(semanticEvents, unorderedEquals(<dynamic>[
|
|
<String, dynamic>{
|
|
'type': 'longPress',
|
|
'nodeId': findDebugSemantics(object).id,
|
|
'data': <String, dynamic>{},
|
|
},
|
|
<String, dynamic>{
|
|
'type': 'tooltip',
|
|
'data': <String, dynamic>{
|
|
'message': 'Foo',
|
|
},
|
|
},
|
|
]));
|
|
semantics.dispose();
|
|
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, null);
|
|
});
|
|
|
|
testWidgets('has semantic events by default - TooltipTheme', (WidgetTester tester) async {
|
|
final List<dynamic> semanticEvents = <dynamic>[];
|
|
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, (dynamic message) async {
|
|
semanticEvents.add(message);
|
|
});
|
|
final SemanticsTester semantics = SemanticsTester(tester);
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: TooltipTheme(
|
|
data: const TooltipThemeData(),
|
|
child: Center(
|
|
child: Tooltip(
|
|
message: 'Foo',
|
|
child: Container(
|
|
width: 100.0,
|
|
height: 100.0,
|
|
color: Colors.green[500],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
await tester.longPress(find.byType(Tooltip));
|
|
final RenderObject object = tester.firstRenderObject(find.byType(Tooltip));
|
|
|
|
expect(semanticEvents, unorderedEquals(<dynamic>[
|
|
<String, dynamic>{
|
|
'type': 'longPress',
|
|
'nodeId': findDebugSemantics(object).id,
|
|
'data': <String, dynamic>{},
|
|
},
|
|
<String, dynamic>{
|
|
'type': 'tooltip',
|
|
'data': <String, dynamic>{
|
|
'message': 'Foo',
|
|
},
|
|
},
|
|
]));
|
|
semantics.dispose();
|
|
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, null);
|
|
});
|
|
|
|
testWidgets('default Tooltip debugFillProperties', (WidgetTester tester) async {
|
|
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
|
|
|
const Tooltip(message: 'message').debugFillProperties(builder);
|
|
|
|
final List<String> description = builder.properties
|
|
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
|
|
.map((DiagnosticsNode node) => node.toString()).toList();
|
|
|
|
expect(description, <String>[
|
|
'"message"',
|
|
]);
|
|
});
|
|
}
|
|
|
|
SemanticsNode findDebugSemantics(RenderObject object) {
|
|
if (object.debugSemantics != null) {
|
|
return object.debugSemantics!;
|
|
}
|
|
return findDebugSemantics(object.parent! as RenderObject);
|
|
}
|