// 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'])
library;

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

import '../widgets/feedback_tester.dart';
import '../widgets/semantics_tester.dart';

Finder findRenderChipElement() {
  return find.byElementPredicate((Element e) => '${e.renderObject.runtimeType}' == '_RenderChip');
}

RenderBox getMaterialBox(WidgetTester tester) {
  return tester.firstRenderObject<RenderBox>(
    find.descendant(of: find.byType(RawChip), matching: find.byType(CustomPaint)),
  );
}

Material getMaterial(WidgetTester tester) {
  return tester.widget<Material>(
    find.descendant(of: find.byType(RawChip), matching: find.byType(Material)),
  );
}

IconThemeData getIconData(WidgetTester tester) {
  final IconTheme iconTheme = tester.firstWidget(
    find.descendant(of: find.byType(RawChip), matching: find.byType(IconTheme)),
  );
  return iconTheme.data;
}

DefaultTextStyle getLabelStyle(WidgetTester tester, String labelText) {
  return tester.widget(
    find.ancestor(of: find.text(labelText), matching: find.byType(DefaultTextStyle)).first,
  );
}

TextStyle? getIconStyle(WidgetTester tester, IconData icon) {
  final RichText iconRichText = tester.widget<RichText>(
    find.descendant(of: find.byIcon(icon).first, matching: find.byType(RichText)),
  );
  return iconRichText.text.style;
}

dynamic getRenderChip(WidgetTester tester) {
  if (!tester.any(findRenderChipElement())) {
    return null;
  }
  final Element element = tester.element(findRenderChipElement().first);
  return element.renderObject;
}

double getSelectProgress(WidgetTester tester) {
  // ignore: avoid_dynamic_calls
  return getRenderChip(tester)?.checkmarkAnimation?.value as double;
}

double getAvatarDrawerProgress(WidgetTester tester) {
  // ignore: avoid_dynamic_calls
  return getRenderChip(tester)?.avatarDrawerAnimation?.value as double;
}

double getDeleteDrawerProgress(WidgetTester tester) {
  // ignore: avoid_dynamic_calls
  return getRenderChip(tester)?.deleteDrawerAnimation?.value as double;
}

/// Adds the basic requirements for a Chip.
Widget wrapForChip({
  required Widget child,
  TextDirection textDirection = TextDirection.ltr,
  TextScaler textScaler = TextScaler.noScaling,
  ThemeData? theme,
}) {
  return MaterialApp(
    theme: theme,
    home: Directionality(
      textDirection: textDirection,
      child: MediaQuery(
        data: MediaQueryData(textScaler: textScaler),
        child: Material(child: child),
      ),
    ),
  );
}

/// Tests that a [Chip] that has its size constrained by its parent is
/// further constraining the size of its child, the label widget.
/// Optionally, adding an avatar or delete icon to the chip should not
/// cause the chip or label to exceed its constrained height.
Future<void> testConstrainedLabel(
  WidgetTester tester, {
  CircleAvatar? avatar,
  VoidCallback? onDeleted,
}) async {
  const labelWidth = 100.0;
  const labelHeight = 50.0;
  const chipParentWidth = 75.0;
  const chipParentHeight = 25.0;
  final Key labelKey = UniqueKey();

  await tester.pumpWidget(
    wrapForChip(
      child: Center(
        child: SizedBox(
          width: chipParentWidth,
          height: chipParentHeight,
          child: Chip(
            avatar: avatar,
            label: SizedBox(key: labelKey, width: labelWidth, height: labelHeight),
            onDeleted: onDeleted,
          ),
        ),
      ),
    ),
  );

  final Size labelSize = tester.getSize(find.byKey(labelKey));
  expect(labelSize.width, lessThan(chipParentWidth));
  expect(labelSize.height, lessThanOrEqualTo(chipParentHeight));

  final Size chipSize = tester.getSize(find.byType(Chip));
  expect(chipSize.width, chipParentWidth);
  expect(chipSize.height, chipParentHeight);
}

void doNothing() {}

Widget chipWithOptionalDeleteButton({
  Key? deleteButtonKey,
  Key? labelKey,
  required bool deletable,
  TextDirection textDirection = TextDirection.ltr,
  String? chipTooltip,
  String? deleteButtonTooltipMessage,
  double? size,
  VoidCallback? onPressed = doNothing,
  ThemeData? themeData,
}) {
  return wrapForChip(
    textDirection: textDirection,
    theme: themeData,
    child: Wrap(
      children: <Widget>[
        RawChip(
          tooltip: chipTooltip,
          onPressed: onPressed,
          onDeleted: deletable ? doNothing : null,
          deleteIcon: Icon(key: deleteButtonKey, size: size, Icons.close),
          deleteButtonTooltipMessage: deleteButtonTooltipMessage,
          label: Text(
            deletable ? 'Chip with Delete Button' : 'Chip without Delete Button',
            key: labelKey,
          ),
        ),
      ],
    ),
  );
}

bool offsetsAreClose(Offset a, Offset b) => (a - b).distance < 1.0;
bool radiiAreClose(double a, double b) => (a - b).abs() < 1.0;

// Ripple pattern matches if there exists at least one ripple
// with the [expectedCenter] and [expectedRadius].
// This ensures the existence of a ripple.
PaintPattern ripplePattern(Offset expectedCenter, double expectedRadius) {
  return paints..something((Symbol method, List<dynamic> arguments) {
    if (method != #drawCircle) {
      return false;
    }
    final center = arguments[0] as Offset;
    final radius = arguments[1] as double;
    return offsetsAreClose(center, expectedCenter) && radiiAreClose(radius, expectedRadius);
  });
}

// Unique ripple pattern matches if there does not exist ripples
// other than ones with the [expectedCenter] and [expectedRadius].
// This ensures the nonexistence of two different ripples.
PaintPattern uniqueRipplePattern(Offset expectedCenter, double expectedRadius) {
  return paints..everything((Symbol method, List<dynamic> arguments) {
    if (method != #drawCircle) {
      return true;
    }
    final center = arguments[0] as Offset;
    final radius = arguments[1] as double;
    if (offsetsAreClose(center, expectedCenter) && radiiAreClose(radius, expectedRadius)) {
      return true;
    }
    throw '''
              Expected: center == $expectedCenter, radius == $expectedRadius
              Found: center == $center radius == $radius''';
  });
}

// Finds any container of a tooltip.
Finder findTooltipContainer(String tooltipText) {
  return find.ancestor(of: find.text(tooltipText), matching: find.byType(Container));
}

void main() {
  testWidgets('M3 Chip defaults', (WidgetTester tester) async {
    late TextTheme textTheme;
    final lightTheme = ThemeData();
    final darkTheme = ThemeData.dark();

    Widget buildFrame(ThemeData theme) {
      return MaterialApp(
        theme: theme,
        home: Scaffold(
          body: Center(
            child: Builder(
              builder: (BuildContext context) {
                textTheme = Theme.of(context).textTheme;
                return Chip(
                  avatar: const CircleAvatar(child: Text('A')),
                  label: const Text('Chip A'),
                  onDeleted: () {},
                );
              },
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildFrame(lightTheme));
    expect(getMaterial(tester).color, null);
    expect(getMaterial(tester).elevation, 0);
    expect(
      getMaterial(tester).shape,
      RoundedRectangleBorder(
        side: BorderSide(color: lightTheme.colorScheme.outlineVariant),
        borderRadius: const BorderRadius.all(Radius.circular(8.0)),
      ),
    );
    expect(getIconData(tester).color, lightTheme.colorScheme.primary);
    expect(getIconData(tester).opacity, null);
    expect(getIconData(tester).size, 18);

    TextStyle labelStyle = getLabelStyle(tester, 'Chip A').style;
    expect(labelStyle.color, lightTheme.colorScheme.onSurfaceVariant);
    expect(labelStyle.fontFamily, textTheme.labelLarge?.fontFamily);
    expect(labelStyle.fontFamilyFallback, textTheme.labelLarge?.fontFamilyFallback);
    expect(labelStyle.fontFeatures, textTheme.labelLarge?.fontFeatures);
    expect(labelStyle.fontSize, textTheme.labelLarge?.fontSize);
    expect(labelStyle.fontStyle, textTheme.labelLarge?.fontStyle);
    expect(labelStyle.fontWeight, textTheme.labelLarge?.fontWeight);
    expect(labelStyle.height, textTheme.labelLarge?.height);
    expect(labelStyle.inherit, textTheme.labelLarge?.inherit);
    expect(labelStyle.leadingDistribution, textTheme.labelLarge?.leadingDistribution);
    expect(labelStyle.letterSpacing, textTheme.labelLarge?.letterSpacing);
    expect(labelStyle.overflow, textTheme.labelLarge?.overflow);
    expect(labelStyle.textBaseline, textTheme.labelLarge?.textBaseline);
    expect(labelStyle.wordSpacing, textTheme.labelLarge?.wordSpacing);

    await tester.pumpWidget(buildFrame(darkTheme));
    await tester.pumpAndSettle(); // Theme transition animation
    expect(getMaterial(tester).color, null);
    expect(getMaterial(tester).elevation, 0);
    expect(
      getMaterial(tester).shape,
      RoundedRectangleBorder(
        side: BorderSide(color: darkTheme.colorScheme.outlineVariant),
        borderRadius: const BorderRadius.all(Radius.circular(8.0)),
      ),
    );
    expect(getIconData(tester).color, darkTheme.colorScheme.primary);
    expect(getIconData(tester).opacity, null);
    expect(getIconData(tester).size, 18);

    labelStyle = getLabelStyle(tester, 'Chip A').style;
    expect(labelStyle.color, darkTheme.colorScheme.onSurfaceVariant);
    expect(labelStyle.fontFamily, textTheme.labelLarge?.fontFamily);
    expect(labelStyle.fontFamilyFallback, textTheme.labelLarge?.fontFamilyFallback);
    expect(labelStyle.fontFeatures, textTheme.labelLarge?.fontFeatures);
    expect(labelStyle.fontSize, textTheme.labelLarge?.fontSize);
    expect(labelStyle.fontStyle, textTheme.labelLarge?.fontStyle);
    expect(labelStyle.fontWeight, textTheme.labelLarge?.fontWeight);
    expect(labelStyle.height, textTheme.labelLarge?.height);
    expect(labelStyle.inherit, textTheme.labelLarge?.inherit);
    expect(labelStyle.leadingDistribution, textTheme.labelLarge?.leadingDistribution);
    expect(labelStyle.letterSpacing, textTheme.labelLarge?.letterSpacing);
    expect(labelStyle.overflow, textTheme.labelLarge?.overflow);
    expect(labelStyle.textBaseline, textTheme.labelLarge?.textBaseline);
    expect(labelStyle.wordSpacing, textTheme.labelLarge?.wordSpacing);
  });

  testWidgets('Chip control test', (WidgetTester tester) async {
    final feedback = FeedbackTester();
    final deletedChipLabels = <String>[];
    await tester.pumpWidget(
      wrapForChip(
        child: Column(
          children: <Widget>[
            Chip(
              avatar: const CircleAvatar(child: Text('A')),
              label: const Text('Chip A'),
              onDeleted: () {
                deletedChipLabels.add('A');
              },
              deleteButtonTooltipMessage: 'Delete chip A',
            ),
            Chip(
              avatar: const CircleAvatar(child: Text('B')),
              label: const Text('Chip B'),
              onDeleted: () {
                deletedChipLabels.add('B');
              },
              deleteButtonTooltipMessage: 'Delete chip B',
            ),
          ],
        ),
      ),
    );

    expect(tester.widget(find.byTooltip('Delete chip A')), isNotNull);
    expect(tester.widget(find.byTooltip('Delete chip B')), isNotNull);

    expect(feedback.clickSoundCount, 0);

    expect(deletedChipLabels, isEmpty);
    await tester.tap(find.byTooltip('Delete chip A'));
    expect(deletedChipLabels, equals(<String>['A']));

    await tester.pumpAndSettle(const Duration(seconds: 1));
    expect(feedback.clickSoundCount, 1);

    await tester.tap(find.byTooltip('Delete chip B'));
    expect(deletedChipLabels, equals(<String>['A', 'B']));

    await tester.pumpAndSettle(const Duration(seconds: 1));
    expect(feedback.clickSoundCount, 2);

    feedback.dispose();
  });

  testWidgets('Chip does not constrain size of label widget if it does not exceed '
      'the available space', (WidgetTester tester) async {
    const labelWidth = 50.0;
    const labelHeight = 30.0;
    final Key labelKey = UniqueKey();

    await tester.pumpWidget(
      wrapForChip(
        child: Center(
          child: SizedBox.square(
            dimension: 500.0,
            child: Column(
              children: <Widget>[
                Chip(
                  label: SizedBox(key: labelKey, width: labelWidth, height: labelHeight),
                ),
              ],
            ),
          ),
        ),
      ),
    );

    final Size labelSize = tester.getSize(find.byKey(labelKey));
    expect(labelSize.width, labelWidth);
    expect(labelSize.height, labelHeight);
  });

  testWidgets('Chip constrains the size of the label widget when it exceeds the '
      'available space', (WidgetTester tester) async {
    await testConstrainedLabel(tester);
  });

  testWidgets('Chip constrains the size of the label widget when it exceeds the '
      'available space and the avatar is present', (WidgetTester tester) async {
    await testConstrainedLabel(tester, avatar: const CircleAvatar(child: Text('A')));
  });

  testWidgets('Chip constrains the size of the label widget when it exceeds the '
      'available space and the delete icon is present', (WidgetTester tester) async {
    await testConstrainedLabel(tester, onDeleted: () {});
  });

  testWidgets('Chip constrains the size of the label widget when it exceeds the '
      'available space and both avatar and delete icons are present', (WidgetTester tester) async {
    await testConstrainedLabel(
      tester,
      avatar: const CircleAvatar(child: Text('A')),
      onDeleted: () {},
    );
  });

  testWidgets('Chip constrains the avatar, label, and delete icons to the bounds of '
      'the chip when it exceeds the available space', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/11523
    Widget chipBuilder(String text, {Widget? avatar, VoidCallback? onDeleted}) {
      return MaterialApp(
        home: Scaffold(
          body: SizedBox(
            width: 150,
            child: Column(
              children: <Widget>[Chip(avatar: avatar, label: Text(text), onDeleted: onDeleted)],
            ),
          ),
        ),
      );
    }

    void chipRectContains(Rect chipRect, Rect rect) {
      expect(chipRect.contains(rect.topLeft), true);
      expect(chipRect.contains(rect.topRight), true);
      expect(chipRect.contains(rect.bottomLeft), true);
      expect(chipRect.contains(rect.bottomRight), true);
    }

    Rect chipRect;
    Rect avatarRect;
    Rect labelRect;
    Rect deleteIconRect;
    const text = 'Very long text that will be clipped';

    await tester.pumpWidget(chipBuilder(text));

    chipRect = tester.getRect(find.byType(Chip));
    labelRect = tester.getRect(find.text(text));
    chipRectContains(chipRect, labelRect);

    await tester.pumpWidget(chipBuilder(text, avatar: const CircleAvatar(child: Text('A'))));
    await tester.pumpAndSettle();

    chipRect = tester.getRect(find.byType(Chip));
    avatarRect = tester.getRect(find.byType(CircleAvatar));
    chipRectContains(chipRect, avatarRect);

    labelRect = tester.getRect(find.text(text));
    chipRectContains(chipRect, labelRect);

    await tester.pumpWidget(
      chipBuilder(
        text,
        avatar: const CircleAvatar(child: Text('A')),
        onDeleted: () {},
      ),
    );
    await tester.pumpAndSettle();

    chipRect = tester.getRect(find.byType(Chip));
    avatarRect = tester.getRect(find.byType(CircleAvatar));
    chipRectContains(chipRect, avatarRect);

    labelRect = tester.getRect(find.text(text));
    chipRectContains(chipRect, labelRect);

    deleteIconRect = tester.getRect(find.byIcon(Icons.cancel));
    chipRectContains(chipRect, deleteIconRect);
  });

  testWidgets('Material2 - Chip in row works ok', (WidgetTester tester) async {
    const style = TextStyle(fontSize: 10.0);
    await tester.pumpWidget(
      wrapForChip(
        theme: ThemeData(useMaterial3: false),
        child: const Row(
          children: <Widget>[Chip(label: Text('Test'), labelStyle: style)],
        ),
      ),
    );
    expect(tester.getSize(find.byType(Text)), const Size(40.0, 10.0));
    expect(tester.getSize(find.byType(Chip)), const Size(64.0, 48.0));
    await tester.pumpWidget(
      wrapForChip(
        child: const Row(
          children: <Widget>[
            Flexible(
              child: Chip(label: Text('Test'), labelStyle: style),
            ),
          ],
        ),
      ),
    );
    expect(tester.getSize(find.byType(Text)), const Size(40.0, 10.0));
    expect(tester.getSize(find.byType(Chip)), const Size(64.0, 48.0));
    await tester.pumpWidget(
      wrapForChip(
        child: const Row(
          children: <Widget>[
            Expanded(
              child: Chip(label: Text('Test'), labelStyle: style),
            ),
          ],
        ),
      ),
    );
    expect(tester.getSize(find.byType(Text)), const Size(40.0, 10.0));
    expect(tester.getSize(find.byType(Chip)), const Size(800.0, 48.0));
  });

  testWidgets('Material3 - Chip in row works ok', (WidgetTester tester) async {
    const style = TextStyle(fontSize: 10.0);
    await tester.pumpWidget(
      wrapForChip(
        child: const Row(
          children: <Widget>[Chip(label: Text('Test'), labelStyle: style)],
        ),
      ),
    );
    expect(tester.getSize(find.byType(Text)).width, closeTo(40.4, 0.01));
    expect(tester.getSize(find.byType(Text)).height, equals(14.0));
    expect(tester.getSize(find.byType(Chip)).width, closeTo(74.4, 0.01));
    expect(tester.getSize(find.byType(Chip)).height, equals(48.0));
    await tester.pumpWidget(
      wrapForChip(
        child: const Row(
          children: <Widget>[
            Flexible(
              child: Chip(label: Text('Test'), labelStyle: style),
            ),
          ],
        ),
      ),
    );
    expect(tester.getSize(find.byType(Text)).width, closeTo(40.4, 0.01));
    expect(tester.getSize(find.byType(Text)).height, equals(14.0));
    expect(tester.getSize(find.byType(Chip)).width, closeTo(74.4, 0.01));
    expect(tester.getSize(find.byType(Chip)).height, equals(48.0));
    await tester.pumpWidget(
      wrapForChip(
        child: const Row(
          children: <Widget>[
            Expanded(
              child: Chip(label: Text('Test'), labelStyle: style),
            ),
          ],
        ),
      ),
    );
    expect(tester.getSize(find.byType(Text)).width, closeTo(40.4, 0.01));
    expect(tester.getSize(find.byType(Text)).height, equals(14.0));
    expect(tester.getSize(find.byType(Chip)), const Size(800.0, 48.0));
  });

  testWidgets('Material2 - Chip responds to materialTapTargetSize', (WidgetTester tester) async {
    await tester.pumpWidget(
      wrapForChip(
        theme: ThemeData(useMaterial3: false),
        child: const Column(
          children: <Widget>[
            Chip(label: Text('X'), materialTapTargetSize: MaterialTapTargetSize.padded),
            Chip(label: Text('X'), materialTapTargetSize: MaterialTapTargetSize.shrinkWrap),
          ],
        ),
      ),
    );
    expect(tester.getSize(find.byType(Chip).first), const Size(48.0, 48.0));
    expect(tester.getSize(find.byType(Chip).last), const Size(38.0, 32.0));
  });

  testWidgets('Material3 - Chip responds to materialTapTargetSize', (WidgetTester tester) async {
    await tester.pumpWidget(
      wrapForChip(
        child: const Column(
          children: <Widget>[
            Chip(label: Text('X'), materialTapTargetSize: MaterialTapTargetSize.padded),
            Chip(label: Text('X'), materialTapTargetSize: MaterialTapTargetSize.shrinkWrap),
          ],
        ),
      ),
    );

    expect(tester.getSize(find.byType(Chip).first).width, closeTo(48.1, 0.01));
    expect(tester.getSize(find.byType(Chip).first).height, equals(48.0));
    expect(tester.getSize(find.byType(Chip).last).width, closeTo(48.1, 0.01));
    expect(tester.getSize(find.byType(Chip).last).height, equals(38.0));
  });

  testWidgets('Delete button tap target is the right proportion of the chip', (
    WidgetTester tester,
  ) async {
    final deleteKey = UniqueKey();
    var calledDelete = false;
    await tester.pumpWidget(
      wrapForChip(
        child: Column(
          children: <Widget>[
            Chip(
              label: const Text('Really Long Label'),
              deleteIcon: Icon(Icons.delete, key: deleteKey),
              onDeleted: () {
                calledDelete = true;
              },
            ),
          ],
        ),
      ),
    );

    // Test correct tap target size.
    await tester.tapAt(
      tester.getCenter(find.byKey(deleteKey)) - const Offset(18.0, 0.0),
    ); // Half the width of the delete button + right label padding.
    await tester.pump();
    expect(calledDelete, isTrue);
    calledDelete = false;

    // Test incorrect tap target size.
    await tester.tapAt(tester.getCenter(find.byKey(deleteKey)) - const Offset(19.0, 0.0));
    await tester.pump();
    expect(calledDelete, isFalse);
    calledDelete = false;

    await tester.pumpWidget(
      wrapForChip(
        child: Column(
          children: <Widget>[
            Chip(
              label: const SizedBox(), // Short label
              deleteIcon: Icon(Icons.cancel, key: deleteKey),
              onDeleted: () {
                calledDelete = true;
              },
            ),
          ],
        ),
      ),
    );

    // Chip width is 48 with padding, 40 without padding, so halfway is at 20. Cancel
    // icon is 24x24, so since 24 > 20 the split location should be halfway across the
    // chip, which is at 12 + 8 = 20 from the right side. Since the split is just
    // slightly less than 50%, 8 from the center of the delete button should hit the
    // chip, not the delete button.
    await tester.tapAt(tester.getCenter(find.byKey(deleteKey)) - const Offset(7.0, 0.0));
    await tester.pump();
    expect(calledDelete, isTrue);
    calledDelete = false;

    await tester.tapAt(tester.getCenter(find.byKey(deleteKey)) - const Offset(8.0, 0.0));
    await tester.pump();
    expect(calledDelete, isFalse);
  });

  testWidgets('Chip elements are ordered horizontally for locale', (WidgetTester tester) async {
    final iconKey = UniqueKey();
    late final OverlayEntry entry;
    addTearDown(
      () => entry
        ..remove()
        ..dispose(),
    );
    final Widget test = Overlay(
      initialEntries: <OverlayEntry>[
        entry = OverlayEntry(
          builder: (BuildContext context) {
            return Material(
              child: Chip(
                deleteIcon: Icon(Icons.delete, key: iconKey),
                onDeleted: () {},
                label: const Text('ABC'),
              ),
            );
          },
        ),
      ],
    );

    await tester.pumpWidget(wrapForChip(child: test, textDirection: TextDirection.rtl));
    await tester.pumpAndSettle(const Duration(milliseconds: 500));
    expect(
      tester.getCenter(find.text('ABC')).dx,
      greaterThan(tester.getCenter(find.byKey(iconKey)).dx),
    );
    await tester.pumpWidget(wrapForChip(child: test));
    await tester.pumpAndSettle(const Duration(milliseconds: 500));
    expect(
      tester.getCenter(find.text('ABC')).dx,
      lessThan(tester.getCenter(find.byKey(iconKey)).dx),
    );
  });

  testWidgets('Material2 - Chip responds to textScaleFactor', (WidgetTester tester) async {
    await tester.pumpWidget(
      wrapForChip(
        theme: ThemeData(useMaterial3: false),
        child: const Column(
          children: <Widget>[
            Chip(
              avatar: CircleAvatar(child: Text('A')),
              label: Text('Chip A'),
            ),
            Chip(
              avatar: CircleAvatar(child: Text('B')),
              label: Text('Chip B'),
            ),
          ],
        ),
      ),
    );

    expect(tester.getSize(find.text('Chip A')), const Size(84.0, 14.0));
    expect(tester.getSize(find.text('Chip B')), const Size(84.0, 14.0));
    expect(tester.getSize(find.byType(Chip).first), const Size(132.0, 48.0));
    expect(tester.getSize(find.byType(Chip).last), const Size(132.0, 48.0));

    await tester.pumpWidget(
      wrapForChip(
        textScaler: const TextScaler.linear(3.0),
        child: const Column(
          children: <Widget>[
            Chip(
              avatar: CircleAvatar(child: Text('A')),
              label: Text('Chip A'),
            ),
            Chip(
              avatar: CircleAvatar(child: Text('B')),
              label: Text('Chip B'),
            ),
          ],
        ),
      ),
    );

    expect(tester.getSize(find.text('Chip A')), const Size(252.0, 42.0));
    expect(tester.getSize(find.text('Chip B')), const Size(252.0, 42.0));
    expect(tester.getSize(find.byType(Chip).first), const Size(310.0, 50.0));
    expect(tester.getSize(find.byType(Chip).last), const Size(310.0, 50.0));

    // Check that individual text scales are taken into account.
    await tester.pumpWidget(
      wrapForChip(
        child: const Column(
          children: <Widget>[
            Chip(
              avatar: CircleAvatar(child: Text('A')),
              label: Text('Chip A', textScaleFactor: 3.0),
            ),
            Chip(
              avatar: CircleAvatar(child: Text('B')),
              label: Text('Chip B'),
            ),
          ],
        ),
      ),
    );

    expect(tester.getSize(find.text('Chip A')), const Size(252.0, 42.0));
    expect(tester.getSize(find.text('Chip B')), const Size(84.0, 14.0));
    expect(tester.getSize(find.byType(Chip).first), const Size(318.0, 50.0));
    expect(tester.getSize(find.byType(Chip).last), const Size(132.0, 48.0));
  });

  testWidgets('Material3 - Chip responds to textScaleFactor', (WidgetTester tester) async {
    await tester.pumpWidget(
      wrapForChip(
        child: const Column(
          children: <Widget>[
            Chip(
              avatar: CircleAvatar(child: Text('A')),
              label: Text('Chip A'),
            ),
            Chip(
              avatar: CircleAvatar(child: Text('B')),
              label: Text('Chip B'),
            ),
          ],
        ),
      ),
    );

    expect(tester.getSize(find.text('Chip A')).width, closeTo(84.5, 0.1));
    expect(tester.getSize(find.text('Chip A')).height, equals(20.0));
    expect(tester.getSize(find.text('Chip B')).width, closeTo(84.5, 0.1));
    expect(tester.getSize(find.text('Chip B')).height, equals(20.0));

    await tester.pumpWidget(
      wrapForChip(
        textScaler: const TextScaler.linear(3.0),
        child: const Column(
          children: <Widget>[
            Chip(
              avatar: CircleAvatar(child: Text('A')),
              label: Text('Chip A'),
            ),
            Chip(
              avatar: CircleAvatar(child: Text('B')),
              label: Text('Chip B'),
            ),
          ],
        ),
      ),
    );

    expect(tester.getSize(find.text('Chip A')).width, closeTo(252.6, 0.1));
    expect(tester.getSize(find.text('Chip A')).height, equals(60.0));
    expect(tester.getSize(find.text('Chip B')).width, closeTo(252.6, 0.1));
    expect(tester.getSize(find.text('Chip B')).height, equals(60.0));
    expect(tester.getSize(find.byType(Chip).first).width, closeTo(338.6, 0.1));
    expect(tester.getSize(find.byType(Chip).first).height, equals(78.0));
    expect(tester.getSize(find.byType(Chip).last).width, closeTo(338.6, 0.1));
    expect(tester.getSize(find.byType(Chip).last).height, equals(78.0));

    // Check that individual text scales are taken into account.
    await tester.pumpWidget(
      wrapForChip(
        child: const Column(
          children: <Widget>[
            Chip(
              avatar: CircleAvatar(child: Text('A')),
              label: Text('Chip A', textScaleFactor: 3.0),
            ),
            Chip(
              avatar: CircleAvatar(child: Text('B')),
              label: Text('Chip B'),
            ),
          ],
        ),
      ),
    );

    expect(tester.getSize(find.text('Chip A')).width, closeTo(252.6, 0.01));
    expect(tester.getSize(find.text('Chip A')).height, equals(60.0));
    expect(tester.getSize(find.text('Chip B')).width, closeTo(84.59, 0.01));
    expect(tester.getSize(find.text('Chip B')).height, equals(20.0));
    expect(tester.getSize(find.byType(Chip).first).width, closeTo(346.6, 0.01));
    expect(tester.getSize(find.byType(Chip).first).height, equals(78.0));
    expect(tester.getSize(find.byType(Chip).last).width, closeTo(138.59, 0.01));
    expect(tester.getSize(find.byType(Chip).last).height, equals(48.0));
  });

  testWidgets('Material2 - Labels can be non-text widgets', (WidgetTester tester) async {
    final Key keyA = GlobalKey();
    final Key keyB = GlobalKey();
    await tester.pumpWidget(
      wrapForChip(
        theme: ThemeData(useMaterial3: false),
        child: Column(
          children: <Widget>[
            Chip(
              avatar: const CircleAvatar(child: Text('A')),
              label: Text('Chip A', key: keyA),
            ),
            Chip(
              avatar: const CircleAvatar(child: Text('B')),
              label: SizedBox(key: keyB, width: 10.0, height: 10.0),
            ),
          ],
        ),
      ),
    );

    expect(tester.getSize(find.byKey(keyA)), const Size(84.0, 14.0));
    expect(tester.getSize(find.byKey(keyB)), const Size(10.0, 10.0));
    expect(tester.getSize(find.byType(Chip).first), const Size(132.0, 48.0));
    expect(tester.getSize(find.byType(Chip).last), const Size(58.0, 48.0));
  });

  testWidgets('Material3 - Labels can be non-text widgets', (WidgetTester tester) async {
    final Key keyA = GlobalKey();
    final Key keyB = GlobalKey();
    await tester.pumpWidget(
      wrapForChip(
        child: Column(
          children: <Widget>[
            Chip(
              avatar: const CircleAvatar(child: Text('A')),
              label: Text('Chip A', key: keyA),
            ),
            Chip(
              avatar: const CircleAvatar(child: Text('B')),
              label: SizedBox(key: keyB, width: 10.0, height: 10.0),
            ),
          ],
        ),
      ),
    );

    expect(tester.getSize(find.byKey(keyA)).width, moreOrLessEquals(84.5, epsilon: 0.1));
    expect(tester.getSize(find.byKey(keyA)).height, equals(20.0));
    expect(tester.getSize(find.byKey(keyB)), const Size(10.0, 10.0));
    expect(tester.getSize(find.byType(Chip).first).width, moreOrLessEquals(138.5, epsilon: 0.1));
    expect(tester.getSize(find.byType(Chip).first).height, equals(48.0));
    expect(tester.getSize(find.byType(Chip).last), const Size(60.0, 48.0));
  });

  testWidgets('Avatars can be non-circle avatar widgets', (WidgetTester tester) async {
    final Key keyA = GlobalKey();
    await tester.pumpWidget(
      wrapForChip(
        child: Column(
          children: <Widget>[
            Chip(
              avatar: SizedBox(key: keyA, width: 20.0, height: 20.0),
              label: const Text('Chip A'),
            ),
          ],
        ),
      ),
    );

    expect(tester.getSize(find.byKey(keyA)), equals(const Size(20.0, 20.0)));
  });

  testWidgets('Delete icons can be non-icon widgets', (WidgetTester tester) async {
    final Key keyA = GlobalKey();
    await tester.pumpWidget(
      wrapForChip(
        child: Column(
          children: <Widget>[
            Chip(
              deleteIcon: SizedBox(key: keyA, width: 20.0, height: 20.0),
              label: const Text('Chip A'),
              onDeleted: () {},
            ),
          ],
        ),
      ),
    );

    expect(tester.getSize(find.byKey(keyA)), equals(const Size(20.0, 20.0)));
  });

  testWidgets('Chip padding - LTR', (WidgetTester tester) async {
    final GlobalKey keyA = GlobalKey();
    final GlobalKey keyB = GlobalKey();

    late final OverlayEntry entry;
    addTearDown(
      () => entry
        ..remove()
        ..dispose(),
    );
    await tester.pumpWidget(
      wrapForChip(
        child: Overlay(
          initialEntries: <OverlayEntry>[
            entry = OverlayEntry(
              builder: (BuildContext context) {
                return Material(
                  child: Center(
                    child: Chip(
                      avatar: Placeholder(key: keyA),
                      label: SizedBox(key: keyB, width: 40.0, height: 40.0),
                      onDeleted: () {},
                    ),
                  ),
                );
              },
            ),
          ],
        ),
      ),
    );
    expect(tester.getTopLeft(find.byKey(keyA)), const Offset(332.0, 280.0));
    expect(tester.getBottomRight(find.byKey(keyA)), const Offset(372.0, 320.0));
    expect(tester.getTopLeft(find.byKey(keyB)), const Offset(380.0, 280.0));
    expect(tester.getBottomRight(find.byKey(keyB)), const Offset(420.0, 320.0));
    expect(tester.getTopLeft(find.byType(Icon)), const Offset(439.0, 291.0));
    expect(tester.getBottomRight(find.byType(Icon)), const Offset(457.0, 309.0));
  });

  testWidgets('Chip padding - RTL', (WidgetTester tester) async {
    final GlobalKey keyA = GlobalKey();
    final GlobalKey keyB = GlobalKey();

    late final OverlayEntry entry;
    addTearDown(
      () => entry
        ..remove()
        ..dispose(),
    );

    await tester.pumpWidget(
      wrapForChip(
        textDirection: TextDirection.rtl,
        child: Overlay(
          initialEntries: <OverlayEntry>[
            entry = OverlayEntry(
              builder: (BuildContext context) {
                return Material(
                  child: Center(
                    child: Chip(
                      avatar: Placeholder(key: keyA),
                      label: SizedBox(key: keyB, width: 40.0, height: 40.0),
                      onDeleted: () {},
                    ),
                  ),
                );
              },
            ),
          ],
        ),
      ),
    );

    expect(tester.getTopLeft(find.byKey(keyA)), const Offset(428.0, 280.0));
    expect(tester.getBottomRight(find.byKey(keyA)), const Offset(468.0, 320.0));
    expect(tester.getTopLeft(find.byKey(keyB)), const Offset(380.0, 280.0));
    expect(tester.getBottomRight(find.byKey(keyB)), const Offset(420.0, 320.0));
    expect(tester.getTopLeft(find.byType(Icon)), const Offset(343.0, 291.0));
    expect(tester.getBottomRight(find.byType(Icon)), const Offset(361.0, 309.0));
  });

  testWidgets('Material2 - Avatar drawer works as expected on RawChip', (
    WidgetTester tester,
  ) async {
    final GlobalKey labelKey = GlobalKey();
    Future<void> pushChip({Widget? avatar}) async {
      return tester.pumpWidget(
        wrapForChip(
          theme: ThemeData(useMaterial3: false),
          child: Wrap(
            children: <Widget>[
              RawChip(
                avatar: avatar,
                label: Text('Chip', key: labelKey),
                shape: const StadiumBorder(),
              ),
            ],
          ),
        ),
      );
    }

    // No avatar
    await pushChip();
    expect(tester.getSize(find.byType(RawChip)), equals(const Size(80.0, 48.0)));
    final GlobalKey avatarKey = GlobalKey();

    // Add an avatar
    await pushChip(
      avatar: Container(key: avatarKey, color: const Color(0xff000000), width: 40.0, height: 40.0),
    );
    // Avatar drawer should start out closed.
    expect(tester.getSize(find.byType(RawChip)), equals(const Size(80.0, 48.0)));
    expect(tester.getSize(find.byKey(avatarKey)), equals(const Size(24.0, 24.0)));
    expect(tester.getTopLeft(find.byKey(avatarKey)), equals(const Offset(-20.0, 12.0)));
    expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(12.0, 17.0)));

    await tester.pump(const Duration(milliseconds: 20));
    // Avatar drawer should start expanding.
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(81.2, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(avatarKey)), equals(const Size(24.0, 24.0)));
    expect(tester.getTopLeft(find.byKey(avatarKey)).dx, moreOrLessEquals(-18.8, epsilon: 0.1));
    expect(tester.getTopLeft(find.byKey(labelKey)).dx, moreOrLessEquals(13.2, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(86.7, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(avatarKey)), equals(const Size(24.0, 24.0)));
    expect(tester.getTopLeft(find.byKey(avatarKey)).dx, moreOrLessEquals(-13.3, epsilon: 0.1));
    expect(tester.getTopLeft(find.byKey(labelKey)).dx, moreOrLessEquals(18.6, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(94.7, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(avatarKey)), equals(const Size(24.0, 24.0)));
    expect(tester.getTopLeft(find.byKey(avatarKey)).dx, moreOrLessEquals(-5.3, epsilon: 0.1));
    expect(tester.getTopLeft(find.byKey(labelKey)).dx, moreOrLessEquals(26.7, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(99.5, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(avatarKey)), equals(const Size(24.0, 24.0)));
    expect(tester.getTopLeft(find.byKey(avatarKey)).dx, moreOrLessEquals(-0.5, epsilon: 0.1));
    expect(tester.getTopLeft(find.byKey(labelKey)).dx, moreOrLessEquals(31.5, epsilon: 0.1));

    // Wait for being done with animation, and make sure it didn't change
    // height.
    await tester.pumpAndSettle(const Duration(milliseconds: 200));
    expect(tester.getSize(find.byType(RawChip)), equals(const Size(104.0, 48.0)));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(avatarKey)), equals(const Size(24.0, 24.0)));
    expect(tester.getTopLeft(find.byKey(avatarKey)), equals(const Offset(4.0, 12.0)));
    expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(36.0, 17.0)));

    // Remove the avatar again
    await pushChip();
    // Avatar drawer should start out open.
    expect(tester.getSize(find.byType(RawChip)), equals(const Size(104.0, 48.0)));
    expect(tester.getSize(find.byKey(avatarKey)), equals(const Size(24.0, 24.0)));
    expect(tester.getTopLeft(find.byKey(avatarKey)), equals(const Offset(4.0, 12.0)));
    expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(36.0, 17.0)));

    await tester.pump(const Duration(milliseconds: 20));
    // Avatar drawer should start contracting.
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(102.9, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(avatarKey)), equals(const Size(24.0, 24.0)));
    expect(tester.getTopLeft(find.byKey(avatarKey)).dx, moreOrLessEquals(2.9, epsilon: 0.1));
    expect(tester.getTopLeft(find.byKey(labelKey)).dx, moreOrLessEquals(34.9, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(98.0, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(avatarKey)), equals(const Size(24.0, 24.0)));
    expect(tester.getTopLeft(find.byKey(avatarKey)).dx, moreOrLessEquals(-2.0, epsilon: 0.1));
    expect(tester.getTopLeft(find.byKey(labelKey)).dx, moreOrLessEquals(30.0, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(84.1, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(avatarKey)), equals(const Size(24.0, 24.0)));
    expect(tester.getTopLeft(find.byKey(avatarKey)).dx, moreOrLessEquals(-15.9, epsilon: 0.1));
    expect(tester.getTopLeft(find.byKey(labelKey)).dx, moreOrLessEquals(16.1, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(80.0, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(avatarKey)), equals(const Size(24.0, 24.0)));
    expect(tester.getTopLeft(find.byKey(avatarKey)).dx, moreOrLessEquals(-20.0, epsilon: 0.1));
    expect(tester.getTopLeft(find.byKey(labelKey)).dx, moreOrLessEquals(12.0, epsilon: 0.1));

    // Wait for being done with animation, make sure it didn't change
    // height, and make sure that the avatar is no longer drawn.
    await tester.pumpAndSettle(const Duration(milliseconds: 200));
    expect(tester.getSize(find.byType(RawChip)), equals(const Size(80.0, 48.0)));
    expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(12.0, 17.0)));
    expect(find.byKey(avatarKey), findsNothing);
  });

  testWidgets('Material3 - Avatar drawer works as expected on RawChip', (
    WidgetTester tester,
  ) async {
    final GlobalKey labelKey = GlobalKey();
    Future<void> pushChip({Widget? avatar}) async {
      return tester.pumpWidget(
        wrapForChip(
          child: Wrap(
            children: <Widget>[
              RawChip(
                avatar: avatar,
                label: Text('Chip', key: labelKey),
                shape: const StadiumBorder(),
              ),
            ],
          ),
        ),
      );
    }

    // No avatar
    await pushChip();
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(90.4, epsilon: 0.1));
    final GlobalKey avatarKey = GlobalKey();

    // Add an avatar
    await pushChip(
      avatar: Container(key: avatarKey, color: const Color(0xff000000), width: 40.0, height: 40.0),
    );
    // Avatar drawer should start out closed.
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(90.4, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(avatarKey)), equals(const Size(20.0, 20.0)));
    expect(tester.getTopLeft(find.byKey(avatarKey)), equals(const Offset(-11.0, 14.0)));
    expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(17.0, 14.0)));

    await tester.pump(const Duration(milliseconds: 20));
    // Avatar drawer should start expanding.
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(91.3, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(avatarKey)), equals(const Size(20.0, 20.0)));
    expect(tester.getTopLeft(find.byKey(avatarKey)).dx, moreOrLessEquals(-10, epsilon: 0.1));
    expect(tester.getTopLeft(find.byKey(labelKey)).dx, moreOrLessEquals(17.9, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(95.9, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(avatarKey)), equals(const Size(20.0, 20.0)));
    expect(tester.getTopLeft(find.byKey(avatarKey)).dx, moreOrLessEquals(-5.4, epsilon: 0.1));
    expect(tester.getTopLeft(find.byKey(labelKey)).dx, moreOrLessEquals(22.5, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(102.6, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(avatarKey)), equals(const Size(20.0, 20.0)));
    expect(tester.getTopLeft(find.byKey(avatarKey)).dx, moreOrLessEquals(1.2, epsilon: 0.1));
    expect(tester.getTopLeft(find.byKey(labelKey)).dx, moreOrLessEquals(29.2, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(106.6, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(avatarKey)), equals(const Size(20.0, 20.0)));
    expect(tester.getTopLeft(find.byKey(avatarKey)).dx, moreOrLessEquals(5.2, epsilon: 0.1));
    expect(tester.getTopLeft(find.byKey(labelKey)).dx, moreOrLessEquals(33.2, epsilon: 0.1));

    // Wait for being done with animation, and make sure it didn't change
    // height.
    await tester.pumpAndSettle(const Duration(milliseconds: 200));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(110.4, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(avatarKey)), equals(const Size(20.0, 20.0)));
    expect(tester.getTopLeft(find.byKey(avatarKey)), equals(const Offset(9.0, 14.0)));
    expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(37.0, 14.0)));

    // Remove the avatar again
    await pushChip();
    // Avatar drawer should start out open.
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(110.4, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(avatarKey)), equals(const Size(20.0, 20.0)));
    expect(tester.getTopLeft(find.byKey(avatarKey)), equals(const Offset(9.0, 14.0)));
    expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(37.0, 14.0)));

    await tester.pump(const Duration(milliseconds: 20));
    // Avatar drawer should start contracting.
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(109.5, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(avatarKey)), equals(const Size(20.0, 20.0)));
    expect(tester.getTopLeft(find.byKey(avatarKey)).dx, moreOrLessEquals(8.1, epsilon: 0.1));
    expect(tester.getTopLeft(find.byKey(labelKey)).dx, moreOrLessEquals(36.1, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(105.4, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(avatarKey)), equals(const Size(20.0, 20.0)));
    expect(tester.getTopLeft(find.byKey(avatarKey)).dx, moreOrLessEquals(4.0, epsilon: 0.1));
    expect(tester.getTopLeft(find.byKey(labelKey)).dx, moreOrLessEquals(32.0, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(93.7, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(avatarKey)), equals(const Size(20.0, 20.0)));
    expect(tester.getTopLeft(find.byKey(avatarKey)).dx, moreOrLessEquals(-7.6, epsilon: 0.1));
    expect(tester.getTopLeft(find.byKey(labelKey)).dx, moreOrLessEquals(20.3, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(90.4, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(avatarKey)), equals(const Size(20.0, 20.0)));
    expect(tester.getTopLeft(find.byKey(avatarKey)).dx, moreOrLessEquals(-11.0, epsilon: 0.1));
    expect(tester.getTopLeft(find.byKey(labelKey)).dx, moreOrLessEquals(17.0, epsilon: 0.1));

    // Wait for being done with animation, make sure it didn't change
    // height, and make sure that the avatar is no longer drawn.
    await tester.pumpAndSettle(const Duration(milliseconds: 200));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(90.4, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(17.0, 14.0)));
    expect(find.byKey(avatarKey), findsNothing);
  });

  testWidgets('Material2 - Delete button drawer works as expected on RawChip', (
    WidgetTester tester,
  ) async {
    const labelKey = Key('label');
    const deleteButtonKey = Key('delete');
    var wasDeleted = false;
    Future<void> pushChip({bool deletable = false}) async {
      return tester.pumpWidget(
        wrapForChip(
          theme: ThemeData(useMaterial3: false),
          child: Wrap(
            children: <Widget>[
              StatefulBuilder(
                builder: (BuildContext context, StateSetter setState) {
                  return RawChip(
                    onDeleted: deletable
                        ? () {
                            setState(() {
                              wasDeleted = true;
                            });
                          }
                        : null,
                    deleteIcon: Container(
                      width: 40.0,
                      height: 40.0,
                      color: Colors.blue,
                      key: deleteButtonKey,
                    ),
                    label: const Text('Chip', key: labelKey),
                    shape: const StadiumBorder(),
                  );
                },
              ),
            ],
          ),
        ),
      );
    }

    // No delete button
    await pushChip();
    expect(tester.getSize(find.byType(RawChip)), equals(const Size(80.0, 48.0)));

    // Add a delete button
    await pushChip(deletable: true);
    // Delete button drawer should start out closed.
    expect(tester.getSize(find.byType(RawChip)), equals(const Size(80.0, 48.0)));
    expect(tester.getSize(find.byKey(deleteButtonKey)), equals(const Size(24.0, 24.0)));
    expect(tester.getTopLeft(find.byKey(deleteButtonKey)), equals(const Offset(52.0, 12.0)));
    expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(12.0, 17.0)));

    await tester.pump(const Duration(milliseconds: 20));
    // Delete button drawer should start expanding.
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(81.2, epsilon: 0.1));
    expect(tester.getSize(find.byKey(deleteButtonKey)), equals(const Size(24.0, 24.0)));
    expect(tester.getTopLeft(find.byKey(deleteButtonKey)).dx, moreOrLessEquals(53.2, epsilon: 0.1));
    expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(12.0, 17.0)));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(86.7, epsilon: 0.1));
    expect(tester.getSize(find.byKey(deleteButtonKey)), equals(const Size(24.0, 24.0)));
    expect(tester.getTopLeft(find.byKey(deleteButtonKey)).dx, moreOrLessEquals(58.7, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(94.7, epsilon: 0.1));
    expect(tester.getSize(find.byKey(deleteButtonKey)), equals(const Size(24.0, 24.0)));
    expect(tester.getTopLeft(find.byKey(deleteButtonKey)).dx, moreOrLessEquals(66.7, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(99.5, epsilon: 0.1));
    expect(tester.getSize(find.byKey(deleteButtonKey)), equals(const Size(24.0, 24.0)));
    expect(tester.getTopLeft(find.byKey(deleteButtonKey)).dx, moreOrLessEquals(71.5, epsilon: 0.1));

    // Wait for being done with animation, and make sure it didn't change
    // height.
    await tester.pumpAndSettle(const Duration(milliseconds: 200));
    expect(tester.getSize(find.byType(RawChip)), equals(const Size(104.0, 48.0)));
    expect(tester.getSize(find.byKey(deleteButtonKey)), equals(const Size(24.0, 24.0)));
    expect(tester.getTopLeft(find.byKey(deleteButtonKey)), equals(const Offset(76.0, 12.0)));
    expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(12.0, 17.0)));

    // Test the tap work for the delete button, but not the rest of the chip.
    expect(wasDeleted, isFalse);
    await tester.tap(find.byKey(labelKey));
    expect(wasDeleted, isFalse);
    await tester.tap(find.byKey(deleteButtonKey));
    expect(wasDeleted, isTrue);

    // Remove the delete button again
    await pushChip();
    // Delete button drawer should start out open.
    expect(tester.getSize(find.byType(RawChip)), equals(const Size(104.0, 48.0)));
    expect(tester.getSize(find.byKey(deleteButtonKey)), equals(const Size(24.0, 24.0)));
    expect(tester.getTopLeft(find.byKey(deleteButtonKey)), equals(const Offset(76.0, 12.0)));
    expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(12.0, 17.0)));

    await tester.pump(const Duration(milliseconds: 20));
    // Delete button drawer should start contracting.
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(103.8, epsilon: 0.1));
    expect(tester.getSize(find.byKey(deleteButtonKey)), equals(const Size(24.0, 24.0)));
    expect(tester.getTopLeft(find.byKey(deleteButtonKey)).dx, moreOrLessEquals(75.8, epsilon: 0.1));
    expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(12.0, 17.0)));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(102.9, epsilon: 0.1));
    expect(tester.getSize(find.byKey(deleteButtonKey)), equals(const Size(24.0, 24.0)));
    expect(tester.getTopLeft(find.byKey(deleteButtonKey)).dx, moreOrLessEquals(74.9, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(101.0, epsilon: 0.1));
    expect(tester.getSize(find.byKey(deleteButtonKey)), equals(const Size(24.0, 24.0)));
    expect(tester.getTopLeft(find.byKey(deleteButtonKey)).dx, moreOrLessEquals(73.0, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(97.5, epsilon: 0.1));
    expect(tester.getSize(find.byKey(deleteButtonKey)), equals(const Size(24.0, 24.0)));
    expect(tester.getTopLeft(find.byKey(deleteButtonKey)).dx, moreOrLessEquals(69.5, epsilon: 0.1));

    // Wait for being done with animation, make sure it didn't change
    // height, and make sure that the delete button is no longer drawn.
    await tester.pumpAndSettle(const Duration(milliseconds: 200));
    expect(tester.getSize(find.byType(RawChip)), equals(const Size(80.0, 48.0)));
    expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(12.0, 17.0)));
    expect(find.byKey(deleteButtonKey), findsNothing);
  });

  testWidgets('Material3 - Delete button drawer works as expected on RawChip', (
    WidgetTester tester,
  ) async {
    const labelKey = Key('label');
    const deleteButtonKey = Key('delete');
    var wasDeleted = false;
    Future<void> pushChip({bool deletable = false}) async {
      return tester.pumpWidget(
        wrapForChip(
          child: Wrap(
            children: <Widget>[
              StatefulBuilder(
                builder: (BuildContext context, StateSetter setState) {
                  return RawChip(
                    onDeleted: deletable
                        ? () {
                            setState(() {
                              wasDeleted = true;
                            });
                          }
                        : null,
                    deleteIcon: Container(
                      width: 40.0,
                      height: 40.0,
                      color: Colors.blue,
                      key: deleteButtonKey,
                    ),
                    label: const Text('Chip', key: labelKey),
                    shape: const StadiumBorder(),
                  );
                },
              ),
            ],
          ),
        ),
      );
    }

    // No delete button
    await pushChip();
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(90.4, epsilon: 0.01));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));

    // Add a delete button
    await pushChip(deletable: true);
    // Delete button drawer should start out closed.
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(90.4, epsilon: 0.01));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(deleteButtonKey)), equals(const Size(20.0, 20.0)));
    expect(
      tester.getTopLeft(find.byKey(deleteButtonKey)),
      offsetMoreOrLessEquals(const Offset(61.4, 14.0), epsilon: 0.01),
    );
    expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(17.0, 14.0)));

    await tester.pump(const Duration(milliseconds: 20));
    // Delete button drawer should start expanding.
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(91.3, epsilon: 0.1));
    expect(tester.getSize(find.byKey(deleteButtonKey)), equals(const Size(20.0, 20.0)));
    expect(tester.getTopLeft(find.byKey(deleteButtonKey)).dx, moreOrLessEquals(62.3, epsilon: 0.1));
    expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(17.0, 14.0)));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(95.9, epsilon: 0.1));
    expect(tester.getSize(find.byKey(deleteButtonKey)), equals(const Size(20.0, 20.0)));
    expect(tester.getTopLeft(find.byKey(deleteButtonKey)).dx, moreOrLessEquals(66.9, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(102.6, epsilon: 0.1));
    expect(tester.getSize(find.byKey(deleteButtonKey)), equals(const Size(20.0, 20.0)));
    expect(tester.getTopLeft(find.byKey(deleteButtonKey)).dx, moreOrLessEquals(73.6, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(106.6, epsilon: 0.1));
    expect(tester.getSize(find.byKey(deleteButtonKey)), equals(const Size(20.0, 20.0)));
    expect(tester.getTopLeft(find.byKey(deleteButtonKey)).dx, moreOrLessEquals(77.6, epsilon: 0.1));

    // Wait for being done with animation, and make sure it didn't change
    // height.
    await tester.pumpAndSettle(const Duration(milliseconds: 200));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(110.4, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(deleteButtonKey)), equals(const Size(20.0, 20.0)));
    expect(
      tester.getTopLeft(find.byKey(deleteButtonKey)),
      offsetMoreOrLessEquals(const Offset(81.4, 14.0), epsilon: 0.01),
    );
    expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(17.0, 14.0)));

    // Test the tap work for the delete button, but not the rest of the chip.
    expect(wasDeleted, isFalse);
    await tester.tap(find.byKey(labelKey));
    expect(wasDeleted, isFalse);
    await tester.tap(find.byKey(deleteButtonKey));
    expect(wasDeleted, isTrue);

    // Remove the delete button again
    await pushChip();
    // Delete button drawer should start out open.
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(110.4, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getSize(find.byKey(deleteButtonKey)), equals(const Size(20.0, 20.0)));
    expect(
      tester.getTopLeft(find.byKey(deleteButtonKey)),
      offsetMoreOrLessEquals(const Offset(81.4, 14.0), epsilon: 0.01),
    );
    expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(17.0, 14.0)));

    await tester.pump(const Duration(milliseconds: 20));
    // Delete button drawer should start contracting.
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(110.1, epsilon: 0.1));
    expect(tester.getSize(find.byKey(deleteButtonKey)), equals(const Size(20.0, 20.0)));
    expect(tester.getTopLeft(find.byKey(deleteButtonKey)).dx, moreOrLessEquals(81.1, epsilon: 0.1));
    expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(17.0, 14.0)));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(109.4, epsilon: 0.1));
    expect(tester.getSize(find.byKey(deleteButtonKey)), equals(const Size(20.0, 20.0)));
    expect(tester.getTopLeft(find.byKey(deleteButtonKey)).dx, moreOrLessEquals(80.4, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(107.9, epsilon: 0.1));
    expect(tester.getSize(find.byKey(deleteButtonKey)), equals(const Size(20.0, 20.0)));
    expect(tester.getTopLeft(find.byKey(deleteButtonKey)).dx, moreOrLessEquals(78.9, epsilon: 0.1));

    await tester.pump(const Duration(milliseconds: 20));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(104.9, epsilon: 0.1));
    expect(tester.getSize(find.byKey(deleteButtonKey)), equals(const Size(20.0, 20.0)));
    expect(tester.getTopLeft(find.byKey(deleteButtonKey)).dx, moreOrLessEquals(75.9, epsilon: 0.1));

    // Wait for being done with animation, make sure it didn't change
    // height, and make sure that the delete button is no longer drawn.
    await tester.pumpAndSettle(const Duration(milliseconds: 200));
    expect(tester.getSize(find.byType(RawChip)).width, moreOrLessEquals(90.4, epsilon: 0.1));
    expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
    expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(17.0, 14.0)));
    expect(find.byKey(deleteButtonKey), findsNothing);
  });

  testWidgets('Delete button takes up at most half of the chip', (WidgetTester tester) async {
    final chipKey = UniqueKey();
    var chipPressed = false;
    var deletePressed = false;

    await tester.pumpWidget(
      wrapForChip(
        child: Wrap(
          children: <Widget>[
            RawChip(
              key: chipKey,
              onPressed: () {
                chipPressed = true;
              },
              onDeleted: () {
                deletePressed = true;
              },
              label: const Text(''),
            ),
          ],
        ),
      ),
    );

    await tester.tapAt(tester.getCenter(find.byKey(chipKey)));
    await tester.pump();
    expect(chipPressed, isTrue);
    expect(deletePressed, isFalse);
    chipPressed = false;

    await tester.tapAt(tester.getCenter(find.byKey(chipKey)) + const Offset(1.0, 0.0));
    await tester.pump();
    expect(chipPressed, isFalse);
    expect(deletePressed, isTrue);
  });

  testWidgets('Material2 - Chip creates centered, unique ripple when label is tapped', (
    WidgetTester tester,
  ) async {
    final labelKey = UniqueKey();
    final deleteButtonKey = UniqueKey();

    await tester.pumpWidget(
      chipWithOptionalDeleteButton(
        themeData: ThemeData(useMaterial3: false),
        labelKey: labelKey,
        deleteButtonKey: deleteButtonKey,
        deletable: true,
      ),
    );

    final RenderBox box = getMaterialBox(tester);

    // Taps at a location close to the center of the label.
    final Offset centerOfLabel = tester.getCenter(find.byKey(labelKey));
    final Offset tapLocationOfLabel = centerOfLabel + const Offset(-10, -10);
    final TestGesture gesture = await tester.startGesture(tapLocationOfLabel);
    await tester.pump();

    // Waits for 100 ms.
    await tester.pump(const Duration(milliseconds: 100));

    // There should be one unique, centered ink ripple.
    expect(box, ripplePattern(const Offset(163.0, 6.0), 20.9));
    expect(box, uniqueRipplePattern(const Offset(163.0, 6.0), 20.9));

    // There should be no tooltip.
    expect(findTooltipContainer('Delete'), findsNothing);

    // Waits for 100 ms again.
    await tester.pump(const Duration(milliseconds: 100));

    // The ripple should grow, with the same center.
    expect(box, ripplePattern(const Offset(163.0, 6.0), 41.8));
    expect(box, uniqueRipplePattern(const Offset(163.0, 6.0), 41.8));

    // There should be no tooltip.
    expect(findTooltipContainer('Delete'), findsNothing);

    // Waits for a very long time.
    await tester.pumpAndSettle();

    // There should still be no tooltip.
    expect(findTooltipContainer('Delete'), findsNothing);

    await gesture.up();
  });

  testWidgets('Material3 - Chip creates centered, unique sparkle when label is tapped', (
    WidgetTester tester,
  ) async {
    final labelKey = UniqueKey();
    final deleteButtonKey = UniqueKey();

    await tester.pumpWidget(
      chipWithOptionalDeleteButton(
        labelKey: labelKey,
        deleteButtonKey: deleteButtonKey,
        deletable: true,
      ),
    );

    // Taps at a location close to the center of the label.
    final Offset centerOfLabel = tester.getCenter(find.byKey(labelKey));
    final Offset tapLocationOfLabel = centerOfLabel + const Offset(-10, -10);
    final TestGesture gesture = await tester.startGesture(tapLocationOfLabel);
    await tester.pump();

    // Waits for 100 ms.
    await tester.pump(const Duration(milliseconds: 100));

    // There should be one unique, centered ink sparkle.
    await expectLater(
      find.byType(RawChip),
      matchesGoldenFile('chip.label_tapped.ink_sparkle.0.png'),
    );

    // There should be no tooltip.
    expect(findTooltipContainer('Delete'), findsNothing);

    // Waits for 100 ms again.
    await tester.pump(const Duration(milliseconds: 100));

    // The sparkle should grow, with the same center.
    await expectLater(
      find.byType(RawChip),
      matchesGoldenFile('chip.label_tapped.ink_sparkle.1.png'),
    );

    // There should be no tooltip.
    expect(findTooltipContainer('Delete'), findsNothing);

    // Waits for a very long time.
    await tester.pumpAndSettle();

    // There should still be no tooltip.
    expect(findTooltipContainer('Delete'), findsNothing);

    await gesture.up();
  });

  testWidgets('Delete button is focusable', (WidgetTester tester) async {
    final GlobalKey labelKey = GlobalKey();
    final GlobalKey deleteButtonKey = GlobalKey();

    await tester.pumpWidget(
      chipWithOptionalDeleteButton(
        labelKey: labelKey,
        deleteButtonKey: deleteButtonKey,
        deletable: true,
      ),
    );

    Focus.of(deleteButtonKey.currentContext!).requestFocus();
    await tester.pump();

    // They shouldn't have the same focus node.
    expect(
      Focus.of(deleteButtonKey.currentContext!),
      isNot(equals(Focus.of(labelKey.currentContext!))),
    );
    expect(Focus.of(deleteButtonKey.currentContext!).hasFocus, isTrue);
    expect(Focus.of(deleteButtonKey.currentContext!).hasPrimaryFocus, isTrue);
    // Delete button is a child widget of the Chip, so the Chip should have focus if
    // the delete button does.
    expect(Focus.of(labelKey.currentContext!).hasFocus, isTrue);
    expect(Focus.of(labelKey.currentContext!).hasPrimaryFocus, isFalse);

    Focus.of(labelKey.currentContext!).requestFocus();
    await tester.pump();

    expect(Focus.of(deleteButtonKey.currentContext!).hasFocus, isFalse);
    expect(Focus.of(deleteButtonKey.currentContext!).hasPrimaryFocus, isFalse);
    expect(Focus.of(labelKey.currentContext!).hasFocus, isTrue);
    expect(Focus.of(labelKey.currentContext!).hasPrimaryFocus, isTrue);
  });

  testWidgets('Material2 - Delete button creates centered, unique ripple when tapped', (
    WidgetTester tester,
  ) async {
    final labelKey = UniqueKey();
    final deleteButtonKey = UniqueKey();

    await tester.pumpWidget(
      chipWithOptionalDeleteButton(
        themeData: ThemeData(useMaterial3: false),
        labelKey: labelKey,
        deleteButtonKey: deleteButtonKey,
        deletable: true,
      ),
    );

    final RenderBox box = getMaterialBox(tester);

    // Taps at a location close to the center of the delete icon.
    final Offset centerOfDeleteButton = tester.getCenter(find.byKey(deleteButtonKey));
    final Offset tapLocationOfDeleteButton = centerOfDeleteButton + const Offset(-10, -10);
    final TestGesture gesture = await tester.startGesture(tapLocationOfDeleteButton);
    await tester.pump();

    // Waits for 200 ms.
    await tester.pump(const Duration(milliseconds: 100));
    await tester.pump(const Duration(milliseconds: 100));

    // There should be one unique ink ripple.
    expect(box, ripplePattern(Offset.zero, 1.44));
    expect(box, uniqueRipplePattern(Offset.zero, 1.44));

    // There should be no tooltip.
    expect(findTooltipContainer('Delete'), findsNothing);

    // Waits for 200 ms again.
    await tester.pump(const Duration(milliseconds: 100));
    await tester.pump(const Duration(milliseconds: 100));

    // The ripple should grow, but the center should move,
    // Towards the center of the delete icon.
    expect(box, ripplePattern(const Offset(2.0, 2.0), 4.32));
    expect(box, uniqueRipplePattern(const Offset(2.0, 2.0), 4.32));

    // There should be no tooltip.
    expect(findTooltipContainer('Delete'), findsNothing);

    // Waits for a very long time.
    // This is pressing and holding the delete button.
    await tester.pumpAndSettle();

    // There should be a tooltip.
    expect(findTooltipContainer('Delete'), findsOneWidget);

    await gesture.up();
  });

  testWidgets('Material3 - Delete button creates non-centered, unique sparkle when tapped', (
    WidgetTester tester,
  ) async {
    final labelKey = UniqueKey();
    final deleteButtonKey = UniqueKey();

    await tester.pumpWidget(
      chipWithOptionalDeleteButton(
        labelKey: labelKey,
        deleteButtonKey: deleteButtonKey,
        deletable: true,
        size: 18.0,
      ),
    );

    // Taps at a location close to the center of the delete icon.
    final Offset centerOfDeleteButton = tester.getCenter(find.byKey(deleteButtonKey));
    final Offset tapLocationOfDeleteButton = centerOfDeleteButton + const Offset(-10, -10);
    final TestGesture gesture = await tester.startGesture(tapLocationOfDeleteButton);
    await tester.pump();

    // Waits for 200 ms.
    await tester.pump(const Duration(milliseconds: 100));
    await tester.pump(const Duration(milliseconds: 100));

    // There should be one unique ink sparkle.
    await expectLater(
      find.byType(RawChip),
      matchesGoldenFile('chip.delete_button_tapped.ink_sparkle.0.png'),
    );

    // There should be no tooltip.
    expect(findTooltipContainer('Delete'), findsNothing);

    // Waits for 200 ms again.
    await tester.pump(const Duration(milliseconds: 100));
    await tester.pump(const Duration(milliseconds: 100));

    // The sparkle should grow, but the center should move,
    // towards the center of the delete icon.
    await expectLater(
      find.byType(RawChip),
      matchesGoldenFile('chip.delete_button_tapped.ink_sparkle.1.png'),
    );

    // There should be no tooltip.
    expect(findTooltipContainer('Delete'), findsNothing);

    // Waits for a very long time.
    // This is pressing and holding the delete button.
    await tester.pumpAndSettle();

    // There should be a tooltip.
    expect(findTooltipContainer('Delete'), findsOneWidget);

    await gesture.up();
  });

  testWidgets(
    'Material2 - Delete button in a chip with null onPressed creates ripple when tapped',
    (WidgetTester tester) async {
      final labelKey = UniqueKey();
      final deleteButtonKey = UniqueKey();

      await tester.pumpWidget(
        chipWithOptionalDeleteButton(
          themeData: ThemeData(useMaterial3: false),
          labelKey: labelKey,
          onPressed: null,
          deleteButtonKey: deleteButtonKey,
          deletable: true,
        ),
      );

      final RenderBox box = getMaterialBox(tester);

      // Taps at a location close to the center of the delete icon.
      final Offset centerOfDeleteButton = tester.getCenter(find.byKey(deleteButtonKey));
      final Offset tapLocationOfDeleteButton = centerOfDeleteButton + const Offset(-10, -10);
      final TestGesture gesture = await tester.startGesture(tapLocationOfDeleteButton);
      await tester.pump();

      // Waits for 200 ms.
      await tester.pump(const Duration(milliseconds: 100));
      await tester.pump(const Duration(milliseconds: 100));

      // There should be one unique ink ripple.
      expect(box, ripplePattern(Offset.zero, 1.44));
      expect(box, uniqueRipplePattern(Offset.zero, 1.44));

      // There should be no tooltip.
      expect(findTooltipContainer('Delete'), findsNothing);

      // Waits for 200 ms again.
      await tester.pump(const Duration(milliseconds: 100));
      await tester.pump(const Duration(milliseconds: 100));

      // The ripple should grow, but the center should move,
      // Towards the center of the delete icon.
      expect(box, ripplePattern(const Offset(2.0, 2.0), 4.32));
      expect(box, uniqueRipplePattern(const Offset(2.0, 2.0), 4.32));

      // There should be no tooltip.
      expect(findTooltipContainer('Delete'), findsNothing);

      // Waits for a very long time.
      // This is pressing and holding the delete button.
      await tester.pumpAndSettle();

      // There should be a tooltip.
      expect(findTooltipContainer('Delete'), findsOneWidget);

      await gesture.up();
    },
  );

  testWidgets(
    'Material3 - Delete button in a chip with null onPressed creates sparkle when tapped',
    (WidgetTester tester) async {
      final labelKey = UniqueKey();
      final deleteButtonKey = UniqueKey();

      await tester.pumpWidget(
        chipWithOptionalDeleteButton(
          labelKey: labelKey,
          onPressed: null,
          deleteButtonKey: deleteButtonKey,
          deletable: true,
          size: 18.0,
        ),
      );

      // Taps at a location close to the center of the delete icon.
      final Offset centerOfDeleteButton = tester.getCenter(find.byKey(deleteButtonKey));
      final Offset tapLocationOfDeleteButton = centerOfDeleteButton + const Offset(-10, -10);
      final TestGesture gesture = await tester.startGesture(tapLocationOfDeleteButton);
      await tester.pump();

      // Waits for 200 ms.
      await tester.pump(const Duration(milliseconds: 100));
      await tester.pump(const Duration(milliseconds: 100));

      // There should be one unique ink sparkle.
      await expectLater(
        find.byType(RawChip),
        matchesGoldenFile('chip.delete_button_tapped.disabled.ink_sparkle.0.png'),
      );

      // There should be no tooltip.
      expect(findTooltipContainer('Delete'), findsNothing);

      // Waits for 200 ms again.
      await tester.pump(const Duration(milliseconds: 100));
      await tester.pump(const Duration(milliseconds: 100));

      // The sparkle should grow, but the center should move,
      // towards the center of the delete icon.
      await expectLater(
        find.byType(RawChip),
        matchesGoldenFile('chip.delete_button_tapped.disabled.ink_sparkle.1.png'),
      );

      // There should be no tooltip.
      expect(findTooltipContainer('Delete'), findsNothing);

      // Waits for a very long time.
      // This is pressing and holding the delete button.
      await tester.pumpAndSettle();

      // There should be a tooltip.
      expect(findTooltipContainer('Delete'), findsOneWidget);

      await gesture.up();
    },
  );

  testWidgets('RTL delete button responds to tap on the left of the chip', (
    WidgetTester tester,
  ) async {
    // Creates an RTL chip with a delete button.
    final labelKey = UniqueKey();
    final deleteButtonKey = UniqueKey();

    await tester.pumpWidget(
      chipWithOptionalDeleteButton(
        labelKey: labelKey,
        deleteButtonKey: deleteButtonKey,
        deletable: true,
        textDirection: TextDirection.rtl,
      ),
    );

    // Taps at a location close to the center of the delete icon,
    // Which is on the left side of the chip.
    final Offset topLeftOfInkWell = tester.getTopLeft(find.byType(InkWell).first);
    final Offset tapLocation = topLeftOfInkWell + const Offset(8, 8);
    final TestGesture gesture = await tester.startGesture(tapLocation);
    await tester.pump();

    await tester.pumpAndSettle();

    // The existence of a 'Delete' tooltip indicates the delete icon is tapped,
    // Instead of the label.
    expect(findTooltipContainer('Delete'), findsOneWidget);

    await gesture.up();
  });

  testWidgets('Material2 - Chip without delete button creates correct ripple', (
    WidgetTester tester,
  ) async {
    // Creates a chip with a delete button.
    final labelKey = UniqueKey();

    await tester.pumpWidget(
      chipWithOptionalDeleteButton(
        themeData: ThemeData(useMaterial3: false),
        labelKey: labelKey,
        deletable: false,
      ),
    );

    final RenderBox box = getMaterialBox(tester);

    // Taps at a location close to the bottom-right corner of the chip.
    final Offset bottomRightOfInkWell = tester.getBottomRight(find.byType(InkWell));
    final Offset tapLocation = bottomRightOfInkWell + const Offset(-10, -10);
    final TestGesture gesture = await tester.startGesture(tapLocation);
    await tester.pump();

    // Waits for 100 ms.
    await tester.pump(const Duration(milliseconds: 100));

    // There should be exactly one ink-creating widget.
    expect(find.byType(InkWell), findsOneWidget);
    expect(find.byType(InkResponse), findsNothing);

    // There should be one unique, centered ink ripple.
    expect(box, ripplePattern(const Offset(378.0, 22.0), 37.9));
    expect(box, uniqueRipplePattern(const Offset(378.0, 22.0), 37.9));

    // There should be no tooltip.
    expect(findTooltipContainer('Delete'), findsNothing);

    // Waits for 100 ms again.
    await tester.pump(const Duration(milliseconds: 100));

    // The ripple should grow, with the same center.
    // This indicates that the tap is not on a delete icon.
    expect(box, ripplePattern(const Offset(378.0, 22.0), 75.8));
    expect(box, uniqueRipplePattern(const Offset(378.0, 22.0), 75.8));

    // There should be no tooltip.
    expect(findTooltipContainer('Delete'), findsNothing);

    // Waits for a very long time.
    await tester.pumpAndSettle();

    // There should still be no tooltip.
    // This indicates that the tap is not on a delete icon.
    expect(findTooltipContainer('Delete'), findsNothing);

    await gesture.up();
  });

  testWidgets('Material3 - Chip without delete button creates correct sparkle', (
    WidgetTester tester,
  ) async {
    // Creates a chip with a delete button.
    final labelKey = UniqueKey();

    await tester.pumpWidget(chipWithOptionalDeleteButton(labelKey: labelKey, deletable: false));

    // Taps at a location close to the bottom-right corner of the chip.
    final Offset bottomRightOfInkWell = tester.getBottomRight(find.byType(InkWell));
    final Offset tapLocation = bottomRightOfInkWell + const Offset(-10, -10);
    final TestGesture gesture = await tester.startGesture(tapLocation);
    await tester.pump();

    // Waits for 100 ms.
    await tester.pump(const Duration(milliseconds: 100));

    // There should be exactly one ink-creating widget.
    expect(find.byType(InkWell), findsOneWidget);
    expect(find.byType(InkResponse), findsNothing);

    // There should be one unique, centered ink sparkle.
    await expectLater(
      find.byType(RawChip),
      matchesGoldenFile('chip.without_delete_button.ink_sparkle.0.png'),
    );

    // There should be no tooltip.
    expect(findTooltipContainer('Delete'), findsNothing);

    // Waits for 100 ms again.
    await tester.pump(const Duration(milliseconds: 100));

    // The sparkle should grow, with the same center.
    // This indicates that the tap is not on a delete icon.
    await expectLater(
      find.byType(RawChip),
      matchesGoldenFile('chip.without_delete_button.ink_sparkle.1.png'),
    );

    // There should be no tooltip.
    expect(findTooltipContainer('Delete'), findsNothing);

    // Waits for a very long time.
    await tester.pumpAndSettle();

    // There should still be no tooltip.
    // This indicates that the tap is not on a delete icon.
    expect(findTooltipContainer('Delete'), findsNothing);

    await gesture.up();
  });

  testWidgets('Material2 - Selection with avatar works as expected on RawChip', (
    WidgetTester tester,
  ) async {
    var selected = false;
    final labelKey = UniqueKey();
    Future<void> pushChip({Widget? avatar, bool selectable = false}) async {
      return tester.pumpWidget(
        wrapForChip(
          theme: ThemeData(useMaterial3: false),
          child: Wrap(
            children: <Widget>[
              StatefulBuilder(
                builder: (BuildContext context, StateSetter setState) {
                  return RawChip(
                    avatar: avatar,
                    onSelected: selectable
                        ? (bool value) {
                            setState(() {
                              selected = value;
                            });
                          }
                        : null,
                    selected: selected,
                    label: Text('Long Chip Label', key: labelKey),
                    shape: const StadiumBorder(),
                  );
                },
              ),
            ],
          ),
        ),
      );
    }

    // With avatar, but not selectable.
    final avatarKey = UniqueKey();
    await pushChip(avatar: SizedBox(width: 40.0, height: 40.0, key: avatarKey));
    expect(tester.getSize(find.byType(RawChip)), equals(const Size(258.0, 48.0)));

    // Turn on selection.
    await pushChip(avatar: SizedBox(width: 40.0, height: 40.0, key: avatarKey), selectable: true);
    await tester.pumpAndSettle();

    expect(SchedulerBinding.instance.transientCallbackCount, equals(0));

    // Simulate a tap on the label to select the chip.
    await tester.tap(find.byKey(labelKey));
    expect(selected, equals(true));
    expect(SchedulerBinding.instance.transientCallbackCount, equals(2));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 50));
    expect(getSelectProgress(tester), moreOrLessEquals(0.002, epsilon: 0.01));
    expect(getAvatarDrawerProgress(tester), equals(1.0));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pump(const Duration(milliseconds: 50));
    expect(getSelectProgress(tester), moreOrLessEquals(0.54, epsilon: 0.01));
    expect(getAvatarDrawerProgress(tester), equals(1.0));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pump(const Duration(milliseconds: 100));
    expect(getSelectProgress(tester), equals(1.0));
    expect(getAvatarDrawerProgress(tester), equals(1.0));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pumpAndSettle();

    // Simulate another tap on the label to deselect the chip.
    await tester.tap(find.byKey(labelKey));
    expect(selected, equals(false));
    expect(SchedulerBinding.instance.transientCallbackCount, equals(2));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 20));
    expect(getSelectProgress(tester), moreOrLessEquals(0.875, epsilon: 0.01));
    expect(getAvatarDrawerProgress(tester), equals(1.0));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pump(const Duration(milliseconds: 20));
    expect(getSelectProgress(tester), moreOrLessEquals(0.13, epsilon: 0.01));
    expect(getAvatarDrawerProgress(tester), equals(1.0));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pump(const Duration(milliseconds: 100));
    expect(getSelectProgress(tester), equals(0.0));
    expect(getAvatarDrawerProgress(tester), equals(1.0));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
  });

  testWidgets('Material3 - Selection with avatar works as expected on RawChip', (
    WidgetTester tester,
  ) async {
    var selected = false;
    final labelKey = UniqueKey();
    Future<void> pushChip({Widget? avatar, bool selectable = false}) async {
      return tester.pumpWidget(
        wrapForChip(
          child: Wrap(
            children: <Widget>[
              StatefulBuilder(
                builder: (BuildContext context, StateSetter setState) {
                  return RawChip(
                    avatar: avatar,
                    onSelected: selectable
                        ? (bool value) {
                            setState(() {
                              selected = value;
                            });
                          }
                        : null,
                    selected: selected,
                    label: Text('Long Chip Label', key: labelKey),
                    shape: const StadiumBorder(),
                  );
                },
              ),
            ],
          ),
        ),
      );
    }

    // With avatar, but not selectable.
    final avatarKey = UniqueKey();
    await pushChip(avatar: SizedBox(width: 40.0, height: 40.0, key: avatarKey));
    expect(tester.getSize(find.byType(RawChip)), equals(const Size(265.5, 48.0)));

    // Turn on selection.
    await pushChip(avatar: SizedBox(width: 40.0, height: 40.0, key: avatarKey), selectable: true);
    await tester.pumpAndSettle();

    expect(SchedulerBinding.instance.transientCallbackCount, equals(0));

    // Simulate a tap on the label to select the chip.
    await tester.tap(find.byKey(labelKey));
    expect(selected, equals(true));
    expect(SchedulerBinding.instance.transientCallbackCount, equals(kIsWeb ? 3 : 1));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 50));
    expect(getSelectProgress(tester), moreOrLessEquals(0.002, epsilon: 0.01));
    expect(getAvatarDrawerProgress(tester), equals(1.0));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pump(const Duration(milliseconds: 50));
    expect(getSelectProgress(tester), moreOrLessEquals(0.54, epsilon: 0.01));
    expect(getAvatarDrawerProgress(tester), equals(1.0));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pump(const Duration(milliseconds: 100));
    expect(getSelectProgress(tester), equals(1.0));
    expect(getAvatarDrawerProgress(tester), equals(1.0));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pumpAndSettle();

    // Simulate another tap on the label to deselect the chip.
    await tester.tap(find.byKey(labelKey));
    expect(selected, equals(false));
    expect(SchedulerBinding.instance.transientCallbackCount, equals(kIsWeb ? 3 : 1));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 20));
    expect(getSelectProgress(tester), moreOrLessEquals(0.875, epsilon: 0.01));
    expect(getAvatarDrawerProgress(tester), equals(1.0));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pump(const Duration(milliseconds: 20));
    expect(getSelectProgress(tester), moreOrLessEquals(0.13, epsilon: 0.01));
    expect(getAvatarDrawerProgress(tester), equals(1.0));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pump(const Duration(milliseconds: 100));
    expect(getSelectProgress(tester), equals(0.0));
    expect(getAvatarDrawerProgress(tester), equals(1.0));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
  });

  testWidgets('Material2 - Selection without avatar works as expected on RawChip', (
    WidgetTester tester,
  ) async {
    var selected = false;
    final labelKey = UniqueKey();
    Future<void> pushChip({bool selectable = false}) async {
      return tester.pumpWidget(
        wrapForChip(
          theme: ThemeData(useMaterial3: false),
          child: Wrap(
            children: <Widget>[
              StatefulBuilder(
                builder: (BuildContext context, StateSetter setState) {
                  return RawChip(
                    onSelected: selectable
                        ? (bool value) {
                            setState(() {
                              selected = value;
                            });
                          }
                        : null,
                    selected: selected,
                    label: Text('Long Chip Label', key: labelKey),
                    shape: const StadiumBorder(),
                  );
                },
              ),
            ],
          ),
        ),
      );
    }

    // Without avatar, but not selectable.
    await pushChip();
    expect(tester.getSize(find.byType(RawChip)), equals(const Size(234.0, 48.0)));

    // Turn on selection.
    await pushChip(selectable: true);
    await tester.pumpAndSettle();

    // Simulate a tap on the label to select the chip.
    await tester.tap(find.byKey(labelKey));
    expect(selected, equals(true));
    expect(SchedulerBinding.instance.transientCallbackCount, equals(2));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 50));
    expect(getSelectProgress(tester), moreOrLessEquals(0.002, epsilon: 0.01));
    expect(getAvatarDrawerProgress(tester), moreOrLessEquals(0.459, epsilon: 0.01));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pump(const Duration(milliseconds: 50));
    expect(getSelectProgress(tester), moreOrLessEquals(0.54, epsilon: 0.01));
    expect(getAvatarDrawerProgress(tester), moreOrLessEquals(0.92, epsilon: 0.01));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pump(const Duration(milliseconds: 100));
    expect(getSelectProgress(tester), equals(1.0));
    expect(getAvatarDrawerProgress(tester), equals(1.0));
    expect(getDeleteDrawerProgress(tester), equals(0.0));

    await tester.pumpAndSettle();

    // Simulate another tap on the label to deselect the chip.
    await tester.tap(find.byKey(labelKey));
    expect(selected, equals(false));
    expect(SchedulerBinding.instance.transientCallbackCount, equals(2));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 20));
    expect(getSelectProgress(tester), moreOrLessEquals(0.875, epsilon: 0.01));
    expect(getAvatarDrawerProgress(tester), moreOrLessEquals(0.96, epsilon: 0.01));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pump(const Duration(milliseconds: 20));
    expect(getSelectProgress(tester), moreOrLessEquals(0.13, epsilon: 0.01));
    expect(getAvatarDrawerProgress(tester), moreOrLessEquals(0.75, epsilon: 0.01));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pump(const Duration(milliseconds: 100));
    expect(getSelectProgress(tester), equals(0.0));
    expect(getAvatarDrawerProgress(tester), equals(0.0));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
  });

  testWidgets('Material3 - Selection without avatar works as expected on RawChip', (
    WidgetTester tester,
  ) async {
    var selected = false;
    final labelKey = UniqueKey();
    Future<void> pushChip({bool selectable = false}) async {
      return tester.pumpWidget(
        wrapForChip(
          child: Wrap(
            children: <Widget>[
              StatefulBuilder(
                builder: (BuildContext context, StateSetter setState) {
                  return RawChip(
                    onSelected: selectable
                        ? (bool value) {
                            setState(() {
                              selected = value;
                            });
                          }
                        : null,
                    selected: selected,
                    label: Text('Long Chip Label', key: labelKey),
                    shape: const StadiumBorder(),
                  );
                },
              ),
            ],
          ),
        ),
      );
    }

    // Without avatar, but not selectable.
    await pushChip();
    expect(tester.getSize(find.byType(RawChip)), equals(const Size(245.5, 48.0)));

    // Turn on selection.
    await pushChip(selectable: true);
    await tester.pumpAndSettle();

    expect(SchedulerBinding.instance.transientCallbackCount, equals(0));

    // Simulate a tap on the label to select the chip.
    await tester.tap(find.byKey(labelKey));
    expect(selected, equals(true));
    expect(SchedulerBinding.instance.transientCallbackCount, equals(kIsWeb ? 3 : 1));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 50));
    expect(getSelectProgress(tester), moreOrLessEquals(0.002, epsilon: 0.01));
    expect(getAvatarDrawerProgress(tester), moreOrLessEquals(0.459, epsilon: 0.01));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pump(const Duration(milliseconds: 50));
    expect(getSelectProgress(tester), moreOrLessEquals(0.54, epsilon: 0.01));
    expect(getAvatarDrawerProgress(tester), moreOrLessEquals(0.92, epsilon: 0.01));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pump(const Duration(milliseconds: 100));
    expect(getSelectProgress(tester), equals(1.0));
    expect(getAvatarDrawerProgress(tester), equals(1.0));
    expect(getDeleteDrawerProgress(tester), equals(0.0));

    await tester.pumpAndSettle();

    // Simulate another tap on the label to deselect the chip.
    await tester.tap(find.byKey(labelKey));
    expect(selected, equals(false));
    expect(SchedulerBinding.instance.transientCallbackCount, equals(kIsWeb ? 3 : 1));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 20));
    expect(getSelectProgress(tester), moreOrLessEquals(0.875, epsilon: 0.01));
    expect(getAvatarDrawerProgress(tester), moreOrLessEquals(0.96, epsilon: 0.01));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pump(const Duration(milliseconds: 20));
    expect(getSelectProgress(tester), moreOrLessEquals(0.13, epsilon: 0.01));
    expect(getAvatarDrawerProgress(tester), moreOrLessEquals(0.75, epsilon: 0.01));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pump(const Duration(milliseconds: 100));
    expect(getSelectProgress(tester), equals(0.0));
    expect(getAvatarDrawerProgress(tester), equals(0.0));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
  });

  testWidgets('Material2 - Activation works as expected on RawChip', (WidgetTester tester) async {
    var selected = false;
    final labelKey = UniqueKey();
    Future<void> pushChip({Widget? avatar, bool selectable = false}) async {
      return tester.pumpWidget(
        wrapForChip(
          theme: ThemeData(useMaterial3: false),
          child: Wrap(
            children: <Widget>[
              StatefulBuilder(
                builder: (BuildContext context, StateSetter setState) {
                  return RawChip(
                    avatar: avatar,
                    onSelected: selectable
                        ? (bool value) {
                            setState(() {
                              selected = value;
                            });
                          }
                        : null,
                    selected: selected,
                    label: Text('Long Chip Label', key: labelKey),
                    shape: const StadiumBorder(),
                    showCheckmark: false,
                  );
                },
              ),
            ],
          ),
        ),
      );
    }

    final avatarKey = UniqueKey();
    await pushChip(avatar: SizedBox(width: 40.0, height: 40.0, key: avatarKey), selectable: true);
    await tester.pumpAndSettle();

    await tester.tap(find.byKey(labelKey));
    expect(selected, equals(true));
    expect(SchedulerBinding.instance.transientCallbackCount, equals(2));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 50));
    expect(getSelectProgress(tester), moreOrLessEquals(0.002, epsilon: 0.01));
    expect(getAvatarDrawerProgress(tester), equals(1.0));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pump(const Duration(milliseconds: 50));
    expect(getSelectProgress(tester), moreOrLessEquals(0.54, epsilon: 0.01));
    expect(getAvatarDrawerProgress(tester), equals(1.0));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pump(const Duration(milliseconds: 100));
    expect(getSelectProgress(tester), equals(1.0));
    expect(getAvatarDrawerProgress(tester), equals(1.0));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pumpAndSettle();
  });

  testWidgets('Material3 - Activation works as expected on RawChip', (WidgetTester tester) async {
    var selected = false;
    final labelKey = UniqueKey();
    Future<void> pushChip({Widget? avatar, bool selectable = false}) async {
      return tester.pumpWidget(
        wrapForChip(
          child: Wrap(
            children: <Widget>[
              StatefulBuilder(
                builder: (BuildContext context, StateSetter setState) {
                  return RawChip(
                    avatar: avatar,
                    onSelected: selectable
                        ? (bool value) {
                            setState(() {
                              selected = value;
                            });
                          }
                        : null,
                    selected: selected,
                    label: Text('Long Chip Label', key: labelKey),
                    shape: const StadiumBorder(),
                    showCheckmark: false,
                  );
                },
              ),
            ],
          ),
        ),
      );
    }

    final avatarKey = UniqueKey();
    await pushChip(avatar: SizedBox(width: 40.0, height: 40.0, key: avatarKey), selectable: true);
    await tester.pumpAndSettle();

    expect(SchedulerBinding.instance.transientCallbackCount, equals(0));

    await tester.tap(find.byKey(labelKey));
    expect(selected, equals(true));
    expect(SchedulerBinding.instance.transientCallbackCount, equals(kIsWeb ? 3 : 1));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 50));
    expect(getSelectProgress(tester), moreOrLessEquals(0.002, epsilon: 0.01));
    expect(getAvatarDrawerProgress(tester), equals(1.0));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pump(const Duration(milliseconds: 50));
    expect(getSelectProgress(tester), moreOrLessEquals(0.54, epsilon: 0.01));
    expect(getAvatarDrawerProgress(tester), equals(1.0));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pump(const Duration(milliseconds: 100));
    expect(getSelectProgress(tester), equals(1.0));
    expect(getAvatarDrawerProgress(tester), equals(1.0));
    expect(getDeleteDrawerProgress(tester), equals(0.0));
    await tester.pumpAndSettle();
  });

  testWidgets('Chip uses ThemeData chip theme if present', (WidgetTester tester) async {
    final theme = ThemeData(chipTheme: const ChipThemeData(backgroundColor: Color(0xffff0000)));

    Widget buildChip() {
      return wrapForChip(
        child: Theme(
          data: theme,
          child: InputChip(label: const Text('Label'), onPressed: () {}),
        ),
      );
    }

    await tester.pumpWidget(buildChip());

    final RenderBox materialBox = tester.firstRenderObject<RenderBox>(
      find.descendant(of: find.byType(RawChip), matching: find.byType(CustomPaint)),
    );

    expect(materialBox, paints..rrect(color: theme.chipTheme.backgroundColor));
  });

  testWidgets('Chip merges ChipThemeData label style with the provided label style', (
    WidgetTester tester,
  ) async {
    // The font family should be preserved even if the chip overrides some label style properties
    final theme = ThemeData(fontFamily: 'MyFont');

    Widget buildChip() {
      return wrapForChip(
        child: Theme(
          data: theme,
          child: const Chip(
            label: Text('Label'),
            labelStyle: TextStyle(fontWeight: FontWeight.w200),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildChip());

    final TextStyle labelStyle = getLabelStyle(tester, 'Label').style;
    expect(labelStyle.inherit, false);
    expect(labelStyle.fontFamily, 'MyFont');
    expect(labelStyle.fontWeight, FontWeight.w200);
  });

  testWidgets('ChipTheme labelStyle with inherit:true', (WidgetTester tester) async {
    Widget buildChip() {
      return wrapForChip(
        child: Theme(
          data: ThemeData(
            chipTheme: const ChipThemeData(
              labelStyle: TextStyle(height: 4), // inherit: true
            ),
          ),
          child: const Chip(label: Text('Label')), // labelStyle: null
        ),
      );
    }

    await tester.pumpWidget(buildChip());
    final TextStyle labelStyle = getLabelStyle(tester, 'Label').style;
    expect(labelStyle.inherit, true); // because chipTheme.labelStyle.merge(null)
    expect(labelStyle.height, 4);
  });

  testWidgets('Chip does not merge inherit:false label style with the theme label style', (
    WidgetTester tester,
  ) async {
    Widget buildChip() {
      return wrapForChip(
        child: Theme(
          data: ThemeData(fontFamily: 'MyFont'),
          child: const DefaultTextStyle(
            style: TextStyle(height: 8),
            child: Chip(
              label: Text('Label'),
              labelStyle: TextStyle(fontWeight: FontWeight.w200, inherit: false),
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildChip());
    final TextStyle labelStyle = getLabelStyle(tester, 'Label').style;
    expect(labelStyle.inherit, false);
    expect(labelStyle.fontFamily, null);
    expect(labelStyle.height, null);
    expect(labelStyle.fontWeight, FontWeight.w200);
  });

  testWidgets('Material2 - Chip size is configurable by ThemeData.materialTapTargetSize', (
    WidgetTester tester,
  ) async {
    final Key key1 = UniqueKey();
    await tester.pumpWidget(
      wrapForChip(
        child: Theme(
          data: ThemeData(useMaterial3: false, materialTapTargetSize: MaterialTapTargetSize.padded),
          child: Center(
            child: RawChip(key: key1, label: const Text('test')),
          ),
        ),
      ),
    );

    expect(tester.getSize(find.byKey(key1)), const Size(80.0, 48.0));

    final Key key2 = UniqueKey();
    await tester.pumpWidget(
      wrapForChip(
        child: Theme(
          data: ThemeData(
            useMaterial3: false,
            materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
          ),
          child: Center(
            child: RawChip(key: key2, label: const Text('test')),
          ),
        ),
      ),
    );

    expect(tester.getSize(find.byKey(key2)), const Size(80.0, 32.0));
  });

  testWidgets('Material3 - Chip size is configurable by ThemeData.materialTapTargetSize', (
    WidgetTester tester,
  ) async {
    final Key key1 = UniqueKey();
    await tester.pumpWidget(
      wrapForChip(
        child: Theme(
          data: ThemeData(materialTapTargetSize: MaterialTapTargetSize.padded),
          child: Center(
            child: RawChip(key: key1, label: const Text('test')),
          ),
        ),
      ),
    );

    expect(tester.getSize(find.byKey(key1)).width, moreOrLessEquals(90.4, epsilon: 0.1));
    expect(tester.getSize(find.byKey(key1)).height, equals(48.0));

    final Key key2 = UniqueKey();
    await tester.pumpWidget(
      wrapForChip(
        child: Theme(
          data: ThemeData(materialTapTargetSize: MaterialTapTargetSize.shrinkWrap),
          child: Center(
            child: RawChip(key: key2, label: const Text('test')),
          ),
        ),
      ),
    );

    expect(tester.getSize(find.byKey(key2)).width, moreOrLessEquals(90.4, epsilon: 0.1));
    expect(tester.getSize(find.byKey(key2)).height, equals(38.0));
  });

  testWidgets('Chip uses the right theme colors for the right components', (
    WidgetTester tester,
  ) async {
    final themeData = ThemeData(platform: TargetPlatform.android, primarySwatch: Colors.blue);
    final defaultChipTheme = ChipThemeData.fromDefaults(
      brightness: themeData.brightness,
      secondaryColor: Colors.blue,
      labelStyle: themeData.textTheme.bodyLarge!,
    );
    var value = false;
    Widget buildApp({
      ChipThemeData? chipTheme,
      Widget? avatar,
      Widget? deleteIcon,
      bool isSelectable = true,
      bool isPressable = false,
      bool isDeletable = true,
      bool showCheckmark = true,
    }) {
      chipTheme ??= defaultChipTheme;
      return wrapForChip(
        child: Theme(
          data: themeData,
          child: ChipTheme(
            data: chipTheme,
            child: StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
                return RawChip(
                  showCheckmark: showCheckmark,
                  onDeleted: isDeletable ? () {} : null,
                  avatar: avatar,
                  deleteIcon: deleteIcon,
                  isEnabled: isSelectable || isPressable,
                  shape: chipTheme?.shape,
                  selected: isSelectable && value,
                  label: Text('$value'),
                  onSelected: isSelectable
                      ? (bool newValue) {
                          setState(() {
                            value = newValue;
                          });
                        }
                      : null,
                  onPressed: isPressable
                      ? () {
                          setState(() {
                            value = true;
                          });
                        }
                      : null,
                );
              },
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildApp());

    RenderBox materialBox = getMaterialBox(tester);
    IconThemeData iconData = getIconData(tester);
    DefaultTextStyle labelStyle = getLabelStyle(tester, 'false');

    // Check default theme for enabled widget.
    expect(materialBox, paints..rrect(color: defaultChipTheme.backgroundColor));
    expect(iconData.color, equals(const Color(0xde000000)));
    expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));
    await tester.tap(find.byType(RawChip));
    await tester.pumpAndSettle();
    materialBox = getMaterialBox(tester);
    expect(materialBox, paints..rrect(color: defaultChipTheme.selectedColor));
    await tester.tap(find.byType(RawChip));
    await tester.pumpAndSettle();

    // Check default theme with disabled widget.
    await tester.pumpWidget(buildApp(isSelectable: false));
    await tester.pumpAndSettle();
    materialBox = getMaterialBox(tester);
    labelStyle = getLabelStyle(tester, 'false');
    expect(materialBox, paints..rrect(color: defaultChipTheme.disabledColor));
    expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));

    // Apply a custom theme.
    const customColor1 = Color(0xcafefeed);
    const customColor2 = Color(0xdeadbeef);
    const customColor3 = Color(0xbeefcafe);
    const customColor4 = Color(0xaddedabe);
    final ChipThemeData customTheme = defaultChipTheme.copyWith(
      brightness: Brightness.dark,
      backgroundColor: customColor1,
      disabledColor: customColor2,
      selectedColor: customColor3,
      deleteIconColor: customColor4,
    );
    await tester.pumpWidget(buildApp(chipTheme: customTheme));
    await tester.pumpAndSettle();
    materialBox = getMaterialBox(tester);
    iconData = getIconData(tester);
    labelStyle = getLabelStyle(tester, 'false');

    // Check custom theme for enabled widget.
    expect(materialBox, paints..rrect(color: customTheme.backgroundColor));
    expect(iconData.color, equals(customTheme.deleteIconColor));
    expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));
    await tester.tap(find.byType(RawChip));
    await tester.pumpAndSettle();
    materialBox = getMaterialBox(tester);
    expect(materialBox, paints..rrect(color: customTheme.selectedColor));
    await tester.tap(find.byType(RawChip));
    await tester.pumpAndSettle();

    // Check custom theme with disabled widget.
    await tester.pumpWidget(buildApp(chipTheme: customTheme, isSelectable: false));
    await tester.pumpAndSettle();
    materialBox = getMaterialBox(tester);
    labelStyle = getLabelStyle(tester, 'false');
    expect(materialBox, paints..rrect(color: customTheme.disabledColor));
    expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));
  });

  testWidgets('Chip uses the resolved color based on its state for the delete icon color', (
    WidgetTester tester,
  ) async {
    Widget buildApp({required ChipThemeData chipTheme, bool isSelected = false}) {
      return wrapForChip(
        child: ChipTheme(
          data: chipTheme,
          child: StatefulBuilder(
            builder: (BuildContext context, StateSetter setState) {
              return InputChip(
                label: const Text('Label'),
                selected: isSelected,
                onSelected: (_) {},
                onDeleted: () {},
              );
            },
          ),
        ),
      );
    }

    final chipTheme = ChipThemeData(
      deleteIconColor: WidgetStateColor.resolveWith((Set<WidgetState> states) {
        if (states.contains(WidgetState.selected)) {
          return Colors.green;
        }
        return Colors.blue;
      }),
    );

    await tester.pumpWidget(buildApp(chipTheme: chipTheme));

    IconThemeData iconData = getIconData(tester);
    expect(iconData.color, equals(Colors.blue));

    await tester.pumpWidget(buildApp(chipTheme: chipTheme, isSelected: true));

    iconData = getIconData(tester);
    expect(iconData.color, equals(Colors.green));
  });

  group('Chip semantics', () {
    testWidgets('label only', (WidgetTester tester) async {
      final semanticsTester = SemanticsTester(tester);

      await tester.pumpWidget(
        const MaterialApp(
          home: Material(child: RawChip(label: Text('test'))),
        ),
      );

      expect(
        semanticsTester,
        hasSemantics(
          TestSemantics.root(
            children: <TestSemantics>[
              TestSemantics(
                textDirection: TextDirection.ltr,
                children: <TestSemantics>[
                  TestSemantics(
                    children: <TestSemantics>[
                      TestSemantics(
                        flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
                        children: <TestSemantics>[
                          TestSemantics(
                            label: 'test',
                            textDirection: TextDirection.ltr,
                            flags: <SemanticsFlag>[
                              if (kIsWeb) SemanticsFlag.hasCheckedState,
                              if (!kIsWeb) SemanticsFlag.hasSelectedState,
                              SemanticsFlag.hasEnabledState,
                              SemanticsFlag.isButton,
                            ],
                          ),
                        ],
                      ),
                    ],
                  ),
                ],
              ),
            ],
          ),
          ignoreTransform: true,
          ignoreId: true,
          ignoreRect: true,
        ),
      );
      semanticsTester.dispose();
    });

    testWidgets('delete', (WidgetTester tester) async {
      final semanticsTester = SemanticsTester(tester);

      await tester.pumpWidget(
        MaterialApp(
          home: Material(
            child: RawChip(label: const Text('test'), onDeleted: () {}),
          ),
        ),
      );

      expect(
        semanticsTester,
        hasSemantics(
          TestSemantics.root(
            children: <TestSemantics>[
              TestSemantics(
                textDirection: TextDirection.ltr,
                children: <TestSemantics>[
                  TestSemantics(
                    children: <TestSemantics>[
                      TestSemantics(
                        flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
                        children: <TestSemantics>[
                          TestSemantics(
                            label: 'test',
                            textDirection: TextDirection.ltr,
                            flags: <SemanticsFlag>[
                              if (kIsWeb) SemanticsFlag.hasCheckedState,
                              if (!kIsWeb) SemanticsFlag.hasSelectedState,
                              SemanticsFlag.hasEnabledState,
                              SemanticsFlag.isButton,
                            ],
                            children: <TestSemantics>[
                              TestSemantics(
                                tooltip: 'Delete',
                                actions: <SemanticsAction>[
                                  SemanticsAction.tap,
                                  SemanticsAction.focus,
                                ],
                                textDirection: TextDirection.ltr,
                                flags: <SemanticsFlag>[
                                  SemanticsFlag.isButton,
                                  SemanticsFlag.isFocusable,
                                ],
                              ),
                            ],
                          ),
                        ],
                      ),
                    ],
                  ),
                ],
              ),
            ],
          ),
          ignoreTransform: true,
          ignoreId: true,
          ignoreRect: true,
        ),
      );
      semanticsTester.dispose();
    });

    testWidgets('with onPressed', (WidgetTester tester) async {
      final semanticsTester = SemanticsTester(tester);

      await tester.pumpWidget(
        MaterialApp(
          home: Material(
            child: RawChip(label: const Text('test'), onPressed: () {}),
          ),
        ),
      );

      expect(
        semanticsTester,
        hasSemantics(
          TestSemantics.root(
            children: <TestSemantics>[
              TestSemantics(
                textDirection: TextDirection.ltr,
                children: <TestSemantics>[
                  TestSemantics(
                    children: <TestSemantics>[
                      TestSemantics(
                        flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
                        children: <TestSemantics>[
                          TestSemantics(
                            label: 'test',
                            textDirection: TextDirection.ltr,
                            flags: <SemanticsFlag>[
                              if (kIsWeb) SemanticsFlag.hasCheckedState,
                              if (!kIsWeb) SemanticsFlag.hasSelectedState,
                              SemanticsFlag.hasEnabledState,
                              SemanticsFlag.isButton,
                              SemanticsFlag.isEnabled,
                              SemanticsFlag.isFocusable,
                            ],
                            actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
                          ),
                        ],
                      ),
                    ],
                  ),
                ],
              ),
            ],
          ),
          ignoreTransform: true,
          ignoreId: true,
          ignoreRect: true,
        ),
      );

      semanticsTester.dispose();
    });

    testWidgets('with onSelected', (WidgetTester tester) async {
      final semanticsTester = SemanticsTester(tester);
      var selected = false;

      await tester.pumpWidget(
        MaterialApp(
          home: Material(
            child: RawChip(
              label: const Text('test'),
              selected: selected,
              onSelected: (bool value) {
                selected = value;
              },
            ),
          ),
        ),
      );

      expect(
        semanticsTester,
        hasSemantics(
          TestSemantics.root(
            children: <TestSemantics>[
              TestSemantics(
                textDirection: TextDirection.ltr,
                children: <TestSemantics>[
                  TestSemantics(
                    children: <TestSemantics>[
                      TestSemantics(
                        flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
                        children: <TestSemantics>[
                          TestSemantics(
                            label: 'test',
                            textDirection: TextDirection.ltr,
                            flags: <SemanticsFlag>[
                              if (kIsWeb) SemanticsFlag.hasCheckedState,
                              if (!kIsWeb) SemanticsFlag.hasSelectedState,
                              SemanticsFlag.hasEnabledState,
                              SemanticsFlag.isButton,
                              SemanticsFlag.isEnabled,
                              SemanticsFlag.isFocusable,
                            ],
                            actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
                          ),
                        ],
                      ),
                    ],
                  ),
                ],
              ),
            ],
          ),
          ignoreTransform: true,
          ignoreId: true,
          ignoreRect: true,
        ),
      );

      await tester.tap(find.byType(RawChip));
      await tester.pumpWidget(
        MaterialApp(
          home: Material(
            child: RawChip(
              label: const Text('test'),
              selected: selected,
              onSelected: (bool value) {
                selected = value;
              },
            ),
          ),
        ),
      );

      expect(selected, true);
      expect(
        semanticsTester,
        hasSemantics(
          TestSemantics.root(
            children: <TestSemantics>[
              TestSemantics(
                textDirection: TextDirection.ltr,
                children: <TestSemantics>[
                  TestSemantics(
                    children: <TestSemantics>[
                      TestSemantics(
                        flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
                        children: <TestSemantics>[
                          TestSemantics(
                            label: 'test',
                            textDirection: TextDirection.ltr,
                            flags: <SemanticsFlag>[
                              SemanticsFlag.hasEnabledState,
                              SemanticsFlag.isButton,
                              SemanticsFlag.isEnabled,
                              SemanticsFlag.isFocusable,
                              if (kIsWeb) ...<SemanticsFlag>[
                                SemanticsFlag.hasCheckedState,
                                SemanticsFlag.isChecked,
                              ],
                              if (!kIsWeb) ...<SemanticsFlag>[
                                SemanticsFlag.hasSelectedState,
                                SemanticsFlag.isSelected,
                              ],
                            ],
                            actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
                          ),
                        ],
                      ),
                    ],
                  ),
                ],
              ),
            ],
          ),
          ignoreTransform: true,
          ignoreId: true,
          ignoreRect: true,
        ),
      );

      semanticsTester.dispose();
    });

    testWidgets('disabled', (WidgetTester tester) async {
      final semanticsTester = SemanticsTester(tester);

      await tester.pumpWidget(
        MaterialApp(
          home: Material(
            child: RawChip(isEnabled: false, onPressed: () {}, label: const Text('test')),
          ),
        ),
      );

      expect(
        semanticsTester,
        hasSemantics(
          TestSemantics.root(
            children: <TestSemantics>[
              TestSemantics(
                textDirection: TextDirection.ltr,
                children: <TestSemantics>[
                  TestSemantics(
                    children: <TestSemantics>[
                      TestSemantics(
                        flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
                        children: <TestSemantics>[
                          TestSemantics(
                            label: 'test',
                            textDirection: TextDirection.ltr,
                            flags: <SemanticsFlag>[
                              if (kIsWeb) SemanticsFlag.hasCheckedState,
                              if (!kIsWeb) SemanticsFlag.hasSelectedState,
                              SemanticsFlag.hasEnabledState,
                              SemanticsFlag.isButton,
                            ],
                            actions: <SemanticsAction>[],
                          ),
                        ],
                      ),
                    ],
                  ),
                ],
              ),
            ],
          ),
          ignoreTransform: true,
          ignoreId: true,
          ignoreRect: true,
        ),
      );

      semanticsTester.dispose();
    });

    testWidgets('tapEnabled explicitly false', (WidgetTester tester) async {
      final semanticsTester = SemanticsTester(tester);

      await tester.pumpWidget(
        const MaterialApp(
          home: Material(child: RawChip(tapEnabled: false, label: Text('test'))),
        ),
      );

      expect(
        semanticsTester,
        hasSemantics(
          TestSemantics.root(
            children: <TestSemantics>[
              TestSemantics(
                textDirection: TextDirection.ltr,
                children: <TestSemantics>[
                  TestSemantics(
                    children: <TestSemantics>[
                      TestSemantics(
                        flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
                        children: <TestSemantics>[
                          TestSemantics(
                            label: 'test',
                            textDirection: TextDirection.ltr,
                            // Must not be a button when tapping is disabled.
                            flags: <SemanticsFlag>[
                              if (kIsWeb) SemanticsFlag.hasCheckedState,
                              if (!kIsWeb) SemanticsFlag.hasSelectedState,
                            ],
                            actions: <SemanticsAction>[],
                          ),
                        ],
                      ),
                    ],
                  ),
                ],
              ),
            ],
          ),
          ignoreTransform: true,
          ignoreId: true,
          ignoreRect: true,
        ),
      );

      semanticsTester.dispose();
    });

    testWidgets('enabled when tapEnabled and canTap', (WidgetTester tester) async {
      final semanticsTester = SemanticsTester(tester);

      // These settings make a Chip which can be tapped, both in general and at this moment.
      await tester.pumpWidget(
        MaterialApp(
          home: Material(
            child: RawChip(onPressed: () {}, label: const Text('test')),
          ),
        ),
      );

      expect(
        semanticsTester,
        hasSemantics(
          TestSemantics.root(
            children: <TestSemantics>[
              TestSemantics(
                textDirection: TextDirection.ltr,
                children: <TestSemantics>[
                  TestSemantics(
                    children: <TestSemantics>[
                      TestSemantics(
                        flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
                        children: <TestSemantics>[
                          TestSemantics(
                            label: 'test',
                            textDirection: TextDirection.ltr,
                            flags: <SemanticsFlag>[
                              if (kIsWeb) SemanticsFlag.hasCheckedState,
                              if (!kIsWeb) SemanticsFlag.hasSelectedState,
                              SemanticsFlag.hasEnabledState,
                              SemanticsFlag.isButton,
                              SemanticsFlag.isEnabled,
                              SemanticsFlag.isFocusable,
                            ],
                            actions: <SemanticsAction>[SemanticsAction.tap, SemanticsAction.focus],
                          ),
                        ],
                      ),
                    ],
                  ),
                ],
              ),
            ],
          ),
          ignoreTransform: true,
          ignoreId: true,
          ignoreRect: true,
        ),
      );

      semanticsTester.dispose();
    });

    testWidgets('disabled when tapEnabled but not canTap', (WidgetTester tester) async {
      final semanticsTester = SemanticsTester(tester);
      // These settings make a Chip which _could_ be tapped, but not currently (ensures `canTap == false`).
      await tester.pumpWidget(
        const MaterialApp(
          home: Material(child: RawChip(label: Text('test'))),
        ),
      );

      expect(
        semanticsTester,
        hasSemantics(
          TestSemantics.root(
            children: <TestSemantics>[
              TestSemantics(
                textDirection: TextDirection.ltr,
                children: <TestSemantics>[
                  TestSemantics(
                    children: <TestSemantics>[
                      TestSemantics(
                        flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
                        children: <TestSemantics>[
                          TestSemantics(
                            label: 'test',
                            textDirection: TextDirection.ltr,
                            flags: <SemanticsFlag>[
                              if (kIsWeb) SemanticsFlag.hasCheckedState,
                              if (!kIsWeb) SemanticsFlag.hasSelectedState,
                              SemanticsFlag.hasEnabledState,
                              SemanticsFlag.isButton,
                            ],
                          ),
                        ],
                      ),
                    ],
                  ),
                ],
              ),
            ],
          ),
          ignoreTransform: true,
          ignoreId: true,
          ignoreRect: true,
        ),
      );

      semanticsTester.dispose();
    });
  });

  testWidgets('can be tapped outside of chip delete icon', (WidgetTester tester) async {
    var deleted = false;
    await tester.pumpWidget(
      wrapForChip(
        child: Row(
          children: <Widget>[
            Chip(
              materialTapTargetSize: MaterialTapTargetSize.padded,
              shape: const RoundedRectangleBorder(),
              avatar: const CircleAvatar(child: Text('A')),
              label: const Text('Chip A'),
              onDeleted: () {
                deleted = true;
              },
              deleteIcon: const Icon(Icons.delete),
            ),
          ],
        ),
      ),
    );

    await tester.tapAt(tester.getTopRight(find.byType(Chip)) - const Offset(2.0, -2.0));
    await tester.pumpAndSettle();
    expect(deleted, true);
  });

  testWidgets('Chips can be tapped', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(child: RawChip(label: Text('raw chip'))),
      ),
    );

    await tester.tap(find.byType(RawChip));
    expect(tester.takeException(), null);
  });

  testWidgets('Material2 - Chip elevation and shadow color work correctly', (
    WidgetTester tester,
  ) async {
    final theme = ThemeData(
      useMaterial3: false,
      platform: TargetPlatform.android,
      primarySwatch: Colors.red,
    );

    var inputChip = const InputChip(label: Text('Label'));

    Widget buildChip() {
      return wrapForChip(
        child: Theme(data: theme, child: inputChip),
      );
    }

    await tester.pumpWidget(buildChip());
    Material material = getMaterial(tester);
    expect(material.elevation, 0.0);
    expect(material.shadowColor, Colors.black);

    inputChip = const InputChip(
      label: Text('Label'),
      elevation: 4.0,
      shadowColor: Colors.green,
      selectedShadowColor: Colors.blue,
    );

    await tester.pumpWidget(buildChip());
    await tester.pumpAndSettle();
    material = getMaterial(tester);
    expect(material.elevation, 4.0);
    expect(material.shadowColor, Colors.green);

    inputChip = const InputChip(
      label: Text('Label'),
      selected: true,
      shadowColor: Colors.green,
      selectedShadowColor: Colors.blue,
    );

    await tester.pumpWidget(buildChip());
    await tester.pumpAndSettle();
    material = getMaterial(tester);
    expect(material.shadowColor, Colors.blue);
  });

  testWidgets('Material3 - Chip elevation and shadow color work correctly', (
    WidgetTester tester,
  ) async {
    final theme = ThemeData();

    var inputChip = const InputChip(label: Text('Label'));

    Widget buildChip() {
      return wrapForChip(theme: theme, child: inputChip);
    }

    await tester.pumpWidget(buildChip());
    Material material = getMaterial(tester);
    expect(material.elevation, 0.0);
    expect(material.shadowColor, Colors.transparent);

    inputChip = const InputChip(
      label: Text('Label'),
      elevation: 4.0,
      shadowColor: Colors.green,
      selectedShadowColor: Colors.blue,
    );

    await tester.pumpWidget(buildChip());
    await tester.pumpAndSettle();
    material = getMaterial(tester);
    expect(material.elevation, 4.0);
    expect(material.shadowColor, Colors.green);

    inputChip = const InputChip(
      label: Text('Label'),
      selected: true,
      shadowColor: Colors.green,
      selectedShadowColor: Colors.blue,
    );

    await tester.pumpWidget(buildChip());
    await tester.pumpAndSettle();
    material = getMaterial(tester);
    expect(material.shadowColor, Colors.blue);
  });

  testWidgets('can be tapped outside of chip body', (WidgetTester tester) async {
    var pressed = false;
    await tester.pumpWidget(
      wrapForChip(
        child: Row(
          children: <Widget>[
            InputChip(
              materialTapTargetSize: MaterialTapTargetSize.padded,
              shape: const RoundedRectangleBorder(),
              avatar: const CircleAvatar(child: Text('A')),
              label: const Text('Chip A'),
              onPressed: () {
                pressed = true;
              },
            ),
          ],
        ),
      ),
    );

    await tester.tapAt(tester.getRect(find.byType(InputChip)).topCenter);
    await tester.pumpAndSettle();
    expect(pressed, true);
  });

  testWidgets('is hitTestable', (WidgetTester tester) async {
    await tester.pumpWidget(
      wrapForChip(
        child: InputChip(
          shape: const RoundedRectangleBorder(),
          avatar: const CircleAvatar(child: Text('A')),
          label: const Text('Chip A'),
          onPressed: () {},
        ),
      ),
    );

    expect(find.byType(InputChip).hitTestable(), findsOneWidget);
  });

  void checkChipMaterialClipBehavior(WidgetTester tester, Clip clipBehavior) {
    final Iterable<Material> materials = tester.widgetList<Material>(find.byType(Material));
    expect(materials.length, 2);
    expect(materials.last.clipBehavior, clipBehavior);
  }

  testWidgets('Chip clipBehavior properly passes through to the Material', (
    WidgetTester tester,
  ) async {
    const label = Text('label');
    await tester.pumpWidget(wrapForChip(child: const Chip(label: label)));
    checkChipMaterialClipBehavior(tester, Clip.none);

    await tester.pumpWidget(
      wrapForChip(
        child: const Chip(label: label, clipBehavior: Clip.antiAlias),
      ),
    );
    checkChipMaterialClipBehavior(tester, Clip.antiAlias);
  });

  testWidgets('Material2 - selected chip and avatar draw darkened layer within avatar circle', (
    WidgetTester tester,
  ) async {
    await tester.pumpWidget(
      wrapForChip(
        theme: ThemeData(useMaterial3: false),
        child: const FilterChip(
          avatar: CircleAvatar(child: Text('t')),
          label: Text('test'),
          selected: true,
          onSelected: null,
        ),
      ),
    );
    final RenderBox rawChip = tester.firstRenderObject<RenderBox>(
      find.descendant(
        of: find.byType(RawChip),
        matching: find.byWidgetPredicate((Widget widget) {
          return widget.runtimeType.toString() == '_ChipRenderWidget';
        }),
      ),
    );
    const avatarX = 16.0;
    const avatarY = 16.0;
    const avatarRadius = 12.0;
    const selectScrimColor = Color(0x60191919);
    expect(
      rawChip,
      paints
        // CircleAvatar background.
        ..circle(x: avatarX, y: avatarY, radius: avatarRadius)
        // Selection scrim overlay.
        ..circle(color: selectScrimColor, x: avatarX, y: avatarY, radius: avatarRadius),
    );
  });

  testWidgets('Material3 - selected chip and avatar draw darkened layer within avatar circle', (
    WidgetTester tester,
  ) async {
    await tester.pumpWidget(
      wrapForChip(
        child: const FilterChip(
          avatar: CircleAvatar(child: Text('t')),
          label: Text('test'),
          selected: true,
          onSelected: null,
        ),
      ),
    );
    final RenderBox rawChip = tester.firstRenderObject<RenderBox>(
      find.descendant(
        of: find.byType(RawChip),
        matching: find.byWidgetPredicate((Widget widget) {
          return widget.runtimeType.toString() == '_ChipRenderWidget';
        }),
      ),
    );
    const avatarX = 18.0;
    const avatarY = 18.0;
    const avatarRadius = 10.0;
    const selectScrimColor = Color(0x60191919);
    expect(
      rawChip,
      paints
        // CircleAvatar background.
        ..circle(x: avatarX, y: avatarY, radius: avatarRadius)
        // Selection scrim overlay.
        ..circle(color: selectScrimColor, x: avatarX, y: avatarY, radius: avatarRadius),
    );
  });

  testWidgets('Chips should use InkWell instead of InkResponse.', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/28646
    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: ActionChip(onPressed: () {}, label: const Text('action chip')),
        ),
      ),
    );
    expect(find.byType(InkWell), findsOneWidget);
  });

  testWidgets('Chip uses stateful color for text color in different states', (
    WidgetTester tester,
  ) async {
    final focusNode = FocusNode();
    addTearDown(focusNode.dispose);

    const pressedColor = Color(0x00000001);
    const hoverColor = Color(0x00000002);
    const focusedColor = Color(0x00000003);
    const defaultColor = Color(0x00000004);
    const selectedColor = Color(0x00000005);
    const disabledColor = Color(0x00000006);

    Color getTextColor(Set<WidgetState> states) {
      if (states.contains(WidgetState.disabled)) {
        return disabledColor;
      }

      if (states.contains(WidgetState.pressed)) {
        return pressedColor;
      }

      if (states.contains(WidgetState.hovered)) {
        return hoverColor;
      }

      if (states.contains(WidgetState.focused)) {
        return focusedColor;
      }

      if (states.contains(WidgetState.selected)) {
        return selectedColor;
      }

      return defaultColor;
    }

    Widget chipWidget({bool enabled = true, bool selected = false}) {
      return MaterialApp(
        home: Scaffold(
          body: Focus(
            focusNode: focusNode,
            child: ChoiceChip(
              label: const Text('Chip'),
              selected: selected,
              onSelected: enabled ? (_) {} : null,
              labelStyle: TextStyle(color: WidgetStateColor.resolveWith(getTextColor)),
            ),
          ),
        ),
      );
    }

    Color textColor() {
      return tester.renderObject<RenderParagraph>(find.text('Chip')).text.style!.color!;
    }

    // Default, not disabled.
    await tester.pumpWidget(chipWidget());
    expect(textColor(), equals(defaultColor));

    // Selected.
    await tester.pumpWidget(chipWidget(selected: true));
    expect(textColor(), selectedColor);

    // Focused.
    final FocusNode chipFocusNode = focusNode.children.first;
    chipFocusNode.requestFocus();
    await tester.pumpAndSettle();
    expect(textColor(), focusedColor);

    // Hovered.
    final Offset center = tester.getCenter(find.byType(ChoiceChip));
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer();
    await gesture.moveTo(center);
    await tester.pumpAndSettle();
    expect(textColor(), hoverColor);

    // Pressed.
    await gesture.down(center);
    await tester.pumpAndSettle();
    expect(textColor(), pressedColor);

    // Disabled.
    await tester.pumpWidget(chipWidget(enabled: false));
    await tester.pumpAndSettle();
    expect(textColor(), disabledColor);
  });

  testWidgets('Material2 - Chip uses stateful border side color in different states', (
    WidgetTester tester,
  ) async {
    final focusNode = FocusNode();
    addTearDown(focusNode.dispose);

    const pressedColor = Color(0x00000001);
    const hoverColor = Color(0x00000002);
    const focusedColor = Color(0x00000003);
    const defaultColor = Color(0x00000004);
    const selectedColor = Color(0x00000005);
    const disabledColor = Color(0x00000006);

    BorderSide getBorderSide(Set<WidgetState> states) {
      var sideColor = defaultColor;
      if (states.contains(WidgetState.disabled)) {
        sideColor = disabledColor;
      } else if (states.contains(WidgetState.pressed)) {
        sideColor = pressedColor;
      } else if (states.contains(WidgetState.hovered)) {
        sideColor = hoverColor;
      } else if (states.contains(WidgetState.focused)) {
        sideColor = focusedColor;
      } else if (states.contains(WidgetState.selected)) {
        sideColor = selectedColor;
      }
      return BorderSide(color: sideColor);
    }

    Widget chipWidget({bool enabled = true, bool selected = false}) {
      return MaterialApp(
        theme: ThemeData(useMaterial3: false),
        home: Scaffold(
          body: Focus(
            focusNode: focusNode,
            child: ChoiceChip(
              label: const Text('Chip'),
              selected: selected,
              onSelected: enabled ? (_) {} : null,
              side: _TestWidgetStateBorderSide(getBorderSide),
            ),
          ),
        ),
      );
    }

    // Default, not disabled.
    await tester.pumpWidget(chipWidget());
    expect(
      find.byType(RawChip),
      paints
        ..rrect()
        ..rrect(color: defaultColor),
    );

    // Selected.
    await tester.pumpWidget(chipWidget(selected: true));
    expect(
      find.byType(RawChip),
      paints
        ..rrect()
        ..rrect(color: selectedColor),
    );

    // Focused.
    final FocusNode chipFocusNode = focusNode.children.first;
    chipFocusNode.requestFocus();
    await tester.pumpAndSettle();
    expect(
      find.byType(RawChip),
      paints
        ..rrect()
        ..rrect(color: focusedColor),
    );

    // Hovered.
    final Offset center = tester.getCenter(find.byType(ChoiceChip));
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer();
    await gesture.moveTo(center);
    await tester.pumpAndSettle();
    expect(
      find.byType(RawChip),
      paints
        ..rrect()
        ..rrect(color: hoverColor),
    );

    // Pressed.
    await gesture.down(center);
    await tester.pumpAndSettle();
    expect(
      find.byType(RawChip),
      paints
        ..rrect()
        ..rrect(color: pressedColor),
    );

    // Disabled.
    await tester.pumpWidget(chipWidget(enabled: false));
    await tester.pumpAndSettle();
    expect(
      find.byType(RawChip),
      paints
        ..rrect()
        ..rrect(color: disabledColor),
    );
  });

  testWidgets('Material3 - Chip uses stateful border side color in different states', (
    WidgetTester tester,
  ) async {
    final focusNode = FocusNode();
    addTearDown(focusNode.dispose);

    const pressedColor = Color(0x00000001);
    const hoverColor = Color(0x00000002);
    const focusedColor = Color(0x00000003);
    const defaultColor = Color(0x00000004);
    const selectedColor = Color(0x00000005);
    const disabledColor = Color(0x00000006);

    BorderSide getBorderSide(Set<WidgetState> states) {
      var sideColor = defaultColor;
      if (states.contains(WidgetState.disabled)) {
        sideColor = disabledColor;
      } else if (states.contains(WidgetState.pressed)) {
        sideColor = pressedColor;
      } else if (states.contains(WidgetState.hovered)) {
        sideColor = hoverColor;
      } else if (states.contains(WidgetState.focused)) {
        sideColor = focusedColor;
      } else if (states.contains(WidgetState.selected)) {
        sideColor = selectedColor;
      }
      return BorderSide(color: sideColor);
    }

    Widget chipWidget({bool enabled = true, bool selected = false}) {
      return MaterialApp(
        home: Scaffold(
          body: Focus(
            focusNode: focusNode,
            child: ChoiceChip(
              label: const Text('Chip'),
              selected: selected,
              onSelected: enabled ? (_) {} : null,
              side: _TestWidgetStateBorderSide(getBorderSide),
            ),
          ),
        ),
      );
    }

    // Default, not disabled.
    await tester.pumpWidget(chipWidget());
    expect(find.byType(RawChip), paints..drrect(color: defaultColor));

    // Selected.
    await tester.pumpWidget(chipWidget(selected: true));
    expect(find.byType(RawChip), paints..drrect(color: selectedColor));

    // Focused.
    final FocusNode chipFocusNode = focusNode.children.first;
    chipFocusNode.requestFocus();
    await tester.pumpAndSettle();
    expect(find.byType(RawChip), paints..drrect(color: focusedColor));

    // Hovered.
    final Offset center = tester.getCenter(find.byType(ChoiceChip));
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer();
    await gesture.moveTo(center);
    await tester.pumpAndSettle();
    expect(find.byType(RawChip), paints..drrect(color: hoverColor));

    // Pressed.
    await gesture.down(center);
    await tester.pumpAndSettle();
    expect(find.byType(RawChip), paints..drrect(color: pressedColor));

    // Disabled.
    await tester.pumpWidget(chipWidget(enabled: false));
    await tester.pumpAndSettle();
    expect(find.byType(RawChip), paints..drrect(color: disabledColor));
  });

  testWidgets('Material2 - Chip uses stateful border side color from resolveWith', (
    WidgetTester tester,
  ) async {
    final focusNode = FocusNode();
    addTearDown(focusNode.dispose);

    const pressedColor = Color(0x00000001);
    const hoverColor = Color(0x00000002);
    const focusedColor = Color(0x00000003);
    const defaultColor = Color(0x00000004);
    const selectedColor = Color(0x00000005);
    const disabledColor = Color(0x00000006);

    BorderSide getBorderSide(Set<WidgetState> states) {
      var sideColor = defaultColor;
      if (states.contains(WidgetState.disabled)) {
        sideColor = disabledColor;
      } else if (states.contains(WidgetState.pressed)) {
        sideColor = pressedColor;
      } else if (states.contains(WidgetState.hovered)) {
        sideColor = hoverColor;
      } else if (states.contains(WidgetState.focused)) {
        sideColor = focusedColor;
      } else if (states.contains(WidgetState.selected)) {
        sideColor = selectedColor;
      }
      return BorderSide(color: sideColor);
    }

    Widget chipWidget({bool enabled = true, bool selected = false}) {
      return MaterialApp(
        theme: ThemeData(useMaterial3: false),
        home: Scaffold(
          body: Focus(
            focusNode: focusNode,
            child: ChoiceChip(
              label: const Text('Chip'),
              selected: selected,
              onSelected: enabled ? (_) {} : null,
              side: WidgetStateBorderSide.resolveWith(getBorderSide),
            ),
          ),
        ),
      );
    }

    // Default, not disabled.
    await tester.pumpWidget(chipWidget());
    expect(
      find.byType(RawChip),
      paints
        ..rrect()
        ..rrect(color: defaultColor),
    );

    // Selected.
    await tester.pumpWidget(chipWidget(selected: true));
    expect(
      find.byType(RawChip),
      paints
        ..rrect()
        ..rrect(color: selectedColor),
    );

    // Focused.
    final FocusNode chipFocusNode = focusNode.children.first;
    chipFocusNode.requestFocus();
    await tester.pumpAndSettle();
    expect(
      find.byType(RawChip),
      paints
        ..rrect()
        ..rrect(color: focusedColor),
    );

    // Hovered.
    final Offset center = tester.getCenter(find.byType(ChoiceChip));
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer();
    await gesture.moveTo(center);
    await tester.pumpAndSettle();
    expect(
      find.byType(RawChip),
      paints
        ..rrect()
        ..rrect(color: hoverColor),
    );

    // Pressed.
    await gesture.down(center);
    await tester.pumpAndSettle();
    expect(
      find.byType(RawChip),
      paints
        ..rrect()
        ..rrect(color: pressedColor),
    );

    // Disabled.
    await tester.pumpWidget(chipWidget(enabled: false));
    await tester.pumpAndSettle();
    expect(
      find.byType(RawChip),
      paints
        ..rrect()
        ..rrect(color: disabledColor),
    );
  });

  testWidgets('Material3 - Chip uses stateful border side color from resolveWith', (
    WidgetTester tester,
  ) async {
    final focusNode = FocusNode();
    addTearDown(focusNode.dispose);

    const pressedColor = Color(0x00000001);
    const hoverColor = Color(0x00000002);
    const focusedColor = Color(0x00000003);
    const defaultColor = Color(0x00000004);
    const selectedColor = Color(0x00000005);
    const disabledColor = Color(0x00000006);

    BorderSide getBorderSide(Set<WidgetState> states) {
      var sideColor = defaultColor;
      if (states.contains(WidgetState.disabled)) {
        sideColor = disabledColor;
      } else if (states.contains(WidgetState.pressed)) {
        sideColor = pressedColor;
      } else if (states.contains(WidgetState.hovered)) {
        sideColor = hoverColor;
      } else if (states.contains(WidgetState.focused)) {
        sideColor = focusedColor;
      } else if (states.contains(WidgetState.selected)) {
        sideColor = selectedColor;
      }
      return BorderSide(color: sideColor);
    }

    Widget chipWidget({bool enabled = true, bool selected = false}) {
      return MaterialApp(
        home: Scaffold(
          body: Focus(
            focusNode: focusNode,
            child: ChoiceChip(
              label: const Text('Chip'),
              selected: selected,
              onSelected: enabled ? (_) {} : null,
              side: WidgetStateBorderSide.resolveWith(getBorderSide),
            ),
          ),
        ),
      );
    }

    // Default, not disabled.
    await tester.pumpWidget(chipWidget());
    expect(find.byType(RawChip), paints..drrect(color: defaultColor));

    // Selected.
    await tester.pumpWidget(chipWidget(selected: true));
    expect(find.byType(RawChip), paints..drrect(color: selectedColor));

    // Focused.
    final FocusNode chipFocusNode = focusNode.children.first;
    chipFocusNode.requestFocus();
    await tester.pumpAndSettle();
    expect(find.byType(RawChip), paints..drrect(color: focusedColor));

    // Hovered.
    final Offset center = tester.getCenter(find.byType(ChoiceChip));
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer();
    await gesture.moveTo(center);
    await tester.pumpAndSettle();
    expect(find.byType(RawChip), paints..drrect(color: hoverColor));

    // Pressed.
    await gesture.down(center);
    await tester.pumpAndSettle();
    expect(find.byType(RawChip), paints..drrect(color: pressedColor));

    // Disabled.
    await tester.pumpWidget(chipWidget(enabled: false));
    await tester.pumpAndSettle();
    expect(find.byType(RawChip), paints..drrect(color: disabledColor));
  });

  testWidgets('Material2 - Chip uses stateful nullable border side color from resolveWith', (
    WidgetTester tester,
  ) async {
    final focusNode = FocusNode();
    addTearDown(focusNode.dispose);

    const pressedColor = Color(0x00000001);
    const hoverColor = Color(0x00000002);
    const focusedColor = Color(0x00000003);
    const defaultColor = Color(0x00000004);
    const disabledColor = Color(0x00000006);

    const fallbackThemeColor = Color(0x00000007);
    const defaultBorderSide = BorderSide(color: fallbackThemeColor, width: 10.0);

    BorderSide? getBorderSide(Set<WidgetState> states) {
      var sideColor = defaultColor;
      if (states.contains(WidgetState.disabled)) {
        sideColor = disabledColor;
      } else if (states.contains(WidgetState.pressed)) {
        sideColor = pressedColor;
      } else if (states.contains(WidgetState.hovered)) {
        sideColor = hoverColor;
      } else if (states.contains(WidgetState.focused)) {
        sideColor = focusedColor;
      } else if (states.contains(WidgetState.selected)) {
        return null;
      }
      return BorderSide(color: sideColor);
    }

    Widget chipWidget({bool enabled = true, bool selected = false}) {
      return MaterialApp(
        theme: ThemeData(useMaterial3: false),
        home: Scaffold(
          body: Focus(
            focusNode: focusNode,
            child: ChipTheme(
              data: ThemeData().chipTheme.copyWith(side: defaultBorderSide),
              child: ChoiceChip(
                label: const Text('Chip'),
                selected: selected,
                onSelected: enabled ? (_) {} : null,
                side: WidgetStateBorderSide.resolveWith(getBorderSide),
              ),
            ),
          ),
        ),
      );
    }

    // Default, not disabled.
    await tester.pumpWidget(chipWidget());
    expect(
      find.byType(RawChip),
      paints
        ..rrect()
        ..rrect(color: defaultColor),
    );

    // Selected.
    await tester.pumpWidget(chipWidget(selected: true));
    // Because the resolver returns `null` for this value, we should fall back
    // to the theme.
    expect(
      find.byType(RawChip),
      paints
        ..rrect()
        ..rrect(color: fallbackThemeColor),
    );

    // Focused.
    final FocusNode chipFocusNode = focusNode.children.first;
    chipFocusNode.requestFocus();
    await tester.pumpAndSettle();
    expect(
      find.byType(RawChip),
      paints
        ..rrect()
        ..rrect(color: focusedColor),
    );

    // Hovered.
    final Offset center = tester.getCenter(find.byType(ChoiceChip));
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer();
    await gesture.moveTo(center);
    await tester.pumpAndSettle();
    expect(
      find.byType(RawChip),
      paints
        ..rrect()
        ..rrect(color: hoverColor),
    );

    // Pressed.
    await gesture.down(center);
    await tester.pumpAndSettle();
    expect(
      find.byType(RawChip),
      paints
        ..rrect()
        ..rrect(color: pressedColor),
    );

    // Disabled.
    await tester.pumpWidget(chipWidget(enabled: false));
    await tester.pumpAndSettle();
    expect(
      find.byType(RawChip),
      paints
        ..rrect()
        ..rrect(color: disabledColor),
    );
  });

  testWidgets('Material3 - Chip uses stateful nullable border side color from resolveWith', (
    WidgetTester tester,
  ) async {
    final focusNode = FocusNode();
    addTearDown(focusNode.dispose);

    const pressedColor = Color(0x00000001);
    const hoverColor = Color(0x00000002);
    const focusedColor = Color(0x00000003);
    const defaultColor = Color(0x00000004);
    const disabledColor = Color(0x00000006);

    const fallbackThemeColor = Color(0x00000007);
    const defaultBorderSide = BorderSide(color: fallbackThemeColor, width: 10.0);

    BorderSide? getBorderSide(Set<WidgetState> states) {
      var sideColor = defaultColor;
      if (states.contains(WidgetState.disabled)) {
        sideColor = disabledColor;
      } else if (states.contains(WidgetState.pressed)) {
        sideColor = pressedColor;
      } else if (states.contains(WidgetState.hovered)) {
        sideColor = hoverColor;
      } else if (states.contains(WidgetState.focused)) {
        sideColor = focusedColor;
      } else if (states.contains(WidgetState.selected)) {
        return null;
      }
      return BorderSide(color: sideColor);
    }

    Widget chipWidget({bool enabled = true, bool selected = false}) {
      return MaterialApp(
        home: Scaffold(
          body: Focus(
            focusNode: focusNode,
            child: ChipTheme(
              data: ThemeData().chipTheme.copyWith(side: defaultBorderSide),
              child: ChoiceChip(
                label: const Text('Chip'),
                selected: selected,
                onSelected: enabled ? (_) {} : null,
                side: WidgetStateBorderSide.resolveWith(getBorderSide),
              ),
            ),
          ),
        ),
      );
    }

    // Default, not disabled.
    await tester.pumpWidget(chipWidget());
    expect(find.byType(RawChip), paints..drrect(color: defaultColor));

    // Selected.
    await tester.pumpWidget(chipWidget(selected: true));
    // Because the resolver returns `null` for this value, we should fall back
    // to the theme
    expect(find.byType(RawChip), paints..drrect(color: fallbackThemeColor));

    // Focused.
    final FocusNode chipFocusNode = focusNode.children.first;
    chipFocusNode.requestFocus();
    await tester.pumpAndSettle();
    expect(find.byType(RawChip), paints..drrect(color: focusedColor));

    // Hovered.
    final Offset center = tester.getCenter(find.byType(ChoiceChip));
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer();
    await gesture.moveTo(center);
    await tester.pumpAndSettle();
    expect(find.byType(RawChip), paints..drrect(color: hoverColor));

    // Pressed.
    await gesture.down(center);
    await tester.pumpAndSettle();
    expect(find.byType(RawChip), paints..drrect(color: pressedColor));

    // Disabled.
    await tester.pumpWidget(chipWidget(enabled: false));
    await tester.pumpAndSettle();
    expect(find.byType(RawChip), paints..drrect(color: disabledColor));
  });

  testWidgets('Material2 - Chip uses stateful shape in different states', (
    WidgetTester tester,
  ) async {
    final focusNode = FocusNode();
    addTearDown(focusNode.dispose);

    OutlinedBorder? getShape(Set<WidgetState> states) {
      if (states.contains(WidgetState.disabled)) {
        return const BeveledRectangleBorder();
      } else if (states.contains(WidgetState.pressed)) {
        return const CircleBorder();
      } else if (states.contains(WidgetState.hovered)) {
        return const ContinuousRectangleBorder();
      } else if (states.contains(WidgetState.focused)) {
        return const RoundedRectangleBorder();
      } else if (states.contains(WidgetState.selected)) {
        return const BeveledRectangleBorder();
      }
      return null;
    }

    Widget chipWidget({bool enabled = true, bool selected = false}) {
      return MaterialApp(
        theme: ThemeData(useMaterial3: false),
        home: Scaffold(
          body: Focus(
            focusNode: focusNode,
            child: ChoiceChip(
              selected: selected,
              label: const Text('Chip'),
              shape: _TestWidgetStateOutlinedBorder(getShape),
              onSelected: enabled ? (_) {} : null,
            ),
          ),
        ),
      );
    }

    // Default, not disabled. Defers to default shape.
    await tester.pumpWidget(chipWidget());
    expect(getMaterial(tester).shape, isA<StadiumBorder>());

    // Selected.
    await tester.pumpWidget(chipWidget(selected: true));
    expect(getMaterial(tester).shape, isA<BeveledRectangleBorder>());

    // Focused.
    final FocusNode chipFocusNode = focusNode.children.first;
    chipFocusNode.requestFocus();
    await tester.pumpAndSettle();
    expect(getMaterial(tester).shape, isA<RoundedRectangleBorder>());

    // Hovered.
    final Offset center = tester.getCenter(find.byType(ChoiceChip));
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer();
    await gesture.moveTo(center);
    await tester.pumpAndSettle();
    expect(getMaterial(tester).shape, isA<ContinuousRectangleBorder>());

    // Pressed.
    await gesture.down(center);
    await tester.pumpAndSettle();
    expect(getMaterial(tester).shape, isA<CircleBorder>());

    // Disabled.
    await tester.pumpWidget(chipWidget(enabled: false));
    await tester.pumpAndSettle();
    expect(getMaterial(tester).shape, isA<BeveledRectangleBorder>());
  });

  testWidgets('Material3 - Chip uses stateful shape in different states', (
    WidgetTester tester,
  ) async {
    final focusNode = FocusNode();
    addTearDown(focusNode.dispose);

    OutlinedBorder? getShape(Set<WidgetState> states) {
      if (states.contains(WidgetState.disabled)) {
        return const BeveledRectangleBorder();
      } else if (states.contains(WidgetState.pressed)) {
        return const CircleBorder();
      } else if (states.contains(WidgetState.hovered)) {
        return const ContinuousRectangleBorder();
      } else if (states.contains(WidgetState.focused)) {
        return const RoundedRectangleBorder();
      } else if (states.contains(WidgetState.selected)) {
        return const BeveledRectangleBorder();
      }
      return null;
    }

    Widget chipWidget({bool enabled = true, bool selected = false}) {
      return MaterialApp(
        home: Scaffold(
          body: Focus(
            focusNode: focusNode,
            child: ChoiceChip(
              selected: selected,
              label: const Text('Chip'),
              shape: _TestWidgetStateOutlinedBorder(getShape),
              onSelected: enabled ? (_) {} : null,
            ),
          ),
        ),
      );
    }

    // Default, not disabled. Defers to default shape.
    await tester.pumpWidget(chipWidget());
    expect(getMaterial(tester).shape, isA<RoundedRectangleBorder>());

    // Selected.
    await tester.pumpWidget(chipWidget(selected: true));
    expect(getMaterial(tester).shape, isA<BeveledRectangleBorder>());

    // Focused.
    final FocusNode chipFocusNode = focusNode.children.first;
    chipFocusNode.requestFocus();
    await tester.pumpAndSettle();
    expect(getMaterial(tester).shape, isA<RoundedRectangleBorder>());

    // Hovered.
    final Offset center = tester.getCenter(find.byType(ChoiceChip));
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer();
    await gesture.moveTo(center);
    await tester.pumpAndSettle();
    expect(getMaterial(tester).shape, isA<ContinuousRectangleBorder>());

    // Pressed.
    await gesture.down(center);
    await tester.pumpAndSettle();
    expect(getMaterial(tester).shape, isA<CircleBorder>());

    // Disabled.
    await tester.pumpWidget(chipWidget(enabled: false));
    await tester.pumpAndSettle();
    expect(getMaterial(tester).shape, isA<BeveledRectangleBorder>());
  });

  testWidgets('Material2 - Chip defers to theme, if shape and side resolves to null', (
    WidgetTester tester,
  ) async {
    const OutlinedBorder themeShape = StadiumBorder();
    const OutlinedBorder selectedShape = RoundedRectangleBorder();
    const themeBorderSide = BorderSide(color: Color(0x00000001));
    const selectedBorderSide = BorderSide(color: Color(0x00000002));

    OutlinedBorder? getShape(Set<WidgetState> states) {
      if (states.contains(WidgetState.selected)) {
        return selectedShape;
      }
      return null;
    }

    BorderSide? getBorderSide(Set<WidgetState> states) {
      if (states.contains(WidgetState.selected)) {
        return selectedBorderSide;
      }
      return null;
    }

    Widget chipWidget({bool enabled = true, bool selected = false}) {
      return MaterialApp(
        theme: ThemeData(
          useMaterial3: false,
          chipTheme: ThemeData().chipTheme.copyWith(shape: themeShape, side: themeBorderSide),
        ),
        home: Scaffold(
          body: ChoiceChip(
            selected: selected,
            label: const Text('Chip'),
            shape: _TestWidgetStateOutlinedBorder(getShape),
            side: _TestWidgetStateBorderSide(getBorderSide),
            onSelected: enabled ? (_) {} : null,
          ),
        ),
      );
    }

    // Default, not disabled. Defer to theme.
    await tester.pumpWidget(chipWidget());
    expect(getMaterial(tester).shape, isA<StadiumBorder>());
    expect(
      find.byType(RawChip),
      paints
        ..rrect()
        ..rrect(color: themeBorderSide.color),
    );

    // Selected.
    await tester.pumpWidget(chipWidget(selected: true));
    expect(getMaterial(tester).shape, isA<RoundedRectangleBorder>());
    expect(
      find.byType(RawChip),
      paints
        ..rect()
        ..drrect(color: selectedBorderSide.color),
    );
  });

  testWidgets('Chip defers to theme, if shape and side resolves to null', (
    WidgetTester tester,
  ) async {
    const OutlinedBorder themeShape = StadiumBorder();
    const OutlinedBorder selectedShape = RoundedRectangleBorder();
    const themeBorderSide = BorderSide(color: Color(0x00000001));
    const selectedBorderSide = BorderSide(color: Color(0x00000002));

    OutlinedBorder? getShape(Set<WidgetState> states) {
      if (states.contains(WidgetState.selected)) {
        return selectedShape;
      }
      return null;
    }

    BorderSide? getBorderSide(Set<WidgetState> states) {
      if (states.contains(WidgetState.selected)) {
        return selectedBorderSide;
      }
      return null;
    }

    Widget chipWidget({bool enabled = true, bool selected = false}) {
      return MaterialApp(
        theme: ThemeData(
          chipTheme: ThemeData().chipTheme.copyWith(shape: themeShape, side: themeBorderSide),
        ),
        home: Scaffold(
          body: ChoiceChip(
            selected: selected,
            label: const Text('Chip'),
            shape: _TestWidgetStateOutlinedBorder(getShape),
            side: _TestWidgetStateBorderSide(getBorderSide),
            onSelected: enabled ? (_) {} : null,
          ),
        ),
      );
    }

    // Default, not disabled. Defer to theme.
    await tester.pumpWidget(chipWidget());
    expect(getMaterial(tester).shape, isA<StadiumBorder>());
    expect(
      find.byType(RawChip),
      paints
        ..rrect()
        ..rrect(color: themeBorderSide.color),
    );

    // Selected.
    await tester.pumpWidget(chipWidget(selected: true));
    expect(getMaterial(tester).shape, isA<RoundedRectangleBorder>());
    expect(
      find.byType(RawChip),
      paints
        ..rect()
        ..drrect(color: selectedBorderSide.color),
    );
  });

  testWidgets('Material2 - Chip responds to density changes', (WidgetTester tester) async {
    const key = Key('test');
    const textKey = Key('test text');
    const iconKey = Key('test icon');
    const avatarKey = Key('test avatar');
    Future<void> buildTest(VisualDensity visualDensity) async {
      return tester.pumpWidget(
        MaterialApp(
          theme: ThemeData(useMaterial3: false),
          home: Material(
            child: Center(
              child: Column(
                children: <Widget>[
                  InputChip(
                    visualDensity: visualDensity,
                    key: key,
                    onPressed: () {},
                    onDeleted: () {},
                    label: const Text('Test', key: textKey),
                    deleteIcon: const Icon(Icons.delete, key: iconKey),
                    avatar: const Icon(Icons.play_arrow, key: avatarKey),
                  ),
                ],
              ),
            ),
          ),
        ),
      );
    }

    // The Chips only change in size vertically in response to density, so
    // horizontal changes aren't expected.
    await buildTest(VisualDensity.standard);
    Rect box = tester.getRect(find.byKey(key));
    Rect textBox = tester.getRect(find.byKey(textKey));
    Rect iconBox = tester.getRect(find.byKey(iconKey));
    Rect avatarBox = tester.getRect(find.byKey(avatarKey));
    expect(box.size, equals(const Size(128, 32.0 + 16.0)));
    expect(textBox.size, equals(const Size(56, 14)));
    expect(iconBox.size, equals(const Size(18, 18)));
    expect(avatarBox.size, equals(const Size(18, 18)));
    expect(textBox.top, equals(17));
    expect(box.bottom - textBox.bottom, equals(17));
    expect(textBox.left, equals(372));
    expect(box.right - textBox.right, equals(36));

    // Try decreasing density (with higher density numbers).
    await buildTest(const VisualDensity(horizontal: 3.0, vertical: 3.0));
    box = tester.getRect(find.byKey(key));
    textBox = tester.getRect(find.byKey(textKey));
    iconBox = tester.getRect(find.byKey(iconKey));
    avatarBox = tester.getRect(find.byKey(avatarKey));
    expect(box.size, equals(const Size(128, 60)));
    expect(textBox.size, equals(const Size(56, 14)));
    expect(iconBox.size, equals(const Size(18, 18)));
    expect(avatarBox.size, equals(const Size(18, 18)));
    expect(textBox.top, equals(23));
    expect(box.bottom - textBox.bottom, equals(23));
    expect(textBox.left, equals(372));
    expect(box.right - textBox.right, equals(36));

    // Try increasing density (with lower density numbers).
    await buildTest(const VisualDensity(horizontal: -3.0, vertical: -3.0));
    box = tester.getRect(find.byKey(key));
    textBox = tester.getRect(find.byKey(textKey));
    iconBox = tester.getRect(find.byKey(iconKey));
    avatarBox = tester.getRect(find.byKey(avatarKey));
    expect(box.size, equals(const Size(128, 36)));
    expect(textBox.size, equals(const Size(56, 14)));
    expect(iconBox.size, equals(const Size(18, 18)));
    expect(avatarBox.size, equals(const Size(18, 18)));
    expect(textBox.top, equals(11));
    expect(box.bottom - textBox.bottom, equals(11));
    expect(textBox.left, equals(372));
    expect(box.right - textBox.right, equals(36));

    // Now test that horizontal and vertical are wired correctly. Negating the
    // horizontal should have no change over what's above.
    await buildTest(const VisualDensity(horizontal: 3.0, vertical: -3.0));
    await tester.pumpAndSettle();
    box = tester.getRect(find.byKey(key));
    textBox = tester.getRect(find.byKey(textKey));
    iconBox = tester.getRect(find.byKey(iconKey));
    avatarBox = tester.getRect(find.byKey(avatarKey));
    expect(box.size, equals(const Size(128, 36)));
    expect(textBox.size, equals(const Size(56, 14)));
    expect(iconBox.size, equals(const Size(18, 18)));
    expect(avatarBox.size, equals(const Size(18, 18)));
    expect(textBox.top, equals(11));
    expect(box.bottom - textBox.bottom, equals(11));
    expect(textBox.left, equals(372));
    expect(box.right - textBox.right, equals(36));

    // Make sure the "Comfortable" setting is the spec'd size
    await buildTest(VisualDensity.comfortable);
    await tester.pumpAndSettle();
    box = tester.getRect(find.byKey(key));
    expect(box.size, equals(const Size(128, 28.0 + 16.0)));

    // Make sure the "Compact" setting is the spec'd size
    await buildTest(VisualDensity.compact);
    await tester.pumpAndSettle();
    box = tester.getRect(find.byKey(key));
    expect(box.size, equals(const Size(128, 24.0 + 16.0)));
  });

  testWidgets('Material3 - Chip responds to density changes', (WidgetTester tester) async {
    const key = Key('test');
    const textKey = Key('test text');
    const iconKey = Key('test icon');
    const avatarKey = Key('test avatar');
    Future<void> buildTest(VisualDensity visualDensity) async {
      return tester.pumpWidget(
        MaterialApp(
          home: Material(
            child: Center(
              child: Column(
                children: <Widget>[
                  InputChip(
                    visualDensity: visualDensity,
                    key: key,
                    onPressed: () {},
                    onDeleted: () {},
                    label: const Text('Test', key: textKey),
                    deleteIcon: const Icon(Icons.delete, key: iconKey),
                    avatar: const Icon(Icons.play_arrow, key: avatarKey),
                  ),
                ],
              ),
            ),
          ),
        ),
      );
    }

    // The Chips only change in size vertically in response to density, so
    // horizontal changes aren't expected.
    await buildTest(VisualDensity.standard);
    Rect box = tester.getRect(find.byKey(key));
    Rect textBox = tester.getRect(find.byKey(textKey));
    Rect iconBox = tester.getRect(find.byKey(iconKey));
    Rect avatarBox = tester.getRect(find.byKey(avatarKey));
    expect(box.size.width, moreOrLessEquals(130.4, epsilon: 0.1));
    expect(box.size.height, equals(32.0 + 16.0));
    expect(textBox.size.width, moreOrLessEquals(56.4, epsilon: 0.1));
    expect(textBox.size.height, equals(20.0));
    expect(iconBox.size, equals(const Size(18, 18)));
    expect(avatarBox.size, equals(const Size(18, 18)));
    expect(textBox.top, equals(14));
    expect(box.bottom - textBox.bottom, equals(14));
    expect(textBox.left, moreOrLessEquals(371.79, epsilon: 0.1));
    expect(box.right - textBox.right, equals(37));

    // Try decreasing density (with higher density numbers).
    await buildTest(const VisualDensity(horizontal: 3.0, vertical: 3.0));
    box = tester.getRect(find.byKey(key));
    textBox = tester.getRect(find.byKey(textKey));
    iconBox = tester.getRect(find.byKey(iconKey));
    avatarBox = tester.getRect(find.byKey(avatarKey));
    expect(box.size.width, moreOrLessEquals(130.4, epsilon: 0.1));
    expect(box.size.height, equals(60));
    expect(textBox.size.width, moreOrLessEquals(56.4, epsilon: 0.1));
    expect(textBox.size.height, equals(20.0));
    expect(iconBox.size, equals(const Size(18, 18)));
    expect(avatarBox.size, equals(const Size(18, 18)));
    expect(textBox.top, equals(20));
    expect(box.bottom - textBox.bottom, equals(20));
    expect(textBox.left, moreOrLessEquals(371.79, epsilon: 0.1));
    expect(box.right - textBox.right, equals(37));

    // Try increasing density (with lower density numbers).
    await buildTest(const VisualDensity(horizontal: -3.0, vertical: -3.0));
    box = tester.getRect(find.byKey(key));
    textBox = tester.getRect(find.byKey(textKey));
    iconBox = tester.getRect(find.byKey(iconKey));
    avatarBox = tester.getRect(find.byKey(avatarKey));
    expect(box.size.width, moreOrLessEquals(130.4, epsilon: 0.1));
    expect(box.size.height, equals(36));
    expect(textBox.size.width, moreOrLessEquals(56.4, epsilon: 0.1));
    expect(textBox.size.height, equals(20.0));
    expect(iconBox.size, equals(const Size(18, 18)));
    expect(avatarBox.size, equals(const Size(18, 18)));
    expect(textBox.top, equals(8));
    expect(box.bottom - textBox.bottom, equals(8));
    expect(textBox.left, moreOrLessEquals(371.79, epsilon: 0.1));
    expect(box.right - textBox.right, equals(37));

    // Now test that horizontal and vertical are wired correctly. Negating the
    // horizontal should have no change over what's above.
    await buildTest(const VisualDensity(horizontal: 3.0, vertical: -3.0));
    await tester.pumpAndSettle();
    box = tester.getRect(find.byKey(key));
    textBox = tester.getRect(find.byKey(textKey));
    iconBox = tester.getRect(find.byKey(iconKey));
    avatarBox = tester.getRect(find.byKey(avatarKey));
    expect(box.size.width, moreOrLessEquals(130.4, epsilon: 0.1));
    expect(box.size.height, equals(36));
    expect(textBox.size.width, moreOrLessEquals(56.4, epsilon: 0.1));
    expect(textBox.size.height, equals(20.0));
    expect(iconBox.size, equals(const Size(18, 18)));
    expect(avatarBox.size, equals(const Size(18, 18)));
    expect(textBox.top, equals(8));
    expect(box.bottom - textBox.bottom, equals(8));
    expect(textBox.left, moreOrLessEquals(371.79, epsilon: 0.1));
    expect(box.right - textBox.right, equals(37));

    // Make sure the "Comfortable" setting is the spec'd size
    await buildTest(VisualDensity.comfortable);
    await tester.pumpAndSettle();
    box = tester.getRect(find.byKey(key));
    expect(box.size.width, moreOrLessEquals(130.4, epsilon: 0.1));
    expect(box.size.height, equals(28.0 + 16.0));

    // Make sure the "Compact" setting is the spec'd size
    await buildTest(VisualDensity.compact);
    await tester.pumpAndSettle();
    box = tester.getRect(find.byKey(key));
    expect(box.size.width, moreOrLessEquals(130.4, epsilon: 0.1));
    expect(box.size.height, equals(24.0 + 16.0));
  });

  testWidgets('Chip delete button tooltip is disabled if deleteButtonTooltipMessage is empty', (
    WidgetTester tester,
  ) async {
    final deleteButtonKey = UniqueKey();
    await tester.pumpWidget(
      chipWithOptionalDeleteButton(
        deleteButtonKey: deleteButtonKey,
        deletable: true,
        deleteButtonTooltipMessage: '',
      ),
    );

    // Hover over the delete icon of the chip
    final Offset centerOfDeleteButton = tester.getCenter(find.byKey(deleteButtonKey));
    final TestGesture hoverGesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await hoverGesture.moveTo(centerOfDeleteButton);
    addTearDown(hoverGesture.removePointer);

    await tester.pump();

    // Wait for some more time while hovering over the delete button
    await tester.pumpAndSettle();

    // There should be no delete button tooltip
    expect(findTooltipContainer(''), findsNothing);
  });

  testWidgets('Disabling delete button tooltip does not disable chip tooltip', (
    WidgetTester tester,
  ) async {
    final deleteButtonKey = UniqueKey();
    await tester.pumpWidget(
      chipWithOptionalDeleteButton(
        deleteButtonKey: deleteButtonKey,
        deletable: true,
        deleteButtonTooltipMessage: '',
        chipTooltip: 'Chip Tooltip',
      ),
    );

    // Hover over the delete icon of the chip
    final Offset centerOfDeleteButton = tester.getCenter(find.byKey(deleteButtonKey));
    final TestGesture hoverGesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await hoverGesture.moveTo(centerOfDeleteButton);
    addTearDown(hoverGesture.removePointer);

    await tester.pump();

    // Wait for some more time while hovering over the delete button
    await tester.pumpAndSettle();

    // There should be no delete button tooltip
    expect(findTooltipContainer(''), findsNothing);
    // There should be a chip tooltip, however.
    expect(findTooltipContainer('Chip Tooltip'), findsOneWidget);
  });

  testWidgets('Triggering delete button tooltip does not trigger Chip tooltip', (
    WidgetTester tester,
  ) async {
    final deleteButtonKey = UniqueKey();
    await tester.pumpWidget(
      chipWithOptionalDeleteButton(
        deleteButtonKey: deleteButtonKey,
        deletable: true,
        chipTooltip: 'Chip Tooltip',
      ),
    );

    // Hover over the delete icon of the chip
    final Offset centerOfDeleteButton = tester.getCenter(find.byKey(deleteButtonKey));
    final TestGesture hoverGesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await hoverGesture.moveTo(centerOfDeleteButton);
    addTearDown(hoverGesture.removePointer);

    await tester.pump();

    // Wait for some more time while hovering over the delete button
    await tester.pumpAndSettle();

    // There should not be a chip tooltip
    expect(findTooltipContainer('Chip Tooltip'), findsNothing);
    // There should be a delete button tooltip
    expect(findTooltipContainer('Delete'), findsOneWidget);
  });

  testWidgets('intrinsicHeight implementation meets constraints', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/49478.
    await tester.pumpWidget(
      wrapForChip(
        child: const Chip(label: Text('text'), padding: EdgeInsets.symmetric(horizontal: 20)),
      ),
    );

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

  testWidgets('Material2 - Chip background color and shape are drawn on Ink', (
    WidgetTester tester,
  ) async {
    const backgroundColor = Color(0xff00ff00);
    const OutlinedBorder shape = ContinuousRectangleBorder();

    await tester.pumpWidget(
      wrapForChip(
        theme: ThemeData(useMaterial3: false),
        child: const RawChip(label: Text('text'), backgroundColor: backgroundColor, shape: shape),
      ),
    );

    final Ink ink = tester.widget(
      find.descendant(of: find.byType(RawChip), matching: find.byType(Ink)),
    );
    final decoration = ink.decoration! as ShapeDecoration;
    expect(decoration.color, backgroundColor);
    expect(decoration.shape, shape);
  });

  testWidgets('Material3 - Chip background color and shape are drawn on Ink', (
    WidgetTester tester,
  ) async {
    const backgroundColor = Color(0xff00ff00);
    const OutlinedBorder shape = ContinuousRectangleBorder();
    final theme = ThemeData();

    await tester.pumpWidget(
      wrapForChip(
        theme: theme,
        child: const RawChip(label: Text('text'), backgroundColor: backgroundColor, shape: shape),
      ),
    );

    final Ink ink = tester.widget(
      find.descendant(of: find.byType(RawChip), matching: find.byType(Ink)),
    );
    final decoration = ink.decoration! as ShapeDecoration;
    expect(decoration.color, backgroundColor);
    expect(
      decoration.shape,
      shape.copyWith(side: BorderSide(color: theme.colorScheme.outlineVariant)),
    );
  });

  testWidgets('Chip highlight color is drawn on top of the backgroundColor', (
    WidgetTester tester,
  ) async {
    final focusNode = FocusNode(debugLabel: 'RawChip');
    addTearDown(focusNode.dispose);
    tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
    const backgroundColor = Color(0xff00ff00);

    await tester.pumpWidget(
      wrapForChip(
        child: RawChip(
          label: const Text('text'),
          backgroundColor: backgroundColor,
          autofocus: true,
          focusNode: focusNode,
          onPressed: () {},
        ),
      ),
    );

    await tester.pumpAndSettle();

    expect(focusNode.hasPrimaryFocus, isTrue);
    expect(
      find.byType(Material).last,
      paints
        // Background color is drawn first.
        ..rrect(color: backgroundColor)
        // Highlight color is drawn on top of the background color.
        ..rect(color: const Color(0x1f000000)),
    );
  });

  testWidgets('RawChip.color resolves material states', (WidgetTester tester) async {
    const disabledSelectedColor = Color(0xffffff00);
    const disabledColor = Color(0xff00ff00);
    const backgroundColor = Color(0xff0000ff);
    const selectedColor = Color(0xffff0000);
    Widget buildApp({required bool enabled, required bool selected}) {
      return wrapForChip(
        child: RawChip(
          isEnabled: enabled,
          selected: selected,
          color: WidgetStateProperty.resolveWith((Set<WidgetState> states) {
            if (states.contains(WidgetState.disabled) && states.contains(WidgetState.selected)) {
              return disabledSelectedColor;
            }
            if (states.contains(WidgetState.disabled)) {
              return disabledColor;
            }
            if (states.contains(WidgetState.selected)) {
              return selectedColor;
            }
            return backgroundColor;
          }),
          label: const Text('RawChip'),
        ),
      );
    }

    // Test enabled chip.
    await tester.pumpWidget(buildApp(enabled: true, selected: false));

    // Enabled chip should have the provided backgroundColor.
    expect(getMaterialBox(tester), paints..rrect(color: backgroundColor));

    // Test disabled chip.
    await tester.pumpWidget(buildApp(enabled: false, selected: false));
    await tester.pumpAndSettle();

    // Disabled chip should have the provided disabledColor.
    expect(getMaterialBox(tester), paints..rrect(color: disabledColor));

    // Test enabled & selected chip.
    await tester.pumpWidget(buildApp(enabled: true, selected: true));
    await tester.pumpAndSettle();

    // Enabled & selected chip should have the provided selectedColor.
    expect(getMaterialBox(tester), paints..rrect(color: selectedColor));

    // Test disabled & selected chip.
    await tester.pumpWidget(buildApp(enabled: false, selected: true));
    await tester.pumpAndSettle();

    // Disabled & selected chip should have the provided disabledSelectedColor.
    expect(getMaterialBox(tester), paints..rrect(color: disabledSelectedColor));
  });

  testWidgets('RawChip uses provided state color properties', (WidgetTester tester) async {
    const disabledColor = Color(0xff00ff00);
    const backgroundColor = Color(0xff0000ff);
    const selectedColor = Color(0xffff0000);
    Widget buildApp({required bool enabled, required bool selected}) {
      return wrapForChip(
        child: RawChip(
          isEnabled: enabled,
          selected: selected,
          disabledColor: disabledColor,
          backgroundColor: backgroundColor,
          selectedColor: selectedColor,
          label: const Text('RawChip'),
        ),
      );
    }

    // Test enabled chip.
    await tester.pumpWidget(buildApp(enabled: true, selected: false));

    // Enabled chip should have the provided backgroundColor.
    expect(getMaterialBox(tester), paints..rrect(color: backgroundColor));

    // Test disabled chip.
    await tester.pumpWidget(buildApp(enabled: false, selected: false));
    await tester.pumpAndSettle();

    // Disabled chip should have the provided disabledColor.
    expect(getMaterialBox(tester), paints..rrect(color: disabledColor));

    // Test enabled & selected chip.
    await tester.pumpWidget(buildApp(enabled: true, selected: true));
    await tester.pumpAndSettle();

    // Enabled & selected chip should have the provided selectedColor.
    expect(getMaterialBox(tester), paints..rrect(color: selectedColor));
  });

  testWidgets('Delete button tap target area does not include label', (WidgetTester tester) async {
    var calledDelete = false;
    await tester.pumpWidget(
      wrapForChip(
        child: Column(
          children: <Widget>[
            Chip(
              label: const Text('Chip'),
              onDeleted: () {
                calledDelete = true;
              },
            ),
          ],
        ),
      ),
    );

    // Tap on the delete button.
    await tester.tapAt(tester.getCenter(find.byType(Icon)));
    await tester.pump();
    expect(calledDelete, isTrue);
    calledDelete = false;

    final Offset labelCenter = tester.getCenter(find.text('Chip'));

    // Tap on the label.
    await tester.tapAt(labelCenter);
    await tester.pump();
    expect(calledDelete, isFalse);

    // Tap before end of the label.
    final Size labelSize = tester.getSize(find.text('Chip'));
    await tester.tapAt(Offset(labelCenter.dx + (labelSize.width / 2) - 1, labelCenter.dy));
    await tester.pump();
    expect(calledDelete, isFalse);

    // Tap after end of the label.
    await tester.tapAt(Offset(labelCenter.dx + (labelSize.width / 2) + 0.01, labelCenter.dy));
    await tester.pump();
    expect(calledDelete, isTrue);
  });

  // This is a regression test for https://github.com/flutter/flutter/pull/133615.
  testWidgets('Material3 - Custom shape without provided side uses default side', (
    WidgetTester tester,
  ) async {
    final theme = ThemeData();
    await tester.pumpWidget(
      MaterialApp(
        theme: theme,
        home: const Material(
          child: Center(
            child: RawChip(
              // No side provided.
              shape: StadiumBorder(),
              label: Text('RawChip'),
            ),
          ),
        ),
      ),
    );

    // Chip should have the default side.
    expect(
      getMaterial(tester).shape,
      StadiumBorder(side: BorderSide(color: theme.colorScheme.outlineVariant)),
    );
  });

  testWidgets("Material3 - RawChip.shape's side is used when provided", (
    WidgetTester tester,
  ) async {
    Widget buildChip({OutlinedBorder? shape, BorderSide? side}) {
      return MaterialApp(
        home: Material(
          child: Center(
            child: RawChip(shape: shape, side: side, label: const Text('RawChip')),
          ),
        ),
      );
    }

    // Test [RawChip.shape] with a side.
    await tester.pumpWidget(
      buildChip(
        shape: const RoundedRectangleBorder(
          side: BorderSide(color: Color(0xffff00ff)),
          borderRadius: BorderRadius.all(Radius.circular(7.0)),
        ),
      ),
    );

    // Chip should have the provided shape and the side from [RawChip.shape].
    expect(
      getMaterial(tester).shape,
      const RoundedRectangleBorder(
        side: BorderSide(color: Color(0xffff00ff)),
        borderRadius: BorderRadius.all(Radius.circular(7.0)),
      ),
    );

    // Test [RawChip.shape] with a side and [RawChip.side].
    await tester.pumpWidget(
      buildChip(
        shape: const RoundedRectangleBorder(
          side: BorderSide(color: Color(0xffff00ff)),
          borderRadius: BorderRadius.all(Radius.circular(7.0)),
        ),
        side: const BorderSide(color: Color(0xfffff000)),
      ),
    );
    await tester.pumpAndSettle();

    // Chip use shape from [RawChip.shape] and the side from [RawChip.side].
    // [RawChip.shape]'s side should be ignored.
    expect(
      getMaterial(tester).shape,
      const RoundedRectangleBorder(
        side: BorderSide(color: Color(0xfffff000)),
        borderRadius: BorderRadius.all(Radius.circular(7.0)),
      ),
    );
  });

  testWidgets('Material3 - Chip.iconTheme respects default iconTheme.size', (
    WidgetTester tester,
  ) async {
    Widget buildChip({IconThemeData? iconTheme}) {
      return MaterialApp(
        home: Directionality(
          textDirection: TextDirection.ltr,
          child: Material(
            child: Center(
              child: RawChip(
                iconTheme: iconTheme,
                avatar: const Icon(Icons.add),
                label: const SizedBox(width: 100, height: 100),
                onSelected: (bool newValue) {},
              ),
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildChip(iconTheme: const IconThemeData(color: Color(0xff332211))));

    // Icon should have the default chip iconSize.
    expect(getIconData(tester).size, 18.0);
    expect(getIconData(tester).color, const Color(0xff332211));

    // Icon should have the provided iconSize.
    await tester.pumpWidget(
      buildChip(iconTheme: const IconThemeData(color: Color(0xff112233), size: 23.0)),
    );
    await tester.pumpAndSettle();

    expect(getIconData(tester).size, 23.0);
    expect(getIconData(tester).color, const Color(0xff112233));
  });

  // This is a regression test for https://github.com/flutter/flutter/issues/138287.
  testWidgets("Enabling and disabling Chip with Tooltip doesn't throw an exception", (
    WidgetTester tester,
  ) async {
    var isEnabled = true;

    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: Center(
            child: StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
                return Column(
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[
                    RawChip(
                      tooltip: 'tooltip',
                      isEnabled: isEnabled,
                      onPressed: isEnabled ? () {} : null,
                      label: const Text('RawChip'),
                    ),
                    ElevatedButton(
                      onPressed: () {
                        setState(() {
                          isEnabled = !isEnabled;
                        });
                      },
                      child: Text('${isEnabled ? 'Disable' : 'Enable'} Chip'),
                    ),
                  ],
                );
              },
            ),
          ),
        ),
      ),
    );

    // Tap the elevated button to disable the chip with a tooltip.
    await tester.tap(find.widgetWithText(ElevatedButton, 'Disable Chip'));
    await tester.pumpAndSettle();

    // No exception should be thrown.
    expect(tester.takeException(), isNull);

    // Tap the elevated button to enable the chip with a tooltip.
    await tester.tap(find.widgetWithText(ElevatedButton, 'Enable Chip'));
    await tester.pumpAndSettle();

    // No exception should be thrown.
    expect(tester.takeException(), isNull);
  });

  testWidgets('Delete button is visible on disabled RawChip', (WidgetTester tester) async {
    await tester.pumpWidget(
      wrapForChip(
        child: RawChip(isEnabled: false, label: const Text('Label'), onDeleted: () {}),
      ),
    );

    // Delete button should be visible.
    await expectLater(
      find.byType(RawChip),
      matchesGoldenFile('raw_chip.disabled.delete_button.png'),
    );
  });

  testWidgets('Delete button tooltip is not shown on disabled RawChip', (
    WidgetTester tester,
  ) async {
    Widget buildChip({bool enabled = true}) {
      return wrapForChip(
        child: RawChip(isEnabled: enabled, label: const Text('Label'), onDeleted: () {}),
      );
    }

    // Test enabled chip.
    await tester.pumpWidget(buildChip());

    final Offset deleteButtonLocation = tester.getCenter(find.byType(Icon));
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.moveTo(deleteButtonLocation);
    await tester.pump();

    // Delete button tooltip should be visible.
    expect(findTooltipContainer('Delete'), findsOneWidget);

    // Test disabled chip.
    await tester.pumpWidget(buildChip(enabled: false));
    await tester.pump();

    // Delete button tooltip should not be visible.
    expect(findTooltipContainer('Delete'), findsNothing);
  });

  testWidgets('Chip avatar layout constraints can be customized', (WidgetTester tester) async {
    const border = 1.0;
    const iconSize = 18.0;
    const labelPadding = 8.0;
    const padding = 8.0;
    const labelSize = Size(100, 100);

    Widget buildChip({BoxConstraints? avatarBoxConstraints}) {
      return wrapForChip(
        child: Center(
          child: Chip(
            avatarBoxConstraints: avatarBoxConstraints,
            avatar: const Icon(Icons.favorite),
            label: Container(
              width: labelSize.width,
              height: labelSize.width,
              color: const Color(0xFFFF0000),
            ),
          ),
        ),
      );
    }

    // Test default avatar layout constraints.
    await tester.pumpWidget(buildChip());

    expect(tester.getSize(find.byType(Chip)).width, equals(234.0));
    expect(tester.getSize(find.byType(Chip)).height, equals(118.0));

    // Calculate the distance between avatar and chip edges.
    Offset chipTopLeft = tester.getTopLeft(find.byWidget(getMaterial(tester)));
    final Offset avatarCenter = tester.getCenter(find.byIcon(Icons.favorite));
    expect(chipTopLeft.dx, avatarCenter.dx - (labelSize.width / 2) - padding - border);
    expect(chipTopLeft.dy, avatarCenter.dy - (labelSize.width / 2) - padding - border);

    // Calculate the distance between avatar and label.
    Offset labelTopLeft = tester.getTopLeft(find.byType(Container));
    expect(labelTopLeft.dx, avatarCenter.dx + (labelSize.width / 2) + labelPadding);

    // Test custom avatar layout constraints.
    await tester.pumpWidget(buildChip(avatarBoxConstraints: const BoxConstraints.tightForFinite()));
    await tester.pump();

    expect(tester.getSize(find.byType(Chip)).width, equals(152.0));
    expect(tester.getSize(find.byType(Chip)).height, equals(118.0));

    // Calculate the distance between avatar and chip edges.
    chipTopLeft = tester.getTopLeft(find.byWidget(getMaterial(tester)));
    expect(chipTopLeft.dx, avatarCenter.dx - (iconSize / 2) - padding - border);
    expect(chipTopLeft.dy, avatarCenter.dy - (labelSize.width / 2) - padding - border);

    // Calculate the distance between avatar and label.
    labelTopLeft = tester.getTopLeft(find.byType(Container));
    expect(labelTopLeft.dx, avatarCenter.dx + (iconSize / 2) + labelPadding);
  });

  testWidgets('RawChip avatar layout constraints can be customized', (WidgetTester tester) async {
    const border = 1.0;
    const iconSize = 18.0;
    const labelPadding = 8.0;
    const padding = 8.0;
    const labelSize = Size(100, 100);

    Widget buildChip({BoxConstraints? avatarBoxConstraints}) {
      return wrapForChip(
        child: Center(
          child: RawChip(
            avatarBoxConstraints: avatarBoxConstraints,
            avatar: const Icon(Icons.favorite),
            label: Container(
              width: labelSize.width,
              height: labelSize.width,
              color: const Color(0xFFFF0000),
            ),
          ),
        ),
      );
    }

    // Test default avatar layout constraints.
    await tester.pumpWidget(buildChip());

    expect(tester.getSize(find.byType(RawChip)).width, equals(234.0));
    expect(tester.getSize(find.byType(RawChip)).height, equals(118.0));

    // Calculate the distance between avatar and chip edges.
    Offset chipTopLeft = tester.getTopLeft(find.byWidget(getMaterial(tester)));
    final Offset avatarCenter = tester.getCenter(find.byIcon(Icons.favorite));
    expect(chipTopLeft.dx, avatarCenter.dx - (labelSize.width / 2) - padding - border);
    expect(chipTopLeft.dy, avatarCenter.dy - (labelSize.width / 2) - padding - border);

    // Calculate the distance between avatar and label.
    Offset labelTopLeft = tester.getTopLeft(find.byType(Container));
    expect(labelTopLeft.dx, avatarCenter.dx + (labelSize.width / 2) + labelPadding);

    // Test custom avatar layout constraints.
    await tester.pumpWidget(buildChip(avatarBoxConstraints: const BoxConstraints.tightForFinite()));
    await tester.pump();

    expect(tester.getSize(find.byType(RawChip)).width, equals(152.0));
    expect(tester.getSize(find.byType(RawChip)).height, equals(118.0));

    // Calculate the distance between avatar and chip edges.
    chipTopLeft = tester.getTopLeft(find.byWidget(getMaterial(tester)));
    expect(chipTopLeft.dx, avatarCenter.dx - (iconSize / 2) - padding - border);
    expect(chipTopLeft.dy, avatarCenter.dy - (labelSize.width / 2) - padding - border);

    // Calculate the distance between avatar and label.
    labelTopLeft = tester.getTopLeft(find.byType(Container));
    expect(labelTopLeft.dx, avatarCenter.dx + (iconSize / 2) + labelPadding);
  });

  testWidgets('Chip delete icon layout constraints can be customized', (WidgetTester tester) async {
    const border = 1.0;
    const iconSize = 18.0;
    const labelPadding = 8.0;
    const padding = 8.0;
    const labelSize = Size(100, 100);

    Widget buildChip({BoxConstraints? deleteIconBoxConstraints}) {
      return wrapForChip(
        child: Center(
          child: Chip(
            deleteIconBoxConstraints: deleteIconBoxConstraints,
            onDeleted: () {},
            label: Container(
              width: labelSize.width,
              height: labelSize.width,
              color: const Color(0xFFFF0000),
            ),
          ),
        ),
      );
    }

    // Test default delete icon layout constraints.
    await tester.pumpWidget(buildChip());

    expect(tester.getSize(find.byType(Chip)).width, equals(234.0));
    expect(tester.getSize(find.byType(Chip)).height, equals(118.0));

    // Calculate the distance between delete icon and chip edges.
    Offset chipTopRight = tester.getTopRight(find.byWidget(getMaterial(tester)));
    final Offset deleteIconCenter = tester.getCenter(find.byIcon(Icons.cancel));
    expect(chipTopRight.dx, deleteIconCenter.dx + (labelSize.width / 2) + padding + border);
    expect(chipTopRight.dy, deleteIconCenter.dy - (labelSize.width / 2) - padding - border);

    // Calculate the distance between delete icon and label.
    Offset labelTopRight = tester.getTopRight(find.byType(Container));
    expect(labelTopRight.dx, deleteIconCenter.dx - (labelSize.width / 2) - labelPadding);

    // Test custom avatar layout constraints.
    await tester.pumpWidget(
      buildChip(deleteIconBoxConstraints: const BoxConstraints.tightForFinite()),
    );
    await tester.pump();

    expect(tester.getSize(find.byType(Chip)).width, equals(152.0));
    expect(tester.getSize(find.byType(Chip)).height, equals(118.0));

    // Calculate the distance between delete icon and chip edges.
    chipTopRight = tester.getTopRight(find.byWidget(getMaterial(tester)));
    expect(chipTopRight.dx, deleteIconCenter.dx + (iconSize / 2) + padding + border);
    expect(chipTopRight.dy, deleteIconCenter.dy - (labelSize.width / 2) - padding - border);

    // Calculate the distance between delete icon and label.
    labelTopRight = tester.getTopRight(find.byType(Container));
    expect(labelTopRight.dx, deleteIconCenter.dx - (iconSize / 2) - labelPadding);
  });

  testWidgets('RawChip delete icon layout constraints can be customized', (
    WidgetTester tester,
  ) async {
    const border = 1.0;
    const iconSize = 18.0;
    const labelPadding = 8.0;
    const padding = 8.0;
    const labelSize = Size(100, 100);

    Widget buildChip({BoxConstraints? deleteIconBoxConstraints}) {
      return wrapForChip(
        child: Center(
          child: RawChip(
            deleteIconBoxConstraints: deleteIconBoxConstraints,
            onDeleted: () {},
            label: Container(
              width: labelSize.width,
              height: labelSize.width,
              color: const Color(0xFFFF0000),
            ),
          ),
        ),
      );
    }

    // Test default delete icon layout constraints.
    await tester.pumpWidget(buildChip());

    expect(tester.getSize(find.byType(RawChip)).width, equals(234.0));
    expect(tester.getSize(find.byType(RawChip)).height, equals(118.0));

    // Calculate the distance between delete icon and chip edges.
    Offset chipTopRight = tester.getTopRight(find.byWidget(getMaterial(tester)));
    final Offset deleteIconCenter = tester.getCenter(find.byIcon(Icons.cancel));
    expect(chipTopRight.dx, deleteIconCenter.dx + (labelSize.width / 2) + padding + border);
    expect(chipTopRight.dy, deleteIconCenter.dy - (labelSize.width / 2) - padding - border);

    // Calculate the distance between delete icon and label.
    Offset labelTopRight = tester.getTopRight(find.byType(Container));
    expect(labelTopRight.dx, deleteIconCenter.dx - (labelSize.width / 2) - labelPadding);

    // Test custom avatar layout constraints.
    await tester.pumpWidget(
      buildChip(deleteIconBoxConstraints: const BoxConstraints.tightForFinite()),
    );
    await tester.pump();

    expect(tester.getSize(find.byType(RawChip)).width, equals(152.0));
    expect(tester.getSize(find.byType(RawChip)).height, equals(118.0));

    // Calculate the distance between delete icon and chip edges.
    chipTopRight = tester.getTopRight(find.byWidget(getMaterial(tester)));
    expect(chipTopRight.dx, deleteIconCenter.dx + (iconSize / 2) + padding + border);
    expect(chipTopRight.dy, deleteIconCenter.dy - (labelSize.width / 2) - padding - border);

    // Calculate the distance between delete icon and label.
    labelTopRight = tester.getTopRight(find.byType(Container));
    expect(labelTopRight.dx, deleteIconCenter.dx - (iconSize / 2) - labelPadding);
  });

  testWidgets('Default delete button InkWell shape', (WidgetTester tester) async {
    await tester.pumpWidget(
      wrapForChip(
        child: Center(
          child: RawChip(onDeleted: () {}, label: const Text('RawChip')),
        ),
      ),
    );

    final InkWell deleteButtonInkWell = tester.widget<InkWell>(
      find.ancestor(of: find.byIcon(Icons.cancel), matching: find.byType(InkWell).last),
    );
    expect(deleteButtonInkWell.customBorder, const CircleBorder());
  });

  testWidgets('Default delete button overlay', (WidgetTester tester) async {
    final theme = ThemeData();
    await tester.pumpWidget(
      wrapForChip(
        child: Center(
          child: RawChip(onDeleted: () {}, label: const Text('RawChip')),
        ),
        theme: theme,
      ),
    );

    RenderObject inkFeatures = tester.allRenderObjects.firstWhere(
      (RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures',
    );
    expect(inkFeatures, isNot(paints..rect(color: theme.hoverColor)));
    expect(inkFeatures, paintsExactlyCountTimes(#clipPath, 0));

    // Hover over the delete icon.
    final Offset centerOfDeleteButton = tester.getCenter(find.byType(Icon));
    final TestGesture hoverGesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await hoverGesture.moveTo(centerOfDeleteButton);
    addTearDown(hoverGesture.removePointer);
    await tester.pumpAndSettle();

    inkFeatures = tester.allRenderObjects.firstWhere(
      (RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures',
    );
    expect(inkFeatures, paints..rect(color: theme.hoverColor));
    expect(inkFeatures, paintsExactlyCountTimes(#clipPath, 1));

    const expectedClipRect = Rect.fromLTRB(124.7, 10.0, 142.7, 28.0);
    final expectedClipPath = Path()..addRect(expectedClipRect);
    expect(
      inkFeatures,
      paints..clipPath(
        pathMatcher: coversSameAreaAs(
          expectedClipPath,
          areaToCompare: expectedClipRect.inflate(48.0),
          sampleSize: 100,
        ),
      ),
    );
  });

  group('Material 2', () {
    // These tests are only relevant for Material 2. Once Material 2
    // support is deprecated and the APIs are removed, these tests
    // can be deleted.

    testWidgets('M2 Chip defaults', (WidgetTester tester) async {
      late TextTheme textTheme;

      Widget buildFrame(Brightness brightness) {
        return MaterialApp(
          theme: ThemeData(brightness: brightness, useMaterial3: false),
          home: Scaffold(
            body: Center(
              child: Builder(
                builder: (BuildContext context) {
                  textTheme = Theme.of(context).textTheme;
                  return Chip(
                    avatar: const CircleAvatar(child: Text('A')),
                    label: const Text('Chip A'),
                    onDeleted: () {},
                  );
                },
              ),
            ),
          ),
        );
      }

      await tester.pumpWidget(buildFrame(Brightness.light));
      expect(
        getMaterialBox(tester),
        paints
          ..rrect()
          ..circle(color: const Color(0xff1976d2)),
      );
      expect(tester.getSize(find.byType(Chip)), const Size(156.0, 48.0));
      expect(getMaterial(tester).color, null);
      expect(getMaterial(tester).elevation, 0);
      expect(getMaterial(tester).shape, const StadiumBorder());
      expect(getIconData(tester).color, const Color(0xdd000000));
      expect(getIconData(tester).opacity, null);
      expect(getIconData(tester).size, 18.0);

      TextStyle labelStyle = getLabelStyle(tester, 'Chip A').style;
      expect(labelStyle.color?.value, 0xde000000);
      expect(labelStyle.fontFamily, textTheme.bodyLarge?.fontFamily);
      expect(labelStyle.fontFamilyFallback, textTheme.bodyLarge?.fontFamilyFallback);
      expect(labelStyle.fontFeatures, textTheme.bodyLarge?.fontFeatures);
      expect(labelStyle.fontSize, textTheme.bodyLarge?.fontSize);
      expect(labelStyle.fontStyle, textTheme.bodyLarge?.fontStyle);
      expect(labelStyle.fontWeight, textTheme.bodyLarge?.fontWeight);
      expect(labelStyle.height, textTheme.bodyLarge?.height);
      expect(labelStyle.inherit, textTheme.bodyLarge?.inherit);
      expect(labelStyle.leadingDistribution, textTheme.bodyLarge?.leadingDistribution);
      expect(labelStyle.letterSpacing, textTheme.bodyLarge?.letterSpacing);
      expect(labelStyle.overflow, textTheme.bodyLarge?.overflow);
      expect(labelStyle.textBaseline, textTheme.bodyLarge?.textBaseline);
      expect(labelStyle.wordSpacing, textTheme.bodyLarge?.wordSpacing);

      await tester.pumpWidget(buildFrame(Brightness.dark));
      await tester.pumpAndSettle(); // Theme transition animation
      expect(getMaterialBox(tester), paints..rrect(color: const Color(0x1fffffff)));
      expect(tester.getSize(find.byType(Chip)), const Size(156.0, 48.0));
      expect(getMaterial(tester).color, null);
      expect(getMaterial(tester).elevation, 0);
      expect(getMaterial(tester).shape, const StadiumBorder());
      expect(getIconData(tester).color?.value, 0xffffffff);
      expect(getIconData(tester).opacity, null);
      expect(getIconData(tester).size, 18.0);

      labelStyle = getLabelStyle(tester, 'Chip A').style;
      expect(labelStyle.color?.value, 0xdeffffff);
      expect(labelStyle.fontFamily, textTheme.bodyLarge?.fontFamily);
      expect(labelStyle.fontFamilyFallback, textTheme.bodyLarge?.fontFamilyFallback);
      expect(labelStyle.fontFeatures, textTheme.bodyLarge?.fontFeatures);
      expect(labelStyle.fontSize, textTheme.bodyLarge?.fontSize);
      expect(labelStyle.fontStyle, textTheme.bodyLarge?.fontStyle);
      expect(labelStyle.fontWeight, textTheme.bodyLarge?.fontWeight);
      expect(labelStyle.height, textTheme.bodyLarge?.height);
      expect(labelStyle.inherit, textTheme.bodyLarge?.inherit);
      expect(labelStyle.leadingDistribution, textTheme.bodyLarge?.leadingDistribution);
      expect(labelStyle.letterSpacing, textTheme.bodyLarge?.letterSpacing);
      expect(labelStyle.overflow, textTheme.bodyLarge?.overflow);
      expect(labelStyle.textBaseline, textTheme.bodyLarge?.textBaseline);
      expect(labelStyle.wordSpacing, textTheme.bodyLarge?.wordSpacing);
    });

    testWidgets('Chip uses the right theme colors for the right components', (
      WidgetTester tester,
    ) async {
      final themeData = ThemeData(
        platform: TargetPlatform.android,
        primarySwatch: Colors.blue,
        useMaterial3: false,
      );
      final defaultChipTheme = ChipThemeData.fromDefaults(
        brightness: themeData.brightness,
        secondaryColor: Colors.blue,
        labelStyle: themeData.textTheme.bodyLarge!,
      );
      var value = false;
      Widget buildApp({
        ChipThemeData? chipTheme,
        Widget? avatar,
        Widget? deleteIcon,
        bool isSelectable = true,
        bool isPressable = false,
        bool isDeletable = true,
        bool showCheckmark = true,
      }) {
        chipTheme ??= defaultChipTheme;
        return wrapForChip(
          child: Theme(
            data: themeData,
            child: ChipTheme(
              data: chipTheme,
              child: StatefulBuilder(
                builder: (BuildContext context, StateSetter setState) {
                  return RawChip(
                    showCheckmark: showCheckmark,
                    onDeleted: isDeletable ? () {} : null,
                    avatar: avatar,
                    deleteIcon: deleteIcon,
                    isEnabled: isSelectable || isPressable,
                    shape: chipTheme?.shape,
                    selected: isSelectable && value,
                    label: Text('$value'),
                    onSelected: isSelectable
                        ? (bool newValue) {
                            setState(() {
                              value = newValue;
                            });
                          }
                        : null,
                    onPressed: isPressable
                        ? () {
                            setState(() {
                              value = true;
                            });
                          }
                        : null,
                  );
                },
              ),
            ),
          ),
        );
      }

      await tester.pumpWidget(buildApp());

      RenderBox materialBox = getMaterialBox(tester);
      IconThemeData iconData = getIconData(tester);
      DefaultTextStyle labelStyle = getLabelStyle(tester, 'false');

      // Check default theme for enabled chip.
      expect(materialBox, paints..rrect(color: defaultChipTheme.backgroundColor));
      expect(iconData.color, equals(const Color(0xde000000)));
      expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));

      // Check default theme for disabled chip.
      await tester.pumpWidget(buildApp(isSelectable: false));
      await tester.pumpAndSettle();
      materialBox = getMaterialBox(tester);
      labelStyle = getLabelStyle(tester, 'false');
      expect(materialBox, paints..rrect(color: defaultChipTheme.disabledColor));
      expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));

      // Check default theme for enabled and selected chip.
      await tester.pumpWidget(buildApp());
      await tester.pumpAndSettle();
      await tester.tap(find.byType(RawChip));
      await tester.pumpAndSettle();
      materialBox = getMaterialBox(tester);
      expect(materialBox, paints..rrect(color: defaultChipTheme.selectedColor));

      // Check default theme for disabled and selected chip.
      await tester.pumpWidget(buildApp(isSelectable: false));
      await tester.pumpAndSettle();
      materialBox = getMaterialBox(tester);
      labelStyle = getLabelStyle(tester, 'true');
      expect(materialBox, paints..rrect(color: defaultChipTheme.disabledColor));
      expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));

      // Enable the chip again.
      await tester.pumpWidget(buildApp());
      await tester.pumpAndSettle();
      // Tap to unselect the chip.
      await tester.tap(find.byType(RawChip));
      await tester.pumpAndSettle();

      // Apply a custom theme.
      const customColor1 = Color(0xcafefeed);
      const customColor2 = Color(0xdeadbeef);
      const customColor3 = Color(0xbeefcafe);
      const customColor4 = Color(0xaddedabe);
      final ChipThemeData customTheme = defaultChipTheme.copyWith(
        brightness: Brightness.dark,
        backgroundColor: customColor1,
        disabledColor: customColor2,
        selectedColor: customColor3,
        deleteIconColor: customColor4,
      );
      await tester.pumpWidget(buildApp(chipTheme: customTheme));
      await tester.pumpAndSettle();
      materialBox = getMaterialBox(tester);
      iconData = getIconData(tester);
      labelStyle = getLabelStyle(tester, 'false');

      // Check custom theme for enabled chip.
      expect(materialBox, paints..rrect(color: customTheme.backgroundColor));
      expect(iconData.color, equals(customTheme.deleteIconColor));
      expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));

      // Check custom theme with disabled widget.
      await tester.pumpWidget(buildApp(chipTheme: customTheme, isSelectable: false));
      await tester.pumpAndSettle();
      materialBox = getMaterialBox(tester);
      labelStyle = getLabelStyle(tester, 'false');
      expect(materialBox, paints..rrect(color: customTheme.disabledColor));
      expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));

      // Check custom theme for enabled and selected chip.
      await tester.pumpWidget(buildApp(chipTheme: customTheme));
      await tester.pumpAndSettle();
      await tester.tap(find.byType(RawChip));
      await tester.pumpAndSettle();
      materialBox = getMaterialBox(tester);
      expect(materialBox, paints..rrect(color: customTheme.selectedColor));

      // Check custom theme for disabled and selected chip.
      await tester.pumpWidget(buildApp(chipTheme: customTheme, isSelectable: false));
      await tester.pumpAndSettle();
      materialBox = getMaterialBox(tester);
      labelStyle = getLabelStyle(tester, 'true');
      expect(materialBox, paints..rrect(color: customTheme.disabledColor));
      expect(labelStyle.style.color, equals(Colors.black.withAlpha(0xde)));
    });
  });

  testWidgets('Chip Baseline location', (WidgetTester tester) async {
    const text = Text('A', style: TextStyle(fontSize: 10.0, height: 1.0));
    await tester.pumpWidget(
      wrapForChip(
        child: const Align(
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.baseline,
            textBaseline: TextBaseline.alphabetic,
            children: <Widget>[
              text,
              RawChip(label: text),
            ],
          ),
        ),
      ),
    );

    expect(find.text('A'), findsNWidgets(2));
    // Baseline aligning text.
    expect(tester.getTopLeft(find.text('A').first).dy, tester.getTopLeft(find.text('A').last).dy);
  });

  testWidgets('ChipThemeData.iconTheme updates avatar and delete icons', (
    WidgetTester tester,
  ) async {
    const iconColor = Color(0xffff00ff);
    const iconSize = 28.0;
    const IconData avatarIcon = Icons.favorite;
    const IconData deleteIcon = Icons.delete;

    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: Center(
            child: RawChip(
              iconTheme: const IconThemeData(color: iconColor, size: iconSize),
              avatar: const Icon(Icons.favorite),
              deleteIcon: const Icon(Icons.delete),
              onDeleted: () {},
              label: const SizedBox(height: 100),
            ),
          ),
        ),
      ),
    );

    // Test rendered icon size.
    final RenderBox avatarIconBox = tester.renderObject(find.byIcon(avatarIcon));
    final RenderBox deleteIconBox = tester.renderObject(find.byIcon(deleteIcon));
    expect(avatarIconBox.size.width, equals(iconSize));
    expect(deleteIconBox.size.width, equals(iconSize));

    // Test rendered icon color.
    expect(getIconStyle(tester, avatarIcon)?.color, iconColor);
    expect(getIconStyle(tester, deleteIcon)?.color, iconColor);
  });

  testWidgets('RawChip.deleteIconColor overrides iconTheme color', (WidgetTester tester) async {
    const iconColor = Color(0xffff00ff);
    const deleteIconColor = Color(0xffff00ff);
    const IconData deleteIcon = Icons.delete;

    Widget buildChip({Color? deleteIconColor, Color? iconColor}) {
      return MaterialApp(
        home: Material(
          child: Center(
            child: RawChip(
              deleteIconColor: deleteIconColor,
              iconTheme: IconThemeData(color: iconColor),
              deleteIcon: const Icon(Icons.delete),
              onDeleted: () {},
              label: const SizedBox(height: 100),
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildChip(iconColor: iconColor));

    // Test rendered icon color.
    expect(getIconStyle(tester, deleteIcon)?.color, iconColor);

    await tester.pumpWidget(buildChip(deleteIconColor: deleteIconColor, iconColor: iconColor));

    // Test rendered icon color.
    expect(getIconStyle(tester, deleteIcon)?.color, deleteIconColor);
  });

  testWidgets('Chip label only does layout once', (WidgetTester tester) async {
    final renderLayoutCount = RenderLayoutCount();
    final Widget layoutCounter = Center(
      key: GlobalKey(),
      child: WidgetToRenderBoxAdapter(renderBox: renderLayoutCount),
    );

    await tester.pumpWidget(wrapForChip(child: RawChip(label: layoutCounter)));

    expect(renderLayoutCount.layoutCount, 1);
  });

  testWidgets('ChipAnimationStyle.enableAnimation overrides chip enable animation duration', (
    WidgetTester tester,
  ) async {
    const disabledColor = Color(0xffff0000);
    const backgroundColor = Color(0xff00ff00);
    var enabled = true;

    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: Center(
            child: StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
                return Column(
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[
                    RawChip(
                      chipAnimationStyle: ChipAnimationStyle(
                        enableAnimation: const AnimationStyle(
                          duration: Duration(milliseconds: 300),
                          reverseDuration: Duration(milliseconds: 150),
                        ),
                      ),
                      isEnabled: enabled,
                      disabledColor: disabledColor,
                      backgroundColor: backgroundColor,
                      label: const Text('RawChip'),
                    ),
                    ElevatedButton(
                      onPressed: () {
                        setState(() {
                          enabled = !enabled;
                        });
                      },
                      child: Text('${enabled ? 'Disable' : 'Enable'} Chip'),
                    ),
                  ],
                );
              },
            ),
          ),
        ),
      ),
    );

    final RenderBox materialBox = tester.firstRenderObject<RenderBox>(
      find.descendant(of: find.byType(RawChip), matching: find.byType(CustomPaint)),
    );

    // Test background color when the chip is enabled.
    expect(materialBox, paints..rrect(color: backgroundColor));

    await tester.tap(find.widgetWithText(ElevatedButton, 'Disable Chip'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 75));

    expect(materialBox, paints..rrect(color: const Color(0x80ff0000)));

    await tester.pump(const Duration(milliseconds: 75));

    // Test background color when the chip is disabled.
    expect(materialBox, paints..rrect(color: disabledColor));

    await tester.tap(find.widgetWithText(ElevatedButton, 'Enable Chip'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 150));

    expect(materialBox, paints..rrect(color: const Color(0x8000ff00)));

    await tester.pump(const Duration(milliseconds: 150));

    // Test background color when the chip is enabled.
    expect(materialBox, paints..rrect(color: backgroundColor));
  });

  testWidgets('ChipAnimationStyle.selectAnimation overrides chip selection animation duration', (
    WidgetTester tester,
  ) async {
    const backgroundColor = Color(0xff00ff00);
    const selectedColor = Color(0xff0000ff);
    var selected = false;

    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: Center(
            child: StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
                return Column(
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[
                    RawChip(
                      chipAnimationStyle: ChipAnimationStyle(
                        selectAnimation: const AnimationStyle(
                          duration: Duration(milliseconds: 600),
                          reverseDuration: Duration(milliseconds: 300),
                        ),
                      ),
                      backgroundColor: backgroundColor,
                      selectedColor: selectedColor,
                      selected: selected,
                      onSelected: (bool value) {},
                      label: const Text('RawChip'),
                    ),
                    ElevatedButton(
                      onPressed: () {
                        setState(() {
                          selected = !selected;
                        });
                      },
                      child: Text('${selected ? 'Unselect' : 'Select'} Chip'),
                    ),
                  ],
                );
              },
            ),
          ),
        ),
      ),
    );

    final RenderBox materialBox = tester.firstRenderObject<RenderBox>(
      find.descendant(of: find.byType(RawChip), matching: find.byType(CustomPaint)),
    );

    // Test background color when the chip is unselected.
    expect(materialBox, paints..rrect(color: backgroundColor));

    await tester.tap(find.widgetWithText(ElevatedButton, 'Select Chip'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 300));

    expect(materialBox, paints..rrect(color: const Color(0xc60000ff)));

    await tester.pump(const Duration(milliseconds: 300));

    // Test background color when the chip is selected.
    expect(materialBox, paints..rrect(color: selectedColor));

    await tester.tap(find.widgetWithText(ElevatedButton, 'Unselect Chip'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 150));

    expect(materialBox, paints..rrect(color: const Color(0x3900ff00)));

    await tester.pump(const Duration(milliseconds: 150));

    // Test background color when the chip is unselected.
    expect(materialBox, paints..rrect(color: backgroundColor));
  });

  testWidgets('ChipAnimationStyle.avatarDrawerAnimation overrides chip avatar animation duration', (
    WidgetTester tester,
  ) async {
    const checkmarkColor = Color(0xffff0000);
    var selected = false;

    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: Center(
            child: StatefulBuilder(
              builder: (BuildContext context, StateSetter setState) {
                return Column(
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[
                    RawChip(
                      chipAnimationStyle: ChipAnimationStyle(
                        avatarDrawerAnimation: const AnimationStyle(
                          duration: Duration(milliseconds: 800),
                          reverseDuration: Duration(milliseconds: 400),
                        ),
                      ),
                      checkmarkColor: checkmarkColor,
                      selected: selected,
                      onSelected: (bool value) {},
                      label: const Text('RawChip'),
                    ),
                    ElevatedButton(
                      onPressed: () {
                        setState(() {
                          selected = !selected;
                        });
                      },
                      child: Text('${selected ? 'Unselect' : 'Select'} Chip'),
                    ),
                  ],
                );
              },
            ),
          ),
        ),
      ),
    );

    final RenderBox materialBox = tester.firstRenderObject<RenderBox>(
      find.descendant(of: find.byType(RawChip), matching: find.byType(CustomPaint)),
    );

    // Test the checkmark is not visible yet.
    expect(materialBox, isNot(paints..path(color: checkmarkColor)));
    expect(tester.getSize(find.byType(RawChip)).width, closeTo(132.6, 0.1));

    await tester.tap(find.widgetWithText(ElevatedButton, 'Select Chip'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 400));

    expect(materialBox, paints..path(color: checkmarkColor));
    expect(tester.getSize(find.byType(RawChip)).width, closeTo(148.2, 0.1));

    await tester.pump(const Duration(milliseconds: 400));

    // Test the checkmark is fully visible.
    expect(materialBox, paints..path(color: checkmarkColor));
    expect(tester.getSize(find.byType(RawChip)).width, closeTo(152.6, 0.1));

    await tester.tap(find.widgetWithText(ElevatedButton, 'Unselect Chip'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 200));

    expect(materialBox, isNot(paints..path(color: checkmarkColor)));
    expect(tester.getSize(find.byType(RawChip)).width, closeTo(148.2, 0.1));

    await tester.pump(const Duration(milliseconds: 200));

    // Test if checkmark is removed.
    expect(materialBox, isNot(paints..path(color: checkmarkColor)));
    expect(tester.getSize(find.byType(RawChip)).width, closeTo(132.6, 0.1));
  });

  testWidgets(
    'ChipAnimationStyle.deleteDrawerAnimation overrides chip delete icon animation duration',
    (WidgetTester tester) async {
      var showDeleteIcon = false;
      await tester.pumpWidget(
        MaterialApp(
          home: Material(
            child: Center(
              child: StatefulBuilder(
                builder: (BuildContext context, StateSetter setState) {
                  return Column(
                    mainAxisSize: MainAxisSize.min,
                    children: <Widget>[
                      RawChip(
                        chipAnimationStyle: ChipAnimationStyle(
                          deleteDrawerAnimation: const AnimationStyle(
                            duration: Duration(milliseconds: 500),
                            reverseDuration: Duration(milliseconds: 250),
                          ),
                        ),
                        onDeleted: showDeleteIcon ? () {} : null,
                        label: const Text('RawChip'),
                      ),
                      ElevatedButton(
                        onPressed: () {
                          setState(() {
                            showDeleteIcon = !showDeleteIcon;
                          });
                        },
                        child: Text('${showDeleteIcon ? 'Hide' : 'Show'} delete icon'),
                      ),
                    ],
                  );
                },
              ),
            ),
          ),
        ),
      );

      // Test the delete icon is not visible yet.
      expect(find.byIcon(Icons.cancel), findsNothing);
      expect(tester.getSize(find.byType(RawChip)).width, closeTo(132.6, 0.1));

      await tester.tap(find.widgetWithText(ElevatedButton, 'Show delete icon'));
      await tester.pump();
      await tester.pump(const Duration(milliseconds: 250));

      expect(find.byIcon(Icons.cancel), findsOneWidget);
      expect(tester.getSize(find.byType(RawChip)).width, closeTo(148.2, 0.1));

      await tester.pump(const Duration(milliseconds: 250));

      // Test the delete icon is fully visible.
      expect(find.byIcon(Icons.cancel), findsOneWidget);
      expect(tester.getSize(find.byType(RawChip)).width, closeTo(152.6, 0.1));

      await tester.tap(find.widgetWithText(ElevatedButton, 'Hide delete icon'));
      await tester.pump();
      await tester.pump(const Duration(milliseconds: 125));

      expect(find.byIcon(Icons.cancel), findsOneWidget);
      expect(tester.getSize(find.byType(RawChip)).width, closeTo(148.2, 0.1));

      await tester.pump(const Duration(milliseconds: 125));

      // Test if delete icon is removed.
      expect(find.byIcon(Icons.cancel), findsNothing);
      expect(tester.getSize(find.byType(RawChip)).width, closeTo(132.6, 0.1));
    },
  );

  testWidgets('Chip.chipAnimationStyle is passed to RawChip', (WidgetTester tester) async {
    final chipAnimationStyle = ChipAnimationStyle(
      enableAnimation: AnimationStyle.noAnimation,
      selectAnimation: const AnimationStyle(duration: Durations.long3),
    );

    await tester.pumpWidget(
      wrapForChip(
        child: Center(
          child: Chip(chipAnimationStyle: chipAnimationStyle, label: const Text('Chip')),
        ),
      ),
    );

    expect(tester.widget<RawChip>(find.byType(RawChip)).chipAnimationStyle, chipAnimationStyle);
  });

  // Regression test for https://github.com/flutter/flutter/issues/157622.
  testWidgets('Chip does not glitch on hover when providing ThemeData.hoverColor', (
    WidgetTester tester,
  ) async {
    const themeDataHoverColor = Color(0xffff0000);
    const hoverColor = Color(0xff00ff00);
    const backgroundColor = Color(0xff0000ff);
    await tester.pumpWidget(
      wrapForChip(
        theme: ThemeData(hoverColor: themeDataHoverColor),
        child: Center(
          child: RawChip(
            color: WidgetStateProperty.resolveWith((Set<WidgetState> states) {
              if (states.contains(WidgetState.hovered)) {
                return hoverColor;
              }
              return backgroundColor;
            }),
            label: const Text('Chip'),
            onPressed: () {},
          ),
        ),
      ),
    );

    expect(getMaterialBox(tester), paints..rrect(color: backgroundColor));

    // Hover over the chip.
    final Offset center = tester.getCenter(find.byType(RawChip));
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer();
    await gesture.moveTo(center);
    addTearDown(gesture.removePointer);
    await tester.pumpAndSettle();

    expect(
      getMaterialBox(tester),
      paints
        ..rrect(color: hoverColor)
        ..rect(color: Colors.transparent),
    );
    expect(
      getMaterialBox(tester),
      isNot(
        paints
          ..rrect(color: hoverColor)
          ..rect(color: themeDataHoverColor),
      ),
    );
  });

  testWidgets('Chip mouse cursor behavior', (WidgetTester tester) async {
    const SystemMouseCursor customCursor = SystemMouseCursors.grab;

    await tester.pumpWidget(
      wrapForChip(
        child: const Center(
          child: Chip(mouseCursor: customCursor, label: Text('Chip')),
        ),
      ),
    );

    final TestGesture gesture = await tester.createGesture(
      kind: PointerDeviceKind.mouse,
      pointer: 1,
    );
    await gesture.addPointer(location: const Offset(10, 10));
    await tester.pump();
    expect(
      RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
      SystemMouseCursors.basic,
    );

    final Offset chip = tester.getCenter(find.text('Chip'));
    await gesture.moveTo(chip);
    await tester.pump();
    expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), customCursor);
  });

  testWidgets('Mouse cursor resolves in disabled states', (WidgetTester tester) async {
    tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;

    await tester.pumpWidget(
      wrapForChip(
        child: const Center(
          child: Chip(
            mouseCursor: WidgetStateMouseCursor.fromMap(<WidgetStatesConstraint, MouseCursor>{
              WidgetState.disabled: SystemMouseCursors.forbidden,
            }),
            label: Text('Chip'),
          ),
        ),
      ),
    );
    // Unfocused case.
    final TestGesture gesture1 = await tester.createGesture(
      kind: PointerDeviceKind.mouse,
      pointer: 1,
    );
    addTearDown(gesture1.removePointer);
    await gesture1.addPointer(location: tester.getCenter(find.text('Chip')));
    await tester.pump();
    await gesture1.moveTo(tester.getCenter(find.text('Chip')));
    expect(
      RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
      SystemMouseCursors.forbidden,
    );
  });

  testWidgets('Delete button semantic tap target complies with Material guideline', (
    WidgetTester tester,
  ) async {
    final SemanticsHandle handle = tester.ensureSemantics();
    final deleteKey = UniqueKey();
    await tester.pumpWidget(
      wrapForChip(
        child: Column(
          children: <Widget>[
            Chip(
              label: const Text('Label'),
              deleteIcon: Icon(Icons.delete, key: deleteKey),
              onDeleted: () {},
            ),
          ],
        ),
      ),
    );

    await expectLater(tester, meetsGuideline(androidTapTargetGuideline));

    final Finder deleteIcon = find.byKey(deleteKey);
    final Size iconSize = tester.getSize(deleteIcon);
    final Rect semanticRect = tester.getSemantics(deleteIcon).rect;

    // Semantic rect is centered around the icon.
    expect(semanticRect.center, Offset(iconSize.width / 2, iconSize.height / 2));

    handle.dispose();
  });

  testWidgets('Delete button semantic tap target is 32x32 on desktop', (WidgetTester tester) async {
    final SemanticsHandle handle = tester.ensureSemantics();
    final deleteKey = UniqueKey();
    await tester.pumpWidget(
      wrapForChip(
        child: Column(
          children: <Widget>[
            Chip(
              label: const Text('Label'),
              deleteIcon: Icon(Icons.delete, key: deleteKey),
              onDeleted: () {},
            ),
          ],
        ),
      ),
    );

    final Finder deleteIcon = find.byKey(deleteKey);
    final Size iconSize = tester.getSize(deleteIcon);
    final Rect semanticRect = tester.getSemantics(deleteIcon).rect;

    expect(semanticRect.size, const Size(32.0, 32.0));

    // Semantic rect is centered around the icon.
    expect(semanticRect.center, Offset(iconSize.width / 2, iconSize.height / 2));

    handle.dispose();
  }, variant: TargetPlatformVariant.desktop());

  testWidgets(
    'Delete button semantic tap target can be larger than the minimum interactive dimension',
    (WidgetTester tester) async {
      final SemanticsHandle handle = tester.ensureSemantics();
      final deleteKey = UniqueKey();
      const double iconHeight = 60;
      await tester.pumpWidget(
        wrapForChip(
          child: Column(
            children: <Widget>[
              Chip(
                label: const Text('Label', style: TextStyle(fontSize: iconHeight)),
                deleteIcon: Icon(Icons.delete, key: deleteKey, size: iconHeight),
                onDeleted: () {},
              ),
            ],
          ),
        ),
      );

      final Finder deleteIcon = find.byKey(deleteKey);
      final Size iconSize = tester.getSize(deleteIcon);
      final Rect semanticRect = tester.getSemantics(deleteIcon).rect;

      expect(semanticRect.size, iconSize);

      handle.dispose();
    },
  );

  testWidgets('Chip renders at zero area', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Center(
          child: SizedBox.shrink(
            child: Scaffold(body: Chip(label: Text('X'))),
          ),
        ),
      ),
    );
    final Finder xText = find.text('X');
    expect(tester.getSize(xText).isEmpty, isTrue);
  });

  testWidgets('RawChip renders at zero area', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Center(
          child: SizedBox.shrink(
            child: Scaffold(body: RawChip(label: Text('X'))),
          ),
        ),
      ),
    );
    final Finder xText = find.text('X');
    expect(tester.getSize(xText).isEmpty, isTrue);
  });
}

class _TestWidgetStateOutlinedBorder extends StadiumBorder implements WidgetStateOutlinedBorder {
  const _TestWidgetStateOutlinedBorder(this.resolver);

  final WidgetPropertyResolver<OutlinedBorder?> resolver;

  @override
  OutlinedBorder? resolve(Set<WidgetState> states) => resolver(states);
}

class _TestWidgetStateBorderSide extends WidgetStateBorderSide {
  const _TestWidgetStateBorderSide(this.resolver);

  final WidgetPropertyResolver<BorderSide?> resolver;

  @override
  BorderSide? resolve(Set<WidgetState> states) => resolver(states);
}

class RenderLayoutCount extends RenderBox {
  int layoutCount = 0;

  @override
  Size computeDryLayout(covariant BoxConstraints constraints) => constraints.biggest;

  @override
  void performLayout() {
    layoutCount += 1;
    size = constraints.biggest;
  }
}
