// 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 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';

import '../rendering/mock_canvas.dart';

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,
  TextStyle? baseStyle,
  TextAlignVertical? textAlignVertical,
  VisualDensity? visualDensity,
  bool fixTextFieldOutlineLabel = false,
  Widget child = const Text(
    'text',
    style: TextStyle(fontFamily: 'Ahem', fontSize: 16.0),
  ),
}) {
  return MaterialApp(
    home: Material(
      child: Builder(
        builder: (BuildContext context) {
          return Theme(
            data: (theme ?? Theme.of(context)).copyWith(
              inputDecorationTheme: inputDecorationTheme,
              visualDensity: visualDensity,
              fixTextFieldOutlineLabel: fixTextFieldOutlineLabel,
            ),
            child: Align(
              alignment: Alignment.topLeft,
              child: Directionality(
                textDirection: textDirection,
                child: InputDecorator(
                  expands: expands,
                  decoration: decoration,
                  isEmpty: isEmpty,
                  isFocused: isFocused,
                  isHovering: isHovering,
                  baseStyle: baseStyle,
                  textAlignVertical: textAlignVertical,
                  child: child,
                ),
              ),
            ),
          );
        },
      ),
    ),
  );
}

Finder findBorderPainter() {
  return find.descendant(
    of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_BorderContainer'),
    matching: find.byWidgetPredicate((Widget w) => w is CustomPaint),
  );
}

double getBorderBottom(WidgetTester tester) {
  final RenderBox box = InputDecorator.containerOf(tester.element(findBorderPainter()))!;
  return box.size.height;
}

Finder findLabel() {
  return find.descendant(
    of: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_Shaker'),
    matching: find.byWidgetPredicate((Widget w) => w is Text),
  );
}

Rect getLabelRect(WidgetTester tester) {
  return tester.getRect(findLabel());
}

InputBorder? getBorder(WidgetTester tester) {
  if (!tester.any(findBorderPainter()))
    return null;
  final CustomPaint customPaint = tester.widget(findBorderPainter());
  final dynamic/*_InputBorderPainter*/ inputBorderPainter = customPaint.foregroundPainter;
  final dynamic/*_InputBorderTween*/ inputBorderTween = inputBorderPainter.border;
  final Animation<double> animation = inputBorderPainter.borderAnimation as Animation<double>;
  final InputBorder border = inputBorderTween.evaluate(animation) as InputBorder;
  return border;
}

BorderSide? getBorderSide(WidgetTester tester) {
  return getBorder(tester)!.borderSide;
}

BorderRadius? getBorderRadius(WidgetTester tester) {
  final InputBorder border = getBorder(tester)!;
  if (border is UnderlineInputBorder) {
    return border.borderRadius;
  }
  return null;
}

double getBorderWeight(WidgetTester tester) => getBorderSide(tester)!.width;

Color getBorderColor(WidgetTester tester) => getBorderSide(tester)!.color;

Color getContainerColor(WidgetTester tester) {
  final CustomPaint customPaint = tester.widget(findBorderPainter());
  final dynamic/*_InputBorderPainter*/ inputBorderPainter = customPaint.foregroundPainter;
  return inputBorderPainter.blendedColor as Color;
}

double getOpacity(WidgetTester tester, String textValue) {
  final FadeTransition opacityWidget = tester.widget<FadeTransition>(
    find.ancestor(
      of: find.text(textValue),
      matching: find.byType(FadeTransition),
    ).first,
  );
  return opacityWidget.opacity.value;
}

void main() {
  testWidgets('InputDecorator input/label layout', (WidgetTester tester) async {
    // The label appears above the input text
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: const InputDecoration(
          labelText: 'label',
        ),
      ),
    );
    await tester.pumpAndSettle();

    // Overall height for this InputDecorator is 56dps:
    //   12 - top padding
    //   12 - floating label (ahem font size 16dps * 0.75 = 12)
    //    4 - floating label / input text gap
    //   16 - input text (ahem font size 16dps)
    //   12 - bottom padding

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
    expect(tester.getTopLeft(find.text('text')).dy, 28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, 44.0);
    expect(tester.getTopLeft(find.text('label')).dy, 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 24.0);
    expect(getBorderBottom(tester), 56.0);
    expect(getBorderWeight(tester), 1.0);

    // The label appears within the input when there is no text content
    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        // isFocused: false (default)
        decoration: const InputDecoration(
          labelText: 'label',
        ),
      ),
    );
    await tester.pumpAndSettle();

    expect(tester.getTopLeft(find.text('label')).dy, 20.0);

    // The label appears above the input text when there is no content and floatingLabelBehavior is always
    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        // isFocused: false (default)
        decoration: const InputDecoration(
          labelText: 'label',
          floatingLabelBehavior: FloatingLabelBehavior.always
        ),
      ),
    );
    await tester.pumpAndSettle();

    expect(tester.getTopLeft(find.text('label')).dy, 12.0);

    // The label appears within the input text when there is content and floatingLabelBehavior is never
    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: false,
        // isFocused: false (default)
        decoration: const InputDecoration(
          labelText: 'label',
          floatingLabelBehavior: FloatingLabelBehavior.never
        ),
      ),
    );
    await tester.pumpAndSettle();

    expect(tester.getTopLeft(find.text('label')).dy, 20.0);

    // Overall height for this InputDecorator is 56dps:
    //   12 - top padding
    //   12 - floating label (ahem font size 16dps * 0.75 = 12)
    //    4 - floating label / input text gap
    //   16 - input text (ahem font size 16dps)
    //   12 - bottom padding

    expect(tester.getTopLeft(find.text('label')).dy, 20.0);

    // isFocused: true increases the border's weight from 1.0 to 2.0
    // but does not change the overall height.
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        isFocused: true,
        decoration: const InputDecoration(
          labelText: 'label',
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
    expect(tester.getTopLeft(find.text('text')).dy, 28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, 44.0);
    expect(tester.getTopLeft(find.text('label')).dy, 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 24.0);
    expect(getBorderBottom(tester), 56.0);
    expect(getBorderWeight(tester), 2.0);

    // isEmpty: true causes the label to be aligned with the input text
    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        isFocused: false,
        decoration: const InputDecoration(
          labelText: 'label',
        ),
      ),
    );

    // The label animates downwards from it's initial position
    // above the input text. The animation's duration is 200ms.
    {
      await tester.pump(const Duration(milliseconds: 50));
      final double labelY50ms = tester.getTopLeft(find.text('label')).dy;
      expect(labelY50ms, inExclusiveRange(12.0, 20.0));
      await tester.pump(const Duration(milliseconds: 50));
      final double labelY100ms = tester.getTopLeft(find.text('label')).dy;
      expect(labelY100ms, inExclusiveRange(labelY50ms, 20.0));
    }
    await tester.pumpAndSettle();
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
    expect(tester.getTopLeft(find.text('text')).dy, 28.0);
    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(getBorderBottom(tester), 56.0);
    expect(getBorderWeight(tester), 1.0);

    // isFocused: true causes the label to move back up above the input text.
    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        isFocused: true,
        decoration: const InputDecoration(
          labelText: 'label',
        ),
      ),
    );

    // The label animates upwards from it's initial position
    // above the input text. The animation's duration is 200ms.
    {
      await tester.pump(const Duration(milliseconds: 50));
      final double labelY50ms = tester.getTopLeft(find.text('label')).dy;
      expect(labelY50ms, inExclusiveRange(12.0, 28.0));
      await tester.pump(const Duration(milliseconds: 50));
      final double labelY100ms = tester.getTopLeft(find.text('label')).dy;
      expect(labelY100ms, inExclusiveRange(12.0, labelY50ms));
    }

    await tester.pumpAndSettle();
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
    expect(tester.getTopLeft(find.text('text')).dy, 28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, 44.0);
    expect(tester.getTopLeft(find.text('label')).dy, 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 24.0);
    expect(getBorderBottom(tester), 56.0);
    expect(getBorderWeight(tester), 2.0);

    // 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(
        isEmpty: true,
        isFocused: false,
        decoration: const InputDecoration(
          labelText: 'label',
          enabled: false,
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
    expect(tester.getTopLeft(find.text('text')).dy, 28.0);
    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), 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(
        isEmpty: true,
        isFocused: false,
        decoration: const InputDecoration(
          labelText: 'label',
          enabled: false,
          filled: true,
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
    expect(tester.getTopLeft(find.text('text')).dy, 28.0);
    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(getBorderColor(tester), Colors.transparent);

    // alignLabelWithHint: true positions the label at the text baseline,
    // aligned with the hint.
    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        isFocused: false,
        decoration: const InputDecoration(
          labelText: 'label',
          alignLabelWithHint: true,
          hintText: 'hint',
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
    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);
  });

  group('alignLabelWithHint', () {
    group('expands false', () {
      testWidgets('multiline TextField no-strut', (WidgetTester tester) async {
        const String text = 'text';
        final FocusNode focusNode = FocusNode();
        final TextEditingController controller = TextEditingController();
        Widget buildFrame(bool alignLabelWithHint) {
          return MaterialApp(
            home: Material(
              child: Directionality(
                textDirection: TextDirection.ltr,
                child: TextField(
                  controller: controller,
                  focusNode: focusNode,
                  maxLines: 8,
                  decoration: InputDecoration(
                    labelText: 'label',
                    alignLabelWithHint: alignLabelWithHint,
                    hintText: 'hint',
                  ),
                  strutStyle: StrutStyle.disabled,
                ),
              ),
            ),
          );
        }

        // alignLabelWithHint: false centers the label in the TextField.
        await tester.pumpWidget(buildFrame(false));
        await tester.pumpAndSettle();
        expect(tester.getTopLeft(find.text('label')).dy, 76.0);
        expect(tester.getBottomLeft(find.text('label')).dy, 92.0);

        // Entering text still happens at the top.
        await tester.enterText(find.byType(TextField), text);
        expect(tester.getTopLeft(find.text(text)).dy, 28.0);
        controller.clear();
        focusNode.unfocus();

        // alignLabelWithHint: true aligns the label with the hint.
        await tester.pumpWidget(buildFrame(true));
        await tester.pumpAndSettle();
        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);

        // Entering text still happens at the top.
        await tester.enterText(find.byType(TextField), text);
        expect(tester.getTopLeft(find.text(text)).dy, 28.0);
        controller.clear();
        focusNode.unfocus();
      });

      testWidgets('multiline TextField', (WidgetTester tester) async {
        const String text = 'text';
        final FocusNode focusNode = FocusNode();
        final TextEditingController controller = TextEditingController();
        Widget buildFrame(bool alignLabelWithHint) {
          return MaterialApp(
            home: Material(
              child: Directionality(
                textDirection: TextDirection.ltr,
                child: TextField(
                  controller: controller,
                  focusNode: focusNode,
                  maxLines: 8,
                  decoration: InputDecoration(
                    labelText: 'label',
                    alignLabelWithHint: alignLabelWithHint,
                    hintText: 'hint',
                  ),
                ),
              ),
            ),
          );
        }

        // alignLabelWithHint: false centers the label in the TextField.
        await tester.pumpWidget(buildFrame(false));
        await tester.pumpAndSettle();
        expect(tester.getTopLeft(find.text('label')).dy, 76.0);
        expect(tester.getBottomLeft(find.text('label')).dy, 92.0);

        // Entering text still happens at the top.
        await tester.enterText(find.byType(InputDecorator), text);
        expect(tester.getTopLeft(find.text(text)).dy, 28.0);
        controller.clear();
        focusNode.unfocus();

        // alignLabelWithHint: true aligns the label with the hint.
        await tester.pumpWidget(buildFrame(true));
        await tester.pumpAndSettle();
        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);

        // Entering text still happens at the top.
        await tester.enterText(find.byType(InputDecorator), text);
        expect(tester.getTopLeft(find.text(text)).dy, 28.0);
        controller.clear();
        focusNode.unfocus();
      });
    });

    group('expands true', () {
      testWidgets('multiline TextField', (WidgetTester tester) async {
        const String text = 'text';
        final FocusNode focusNode = FocusNode();
        final TextEditingController controller = TextEditingController();
        Widget buildFrame(bool alignLabelWithHint) {
          return MaterialApp(
            home: Material(
              child: Directionality(
                textDirection: TextDirection.ltr,
                child: TextField(
                  controller: controller,
                  focusNode: focusNode,
                  maxLines: null,
                  expands: true,
                  decoration: InputDecoration(
                    labelText: 'label',
                    alignLabelWithHint: alignLabelWithHint,
                    hintText: 'hint',
                  ),
                ),
              ),
            ),
          );
        }

        // alignLabelWithHint: false centers the label in the TextField.
        await tester.pumpWidget(buildFrame(false));
        await tester.pumpAndSettle();
        expect(tester.getTopLeft(find.text('label')).dy, 292.0);
        expect(tester.getBottomLeft(find.text('label')).dy, 308.0);

        // Entering text still happens at the top.
        await tester.enterText(find.byType(InputDecorator), text);
        expect(tester.getTopLeft(find.text(text)).dy, 28.0);
        controller.clear();
        focusNode.unfocus();

        // alignLabelWithHint: true aligns the label with the hint at the top.
        await tester.pumpWidget(buildFrame(true));
        await tester.pumpAndSettle();
        expect(tester.getTopLeft(find.text('label')).dy, 28.0);
        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);

        // Entering text still happens at the top.
        await tester.enterText(find.byType(InputDecorator), text);
        expect(tester.getTopLeft(find.text(text)).dy, 28.0);
        controller.clear();
        focusNode.unfocus();
      });

      testWidgets('multiline TextField with outline border', (WidgetTester tester) async {
        const String text = 'text';
        final FocusNode focusNode = FocusNode();
        final TextEditingController controller = TextEditingController();
        Widget buildFrame(bool alignLabelWithHint) {
          return MaterialApp(
            home: Material(
              child: Directionality(
                textDirection: TextDirection.ltr,
                child: TextField(
                  controller: controller,
                  focusNode: focusNode,
                  maxLines: null,
                  expands: true,
                  decoration: InputDecoration(
                    labelText: 'label',
                    alignLabelWithHint: alignLabelWithHint,
                    hintText: 'hint',
                    border: OutlineInputBorder(
                      borderSide: const BorderSide(width: 1, color: Colors.black, style: BorderStyle.solid),
                      borderRadius: BorderRadius.circular(0),
                    ),
                  ),
                ),
              ),
            ),
          );
        }

        // alignLabelWithHint: false centers the label in the TextField.
        await tester.pumpWidget(buildFrame(false));
        await tester.pumpAndSettle();
        expect(tester.getTopLeft(find.text('label')).dy, 292.0);
        expect(tester.getBottomLeft(find.text('label')).dy, 308.0);

        // Entering text happens in the center as well.
        await tester.enterText(find.byType(InputDecorator), text);
        expect(tester.getTopLeft(find.text(text)).dy, 291.0);
        controller.clear();
        focusNode.unfocus();

        // alignLabelWithHint: true aligns keeps the label in the center because
        // that's where the hint is.
        await tester.pumpWidget(buildFrame(true));
        await tester.pumpAndSettle();
        expect(tester.getTopLeft(find.text('label')).dy, 291.0);
        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);

        // Entering text still happens in the center.
        await tester.enterText(find.byType(InputDecorator), text);
        expect(tester.getTopLeft(find.text(text)).dy, 291.0);
        controller.clear();
        focusNode.unfocus();
      });
    });
  });

  // Overall height for this InputDecorator is 40.0dps
  //   12 - top padding
  //   16 - input text (ahem font size 16dps)
  //   12 - bottom padding
  testWidgets('InputDecorator input/hint layout', (WidgetTester tester) async {
    // The hint aligns with the input text
    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        // isFocused: false (default)
        decoration: const InputDecoration(
          hintText: 'hint',
        ),
      ),
    );

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, kMinInteractiveDimension));
    expect(tester.getTopLeft(find.text('text')).dy, 16.0);
    expect(tester.getBottomLeft(find.text('text')).dy, 32.0);
    expect(tester.getTopLeft(find.text('hint')).dy, 16.0);
    expect(tester.getBottomLeft(find.text('hint')).dy, 32.0);
    expect(getBorderBottom(tester), 48.0);
    expect(getBorderWeight(tester), 1.0);

    expect(tester.getSize(find.text('hint')).width, tester.getSize(find.text('text')).width);
  });

  testWidgets('InputDecorator input/label/hint layout', (WidgetTester tester) async {
    // Label is visible, hint is not (opacity 0.0).
    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        // isFocused: false (default)
        decoration: const InputDecoration(
          labelText: 'label',
          hintText: 'hint',
        ),
      ),
    );

    // Overall height for this InputDecorator is 56dps. When the
    // label is "floating" (empty input or no focus) the layout is:
    //
    //   12 - top padding
    //   12 - floating label (ahem font size 16dps * 0.75 = 12)
    //    4 - floating label / input text gap
    //   16 - input text (ahem font size 16dps)
    //   12 - bottom padding
    //
    // When the label is not floating, it's vertically centered.
    //
    //   20 - top padding
    //   16 - label (ahem font size 16dps)
    //   20 - bottom padding (empty input text still appears here)


    // The label is not floating so it's vertically centered.
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
    expect(tester.getTopLeft(find.text('text')).dy, 28.0);
    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(getOpacity(tester, 'hint'), 0.0);
    expect(getBorderBottom(tester), 56.0);
    expect(getBorderWeight(tester), 1.0);

    // Label moves upwards, hint is visible (opacity 1.0).
    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        isFocused: true,
        decoration: const InputDecoration(
          labelText: 'label',
          hintText: 'hint',
        ),
      ),
    );

    // The hint's opacity animates from 0.0 to 1.0.
    // The animation's duration is 200ms.
    {
      await tester.pump(const Duration(milliseconds: 50));
      final double hintOpacity50ms = getOpacity(tester, 'hint');
      expect(hintOpacity50ms, inExclusiveRange(0.0, 1.0));
      await tester.pump(const Duration(milliseconds: 50));
      final double hintOpacity100ms = getOpacity(tester, 'hint');
      expect(hintOpacity100ms, inExclusiveRange(hintOpacity50ms, 1.0));
    }

    await tester.pumpAndSettle();
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
    expect(tester.getTopLeft(find.text('text')).dy, 28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, 44.0);
    expect(tester.getTopLeft(find.text('label')).dy, 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 24.0);
    expect(tester.getTopLeft(find.text('hint')).dy, 28.0);
    expect(tester.getBottomLeft(find.text('hint')).dy, 44.0);
    expect(getOpacity(tester, 'hint'), 1.0);
    expect(getBorderBottom(tester), 56.0);
    expect(getBorderWeight(tester), 2.0);

    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: false,
        isFocused: true,
        decoration: const InputDecoration(
          labelText: 'label',
          hintText: 'hint',
        ),
      ),
    );

    // The hint's opacity animates from 1.0 to 0.0.
    // The animation's duration is 200ms.
    {
      await tester.pump(const Duration(milliseconds: 50));
      final double hintOpacity50ms = getOpacity(tester, 'hint');
      expect(hintOpacity50ms, inExclusiveRange(0.0, 1.0));
      await tester.pump(const Duration(milliseconds: 50));
      final double hintOpacity100ms = getOpacity(tester, 'hint');
      expect(hintOpacity100ms, inExclusiveRange(0.0, hintOpacity50ms));
    }

    await tester.pumpAndSettle();
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
    expect(tester.getTopLeft(find.text('text')).dy, 28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, 44.0);
    expect(tester.getTopLeft(find.text('label')).dy, 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 24.0);
    expect(tester.getTopLeft(find.text('hint')).dy, 28.0);
    expect(tester.getBottomLeft(find.text('hint')).dy, 44.0);
    expect(getOpacity(tester, 'hint'), 0.0);
    expect(getBorderBottom(tester), 56.0);
    expect(getBorderWeight(tester), 2.0);
  });

  testWidgets('InputDecorator input/label/hint dense layout', (WidgetTester tester) async {
    // Label is visible, hint is not (opacity 0.0).
    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        // isFocused: false (default)
        decoration: const InputDecoration(
          labelText: 'label',
          hintText: 'hint',
          isDense: true,
        ),
      ),
    );

    // Overall height for this InputDecorator is 48dps. When the
    // label is "floating" (empty input or no focus) the layout is:
    //
    //    8 - top padding
    //   12 - floating label (ahem font size 16dps * 0.75 = 12)
    //    4 - floating label / input text gap
    //   16 - input text (ahem font size 16dps)
    //    8 - bottom padding
    //
    // When the label is not floating, it's vertically centered.
    //
    //   16 - top padding
    //   16 - label (ahem font size 16dps)
    //   16 - bottom padding (empty input text still appears here)

    // The label is not floating so it's vertically centered.
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0));
    expect(tester.getTopLeft(find.text('text')).dy, 24.0);
    expect(tester.getBottomLeft(find.text('text')).dy, 40.0);
    expect(tester.getTopLeft(find.text('label')).dy, 16.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 32.0);
    expect(getOpacity(tester, 'hint'), 0.0);
    expect(getBorderBottom(tester), 48.0);
    expect(getBorderWeight(tester), 1.0);

    // Label is visible, hint is not (opacity 0.0).
    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        isFocused: true,
        decoration: const InputDecoration(
          labelText: 'label',
          hintText: 'hint',
          isDense: true,
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0));
    expect(tester.getTopLeft(find.text('text')).dy, 24.0);
    expect(tester.getBottomLeft(find.text('text')).dy, 40.0);
    expect(tester.getTopLeft(find.text('label')).dy, 8.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 20.0);
    expect(getOpacity(tester, 'hint'), 1.0);
    expect(getBorderBottom(tester), 48.0);
    expect(getBorderWeight(tester), 2.0);
  });

  testWidgets('InputDecorator with no input border', (WidgetTester tester) async {
    // Label is visible, hint is not (opacity 0.0).
    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        // isFocused: false (default)
        decoration: const InputDecoration(
          border: InputBorder.none,
        ),
      ),
    );
    expect(getBorderWeight(tester), 0.0);
  });

  testWidgets('InputDecorator error/helper/counter layout', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        // isFocused: false (default)
        decoration: const InputDecoration(
          labelText: 'label',
          helperText: 'helper',
          counterText: 'counter',
          filled: true,
        ),
      ),
    );

    // Overall height for this InputDecorator is 76dps. When the label is
    // floating the layout is:
    //
    //   12 - top padding
    //   12 - floating label (ahem font size 16dps * 0.75 = 12)
    //    4 - floating label / input text gap
    //   16 - input text (ahem font size 16dps)
    //   12 - bottom padding
    //    8 - below the border padding
    //   12 - help/error/counter text (ahem font size 12dps)
    //
    // When the label is not floating, it's vertically centered in the space
    // above the subtext:
    //
    //   20 - top padding
    //   16 - label (ahem font size 16dps)
    //   20 - bottom padding (empty input text still appears here)
    //    8 - below the border padding
    //   12 - help/error/counter text (ahem font size 12dps)

    // isEmpty: true, the label is not floating
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 76.0));
    expect(tester.getTopLeft(find.text('text')).dy, 28.0);
    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(getBorderBottom(tester), 56.0);
    expect(getBorderWeight(tester), 1.0);
    expect(tester.getTopLeft(find.text('helper')), const Offset(12.0, 64.0));
    expect(tester.getTopRight(find.text('counter')), const Offset(788.0, 64.0));

    // If errorText is specified then the helperText isn't shown
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: const InputDecoration(
          labelText: 'label',
          errorText: 'error',
          helperText: 'helper',
          counterText: 'counter',
          filled: true,
        ),
      ),
    );
    await tester.pumpAndSettle();

    // isEmpty: false, the label _is_ floating
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 76.0));
    expect(tester.getTopLeft(find.text('text')).dy, 28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, 44.0);
    expect(tester.getTopLeft(find.text('label')).dy, 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 24.0);
    expect(getBorderBottom(tester), 56.0);
    expect(getBorderWeight(tester), 1.0);
    expect(tester.getTopLeft(find.text('error')), const Offset(12.0, 64.0));
    expect(tester.getTopRight(find.text('counter')), const Offset(788.0, 64.0));
    expect(find.text('helper'), findsNothing);

    // Overall height for this dense layout InputDecorator is 68dps. When the
    // label is floating the layout is:
    //
    //    8 - top padding
    //   12 - floating label (ahem font size 16dps * 0.75 = 12)
    //    4 - floating label / input text gap
    //   16 - input text (ahem font size 16dps)
    //    8 - bottom padding
    //    8 - below the border padding
    //   12 - help/error/counter text (ahem font size 12dps)
    //
    // When the label is not floating, it's vertically centered in the space
    // above the subtext:
    //
    //   16 - top padding
    //   16 - label (ahem font size 16dps)
    //   16 - bottom padding (empty input text still appears here)
    //    8 - below the border padding
    //   12 - help/error/counter text (ahem font size 12dps)
    // The layout of the error/helper/counter subtext doesn't change for dense layout.
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: const InputDecoration(
          isDense: true,
          labelText: 'label',
          errorText: 'error',
          helperText: 'helper',
          counterText: 'counter',
          filled: true,
        ),
      ),
    );
    await tester.pumpAndSettle();

    // isEmpty: false, the label _is_ floating
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 68.0));
    expect(tester.getTopLeft(find.text('text')).dy, 24.0);
    expect(tester.getBottomLeft(find.text('text')).dy, 40.0);
    expect(tester.getTopLeft(find.text('label')).dy, 8.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 20.0);
    expect(getBorderBottom(tester), 48.0);
    expect(getBorderWeight(tester), 1.0);
    expect(tester.getTopLeft(find.text('error')), const Offset(12.0, 56.0));
    expect(tester.getTopRight(find.text('counter')), const Offset(788.0, 56.0));

    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        // isFocused: false (default)
        decoration: const InputDecoration(
          isDense: true,
          labelText: 'label',
          errorText: 'error',
          helperText: 'helper',
          counterText: 'counter',
          filled: true,
        ),
      ),
    );
    await tester.pumpAndSettle();

    // isEmpty: false, the label is not floating
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 68.0));
    expect(tester.getTopLeft(find.text('text')).dy, 24.0);
    expect(tester.getBottomLeft(find.text('text')).dy, 40.0);
    expect(tester.getTopLeft(find.text('label')).dy, 16.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 32.0);
    expect(getBorderBottom(tester), 48.0);
    expect(getBorderWeight(tester), 1.0);
    expect(tester.getTopLeft(find.text('error')), const Offset(12.0, 56.0));
    expect(tester.getTopRight(find.text('counter')), const Offset(788.0, 56.0));
  });

  testWidgets('InputDecorator counter text, widget, and null', (WidgetTester tester) async {
    Widget buildFrame({
      InputCounterWidgetBuilder? buildCounter,
      String? counterText,
      Widget? counter,
      int? maxLength,
    }) {
      return MaterialApp(
        home: Scaffold(
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                TextFormField(
                  buildCounter: buildCounter,
                  maxLength: maxLength,
                  decoration: InputDecoration(
                    counterText: counterText,
                    counter: counter,
                  ),
                ),
              ],
            ),
          ),
        ),
      );
    }

    // When counter, counterText, and buildCounter are null, defaults to showing
    // the built-in counter.
    int? maxLength = 10;
    await tester.pumpWidget(buildFrame(maxLength: maxLength));
    Finder counterFinder = find.byType(Text);
    expect(counterFinder, findsOneWidget);
    final Text counterWidget = tester.widget(counterFinder);
    expect(counterWidget.data, '0/${maxLength.toString()}');

    // When counter, counterText, and buildCounter are set, shows the counter
    // widget.
    final Key counterKey = UniqueKey();
    final Key buildCounterKey = UniqueKey();
    const String counterText = 'I show instead of count';
    final Widget counter = Text('hello', key: counterKey);
    Widget buildCounter(
      BuildContext context, {
      required int currentLength,
      required int? maxLength,
      required bool isFocused,
    }) {
      return Text(
        '${currentLength.toString()} of ${maxLength.toString()}',
        key: buildCounterKey,
      );
    }

    await tester.pumpWidget(buildFrame(
      counterText: counterText,
      counter: counter,
      buildCounter: buildCounter,
      maxLength: maxLength,
    ));
    counterFinder = find.byKey(counterKey);
    expect(counterFinder, findsOneWidget);
    expect(find.text(counterText), findsNothing);
    expect(find.byKey(buildCounterKey), findsNothing);

    // When counter is null but counterText and buildCounter are set, shows the
    // counterText.
    await tester.pumpWidget(buildFrame(
      counterText: counterText,
      buildCounter: buildCounter,
      maxLength: maxLength,
    ));
    expect(find.text(counterText), findsOneWidget);
    counterFinder = find.byKey(counterKey);
    expect(counterFinder, findsNothing);
    expect(find.byKey(buildCounterKey), findsNothing);

    // When counter and counterText are null but buildCounter is set, shows the
    // generated widget.
    await tester.pumpWidget(buildFrame(
      buildCounter: buildCounter,
      maxLength: maxLength,
    ));
    expect(find.byKey(buildCounterKey), findsOneWidget);
    expect(counterFinder, findsNothing);
    expect(find.text(counterText), findsNothing);

    // When counterText is empty string and counter and buildCounter are null,
    // shows nothing.
    await tester.pumpWidget(buildFrame(counterText: '', maxLength: maxLength));
    expect(find.byType(Text), findsNothing);

    // When no maxLength, can still show a counter
    maxLength = null;
    await tester.pumpWidget(buildFrame(
      buildCounter: buildCounter,
      maxLength: maxLength,
    ));
    expect(find.byKey(buildCounterKey), findsOneWidget);
  });

  testWidgets('InputDecoration errorMaxLines', (WidgetTester tester) async {
    const String kError1 = 'e0';
    const String kError2 = 'e0\ne1';
    const String kError3 = 'e0\ne1\ne2';

    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        // isFocused: false (default)
        decoration: const InputDecoration(
          labelText: 'label',
          helperText: 'helper',
          errorText: kError3,
          errorMaxLines: 3,
          filled: true,
        ),
      ),
    );

    // Overall height for this InputDecorator is 100dps:
    //
    //   12 - top padding
    //   12 - floating label (ahem font size 16dps * 0.75 = 12)
    //    4 - floating label / input text gap
    //   16 - input text (ahem font size 16dps)
    //   12 - bottom padding
    //    8 - below the border padding
    //   36 - error text (3 lines, ahem font size 12dps)

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 100.0));
    expect(tester.getTopLeft(find.text(kError3)), const Offset(12.0, 64.0));
    expect(tester.getBottomLeft(find.text(kError3)), const Offset(12.0, 100.0));

    // Overall height for this InputDecorator is 12 less than the first
    // one, 88dps, because errorText only occupies two lines.

    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        // isFocused: false (default)
        decoration: const InputDecoration(
          labelText: 'label',
          helperText: 'helper',
          errorText: kError2,
          errorMaxLines: 3,
          filled: true,
        ),
      ),
    );

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 88.0));
    expect(tester.getTopLeft(find.text(kError2)), const Offset(12.0, 64.0));
    expect(tester.getBottomLeft(find.text(kError2)), const Offset(12.0, 88.0));

    // Overall height for this InputDecorator is 24 less than the first
    // one, 88dps, because errorText only occupies one line.

    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        // isFocused: false (default)
        decoration: const InputDecoration(
          labelText: 'label',
          helperText: 'helper',
          errorText: kError1,
          errorMaxLines: 3,
          filled: true,
        ),
      ),
    );

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 76.0));
    expect(tester.getTopLeft(find.text(kError1)), const Offset(12.0, 64.0));
    expect(tester.getBottomLeft(find.text(kError1)), const Offset(12.0, 76.0));
  });

  testWidgets('InputDecoration helperMaxLines', (WidgetTester tester) async {
    const String kHelper1 = 'e0';
    const String kHelper2 = 'e0\ne1';
    const String kHelper3 = 'e0\ne1\ne2';

    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        // isFocused: false (default)
        decoration: const InputDecoration(
          labelText: 'label',
          helperText: kHelper3,
          helperMaxLines: 3,
          errorText: null,
          filled: true,
        ),
      ),
    );

    // Overall height for this InputDecorator is 100dps:
    //
    //   12 - top padding
    //   12 - floating label (ahem font size 16dps * 0.75 = 12)
    //    4 - floating label / input text gap
    //   16 - input text (ahem font size 16dps)
    //   12 - bottom padding
    //    8 - below the border padding
    //   36 - helper text (3 lines, ahem font size 12dps)

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 100.0));
    expect(tester.getTopLeft(find.text(kHelper3)), const Offset(12.0, 64.0));
    expect(tester.getBottomLeft(find.text(kHelper3)), const Offset(12.0, 100.0));

    // Overall height for this InputDecorator is 12 less than the first
    // one, 88dps, because helperText only occupies two lines.

    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        // isFocused: false (default)
        decoration: const InputDecoration(
          labelText: 'label',
          helperText: kHelper3,
          helperMaxLines: 2,
          errorText: null,
          filled: true,
        ),
      ),
    );

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 88.0));
    expect(tester.getTopLeft(find.text(kHelper3)), const Offset(12.0, 64.0));
    expect(tester.getBottomLeft(find.text(kHelper3)), const Offset(12.0, 88.0));

    // Overall height for this InputDecorator is 12 less than the first
    // one, 88dps, because helperText only occupies two lines.

    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        // isFocused: false (default)
        decoration: const InputDecoration(
          labelText: 'label',
          helperText: kHelper2,
          helperMaxLines: 3,
          errorText: null,
          filled: true,
        ),
      ),
    );

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 88.0));
    expect(tester.getTopLeft(find.text(kHelper2)), const Offset(12.0, 64.0));
    expect(tester.getBottomLeft(find.text(kHelper2)), const Offset(12.0, 88.0));

    // Overall height for this InputDecorator is 24 less than the first
    // one, 88dps, because helperText only occupies one line.

    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        // isFocused: false (default)
        decoration: const InputDecoration(
          labelText: 'label',
          helperText: kHelper1,
          helperMaxLines: 3,
          errorText: null,
          filled: true,
        ),
      ),
    );

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 76.0));
    expect(tester.getTopLeft(find.text(kHelper1)), const Offset(12.0, 64.0));
    expect(tester.getBottomLeft(find.text(kHelper1)), const Offset(12.0, 76.0));
  });

  testWidgets('InputDecorator prefix/suffix texts', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: const InputDecoration(
          prefixText: 'p',
          suffixText: 's',
          filled: true,
        ),
      ),
    );

    // Overall height for this InputDecorator is 40dps:
    //   12 - top padding
    //   16 - input text (ahem font size 16dps)
    //   12 - bottom padding
    //
    // The prefix and suffix wrap the input text and are left and right justified
    // respectively. They should have the same height as the input text (16).

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, kMinInteractiveDimension));
    expect(tester.getSize(find.text('text')).height, 16.0);
    expect(tester.getSize(find.text('p')).height, 16.0);
    expect(tester.getSize(find.text('s')).height, 16.0);
    expect(tester.getTopLeft(find.text('text')).dy, 16.0);
    expect(tester.getTopLeft(find.text('p')).dy, 16.0);
    expect(tester.getTopLeft(find.text('p')).dx, 12.0);
    expect(tester.getTopLeft(find.text('s')).dy, 16.0);
    expect(tester.getTopRight(find.text('s')).dx, 788.0);

    // layout is a row: [p text s]
    expect(tester.getTopLeft(find.text('p')).dx, 12.0);
    expect(tester.getTopRight(find.text('p')).dx, lessThanOrEqualTo(tester.getTopLeft(find.text('text')).dx));
    expect(tester.getTopRight(find.text('text')).dx, lessThanOrEqualTo(tester.getTopLeft(find.text('s')).dx));
  });

  testWidgets('InputDecorator icon/prefix/suffix', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: const InputDecoration(
          prefixText: 'p',
          suffixText: 's',
          icon: Icon(Icons.android),
          filled: true,
        ),
      ),
    );

    // Overall height for this InputDecorator is 40dps:
    //   12 - top padding
    //   16 - input text (ahem font size 16dps)
    //   12 - bottom padding

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, kMinInteractiveDimension));
    expect(tester.getSize(find.text('text')).height, 16.0);
    expect(tester.getSize(find.text('p')).height, 16.0);
    expect(tester.getSize(find.text('s')).height, 16.0);
    expect(tester.getTopLeft(find.text('text')).dy, 16.0);
    expect(tester.getTopLeft(find.text('p')).dy, 16.0);
    expect(tester.getTopLeft(find.text('s')).dy, 16.0);
    expect(tester.getTopRight(find.text('s')).dx, 788.0);
    expect(tester.getSize(find.byType(Icon)).height, 24.0);

    // The 24dps high icon is centered on the 16dps high input line
    expect(tester.getTopLeft(find.byType(Icon)).dy, 12.0);

    // layout is a row: [icon, p text s]
    expect(tester.getTopLeft(find.byType(Icon)).dx, 0.0);
    expect(tester.getTopRight(find.byType(Icon)).dx, lessThanOrEqualTo(tester.getTopLeft(find.text('p')).dx));
    expect(tester.getTopRight(find.text('p')).dx, lessThanOrEqualTo(tester.getTopLeft(find.text('text')).dx));
    expect(tester.getTopRight(find.text('text')).dx, lessThanOrEqualTo(tester.getTopLeft(find.text('s')).dx));
  });

  testWidgets('InputDecorator prefix/suffix widgets', (WidgetTester tester) async {
    const Key pKey = Key('p');
    const Key sKey = Key('s');
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: const InputDecoration(
          prefix: Padding(
            key: pKey,
            padding: EdgeInsets.all(4.0),
            child: Text('p'),
          ),
          suffix: Padding(
            key: sKey,
            padding: EdgeInsets.all(4.0),
            child: Text('s'),
          ),
          filled: true,
        ),
      ),
    );

    // Overall height for this InputDecorator is 48dps because
    // the prefix and the suffix widget is surrounded with padding:
    //   12 - top padding
    //    4 - top prefix/suffix padding
    //   16 - input text (ahem font size 16dps)
    //    4 - bottom prefix/suffix padding
    //   12 - bottom padding

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0));
    expect(tester.getSize(find.text('text')).height, 16.0);
    expect(tester.getSize(find.byKey(pKey)).height, 24.0);
    expect(tester.getSize(find.text('p')).height, 16.0);
    expect(tester.getSize(find.byKey(sKey)).height, 24.0);
    expect(tester.getSize(find.text('s')).height, 16.0);
    expect(tester.getTopLeft(find.text('text')).dy, 16.0);
    expect(tester.getTopLeft(find.byKey(pKey)).dy, 12.0);
    expect(tester.getTopLeft(find.text('p')).dy, 16.0);
    expect(tester.getTopLeft(find.byKey(sKey)).dy, 12.0);
    expect(tester.getTopLeft(find.text('s')).dy, 16.0);
    expect(tester.getTopRight(find.byKey(sKey)).dx, 788.0);
    expect(tester.getTopRight(find.text('s')).dx, 784.0);

    // layout is a row: [prefix text suffix]
    expect(tester.getTopLeft(find.byKey(pKey)).dx, 12.0);
    expect(tester.getTopRight(find.byKey(pKey)).dx, tester.getTopLeft(find.text('text')).dx);
    expect(tester.getTopRight(find.text('text')).dx, lessThanOrEqualTo(tester.getTopRight(find.byKey(sKey)).dx));
  });

  testWidgets('InputDecorator tall prefix', (WidgetTester tester) async {
    const Key pKey = Key('p');
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: const InputDecoration(
          prefix: SizedBox(
            key: pKey,
            height: 100,
            width: 10,
          ),
          filled: true,
        ),
        // Set the fontSize so that everything works out to whole numbers.
        child: const Text(
          'text',
          style: TextStyle(fontFamily: 'Ahem', fontSize: 20.0),
        ),
      ),
    );

    // Overall height for this InputDecorator is ~127.2dps because
    // the prefix is 100dps tall, but it aligns with the input's baseline,
    // overlapping the input a bit.
    //   12 - top padding
    //  100 - total height of prefix
    //  -16 - input prefix overlap (distance input top to baseline, not exact)
    //   20 - input text (ahem font size 16dps)
    //    0 - bottom prefix/suffix padding
    //   12 - bottom padding

    expect(tester.getSize(find.byType(InputDecorator)).width, 800.0);
    expect(tester.getSize(find.byType(InputDecorator)).height, moreOrLessEquals(128.0, epsilon: .0001));
    expect(tester.getSize(find.text('text')).height, 20.0);
    expect(tester.getSize(find.byKey(pKey)).height, 100.0);
    expect(tester.getTopLeft(find.text('text')).dy, moreOrLessEquals(96, epsilon: .0001)); // 12 + 100 - 16
    expect(tester.getTopLeft(find.byKey(pKey)).dy, 12.0);

    // layout is a row: [prefix text suffix]
    expect(tester.getTopLeft(find.byKey(pKey)).dx, 12.0);
    expect(tester.getTopRight(find.byKey(pKey)).dx, tester.getTopLeft(find.text('text')).dx);
  });

  testWidgets('InputDecorator tall prefix with border', (WidgetTester tester) async {
    const Key pKey = Key('p');
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: const InputDecoration(
          border: OutlineInputBorder(),
          prefix: SizedBox(
            key: pKey,
            height: 100,
            width: 10,
          ),
          filled: true,
        ),
        // Set the fontSize so that everything works out to whole numbers.
        child: const Text(
          'text',
          style: TextStyle(fontFamily: 'Ahem', fontSize: 20.0),
        ),
      ),
    );

    // Overall height for this InputDecorator is ~127.2dps because
    // the prefix is 100dps tall, but it aligns with the input's baseline,
    // overlapping the input a bit.
    //   24 - top padding
    //  100 - total height of prefix
    //  -16 - input prefix overlap (distance input top to baseline, not exact)
    //   20 - input text (ahem font size 16dps)
    //    0 - bottom prefix/suffix padding
    //   16 - bottom padding
    // When a border is present, the input text and prefix/suffix are centered
    // within the input. Here, that will be content of height 106, including 2
    // extra pixels of space, centered within an input of height 144. That gives
    // 19 pixels of space on each side of the content, so the prefix is
    // positioned at 19, and the text is at 19+100-16=103.

    expect(tester.getSize(find.byType(InputDecorator)).width, 800.0);
    expect(tester.getSize(find.byType(InputDecorator)).height, moreOrLessEquals(144, epsilon: .0001));
    expect(tester.getSize(find.text('text')).height, 20.0);
    expect(tester.getSize(find.byKey(pKey)).height, 100.0);
    expect(tester.getTopLeft(find.text('text')).dy, moreOrLessEquals(103, epsilon: .0001));
    expect(tester.getTopLeft(find.byKey(pKey)).dy, 19.0);

    // layout is a row: [prefix text suffix]
    expect(tester.getTopLeft(find.byKey(pKey)).dx, 12.0);
    expect(tester.getTopRight(find.byKey(pKey)).dx, tester.getTopLeft(find.text('text')).dx);
  });

  testWidgets('InputDecorator prefixIcon/suffixIcon', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: const InputDecoration(
          prefixIcon: Icon(Icons.pages),
          suffixIcon: Icon(Icons.satellite),
          filled: true,
        ),
      ),
    );

    // Overall height for this InputDecorator is 48dps because the prefix icon's minimum size
    // is 48x48 and the rest of the elements only require 40dps:
     //   12 - top padding
     //   16 - input text (ahem font size 16dps)
     //   12 - bottom padding

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0));
    expect(tester.getSize(find.text('text')).height, 16.0);
    expect(tester.getSize(find.byIcon(Icons.pages)).height, 48.0);
    expect(tester.getSize(find.byIcon(Icons.satellite)).height, 48.0);
    expect(tester.getTopLeft(find.text('text')).dy, 12.0);
    expect(tester.getTopLeft(find.byIcon(Icons.pages)).dy, 0.0);
    expect(tester.getTopLeft(find.byIcon(Icons.satellite)).dy, 0.0);
    expect(tester.getTopRight(find.byIcon(Icons.satellite)).dx, 800.0);


    // layout is a row: [icon text icon]
    expect(tester.getTopLeft(find.byIcon(Icons.pages)).dx, 0.0);
    expect(tester.getTopRight(find.byIcon(Icons.pages)).dx, lessThanOrEqualTo(tester.getTopLeft(find.text('text')).dx));
    expect(tester.getTopRight(find.text('text')).dx, lessThanOrEqualTo(tester.getTopLeft(find.byIcon(Icons.satellite)).dx));
  });

  testWidgets('InputDecorator prefixIconConstraints/suffixIconConstraints', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: const InputDecoration(
          prefixIcon: Icon(Icons.pages),
          prefixIconConstraints: BoxConstraints(
            minWidth: 32,
            minHeight: 32,
          ),
          suffixIcon: Icon(Icons.satellite),
          suffixIconConstraints: BoxConstraints(
            minWidth: 25,
            minHeight: 25,
          ),
          isDense: true, // has to be true to go below 48px height
        ),
      ),
    );

    // Overall height for this InputDecorator is 32px because the prefix icon
    // is now a custom value
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 32.0));
    expect(tester.getSize(find.text('text')).height, 16.0);
    expect(tester.getSize(find.byIcon(Icons.pages)).height, 32.0);
    expect(tester.getSize(find.byIcon(Icons.satellite)).height, 25.0);

    // (InputDecorator height - Text widget height) / 2
    expect(tester.getTopLeft(find.text('text')).dy, (32.0 - 16.0) / 2);
    // prefixIcon should take up the entire height of InputDecorator
    expect(tester.getTopLeft(find.byIcon(Icons.pages)).dy, 0.0);
    // (InputDecorator height - suffixIcon height) / 2
    expect(tester.getTopLeft(find.byIcon(Icons.satellite)).dy, (32.0 - 25.0) / 2);
    expect(tester.getTopRight(find.byIcon(Icons.satellite)).dx, 800.0);
  });

  testWidgets('prefix/suffix icons are centered when smaller than 48 by 48', (WidgetTester tester) async {
    const Key prefixKey = Key('prefix');
    await tester.pumpWidget(
      buildInputDecorator(
        decoration: const InputDecoration(
          prefixIcon: Padding(
            padding: EdgeInsets.all(16.0),
            child: SizedBox(width: 8.0, height: 8.0, key: prefixKey),
          ),
          filled: true,
        ),
      ),
    );

    // Overall height for this InputDecorator is 48dps because the prefix icon's minimum size
     // is 48x48 and the rest of the elements only require 40dps:
     //   12 - top padding
     //   16 - input text (ahem font size 16dps)
     //   12 - bottom padding

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0));
    expect(tester.getSize(find.byKey(prefixKey)).height, 16.0);
    expect(tester.getTopLeft(find.byKey(prefixKey)).dy, 16.0);
  });

  testWidgets('InputDecorator respects reduced theme visualDensity', (WidgetTester tester) async {
    // Label is visible, hint is not (opacity 0.0).
    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        visualDensity: VisualDensity.compact,
        decoration: const InputDecoration(
          labelText: 'label',
          hintText: 'hint',
        ),
      ),
    );

    // The label is not floating so it's vertically centered.
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0));
    expect(tester.getTopLeft(find.text('text')).dy, 24.0);
    expect(tester.getBottomLeft(find.text('text')).dy, 40.0);
    expect(tester.getTopLeft(find.text('label')).dy, 16.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 32.0);
    expect(getOpacity(tester, 'hint'), 0.0);
    expect(getBorderBottom(tester), 48.0);
    expect(getBorderWeight(tester), 1.0);

    // Label moves upwards, hint is visible (opacity 1.0).
    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        isFocused: true,
        visualDensity: VisualDensity.compact,
        decoration: const InputDecoration(
          labelText: 'label',
          hintText: 'hint',
        ),
      ),
    );

    // The hint's opacity animates from 0.0 to 1.0.
    // The animation's duration is 200ms.
    {
      await tester.pump(const Duration(milliseconds: 50));
      final double hintOpacity50ms = getOpacity(tester, 'hint');
      expect(hintOpacity50ms, inExclusiveRange(0.0, 1.0));
      await tester.pump(const Duration(milliseconds: 50));
      final double hintOpacity100ms = getOpacity(tester, 'hint');
      expect(hintOpacity100ms, inExclusiveRange(hintOpacity50ms, 1.0));
    }

    await tester.pumpAndSettle();
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0));
    expect(tester.getTopLeft(find.text('text')).dy, 24.0);
    expect(tester.getBottomLeft(find.text('text')).dy, 40.0);
    expect(tester.getTopLeft(find.text('label')).dy, 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 24.0);
    expect(tester.getTopLeft(find.text('hint')).dy, 24.0);
    expect(tester.getBottomLeft(find.text('hint')).dy, 40.0);
    expect(getOpacity(tester, 'hint'), 1.0);
    expect(getBorderBottom(tester), 48.0);
    expect(getBorderWeight(tester), 2.0);

    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: false,
        isFocused: true,
        visualDensity: VisualDensity.compact,
        decoration: const InputDecoration(
          labelText: 'label',
          hintText: 'hint',
        ),
      ),
    );

    // The hint's opacity animates from 1.0 to 0.0.
    // The animation's duration is 200ms.
    {
      await tester.pump(const Duration(milliseconds: 50));
      final double hintOpacity50ms = getOpacity(tester, 'hint');
      expect(hintOpacity50ms, inExclusiveRange(0.0, 1.0));
      await tester.pump(const Duration(milliseconds: 50));
      final double hintOpacity100ms = getOpacity(tester, 'hint');
      expect(hintOpacity100ms, inExclusiveRange(0.0, hintOpacity50ms));
    }

    await tester.pumpAndSettle();
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0));
    expect(tester.getTopLeft(find.text('text')).dy, 24.0);
    expect(tester.getBottomLeft(find.text('text')).dy, 40.0);
    expect(tester.getTopLeft(find.text('label')).dy, 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 24.0);
    expect(tester.getTopLeft(find.text('hint')).dy, 24.0);
    expect(tester.getBottomLeft(find.text('hint')).dy, 40.0);
    expect(getOpacity(tester, 'hint'), 0.0);
    expect(getBorderBottom(tester), 48.0);
    expect(getBorderWeight(tester), 2.0);
  });

  testWidgets('InputDecorator respects increased theme visualDensity', (WidgetTester tester) async {
    // Label is visible, hint is not (opacity 0.0).
    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        visualDensity: const VisualDensity(horizontal: 2.0, vertical: 2.0),
        decoration: const InputDecoration(
          labelText: 'label',
          hintText: 'hint',
        ),
      ),
    );

    // The label is not floating so it's vertically centered.
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 64.0));
    expect(tester.getTopLeft(find.text('text')).dy, 32.0);
    expect(tester.getBottomLeft(find.text('text')).dy, 48.0);
    expect(tester.getTopLeft(find.text('label')).dy, 24.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 40.0);
    expect(getOpacity(tester, 'hint'), 0.0);
    expect(getBorderBottom(tester), 64.0);
    expect(getBorderWeight(tester), 1.0);

    // Label moves upwards, hint is visible (opacity 1.0).
    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        isFocused: true,
        visualDensity: const VisualDensity(horizontal: 2.0, vertical: 2.0),
        decoration: const InputDecoration(
          labelText: 'label',
          hintText: 'hint',
        ),
      ),
    );

    // The hint's opacity animates from 0.0 to 1.0.
    // The animation's duration is 200ms.
    {
      await tester.pump(const Duration(milliseconds: 50));
      final double hintOpacity50ms = getOpacity(tester, 'hint');
      expect(hintOpacity50ms, inExclusiveRange(0.0, 1.0));
      await tester.pump(const Duration(milliseconds: 50));
      final double hintOpacity100ms = getOpacity(tester, 'hint');
      expect(hintOpacity100ms, inExclusiveRange(hintOpacity50ms, 1.0));
    }

    await tester.pumpAndSettle();
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 64.0));
    expect(tester.getTopLeft(find.text('text')).dy, 32.0);
    expect(tester.getBottomLeft(find.text('text')).dy, 48.0);
    expect(tester.getTopLeft(find.text('label')).dy, 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 24.0);
    expect(tester.getTopLeft(find.text('hint')).dy, 32.0);
    expect(tester.getBottomLeft(find.text('hint')).dy, 48.0);
    expect(getOpacity(tester, 'hint'), 1.0);
    expect(getBorderBottom(tester), 64.0);
    expect(getBorderWeight(tester), 2.0);

    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: false,
        isFocused: true,
        visualDensity: const VisualDensity(horizontal: 2.0, vertical: 2.0),
        decoration: const InputDecoration(
          labelText: 'label',
          hintText: 'hint',
        ),
      ),
    );

    // The hint's opacity animates from 1.0 to 0.0.
    // The animation's duration is 200ms.
    {
      await tester.pump(const Duration(milliseconds: 50));
      final double hintOpacity50ms = getOpacity(tester, 'hint');
      expect(hintOpacity50ms, inExclusiveRange(0.0, 1.0));
      await tester.pump(const Duration(milliseconds: 50));
      final double hintOpacity100ms = getOpacity(tester, 'hint');
      expect(hintOpacity100ms, inExclusiveRange(0.0, hintOpacity50ms));
    }

    await tester.pumpAndSettle();
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 64.0));
    expect(tester.getTopLeft(find.text('text')).dy, 32.0);
    expect(tester.getBottomLeft(find.text('text')).dy, 48.0);
    expect(tester.getTopLeft(find.text('label')).dy, 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 24.0);
    expect(tester.getTopLeft(find.text('hint')).dy, 32.0);
    expect(tester.getBottomLeft(find.text('hint')).dy, 48.0);
    expect(getOpacity(tester, 'hint'), 0.0);
    expect(getBorderBottom(tester), 64.0);
    expect(getBorderWeight(tester), 2.0);
  });

  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(
        decoration: const InputDecoration(
          prefixIcon: SizedBox(width: 100.0, height: 100.0, key: prefixKey),
          filled: true,
        ),
      ),
    );

    // Overall height for this InputDecorator is 100dps because the prefix icon's  size
    // is 100x100 and the rest of the elements only require 40dps:
     //   12 - top padding
     //   16 - input text (ahem font size 16dps)
     //   12 - bottom padding

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 100.0));
    expect(tester.getSize(find.byKey(prefixKey)).height, 100.0);
    expect(tester.getTopLeft(find.byKey(prefixKey)).dy, 0.0);
  });

  group('textAlignVertical position', () {
    group('simple case', () {
      testWidgets('align top (default)', (WidgetTester tester) async {
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            // isEmpty: false (default)
            // isFocused: false (default)
            expands: true, // so we have a tall input where align can vary
            decoration: const InputDecoration(
              filled: true,
            ),
            textAlignVertical: TextAlignVertical.top, // default when no border
            // Set the fontSize so that everything works out to whole numbers.
            child: const Text(
              text,
              style: TextStyle(fontFamily: 'Ahem', fontSize: 20.0),
            ),
          ),
        );

        // Same as the default case above.
        expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(12.0, epsilon: .0001));
      });

      testWidgets('align center', (WidgetTester tester) async {
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            // isEmpty: false (default)
            // isFocused: false (default)
            expands: true,
            decoration: const InputDecoration(
              filled: true,
            ),
            textAlignVertical: TextAlignVertical.center,
            // Set the fontSize so that everything works out to whole numbers.
            child: const Text(
              text,
              style: TextStyle(fontFamily: 'Ahem', fontSize: 20.0),
            ),
          ),
        );

        // Below the top aligned case.
        expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(290.0, epsilon: .0001));
      });

      testWidgets('align bottom', (WidgetTester tester) async {
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            // isEmpty: false (default)
            // isFocused: false (default)
            expands: true,
            decoration: const InputDecoration(
              filled: true,
            ),
            textAlignVertical: TextAlignVertical.bottom,
            // Set the fontSize so that everything works out to whole numbers.
            child: const Text(
              text,
              style: TextStyle(fontFamily: 'Ahem', fontSize: 20.0),
            ),
          ),
        );

        // Below the center aligned case.
        expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(568.0, epsilon: .0001));
      });

      testWidgets('align as a double', (WidgetTester tester) async {
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            // isEmpty: false (default)
            // isFocused: false (default)
            expands: true,
            decoration: const InputDecoration(
              filled: true,
            ),
            textAlignVertical: const TextAlignVertical(y: 0.75),
            // Set the fontSize so that everything works out to whole numbers.
            child: const Text(
              text,
              style: TextStyle(fontFamily: 'Ahem', fontSize: 20.0),
            ),
          ),
        );

        // In between the center and bottom aligned cases.
        expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(498.5, epsilon: .0001));
      });
    });

    group('outline border', () {
      testWidgets('align top', (WidgetTester tester) async {
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            // isEmpty: false (default)
            // isFocused: false (default)
            expands: true, // so we have a tall input where align can vary
            decoration: const InputDecoration(
              filled: true,
              border: OutlineInputBorder(),
            ),
            textAlignVertical: TextAlignVertical.top,
            // Set the fontSize so that everything works out to whole numbers.
            child: const Text(
              text,
              style: TextStyle(fontFamily: 'Ahem', fontSize: 20.0),
            ),
          ),
        );

        // Similar to the case without a border, but with a little extra room at
        // the top to make room for the border.
        expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(24.0, epsilon: .0001));
      });

      testWidgets('align center (default)', (WidgetTester tester) async {
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            // isEmpty: false (default)
            // isFocused: false (default)
            expands: true,
            decoration: const InputDecoration(
              filled: true,
              border: OutlineInputBorder(),
            ),
            textAlignVertical: TextAlignVertical.center, // default when border
            // Set the fontSize so that everything works out to whole numbers.
            child: const Text(
              text,
              style: TextStyle(fontFamily: 'Ahem', fontSize: 20.0),
            ),
          ),
        );

        // Below the top aligned case.
        expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(289.0, epsilon: .0001));
      });

      testWidgets('align bottom', (WidgetTester tester) async {
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            // isEmpty: false (default)
            // isFocused: false (default)
            expands: true,
            decoration: const InputDecoration(
              filled: true,
              border: OutlineInputBorder(),
            ),
            textAlignVertical: TextAlignVertical.bottom,
            // Set the fontSize so that everything works out to whole numbers.
            child: const Text(
              text,
              style: TextStyle(fontFamily: 'Ahem', fontSize: 20.0),
            ),
          ),
        );

        // Below the center aligned case.
        expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(564.0, epsilon: .0001));
      });
    });

    group('prefix', () {
      testWidgets('InputDecorator tall prefix align top', (WidgetTester tester) async {
        const Key pKey = Key('p');
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            // isEmpty: false (default)
            // isFocused: false (default)
            decoration: const InputDecoration(
              prefix: SizedBox(
                key: pKey,
                height: 100,
                width: 10,
              ),
              filled: true,
            ),
            textAlignVertical: TextAlignVertical.top, // default when no border
            // Set the fontSize so that everything works out to whole numbers.
            child: const Text(
              text,
              style: TextStyle(fontFamily: 'Ahem', fontSize: 20.0),
            ),
          ),
        );

        // Same as the default case above.
        expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(96, epsilon: .0001));
        expect(tester.getTopLeft(find.byKey(pKey)).dy, 12.0);
      });

      testWidgets('InputDecorator tall prefix align center', (WidgetTester tester) async {
        const Key pKey = Key('p');
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            // isEmpty: false (default)
            // isFocused: false (default)
            decoration: const InputDecoration(
              prefix: SizedBox(
                key: pKey,
                height: 100,
                width: 10,
              ),
              filled: true,
            ),
            textAlignVertical: TextAlignVertical.center,
            // Set the fontSize so that everything works out to whole numbers.
            child: const Text(
              text,
              style: TextStyle(fontFamily: 'Ahem', fontSize: 20.0),
            ),
          ),
        );

        // Same as the default case above.
        expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(96.0, epsilon: .0001));
        expect(tester.getTopLeft(find.byKey(pKey)).dy, 12.0);
      });

      testWidgets('InputDecorator tall prefix align bottom', (WidgetTester tester) async {
        const Key pKey = Key('p');
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            // isEmpty: false (default)
            // isFocused: false (default)
            decoration: const InputDecoration(
              prefix: SizedBox(
                key: pKey,
                height: 100,
                width: 10,
              ),
              filled: true,
            ),
            textAlignVertical: TextAlignVertical.bottom,
            // Set the fontSize so that everything works out to whole numbers.
            child: const Text(
              text,
              style: TextStyle(fontFamily: 'Ahem', fontSize: 20.0),
            ),
          ),
        );

        // Top of the input + 100 prefix height - overlap
        expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(96.0, epsilon: .0001));
        expect(tester.getTopLeft(find.byKey(pKey)).dy, 12.0);
      });
    });

    group('outline border and prefix', () {
      testWidgets('InputDecorator tall prefix align center', (WidgetTester tester) async {
        const Key pKey = Key('p');
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            // isEmpty: false (default)
            // isFocused: false (default)
            expands: true,
            decoration: const InputDecoration(
              border: OutlineInputBorder(),
              prefix: SizedBox(
                key: pKey,
                height: 100,
                width: 10,
              ),
              filled: true,
            ),
            textAlignVertical: TextAlignVertical.center, // default when border
            // Set the fontSize so that everything works out to whole numbers.
            child: const Text(
              text,
              style: TextStyle(fontFamily: 'Ahem', fontSize: 20.0),
            ),
          ),
        );

        // In the middle of the expanded InputDecorator.
        expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(331.0, epsilon: .0001));
        expect(tester.getTopLeft(find.byKey(pKey)).dy, moreOrLessEquals(247.0, epsilon: .0001));
      });

      testWidgets('InputDecorator tall prefix with border align top', (WidgetTester tester) async {
        const Key pKey = Key('p');
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            // isEmpty: false (default)
            // isFocused: false (default)
            expands: true,
            decoration: const InputDecoration(
              border: OutlineInputBorder(),
              prefix: SizedBox(
                key: pKey,
                height: 100,
                width: 10,
              ),
              filled: true,
            ),
            textAlignVertical: TextAlignVertical.top,
            // Set the fontSize so that everything works out to whole numbers.
            child: const Text(
              text,
              style: TextStyle(fontFamily: 'Ahem', fontSize: 20.0),
            ),
          ),
        );

        // Above the center example.
        expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(108.0, epsilon: .0001));
        // The prefix is positioned at the top of the input, so this value is
        // the same as the top aligned test without a prefix.
        expect(tester.getTopLeft(find.byKey(pKey)).dy, 24.0);
      });

      testWidgets('InputDecorator tall prefix with border align bottom', (WidgetTester tester) async {
        const Key pKey = Key('p');
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            // isEmpty: false (default)
            // isFocused: false (default)
            expands: true,
            decoration: const InputDecoration(
              border: OutlineInputBorder(),
              prefix: SizedBox(
                key: pKey,
                height: 100,
                width: 10,
              ),
              filled: true,
            ),
            textAlignVertical: TextAlignVertical.bottom,
            // Set the fontSize so that everything works out to whole numbers.
            child: const Text(
              text,
              style: TextStyle(fontFamily: 'Ahem', fontSize: 20.0),
            ),
          ),
        );

        // Below the center example.
        expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(564.0, epsilon: .0001));
        expect(tester.getTopLeft(find.byKey(pKey)).dy, moreOrLessEquals(480.0, epsilon: .0001));
      });

      testWidgets('InputDecorator tall prefix with border align double', (WidgetTester tester) async {
        const Key pKey = Key('p');
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            // isEmpty: false (default)
            // isFocused: false (default)
            expands: true,
            decoration: const InputDecoration(
              border: OutlineInputBorder(),
              prefix: SizedBox(
                key: pKey,
                height: 100,
                width: 10,
              ),
              filled: true,
            ),
            textAlignVertical: const TextAlignVertical(y: 0.1),
            // Set the fontSize so that everything works out to whole numbers.
            child: const Text(
              text,
              style: TextStyle(fontFamily: 'Ahem', fontSize: 20.0),
            ),
          ),
        );

        // Between the top and center examples.
        expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(354.3, epsilon: .0001));
        expect(tester.getTopLeft(find.byKey(pKey)).dy, moreOrLessEquals(270.3, epsilon: .0001));
      });
    });

    group('label', () {
      testWidgets('align top (default)', (WidgetTester tester) async {
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            // isEmpty: false (default)
            // isFocused: false (default)
            expands: true, // so we have a tall input where align can vary
            decoration: const InputDecoration(
              labelText: 'label',
              filled: true,
            ),
            textAlignVertical: TextAlignVertical.top, // default
            // Set the fontSize so that everything works out to whole numbers.
            child: const Text(
              text,
              style: TextStyle(fontFamily: 'Ahem', fontSize: 20.0),
            ),
          ),
        );

        // The label causes the text to start slightly lower than it would
        // otherwise.
        expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(28.0, epsilon: .0001));
      });

      testWidgets('align center', (WidgetTester tester) async {
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            // isEmpty: false (default)
            // isFocused: false (default)
            expands: true, // so we have a tall input where align can vary
            decoration: const InputDecoration(
              labelText: 'label',
              filled: true,
            ),
            textAlignVertical: TextAlignVertical.center,
            // Set the fontSize so that everything works out to whole numbers.
            child: const Text(
              text,
              style: TextStyle(fontFamily: 'Ahem', fontSize: 20.0),
            ),
          ),
        );

        // The label reduces the amount of space available for text, so the
        // center is slightly lower.
        expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(298.0, epsilon: .0001));
      });

      testWidgets('align bottom', (WidgetTester tester) async {
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            // isEmpty: false (default)
            // isFocused: false (default)
            expands: true, // so we have a tall input where align can vary
            decoration: const InputDecoration(
              labelText: 'label',
              filled: true,
            ),
            textAlignVertical: TextAlignVertical.bottom,
            // Set the fontSize so that everything works out to whole numbers.
            child: const Text(
              text,
              style: TextStyle(fontFamily: 'Ahem', fontSize: 20.0),
            ),
          ),
        );

        // The label reduces the amount of space available for text, but the
        // bottom line is still in the same place.
        expect(tester.getTopLeft(find.text(text)).dy, moreOrLessEquals(568.0, epsilon: .0001));
      });
    });
  });

  group('OutlineInputBorder', () {
    group('default alignment', () {
      testWidgets('Centers when border', (WidgetTester tester) async {
        await tester.pumpWidget(
          buildInputDecorator(
            decoration: const InputDecoration(
              border: OutlineInputBorder(),
            ),
          ),
        );

        expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
        expect(tester.getTopLeft(find.text('text')).dy, 19.0);
        expect(tester.getBottomLeft(find.text('text')).dy, 35.0);
        expect(getBorderBottom(tester), 56.0);
        expect(getBorderWeight(tester), 1.0);
      });

      testWidgets('Centers when border and label', (WidgetTester tester) async {
        await tester.pumpWidget(
          buildInputDecorator(
            decoration: const InputDecoration(
              labelText: 'label',
              border: OutlineInputBorder(),
            ),
          ),
        );

        expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
        expect(tester.getTopLeft(find.text('text')).dy, 19.0);
        expect(tester.getBottomLeft(find.text('text')).dy, 35.0);
        expect(getBorderBottom(tester), 56.0);
        expect(getBorderWeight(tester), 1.0);
      });

      testWidgets('Centers when border and contentPadding', (WidgetTester tester) async {
        await tester.pumpWidget(
          buildInputDecorator(
            decoration: const InputDecoration(
              border: OutlineInputBorder(),
              contentPadding: EdgeInsets.fromLTRB(
                12.0, 14.0,
                8.0, 14.0,
              ),
            ),
          ),
        );

        expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0));
        expect(tester.getTopLeft(find.text('text')).dy, 15.0);
        expect(tester.getBottomLeft(find.text('text')).dy, 31.0);
        expect(getBorderBottom(tester), 48.0);
        expect(getBorderWeight(tester), 1.0);
      });

      testWidgets('Centers when border and contentPadding and label', (WidgetTester tester) async {
        await tester.pumpWidget(
          buildInputDecorator(
            decoration: const InputDecoration(
              labelText: 'label',
              border: OutlineInputBorder(),
              contentPadding: EdgeInsets.fromLTRB(
                12.0, 14.0,
                8.0, 14.0,
              ),
            ),
          ),
        );
        expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, kMinInteractiveDimension));
        expect(tester.getTopLeft(find.text('text')).dy, 15.0);
        expect(tester.getBottomLeft(find.text('text')).dy, 31.0);
        expect(getBorderBottom(tester), 48.0);
        expect(getBorderWeight(tester), 1.0);
      });

      testWidgets('Centers when border and lopsided contentPadding and label', (WidgetTester tester) async {
        await tester.pumpWidget(
          buildInputDecorator(
            decoration: const InputDecoration(
              labelText: 'label',
              border: OutlineInputBorder(),
              contentPadding: EdgeInsets.fromLTRB(
                12.0, 104.0,
                8.0, 0.0,
              ),
            ),
          ),
        );

        expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 120.0));
        expect(tester.getTopLeft(find.text('text')).dy, 51.0);
        expect(tester.getBottomLeft(find.text('text')).dy, 67.0);
        expect(getBorderBottom(tester), 120.0);
        expect(getBorderWeight(tester), 1.0);
      });
    });

    group('3 point interpolation alignment', () {
      testWidgets('top align includes padding', (WidgetTester tester) async {
        await tester.pumpWidget(
          buildInputDecorator(
            expands: true,
            textAlignVertical: TextAlignVertical.top,
            decoration: const InputDecoration(
              border: OutlineInputBorder(),
              contentPadding: EdgeInsets.fromLTRB(
                12.0, 24.0,
                8.0, 2.0,
              ),
            ),
          ),
        );

        expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 600.0));
        // Aligned to the top including the 24px padding.
        expect(tester.getTopLeft(find.text('text')).dy, 24.0);
        expect(tester.getBottomLeft(find.text('text')).dy, 40.0);
        expect(getBorderBottom(tester), 600.0);
        expect(getBorderWeight(tester), 1.0);
      });

      testWidgets('center align ignores padding', (WidgetTester tester) async {
        await tester.pumpWidget(
          buildInputDecorator(
            expands: true,
            textAlignVertical: TextAlignVertical.center,
            decoration: const InputDecoration(
              border: OutlineInputBorder(),
              contentPadding: EdgeInsets.fromLTRB(
                12.0, 24.0,
                8.0, 2.0,
              ),
            ),
          ),
        );

        expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 600.0));
        // Baseline is on the center of the 600px high input.
        expect(tester.getTopLeft(find.text('text')).dy, 291.0);
        expect(tester.getBottomLeft(find.text('text')).dy, 307.0);
        expect(getBorderBottom(tester), 600.0);
        expect(getBorderWeight(tester), 1.0);
      });

      testWidgets('bottom align includes padding', (WidgetTester tester) async {
        await tester.pumpWidget(
          buildInputDecorator(
            expands: true,
            textAlignVertical: TextAlignVertical.bottom,
            decoration: const InputDecoration(
              border: OutlineInputBorder(),
              contentPadding: EdgeInsets.fromLTRB(
                12.0, 24.0,
                8.0, 2.0,
              ),
            ),
          ),
        );

        expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 600.0));
        // Includes bottom padding of 2px.
        expect(tester.getTopLeft(find.text('text')).dy, 582.0);
        expect(tester.getBottomLeft(find.text('text')).dy, 598.0);
        expect(getBorderBottom(tester), 600.0);
        expect(getBorderWeight(tester), 1.0);
      });

      testWidgets('padding exceeds middle keeps top at middle', (WidgetTester tester) async {
        await tester.pumpWidget(
          buildInputDecorator(
            expands: true,
            textAlignVertical: TextAlignVertical.top,
            decoration: const InputDecoration(
              border: OutlineInputBorder(),
              contentPadding: EdgeInsets.fromLTRB(
                12.0, 504.0,
                8.0, 0.0,
              ),
            ),
          ),
        );

        expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 600.0));
        // Same position as the center example above.
        expect(tester.getTopLeft(find.text('text')).dy, 291.0);
        expect(tester.getBottomLeft(find.text('text')).dy, 307.0);
        expect(getBorderBottom(tester), 600.0);
        expect(getBorderWeight(tester), 1.0);
      });
    });
  });

  testWidgets('counter text has correct right margin - LTR, not dense', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: const InputDecoration(
          counterText: 'test',
          filled: true,
        ),
      ),
    );

    // Margin for text decoration is 12 when filled
    // (dx) - 12 = (text offset)x.
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 68.0));
    final double dx = tester.getRect(find.byType(InputDecorator)).right;
    expect(tester.getRect(find.text('test')).right, dx - 12.0);
  });

  testWidgets('counter text has correct right margin - RTL, not dense', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        textDirection: TextDirection.rtl,
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: const InputDecoration(
          counterText: 'test',
          filled: true,
        ),
      ),
    );

    // Margin for text decoration is 12 when filled and top left offset is (0, 0)
    // 0 + 12 = 12.
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 68.0));
    expect(tester.getRect(find.text('test')).left, 12.0);
  });

  testWidgets('counter text has correct right margin - LTR, dense', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: const InputDecoration(
          counterText: 'test',
          filled: true,
          isDense: true,
        ),
      ),
    );

    // Margin for text decoration is 12 when filled
    // (dx) - 12 = (text offset)x.
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 52.0));
    final double dx = tester.getRect(find.byType(InputDecorator)).right;
    expect(tester.getRect(find.text('test')).right, dx - 12.0);
  });

  testWidgets('counter text has correct right margin - RTL, dense', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        textDirection: TextDirection.rtl,
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: const InputDecoration(
          counterText: 'test',
          filled: true,
          isDense: true,
        ),
      ),
    );

    // Margin for text decoration is 12 when filled and top left offset is (0, 0)
    // 0 + 12 = 12.
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 52.0));
    expect(tester.getRect(find.text('test')).left, 12.0);
  });

  testWidgets('InputDecorator error/helper/counter RTL layout', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        // isFocused: false (default)
        textDirection: TextDirection.rtl,
        decoration: const InputDecoration(
          labelText: 'label',
          helperText: 'helper',
          counterText: 'counter',
          filled: true,
        ),
      ),
    );

    // Overall height for this InputDecorator is 76dps:
    //   12 - top padding
    //   12 - floating label (ahem font size 16dps * 0.75 = 12)
    //    4 - floating label / input text gap
    //   16 - input text (ahem font size 16dps)
    //   12 - bottom padding
    //    8 - below the border padding
    //   12 - [counter helper/error] (ahem font size 12dps)

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 76.0));
    expect(tester.getTopLeft(find.text('text')).dy, 28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, 44.0);
    expect(tester.getTopLeft(find.text('label')).dy, 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 24.0);
    expect(getBorderBottom(tester), 56.0);
    expect(getBorderWeight(tester), 1.0);
    expect(tester.getTopLeft(find.text('counter')), const Offset(12.0, 64.0));
    expect(tester.getTopRight(find.text('helper')), const Offset(788.0, 64.0));

    // If both error and helper are specified, show the error
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        // isFocused: false (default)
        textDirection: TextDirection.rtl,
        decoration: const InputDecoration(
          labelText: 'label',
          helperText: 'helper',
          errorText: 'error',
          counterText: 'counter',
          filled: true,
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(tester.getTopLeft(find.text('counter')), const Offset(12.0, 64.0));
    expect(tester.getTopRight(find.text('error')), const Offset(788.0, 64.0));
    expect(find.text('helper'), findsNothing);
  });

  testWidgets('InputDecorator prefix/suffix RTL', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        // isFocused: false (default)
        textDirection: TextDirection.rtl,
        decoration: const InputDecoration(
          prefixText: 'p',
          suffixText: 's',
          filled: true,
        ),
      ),
    );

    // Overall height for this InputDecorator is 40dps:
    //   12 - top padding
    //   16 - input text (ahem font size 16dps)
    //   12 - bottom padding

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, kMinInteractiveDimension)); // 40 bumped up to minimum.
    expect(tester.getSize(find.text('text')).height, 16.0);
    expect(tester.getSize(find.text('p')).height, 16.0);
    expect(tester.getSize(find.text('s')).height, 16.0);
    expect(tester.getTopLeft(find.text('text')).dy, 16.0);
    expect(tester.getTopLeft(find.text('p')).dy, 16.0);
    expect(tester.getTopLeft(find.text('s')).dy, 16.0);

    // layout is a row: [s text p]
    expect(tester.getTopLeft(find.text('s')).dx, 12.0);
    expect(tester.getTopRight(find.text('s')).dx, lessThanOrEqualTo(tester.getTopLeft(find.text('text')).dx));
    expect(tester.getTopRight(find.text('text')).dx, lessThanOrEqualTo(tester.getTopLeft(find.text('p')).dx));
  });

  testWidgets('InputDecorator contentPadding RTL layout', (WidgetTester tester) async {
    // LTR: content left edge is contentPadding.start: 40.0
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        // isFocused: false (default)
        textDirection: TextDirection.ltr,
        decoration: const InputDecoration(
          contentPadding: EdgeInsetsDirectional.only(start: 40.0, top: 12.0, bottom: 12.0),
          labelText: 'label',
          hintText: 'hint',
          filled: true,
        ),
      ),
    );
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
    expect(tester.getTopLeft(find.text('text')).dx, 40.0);
    expect(tester.getTopLeft(find.text('label')).dx, 40.0);
    expect(tester.getTopLeft(find.text('hint')).dx, 40.0);

    // RTL: content right edge is 800 - contentPadding.start: 760.0.
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        isFocused: true, // label is floating, still adjusted for contentPadding
        textDirection: TextDirection.rtl,
        decoration: const InputDecoration(
          contentPadding: EdgeInsetsDirectional.only(start: 40.0, top: 12.0, bottom: 12.0),
          labelText: 'label',
          hintText: 'hint',
          filled: true,
        ),
      ),
    );
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
    expect(tester.getTopRight(find.text('text')).dx, 760.0);
    expect(tester.getTopRight(find.text('label')).dx, 760.0);
    expect(tester.getTopRight(find.text('hint')).dx, 760.0);
  });

  testWidgets('InputDecorator prefix/suffix dense layout', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        isFocused: true,
        decoration: const InputDecoration(
          isDense: true,
          prefixText: 'p',
          suffixText: 's',
          filled: true,
        ),
      ),
    );

    // Overall height for this InputDecorator is 32dps:
    //    8 - top padding
    //   16 - input text (ahem font size 16dps)
    //    8 - bottom padding
    //
    // The only difference from normal layout for this case is that the
    // padding above and below the prefix, input text, suffix, is 8 instead of 12.

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 32.0));
    expect(tester.getSize(find.text('text')).height, 16.0);
    expect(tester.getSize(find.text('p')).height, 16.0);
    expect(tester.getSize(find.text('s')).height, 16.0);
    expect(tester.getTopLeft(find.text('text')).dy, 8.0);
    expect(tester.getTopLeft(find.text('p')).dy, 8.0);
    expect(tester.getTopLeft(find.text('p')).dx, 12.0);
    expect(tester.getTopLeft(find.text('s')).dy, 8.0);
    expect(tester.getTopRight(find.text('s')).dx, 788.0);

    // layout is a row: [p text s]
    expect(tester.getTopLeft(find.text('p')).dx, 12.0);
    expect(tester.getTopRight(find.text('p')).dx, lessThanOrEqualTo(tester.getTopLeft(find.text('text')).dx));
    expect(tester.getTopRight(find.text('text')).dx, lessThanOrEqualTo(tester.getTopLeft(find.text('s')).dx));

    expect(getBorderBottom(tester), 32.0);
    expect(getBorderWeight(tester), 2.0);
  });

  testWidgets('InputDecorator with empty InputDecoration', (WidgetTester tester) async {
    await tester.pumpWidget(buildInputDecorator());

    // Overall height for this InputDecorator is 40dps:
    //   12 - top padding
    //   16 - input text (ahem font size 16dps)
    //   12 - bottom padding

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, kMinInteractiveDimension)); // 40 bumped up to minimum.
    expect(tester.getSize(find.text('text')).height, 16.0);
    expect(tester.getTopLeft(find.text('text')).dy, 16.0);
    expect(getBorderBottom(tester), kMinInteractiveDimension); // 40 bumped up to minimum.
    expect(getBorderWeight(tester), 1.0);
  });

  testWidgets('contentPadding smaller than kMinInteractiveDimension', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/42449
    const double verticalPadding = 1.0;
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default),
        // isFocused: false (default)
        decoration: const InputDecoration(
          hintText: 'hint',
          contentPadding: EdgeInsets.symmetric(vertical: verticalPadding),
          isDense: true,
        ),
      ),
    );

    // The overall height is 18dps. This is shorter than
    // kMinInteractiveDimension, but because isDense is true, the minimum is
    // ignored.
    //   16 - input text (ahem font size 16dps)
    //    2 - total vertical padding

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 18.0));
    expect(tester.getSize(find.text('text')).height, 16.0);
    expect(tester.getTopLeft(find.text('text')).dy, 1.0);
    expect(getOpacity(tester, 'hint'), 0.0);
    expect(getBorderWeight(tester), 1.0);

    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default),
        // isFocused: false (default)
        decoration: const InputDecoration.collapsed(
          hintText: 'hint',
          // InputDecoration.collapsed does not support contentPadding
        ),
      ),
    );

    // The overall height is 16dps. This is shorter than
    // kMinInteractiveDimension, but because isCollapsed is true, the minimum is
    // ignored. There is no padding at all, because isCollapsed doesn't support
    // contentPadding.
    //   16 - input text (ahem font size 16dps)

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 16.0));
    expect(tester.getSize(find.text('text')).height, 16.0);
    expect(tester.getTopLeft(find.text('text')).dy, 0.0);
    expect(getOpacity(tester, 'hint'), 0.0);
    expect(getBorderWeight(tester), 1.0);

    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default),
        // isFocused: false (default)
        decoration: const InputDecoration(
          hintText: 'hint',
          contentPadding: EdgeInsets.symmetric(vertical: verticalPadding),
        ),
      ),
    );

    // The requested overall height is 18dps, however the minimum height is
    // kMinInteractiveDimension because neither isDense or isCollapsed are true.
    //   16 - input text (ahem font size 16dps)
    //    2 - total vertical padding

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, kMinInteractiveDimension));
    expect(tester.getSize(find.text('text')).height, 16.0);
    expect(tester.getTopLeft(find.text('text')).dy, 16.0);
    expect(getOpacity(tester, 'hint'), 0.0);
    expect(getBorderWeight(tester), 0.0);
  });

  testWidgets('InputDecorator.collapsed', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default),
        // isFocused: false (default)
        decoration: const InputDecoration.collapsed(
          hintText: 'hint',
        ),
      ),
    );

    // Overall height for this InputDecorator is 16dps. There is no minimum
    // height when InputDecoration.collapsed is used.
    //   16 - input text (ahem font size 16dps)

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 16.0));
    expect(tester.getSize(find.text('text')).height, 16.0);
    expect(tester.getTopLeft(find.text('text')).dy, 0.0);
    expect(getOpacity(tester, 'hint'), 0.0);
    expect(getBorderWeight(tester), 0.0);

    // The hint should appear
    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        isFocused: true,
        decoration: const InputDecoration.collapsed(
          hintText: 'hint',
        ),
      ),
    );
    await tester.pumpAndSettle();

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 16.0));
    expect(tester.getSize(find.text('text')).height, 16.0);
    expect(tester.getTopLeft(find.text('text')).dy, 0.0);
    expect(tester.getSize(find.text('hint')).height, 16.0);
    expect(tester.getTopLeft(find.text('hint')).dy, 0.0);
    expect(getBorderWeight(tester), 0.0);
  });

  testWidgets('InputDecorator with baseStyle', (WidgetTester tester) async {
    // Setting the baseStyle of the InputDecoration and the style of the input
    // text child to a smaller font reduces the InputDecoration's vertical size.
    const TextStyle style = TextStyle(fontFamily: 'Ahem', fontSize: 10.0);
    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true,
        isFocused: false,
        baseStyle: style,
        decoration: const InputDecoration(
          hintText: 'hint',
          labelText: 'label',
        ),
        child: const Text('text', style: style),
      ),
    );

    // Overall height for this InputDecorator is 45.5dps. When the label is
    // floating the layout is:
    //
    //    12  - top padding
    //    7.5 - floating label (ahem font size 10dps * 0.75 = 7.5)
    //    4   - floating label / input text gap
    //   10   - input text (ahem font size 10dps)
    //   12   - bottom padding
    //
    // When the label is not floating, it's vertically centered.
    //
    //   17.75 - top padding
    //      10 - label (ahem font size 10dps)
    //   17.75 - bottom padding (empty input text still appears here)

    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, 10.0);
    expect(tester.getSize(find.text('text')).height, 10.0);
    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(
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: const InputDecoration(
          labelText: 'label',
          hintText: 'hint',
          helperText: 'helper',
          counterText: 'counter',
          labelStyle: TextStyle(),
          hintStyle: TextStyle(),
          errorStyle: TextStyle(),
          helperStyle: TextStyle(),
          filled: true,
        ),
      ),
    );

    // Overall height for this InputDecorator is 76dps. When the label is
    // floating the layout is:
    //   12 - top padding
    //   12 - floating label (ahem font size 16dps * 0.75 = 12)
    //    4 - floating label / input text gap
    //   16 - input text (ahem font size 16dps)
    //   12 - bottom padding
    //    8 - below the border padding
    //   12 - help/error/counter text (ahem font size 12dps)

    // Label is floating because isEmpty is false.
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 76.0));
    expect(tester.getTopLeft(find.text('text')).dy, 28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, 44.0);
    expect(tester.getTopLeft(find.text('label')).dy, 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 24.0);
    expect(getBorderBottom(tester), 56.0);
    expect(getBorderWeight(tester), 1.0);
    expect(tester.getTopLeft(find.text('helper')), const Offset(12.0, 64.0));
    expect(tester.getTopRight(find.text('counter')), const Offset(788.0, 64.0));
  });

  testWidgets('InputDecoration outline shape with no border and no floating placeholder', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        // isFocused: false (default)
        isEmpty: true,
        decoration: const InputDecoration(
          border: OutlineInputBorder(borderSide: BorderSide.none),
          hasFloatingPlaceholder: false,
          labelText: 'label',
        ),
      ),
    );

    // Overall height for this InputDecorator is 56dps. Layout is:
    //   20 - top padding
    //   16 - label (ahem font size 16dps)
    //   20 - bottom padding
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
    expect(tester.getTopLeft(find.text('label')).dy, 20.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 36.0);
    expect(getBorderBottom(tester), 56.0);
    expect(getBorderWeight(tester), 0.0);
  });

  testWidgets('InputDecoration outline shape with no border and no floating placeholder not empty', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: const InputDecoration(
          border: OutlineInputBorder(borderSide: BorderSide.none),
          hasFloatingPlaceholder: false,
          labelText: 'label',
        ),
      ),
    );

    // Overall height for this InputDecorator is 56dps. Layout is:
    //   20 - top padding
    //   16 - label (ahem font size 16dps)
    //   20 - bottom padding
    //    expect(tester.widget<Text>(find.text('prefix')).style.color, prefixStyle.color);
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
    expect(tester.getTopLeft(find.text('label')).dy, 20.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 36.0);
    expect(getBorderBottom(tester), 56.0);
    expect(getBorderWeight(tester), 0.0);

    // The label should not be seen.
    expect(getOpacity(tester, 'label'), 0.0);
  });

  test('InputDecorationTheme copyWith, ==, hashCode basics', () {
    expect(const InputDecorationTheme(), const InputDecorationTheme().copyWith());
    expect(const InputDecorationTheme().hashCode, const InputDecorationTheme().copyWith().hashCode);
  });

  test('InputDecorationTheme copyWith correctly copies and replaces values', () {
    const InputDecorationTheme original = InputDecorationTheme(
      focusColor: Colors.orange,
      fillColor: Colors.green,
    );
    final InputDecorationTheme copy = original.copyWith(
      focusColor: Colors.yellow,
      fillColor: Colors.blue,
    );

    expect(original.focusColor, Colors.orange);
    expect(original.fillColor, Colors.green);
    expect(copy.focusColor, Colors.yellow);
    expect(copy.fillColor, Colors.blue);
  });

  testWidgets('InputDecorationTheme outline border', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true, // label appears, vertically centered
        // isFocused: false (default)
        inputDecorationTheme: const InputDecorationTheme(
          border: OutlineInputBorder(),
        ),
        decoration: const InputDecoration(
          labelText: 'label',
        ),
      ),
    );

    // Overall height for this InputDecorator is 56dps. Layout is:
    //   20 - top padding
    //   16 - label (ahem font size 16dps)
    //   20 - bottom padding
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
    expect(tester.getTopLeft(find.text('label')).dy, 20.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 36.0);
    expect(getBorderBottom(tester), 56.0);
    expect(getBorderWeight(tester), 1.0);
  });

  testWidgets('InputDecorationTheme outline border, dense layout', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true, // label appears, vertically centered
        // isFocused: false (default)
        inputDecorationTheme: const InputDecorationTheme(
          border: OutlineInputBorder(),
          isDense: true,
        ),
        decoration: const InputDecoration(
          labelText: 'label',
          hintText: 'hint',
        ),
      ),
    );

    // Overall height for this InputDecorator is 56dps. Layout is:
    //   16 - top padding
    //   16 - label (ahem font size 16dps)
    //   16 - bottom padding
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 48.0));
    expect(tester.getTopLeft(find.text('label')).dy, 16.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 32.0);
    expect(getBorderBottom(tester), 48.0);
    expect(getBorderWeight(tester), 1.0);
  });

  testWidgets('InputDecorationTheme style overrides', (WidgetTester tester) async {
    const TextStyle style16 = TextStyle(fontFamily: 'Ahem', fontSize: 16.0);
    final TextStyle labelStyle = style16.merge(const TextStyle(color: Colors.red));
    final TextStyle hintStyle = style16.merge(const TextStyle(color: Colors.green));
    final TextStyle prefixStyle = style16.merge(const TextStyle(color: Colors.blue));
    final TextStyle suffixStyle = style16.merge(const TextStyle(color: Colors.purple));

    const TextStyle style12 = TextStyle(fontFamily: 'Ahem', fontSize: 12.0);
    final TextStyle helperStyle = style12.merge(const TextStyle(color: Colors.orange));
    final TextStyle counterStyle = style12.merge(const TextStyle(color: Colors.orange));

    // This test also verifies that the default InputDecorator provides a
    // "small concession to backwards compatibility" by not padding on
    // the left and right. If filled is true or an outline border is
    // provided then the horizontal padding is included.

    await tester.pumpWidget(
      buildInputDecorator(
        isEmpty: true, // label appears, vertically centered
        // isFocused: false (default)
        inputDecorationTheme: InputDecorationTheme(
          labelStyle: labelStyle,
          hintStyle: hintStyle,
          prefixStyle: prefixStyle,
          suffixStyle: suffixStyle,
          helperStyle: helperStyle,
          counterStyle: counterStyle,
          // filled: false (default) - don't pad by left/right 12dps
        ),
        decoration: const InputDecoration(
          labelText: 'label',
          hintText: 'hint',
          prefixText: 'prefix',
          suffixText: 'suffix',
          helperText: 'helper',
          counterText: 'counter',
        ),
      ),
    );

    // Overall height for this InputDecorator is 76dps. Layout is:
    //   12 - top padding
    //   12 - floating label (ahem font size 16dps * 0.75 = 12)
    //    4 - floating label / input text gap
    //   16 - prefix/hint/input/suffix text (ahem font size 16dps)
    //   12 - bottom padding
    //    8 - below the border padding
    //   12 - help/error/counter text (ahem font size 12dps)
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 76.0));
    expect(tester.getTopLeft(find.text('label')).dy, 20.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 36.0);
    expect(getBorderBottom(tester), 56.0);
    expect(getBorderWeight(tester), 1.0);
    expect(tester.getTopLeft(find.text('helper')), const Offset(0.0, 64.0));
    expect(tester.getTopRight(find.text('counter')), const Offset(800.0, 64.0));

    // Verify that the styles were passed along
    expect(tester.widget<Text>(find.text('prefix')).style!.color, prefixStyle.color);
    expect(tester.widget<Text>(find.text('suffix')).style!.color, suffixStyle.color);
    expect(tester.widget<Text>(find.text('helper')).style!.color, helperStyle.color);
    expect(tester.widget<Text>(find.text('counter')).style!.color, counterStyle.color);

    TextStyle getLabelStyle() {
      return tester.firstWidget<AnimatedDefaultTextStyle>(
        find.ancestor(
          of: find.text('label'),
          matching: find.byType(AnimatedDefaultTextStyle),
        ),
      ).style;
    }
    expect(getLabelStyle().color, labelStyle.color);
  });

  testWidgets('InputDecorator.toString()', (WidgetTester tester) async {
    const Widget child = InputDecorator(
      key: Key('key'),
      decoration: InputDecoration(),
      baseStyle: TextStyle(),
      textAlign: TextAlign.center,
      isFocused: false,
      isEmpty: false,
      child: Placeholder(),
    );
    expect(
      child.toString(),
      "InputDecorator-[<'key'>](decoration: InputDecoration(), baseStyle: TextStyle(<all styles inherited>), isFocused: false, isEmpty: false)",
    );
  });

  testWidgets('InputDecorator.debugDescribeChildren', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        decoration: const InputDecoration(
          icon: Text('icon'),
          labelText: 'label',
          hintText: 'hint',
          prefixText: 'prefix',
          suffixText: 'suffix',
          prefixIcon: Text('prefixIcon'),
          suffixIcon: Text('suffixIcon'),
          helperText: 'helper',
          counterText: 'counter',
        ),
        child: const Text('text'),
      ),
    );

    final RenderObject renderer = tester.renderObject(find.byType(InputDecorator));
    final Iterable<String> nodeNames = renderer.debugDescribeChildren()
      .map((DiagnosticsNode node) => node.name!);
    expect(nodeNames, unorderedEquals(<String>[
      'container',
      'counter',
      'helperError',
      'hint',
      'icon',
      'input',
      'label',
      'prefix',
      'prefixIcon',
      'suffix',
      'suffixIcon',
    ]));

    final Set<Object> nodeValues = Set<Object>.from(
      renderer.debugDescribeChildren().map<Object>((DiagnosticsNode node) => node.value!)
    );
    expect(nodeValues.length, 11);
  });

  testWidgets('InputDecorator with empty border and label', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/14165
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: const InputDecoration(
          labelText: 'label',
          border: InputBorder.none,
        ),
      ),
    );

    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
    expect(getBorderWeight(tester), 0.0);
    expect(tester.getTopLeft(find.text('label')).dy, 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, 24.0);
  });

  testWidgets('InputDecorationTheme.inputDecoration', (WidgetTester tester) async {
    const TextStyle themeStyle = TextStyle(color: Colors.green);
    const TextStyle decorationStyle = TextStyle(color: Colors.blue);

    // InputDecorationTheme arguments define InputDecoration properties.
    InputDecoration decoration = const InputDecoration().applyDefaults(
      const InputDecorationTheme(
        labelStyle: themeStyle,
        helperStyle: themeStyle,
        hintStyle: themeStyle,
        errorStyle: themeStyle,
        isDense: true,
        contentPadding: EdgeInsets.all(1.0),
        prefixStyle: themeStyle,
        suffixStyle: themeStyle,
        counterStyle: themeStyle,
        filled: true,
        fillColor: Colors.red,
        focusColor: Colors.blue,
        border: InputBorder.none,
        alignLabelWithHint: true,
      ),
    );

    expect(decoration.labelStyle, themeStyle);
    expect(decoration.helperStyle, themeStyle);
    expect(decoration.hintStyle, themeStyle);
    expect(decoration.errorStyle, themeStyle);
    expect(decoration.isDense, true);
    expect(decoration.contentPadding, const EdgeInsets.all(1.0));
    expect(decoration.prefixStyle, themeStyle);
    expect(decoration.suffixStyle, themeStyle);
    expect(decoration.counterStyle, themeStyle);
    expect(decoration.filled, true);
    expect(decoration.fillColor, Colors.red);
    expect(decoration.border, InputBorder.none);
    expect(decoration.alignLabelWithHint, true);

    // InputDecoration (baseDecoration) defines InputDecoration properties
    decoration = const InputDecoration(
      labelStyle: decorationStyle,
      helperStyle: decorationStyle,
      hintStyle: decorationStyle,
      errorStyle: decorationStyle,
      isDense: false,
      contentPadding: EdgeInsets.all(4.0),
      prefixStyle: decorationStyle,
      suffixStyle: decorationStyle,
      counterStyle: decorationStyle,
      filled: false,
      fillColor: Colors.blue,
      border: OutlineInputBorder(),
      alignLabelWithHint: false,
    ).applyDefaults(
      const InputDecorationTheme(
        labelStyle: themeStyle,
        helperStyle: themeStyle,
        helperMaxLines: 5,
        hintStyle: themeStyle,
        errorStyle: themeStyle,
        errorMaxLines: 4,
        isDense: true,
        contentPadding: EdgeInsets.all(1.0),
        prefixStyle: themeStyle,
        suffixStyle: themeStyle,
        counterStyle: themeStyle,
        filled: true,
        fillColor: Colors.red,
        focusColor: Colors.blue,
        border: InputBorder.none,
        alignLabelWithHint: true,
      ),
    );

    expect(decoration.labelStyle, decorationStyle);
    expect(decoration.helperStyle, decorationStyle);
    expect(decoration.helperMaxLines, 5);
    expect(decoration.hintStyle, decorationStyle);
    expect(decoration.errorStyle, decorationStyle);
    expect(decoration.errorMaxLines, 4);
    expect(decoration.isDense, false);
    expect(decoration.contentPadding, const EdgeInsets.all(4.0));
    expect(decoration.prefixStyle, decorationStyle);
    expect(decoration.suffixStyle, decorationStyle);
    expect(decoration.counterStyle, decorationStyle);
    expect(decoration.filled, false);
    expect(decoration.fillColor, Colors.blue);
    expect(decoration.border, const OutlineInputBorder());
    expect(decoration.alignLabelWithHint, false);
  });

  testWidgets('InputDecorator OutlineInputBorder fillColor is clipped by border', (WidgetTester tester) async {
    // This is a regression test for https://github.com/flutter/flutter/issues/15742

    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: InputDecoration(
          filled: true,
          fillColor: const Color(0xFF00FF00),
          border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(12.0),
          ),
        ),
      ),
    );

    final RenderBox box = tester.renderObject(find.byType(InputDecorator));

    // Fill is the border's outer path, a rounded rectangle
    expect(box, paints..path(
      style: PaintingStyle.fill,
      color: const Color(0xFF00FF00),
      includes: <Offset>[const Offset(800.0/2.0, 56/2.0)],
      excludes: <Offset>[
        const Offset(1.0, 6.0), // outside the rounded corner, top left
        const Offset(800.0 - 1.0, 6.0), // top right
        const Offset(1.0, 56.0 - 6.0), // bottom left
        const Offset(800 - 1.0, 56.0 - 6.0), // bottom right
      ],
    ));

    // Border outline. The rrect is the -center- of the 1.0 stroked outline.
    expect(box, paints..rrect(
      style: PaintingStyle.stroke,
      strokeWidth: 1.0,
      rrect: RRect.fromLTRBR(0.5, 0.5, 799.5, 55.5, const Radius.circular(11.5)),
    ));
  });

  testWidgets('InputDecorator UnderlineInputBorder fillColor is clipped by border', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: const InputDecoration(
          filled: true,
          fillColor: Color(0xFF00FF00),
          border: UnderlineInputBorder(
            borderRadius: BorderRadius.only(
              bottomLeft: Radius.circular(12.0),
              bottomRight: Radius.circular(12.0),
            ),
          ),
        ),
      ),
    );

    final RenderBox box = tester.renderObject(find.byType(InputDecorator));

    // Fill is the border's outer path, a rounded rectangle
    expect(box, paints..path(
      style: PaintingStyle.fill,
      color: const Color(0xFF00FF00),
      includes: <Offset>[const Offset(800.0/2.0, 56/2.0)],
      excludes: <Offset>[
        const Offset(1.0, 56.0 - 6.0), // bottom left
        const Offset(800 - 1.0, 56.0 - 6.0), // bottom right
      ],
    ));
  });

  testWidgets('InputDecorator constrained to 0x0', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/17710
    await tester.pumpWidget(
      Material(
        child: Directionality(
          textDirection: TextDirection.ltr,
          child: UnconstrainedBox(child: ConstrainedBox(
            constraints: BoxConstraints.tight(Size.zero),
            child: const InputDecorator(
              decoration: InputDecoration(
                labelText: 'XP',
                border: OutlineInputBorder(),
              ),
            ),
          )),
        ),
      ),
    );
  });

  testWidgets(
    'InputDecorator OutlineBorder focused label with icon',
    (WidgetTester tester) async {
      // Regression test for https://github.com/flutter/flutter/issues/18111

      Widget buildFrame(TextDirection textDirection) {
        return MaterialApp(
          home: Scaffold(
            body: Container(
              padding: const EdgeInsets.all(16.0),
              alignment: Alignment.center,
              child: Directionality(
                textDirection: textDirection,
                child: const RepaintBoundary(
                  child: InputDecorator(
                    isFocused: true,
                    isEmpty: true,
                    decoration: InputDecoration(
                      icon: Icon(Icons.insert_link),
                      labelText: 'primaryLink',
                      hintText: 'Primary link to story',
                      border: OutlineInputBorder(),
                    ),
                  ),
                ),
              ),
            ),
          ),
        );
      }

      await tester.pumpWidget(buildFrame(TextDirection.ltr));
      await expectLater(
        find.byType(InputDecorator),
        matchesGoldenFile('input_decorator.outline_icon_label.ltr.png'),
      );

      await tester.pumpWidget(buildFrame(TextDirection.rtl));
      await expectLater(
        find.byType(InputDecorator),
        matchesGoldenFile('input_decorator.outline_icon_label.rtl.png'),
      );
    },
  );

  testWidgets('InputDecorator draws and animates hoverColor', (WidgetTester tester) async {
    const Color fillColor = Color(0x0A000000);
    const Color hoverColor = Color(0xFF00FF00);
    const Color disabledColor = Color(0x05000000);
    const Color enabledBorderColor = Color(0x61000000);

    Future<void> pumpDecorator({
      required bool hovering,
      bool enabled = true,
      bool filled = true,
    }) async {
      return tester.pumpWidget(
        buildInputDecorator(
          isHovering: hovering,
          decoration: InputDecoration(
            enabled: enabled,
            filled: filled,
            hoverColor: hoverColor,
            disabledBorder: const OutlineInputBorder(borderSide: BorderSide(color: disabledColor)),
            border: const OutlineInputBorder(borderSide: BorderSide(color: enabledBorderColor)),
          ),
        ),
      );
    }

    // Test filled text field.
    await pumpDecorator(hovering: false);
    expect(getContainerColor(tester), equals(fillColor));
    await tester.pump(const Duration(seconds: 10));
    expect(getContainerColor(tester), equals(fillColor));

    await pumpDecorator(hovering: true);
    expect(getContainerColor(tester), equals(fillColor));
    await tester.pump(const Duration(milliseconds: 15));
    expect(getContainerColor(tester), equals(hoverColor));

    await pumpDecorator(hovering: false);
    expect(getContainerColor(tester), equals(hoverColor));
    await tester.pump(const Duration(milliseconds: 15));
    expect(getContainerColor(tester), equals(fillColor));

    await pumpDecorator(hovering: false, enabled: false);
    expect(getContainerColor(tester), equals(disabledColor));
    await tester.pump(const Duration(seconds: 10));
    expect(getContainerColor(tester), equals(disabledColor));

    await pumpDecorator(hovering: true, enabled: false);
    expect(getContainerColor(tester), equals(disabledColor));
    await tester.pump(const Duration(seconds: 10));
    expect(getContainerColor(tester), equals(disabledColor));

    // Test outline text field.
    const Color blendedHoverColor = Color(0x74004400);
    await pumpDecorator(hovering: false, filled: false);
    await tester.pumpAndSettle();
    expect(getBorderColor(tester), equals(enabledBorderColor));
    await tester.pump(const Duration(seconds: 10));
    expect(getBorderColor(tester), equals(enabledBorderColor));

    await pumpDecorator(hovering: true, filled: false);
    expect(getBorderColor(tester), equals(enabledBorderColor));
    await tester.pump(const Duration(milliseconds: 200));
    expect(getBorderColor(tester), equals(blendedHoverColor));

    await pumpDecorator(hovering: false, filled: false);
    expect(getBorderColor(tester), equals(blendedHoverColor));
    await tester.pump(const Duration(milliseconds: 200));
    expect(getBorderColor(tester), equals(enabledBorderColor));

    await pumpDecorator(hovering: false, filled: false, enabled: false);
    expect(getBorderColor(tester), equals(enabledBorderColor));
    await tester.pump(const Duration(milliseconds: 200));
    expect(getBorderColor(tester), equals(disabledColor));

    await pumpDecorator(hovering: true, filled: false, enabled: false);
    expect(getBorderColor(tester), equals(disabledColor));
    await tester.pump(const Duration(seconds: 10));
    expect(getBorderColor(tester), equals(disabledColor));
  });

  testWidgets('InputDecorator draws and animates focusColor', (WidgetTester tester) async {
    const Color focusColor = Color(0xFF0000FF);
    const Color disabledColor = Color(0x05000000);
    const Color enabledBorderColor = Color(0x61000000);

    Future<void> pumpDecorator({
      required bool focused,
      bool enabled = true,
      bool filled = true,
    }) async {
      return tester.pumpWidget(
        buildInputDecorator(
          isFocused: focused,
          decoration: InputDecoration(
            enabled: enabled,
            filled: filled,
            focusColor: focusColor,
            focusedBorder: const OutlineInputBorder(borderSide: BorderSide(color: focusColor)),
            disabledBorder: const OutlineInputBorder(borderSide: BorderSide(color: disabledColor)),
            border: const OutlineInputBorder(borderSide: BorderSide(color: enabledBorderColor)),
          ),
        ),
      );
    }

    // Test outline text field default border.
    await pumpDecorator(focused: false, filled: false);
    await tester.pumpAndSettle();
    expect(getBorderColor(tester), equals(enabledBorderColor));
    await tester.pump(const Duration(seconds: 10));
    expect(getBorderColor(tester), equals(enabledBorderColor));

    await pumpDecorator(focused: true, filled: false);
    expect(getBorderColor(tester), equals(enabledBorderColor));
    await tester.pump(const Duration(milliseconds: 200));
    expect(getBorderColor(tester), equals(focusColor));

    await pumpDecorator(focused: false, filled: false);
    expect(getBorderColor(tester), equals(focusColor));
    await tester.pump(const Duration(milliseconds: 200));
    expect(getBorderColor(tester), equals(enabledBorderColor));

    await pumpDecorator(focused: false, filled: false, enabled: false);
    expect(getBorderColor(tester), equals(enabledBorderColor));
    await tester.pump(const Duration(milliseconds: 200));
    expect(getBorderColor(tester), equals(disabledColor));

    await pumpDecorator(focused: true, filled: false, enabled: false);
    expect(getBorderColor(tester), equals(disabledColor));
    await tester.pump(const Duration(seconds: 10));
    expect(getBorderColor(tester), equals(disabledColor));
  });

  testWidgets('InputDecorator withdraws label when not empty or focused', (WidgetTester tester) async {
    Future<void> pumpDecorator({
      required bool focused,
      bool enabled = true,
      bool filled = false,
      bool empty = true,
      bool directional = false,
    }) async {
      return tester.pumpWidget(
        buildInputDecorator(
          isEmpty: empty,
          isFocused: focused,
          decoration: InputDecoration(
            labelText: 'Label',
            enabled: enabled,
            filled: filled,
            focusedBorder: const OutlineInputBorder(),
            disabledBorder: const OutlineInputBorder(),
            border: const OutlineInputBorder(),
          ),
        ),
      );
    }

    await pumpDecorator(focused: false, empty: true);
    await tester.pumpAndSettle();
    expect(getLabelRect(tester).topLeft, equals(const Offset(12, 20)));
    expect(getLabelRect(tester).size, equals(const Size(80, 16)));

    await pumpDecorator(focused: false, empty: false);
    await tester.pumpAndSettle();
    expect(getLabelRect(tester).topLeft, equals(const Offset(12, -4)));
    expect(getLabelRect(tester).size, equals(const Size(80, 16)));

    await pumpDecorator(focused: true, empty: true);
    await tester.pumpAndSettle();
    expect(getLabelRect(tester).topLeft, equals(const Offset(12, -4)));
    expect(getLabelRect(tester).size, equals(const Size(80, 16)));

    await pumpDecorator(focused: true, empty: false);
    await tester.pumpAndSettle();
    expect(getLabelRect(tester).topLeft, equals(const Offset(12, -4)));
    expect(getLabelRect(tester).size, equals(const Size(80, 16)));

    await pumpDecorator(focused: false, empty: true, enabled: false);
    await tester.pumpAndSettle();
    expect(getLabelRect(tester).topLeft, equals(const Offset(12, 20)));
    expect(getLabelRect(tester).size, equals(const Size(80, 16)));

    await pumpDecorator(focused: false, empty: false, enabled: false);
    await tester.pumpAndSettle();
    expect(getLabelRect(tester).topLeft, equals(const Offset(12, -4)));
    expect(getLabelRect(tester).size, equals(const Size(80, 16)));

    // Focused and disabled happens with NavigationMode.directional.
    await pumpDecorator(focused: true, empty: true, enabled: false);
    await tester.pumpAndSettle();
    expect(getLabelRect(tester).topLeft, equals(const Offset(12, 20)));
    expect(getLabelRect(tester).size, equals(const Size(80, 16)));

    await pumpDecorator(focused: true, empty: false, enabled: false);
    await tester.pumpAndSettle();
    expect(getLabelRect(tester).topLeft, equals(const Offset(12, -4)));
    expect(getLabelRect(tester).size, equals(const Size(80, 16)));
  });

  testWidgets('InputDecorationTheme.toString()', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/19305
    expect(
      const InputDecorationTheme(
        contentPadding: EdgeInsetsDirectional.only(start: 5.0),
      ).toString(),
      contains('contentPadding: EdgeInsetsDirectional(5.0, 0.0, 0.0, 0.0)'),
    );

    // Regression test for https://github.com/flutter/flutter/issues/20374
    expect(
      const InputDecorationTheme(
        contentPadding: EdgeInsets.only(left: 5.0),
      ).toString(),
      contains('contentPadding: EdgeInsets(5.0, 0.0, 0.0, 0.0)'),
    );

    // Verify that the toString() method succeeds.
    final String debugString = const InputDecorationTheme(
      labelStyle: TextStyle(height: 1.0),
      helperStyle: TextStyle(height: 2.0),
      helperMaxLines: 5,
      hintStyle: TextStyle(height: 3.0),
      errorStyle: TextStyle(height: 4.0),
      errorMaxLines: 5,
      isDense: true,
      contentPadding: EdgeInsets.only(right: 6.0),
      isCollapsed: true,
      prefixStyle: TextStyle(height: 7.0),
      suffixStyle: TextStyle(height: 8.0),
      counterStyle: TextStyle(height: 9.0),
      filled: true,
      fillColor: Color(0x00000010),
      focusColor: Color(0x00000020),
      errorBorder: UnderlineInputBorder(),
      focusedBorder: OutlineInputBorder(),
      focusedErrorBorder: UnderlineInputBorder(),
      disabledBorder: OutlineInputBorder(),
      enabledBorder: UnderlineInputBorder(),
      border: OutlineInputBorder(),
    ).toString();

    // Spot check
    expect(debugString, contains('labelStyle: TextStyle(inherit: true, height: 1.0x)'));
    expect(debugString, contains('isDense: true'));
    expect(debugString, contains('fillColor: Color(0x00000010)'));
    expect(debugString, contains('focusColor: Color(0x00000020)'));
    expect(debugString, contains('errorBorder: UnderlineInputBorder()'));
    expect(debugString, contains('focusedBorder: OutlineInputBorder()'));
  });


  testWidgets('InputDecoration default border uses colorScheme', (WidgetTester tester) async {
    final ThemeData theme = ThemeData.from(colorScheme: const ColorScheme.light());
    final Color enabledColor = theme.colorScheme.onSurface.withOpacity(0.38);
    final Color hoverColor = Color.alphaBlend(theme.hoverColor.withOpacity(0.12), enabledColor);

    // Enabled
    await tester.pumpWidget(
      buildInputDecorator(
        theme: theme,
        decoration: const InputDecoration(),
      ),
    );
    await tester.pumpAndSettle();
    expect(getBorderColor(tester), enabledColor);

    // Filled
    await tester.pumpWidget(
      buildInputDecorator(
        theme: theme,
        decoration: const InputDecoration(
          filled: true,
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(getBorderColor(tester), theme.hintColor);

    // Hovering
    await tester.pumpWidget(
      buildInputDecorator(
        theme: theme,
        isHovering: true,
        decoration: const InputDecoration(),
      ),
    );
    await tester.pumpAndSettle();
    expect(getBorderColor(tester), hoverColor);

    // Focused
    await tester.pumpWidget(
      buildInputDecorator(
        theme: theme,
        isFocused: true,
        decoration: const InputDecoration(),
      ),
    );
    await tester.pumpAndSettle();
    expect(getBorderColor(tester), theme.colorScheme.primary);

    // Error
    await tester.pumpWidget(
      buildInputDecorator(
        theme: theme,
        decoration: const InputDecoration(
          errorText: 'Nope',
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(getBorderColor(tester), theme.errorColor);

    // Disabled
    await tester.pumpWidget(
      buildInputDecorator(
        theme: theme,
        decoration: const InputDecoration(
          enabled: false,
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(getBorderColor(tester), theme.disabledColor);

    // Disabled, filled
    await tester.pumpWidget(
      buildInputDecorator(
        theme: theme,
        decoration: const InputDecoration(
          enabled: false,
          filled: true,
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(getBorderColor(tester), Colors.transparent);
  });

  testWidgets('InputDecoration borders', (WidgetTester tester) async {
    const InputBorder errorBorder = OutlineInputBorder(
      borderSide: BorderSide(color: Colors.red, width: 1.5),
    );
    const InputBorder focusedBorder = OutlineInputBorder(
      borderSide: BorderSide(color: Colors.green, width: 4.0),
    );
    const InputBorder focusedErrorBorder = OutlineInputBorder(
      borderSide: BorderSide(color: Colors.teal, width: 5.0),
    );
    const InputBorder disabledBorder = OutlineInputBorder(
      borderSide: BorderSide(color: Colors.grey, width: 0.0),
    );
    const InputBorder enabledBorder = OutlineInputBorder(
      borderSide: BorderSide(color: Colors.blue, width: 2.5),
    );

    await tester.pumpWidget(
      buildInputDecorator(
        // isFocused: false (default)
        decoration: const InputDecoration(
          // errorText: null (default)
          // enabled: true (default)
          errorBorder: errorBorder,
          focusedBorder: focusedBorder,
          focusedErrorBorder: focusedErrorBorder,
          disabledBorder: disabledBorder,
          enabledBorder: enabledBorder,
        ),
      ),
    );
    expect(getBorder(tester), enabledBorder);

    await tester.pumpWidget(
      buildInputDecorator(
        isFocused: true,
        decoration: const InputDecoration(
          // errorText: null (default)
          // enabled: true (default)
          errorBorder: errorBorder,
          focusedBorder: focusedBorder,
          focusedErrorBorder: focusedErrorBorder,
          disabledBorder: disabledBorder,
          enabledBorder: enabledBorder,
        ),
      ),
    );
    await tester.pumpAndSettle(); // border changes are animated
    expect(getBorder(tester), focusedBorder);

    await tester.pumpWidget(
      buildInputDecorator(
        isFocused: true,
        decoration: const InputDecoration(
          errorText: 'error',
          // enabled: true (default)
          errorBorder: errorBorder,
          focusedBorder: focusedBorder,
          focusedErrorBorder: focusedErrorBorder,
          disabledBorder: disabledBorder,
          enabledBorder: enabledBorder,
        ),
      ),
    );
    await tester.pumpAndSettle(); // border changes are animated
    expect(getBorder(tester), focusedErrorBorder);

    await tester.pumpWidget(
      buildInputDecorator(
        // isFocused: false (default)
        decoration: const InputDecoration(
          errorText: 'error',
          // enabled: true (default)
          errorBorder: errorBorder,
          focusedBorder: focusedBorder,
          focusedErrorBorder: focusedErrorBorder,
          disabledBorder: disabledBorder,
          enabledBorder: enabledBorder,
        ),
      ),
    );
    await tester.pumpAndSettle(); // border changes are animated
    expect(getBorder(tester), errorBorder);

    await tester.pumpWidget(
      buildInputDecorator(
        // isFocused: false (default)
        decoration: const InputDecoration(
          errorText: 'error',
          enabled: false,
          errorBorder: errorBorder,
          focusedBorder: focusedBorder,
          focusedErrorBorder: focusedErrorBorder,
          disabledBorder: disabledBorder,
          enabledBorder: enabledBorder,
        ),
      ),
    );
    await tester.pumpAndSettle(); // border changes are animated
    expect(getBorder(tester), errorBorder);

    await tester.pumpWidget(
      buildInputDecorator(
        // isFocused: false (default)
        decoration: const InputDecoration(
          // errorText: false (default)
          enabled: false,
          errorBorder: errorBorder,
          focusedBorder: focusedBorder,
          focusedErrorBorder: focusedErrorBorder,
          disabledBorder: disabledBorder,
          enabledBorder: enabledBorder,
        ),
      ),
    );
    await tester.pumpAndSettle(); // border changes are animated
    expect(getBorder(tester), disabledBorder);

    await tester.pumpWidget(
      buildInputDecorator(
        isFocused: true,
        decoration: const InputDecoration(
          // errorText: null (default)
          enabled: false,
          errorBorder: errorBorder,
          focusedBorder: focusedBorder,
          focusedErrorBorder: focusedErrorBorder,
          disabledBorder: disabledBorder,
          enabledBorder: enabledBorder,
        ),
      ),
    );
    await tester.pumpAndSettle(); // border changes are animated
    expect(getBorder(tester), disabledBorder);
  });

  testWidgets('OutlineInputBorder borders scale down to fit when large values are passed in', (WidgetTester tester) async {
    // This is a regression test for https://github.com/flutter/flutter/issues/34327
    const double largerBorderRadius = 200.0;
    const double smallerBorderRadius = 100.0;

    // Overall height for this InputDecorator is 56dps:
    //   12 - top padding
    //   12 - floating label (ahem font size 16dps * 0.75 = 12)
    //    4 - floating label / input text gap
    //   16 - input text (ahem font size 16dps)
    //   12 - bottom padding
    const double inputDecoratorHeight = 56.0;
    const double inputDecoratorWidth = 800.0;

    await tester.pumpWidget(
      buildInputDecorator(
        decoration: const InputDecoration(
          filled: true,
          fillColor: Color(0xFF00FF00),
          labelText: 'label text',
          border: OutlineInputBorder(
            borderRadius: BorderRadius.only(
              // Intentionally large values that are larger than the InputDecorator
              topLeft: Radius.circular(smallerBorderRadius),
              bottomLeft: Radius.circular(smallerBorderRadius),
              topRight: Radius.circular(largerBorderRadius),
              bottomRight: Radius.circular(largerBorderRadius),
            ),
          ),
        ),
      ),
    );

    // Skia determines the scale based on the ratios of radii to the total
    // height or width allowed. In this case, it is the right side of the
    // border, which have two corners with largerBorderRadius that add up
    // to be 400.0.
    const double denominator = largerBorderRadius * 2.0;

    const double largerBorderRadiusScaled = largerBorderRadius / denominator * inputDecoratorHeight;
    const double smallerBorderRadiusScaled = smallerBorderRadius / denominator * inputDecoratorHeight;

    expect(findBorderPainter(), paints
      ..save()
      ..path(
        style: PaintingStyle.fill,
        color: const Color(0xFF00FF00),
        includes: const <Offset>[
          // The border should draw along the four edges of the
          // InputDecorator.

          // Top center
          Offset(inputDecoratorWidth / 2.0, 0.0),
          // Bottom center
          Offset(inputDecoratorWidth / 2.0, inputDecoratorHeight),
          // Left center
          Offset(0.0, inputDecoratorHeight / 2.0),
          // Right center
          Offset(inputDecoratorWidth, inputDecoratorHeight / 2.0),

          // The border path should contain points where each rounded corner
          // ends.

          // Bottom-right arc
          Offset(inputDecoratorWidth, inputDecoratorHeight - largerBorderRadiusScaled),
          Offset(inputDecoratorWidth - largerBorderRadiusScaled, inputDecoratorHeight),
          // Top-right arc
          Offset(inputDecoratorWidth,0.0 + largerBorderRadiusScaled),
          Offset(inputDecoratorWidth - largerBorderRadiusScaled, 0.0),
          // Bottom-left arc
          Offset(0.0, inputDecoratorHeight - smallerBorderRadiusScaled),
          Offset(0.0 + smallerBorderRadiusScaled, inputDecoratorHeight),
          // Top-left arc
          Offset(0.0,0.0 + smallerBorderRadiusScaled),
          Offset(0.0 + smallerBorderRadiusScaled, 0.0),
        ],
        excludes: const <Offset>[
          // The border should not contain the corner points, since the border
          // is rounded.

          // Top-left
          Offset.zero,
          // Top-right
          Offset(inputDecoratorWidth, 0.0),
          // Bottom-left
          Offset(0.0, inputDecoratorHeight),
          // Bottom-right
          Offset(inputDecoratorWidth, inputDecoratorHeight),

          // Corners with larger border ratio should not contain points outside
          // of the larger radius.

          // Bottom-right arc
          Offset(inputDecoratorWidth, inputDecoratorHeight - smallerBorderRadiusScaled),
          Offset(inputDecoratorWidth - smallerBorderRadiusScaled, inputDecoratorWidth),
          // Top-left arc
          Offset(inputDecoratorWidth, 0.0 + smallerBorderRadiusScaled),
          Offset(inputDecoratorWidth - smallerBorderRadiusScaled, 0.0),
        ],
      )
      ..restore(),
    );
  }, skip: isBrowser); // https://github.com/flutter/flutter/issues/55317

  testWidgets('OutlineInputBorder radius carries over when lerping', (WidgetTester tester) async {
    // This is a regression test for https://github.com/flutter/flutter/issues/23982
    const Key key = Key('textField');

    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: Directionality(
            textDirection: TextDirection.ltr,
            child: TextField(
              key: key,
              decoration: InputDecoration(
                fillColor: Colors.white,
                filled: true,
                border: UnderlineInputBorder(
                  borderSide: BorderSide(color: Colors.blue, width: 2.0),
                  borderRadius: BorderRadius.zero,
                ),
              ),
            ),
          ),
        ),
      ),
    );

    // TextField has the given border
    expect(getBorderRadius(tester), BorderRadius.zero);

    // Focusing does not change the border
    await tester.tap(find.byKey(key));
    await tester.pump();
    expect(getBorderRadius(tester), BorderRadius.zero);
    await tester.pump(const Duration(milliseconds: 100));
    expect(getBorderRadius(tester), BorderRadius.zero);
    await tester.pumpAndSettle();
    expect(getBorderRadius(tester), BorderRadius.zero);
  });

  testWidgets('OutlineInputBorder async lerp', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/28724

    final Completer<void> completer = Completer<void>();
    bool waitIsOver = false;

    await tester.pumpWidget(
      MaterialApp(
        home: StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return GestureDetector(
              onTap: () async {
                setState(() { waitIsOver = true; });
                await completer.future;
                setState(() { waitIsOver = false;  });
              },
              child: InputDecorator(
                decoration: InputDecoration(
                  labelText: 'Test',
                  enabledBorder: !waitIsOver ? null : const OutlineInputBorder(borderSide: BorderSide(color: Colors.blue)),
                ),
              ),
            );
          },
        ),
      ),
    );

    await tester.tap(find.byType(StatefulBuilder));
    await tester.pumpAndSettle();

    completer.complete();
    await tester.pumpAndSettle();
  });

  test('InputBorder equality', () {
    // OutlineInputBorder's equality is defined by the borderRadius, borderSide, & gapPadding
    const OutlineInputBorder outlineInputBorder = OutlineInputBorder(
      borderRadius: BorderRadius.all(Radius.circular(9.0)),
      borderSide: BorderSide(color: Colors.blue),
      gapPadding: 32.0,
    );
    expect(outlineInputBorder, const OutlineInputBorder(
      borderSide: BorderSide(color: Colors.blue),
      borderRadius: BorderRadius.all(Radius.circular(9.0)),
      gapPadding: 32.0,
    ));
    expect(outlineInputBorder, isNot(const OutlineInputBorder()));

    // UnderlineInputBorder's equality is defined only by the borderSide
    const UnderlineInputBorder underlineInputBorder = UnderlineInputBorder(borderSide: BorderSide(color: Colors.blue));
    expect(underlineInputBorder, const UnderlineInputBorder(borderSide: BorderSide(color: Colors.blue)));
    expect(underlineInputBorder, isNot(const UnderlineInputBorder()));
  });


  test('InputBorder hashCodes', () {
    // OutlineInputBorder's hashCode is defined by the borderRadius, borderSide, & gapPadding
    const OutlineInputBorder outlineInputBorder = OutlineInputBorder(
      borderRadius: BorderRadius.all(Radius.circular(9.0)),
      borderSide: BorderSide(color: Colors.blue),
      gapPadding: 32.0,
    );
    expect(outlineInputBorder.hashCode, const OutlineInputBorder(
      borderRadius: BorderRadius.all(Radius.circular(9.0)),
      borderSide: BorderSide(color: Colors.blue),
      gapPadding: 32.0,
    ).hashCode);
    expect(outlineInputBorder.hashCode, isNot(const OutlineInputBorder().hashCode));

    // UnderlineInputBorder's hashCode is defined only by the borderSide
    const UnderlineInputBorder underlineInputBorder = UnderlineInputBorder(borderSide: BorderSide(color: Colors.blue));
    expect(underlineInputBorder.hashCode, const UnderlineInputBorder(borderSide: BorderSide(color: Colors.blue)).hashCode);
    expect(underlineInputBorder.hashCode, isNot(const UnderlineInputBorder().hashCode));
  });

  testWidgets('InputDecorationTheme implements debugFillDescription', (WidgetTester tester) async {
    final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
    const InputDecorationTheme(
      labelStyle: TextStyle(),
      helperStyle: TextStyle(),
      helperMaxLines: 6,
      hintStyle: TextStyle(),
      errorMaxLines: 5,
      hasFloatingPlaceholder: false,
      floatingLabelBehavior: FloatingLabelBehavior.never,
      contentPadding: EdgeInsetsDirectional.only(start: 40.0, top: 12.0, bottom: 12.0),
      prefixStyle: TextStyle(),
      suffixStyle: TextStyle(),
      counterStyle: TextStyle(),
      filled: true,
      fillColor: Colors.red,
      focusColor: Colors.blue,
      errorBorder: UnderlineInputBorder(),
      focusedBorder: UnderlineInputBorder(),
      focusedErrorBorder: UnderlineInputBorder(),
      disabledBorder: UnderlineInputBorder(),
      enabledBorder: UnderlineInputBorder(),
      border: UnderlineInputBorder(),
      alignLabelWithHint: true,
    ).debugFillProperties(builder);
    final List<String> description = builder.properties
        .where((DiagnosticsNode n) => !n.isFiltered(DiagnosticLevel.info))
        .map((DiagnosticsNode n) => n.toString()).toList();
    expect(description, <String>[
      'labelStyle: TextStyle(<all styles inherited>)',
      'helperStyle: TextStyle(<all styles inherited>)',
      'helperMaxLines: 6',
      'hintStyle: TextStyle(<all styles inherited>)',
      'errorMaxLines: 5',
      'hasFloatingPlaceholder: false',
      'floatingLabelBehavior: FloatingLabelBehavior.never',
      'contentPadding: EdgeInsetsDirectional(40.0, 12.0, 0.0, 12.0)',
      'prefixStyle: TextStyle(<all styles inherited>)',
      'suffixStyle: TextStyle(<all styles inherited>)',
      'counterStyle: TextStyle(<all styles inherited>)',
      'filled: true',
      'fillColor: MaterialColor(primary value: Color(0xfff44336))',
      'focusColor: MaterialColor(primary value: Color(0xff2196f3))',
      'errorBorder: UnderlineInputBorder()',
      'focusedBorder: UnderlineInputBorder()',
      'focusedErrorBorder: UnderlineInputBorder()',
      'disabledBorder: UnderlineInputBorder()',
      'enabledBorder: UnderlineInputBorder()',
      'border: UnderlineInputBorder()',
      'alignLabelWithHint: true',
    ]);
  });

  testWidgets('uses alphabetic baseline for CJK layout', (WidgetTester tester) async {
    await tester.binding.setLocale('zh', 'CN');
    final Typography typography = Typography.material2018();

    final FocusNode focusNode = FocusNode();
    final TextEditingController controller = TextEditingController();
    // The dense theme uses ideographic baselines
    Widget buildFrame(bool alignLabelWithHint) {
      return MaterialApp(
        theme: ThemeData(
          textTheme: typography.dense,
        ),
        home: Material(
          child: Directionality(
            textDirection: TextDirection.ltr,
            child: TextField(
              controller: controller,
              focusNode: focusNode,
              decoration: InputDecoration(
                labelText: 'label',
                alignLabelWithHint: alignLabelWithHint,
                hintText: 'hint',
                hintStyle: const TextStyle(
                  fontFamily: 'Cough',
                ),
              ),
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildFrame(true));
    await tester.pumpAndSettle();

    // These numbers should be the values from using alphabetic baselines:
    // Ideographic (incorrect) value is 31.299999713897705
    expect(tester.getTopLeft(find.text('hint')).dy, 28.75);

    // Ideographic (incorrect) value is 50.299999713897705
    expect(tester.getBottomLeft(find.text('hint')).dy, isBrowser ? 45.75 : 47.75);
  });

  testWidgets('InputDecorator floating label Y coordinate', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/54028
    await tester.pumpWidget(
      buildInputDecorator(
        // Temporary opt-in fix for https://github.com/flutter/flutter/issues/54028
        // Ensures that the floating label is vertically centered relative to
        // center of the top edge of the InputDecorator's outline border.
        fixTextFieldOutlineLabel: true,
        isEmpty: true,
        decoration: const InputDecoration(
          labelText: 'label',
          enabledBorder: OutlineInputBorder(
            borderSide: BorderSide(width: 4),
          ),
          floatingLabelBehavior: FloatingLabelBehavior.always,
        ),
      ),
    );

    await tester.pumpAndSettle();

    // floatingLabelHeight = 12 (ahem font size 16dps * 0.75 = 12)
    // labelY = -floatingLabelHeight/2 + borderWidth/2
    expect(tester.getTopLeft(find.text('label')).dy, -4.0);
  });

  testWidgets('InputDecorator floating label obeys floatingLabelBehavior', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        decoration: const InputDecoration(
          labelText: 'label',
          floatingLabelBehavior: FloatingLabelBehavior.never,
        ),
      ),
    );

    // Passing floating behavior never results in a dy offset of 20
    // because the label is not initially floating.
    expect(tester.getTopLeft(find.text('label')).dy, 20.0);
  });

  testWidgets('InputDecorator hint is displayed when floatingLabelBehavior is always', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        // isFocused: false (default)
        isEmpty: true,
        decoration: const InputDecoration(
          floatingLabelBehavior: FloatingLabelBehavior.always,
          hintText: 'hint',
          labelText: 'label',
        ),
      ),
    );
    await tester.pumpAndSettle();

    expect(getOpacity(tester, 'hint'), 1.0);
  });

  testWidgets('InputDecorator floating label width scales when focused', (WidgetTester tester) async {
    final String longStringA = String.fromCharCodes(List<int>.generate(200, (_) => 65));
    final String longStringB = String.fromCharCodes(List<int>.generate(200, (_) => 66));

    await tester.pumpWidget(
      Center(
        child: SizedBox(
          width: 100,
          height: 100,
          child: buildInputDecorator(
            // isFocused: false (default)
            isEmpty: true,
            decoration: InputDecoration(
              labelText: longStringA,
            ),
          ),
        ),
      ),
    );

    await tester.pumpAndSettle();

    expect(
      find.text(longStringA),
      paints..clipRect(rect: const Rect.fromLTWH(0, 0, 100.0, 16.0)),
    );

    await tester.pumpWidget(
      Center(
        child: SizedBox(
          width: 100,
          height: 100,
          child: buildInputDecorator(
            isFocused: true,
            isEmpty: true,
            decoration: InputDecoration(
              labelText: longStringB,
            ),
          ),
        ),
      ),
    );

    await tester.pumpAndSettle();

    expect(
      find.text(longStringB),
      // 133.3 is approximately 100 / 0.75 (_kFinalLabelScale)
      paints..clipRect(rect: const Rect.fromLTWH(0, 0, 133.0, 16.0)),
    );
  }, skip: isBrowser);  // TODO(yjbanov): https://github.com/flutter/flutter/issues/44020

  testWidgets('textAlignVertical can be updated', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/56933
    const String hintText = 'hint';
    TextAlignVertical? alignment = TextAlignVertical.top;
    late StateSetter setState;
    await tester.pumpWidget(
      MaterialApp(
        home: StatefulBuilder(
          builder: (BuildContext context, StateSetter setter) {
            setState = setter;
            return InputDecorator(
              textAlignVertical: alignment,
              decoration: const InputDecoration(
                hintText: hintText,
              ),
            );
          },
        ),
      ),
    );

    final double topPosition = tester.getTopLeft(find.text(hintText)).dy;

    setState(() {
      alignment = TextAlignVertical.bottom;
    });
    await tester.pump();

    expect(tester.getTopLeft(find.text(hintText)).dy, greaterThan(topPosition));

    // Setting textAlignVertical back to null works and reverts to the default.
    setState(() {
      alignment = null;
    });
    await tester.pump();

    expect(tester.getTopLeft(find.text(hintText)).dy, topPosition);
  });

  testWidgets("InputDecorator label width isn't affected by prefix or suffix", (WidgetTester tester) async {
    const String labelText = 'My Label';
    const String prefixText = 'The five boxing wizards jump quickly.';
    const String suffixText = 'Suffix';

    Widget getLabeledInputDecorator(bool showFix) {
      return MaterialApp(
        home: Material(
          child: Builder(
            builder: (BuildContext context) {
              return Theme(
                data: Theme.of(context),
                child: Align(
                  alignment: Alignment.topLeft,
                  child: TextField(
                    decoration: InputDecoration(
                      icon: const Icon(Icons.assistant),
                      prefixText: showFix ? prefixText : null,
                      suffixText: showFix ? suffixText : null,
                      suffixIcon: const Icon(Icons.threesixty),
                      labelText: labelText,
                    ),
                  ),
                ),
              );
            },
          ),
        ),
      );
    }

    // Build with no prefix or suffix.
    await tester.pumpWidget(getLabeledInputDecorator(false));

    // Get the width of the label when there is no prefix/suffix.
    expect(find.text(prefixText), findsNothing);
    expect(find.text(suffixText), findsNothing);
    final double labelWidth = tester.getSize(find.text(labelText)).width;

    // Build with a prefix and suffix.
    await tester.pumpWidget(getLabeledInputDecorator(true));

    // The prefix and suffix exist but aren't visible. They have not affected
    // the width of the label.
    expect(find.text(prefixText), findsOneWidget);
    expect(getOpacity(tester, prefixText), 0.0);
    expect(find.text(suffixText), findsOneWidget);
    expect(getOpacity(tester, suffixText), 0.0);
    expect(tester.getSize(find.text(labelText)).width, labelWidth);

    // Tap to focus.
    await tester.tap(find.byType(TextField));
    await tester.pumpAndSettle();

    // The prefix and suffix are visible, and the label is floating and still
    // hasn't had its width affected.
    expect(tester.getSize(find.text(labelText)).width, labelWidth);
    expect(getOpacity(tester, prefixText), 1.0);
  });

  // Related issue: https://github.com/flutter/flutter/issues/64427
  testWidgets('OutlineInputBorder and InputDecorator long labels and in Floating, the width should ignore the icon width', (WidgetTester tester) async {
    const String labelText = 'Flutter is Google’s UI toolkit for building beautiful, natively compiled applications for mobile, web, and desktop from a single codebase.';

    Widget getLabeledInputDecorator(FloatingLabelBehavior floatingLabelBehavior) => MaterialApp(
        home: Material(
          child: SizedBox(
            width: 300,
            child: TextField(
              decoration: InputDecoration(
                border: const OutlineInputBorder(
                  borderSide: BorderSide(color: Colors.greenAccent, width: 1.0),
                ),
                suffixIcon: const Icon(Icons.arrow_drop_down),
                floatingLabelBehavior: floatingLabelBehavior,
                labelText: labelText,
              ),
            ),
          ),
        ),
      );

    await tester.pumpWidget(getLabeledInputDecorator(FloatingLabelBehavior.never));

    final double labelWidth = getLabelRect(tester).width;

    await tester.pumpWidget(getLabeledInputDecorator(FloatingLabelBehavior.always));
    await tester.pumpAndSettle();

    final double floatedLabelWidth = getLabelRect(tester).width;

    expect(floatedLabelWidth > labelWidth, isTrue);

    final Widget target = getLabeledInputDecorator(FloatingLabelBehavior.auto);
    await tester.pumpWidget(target);
    await tester.pumpAndSettle();

    expect(getLabelRect(tester).width, labelWidth);

    // Click for Focus.
    await tester.tap(find.byType(TextField));
    // Default animation duration is 200 millisecond.
    await tester.pumpFrames(target, const Duration(milliseconds: 100));

    expect(getLabelRect(tester).width > labelWidth, isTrue);
    expect(getLabelRect(tester).width < floatedLabelWidth, isTrue);

    await tester.pumpAndSettle();

    expect(getLabelRect(tester).width, floatedLabelWidth);
  });

  testWidgets('given enough space, constrained and unconstrained heights result in the same size widget', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/65572
    final UniqueKey keyUnconstrained = UniqueKey();
    final UniqueKey keyConstrained = UniqueKey();

    Widget getInputDecorator(VisualDensity visualDensity) {
      return MaterialApp(
        home: Material(
          child: Builder(
            builder: (BuildContext context) {
              return Theme(
                data: Theme.of(context).copyWith(visualDensity: visualDensity),
                child: Center(
                  child: Row(
                    children: <Widget>[
                      SizedBox(
                        width: 35.0,
                        child: TextField(
                          key: keyUnconstrained,
                        ),
                      ),
                      SizedBox(
                        width: 35.0,
                        // 48 is the height that this TextField would take when
                        // laid out with no constraints.
                        height: 48.0,
                        child: TextField(
                          key: keyConstrained,
                        ),
                      ),
                    ],
                  ),
                ),
              );
            },
          ),
        ),
      );
    }

    await tester.pumpWidget(getInputDecorator(VisualDensity.standard));
    final double constrainedHeight = tester.getSize(find.byKey(keyConstrained)).height;
    final double unConstrainedHeight = tester.getSize(find.byKey(keyUnconstrained)).height;
    expect(constrainedHeight, equals(unConstrainedHeight));

    await tester.pumpWidget(getInputDecorator(VisualDensity.compact));
    final double constrainedHeightCompact = tester.getSize(find.byKey(keyConstrained)).height;
    final double unConstrainedHeightCompact = tester.getSize(find.byKey(keyUnconstrained)).height;
    expect(constrainedHeightCompact, equals(unConstrainedHeightCompact));
  });

  testWidgets('A vertically constrained TextField still positions its text inside of itself', (WidgetTester tester) async {
    await tester.pumpWidget(MaterialApp(
      home: Material(
        child: Center(
          child: SizedBox(
            width: 200,
            height: 28,
            child: TextField(
              controller: TextEditingController(text: 'A'),
            ),
          ),
        ),
      ),
    ));

    final double textFieldTop = tester.getTopLeft(find.byType(TextField)).dy;
    final double textFieldBottom = tester.getBottomLeft(find.byType(TextField)).dy;
    final double textTop = tester.getTopLeft(find.text('A')).dy;

    // The text is inside the field.
    expect(tester.getSize(find.text('A')).height, lessThan(textFieldBottom - textFieldTop));
    expect(textTop, greaterThan(textFieldTop));
    expect(textTop, lessThan(textFieldBottom));
  });

  testWidgets('visual density is included in the intrinsic height calculation', (WidgetTester tester) async {
    final UniqueKey key = UniqueKey();
    final UniqueKey intrinsicHeightKey = UniqueKey();
    await tester.pumpWidget(MaterialApp(
      home: Material(
        child: Builder(
          builder: (BuildContext context) {
            return Theme(
              data: Theme.of(context).copyWith(visualDensity: VisualDensity.compact),
              child: Center(
                child: Row(
                  children: <Widget>[
                    SizedBox(
                      width: 35.0,
                      child: TextField(
                        key: key,
                      ),
                    ),
                    SizedBox(
                      width: 35.0,
                      child: IntrinsicHeight(
                        child: TextField(
                          key: intrinsicHeightKey,
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            );
          },
        ),
      ),
    ));

    final double height = tester.getSize(find.byKey(key)).height;
    final double intrinsicHeight = tester.getSize(find.byKey(intrinsicHeightKey)).height;
    expect(intrinsicHeight, equals(height));
  });

  testWidgets('error message for negative baseline', (WidgetTester tester) async {
    FlutterErrorDetails? errorDetails;
    final FlutterExceptionHandler? oldHandler = FlutterError.onError;
    FlutterError.onError = (FlutterErrorDetails details) {
      errorDetails ??= details;
    };
    try {
      await tester.pumpWidget(
        MaterialApp(
          home: Center(
            child: Directionality(
              textDirection: TextDirection.ltr,
              child: InputDecorator(
                decoration: const InputDecoration(),
                child: Stack(
                  children: const <Widget>[
                    SizedBox(height: 0),
                    Positioned(
                      bottom: 5,
                      child: Text('ok'),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
        null,
        EnginePhase.layout,
      );
    } finally {
      FlutterError.onError = oldHandler;
    }

    expect(errorDetails?.toString(), contains("InputDecorator's children reported a negative baseline"));
    expect(errorDetails?.toString(), contains('RenderStack'));
  });
}
