mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Adds a manual test that allows testing of density for buttons. Also updates some of the button tests to be somewhat simpler and to test the child positions in the test to make sure they are consistent.
761 lines
25 KiB
Dart
761 lines
25 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 'package:flutter/gestures.dart';
|
|
import 'package:flutter/rendering.dart';
|
|
|
|
import '../rendering/mock_canvas.dart';
|
|
import '../widgets/semantics_tester.dart';
|
|
|
|
void main() {
|
|
testWidgets('FlatButton defaults', (WidgetTester tester) async {
|
|
final Finder rawButtonMaterial = find.descendant(
|
|
of: find.byType(FlatButton),
|
|
matching: find.byType(Material),
|
|
);
|
|
|
|
// Enabled FlatButton
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: FlatButton(
|
|
onPressed: () { },
|
|
child: const Text('button'),
|
|
),
|
|
),
|
|
);
|
|
Material material = tester.widget<Material>(rawButtonMaterial);
|
|
expect(material.animationDuration, const Duration(milliseconds: 200));
|
|
expect(material.borderOnForeground, true);
|
|
expect(material.borderRadius, null);
|
|
expect(material.clipBehavior, Clip.none);
|
|
expect(material.color, null);
|
|
expect(material.elevation, 0.0);
|
|
expect(material.shadowColor, const Color(0xff000000));
|
|
expect(material.shape, RoundedRectangleBorder(borderRadius: BorderRadius.circular(2.0)));
|
|
expect(material.textStyle.color, const Color(0xdd000000));
|
|
expect(material.textStyle.fontFamily, 'Roboto');
|
|
expect(material.textStyle.fontSize, 14);
|
|
expect(material.textStyle.fontWeight, FontWeight.w500);
|
|
expect(material.type, MaterialType.transparency);
|
|
|
|
final Offset center = tester.getCenter(find.byType(FlatButton));
|
|
await tester.startGesture(center);
|
|
await tester.pumpAndSettle();
|
|
|
|
material = tester.widget<Material>(rawButtonMaterial);
|
|
// No change vs enabled and not pressed.
|
|
expect(material.animationDuration, const Duration(milliseconds: 200));
|
|
expect(material.borderOnForeground, true);
|
|
expect(material.borderRadius, null);
|
|
expect(material.clipBehavior, Clip.none);
|
|
expect(material.color, null);
|
|
expect(material.elevation, 0.0);
|
|
expect(material.shadowColor, const Color(0xff000000));
|
|
expect(material.shape, RoundedRectangleBorder(borderRadius: BorderRadius.circular(2.0)));
|
|
expect(material.textStyle.color, const Color(0xdd000000));
|
|
expect(material.textStyle.fontFamily, 'Roboto');
|
|
expect(material.textStyle.fontSize, 14);
|
|
expect(material.textStyle.fontWeight, FontWeight.w500);
|
|
expect(material.type, MaterialType.transparency);
|
|
|
|
// Disabled FlatButton
|
|
await tester.pumpWidget(
|
|
const Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: FlatButton(
|
|
onPressed: null,
|
|
child: Text('button'),
|
|
),
|
|
),
|
|
);
|
|
material = tester.widget<Material>(rawButtonMaterial);
|
|
expect(material.animationDuration, const Duration(milliseconds: 200));
|
|
expect(material.borderOnForeground, true);
|
|
expect(material.borderRadius, null);
|
|
expect(material.clipBehavior, Clip.none);
|
|
expect(material.color, null);
|
|
expect(material.elevation, 0.0);
|
|
expect(material.shadowColor, const Color(0xff000000));
|
|
expect(material.shape, RoundedRectangleBorder(borderRadius: BorderRadius.circular(2.0)));
|
|
expect(material.textStyle.color, const Color(0x61000000));
|
|
expect(material.textStyle.fontFamily, 'Roboto');
|
|
expect(material.textStyle.fontSize, 14);
|
|
expect(material.textStyle.fontWeight, FontWeight.w500);
|
|
expect(material.type, MaterialType.transparency);
|
|
});
|
|
|
|
testWidgets('FlatButton implements debugFillProperties', (WidgetTester tester) async {
|
|
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
|
FlatButton(
|
|
onPressed: () { },
|
|
textColor: const Color(0xFF00FF00),
|
|
disabledTextColor: const Color(0xFFFF0000),
|
|
color: const Color(0xFF000000),
|
|
highlightColor: const Color(0xFF1565C0),
|
|
splashColor: const Color(0xFF9E9E9E),
|
|
child: const Text('Hello'),
|
|
).debugFillProperties(builder);
|
|
final List<String> description = builder.properties
|
|
.where((DiagnosticsNode n) => !n.isFiltered(DiagnosticLevel.info))
|
|
.map((DiagnosticsNode n) => n.toString()).toList();
|
|
expect(description, <String>[
|
|
'textColor: Color(0xff00ff00)',
|
|
'disabledTextColor: Color(0xffff0000)',
|
|
'color: Color(0xff000000)',
|
|
'highlightColor: Color(0xff1565c0)',
|
|
'splashColor: Color(0xff9e9e9e)',
|
|
]);
|
|
});
|
|
|
|
testWidgets('Default FlatButton meets a11y contrast guidelines', (WidgetTester tester) async {
|
|
final FocusNode focusNode = FocusNode();
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(
|
|
body: Center(
|
|
child: FlatButton(
|
|
child: const Text('FlatButton'),
|
|
onPressed: () { },
|
|
focusNode: focusNode,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
// Default, not disabled.
|
|
await expectLater(tester, meetsGuideline(textContrastGuideline));
|
|
|
|
// Focused.
|
|
focusNode.requestFocus();
|
|
await tester.pumpAndSettle();
|
|
await expectLater(tester, meetsGuideline(textContrastGuideline));
|
|
|
|
// Hovered.
|
|
final Offset center = tester.getCenter(find.byType(FlatButton));
|
|
final TestGesture gesture = await tester.createGesture(
|
|
kind: PointerDeviceKind.mouse,
|
|
);
|
|
await gesture.addPointer();
|
|
addTearDown(gesture.removePointer);
|
|
await gesture.moveTo(center);
|
|
await tester.pumpAndSettle();
|
|
await expectLater(tester, meetsGuideline(textContrastGuideline));
|
|
|
|
// Highlighted (pressed).
|
|
await gesture.down(center);
|
|
await tester.pump(); // Start the splash and highlight animations.
|
|
await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way.
|
|
await expectLater(tester, meetsGuideline(textContrastGuideline));
|
|
},
|
|
semanticsEnabled: true,
|
|
skip: isBrowser,
|
|
);
|
|
|
|
testWidgets('FlatButton with colored theme meets a11y contrast guidelines', (WidgetTester tester) async {
|
|
final FocusNode focusNode = FocusNode();
|
|
|
|
final ColorScheme colorScheme = ColorScheme.fromSwatch(primarySwatch: Colors.blue);
|
|
|
|
Color getTextColor(Set<MaterialState> states) {
|
|
final Set<MaterialState> interactiveStates = <MaterialState>{
|
|
MaterialState.pressed,
|
|
MaterialState.hovered,
|
|
MaterialState.focused,
|
|
};
|
|
if (states.any(interactiveStates.contains)) {
|
|
return Colors.blue[900];
|
|
}
|
|
return Colors.blue[800];
|
|
}
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(
|
|
body: Center(
|
|
child: ButtonTheme(
|
|
colorScheme: colorScheme,
|
|
textTheme: ButtonTextTheme.primary,
|
|
child: FlatButton(
|
|
child: const Text('FlatButton'),
|
|
onPressed: () {},
|
|
focusNode: focusNode,
|
|
textColor: MaterialStateColor.resolveWith(getTextColor),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
// Default, not disabled.
|
|
await expectLater(tester, meetsGuideline(textContrastGuideline));
|
|
|
|
// Focused.
|
|
focusNode.requestFocus();
|
|
await tester.pumpAndSettle();
|
|
await expectLater(tester, meetsGuideline(textContrastGuideline));
|
|
|
|
// Hovered.
|
|
final Offset center = tester.getCenter(find.byType(FlatButton));
|
|
final TestGesture gesture = await tester.createGesture(
|
|
kind: PointerDeviceKind.mouse,
|
|
);
|
|
await gesture.addPointer();
|
|
addTearDown(gesture.removePointer);
|
|
await gesture.moveTo(center);
|
|
await tester.pumpAndSettle();
|
|
await expectLater(tester, meetsGuideline(textContrastGuideline));
|
|
|
|
// Highlighted (pressed).
|
|
await gesture.down(center);
|
|
await tester.pump(); // Start the splash and highlight animations.
|
|
await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way.
|
|
await expectLater(tester, meetsGuideline(textContrastGuideline));
|
|
},
|
|
semanticsEnabled: true,
|
|
skip: isBrowser,
|
|
);
|
|
|
|
testWidgets('FlatButton uses stateful color for text color in different states', (WidgetTester tester) async {
|
|
final FocusNode focusNode = FocusNode();
|
|
|
|
const Color pressedColor = Color(0x00000001);
|
|
const Color hoverColor = Color(0x00000002);
|
|
const Color focusedColor = Color(0x00000003);
|
|
const Color defaultColor = Color(0x00000004);
|
|
|
|
Color getTextColor(Set<MaterialState> states) {
|
|
if (states.contains(MaterialState.pressed)) {
|
|
return pressedColor;
|
|
}
|
|
if (states.contains(MaterialState.hovered)) {
|
|
return hoverColor;
|
|
}
|
|
if (states.contains(MaterialState.focused)) {
|
|
return focusedColor;
|
|
}
|
|
return defaultColor;
|
|
}
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(
|
|
body: Center(
|
|
child: FlatButton(
|
|
child: const Text('FlatButton'),
|
|
onPressed: () {},
|
|
focusNode: focusNode,
|
|
textColor: MaterialStateColor.resolveWith(getTextColor),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
Color textColor() {
|
|
return tester.renderObject<RenderParagraph>(find.text('FlatButton')).text.style.color;
|
|
}
|
|
|
|
// Default, not disabled.
|
|
expect(textColor(), equals(defaultColor));
|
|
|
|
// Focused.
|
|
focusNode.requestFocus();
|
|
await tester.pumpAndSettle();
|
|
expect(textColor(), focusedColor);
|
|
|
|
// Hovered.
|
|
final Offset center = tester.getCenter(find.byType(FlatButton));
|
|
final TestGesture gesture = await tester.createGesture(
|
|
kind: PointerDeviceKind.mouse,
|
|
);
|
|
await gesture.addPointer();
|
|
addTearDown(gesture.removePointer);
|
|
await gesture.moveTo(center);
|
|
await tester.pumpAndSettle();
|
|
expect(textColor(), hoverColor);
|
|
|
|
// Highlighted (pressed).
|
|
await gesture.down(center);
|
|
await tester.pump(); // Start the splash and highlight animations.
|
|
await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way.
|
|
expect(textColor(), pressedColor);
|
|
});
|
|
|
|
testWidgets('FlatButton uses stateful color for icon color in different states', (WidgetTester tester) async {
|
|
final FocusNode focusNode = FocusNode();
|
|
final Key buttonKey = UniqueKey();
|
|
|
|
const Color pressedColor = Color(0x00000001);
|
|
const Color hoverColor = Color(0x00000002);
|
|
const Color focusedColor = Color(0x00000003);
|
|
const Color defaultColor = Color(0x00000004);
|
|
|
|
Color getTextColor(Set<MaterialState> states) {
|
|
if (states.contains(MaterialState.pressed)) {
|
|
return pressedColor;
|
|
}
|
|
if (states.contains(MaterialState.hovered)) {
|
|
return hoverColor;
|
|
}
|
|
if (states.contains(MaterialState.focused)) {
|
|
return focusedColor;
|
|
}
|
|
return defaultColor;
|
|
}
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(
|
|
body: Center(
|
|
child: FlatButton.icon(
|
|
key: buttonKey,
|
|
icon: const Icon(Icons.add),
|
|
label: const Text('FlatButton'),
|
|
onPressed: () {},
|
|
focusNode: focusNode,
|
|
textColor: MaterialStateColor.resolveWith(getTextColor),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
Color iconColor() => _iconStyle(tester, Icons.add).color;
|
|
// Default, not disabled.
|
|
expect(iconColor(), equals(defaultColor));
|
|
|
|
// Focused.
|
|
focusNode.requestFocus();
|
|
await tester.pumpAndSettle();
|
|
expect(iconColor(), focusedColor);
|
|
|
|
// Hovered.
|
|
final Offset center = tester.getCenter(find.byKey(buttonKey));
|
|
final TestGesture gesture = await tester.createGesture(
|
|
kind: PointerDeviceKind.mouse,
|
|
);
|
|
await gesture.addPointer();
|
|
addTearDown(gesture.removePointer);
|
|
await gesture.moveTo(center);
|
|
await tester.pumpAndSettle();
|
|
expect(iconColor(), hoverColor);
|
|
|
|
// Highlighted (pressed).
|
|
await gesture.down(center);
|
|
await tester.pump(); // Start the splash and highlight animations.
|
|
await tester.pump(const Duration(milliseconds: 800)); // Wait for splash and highlight to be well under way.
|
|
expect(iconColor(), pressedColor);
|
|
});
|
|
|
|
testWidgets('FlatButton ignores disabled text color if text color is stateful', (WidgetTester tester) async {
|
|
final FocusNode focusNode = FocusNode();
|
|
|
|
const Color disabledColor = Color(0x00000001);
|
|
const Color defaultColor = Color(0x00000002);
|
|
const Color unusedDisabledTextColor = Color(0x00000003);
|
|
|
|
Color getTextColor(Set<MaterialState> states) {
|
|
if (states.contains(MaterialState.disabled)) {
|
|
return disabledColor;
|
|
}
|
|
return defaultColor;
|
|
}
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Scaffold(
|
|
body: Center(
|
|
child: FlatButton(
|
|
onPressed: null,
|
|
child: const Text('FlatButton'),
|
|
focusNode: focusNode,
|
|
textColor: MaterialStateColor.resolveWith(getTextColor),
|
|
disabledTextColor: unusedDisabledTextColor,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
Color textColor() {
|
|
return tester.renderObject<RenderParagraph>(find.text('FlatButton')).text.style.color;
|
|
}
|
|
|
|
// Disabled.
|
|
expect(textColor(), equals(disabledColor));
|
|
expect(textColor(), isNot(unusedDisabledTextColor));
|
|
});
|
|
|
|
testWidgets('FlatButton has no clip by default', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Material(
|
|
child: FlatButton(
|
|
child: Container(),
|
|
onPressed: () { /* to make sure the button is enabled */ },
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(
|
|
tester.renderObject(find.byType(FlatButton)),
|
|
paintsExactlyCountTimes(#clipPath, 0),
|
|
);
|
|
});
|
|
|
|
testWidgets('Does FlatButton work with hover', (WidgetTester tester) async {
|
|
const Color hoverColor = Color(0xff001122);
|
|
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: FlatButton(
|
|
hoverColor: hoverColor,
|
|
onPressed: () { },
|
|
child: const Text('button'),
|
|
),
|
|
),
|
|
);
|
|
|
|
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
|
|
await gesture.addPointer();
|
|
await gesture.moveTo(tester.getCenter(find.byType(FlatButton)));
|
|
await tester.pumpAndSettle();
|
|
|
|
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
|
|
expect(inkFeatures, paints..rect(color: hoverColor));
|
|
|
|
await gesture.removePointer();
|
|
});
|
|
|
|
testWidgets('Does FlatButton work with focus', (WidgetTester tester) async {
|
|
const Color focusColor = Color(0xff001122);
|
|
|
|
final FocusNode focusNode = FocusNode(debugLabel: 'FlatButton Node');
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: FlatButton(
|
|
focusColor: focusColor,
|
|
focusNode: focusNode,
|
|
onPressed: () { },
|
|
child: const Text('button'),
|
|
),
|
|
),
|
|
);
|
|
|
|
WidgetsBinding.instance.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
|
|
focusNode.requestFocus();
|
|
await tester.pumpAndSettle();
|
|
|
|
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
|
|
expect(inkFeatures, paints..rect(color: focusColor));
|
|
});
|
|
|
|
testWidgets('Does FlatButton contribute semantics', (WidgetTester tester) async {
|
|
final SemanticsTester semantics = SemanticsTester(tester);
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Material(
|
|
child: Center(
|
|
child: FlatButton(
|
|
onPressed: () { },
|
|
child: const Text('ABC'),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(semantics, hasSemantics(
|
|
TestSemantics.root(
|
|
children: <TestSemantics>[
|
|
TestSemantics.rootChild(
|
|
actions: <SemanticsAction>[
|
|
SemanticsAction.tap,
|
|
],
|
|
label: 'ABC',
|
|
rect: const Rect.fromLTRB(0.0, 0.0, 88.0, 48.0),
|
|
transform: Matrix4.translationValues(356.0, 276.0, 0.0),
|
|
flags: <SemanticsFlag>[
|
|
SemanticsFlag.hasEnabledState,
|
|
SemanticsFlag.isButton,
|
|
SemanticsFlag.isEnabled,
|
|
SemanticsFlag.isFocusable,
|
|
],
|
|
),
|
|
],
|
|
),
|
|
ignoreId: true,
|
|
));
|
|
|
|
semantics.dispose();
|
|
});
|
|
|
|
testWidgets('Does FlatButton scale with font scale changes', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Material(
|
|
child: MediaQuery(
|
|
data: const MediaQueryData(textScaleFactor: 1.0),
|
|
child: Center(
|
|
child: FlatButton(
|
|
onPressed: () { },
|
|
child: const Text('ABC'),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(tester.getSize(find.byType(FlatButton)), equals(const Size(88.0, 48.0)));
|
|
expect(tester.getSize(find.byType(Text)), equals(const Size(42.0, 14.0)));
|
|
|
|
// textScaleFactor expands text, but not button.
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Material(
|
|
child: MediaQuery(
|
|
data: const MediaQueryData(textScaleFactor: 1.3),
|
|
child: Center(
|
|
child: FlatButton(
|
|
onPressed: () { },
|
|
child: const Text('ABC'),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(tester.getSize(find.byType(FlatButton)), equals(const Size(88.0, 48.0)));
|
|
// Scaled text rendering is different on Linux and Mac by one pixel.
|
|
// TODO(gspencergoog): Figure out why this is, and fix it. https://github.com/flutter/flutter/issues/12357
|
|
expect(tester.getSize(find.byType(Text)).width, isIn(<double>[54.0, 55.0]));
|
|
expect(tester.getSize(find.byType(Text)).height, isIn(<double>[18.0, 19.0]));
|
|
|
|
// Set text scale large enough to expand text and button.
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Material(
|
|
child: MediaQuery(
|
|
data: const MediaQueryData(textScaleFactor: 3.0),
|
|
child: Center(
|
|
child: FlatButton(
|
|
onPressed: () { },
|
|
child: const Text('ABC'),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
// Scaled text rendering is different on Linux and Mac by one pixel.
|
|
// TODO(gspencergoog): Figure out why this is, and fix it. https://github.com/flutter/flutter/issues/12357
|
|
expect(tester.getSize(find.byType(FlatButton)).width, isIn(<double>[158.0, 159.0]));
|
|
expect(tester.getSize(find.byType(FlatButton)).height, equals(48.0));
|
|
expect(tester.getSize(find.byType(Text)).width, isIn(<double>[126.0, 127.0]));
|
|
expect(tester.getSize(find.byType(Text)).height, equals(42.0));
|
|
}, skip: isBrowser);
|
|
|
|
testWidgets('FlatButton size is configurable by ThemeData.materialTapTargetSize', (WidgetTester tester) async {
|
|
final Key key1 = UniqueKey();
|
|
await tester.pumpWidget(
|
|
Theme(
|
|
data: ThemeData(materialTapTargetSize: MaterialTapTargetSize.padded),
|
|
child: Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Material(
|
|
child: Center(
|
|
child: FlatButton(
|
|
key: key1,
|
|
child: const SizedBox(width: 50.0, height: 8.0),
|
|
onPressed: () { },
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(tester.getSize(find.byKey(key1)), const Size(88.0, 48.0));
|
|
|
|
final Key key2 = UniqueKey();
|
|
await tester.pumpWidget(
|
|
Theme(
|
|
data: ThemeData(materialTapTargetSize: MaterialTapTargetSize.shrinkWrap),
|
|
child: Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Material(
|
|
child: Center(
|
|
child: FlatButton(
|
|
key: key2,
|
|
child: const SizedBox(width: 50.0, height: 8.0),
|
|
onPressed: () { },
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(tester.getSize(find.byKey(key2)), const Size(88.0, 36.0));
|
|
});
|
|
|
|
testWidgets('FlatButton onPressed and onLongPress callbacks are correctly called when non-null', (WidgetTester tester) async {
|
|
bool wasPressed;
|
|
Finder flatButton;
|
|
|
|
Widget buildFrame({ VoidCallback onPressed, VoidCallback onLongPress }) {
|
|
return Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: FlatButton(
|
|
child: const Text('button'),
|
|
onPressed: onPressed,
|
|
onLongPress: onLongPress,
|
|
),
|
|
);
|
|
}
|
|
|
|
// onPressed not null, onLongPress null.
|
|
wasPressed = false;
|
|
await tester.pumpWidget(
|
|
buildFrame(onPressed: () { wasPressed = true; }, onLongPress: null),
|
|
);
|
|
flatButton = find.byType(FlatButton);
|
|
expect(tester.widget<FlatButton>(flatButton).enabled, true);
|
|
await tester.tap(flatButton);
|
|
expect(wasPressed, true);
|
|
|
|
// onPressed null, onLongPress not null.
|
|
wasPressed = false;
|
|
await tester.pumpWidget(
|
|
buildFrame(onPressed: null, onLongPress: () { wasPressed = true; }),
|
|
);
|
|
flatButton = find.byType(FlatButton);
|
|
expect(tester.widget<FlatButton>(flatButton).enabled, true);
|
|
await tester.longPress(flatButton);
|
|
expect(wasPressed, true);
|
|
|
|
// onPressed null, onLongPress null.
|
|
await tester.pumpWidget(
|
|
buildFrame(onPressed: null, onLongPress: null),
|
|
);
|
|
flatButton = find.byType(FlatButton);
|
|
expect(tester.widget<FlatButton>(flatButton).enabled, false);
|
|
});
|
|
|
|
testWidgets('FlatButton onPressed and onLongPress callbacks are distinctly recognized', (WidgetTester tester) async {
|
|
bool didPressButton = false;
|
|
bool didLongPressButton = false;
|
|
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: FlatButton(
|
|
onPressed: () {
|
|
didPressButton = true;
|
|
},
|
|
onLongPress: () {
|
|
didLongPressButton = true;
|
|
},
|
|
child: const Text('button'),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Finder flatButton = find.byType(FlatButton);
|
|
expect(tester.widget<FlatButton>(flatButton).enabled, true);
|
|
|
|
expect(didPressButton, isFalse);
|
|
await tester.tap(flatButton);
|
|
expect(didPressButton, isTrue);
|
|
|
|
expect(didLongPressButton, isFalse);
|
|
await tester.longPress(flatButton);
|
|
expect(didLongPressButton, isTrue);
|
|
});
|
|
|
|
testWidgets('FlatButton responds to density changes.', (WidgetTester tester) async {
|
|
const Key key = Key('test');
|
|
const Key childKey = Key('test child');
|
|
|
|
Future<void> buildTest(VisualDensity visualDensity, {bool useText = false}) async {
|
|
return await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: Directionality(
|
|
textDirection: TextDirection.rtl,
|
|
child: Center(
|
|
child: FlatButton(
|
|
visualDensity: visualDensity,
|
|
key: key,
|
|
onPressed: () {},
|
|
child: useText ? const Text('Text', key: childKey) : Container(key: childKey, width: 100, height: 100, color: const Color(0xffff0000)),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
await buildTest(const VisualDensity());
|
|
final RenderBox box = tester.renderObject(find.byKey(key));
|
|
Rect childRect = tester.getRect(find.byKey(childKey));
|
|
await tester.pumpAndSettle();
|
|
expect(box.size, equals(const Size(132, 100)));
|
|
expect(childRect, equals(const Rect.fromLTRB(350, 250, 450, 350)));
|
|
|
|
await buildTest(const VisualDensity(horizontal: 3.0, vertical: 3.0));
|
|
await tester.pumpAndSettle();
|
|
childRect = tester.getRect(find.byKey(childKey));
|
|
expect(box.size, equals(const Size(156, 124)));
|
|
expect(childRect, equals(const Rect.fromLTRB(350, 250, 450, 350)));
|
|
|
|
await buildTest(const VisualDensity(horizontal: -3.0, vertical: -3.0));
|
|
await tester.pumpAndSettle();
|
|
childRect = tester.getRect(find.byKey(childKey));
|
|
expect(box.size, equals(const Size(108, 100)));
|
|
expect(childRect, equals(const Rect.fromLTRB(350, 250, 450, 350)));
|
|
|
|
await buildTest(const VisualDensity(), useText: true);
|
|
await tester.pumpAndSettle();
|
|
childRect = tester.getRect(find.byKey(childKey));
|
|
expect(box.size, equals(const Size(88, 48)));
|
|
expect(childRect, equals(const Rect.fromLTRB(372.0, 293.0, 428.0, 307.0)));
|
|
|
|
await buildTest(const VisualDensity(horizontal: 3.0, vertical: 3.0), useText: true);
|
|
await tester.pumpAndSettle();
|
|
childRect = tester.getRect(find.byKey(childKey));
|
|
expect(box.size, equals(const Size(112, 60)));
|
|
expect(childRect, equals(const Rect.fromLTRB(372.0, 293.0, 428.0, 307.0)));
|
|
|
|
await buildTest(const VisualDensity(horizontal: -3.0, vertical: -3.0), useText: true);
|
|
await tester.pumpAndSettle();
|
|
childRect = tester.getRect(find.byKey(childKey));
|
|
expect(box.size, equals(const Size(76, 36)));
|
|
expect(childRect, equals(const Rect.fromLTRB(372.0, 293.0, 428.0, 307.0)));
|
|
});
|
|
}
|
|
|
|
TextStyle _iconStyle(WidgetTester tester, IconData icon) {
|
|
final RichText iconRichText = tester.widget<RichText>(
|
|
find.descendant(of: find.byIcon(icon), matching: find.byType(RichText)),
|
|
);
|
|
return iconRichText.text.style;
|
|
}
|