Unverified Commit 6a7baf57 authored by Bruno Leroux's avatar Bruno Leroux Committed by GitHub

Fix M3 text field height + initial step for input decorator M3 test migration (#142981)

## Description

This PR main purpose is to make progress on the M3 test migration for `InputDecorator` (see https://github.com/flutter/flutter/issues/139076).

Before this PR more than 80 of the 156 tests defined in `input_decorator_test.dart` fail on M3.
Migrating all those tests in one shot is not easy at all because many failures are related to wrong positionning due to M3 typography changes. Another reason is that several M3 specific changes are required in order to get a proper M3 compliant text field, for instance:
- https://github.com/flutter/flutter/issues/142972
- https://github.com/flutter/flutter/issues/141354

Most of the tests were relying on an helper function (`buildInputDecorator`) which had a `useMaterial3` parameter. Unfortunately when `useMaterial3: true `was passed to this function it forced `useMaterial3: false` at the top level but overrided it at a lower level, which was very misleading because people could assume that the tests are ok with M3 (but in fact they were run using M2 typography but have some M3 logic in use).
I considered various way to make this change and I finally decided to run all existing tests only on M2 for the moment. Next step will be to move most of those tests to M3. In this PR, I migrated two of these existing tests for illustration.

Because many of the existing tests are checking input decorator height, I think it would also make sense to fix https://github.com/flutter/flutter/issues/142972 first. That's why I choosed to include a fix to https://github.com/flutter/flutter/issues/142972 in this PR.

A M3 filled `TextField` on Android:

| Before this PR | After this PR |
|--------|--------|
| ![image](https://github.com/flutter/flutter/assets/840911/403225b7-4c91-4aee-b19c-0490447ae7e3) | ![image](https://github.com/flutter/flutter/assets/840911/e96cf786-a9f5-4e15-bcdd-078350ff1608) | 

## Related Issue

Fixes https://github.com/flutter/flutter/issues/142972
Related to https://github.com/flutter/flutter/issues/139076

## Tests

Updates many existing tests 
+ adds 2 tests related to the fix for https://github.com/flutter/flutter/issues/142972
+ adds 1 tests for the M3 migration
+ move 1 tests related to M3
parent c539ded6
......@@ -11,6 +11,6 @@ void main() {
await tester.pumpWidget(
const example.PrefixIconExampleApp(),
);
expect(tester.getCenter(find.byIcon(Icons.person)).dy, 32.0);
expect(tester.getCenter(find.byIcon(Icons.person)).dy, 28.0);
});
}
......@@ -11,6 +11,6 @@ void main() {
await tester.pumpWidget(
const example.SuffixIconExampleApp(),
);
expect(tester.getCenter(find.byIcon(Icons.remove_red_eye)).dy, 32.0);
expect(tester.getCenter(find.byIcon(Icons.remove_red_eye)).dy, 28.0);
});
}
......@@ -2393,30 +2393,42 @@ class _InputDecoratorState extends State<InputDecorator> with TickerProviderStat
final EdgeInsets contentPadding;
final double floatingLabelHeight;
if (decoration.isCollapsed
?? themeData.inputDecorationTheme.isCollapsed) {
if (decoration.isCollapsed ?? themeData.inputDecorationTheme.isCollapsed) {
floatingLabelHeight = 0.0;
contentPadding = decorationContentPadding ?? EdgeInsets.zero;
} else if (!border.isOutline) {
// 4.0: the vertical gap between the inline elements and the floating label.
floatingLabelHeight = MediaQuery.textScalerOf(context).scale(4.0 + 0.75 * labelStyle.fontSize!);
if (decoration.filled ?? false) {
contentPadding = decorationContentPadding ?? (decorationIsDense
? const EdgeInsets.fromLTRB(12.0, 8.0, 12.0, 8.0)
: const EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 12.0));
contentPadding = decorationContentPadding ?? (Theme.of(context).useMaterial3
? decorationIsDense
? const EdgeInsets.fromLTRB(12.0, 4.0, 12.0, 4.0)
: const EdgeInsets.fromLTRB(12.0, 8.0, 12.0, 8.0)
: decorationIsDense
? const EdgeInsets.fromLTRB(12.0, 8.0, 12.0, 8.0)
: const EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 12.0));
} else {
// Not left or right padding for underline borders that aren't filled
// No left or right padding for underline borders that aren't filled
// is a small concession to backwards compatibility. This eliminates
// the most noticeable layout change introduced by #13734.
contentPadding = decorationContentPadding ?? (decorationIsDense
? const EdgeInsets.fromLTRB(0.0, 8.0, 0.0, 8.0)
: const EdgeInsets.fromLTRB(0.0, 12.0, 0.0, 12.0));
contentPadding = decorationContentPadding ?? (Theme.of(context).useMaterial3
? decorationIsDense
? const EdgeInsets.fromLTRB(0.0, 4.0, 0.0, 4.0)
: const EdgeInsets.fromLTRB(0.0, 8.0, 0.0, 8.0)
: decorationIsDense
? const EdgeInsets.fromLTRB(0.0, 8.0, 0.0, 8.0)
: const EdgeInsets.fromLTRB(0.0, 12.0, 0.0, 12.0));
}
} else {
floatingLabelHeight = 0.0;
contentPadding = decorationContentPadding ?? (decorationIsDense
? const EdgeInsets.fromLTRB(12.0, 20.0, 12.0, 12.0)
: const EdgeInsets.fromLTRB(12.0, 24.0, 12.0, 16.0));
contentPadding = decorationContentPadding ?? (Theme.of(context).useMaterial3
? decorationIsDense
? const EdgeInsets.fromLTRB(12.0, 16.0, 12.0, 8.0)
: const EdgeInsets.fromLTRB(12.0, 20.0, 12.0, 12.0)
: decorationIsDense
? const EdgeInsets.fromLTRB(12.0, 20.0, 12.0, 12.0)
: const EdgeInsets.fromLTRB(12.0, 24.0, 12.0, 16.0));
}
final _Decorator decorator = _Decorator(
......
......@@ -234,7 +234,7 @@ void main() {
expect(value, null); // disabledHint shown.
final Offset hintEmptyLabel = tester.getTopLeft(find.text('labelText'));
expect(hintEmptyLabel, const Offset(0.0, 12.0));
expect(hintEmptyLabel, const Offset(0.0, 8.0));
});
testWidgets('label position test - show disabledHint: enable + null item', (WidgetTester tester) async {
......@@ -259,7 +259,7 @@ void main() {
expect(value, null); // disabledHint shown.
final Offset hintEmptyLabel = tester.getTopLeft(find.text('labelText'));
expect(hintEmptyLabel, const Offset(0.0, 12.0));
expect(hintEmptyLabel, const Offset(0.0, 8.0));
});
testWidgets('label position test - show disabledHint: enable + empty item', (WidgetTester tester) async {
......@@ -284,7 +284,7 @@ void main() {
expect(value, null); // disabledHint shown.
final Offset hintEmptyLabel = tester.getTopLeft(find.text('labelText'));
expect(hintEmptyLabel, const Offset(0.0, 12.0));
expect(hintEmptyLabel, const Offset(0.0, 8.0));
});
testWidgets('label position test - show hint: enable + empty item', (WidgetTester tester) async {
......@@ -309,7 +309,7 @@ void main() {
expect(value, null); // hint shown.
final Offset hintEmptyLabel = tester.getTopLeft(find.text('labelText'));
expect(hintEmptyLabel, const Offset(0.0, 12.0));
expect(hintEmptyLabel, const Offset(0.0, 8.0));
});
testWidgets('label position test - no hint shown: enable + no selected + disabledHint', (WidgetTester tester) async {
......@@ -347,7 +347,7 @@ void main() {
expect(value, null);
final Offset hintEmptyLabel = tester.getTopLeft(find.text('labelText'));
expect(hintEmptyLabel, const Offset(0.0, 24.0));
expect(hintEmptyLabel, const Offset(0.0, 20.0));
});
testWidgets('label position test - show selected item: disabled + hint + disabledHint', (WidgetTester tester) async {
......@@ -386,7 +386,7 @@ void main() {
expect(value, 1);
final Offset hintEmptyLabel = tester.getTopLeft(find.text('labelText'));
expect(hintEmptyLabel, const Offset(0.0, 12.0));
expect(hintEmptyLabel, const Offset(0.0, 8.0));
});
// Regression test for https://github.com/flutter/flutter/issues/82910
......@@ -603,7 +603,7 @@ void main() {
final RenderBox box =
tester.renderObject<RenderBox>(find.byType(dropdownButtonType));
expect(box.size.height, 72.0);
expect(box.size.height, 64.0);
});
testWidgets('DropdownButtonFormField.isDense is true by default', (WidgetTester tester) async {
......
......@@ -2408,11 +2408,11 @@ void main() {
await tester.pumpWidget(buildFrame(isFormField: true, buttonKey: buttonKey, onChanged: onChanged, focusNode: focusNode, autofocus: true));
await tester.pumpAndSettle(); // Pump a frame for autofocus to take effect.
expect(focusNode.hasPrimaryFocus, isTrue);
expect(find.byType(Material), paints ..rect(rect: const Rect.fromLTRB(0.0, 264.0, 800.0, 336.0), color: const Color(0x1f000000)));
expect(find.byType(Material), paints ..rect(rect: const Rect.fromLTRB(0.0, 268.0, 800.0, 332.0), color: const Color(0x1f000000)));
await tester.pumpWidget(buildFrame(isFormField: true, buttonKey: buttonKey, onChanged: onChanged, focusNode: focusNode, focusColor: const Color(0xff00ff00)));
await tester.pumpAndSettle(); // Pump a frame for autofocus to take effect.
expect(find.byType(Material), paints ..rect(rect: const Rect.fromLTRB(0.0, 264.0, 800.0, 336.0), color: const Color(0x1f00ff00)));
expect(find.byType(Material), paints ..rect(rect: const Rect.fromLTRB(0.0, 268.0, 800.0, 332.0), color: const Color(0x1f00ff00)));
});
testWidgets("DropdownButton won't be focused if not enabled", (WidgetTester tester) async {
......
......@@ -14,9 +14,8 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
Widget buildInputDecorator({
Widget buildInputDecoratorM2({
InputDecoration decoration = const InputDecoration(),
ThemeData? theme,
InputDecorationTheme? inputDecorationTheme,
......@@ -25,7 +24,6 @@ Widget buildInputDecorator({
bool isEmpty = false,
bool isFocused = false,
bool isHovering = false,
bool useMaterial3 = false,
bool useIntrinsicWidth = false,
TextStyle? baseStyle,
TextAlignVertical? textAlignVertical,
......@@ -59,7 +57,6 @@ Widget buildInputDecorator({
data: (theme ?? Theme.of(context)).copyWith(
inputDecorationTheme: inputDecorationTheme,
visualDensity: visualDensity,
useMaterial3: useMaterial3,
textTheme: const TextTheme(bodyLarge: TextStyle(fontSize: 16.0)),
),
child: Align(
......@@ -76,6 +73,63 @@ Widget buildInputDecorator({
);
}
Widget buildInputDecorator({
InputDecoration decoration = const InputDecoration(),
ThemeData? theme,
InputDecorationTheme? inputDecorationTheme,
TextDirection textDirection = TextDirection.ltr,
bool expands = false,
bool isEmpty = false,
bool isFocused = false,
bool isHovering = false,
bool useIntrinsicWidth = false,
TextStyle? baseStyle,
TextAlignVertical? textAlignVertical,
VisualDensity? visualDensity,
Widget child = const Text(
'text',
// Use a text style copliant with M3 specification (which is bodyLarge for text fields).
style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.w400, letterSpacing: 0.5, height: 1.50)
),
}) {
Widget widget = InputDecorator(
expands: expands,
decoration: decoration,
isEmpty: isEmpty,
isFocused: isFocused,
isHovering: isHovering,
baseStyle: baseStyle,
textAlignVertical: textAlignVertical,
child: child,
);
if (useIntrinsicWidth) {
widget = IntrinsicWidth(child: widget);
}
return MaterialApp(
home: Material(
child: Builder(
builder: (BuildContext context) {
return Theme(
data: (theme ?? Theme.of(context)).copyWith(
inputDecorationTheme: inputDecorationTheme,
visualDensity: visualDensity,
),
child: Align(
alignment: Alignment.topLeft,
child: Directionality(
textDirection: textDirection,
child: widget,
),
),
);
},
),
),
);
}
Finder findBorderPainter() {
return find.descendant(
of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_BorderContainer'),
......@@ -102,7 +156,7 @@ Rect getLabelRect(WidgetTester tester) {
TextStyle getLabelStyle(WidgetTester tester) {
return tester.firstWidget<AnimatedDefaultTextStyle>(
find.ancestor(
of: find.text('label'),
of: findLabel(),
matching: find.byType(AnimatedDefaultTextStyle),
),
).style;
......@@ -164,19 +218,102 @@ TextStyle? getIconStyle(WidgetTester tester, IconData icon) {
}
void main() {
runAllTests(useMaterial3: true);
runAllTests(useMaterial3: false);
runAllM2Tests();
// TODO(bleroux): migrate all M2 tests to M3.
// See https://github.com/flutter/flutter/issues/139076?
// For illustration, two of the existing tests are migrated below.
// Work is in progress to migrate the other tests.
testWidgets('Material3 - Input/label layout: label appears above input', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
decoration: const InputDecoration(
labelText: 'label',
),
),
);
// Overall height for this InputDecorator is 56dp on mobile:
// 8 - top padding
// 12 - floating label (font size = 16 * 0.75, line height is forced to 1.0)
// 4 - gap between label and input
// 24 - input text (font size = 16, line height = 1.5)
// 8 - bottom padding
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('label')).dy, 8.0);
expect(tester.getBottomLeft(find.text('label')).dy, 20.0);
expect(tester.getTopLeft(find.text('text')).dy, 24.0);
expect(tester.getBottomLeft(find.text('text')).dy, 48.0);
expect(getBorderBottom(tester), 56.0);
expect(getBorderWeight(tester), 1.0);
});
testWidgets('Material3 - Floating label is aligned with prefixIcon by default', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
decoration: const InputDecoration(
prefixIcon: Icon(Icons.ac_unit),
labelText: 'label',
border: OutlineInputBorder(),
),
isFocused: true,
),
);
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('label')).dx, 12.0);
expect(tester.getBottomLeft(find.text('text')).dx, 48.0);
expect(getBorderWeight(tester), 2.0);
});
// During the tests migration to M3, add new M3 tests below.
// TODO(bleroux): remove this comment when migration is done.
testWidgets('Material3 - Default height is 56dp on mobile', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
decoration: const InputDecoration(
labelText: 'label',
),
),
);
// Overall height for this InputDecorator is 56dp on mobile:
// 8 - top padding
// 12 - floating label (font size = 16 * 0.75, line height is forced to 1.0)
// 4 - gap between label and input
// 24 - input text (font size = 16, line height = 1.5)
// 8 - bottom padding
// TODO(bleroux): fix input decorator to not rely on a 4 pixels gap between the label and the input,
// this gap is not compliant with the M3 spec (M3 spec uses line height for this purpose).
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
}, variant: TargetPlatformVariant.mobile());
testWidgets('Material3 - Default height is 48dp on desktop', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
decoration: const InputDecoration(
labelText: 'label',
),
),
);
// Overall height for this InputDecorator is 48dp on desktop:
// 4 - top padding
// 12 - floating label (font size = 16 * 0.75, line height is forced to 1.0)
// 4 - gap between label and input
// 24 - input text (font size = 16, line height = 1.5)
// 4 - bottom padding
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0));
}, variant: TargetPlatformVariant.desktop());
}
void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator input/label text layout',
// TODO(polina-c): clean up leaks, https://github.com/flutter/flutter/issues/134787 [leaks-to-clean]
experimentalLeakTesting: LeakTesting.settings.withIgnoredAll(),
(WidgetTester tester) async {
void runAllM2Tests() {
testWidgets('InputDecorator input/label text layout', (WidgetTester tester) async {
// The label appears above the input text
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -203,8 +340,7 @@ void runAllTests({ required bool useMaterial3 }) {
// The label appears within the input when there is no text content
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -218,8 +354,7 @@ void runAllTests({ required bool useMaterial3 }) {
// The label appears above the input text when there is no content and floatingLabelBehavior is always
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -234,8 +369,7 @@ void runAllTests({ required bool useMaterial3 }) {
// The label appears within the input text when there is content and floatingLabelBehavior is never
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isFocused: false (default)
decoration: const InputDecoration(
labelText: 'label',
......@@ -259,8 +393,7 @@ void runAllTests({ required bool useMaterial3 }) {
// isFocused: true increases the border's weight from 1.0 to 2.0
// but does not change the overall height.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
isFocused: true,
decoration: const InputDecoration(
......@@ -279,8 +412,7 @@ void runAllTests({ required bool useMaterial3 }) {
// isEmpty: true causes the label to be aligned with the input text
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
decoration: const InputDecoration(
labelText: 'label',
......@@ -309,8 +441,7 @@ void runAllTests({ required bool useMaterial3 }) {
// isFocused: true causes the label to move back up above the input text.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
isFocused: true,
decoration: const InputDecoration(
......@@ -340,8 +471,7 @@ void runAllTests({ required bool useMaterial3 }) {
// enabled: false produces a hairline border if filled: false (the default)
// The widget's size and layout is the same as for enabled: true.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
decoration: const InputDecoration(
labelText: 'label',
......@@ -355,13 +485,12 @@ void runAllTests({ required bool useMaterial3 }) {
expect(tester.getBottomLeft(find.text('text')).dy, 44.0);
expect(tester.getTopLeft(find.text('label')).dy, 20.0);
expect(tester.getBottomLeft(find.text('label')).dy, 36.0);
expect(getBorderWeight(tester), useMaterial3 ? 1.0 : 0.0);
expect(getBorderWeight(tester), 0.0);
// enabled: false produces a transparent border if filled: true.
// The widget's size and layout is the same as for enabled: true.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
decoration: const InputDecoration(
labelText: 'label',
......@@ -376,14 +505,12 @@ void runAllTests({ required bool useMaterial3 }) {
expect(tester.getBottomLeft(find.text('text')).dy, 44.0);
expect(tester.getTopLeft(find.text('label')).dy, 20.0);
expect(tester.getBottomLeft(find.text('label')).dy, 36.0);
final ThemeData theme = ThemeData.from(colorScheme: const ColorScheme.light());
expect(getBorderColor(tester), useMaterial3 ? theme.colorScheme.onSurface.withOpacity(0.38) : Colors.transparent);
expect(getBorderColor(tester), Colors.transparent);
// alignLabelWithHint: true positions the label at the text baseline,
// aligned with the hint.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
decoration: const InputDecoration(
labelText: 'label',
......@@ -394,10 +521,8 @@ void runAllTests({ required bool useMaterial3 }) {
);
await tester.pumpAndSettle();
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
if (!useMaterial3) {
expect(tester.getTopLeft(find.text('label')).dy, tester.getTopLeft(find.text('hint')).dy);
expect(tester.getBottomLeft(find.text('label')).dy, tester.getBottomLeft(find.text('hint')).dy);
}
expect(tester.getTopLeft(find.text('label')).dy, tester.getTopLeft(find.text('hint')).dy);
expect(tester.getBottomLeft(find.text('label')).dy, tester.getBottomLeft(find.text('hint')).dy);
});
testWidgets('InputDecorator input/label widget layout', (WidgetTester tester) async {
......@@ -405,8 +530,7 @@ void runAllTests({ required bool useMaterial3 }) {
// The label appears above the input text.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -444,8 +568,7 @@ void runAllTests({ required bool useMaterial3 }) {
// The label appears within the input when there is no text content.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -471,8 +594,7 @@ void runAllTests({ required bool useMaterial3 }) {
// The label appears above the input text when there is no content and the
// floatingLabelBehavior is set to always.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -499,8 +621,7 @@ void runAllTests({ required bool useMaterial3 }) {
// The label appears within the input text when there is content and
// the floatingLabelBehavior is set to never.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isFocused: false (default)
decoration: const InputDecoration(
label: Text.rich(
......@@ -535,8 +656,7 @@ void runAllTests({ required bool useMaterial3 }) {
// isFocused: true increases the border's weight from 1.0 to 2.0
// but does not change the overall height.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
isFocused: true,
decoration: const InputDecoration(
......@@ -566,8 +686,7 @@ void runAllTests({ required bool useMaterial3 }) {
// isEmpty: true causes the label to be aligned with the input text.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
decoration: const InputDecoration(
label: Text.rich(
......@@ -606,8 +725,7 @@ void runAllTests({ required bool useMaterial3 }) {
// isFocused: true causes the label to move back up above the input text.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
isFocused: true,
decoration: const InputDecoration(
......@@ -650,8 +768,7 @@ void runAllTests({ required bool useMaterial3 }) {
// enabled: false produces a hairline border if filled: false (the default)
// The widget's size and layout is the same as for enabled: true.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
decoration: const InputDecoration(
label: Text.rich(
......@@ -676,13 +793,12 @@ void runAllTests({ required bool useMaterial3 }) {
expect(tester.getBottomLeft(find.text('text')).dy,44.0);
expect(tester.getTopLeft(find.byKey(key)).dy, 20.0);
expect(tester.getBottomLeft(find.byKey(key)).dy, 36.0);
expect(getBorderWeight(tester),useMaterial3 ? 1.0 : 0.0);
expect(getBorderWeight(tester), 0.0);
// enabled: false produces a transparent border if filled: true.
// The widget's size and layout is the same as for enabled: true.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
decoration: const InputDecoration(
label: Text.rich(
......@@ -708,14 +824,12 @@ void runAllTests({ required bool useMaterial3 }) {
expect(tester.getBottomLeft(find.text('text')).dy, 44.0);
expect(tester.getTopLeft(find.byKey(key)).dy, 20.0);
expect(tester.getBottomLeft(find.byKey(key)).dy, 36.0);
final ThemeData theme = ThemeData.from(colorScheme: const ColorScheme.light());
expect(getBorderColor(tester), useMaterial3 ? theme.colorScheme.onSurface.withOpacity(0.38) : Colors.transparent);
expect(getBorderColor(tester), Colors.transparent);
// alignLabelWithHint: true positions the label at the text baseline,
// aligned with the hint.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
decoration: const InputDecoration(
label: Text.rich(
......@@ -737,11 +851,8 @@ void runAllTests({ required bool useMaterial3 }) {
);
await tester.pumpAndSettle();
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
if (!useMaterial3) {
expect(tester.getTopLeft(find.byKey(key)).dy, tester.getTopLeft(find.text('hint')).dy);
expect(tester.getBottomLeft(find.byKey(key)).dy, tester.getBottomLeft(find.text('hint')).dy);
}
expect(tester.getTopLeft(find.byKey(key)).dy, tester.getTopLeft(find.text('hint')).dy);
expect(tester.getBottomLeft(find.byKey(key)).dy, tester.getBottomLeft(find.text('hint')).dy);
});
testWidgets('InputDecorator floating label animation duration and curve', (WidgetTester tester) async {
......@@ -749,7 +860,7 @@ void runAllTests({ required bool useMaterial3 }) {
required bool isFocused,
}) async {
return tester.pumpWidget(
buildInputDecorator(
buildInputDecoratorM2(
isEmpty: true,
isFocused: isFocused,
decoration: const InputDecoration(
......@@ -1024,8 +1135,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator input/hint layout', (WidgetTester tester) async {
// The hint aligns with the input text
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -1048,8 +1158,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator input/label/hint layout', (WidgetTester tester) async {
// Label is visible, hint is not (opacity 0.0).
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -1087,8 +1196,7 @@ void runAllTests({ required bool useMaterial3 }) {
// Label moves upwards, hint is visible (opacity 1.0).
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
isFocused: true,
decoration: const InputDecoration(
......@@ -1122,8 +1230,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(getBorderWeight(tester), 2.0);
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isFocused: true,
decoration: const InputDecoration(
labelText: 'label',
......@@ -1159,8 +1266,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator input/label/hint dense layout', (WidgetTester tester) async {
// Label is visible, hint is not (opacity 0.0).
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -1198,8 +1304,7 @@ void runAllTests({ required bool useMaterial3 }) {
// Label is visible, hint is not (opacity 0.0).
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
isFocused: true,
decoration: const InputDecoration(
......@@ -1222,8 +1327,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator default hint animation duration', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
decoration: const InputDecoration(
labelText: 'label',
......@@ -1237,8 +1341,7 @@ void runAllTests({ required bool useMaterial3 }) {
// Focus to show the hint.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
isFocused: true,
decoration: const InputDecoration(
......@@ -1263,8 +1366,7 @@ void runAllTests({ required bool useMaterial3 }) {
// Unfocus to hide the hint.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
decoration: const InputDecoration(
labelText: 'label',
......@@ -1289,8 +1391,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator custom hint animation duration', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
decoration: const InputDecoration(
labelText: 'label',
......@@ -1305,8 +1406,7 @@ void runAllTests({ required bool useMaterial3 }) {
// Focus to show the hint.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
isFocused: true,
decoration: const InputDecoration(
......@@ -1332,8 +1432,7 @@ void runAllTests({ required bool useMaterial3 }) {
// Unfocus to hide the hint.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
decoration: const InputDecoration(
labelText: 'label',
......@@ -1359,8 +1458,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator custom hint animation duration from theme', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
inputDecorationTheme: const InputDecorationTheme(
hintFadeDuration: Duration(milliseconds: 120),
),
......@@ -1377,8 +1475,7 @@ void runAllTests({ required bool useMaterial3 }) {
// Focus to show the hint.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
inputDecorationTheme: const InputDecorationTheme(
hintFadeDuration: Duration(milliseconds: 120),
),
......@@ -1406,8 +1503,7 @@ void runAllTests({ required bool useMaterial3 }) {
// Unfocus to hide the hint.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
inputDecorationTheme: const InputDecorationTheme(
hintFadeDuration: Duration(milliseconds: 120),
),
......@@ -1436,8 +1532,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator with no input border', (WidgetTester tester) async {
// Label is visible, hint is not (opacity 0.0).
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -1450,8 +1545,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator error/helper/counter layout', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -1496,8 +1590,7 @@ void runAllTests({ required bool useMaterial3 }) {
// If errorText is specified then the helperText isn't shown
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -1544,8 +1637,7 @@ void runAllTests({ required bool useMaterial3 }) {
// 12 - help/error/counter text (font size 12dps)
// The layout of the error/helper/counter subtext doesn't change for dense layout.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -1572,8 +1664,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(tester.getTopRight(find.text('counter')), const Offset(788.0, 56.0));
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -1708,8 +1799,7 @@ void runAllTests({ required bool useMaterial3 }) {
const String kError3 = 'e0\ne1\ne2';
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -1740,8 +1830,7 @@ void runAllTests({ required bool useMaterial3 }) {
// one, 88dps, because errorText only occupies two lines.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -1762,8 +1851,7 @@ void runAllTests({ required bool useMaterial3 }) {
// one, 88dps, because errorText only occupies one line.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -1787,8 +1875,7 @@ void runAllTests({ required bool useMaterial3 }) {
const String kHelper3 = 'e0\ne1\ne2';
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -1818,8 +1905,7 @@ void runAllTests({ required bool useMaterial3 }) {
// one, 88dps, because helperText only occupies two lines.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -1839,8 +1925,7 @@ void runAllTests({ required bool useMaterial3 }) {
// one, 88dps, because helperText only occupies two lines.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -1860,8 +1945,7 @@ void runAllTests({ required bool useMaterial3 }) {
// one, 88dps, because helperText only occupies one line.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -1880,8 +1964,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator shows error text', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
decoration: const InputDecoration(
errorText: 'errorText',
),
......@@ -1900,8 +1983,7 @@ void runAllTests({ required bool useMaterial3 }) {
);
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isFocused: true,
decoration: const InputDecoration(
errorText: 'error',
......@@ -1915,8 +1997,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(getBorder(tester), focusedErrorBorder);
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isFocused: false (default)
decoration: const InputDecoration(
errorText: 'error',
......@@ -1930,8 +2011,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(getBorder(tester), errorBorder);
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isFocused: false (default)
decoration: const InputDecoration(
errorText: 'error',
......@@ -1945,8 +2025,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(getBorder(tester), errorBorder);
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isFocused: true,
decoration: const InputDecoration(
error: Text('error'),
......@@ -1960,8 +2039,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(getBorder(tester), focusedErrorBorder);
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isFocused: false (default)
decoration: const InputDecoration(
error: Text('error'),
......@@ -1975,8 +2053,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(getBorder(tester), errorBorder);
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isFocused: false (default)
decoration: const InputDecoration(
error: Text('error'),
......@@ -1992,8 +2069,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator shows error widget', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
decoration: const InputDecoration(
error: Text('error', style: TextStyle(fontSize: 20.0)),
),
......@@ -2006,8 +2082,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator throws when error text and error widget are provided', (WidgetTester tester) async {
expect(
() {
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
decoration: InputDecoration(
errorText: 'errorText',
error: const Text('error', style: TextStyle(fontSize: 20.0)),
......@@ -2020,8 +2095,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator prefix/suffix texts', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -2058,8 +2132,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator icon/prefix/suffix', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -2186,8 +2259,7 @@ void runAllTests({ required bool useMaterial3 }) {
const Key pKey = Key('p');
const Key sKey = Key('s');
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -2237,8 +2309,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator tall prefix', (WidgetTester tester) async {
const Key pKey = Key('p');
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -2282,8 +2353,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator tall prefix with border', (WidgetTester tester) async {
const Key pKey = Key('p');
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -2332,8 +2402,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator prefixIcon/suffixIcon', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -2368,8 +2437,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator prefixIconConstraints/suffixIconConstraints', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -2407,8 +2475,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('prefix/suffix icons are centered when smaller than 48 by 48', (WidgetTester tester) async {
const Key prefixKey = Key('prefix');
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
decoration: const InputDecoration(
prefixIcon: Padding(
padding: EdgeInsets.all(16.0),
......@@ -2433,8 +2500,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator respects reduced theme visualDensity', (WidgetTester tester) async {
// Label is visible, hint is not (opacity 0.0).
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
visualDensity: VisualDensity.compact,
decoration: const InputDecoration(
......@@ -2456,8 +2522,7 @@ void runAllTests({ required bool useMaterial3 }) {
// Label moves upwards, hint is visible (opacity 1.0).
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
isFocused: true,
visualDensity: VisualDensity.compact,
......@@ -2492,8 +2557,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(getBorderWeight(tester), 2.0);
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isFocused: true,
visualDensity: VisualDensity.compact,
decoration: const InputDecoration(
......@@ -2530,8 +2594,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator respects increased theme visualDensity', (WidgetTester tester) async {
// Label is visible, hint is not (opacity 0.0).
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
visualDensity: const VisualDensity(horizontal: 2.0, vertical: 2.0),
decoration: const InputDecoration(
......@@ -2553,8 +2616,7 @@ void runAllTests({ required bool useMaterial3 }) {
// Label moves upwards, hint is visible (opacity 1.0).
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
isFocused: true,
visualDensity: const VisualDensity(horizontal: 2.0, vertical: 2.0),
......@@ -2589,8 +2651,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(getBorderWeight(tester), 2.0);
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isFocused: true,
visualDensity: const VisualDensity(horizontal: 2.0, vertical: 2.0),
decoration: const InputDecoration(
......@@ -2627,8 +2688,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('prefix/suffix icons increase height of decoration when larger than 48 by 48', (WidgetTester tester) async {
const Key prefixKey = Key('prefix');
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
decoration: const InputDecoration(
prefixIcon: SizedBox(width: 100.0, height: 100.0, key: prefixKey),
filled: true,
......@@ -2649,9 +2709,7 @@ void runAllTests({ required bool useMaterial3 }) {
group('constraints', () {
testWidgets('No InputDecorator constraints', (WidgetTester tester) async {
await tester.pumpWidget(buildInputDecorator(
useMaterial3: useMaterial3,
));
await tester.pumpWidget(buildInputDecoratorM2());
// Should fill the screen width and be default height
expect(tester.getSize(find.byType(InputDecorator)), const Size(800, 48));
......@@ -2659,8 +2717,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecoratorThemeData constraints', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
theme: ThemeData(
inputDecorationTheme: const InputDecorationTheme(
constraints: BoxConstraints(maxWidth: 300, maxHeight: 40),
......@@ -2675,8 +2732,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator constraints', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
theme: ThemeData(
inputDecorationTheme: const InputDecorationTheme(
constraints: BoxConstraints(maxWidth: 300, maxHeight: 40),
......@@ -2699,8 +2755,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('align top (default)', (WidgetTester tester) async {
const String text = 'text';
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
expands: true, // so we have a tall input where align can vary
......@@ -2723,8 +2778,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('align center', (WidgetTester tester) async {
const String text = 'text';
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
expands: true,
......@@ -2747,8 +2801,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('align bottom', (WidgetTester tester) async {
const String text = 'text';
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
expands: true,
......@@ -2771,8 +2824,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('align as a double', (WidgetTester tester) async {
const String text = 'text';
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
expands: true,
......@@ -2805,8 +2857,7 @@ void runAllTests({ required bool useMaterial3 }) {
child: SizedBox(
key: containerKey,
height: totalHeight,
child: buildInputDecorator(
useMaterial3: useMaterial3,
child: buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
expands: true,
......@@ -2845,8 +2896,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('align top', (WidgetTester tester) async {
const String text = 'text';
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
expands: true, // so we have a tall input where align can vary
......@@ -2871,8 +2921,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('align center (default)', (WidgetTester tester) async {
const String text = 'text';
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
expands: true,
......@@ -2896,8 +2945,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('align bottom', (WidgetTester tester) async {
const String text = 'text';
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
expands: true,
......@@ -2924,8 +2972,7 @@ void runAllTests({ required bool useMaterial3 }) {
const Key pKey = Key('p');
const String text = 'text';
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -2954,8 +3001,7 @@ void runAllTests({ required bool useMaterial3 }) {
const Key pKey = Key('p');
const String text = 'text';
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -2984,8 +3030,7 @@ void runAllTests({ required bool useMaterial3 }) {
const Key pKey = Key('p');
const String text = 'text';
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -3016,8 +3061,7 @@ void runAllTests({ required bool useMaterial3 }) {
const Key pKey = Key('p');
const String text = 'text';
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
expands: true,
......@@ -3048,8 +3092,7 @@ void runAllTests({ required bool useMaterial3 }) {
const Key pKey = Key('p');
const String text = 'text';
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
expands: true,
......@@ -3082,8 +3125,7 @@ void runAllTests({ required bool useMaterial3 }) {
const Key pKey = Key('p');
const String text = 'text';
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
expands: true,
......@@ -3114,8 +3156,7 @@ void runAllTests({ required bool useMaterial3 }) {
const Key pKey = Key('p');
const String text = 'text';
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
expands: true,
......@@ -3147,8 +3188,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('align top (default)', (WidgetTester tester) async {
const String text = 'text';
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
expands: true, // so we have a tall input where align can vary
......@@ -3173,8 +3213,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('align center', (WidgetTester tester) async {
const String text = 'text';
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
expands: true, // so we have a tall input where align can vary
......@@ -3199,8 +3238,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('align bottom', (WidgetTester tester) async {
const String text = 'text';
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
expands: true, // so we have a tall input where align can vary
......@@ -3228,8 +3266,7 @@ void runAllTests({ required bool useMaterial3 }) {
group('default alignment', () {
testWidgets('Centers when border', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
decoration: const InputDecoration(
border: OutlineInputBorder(),
),
......@@ -3245,8 +3282,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('Centers when border and label', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
decoration: const InputDecoration(
labelText: 'label',
border: OutlineInputBorder(),
......@@ -3263,8 +3299,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('Centers when border and contentPadding', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
decoration: const InputDecoration(
border: OutlineInputBorder(),
contentPadding: EdgeInsets.fromLTRB(
......@@ -3284,8 +3319,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('Centers when border and contentPadding and label', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
decoration: const InputDecoration(
labelText: 'label',
border: OutlineInputBorder(),
......@@ -3305,8 +3339,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('Centers when border and lopsided contentPadding and label', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
decoration: const InputDecoration(
labelText: 'label',
border: OutlineInputBorder(),
......@@ -3325,29 +3358,9 @@ void runAllTests({ required bool useMaterial3 }) {
expect(getBorderWeight(tester), 1.0);
});
testWidgets('Floating label is aligned with prefixIcon by default in M3', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
decoration: const InputDecoration(
prefixIcon: Icon(Icons.ac_unit),
labelText: 'label',
border: OutlineInputBorder(),
),
isFocused: true,
),
);
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
expect(tester.getTopLeft(find.text('label')).dx, useMaterial3 ? 12.0 : 48.0);
expect(tester.getBottomLeft(find.text('text')).dx, 48.0);
expect(getBorderWeight(tester), 2.0);
});
testWidgets('Floating label for filled input decoration is aligned with text', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
decoration: const InputDecoration(
prefixIcon: Icon(Icons.ac_unit),
labelText: 'label',
......@@ -3367,8 +3380,7 @@ void runAllTests({ required bool useMaterial3 }) {
group('3 point interpolation alignment', () {
testWidgets('top align includes padding', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
expands: true,
textAlignVertical: TextAlignVertical.top,
decoration: const InputDecoration(
......@@ -3391,8 +3403,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('center align ignores padding', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
expands: true,
textAlignVertical: TextAlignVertical.center,
decoration: const InputDecoration(
......@@ -3415,8 +3426,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('bottom align includes padding', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
expands: true,
textAlignVertical: TextAlignVertical.bottom,
decoration: const InputDecoration(
......@@ -3439,8 +3449,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('padding exceeds middle keeps top at middle', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
expands: true,
textAlignVertical: TextAlignVertical.top,
decoration: const InputDecoration(
......@@ -3465,8 +3474,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('counter text has correct right margin - LTR, not dense', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -3485,8 +3493,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('counter text has correct right margin - RTL, not dense', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
textDirection: TextDirection.rtl,
// isEmpty: false (default)
// isFocused: false (default)
......@@ -3505,8 +3512,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('counter text has correct right margin - LTR, dense', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -3526,8 +3532,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('counter text has correct right margin - RTL, dense', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
textDirection: TextDirection.rtl,
// isEmpty: false (default)
// isFocused: false (default)
......@@ -3547,8 +3552,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator error/helper/counter RTL layout', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
textDirection: TextDirection.rtl,
......@@ -3582,8 +3586,7 @@ void runAllTests({ required bool useMaterial3 }) {
// If both error and helper are specified, show the error
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
textDirection: TextDirection.rtl,
......@@ -3604,8 +3607,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator prefix/suffix RTL', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
textDirection: TextDirection.rtl,
......@@ -3639,8 +3641,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator contentPadding RTL layout', (WidgetTester tester) async {
// LTR: content left edge is contentPadding.start: 40.0
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -3658,8 +3659,7 @@ void runAllTests({ required bool useMaterial3 }) {
// RTL: content right edge is 800 - contentPadding.start: 760.0.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
isFocused: true, // label is floating, still adjusted for contentPadding
textDirection: TextDirection.rtl,
......@@ -3685,8 +3685,7 @@ void runAllTests({ required bool useMaterial3 }) {
group('inputText width', () {
testWidgets('outline textField', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
decoration: const InputDecoration(
border: OutlineInputBorder(),
),
......@@ -3698,8 +3697,7 @@ void runAllTests({ required bool useMaterial3 }) {
});
testWidgets('outline textField with prefix and suffix icons', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
decoration: const InputDecoration(
border: OutlineInputBorder(),
prefixIcon: Icon(Icons.visibility),
......@@ -3713,8 +3711,7 @@ void runAllTests({ required bool useMaterial3 }) {
});
testWidgets('filled textField', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
decoration: const InputDecoration(
filled: true,
),
......@@ -3726,8 +3723,7 @@ void runAllTests({ required bool useMaterial3 }) {
});
testWidgets('filled textField with prefix and suffix icons', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
decoration: const InputDecoration(
filled: true,
prefixIcon: Icon(Icons.visibility),
......@@ -3742,12 +3738,13 @@ void runAllTests({ required bool useMaterial3 }) {
});
group('floatingLabelAlignment', () {
Widget buildInputDecoratorWithFloatingLabel({required TextDirection textDirection,
required bool hasIcon,
required FloatingLabelAlignment alignment,
bool borderIsOutline = false,
}) => buildInputDecorator(
useMaterial3: useMaterial3,
Widget buildInputDecoratorM2WithFloatingLabel({
required TextDirection textDirection,
required bool hasIcon,
required FloatingLabelAlignment alignment,
bool borderIsOutline = false,
}) {
return buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
textDirection: textDirection,
......@@ -3761,11 +3758,12 @@ void runAllTests({ required bool useMaterial3 }) {
border: borderIsOutline ? const OutlineInputBorder() : null,
),
);
}
group('LTR with icon aligned', () {
testWidgets('start', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecoratorWithFloatingLabel(
buildInputDecoratorM2WithFloatingLabel(
textDirection: TextDirection.ltr,
hasIcon: true,
alignment: FloatingLabelAlignment.start,
......@@ -3776,7 +3774,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(tester.getTopLeft(find.text('label')).dx, 80.0);
await tester.pumpWidget(
buildInputDecoratorWithFloatingLabel(
buildInputDecoratorM2WithFloatingLabel(
textDirection: TextDirection.ltr,
hasIcon: true,
alignment: FloatingLabelAlignment.start,
......@@ -3789,7 +3787,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('center', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecoratorWithFloatingLabel(
buildInputDecoratorM2WithFloatingLabel(
textDirection: TextDirection.ltr,
hasIcon: true,
alignment: FloatingLabelAlignment.center,
......@@ -3800,7 +3798,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(tester.getCenter(find.text('label')).dx, 420.0);
await tester.pumpWidget(
buildInputDecoratorWithFloatingLabel(
buildInputDecoratorM2WithFloatingLabel(
textDirection: TextDirection.ltr,
hasIcon: true,
alignment: FloatingLabelAlignment.center,
......@@ -3815,7 +3813,7 @@ void runAllTests({ required bool useMaterial3 }) {
group('LTR without icon aligned', () {
testWidgets('start', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecoratorWithFloatingLabel(
buildInputDecoratorM2WithFloatingLabel(
textDirection: TextDirection.ltr,
hasIcon: false,
alignment: FloatingLabelAlignment.start,
......@@ -3826,7 +3824,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(tester.getTopLeft(find.text('label')).dx, 40.0);
await tester.pumpWidget(
buildInputDecoratorWithFloatingLabel(
buildInputDecoratorM2WithFloatingLabel(
textDirection: TextDirection.ltr,
hasIcon: false,
alignment: FloatingLabelAlignment.start,
......@@ -3839,7 +3837,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('center', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecoratorWithFloatingLabel(
buildInputDecoratorM2WithFloatingLabel(
textDirection: TextDirection.ltr,
hasIcon: false,
alignment: FloatingLabelAlignment.center,
......@@ -3850,7 +3848,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(tester.getCenter(find.text('label')).dx, 400.0);
await tester.pumpWidget(
buildInputDecoratorWithFloatingLabel(
buildInputDecoratorM2WithFloatingLabel(
textDirection: TextDirection.ltr,
hasIcon: false,
alignment: FloatingLabelAlignment.center,
......@@ -3865,7 +3863,7 @@ void runAllTests({ required bool useMaterial3 }) {
group('RTL with icon aligned', () {
testWidgets('start', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecoratorWithFloatingLabel(
buildInputDecoratorM2WithFloatingLabel(
textDirection: TextDirection.rtl,
hasIcon: true,
alignment: FloatingLabelAlignment.start,
......@@ -3876,7 +3874,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(tester.getTopRight(find.text('label')).dx, 720.0);
await tester.pumpWidget(
buildInputDecoratorWithFloatingLabel(
buildInputDecoratorM2WithFloatingLabel(
textDirection: TextDirection.rtl,
hasIcon: true,
alignment: FloatingLabelAlignment.start,
......@@ -3889,7 +3887,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('center', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecoratorWithFloatingLabel(
buildInputDecoratorM2WithFloatingLabel(
textDirection: TextDirection.rtl,
hasIcon: true,
alignment: FloatingLabelAlignment.center,
......@@ -3900,7 +3898,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(tester.getCenter(find.text('label')).dx, 380.0);
await tester.pumpWidget(
buildInputDecoratorWithFloatingLabel(
buildInputDecoratorM2WithFloatingLabel(
textDirection: TextDirection.rtl,
hasIcon: true,
alignment: FloatingLabelAlignment.center,
......@@ -3915,7 +3913,7 @@ void runAllTests({ required bool useMaterial3 }) {
group('RTL without icon aligned', () {
testWidgets('start', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecoratorWithFloatingLabel(
buildInputDecoratorM2WithFloatingLabel(
textDirection: TextDirection.rtl,
hasIcon: false,
alignment: FloatingLabelAlignment.start,
......@@ -3926,7 +3924,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(tester.getTopRight(find.text('label')).dx, 760.0);
await tester.pumpWidget(
buildInputDecoratorWithFloatingLabel(
buildInputDecoratorM2WithFloatingLabel(
textDirection: TextDirection.rtl,
hasIcon: false,
alignment: FloatingLabelAlignment.start,
......@@ -3939,7 +3937,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('center', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecoratorWithFloatingLabel(
buildInputDecoratorM2WithFloatingLabel(
textDirection: TextDirection.rtl,
hasIcon: false,
alignment: FloatingLabelAlignment.center,
......@@ -3950,7 +3948,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(tester.getCenter(find.text('label')).dx, 400.0);
await tester.pumpWidget(
buildInputDecoratorWithFloatingLabel(
buildInputDecoratorM2WithFloatingLabel(
textDirection: TextDirection.rtl,
hasIcon: false,
alignment: FloatingLabelAlignment.center,
......@@ -3965,8 +3963,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator prefix/suffix dense layout', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
isFocused: true,
decoration: const InputDecoration(
......@@ -4006,9 +4003,7 @@ void runAllTests({ required bool useMaterial3 }) {
});
testWidgets('InputDecorator with empty InputDecoration', (WidgetTester tester) async {
await tester.pumpWidget(buildInputDecorator(
useMaterial3: useMaterial3,
));
await tester.pumpWidget(buildInputDecoratorM2());
// Overall height for this InputDecorator is 40dps:
// 12 - top padding
......@@ -4026,8 +4021,7 @@ void runAllTests({ required bool useMaterial3 }) {
// Regression test for https://github.com/flutter/flutter/issues/42449
const double verticalPadding = 1.0;
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default),
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -4051,8 +4045,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(getBorderWeight(tester), 1.0);
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default),
// isFocused: false (default)
decoration: const InputDecoration.collapsed(
......@@ -4075,8 +4068,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(getBorderWeight(tester), 1.0);
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default),
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -4100,8 +4092,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator.collapsed', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default),
// isFocused: false (default)
decoration: const InputDecoration.collapsed(
......@@ -4122,8 +4113,7 @@ void runAllTests({ required bool useMaterial3 }) {
// The hint should appear
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
isFocused: true,
decoration: const InputDecoration.collapsed(
......@@ -4146,8 +4136,7 @@ void runAllTests({ required bool useMaterial3 }) {
// text child to a smaller font reduces the InputDecoration's vertical size.
const TextStyle style = TextStyle(fontSize: 10.0);
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
baseStyle: style,
decoration: const InputDecoration(
......@@ -4173,20 +4162,19 @@ void runAllTests({ required bool useMaterial3 }) {
// 10 - label (font size 10dps)
// 17.75 - bottom padding (empty input text still appears here)
expect(tester.getSize(find.byType(InputDecorator)), Size(800.0, useMaterial3 ? 50.0 : kMinInteractiveDimension)); // 45.5 bumped up to minimum.
expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, kMinInteractiveDimension)); // 45.5 bumped up to minimum.
expect(tester.getSize(find.text('hint')).height, 10.0);
expect(tester.getSize(find.text('label')).height, useMaterial3 ? 16.0 : 10.0);
expect(tester.getSize(find.text('label')).height, 10.0);
expect(tester.getSize(find.text('text')).height, 10.0);
expect(tester.getTopLeft(find.text('hint')).dy, useMaterial3 ? 28 : 24.75);
expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 17 : 19.0);
expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 28 : 24.75);
expect(tester.getTopLeft(find.text('hint')).dy, 24.75);
expect(tester.getTopLeft(find.text('label')).dy, 19.0);
expect(tester.getTopLeft(find.text('text')).dy, 24.75);
});
testWidgets('InputDecorator with empty style overrides', (WidgetTester tester) async {
// Same as not specifying any style overrides
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -4227,8 +4215,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecoration outline shape with no border and no floating placeholder', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isFocused: false (default)
isEmpty: true,
decoration: const InputDecoration(
......@@ -4252,8 +4239,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecoration outline shape with no border and no floating placeholder not empty', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -4404,8 +4390,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorationTheme outline border', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true, // label appears, vertically centered
// isFocused: false (default)
inputDecorationTheme: const InputDecorationTheme(
......@@ -4430,8 +4415,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorationTheme outline border, dense layout', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true, // label appears, vertically centered
// isFocused: false (default)
inputDecorationTheme: const InputDecorationTheme(
......@@ -4473,8 +4457,7 @@ void runAllTests({ required bool useMaterial3 }) {
// provided then the horizontal padding is included.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true, // label appears, vertically centered
// isFocused: false (default)
inputDecorationTheme: InputDecorationTheme(
......@@ -4540,8 +4523,7 @@ void runAllTests({ required bool useMaterial3 }) {
// provided then the horizontal padding is included.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
isFocused: true, // Label appears floating above input field.
inputDecorationTheme: InputDecorationTheme(
......@@ -4606,8 +4588,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator.debugDescribeChildren', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
decoration: const InputDecoration(
icon: Text('icon'),
labelText: 'label',
......@@ -4649,8 +4630,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator with empty border and label', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/14165
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -4951,8 +4931,7 @@ void runAllTests({ required bool useMaterial3 }) {
// This is a regression test for https://github.com/flutter/flutter/issues/15742
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -4990,8 +4969,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator UnderlineInputBorder fillColor is clipped by border', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: const InputDecoration(
......@@ -5137,10 +5115,10 @@ void runAllTests({ required bool useMaterial3 }) {
);
testWidgets('InputDecorator draws and animates hoverColor', (WidgetTester tester) async {
final Color fillColor = useMaterial3 ? const Color(0xffffffff) : const Color(0x0A000000);
const Color fillColor = Color(0x0A000000);
const Color hoverColor = Color(0xFF00FF00);
final Color disabledColor =useMaterial3 ? const Color(0x0A000000) : const Color(0x05000000);
final Color enabledBorderColor = useMaterial3 ? const Color(0xffffffff) : const Color(0x61000000);
const Color disabledColor = Color(0x05000000);
const Color enabledBorderColor = Color(0x61000000);
Future<void> pumpDecorator({
required bool hovering,
......@@ -5148,15 +5126,14 @@ void runAllTests({ required bool useMaterial3 }) {
bool filled = true,
}) async {
return tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isHovering: hovering,
decoration: InputDecoration(
enabled: enabled,
filled: filled,
hoverColor: hoverColor,
disabledBorder: OutlineInputBorder(borderSide: BorderSide(color: disabledColor)),
border: OutlineInputBorder(borderSide: BorderSide(color: enabledBorderColor)),
disabledBorder: const OutlineInputBorder(borderSide: BorderSide(color: disabledColor)),
border: const OutlineInputBorder(borderSide: BorderSide(color: enabledBorderColor)),
),
),
);
......@@ -5189,7 +5166,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(getContainerColor(tester), equals(disabledColor));
// Test outline text field.
final Color blendedHoverColor = useMaterial3 ? const Color(0xff000000) : const Color(0x74004400);
const Color blendedHoverColor = Color(0x74004400);
await pumpDecorator(hovering: false, filled: false);
await tester.pumpAndSettle();
expect(getBorderColor(tester), equals(enabledBorderColor));
......@@ -5220,7 +5197,7 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecorator draws and animates focusColor', (WidgetTester tester) async {
const Color focusColor = Color(0xFF0000FF);
const Color disabledColor = Color(0x05000000);
final Color enabledBorderColor = useMaterial3 ? const Color(0xffffffff) : const Color(0x61000000);
const Color enabledBorderColor = Color(0x61000000);
Future<void> pumpDecorator({
required bool focused,
......@@ -5228,8 +5205,7 @@ void runAllTests({ required bool useMaterial3 }) {
bool filled = true,
}) async {
return tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isFocused: focused,
decoration: InputDecoration(
enabled: enabled,
......@@ -5237,7 +5213,7 @@ void runAllTests({ required bool useMaterial3 }) {
focusColor: focusColor,
focusedBorder: const OutlineInputBorder(borderSide: BorderSide(color: focusColor)),
disabledBorder: const OutlineInputBorder(borderSide: BorderSide(color: disabledColor)),
border: OutlineInputBorder(borderSide: BorderSide(color: enabledBorderColor)),
border: const OutlineInputBorder(borderSide: BorderSide(color: enabledBorderColor)),
),
),
);
......@@ -5280,8 +5256,7 @@ void runAllTests({ required bool useMaterial3 }) {
bool directional = false,
}) async {
return tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: empty,
isFocused: focused,
decoration: InputDecoration(
......@@ -5392,15 +5367,14 @@ void runAllTests({ required bool useMaterial3 }) {
testWidgets('InputDecoration default border uses colorScheme', (WidgetTester tester) async {
final ThemeData theme = ThemeData.from(colorScheme: const ColorScheme.light());
final Color enabledColor = useMaterial3 ? theme.colorScheme.onSurfaceVariant : theme.colorScheme.onSurface.withOpacity(0.38);
final Color disabledColor = useMaterial3 ? theme.colorScheme.onSurface.withOpacity(0.12) : theme.disabledColor;
final ThemeData theme = ThemeData.light(useMaterial3: false);
final Color enabledColor = theme.colorScheme.onSurface.withOpacity(0.38);
final Color disabledColor = theme.disabledColor;
final Color hoverColor = Color.alphaBlend(theme.hoverColor.withOpacity(0.12), enabledColor);
// Enabled
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
theme: theme,
),
);
......@@ -5409,8 +5383,7 @@ void runAllTests({ required bool useMaterial3 }) {
// Filled
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
theme: theme,
decoration: const InputDecoration(
filled: true,
......@@ -5418,12 +5391,11 @@ void runAllTests({ required bool useMaterial3 }) {
),
);
await tester.pumpAndSettle();
expect(getBorderColor(tester), useMaterial3 ? theme.colorScheme.onSurfaceVariant : theme.hintColor);
expect(getBorderColor(tester), theme.hintColor);
// Hovering
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
theme: theme,
isHovering: true,
),
......@@ -5433,8 +5405,7 @@ void runAllTests({ required bool useMaterial3 }) {
// Focused
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
theme: theme,
isFocused: true,
),
......@@ -5444,8 +5415,7 @@ void runAllTests({ required bool useMaterial3 }) {
// Error
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
theme: theme,
decoration: const InputDecoration(
errorText: 'Nope',
......@@ -5457,8 +5427,7 @@ void runAllTests({ required bool useMaterial3 }) {
// Disabled
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
theme: theme,
decoration: const InputDecoration(
enabled: false,
......@@ -5470,8 +5439,7 @@ void runAllTests({ required bool useMaterial3 }) {
// Disabled, filled
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
theme: theme,
decoration: const InputDecoration(
enabled: false,
......@@ -5480,7 +5448,7 @@ void runAllTests({ required bool useMaterial3 }) {
),
);
await tester.pumpAndSettle();
expect(getBorderColor(tester), useMaterial3 ? theme.colorScheme.onSurface.withOpacity(0.38) : Colors.transparent);
expect(getBorderColor(tester), Colors.transparent);
});
testWidgets('InputDecoration borders', (WidgetTester tester) async {
......@@ -5501,8 +5469,7 @@ void runAllTests({ required bool useMaterial3 }) {
);
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isFocused: false (default)
decoration: const InputDecoration(
// errorText: null (default)
......@@ -5518,8 +5485,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(getBorder(tester), enabledBorder);
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isFocused: true,
decoration: const InputDecoration(
// errorText: null (default)
......@@ -5536,8 +5502,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(getBorder(tester), focusedBorder);
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isFocused: true,
decoration: const InputDecoration(
errorText: 'error',
......@@ -5554,8 +5519,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(getBorder(tester), focusedErrorBorder);
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isFocused: false (default)
decoration: const InputDecoration(
errorText: 'error',
......@@ -5572,8 +5536,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(getBorder(tester), errorBorder);
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isFocused: false (default)
decoration: const InputDecoration(
errorText: 'error',
......@@ -5590,8 +5553,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(getBorder(tester), errorBorder);
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isFocused: false (default)
decoration: const InputDecoration(
enabled: false,
......@@ -5607,8 +5569,7 @@ void runAllTests({ required bool useMaterial3 }) {
expect(getBorder(tester), disabledBorder);
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isFocused: true,
decoration: const InputDecoration(
// errorText: null (default)
......@@ -5640,8 +5601,7 @@ void runAllTests({ required bool useMaterial3 }) {
const double inputDecoratorWidth = 800.0;
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
decoration: const InputDecoration(
filled: true,
fillColor: Color(0xFF00FF00),
......@@ -5745,8 +5705,7 @@ void runAllTests({ required bool useMaterial3 }) {
const double inputDecoratorWidth = 800.0;
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
decoration: InputDecoration(
filled: true,
fillColor: const Color(0xFF00FF00),
......@@ -5838,7 +5797,7 @@ testWidgets('OutlineInputBorder with BorderRadius.zero should draw a rectangular
const double borderWidth = 4.0;
await tester.pumpWidget(
buildInputDecorator(
buildInputDecoratorM2(
isFocused: true,
decoration: const InputDecoration(
filled: false,
......@@ -6121,6 +6080,7 @@ testWidgets('OutlineInputBorder with BorderRadius.zero should draw a rectangular
Widget buildFrame(bool alignLabelWithHint) {
return MaterialApp(
theme: ThemeData(
useMaterial3: false,
textTheme: typography.dense,
),
home: Material(
......@@ -6157,8 +6117,7 @@ testWidgets('OutlineInputBorder with BorderRadius.zero should draw a rectangular
testWidgets('InputDecorator floating label Y coordinate', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/54028
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
decoration: const InputDecoration(
labelText: 'label',
......@@ -6179,8 +6138,7 @@ testWidgets('OutlineInputBorder with BorderRadius.zero should draw a rectangular
testWidgets('InputDecorator floating label obeys floatingLabelBehavior', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
decoration: const InputDecoration(
labelText: 'label',
floatingLabelBehavior: FloatingLabelBehavior.never,
......@@ -6196,8 +6154,7 @@ testWidgets('OutlineInputBorder with BorderRadius.zero should draw a rectangular
testWidgets('InputDecorator hint is displayed when floatingLabelBehavior is always', (WidgetTester tester) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isFocused: false (default)
isEmpty: true,
decoration: const InputDecoration(
......@@ -6221,8 +6178,7 @@ testWidgets('OutlineInputBorder with BorderRadius.zero should draw a rectangular
child: SizedBox(
width: 100,
height: 100,
child: buildInputDecorator(
useMaterial3: useMaterial3,
child: buildInputDecoratorM2(
// isFocused: false (default)
isEmpty: true,
decoration: InputDecoration(
......@@ -6245,8 +6201,7 @@ testWidgets('OutlineInputBorder with BorderRadius.zero should draw a rectangular
child: SizedBox(
width: 100,
height: 100,
child: buildInputDecorator(
useMaterial3: useMaterial3,
child: buildInputDecoratorM2(
isFocused: true,
isEmpty: true,
decoration: InputDecoration(
......@@ -6770,8 +6725,7 @@ testWidgets('OutlineInputBorder with BorderRadius.zero should draw a rectangular
// provided then the horizontal padding is included.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true,
isFocused: true, // Label appears floating above input field.
inputDecorationTheme: InputDecorationTheme(
......@@ -6812,8 +6766,7 @@ testWidgets('OutlineInputBorder with BorderRadius.zero should draw a rectangular
// provided then the horizontal padding is included.
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
isEmpty: true, // Label appears inline, on top of the input field.
inputDecorationTheme: InputDecorationTheme(
labelStyle: labelStyle,
......@@ -6855,8 +6808,7 @@ testWidgets('OutlineInputBorder with BorderRadius.zero should draw a rectangular
);
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: decoration,
......@@ -6877,8 +6829,7 @@ testWidgets('OutlineInputBorder with BorderRadius.zero should draw a rectangular
);
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: decoration,
......@@ -6904,8 +6855,7 @@ testWidgets('OutlineInputBorder with BorderRadius.zero should draw a rectangular
for (final TextDirection direction in TextDirection.values) {
Future<Size> measureText(InputDecoration decoration) async {
await tester.pumpWidget(
buildInputDecorator(
useMaterial3: useMaterial3,
buildInputDecoratorM2(
// isEmpty: false (default)
// isFocused: false (default)
decoration: decoration,
......@@ -6953,8 +6903,7 @@ testWidgets('OutlineInputBorder with BorderRadius.zero should draw a rectangular
Center(
child: SizedBox.square(
dimension: 0.0,
child: buildInputDecorator(
useMaterial3: useMaterial3,
child: buildInputDecoratorM2(
decoration: decoration,
),
),
......
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