// 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.

// This file is run as part of a reduced test set in CI on Mac and Windows
// machines.
@Tags(<String>['reduced-test-set'])

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,
  bool useMaterial3 = false,
  TextStyle? baseStyle,
  TextAlignVertical? textAlignVertical,
  VisualDensity? visualDensity,
  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,
              useMaterial3: useMaterial3,
            ),
            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());
}

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

InputBorder? getBorder(WidgetTester tester) {
  if (!tester.any(findBorderPainter())) {
    return null;
  }
  final CustomPaint customPaint = tester.widget(findBorderPainter());
  final dynamic/*_InputBorderPainter*/ inputBorderPainter = customPaint.foregroundPainter;
  // ignore: avoid_dynamic_calls
  final dynamic/*_InputBorderTween*/ inputBorderTween = inputBorderPainter.border;
  // ignore: avoid_dynamic_calls
  final Animation<double> animation = inputBorderPainter.borderAnimation as Animation<double>;
  // ignore: avoid_dynamic_calls
  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;
  // ignore: avoid_dynamic_calls
  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() {
  for(final bool useMaterial3 in  <bool>[true, false]){
  testWidgets('InputDecorator input/label text layout', (WidgetTester tester) async {
    // The label appears above the input text
    await tester.pumpWidget(
      buildInputDecorator(
        useMaterial3: useMaterial3,
        // 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, useMaterial3 ? 27.25 : 28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 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(
        useMaterial3: useMaterial3,
        isEmpty: true,
        // isFocused: false (default)
        decoration: const InputDecoration(
          labelText: 'label',
        ),
      ),
    );
    await tester.pumpAndSettle();

    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 21.0 : 20.0);

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

    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);

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

    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 21.0 : 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, useMaterial3 ? 21.0 : 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(
        useMaterial3: useMaterial3,
        // 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, useMaterial3 ? 27.25 : 28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 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(
        useMaterial3: useMaterial3,
        isEmpty: true,
        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, useMaterial3 ? 27.25 : 28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 21.0 : 20.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 35.0: 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(
        useMaterial3: useMaterial3,
        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, useMaterial3 ? 27.25 : 28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 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(
        useMaterial3: useMaterial3,
        isEmpty: true,
        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, useMaterial3 ? 27.25 : 28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 21.0 : 20.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 35.0: 36.0);
    expect(getBorderWeight(tester), useMaterial3 ? 1.0 : 0.0);

    // enabled: false produces a transparent border if filled: true.
    // The widget's size and layout is the same as for enabled: true.
    await tester.pumpWidget(
      buildInputDecorator(
        useMaterial3: useMaterial3,
        isEmpty: true,
        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, useMaterial3 ? 27.25 : 28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 21.0 : 20.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 35.0: 36.0);
    final ThemeData theme = ThemeData.from(colorScheme: const ColorScheme.light());
    expect(getBorderColor(tester), useMaterial3 ? theme.colorScheme.onSurface.withOpacity(0.38) : Colors.transparent);

    // alignLabelWithHint: true positions the label at the text baseline,
    // aligned with the hint.
    await tester.pumpWidget(
      buildInputDecorator(
        useMaterial3: useMaterial3,
        isEmpty: true,
        decoration: const InputDecoration(
          labelText: 'label',
          alignLabelWithHint: true,
          hintText: 'hint',
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
    if(!useMaterial3) {
      expect(tester.getTopLeft(find.text('label')).dy, tester.getTopLeft(find.text('hint')).dy);
      expect(tester.getBottomLeft(find.text('label')).dy, tester.getBottomLeft(find.text('hint')).dy);
    }
  });

  testWidgets('InputDecorator input/label widget layout', (WidgetTester tester) async {
    const Key key = Key('l');

    // The label appears above the input text.
    await tester.pumpWidget(
      buildInputDecorator(
        useMaterial3: useMaterial3,
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: const InputDecoration(
          label: Text.rich(
            TextSpan(
              children: <InlineSpan>[
                TextSpan(text: 'label'),
                WidgetSpan(
                  child: Text('*', style: TextStyle(color: Colors.red),
                  ),
                ),
              ],
            ),
            key: key,
          ),
        ),
      ),
    );
    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, useMaterial3 ? 27.25 : 28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
    expect(tester.getTopLeft(find.byKey(key)).dy, useMaterial3 ? 12.75 :12.0);
    expect(tester.getBottomLeft(find.byKey(key)).dy, useMaterial3 ? 23.25 :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(
        useMaterial3: useMaterial3,
        isEmpty: true,
        // isFocused: false (default)
        decoration: const InputDecoration(
          label: Text.rich(
            TextSpan(
              children: <InlineSpan>[
                TextSpan(text: 'label'),
                WidgetSpan(
                  child: Text('*', style: TextStyle(color: Colors.red),
                  ),
                ),
              ],
            ),
            key: key,
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();

    expect(tester.getTopLeft(find.byKey(key)).dy, useMaterial3 ? 21.0 :20.0);

    // The label appears above the input text when there is no content and the
    // floatingLabelBehavior is set to always.
    await tester.pumpWidget(
      buildInputDecorator(
        useMaterial3: useMaterial3,
        isEmpty: true,
        // isFocused: false (default)
        decoration: const InputDecoration(
          label: Text.rich(
            TextSpan(
              children: <InlineSpan>[
                TextSpan(text: 'label'),
                WidgetSpan(
                  child: Text('*', style: TextStyle(color: Colors.red),
                  ),
                ),
              ],
            ),
            key: key,
          ),
          floatingLabelBehavior: FloatingLabelBehavior.always,
        ),
      ),
    );
    await tester.pumpAndSettle();

    expect(tester.getTopLeft(find.byKey(key)).dy, useMaterial3 ? 12.75 :12.0);

    // The label appears within the input text when there is content and
    // the floatingLabelBehavior is set to never.
    await tester.pumpWidget(
      buildInputDecorator(
        useMaterial3: useMaterial3,
        // isFocused: false (default)
        decoration: const InputDecoration(
          label: Text.rich(
            TextSpan(
              children: <InlineSpan>[
                TextSpan(text: 'label'),
                WidgetSpan(
                  child: Text('*', style: TextStyle(color: Colors.red),
                  ),
                ),
              ],
            ),
            key: key,
          ),
          floatingLabelBehavior: FloatingLabelBehavior.never,
        ),
      ),
    );
    await tester.pumpAndSettle();

    expect(tester.getTopLeft(find.byKey(key)).dy, useMaterial3 ? 21 :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.byKey(key)).dy, useMaterial3 ? 21 :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(
        useMaterial3: useMaterial3,
        // isEmpty: false (default)
        isFocused: true,
        decoration: const InputDecoration(
          label: Text.rich(
            TextSpan(
              children: <InlineSpan>[
                TextSpan(text: 'label'),
                WidgetSpan(
                  child: Text('*', style: TextStyle(color: Colors.red),
                  ),
                ),
              ],
            ),
            key: key,
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
    expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25 : 28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
    expect(tester.getTopLeft(find.byKey(key)).dy, useMaterial3 ? 12.75 :12.0);
    expect(tester.getBottomLeft(find.byKey(key)).dy, useMaterial3 ? 23.25 :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(
        useMaterial3: useMaterial3,
        isEmpty: true,
        decoration: const InputDecoration(
          label: Text.rich(
            TextSpan(
              children: <InlineSpan>[
                TextSpan(text: 'label'),
                WidgetSpan(
                  child: Text('*', style: TextStyle(color: Colors.red),
                  ),
                ),
              ],
            ),
            key: key,
          ),
        ),
      ),
    );

    // 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.byKey(key)).dy;
    expect(labelY50ms, inExclusiveRange(12.0, 20.0));
    await tester.pump(const Duration(milliseconds: 50));
    final double labelY100ms = tester.getTopLeft(find.byKey(key)).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, useMaterial3 ? 27.25 :28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 :44.0);
    expect(tester.getTopLeft(find.byKey(key)).dy, useMaterial3 ? 21 :20.0);
    expect(tester.getBottomLeft(find.byKey(key)).dy, useMaterial3 ? 35 :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(
        useMaterial3: useMaterial3,
        isEmpty: true,
        isFocused: true,
        decoration: const InputDecoration(
          label: Text.rich(
            TextSpan(
              children: <InlineSpan>[
                TextSpan(text: 'label'),
                WidgetSpan(
                  child: Text('*', style: TextStyle(color: Colors.red),
                  ),
                ),
              ],
            ),
            key: key,
          ),
        ),
      ),
    );

    // 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.byKey(key)).dy;
      expect(labelY50ms, inExclusiveRange(12.0, 28.0));
      await tester.pump(const Duration(milliseconds: 50));
      final double labelY100ms = tester.getTopLeft(find.byKey(key)).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, useMaterial3 ? 27.25 :28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 :44.0);
    expect(tester.getTopLeft(find.byKey(key)).dy, useMaterial3 ? 12.75 :12.0);
    expect(tester.getBottomLeft(find.byKey(key)).dy, useMaterial3 ? 23.25 :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(
        useMaterial3: useMaterial3,
        isEmpty: true,
        decoration: const InputDecoration(
          label: Text.rich(
            TextSpan(
              children: <InlineSpan>[
                TextSpan(text: 'label'),
                WidgetSpan(
                  child: Text('*', style: TextStyle(color: Colors.red),
                  ),
                ),
              ],
            ),
            key: key,
          ),
          enabled: false,
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
    expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25 :28.0);
    expect(tester.getBottomLeft(find.text('text')).dy,useMaterial3 ? 43.25 : 44.0);
    expect(tester.getTopLeft(find.byKey(key)).dy, useMaterial3 ? 21 :20.0);
    expect(tester.getBottomLeft(find.byKey(key)).dy, useMaterial3 ? 35 :36.0);
    expect(getBorderWeight(tester),useMaterial3 ? 1.0 : 0.0);

    // enabled: false produces a transparent border if filled: true.
    // The widget's size and layout is the same as for enabled: true.
    await tester.pumpWidget(
      buildInputDecorator(
        useMaterial3: useMaterial3,
        isEmpty: true,
        decoration: const InputDecoration(
          label: Text.rich(
            TextSpan(
              children: <InlineSpan>[
                TextSpan(text: 'label'),
                WidgetSpan(
                  child: Text('*', style: TextStyle(color: Colors.red),
                  ),
                ),
              ],
            ),
            key: key,
          ),
          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, useMaterial3 ? 27.25: 28.0);
    expect(tester.getBottomLeft(find.text('text')).dy,  useMaterial3 ? 43.25: 44.0);
    expect(tester.getTopLeft(find.byKey(key)).dy,  useMaterial3 ? 21: 20.0);
    expect(tester.getBottomLeft(find.byKey(key)).dy,  useMaterial3 ? 35: 36.0);
    final ThemeData theme = ThemeData.from(colorScheme: const ColorScheme.light());
    expect(getBorderColor(tester), useMaterial3 ? theme.colorScheme.onSurface.withOpacity(0.38) : Colors.transparent);

    // alignLabelWithHint: true positions the label at the text baseline,
    // aligned with the hint.
    await tester.pumpWidget(
      buildInputDecorator(
        useMaterial3: useMaterial3,
        isEmpty: true,
        decoration: const InputDecoration(
          label: Text.rich(
            TextSpan(
              children: <InlineSpan>[
                TextSpan(text: 'label'),
                WidgetSpan(
                  child: Text('*', style: TextStyle(color: Colors.red),
                  ),
                ),
              ],
            ),
            key: key,
          ),
          alignLabelWithHint: true,
          hintText: 'hint',
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(tester.getSize(find.byType(InputDecorator)), const Size(800.0, 56.0));
    if(!useMaterial3) {
      expect(tester.getTopLeft(find.byKey(key)).dy, tester.getTopLeft(find.text('hint')).dy);
      expect(tester.getBottomLeft(find.byKey(key)).dy, tester.getBottomLeft(find.text('hint')).dy);
    }

  });

  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: const OutlineInputBorder(
                      borderRadius: BorderRadius.zero,
                    ),
                  ),
                ),
              ),
            ),
          );
        }

        // 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(
        useMaterial3: useMaterial3,
        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(
        useMaterial3: useMaterial3,
        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, useMaterial3 ? 27.25 : 28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 21.0 : 20.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 35.0: 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(
        useMaterial3: useMaterial3,
        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, useMaterial3 ? 27.25 :28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 :44.0);
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 24.0);
    expect(tester.getTopLeft(find.text('hint')).dy, useMaterial3 ? 27.25 :28.0);
    expect(tester.getBottomLeft(find.text('hint')).dy, useMaterial3 ? 43.25 :44.0);
    expect(getOpacity(tester, 'hint'), 1.0);
    expect(getBorderBottom(tester), 56.0);
    expect(getBorderWeight(tester), 2.0);

    await tester.pumpWidget(
      buildInputDecorator(
        useMaterial3: useMaterial3,
        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, useMaterial3 ? 27.25 :28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 :44.0);
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 24.0);
    expect(tester.getTopLeft(find.text('hint')).dy, useMaterial3 ? 27.25 :28.0);
    expect(tester.getBottomLeft(find.text('hint')).dy, useMaterial3 ? 43.25 :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(
        useMaterial3: useMaterial3,
        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)), Size(800.0, useMaterial3 ? 46.5 :48.0));
    expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 22.5 : 24.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 38.5 : 40.0);
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 16.25 : 16.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 30.25 : 32.0);
    expect(getOpacity(tester, 'hint'), 0.0);
    expect(getBorderBottom(tester), useMaterial3 ? 46.5 : 48.0);
    expect(getBorderWeight(tester), 1.0);

    // Label is visible, hint is not (opacity 0.0).
    await tester.pumpWidget(
      buildInputDecorator(
        useMaterial3: useMaterial3,
        isEmpty: true,
        isFocused: true,
        decoration: const InputDecoration(
          labelText: 'label',
          hintText: 'hint',
          isDense: true,
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(tester.getSize(find.byType(InputDecorator)), Size(800.0, useMaterial3 ? 46.5 : 48.0));
    expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 22.5 : 24.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 38.5 : 40.0);
    expect(tester.getTopLeft(find.text('label')).dy, 8.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 18.5 : 20.0);
    expect(getOpacity(tester, 'hint'), 1.0);
    expect(getBorderBottom(tester), useMaterial3 ? 46.5 : 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(
        useMaterial3: useMaterial3,
        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(
        useMaterial3: useMaterial3,
        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, useMaterial3 ? 27.25 : 28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 :44.0);
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 21.0 : 20.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 35.0: 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(
        useMaterial3: useMaterial3,
        // 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, useMaterial3 ? 27.25 : 28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 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(
        useMaterial3: useMaterial3,
        // 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)), Size(800.0, useMaterial3 ? 66.5 : 68.0));
    expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 22.5 : 24.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 38.5 : 40.0);
    expect(tester.getTopLeft(find.text('label')).dy, 8.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 18.5 : 20.0);
    expect(getBorderBottom(tester), useMaterial3 ? 46.5 : 48.0);
    expect(getBorderWeight(tester), 1.0);
    expect(tester.getTopLeft(find.text('error')), Offset(12.0, useMaterial3 ? 54.5 : 56.0));
    expect(tester.getTopRight(find.text('counter')), Offset(788.0, useMaterial3 ? 54.5 : 56.0));

    await tester.pumpWidget(
      buildInputDecorator(
        useMaterial3: useMaterial3,
        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)), Size(800.0, useMaterial3 ? 66.5 : 68.0));
    expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 22.5 : 24.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 38.5 : 40.0);
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 16.25 : 16.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 30.25 : 32.0);
    expect(getBorderBottom(tester), useMaterial3 ? 46.5 : 48.0);
    expect(getBorderWeight(tester), 1.0);
    expect(tester.getTopLeft(find.text('error')), Offset(12.0, useMaterial3 ? 54.5 : 56.0));
    expect(tester.getTopRight(find.text('counter')), Offset(788.0, useMaterial3 ? 54.5 : 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');

    // 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 of $maxLength',
        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(
        useMaterial3: useMaterial3,
        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(
        useMaterial3: useMaterial3,
        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(
        useMaterial3: useMaterial3,
        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(
        useMaterial3: useMaterial3,
        isEmpty: true,
        // isFocused: false (default)
        decoration: const InputDecoration(
          labelText: 'label',
          helperText: kHelper3,
          helperMaxLines: 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 - 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(
        useMaterial3: useMaterial3,
        isEmpty: true,
        // isFocused: false (default)
        decoration: const InputDecoration(
          labelText: 'label',
          helperText: kHelper3,
          helperMaxLines: 2,
          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(
        useMaterial3: useMaterial3,
        isEmpty: true,
        // isFocused: false (default)
        decoration: const InputDecoration(
          labelText: 'label',
          helperText: kHelper2,
          helperMaxLines: 3,
          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(
        useMaterial3: useMaterial3,
        isEmpty: true,
        // isFocused: false (default)
        decoration: const InputDecoration(
          labelText: 'label',
          helperText: kHelper1,
          helperMaxLines: 3,
          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(
        useMaterial3: useMaterial3,
        // 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(
        useMaterial3: useMaterial3,
        // 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 iconColor/prefixIconColor/suffixIconColor', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: TextField(
            decoration: InputDecoration(
              icon: Icon(Icons.cabin),
              prefixIcon: Icon(Icons.sailing),
              suffixIcon: Icon(Icons.close),
              iconColor: Colors.amber,
              prefixIconColor: Colors.green,
              suffixIconColor: Colors.red,
              filled: true,
            ),
          ),
        ),
      ),
    );

    expect(tester.widget<IconTheme>(find.widgetWithIcon(IconTheme,Icons.cabin).first).data.color, Colors.amber);
    expect(tester.widget<IconTheme>(find.widgetWithIcon(IconTheme,Icons.sailing).first).data.color, Colors.green);
    expect(tester.widget<IconTheme>(find.widgetWithIcon(IconTheme,Icons.close).first).data.color, Colors.red);
  });

  testWidgets('InputDecorator prefix/suffix widgets', (WidgetTester tester) async {
    const Key pKey = Key('p');
    const Key sKey = Key('s');
    await tester.pumpWidget(
      buildInputDecorator(
        useMaterial3: useMaterial3,
        // 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)), Size(800.0, useMaterial3 ? 49.5 : 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, useMaterial3 ? 16.75 : 16.0);
    expect(tester.getTopLeft(find.byKey(pKey)).dy, useMaterial3 ? 12.75 : 12.0);
    expect(tester.getTopLeft(find.text('p')).dy, useMaterial3 ? 16.75 : 16.0);
    expect(tester.getTopLeft(find.byKey(sKey)).dy, useMaterial3 ? 12.75 : 12.0);
    expect(tester.getTopLeft(find.text('s')).dy, useMaterial3 ? 16.75 : 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(
        useMaterial3: useMaterial3,
        // 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(useMaterial3 ? 129.5 : 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(useMaterial3 ? 96.75 : 96, epsilon: .0001)); // 12 + 100 - 16
    expect(tester.getTopLeft(find.byKey(pKey)).dy, useMaterial3 ? 12.75 : 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(
        useMaterial3: useMaterial3,
        // 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(
        useMaterial3: useMaterial3,
        // 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, useMaterial3 ? 12.75 : 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(
        useMaterial3: useMaterial3,
        // 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(
        useMaterial3: useMaterial3,
        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(
        useMaterial3: useMaterial3,
        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, useMaterial3 ? 23.25 : 24.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 39.25 : 40.0);
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 17 : 16.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 31.0 : 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(
        useMaterial3: useMaterial3,
        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, useMaterial3 ? 23.25 : 24.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 39.25 : 40.0);
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 24.0);
    expect(tester.getTopLeft(find.text('hint')).dy, useMaterial3 ? 23.25 : 24.0);
    expect(tester.getBottomLeft(find.text('hint')).dy, useMaterial3 ? 39.25 : 40.0);
    expect(getOpacity(tester, 'hint'), 1.0);
    expect(getBorderBottom(tester), 48.0);
    expect(getBorderWeight(tester), 2.0);

    await tester.pumpWidget(
      buildInputDecorator(
        useMaterial3: useMaterial3,
        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, useMaterial3 ? 23.25 : 24.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 39.25 : 40.0);
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 24.0);
    expect(tester.getTopLeft(find.text('hint')).dy, useMaterial3 ? 23.25 : 24.0);
    expect(tester.getBottomLeft(find.text('hint')).dy, useMaterial3 ? 39.25 : 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(
        useMaterial3: useMaterial3,
        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, useMaterial3 ? 31.25 : 32.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 47.25 : 48.0);
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 25.0 : 24.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 39.0 : 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(
        useMaterial3: useMaterial3,
        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, useMaterial3 ? 31.25 : 32.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 47.25 : 48.0);
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 24.0);
    expect(tester.getTopLeft(find.text('hint')).dy, useMaterial3 ? 31.25 : 32.0);
    expect(tester.getBottomLeft(find.text('hint')).dy, useMaterial3 ? 47.25 : 48.0);
    expect(getOpacity(tester, 'hint'), 1.0);
    expect(getBorderBottom(tester), 64.0);
    expect(getBorderWeight(tester), 2.0);

    await tester.pumpWidget(
      buildInputDecorator(
        useMaterial3: useMaterial3,
        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, useMaterial3 ? 31.25 : 32.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 47.25 : 48.0);
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 24.0);
    expect(tester.getTopLeft(find.text('hint')).dy, useMaterial3 ? 31.25 : 32.0);
    expect(tester.getBottomLeft(find.text('hint')).dy, useMaterial3 ? 47.25 : 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(
        useMaterial3: useMaterial3,
        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('constraints', () {
    testWidgets('No InputDecorator constraints', (WidgetTester tester) async {
      await tester.pumpWidget(buildInputDecorator(
        useMaterial3: useMaterial3,
      ));

      // Should fill the screen width and be default height
      expect(tester.getSize(find.byType(InputDecorator)), const Size(800, 48));
    });

    testWidgets('InputDecoratorThemeData constraints', (WidgetTester tester) async {
      await tester.pumpWidget(
          buildInputDecorator(
            useMaterial3: useMaterial3,
            theme: ThemeData(
              inputDecorationTheme: const InputDecorationTheme(
                constraints: BoxConstraints(maxWidth: 300, maxHeight: 40),
              ),
            ),
          ),
      );

      // Theme settings should make it 300x40 pixels
      expect(tester.getSize(find.byType(InputDecorator)), const Size(300, 40));
    });

    testWidgets('InputDecorator constraints', (WidgetTester tester) async {
      await tester.pumpWidget(
        buildInputDecorator(
          useMaterial3: useMaterial3,
          theme: ThemeData(
            inputDecorationTheme: const InputDecorationTheme(
              constraints: BoxConstraints(maxWidth: 300, maxHeight: 40),
            ),
          ),
          decoration: const InputDecoration(
            constraints: BoxConstraints(maxWidth: 200, maxHeight: 32),
          ),
        ),
      );

      // InputDecoration.constraints should override the theme. It should be
      // only 200x32 pixels
      expect(tester.getSize(find.byType(InputDecorator)), const Size(200, 32));
    });
  });

  group('textAlignVertical position', () {
    group('simple case', () {
      testWidgets('align top (default)', (WidgetTester tester) async {
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            useMaterial3: useMaterial3,
            // 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(useMaterial3 ? 12.75 : 12.0, epsilon: .0001));
      });

      testWidgets('align center', (WidgetTester tester) async {
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            useMaterial3: useMaterial3,
            // 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(
            useMaterial3: useMaterial3,
            // 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(useMaterial3 ? 567.25 : 568.0, epsilon: .0001));
      });

      testWidgets('align as a double', (WidgetTester tester) async {
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            useMaterial3: useMaterial3,
            // 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(useMaterial3 ? 497.9375 : 498.5, epsilon: .0001));
      });
    });

    group('outline border', () {
      testWidgets('align top', (WidgetTester tester) async {
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            useMaterial3: useMaterial3,
            // 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(
            useMaterial3: useMaterial3,
            // 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(
            useMaterial3: useMaterial3,
            // 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(
            useMaterial3: useMaterial3,
            // 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(useMaterial3 ? 96.75 : 96, epsilon: .0001));
        expect(tester.getTopLeft(find.byKey(pKey)).dy, useMaterial3 ? 12.75 : 12.0);
      });

      testWidgets('InputDecorator tall prefix align center', (WidgetTester tester) async {
        const Key pKey = Key('p');
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            useMaterial3: useMaterial3,
            // 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(useMaterial3 ? 96.75 : 96.0, epsilon: .0001));
        expect(tester.getTopLeft(find.byKey(pKey)).dy, useMaterial3 ? 12.75 : 12.0);
      });

      testWidgets('InputDecorator tall prefix align bottom', (WidgetTester tester) async {
        const Key pKey = Key('p');
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            useMaterial3: useMaterial3,
            // 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(useMaterial3 ? 96.75 : 96.0, epsilon: .0001));
        expect(tester.getTopLeft(find.byKey(pKey)).dy, useMaterial3 ? 12.75 : 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(
            useMaterial3: useMaterial3,
            // 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(
            useMaterial3: useMaterial3,
            // 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(
            useMaterial3: useMaterial3,
            // 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(
            useMaterial3: useMaterial3,
            // 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(
            useMaterial3: useMaterial3,
            // 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(useMaterial3 ? 27.25 : 28.0, epsilon: .0001));
      });

      testWidgets('align center', (WidgetTester tester) async {
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            useMaterial3: useMaterial3,
            // 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(useMaterial3 ? 297.25 : 298.0, epsilon: .0001));
      });

      testWidgets('align bottom', (WidgetTester tester) async {
        const String text = 'text';
        await tester.pumpWidget(
          buildInputDecorator(
            useMaterial3: useMaterial3,
            // 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(useMaterial3 ? 567.25 : 568.0, epsilon: .0001));
      });
    });
  });

  group('OutlineInputBorder', () {
    group('default alignment', () {
      testWidgets('Centers when border', (WidgetTester tester) async {
        await tester.pumpWidget(
          buildInputDecorator(
            useMaterial3: useMaterial3,
            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(
            useMaterial3: useMaterial3,
            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(
            useMaterial3: useMaterial3,
            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(
            useMaterial3: useMaterial3,
            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(
            useMaterial3: useMaterial3,
            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(
            useMaterial3: useMaterial3,
            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(
            useMaterial3: useMaterial3,
            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(
            useMaterial3: useMaterial3,
            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(
            useMaterial3: useMaterial3,
            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(
        useMaterial3: useMaterial3,
        // 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(
        useMaterial3: useMaterial3,
        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(
        useMaterial3: useMaterial3,
        // 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(
        useMaterial3: useMaterial3,
        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(
        useMaterial3: useMaterial3,
        // 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, useMaterial3 ? 27.25 : 28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 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(
        useMaterial3: useMaterial3,
        // 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(
        useMaterial3: useMaterial3,
        // 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(
        useMaterial3: useMaterial3,
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: InputDecoration(
          contentPadding: EdgeInsetsDirectional.only(start: 40.0, top: useMaterial3 ? 12.75 : 12.0, bottom: useMaterial3 ? 12.75 : 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(
        useMaterial3: useMaterial3,
        // isEmpty: false (default)
        isFocused: true, // label is floating, still adjusted for contentPadding
        textDirection: TextDirection.rtl,
        decoration: InputDecoration(
          contentPadding: EdgeInsetsDirectional.only(start: 40.0, top: useMaterial3 ? 12.75 : 12.0, bottom: useMaterial3 ? 12.75 : 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('FloatingLabelAlignment.toString()', (WidgetTester tester) async {
    expect(FloatingLabelAlignment.start.toString(), 'FloatingLabelAlignment.start');
    expect(FloatingLabelAlignment.center.toString(), 'FloatingLabelAlignment.center');
  });

  group('floatingLabelAlignment', () {
    Widget buildInputDecoratorWithFloatingLabel({required TextDirection textDirection,
          required bool hasIcon,
          required FloatingLabelAlignment alignment,
          bool borderIsOutline = false,
    }) => buildInputDecorator(
      useMaterial3: useMaterial3,
        // isEmpty: false (default)
        // isFocused: false (default)
        textDirection: textDirection,
        decoration: InputDecoration(
          contentPadding: const EdgeInsetsDirectional.only(start: 40.0, top: 12.0, bottom: 12.0),
          floatingLabelAlignment: alignment,
          icon: hasIcon ? const Icon(Icons.insert_link) : null,
          labelText: 'label',
          hintText: 'hint',
          filled: true,
          border: borderIsOutline ? const OutlineInputBorder() : null,
        ),
      );

    group('LTR with icon aligned', () {
      testWidgets('start', (WidgetTester tester) async {
        await tester.pumpWidget(
          buildInputDecoratorWithFloatingLabel(
            textDirection: TextDirection.ltr,
            hasIcon: true,
            alignment: FloatingLabelAlignment.start,
            // borderIsOutline: false, (default)
          ),
        );
        // icon (40) + contentPadding (40)
        expect(tester.getTopLeft(find.text('label')).dx, 80.0);

        await tester.pumpWidget(
          buildInputDecoratorWithFloatingLabel(
            textDirection: TextDirection.ltr,
            hasIcon: true,
            alignment: FloatingLabelAlignment.start,
            borderIsOutline: true,
          ),
        );
        // icon (40) + contentPadding (40)
        expect(tester.getTopLeft(find.text('label')).dx, 80.0);
      });

      testWidgets('center', (WidgetTester tester) async {
        await tester.pumpWidget(
          buildInputDecoratorWithFloatingLabel(
            textDirection: TextDirection.ltr,
            hasIcon: true,
            alignment: FloatingLabelAlignment.center,
            // borderIsOutline: false, (default)
          ),
        );
        // icon (40) + (decorator (800) - icon (40)) / 2
        expect(tester.getCenter(find.text('label')).dx, 420.0);

        await tester.pumpWidget(
          buildInputDecoratorWithFloatingLabel(
            textDirection: TextDirection.ltr,
            hasIcon: true,
            alignment: FloatingLabelAlignment.center,
            borderIsOutline: true,
          ),
        );
        // icon (40) + (decorator (800) - icon (40)) / 2
        expect(tester.getCenter(find.text('label')).dx, 420.0);
      });
    });

    group('LTR without icon aligned', () {
      testWidgets('start', (WidgetTester tester) async {
        await tester.pumpWidget(
          buildInputDecoratorWithFloatingLabel(
            textDirection: TextDirection.ltr,
            hasIcon: false,
            alignment: FloatingLabelAlignment.start,
            // borderIsOutline: false, (default)
          ),
        );
        // contentPadding (40)
        expect(tester.getTopLeft(find.text('label')).dx, 40.0);

        await tester.pumpWidget(
          buildInputDecoratorWithFloatingLabel(
            textDirection: TextDirection.ltr,
            hasIcon: false,
            alignment: FloatingLabelAlignment.start,
            borderIsOutline: true,
          ),
        );
        // contentPadding (40)
        expect(tester.getTopLeft(find.text('label')).dx, 40.0);
      });

      testWidgets('center', (WidgetTester tester) async {
        await tester.pumpWidget(
          buildInputDecoratorWithFloatingLabel(
            textDirection: TextDirection.ltr,
            hasIcon: false,
            alignment: FloatingLabelAlignment.center,
            // borderIsOutline: false, (default)
          ),
        );
        // decorator (800) / 2
        expect(tester.getCenter(find.text('label')).dx, 400.0);

        await tester.pumpWidget(
          buildInputDecoratorWithFloatingLabel(
            textDirection: TextDirection.ltr,
            hasIcon: false,
            alignment: FloatingLabelAlignment.center,
            borderIsOutline: true,
          ),
        );
        // decorator (800) / 2
        expect(tester.getCenter(find.text('label')).dx, 400.0);
      });
    });

    group('RTL with icon aligned', () {
      testWidgets('start', (WidgetTester tester) async {
        await tester.pumpWidget(
          buildInputDecoratorWithFloatingLabel(
            textDirection: TextDirection.rtl,
            hasIcon: true,
            alignment: FloatingLabelAlignment.start,
            // borderIsOutline: false, (default)
          ),
        );
        // decorator (800) - icon (40) - contentPadding (40)
        expect(tester.getTopRight(find.text('label')).dx, 720.0);

        await tester.pumpWidget(
          buildInputDecoratorWithFloatingLabel(
            textDirection: TextDirection.rtl,
            hasIcon: true,
            alignment: FloatingLabelAlignment.start,
            borderIsOutline: true,
          ),
        );
        // decorator (800) - icon (40) - contentPadding (40)
        expect(tester.getTopRight(find.text('label')).dx, 720.0);
      });

      testWidgets('center', (WidgetTester tester) async {
        await tester.pumpWidget(
          buildInputDecoratorWithFloatingLabel(
            textDirection: TextDirection.rtl,
            hasIcon: true,
            alignment: FloatingLabelAlignment.center,
            // borderIsOutline: false, (default)
          ),
        );
        // (decorator (800) / icon (40)) / 2
        expect(tester.getCenter(find.text('label')).dx, 380.0);

        await tester.pumpWidget(
          buildInputDecoratorWithFloatingLabel(
            textDirection: TextDirection.rtl,
            hasIcon: true,
            alignment: FloatingLabelAlignment.center,
            borderIsOutline: true,
          ),
        );
        // (decorator (800) / icon (40)) / 2
        expect(tester.getCenter(find.text('label')).dx, 380.0);
      });
    });

    group('RTL without icon aligned', () {
      testWidgets('start', (WidgetTester tester) async {
        await tester.pumpWidget(
          buildInputDecoratorWithFloatingLabel(
            textDirection: TextDirection.rtl,
            hasIcon: false,
            alignment: FloatingLabelAlignment.start,
            // borderIsOutline: false, (default)
          ),
        );
        // decorator (800) - contentPadding (40)
        expect(tester.getTopRight(find.text('label')).dx, 760.0);

        await tester.pumpWidget(
          buildInputDecoratorWithFloatingLabel(
            textDirection: TextDirection.rtl,
            hasIcon: false,
            alignment: FloatingLabelAlignment.start,
            borderIsOutline: true,
          ),
        );
        // decorator (800) - contentPadding (40)
        expect(tester.getTopRight(find.text('label')).dx, 760.0);
      });

      testWidgets('center', (WidgetTester tester) async {
        await tester.pumpWidget(
          buildInputDecoratorWithFloatingLabel(
            textDirection: TextDirection.rtl,
            hasIcon: false,
            alignment: FloatingLabelAlignment.center,
            // borderIsOutline: false, (default)
          ),
        );
        // decorator (800) / 2
        expect(tester.getCenter(find.text('label')).dx, 400.0);

        await tester.pumpWidget(
          buildInputDecoratorWithFloatingLabel(
            textDirection: TextDirection.rtl,
            hasIcon: false,
            alignment: FloatingLabelAlignment.center,
            borderIsOutline: true,
          ),
        );
        // decorator (800) / 2
        expect(tester.getCenter(find.text('label')).dx, 400.0);
      });
    });
  });

  testWidgets('InputDecorator prefix/suffix dense layout', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        useMaterial3: useMaterial3,
        // 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), useMaterial3 ? 1.0 : 2.0);
  });

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

    // 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(
        useMaterial3: useMaterial3,
        // 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(
        useMaterial3: useMaterial3,
        // 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(
        useMaterial3: useMaterial3,
        // 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(
        useMaterial3: useMaterial3,
        // 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(
        useMaterial3: useMaterial3,
        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(
        useMaterial3: useMaterial3,
        isEmpty: true,
        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)), Size(800.0, useMaterial3 ? 50.0 : kMinInteractiveDimension)); // 45.5 bumped up to minimum.
    expect(tester.getSize(find.text('hint')).height, 10.0);
    expect(tester.getSize(find.text('label')).height,  useMaterial3 ? 14.0 : 10.0);
    expect(tester.getSize(find.text('text')).height, 10.0);
    expect(tester.getTopLeft(find.text('hint')).dy, useMaterial3 ? 27.25 : 24.75);
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 18 : 19.0);
    expect(tester.getTopLeft(find.text('text')).dy, useMaterial3 ? 27.25 : 24.75);
  });

  testWidgets('InputDecorator with empty style overrides', (WidgetTester tester) async {
    // Same as not specifying any style overrides
    await tester.pumpWidget(
      buildInputDecorator(
        useMaterial3: useMaterial3,
        // 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, useMaterial3 ? 27.25 : 28.0);
    expect(tester.getBottomLeft(find.text('text')).dy, useMaterial3 ? 43.25 : 44.0);
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? 12.75 : 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 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(
        useMaterial3: useMaterial3,
        // isFocused: false (default)
        isEmpty: true,
        decoration: const InputDecoration(
          border: OutlineInputBorder(borderSide: BorderSide.none),
          floatingLabelBehavior: FloatingLabelBehavior.never,
          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, useMaterial3 ? 21.0 : 20.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 35.0: 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(
        useMaterial3: useMaterial3,
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: const InputDecoration(
          border: OutlineInputBorder(borderSide: BorderSide.none),
          floatingLabelBehavior: FloatingLabelBehavior.never,
          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, useMaterial3 ? 21.0 : 20.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 35.0: 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(
        useMaterial3: useMaterial3,
        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, useMaterial3 ? 21.0 : 20.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 35.0: 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(
        useMaterial3: useMaterial3,
        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, useMaterial3 ? 17.0 : 16.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 31.0 : 32.0);
    expect(getBorderBottom(tester), 48.0);
    expect(getBorderWeight(tester), 1.0);
  });

  testWidgets('InputDecorationTheme style overrides', (WidgetTester tester) async {
    final TextStyle defaultStyle = TextStyle(fontFamily: 'Ahem', fontSize: useMaterial3 ? 14.0 : 16.0);
    final TextStyle labelStyle = defaultStyle.merge(const TextStyle(color: Colors.red));
    final TextStyle hintStyle = defaultStyle.merge(const TextStyle(color: Colors.green));
    final TextStyle prefixStyle = defaultStyle.merge(const TextStyle(color: Colors.blue));
    final TextStyle suffixStyle = defaultStyle.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(
        useMaterial3: useMaterial3,
        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, useMaterial3 ? 21.0 : 20.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 35.0: 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('hint')).style!.color, hintStyle.color);
    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);
    expect(getLabelStyle(tester).color, labelStyle.color);
  });

  testWidgets('InputDecorationTheme style overrides (focused)', (WidgetTester tester) async {
    final TextStyle defaultStyle = TextStyle(fontFamily: 'Ahem', fontSize: useMaterial3 ? 14.0 : 16.0);
    final TextStyle labelStyle = defaultStyle.merge(const TextStyle(color: Colors.red));
    final TextStyle floatingLabelStyle = defaultStyle.merge(const TextStyle(color: Colors.indigo));
    final TextStyle hintStyle = defaultStyle.merge(const TextStyle(color: Colors.green));
    final TextStyle prefixStyle = defaultStyle.merge(const TextStyle(color: Colors.blue));
    final TextStyle suffixStyle = defaultStyle.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(
        useMaterial3: useMaterial3,
        isEmpty: true,
        isFocused: true, // Label appears floating above input field.
        inputDecorationTheme: InputDecorationTheme(
          labelStyle: labelStyle,
          floatingLabelStyle: floatingLabelStyle,
          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, useMaterial3 ? 12.75 : 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 24.0);
    expect(getBorderBottom(tester), 56.0);
    expect(getBorderWeight(tester), 2.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('hint')).style!.color, hintStyle.color);
    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);
    expect(getLabelStyle(tester).color, floatingLabelStyle.color);
  });

  testWidgets('InputDecorator.toString()', (WidgetTester tester) async {
    const Widget child = InputDecorator(
      key: Key('key'),
      decoration: InputDecoration(),
      baseStyle: TextStyle(),
      textAlign: TextAlign.center,
      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(
        useMaterial3: useMaterial3,
        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(
        useMaterial3: useMaterial3,
        // 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, useMaterial3 ? 12.75 : 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 23.25 : 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,
        constraints: BoxConstraints(minWidth: 10, maxWidth: 20, minHeight: 30, maxHeight: 40),
      ),
    );

    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);
    expect(decoration.constraints, const BoxConstraints(minWidth: 10, maxWidth: 20, minHeight: 30, maxHeight: 40));

    // 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,
      constraints: BoxConstraints(minWidth: 10, maxWidth: 20, minHeight: 30, maxHeight: 40),
    ).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,
        constraints: BoxConstraints(minWidth: 40, maxWidth: 30, minHeight: 20, maxHeight: 10),
      ),
    );

    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);
    expect(decoration.constraints, const BoxConstraints(minWidth: 10, maxWidth: 20, minHeight: 30, maxHeight: 40));
  });

  testWidgets('InputDecorationTheme.inputDecoration with MaterialState', (WidgetTester tester) async {
    final MaterialStateTextStyle themeStyle =  MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
      return const TextStyle(color: Colors.green);
    });

    final MaterialStateTextStyle decorationStyle =  MaterialStateTextStyle.resolveWith((Set<MaterialState> states) {
      return const TextStyle(color: Colors.blue);
    });

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

    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);
    expect(decoration.constraints, const BoxConstraints(minWidth: 10, maxWidth: 20, minHeight: 30, maxHeight: 40));

    // InputDecoration (baseDecoration) defines InputDecoration properties
    final MaterialStateOutlineInputBorder border = MaterialStateOutlineInputBorder.resolveWith((Set<MaterialState> states) {
      return const OutlineInputBorder();
    });
    decoration = InputDecoration(
      labelStyle: decorationStyle,
      helperStyle: decorationStyle,
      hintStyle: decorationStyle,
      errorStyle: decorationStyle,
      isDense: false,
      contentPadding: const EdgeInsets.all(4.0),
      prefixStyle: decorationStyle,
      suffixStyle: decorationStyle,
      counterStyle: decorationStyle,
      filled: false,
      fillColor: Colors.blue,
      border: border,
      alignLabelWithHint: false,
      constraints: const BoxConstraints(minWidth: 10, maxWidth: 20, minHeight: 30, maxHeight: 40),
    ).applyDefaults(
      InputDecorationTheme(
        labelStyle: themeStyle,
        helperStyle: themeStyle,
        helperMaxLines: 5,
        hintStyle: themeStyle,
        errorStyle: themeStyle,
        errorMaxLines: 4,
        isDense: true,
        contentPadding: const EdgeInsets.all(1.0),
        prefixStyle: themeStyle,
        suffixStyle: themeStyle,
        counterStyle: themeStyle,
        filled: true,
        fillColor: Colors.red,
        focusColor: Colors.blue,
        border: InputBorder.none,
        alignLabelWithHint: true,
        constraints: const BoxConstraints(minWidth: 40, maxWidth: 30, minHeight: 20, maxHeight: 10),
      ),
    );

    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, isA<MaterialStateOutlineInputBorder>());
    expect(decoration.alignLabelWithHint, false);
    expect(decoration.constraints, const BoxConstraints(minWidth: 10, maxWidth: 20, minHeight: 30, maxHeight: 40));
  });

  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(
        useMaterial3: useMaterial3,
        // isEmpty: false (default)
        // isFocused: false (default)
        decoration: const InputDecoration(
          filled: true,
          fillColor: Color(0xFF00FF00),
          border: OutlineInputBorder(
            borderRadius: BorderRadius.all(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, 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(
        useMaterial3: useMaterial3,
        // 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 {
      // This is a regression test for https://github.com/flutter/flutter/issues/82321
      Widget buildFrame(TextDirection textDirection) {
        return MaterialApp(
          home: Scaffold(
            body: Container(
              padding: const EdgeInsets.all(16.0),
              alignment: Alignment.center,
              child: Directionality(
                textDirection: textDirection,
                child: RepaintBoundary(
                  child: InputDecorator(
                    isFocused: true,
                    isEmpty: true,
                    decoration: InputDecoration(
                      filled: true,
                      fillColor: const Color(0xFF00FF00),
                      labelText: 'label text',
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(30.0),
                        gapPadding: 0.0,
                      ),
                    ),
                  ),
                ),
              ),
            ),
          ),
        );
      }

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

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

  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 {
    final Color fillColor = useMaterial3 ? const Color(0xffffffff) : const Color(0x0A000000);
    const Color hoverColor = Color(0xFF00FF00);
    final Color disabledColor =useMaterial3 ? const Color(0x0A000000) : const  Color(0x05000000);
    final Color enabledBorderColor = useMaterial3 ? const Color(0xffffffff) : const Color(0x61000000);

    Future<void> pumpDecorator({
      required bool hovering,
      bool enabled = true,
      bool filled = true,
    }) async {
      return tester.pumpWidget(
        buildInputDecorator(
          useMaterial3: useMaterial3,
          isHovering: hovering,
          decoration: InputDecoration(
            enabled: enabled,
            filled: filled,
            hoverColor: hoverColor,
            disabledBorder: OutlineInputBorder(borderSide: BorderSide(color: disabledColor)),
            border:  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.
    final Color blendedHoverColor = useMaterial3 ? const Color(0xff000000) : const 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);
    final Color enabledBorderColor = useMaterial3 ? const Color(0xffffffff) : const Color(0x61000000);

    Future<void> pumpDecorator({
      required bool focused,
      bool enabled = true,
      bool filled = true,
    }) async {
      return tester.pumpWidget(
        buildInputDecorator(
          useMaterial3: useMaterial3,
          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: 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(
          useMaterial3: useMaterial3,
          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);
    await tester.pumpAndSettle();
    final Size labelSize= useMaterial3 ? const Size(70, 14) : const Size(80, 16);
    expect(getLabelRect(tester).topLeft, equals(Offset(12, useMaterial3 ? 21 : 20)));
    expect(getLabelRect(tester).size, equals(labelSize));

    await pumpDecorator(focused: false, empty: false);
    await tester.pumpAndSettle();
    expect(getLabelRect(tester).topLeft, equals(Offset(12, useMaterial3 ? -4.75 : -5.5)));
    expect(getLabelRect(tester).size, equals(labelSize * 0.75));

    await pumpDecorator(focused: true);
    await tester.pumpAndSettle();
    expect(getLabelRect(tester).topLeft, equals(Offset(12, useMaterial3 ? -4.75 : -5.5)));
    expect(getLabelRect(tester).size, equals(labelSize * 0.75));

    await pumpDecorator(focused: true, empty: false);
    await tester.pumpAndSettle();
    expect(getLabelRect(tester).topLeft, equals( Offset(12, useMaterial3 ? -4.75 : -5.5)));
    expect(getLabelRect(tester).size, equals(labelSize * 0.75));

    await pumpDecorator(focused: false, enabled: false);
    await tester.pumpAndSettle();
    expect(getLabelRect(tester).topLeft, equals(Offset(12, useMaterial3 ? 21 : 20)));
    expect(getLabelRect(tester).size, equals(labelSize));

    await pumpDecorator(focused: false, empty: false, enabled: false);
    await tester.pumpAndSettle();
    expect(getLabelRect(tester).topLeft, equals( Offset(12, useMaterial3 ? -4.75 : -5.5)));
    expect(getLabelRect(tester).size, equals(labelSize * 0.75));

    // Focused and disabled happens with NavigationMode.directional.
    await pumpDecorator(focused: true, enabled: false);
    await tester.pumpAndSettle();
    expect(getLabelRect(tester).topLeft, equals(Offset(12, useMaterial3 ? 21 : 20)));
    expect(getLabelRect(tester).size, equals(labelSize));

    await pumpDecorator(focused: true, empty: false, enabled: false);
    await tester.pumpAndSettle();
    expect(getLabelRect(tester).topLeft, equals( Offset(12, useMaterial3 ? -4.75 : -5.5)));
    expect(getLabelRect(tester).size, equals(labelSize * 0.75));
  });

  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 = useMaterial3 ? theme.colorScheme.onSurfaceVariant : theme.colorScheme.onSurface.withOpacity(0.38);
    final Color disabledColor = useMaterial3 ? theme.colorScheme.onSurface.withOpacity(0.12) : theme.disabledColor;
    final Color hoverColor = Color.alphaBlend(theme.hoverColor.withOpacity(0.12), enabledColor);

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

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

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

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

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

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

    // Disabled, filled
    await tester.pumpWidget(
      buildInputDecorator(
        useMaterial3: useMaterial3,
        theme: theme,
        decoration: const InputDecoration(
          enabled: false,
          filled: true,
        ),
      ),
    );
    await tester.pumpAndSettle();
    expect(getBorderColor(tester), useMaterial3 ? theme.colorScheme.onSurface.withOpacity(0.38) : 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(
        useMaterial3: useMaterial3,
        // 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(
        useMaterial3: useMaterial3,
        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(
        useMaterial3: useMaterial3,
        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(
        useMaterial3: useMaterial3,
        // 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(
        useMaterial3: useMaterial3,
        // 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(
        useMaterial3: useMaterial3,
        // 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(
        useMaterial3: useMaterial3,
        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(
        useMaterial3: useMaterial3,
        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('rounded OutlineInputBorder with zero padding just wraps the label', (WidgetTester tester) async {
    // This is a regression test for https://github.com/flutter/flutter/issues/82321
    const double borderRadius = 30.0;
    const String labelText = 'label text';

    // 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(
        useMaterial3: useMaterial3,
        decoration: InputDecoration(
          filled: true,
          fillColor: const Color(0xFF00FF00),
          labelText: labelText,
          border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(borderRadius),
            gapPadding: 0.0,
          ),
        ),
      ),
    );

    const double denominator = borderRadius * 2.0;
    const double borderRadiusScaled = borderRadius / denominator * inputDecoratorHeight;

    expect(find.text(labelText), findsOneWidget);
    final Rect labelRect = tester.getRect(find.text(labelText));

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

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

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

          // Bottom-right arc
          const Offset(inputDecoratorWidth, inputDecoratorHeight - borderRadiusScaled),
          const Offset(inputDecoratorWidth - borderRadiusScaled, inputDecoratorHeight),
          // Top-right arc
          const Offset(inputDecoratorWidth,0.0 + borderRadiusScaled),
          const Offset(inputDecoratorWidth - borderRadiusScaled, 0.0),
          // Bottom-left arc
          const Offset(0.0, inputDecoratorHeight - borderRadiusScaled),
          const Offset(0.0 + borderRadiusScaled, inputDecoratorHeight),
          // Top-left arc
          const Offset(0.0,0.0 + borderRadiusScaled),
          const Offset(0.0 + borderRadiusScaled, 0.0),

          // Gap edges
          // gap start x = radius - radius * cos(arc sweep)
          // gap start y = radius - radius * sin(arc sweep)
          const Offset(39.49999999999999, 32.284366616798906),
          Offset(39.49999999999999 + labelRect.width, 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),
        ],
      )
      ..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,
      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',
      '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(
        useMaterial3: useMaterial3,
        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, useMaterial3 ? -3.25 : -4.0);
  });

  testWidgets('InputDecorator floating label obeys floatingLabelBehavior', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        useMaterial3: useMaterial3,
        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, useMaterial3 ? 21.0 : 20.0);
  });

  testWidgets('InputDecorator hint is displayed when floatingLabelBehavior is always', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildInputDecorator(
        useMaterial3: useMaterial3,
        // 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(
            useMaterial3: useMaterial3,
            // isFocused: false (default)
            isEmpty: true,
            decoration: InputDecoration(
              labelText: longStringA,
            ),
          ),
        ),
      ),
    );

    await tester.pumpAndSettle();

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

    await tester.pumpWidget(
      Center(
        child: SizedBox(
          width: 100,
          height: 100,
          child: buildInputDecorator(
            useMaterial3: useMaterial3,
            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: Rect.fromLTWH(0, 0, 133.0, useMaterial3 ? 14.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),
                ),
                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, greaterThan(labelWidth));

    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, greaterThan(labelWidth));
    expect(getLabelRect(tester).width, lessThanOrEqualTo(floatedLabelWidth));

    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'));
  });

  testWidgets('min intrinsic height for TextField with no content padding', (WidgetTester tester) async {
    // Regression test for: https://github.com/flutter/flutter/issues/75509
    await tester.pumpWidget(MaterialApp(
      home: Material(
        child: Center(
          child: IntrinsicHeight(
            child: Column(
              children: const <Widget>[
                TextField(
                  decoration: InputDecoration(
                    labelText: 'Label Text',
                    helperText: 'Helper Text',
                    contentPadding: EdgeInsets.zero,
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    ));

    expect(tester.takeException(), isNull);
  });

  testWidgets('min intrinsic height for TextField with prefix icon', (WidgetTester tester) async {
    // Regression test for: https://github.com/flutter/flutter/issues/87403
    await tester.pumpWidget(MaterialApp(
      home: Material(
        child: Center(
          child: SizedBox(
            width: 100.0,
            child: IntrinsicHeight(
              child: Column(
                children: <Widget>[
                  TextField(
                    controller: TextEditingController(text: 'input'),
                    maxLines: null,
                    decoration: const InputDecoration(
                      prefixIcon: Icon(Icons.search),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    ));

    expect(tester.takeException(), isNull);
  });

  testWidgets('min intrinsic height for TextField with suffix icon', (WidgetTester tester) async {
    // Regression test for: https://github.com/flutter/flutter/issues/87403
    await tester.pumpWidget(MaterialApp(
      home: Material(
        child: Center(
          child: SizedBox(
            width: 100.0,
            child: IntrinsicHeight(
              child: Column(
                children: <Widget>[
                  TextField(
                    controller: TextEditingController(text: 'input'),
                    maxLines: null,
                    decoration: const InputDecoration(
                      suffixIcon: Icon(Icons.search),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    ));

    expect(tester.takeException(), isNull);
  });

  testWidgets('min intrinsic height for TextField with prefix', (WidgetTester tester) async {
    // Regression test for: https://github.com/flutter/flutter/issues/87403
    await tester.pumpWidget(MaterialApp(
      home: Material(
        child: Center(
          child: SizedBox(
            width: 100.0,
            child: IntrinsicHeight(
              child: Column(
                children: <Widget>[
                  TextField(
                    controller: TextEditingController(text: 'input'),
                    maxLines: null,
                    decoration: const InputDecoration(
                      prefix: Text('prefix'),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    ));

    expect(tester.takeException(), isNull);
  });

  testWidgets('min intrinsic height for TextField with suffix', (WidgetTester tester) async {
    // Regression test for: https://github.com/flutter/flutter/issues/87403
    await tester.pumpWidget(MaterialApp(
      home: Material(
        child: Center(
          child: SizedBox(
            width: 100.0,
            child: IntrinsicHeight(
              child: Column(
                children: <Widget>[
                  TextField(
                    controller: TextEditingController(text: 'input'),
                    maxLines: null,
                    decoration: const InputDecoration(
                      suffix: Text('suffix'),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    ));

    expect(tester.takeException(), isNull);
  });

  testWidgets('min intrinsic height for TextField with icon', (WidgetTester tester) async {
    // Regression test for: https://github.com/flutter/flutter/issues/87403
    await tester.pumpWidget(MaterialApp(
      home: Material(
        child: Center(
          child: SizedBox(
            width: 100.0,
            child: IntrinsicHeight(
              child: Column(
                children: <Widget>[
                  TextField(
                    controller: TextEditingController(text: 'input'),
                    maxLines: null,
                    decoration: const InputDecoration(
                      icon: Icon(Icons.search),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    ));

    expect(tester.takeException(), isNull);
  });

  testWidgets('InputDecorationTheme floatingLabelStyle overrides label widget styles when the widget is a text widget (focused)', (WidgetTester tester) async {
    const TextStyle style16 = TextStyle(fontFamily: 'Ahem', fontSize: 16.0);
    final TextStyle floatingLabelStyle = style16.merge(const TextStyle(color: Colors.indigo));

    // 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(
        useMaterial3: useMaterial3,
        isEmpty: true,
        isFocused: true, // Label appears floating above input field.
        inputDecorationTheme: InputDecorationTheme(
          floatingLabelStyle: floatingLabelStyle,
          // filled: false (default) - don't pad by left/right 12dps
        ),
        decoration: const InputDecoration(
          label: Text.rich(
            TextSpan(text: 'label'),
          ),
        ),
      ),
    );

    // 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('label')).dy, useMaterial3 ? 12.75 : 12.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 24.75 : 24.0);
    expect(getBorderBottom(tester), 56.0);
    expect(getBorderWeight(tester), 2.0);

    // Verify that the styles were passed along
    expect(getLabelStyle(tester).color, floatingLabelStyle.color);
  });

  testWidgets('InputDecorationTheme labelStyle overrides label widget styles when the widget is a text widget', (WidgetTester tester) async {
    final TextStyle styleDefaultSize = TextStyle(fontFamily: 'Ahem', fontSize: useMaterial3 ? 14.0 : 16.0);
    final TextStyle labelStyle = styleDefaultSize.merge(const TextStyle(color: Colors.purple));

    // 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(
        useMaterial3: useMaterial3,
        isEmpty: true, // Label appears inline, on top of the input field.
        inputDecorationTheme: InputDecorationTheme(
          labelStyle: labelStyle,
          // filled: false (default) - don't pad by left/right 12dps
        ),
        decoration: const InputDecoration(
          label: Text.rich(
            TextSpan(text: 'label'),
          ),
        ),
      ),
    );

    // 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('label')).dy, useMaterial3 ? 21.0 : 20.0);
    expect(tester.getBottomLeft(find.text('label')).dy, useMaterial3 ? 35.0 : 36.0);
    expect(getBorderBottom(tester), 56.0);
    expect(getBorderWeight(tester), 1.0);

    // Verify that the styles were passed along
    expect(getLabelStyle(tester).color, labelStyle.color);
  });

  testWidgets("InputDecorator's floating label origin no longer depends on ThemeData.fixTextFieldOutlineLabel", (WidgetTester tester) async {
    Widget buildFrame(bool fixTextFieldOutlineLabel) {
      return buildInputDecorator(
        useMaterial3: useMaterial3,
        isEmpty: true,
        theme: ThemeData.light().copyWith(
          fixTextFieldOutlineLabel: fixTextFieldOutlineLabel,
        ),
        decoration: const InputDecoration(
          labelText: 'label',
          enabledBorder: OutlineInputBorder(),
          floatingLabelBehavior: FloatingLabelBehavior.always,
        ),
      );
    }

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

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

    await tester.pumpWidget(buildFrame(true));
    await tester.pumpAndSettle();
    expect(tester.getTopLeft(find.text('label')).dy, useMaterial3 ? -4.75 : -5.5);

  });
}
}
