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

/// @docImport '_goldens_io.dart';
library;

import 'dart:convert' show LineSplitter;
import 'dart:math' as math;
import 'dart:ui' as ui;

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart' show Card;
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:matcher/expect.dart';
import 'package:matcher/src/expect/async_matcher.dart'; // ignore: implementation_imports
import 'package:vector_math/vector_math_64.dart' show Matrix3;

import '_matchers_io.dart'
    if (dart.library.js_interop) '_matchers_web.dart'
    show MatchesGoldenFile, captureImage;
import 'accessibility.dart';
import 'binding.dart';
import 'controller.dart';
import 'finders.dart';
import 'goldens.dart';
import 'widget_tester.dart' show WidgetTester;

/// Asserts that the [FinderBase] matches nothing in the available candidates.
///
/// ## Sample code
///
/// ```dart
/// expect(find.text('Save'), findsNothing);
/// ```
///
/// See also:
///
///  * [findsAny], when you want the finder to find one or more candidates.
///  * [findsOne], when you want the finder to find exactly one candidate.
///  * [findsExactly], when you want the finder to find a specific number of candidates.
///  * [findsAtLeast], when you want the finder to find at least a specific number of candidates.
const Matcher findsNothing = _FindsCountMatcher(null, 0);

/// Asserts that the [FinderBase] locates at least one widget in the widget tree.
///
/// This is equivalent to the preferred [findsAny] method.
///
/// ## Sample code
///
/// ```dart
/// expect(find.text('Save'), findsWidgets);
/// ```
///
/// See also:
///
///  * [findsNothing], when you want the finder to not find anything.
///  * [findsOne], when you want the finder to find exactly one candidate.
///  * [findsExactly], when you want the finder to find a specific number of candidates.
///  * [findsAtLeast], when you want the finder to find at least a specific number of candidates.
const Matcher findsWidgets = _FindsCountMatcher(1, null);

/// Asserts that the [FinderBase] locates at least one matching candidate.
///
/// ## Sample code
///
/// ```dart
/// expect(find.text('Save'), findsAny);
/// ```
///
/// See also:
///
///  * [findsNothing], when you want the finder to not find anything.
///  * [findsOne], when you want the finder to find exactly one candidate.
///  * [findsExactly], when you want the finder to find a specific number of candidates.
///  * [findsAtLeast], when you want the finder to find at least a specific number of candidates.
const Matcher findsAny = _FindsCountMatcher(1, null);

/// Asserts that the [FinderBase] locates at exactly one widget in the widget tree.
///
/// This is equivalent to the preferred [findsOne] method.
///
/// ## Sample code
///
/// ```dart
/// expect(find.text('Save'), findsOneWidget);
/// ```
///
/// See also:
///
///  * [findsNothing], when you want the finder to not find anything.
///  * [findsAny], when you want the finder to find one or more candidates.
///  * [findsExactly], when you want the finder to find a specific number of candidates.
///  * [findsAtLeast], when you want the finder to find at least a specific number of candidates.
const Matcher findsOneWidget = _FindsCountMatcher(1, 1);

/// Asserts that the [FinderBase] finds exactly one matching candidate.
///
/// ## Sample code
///
/// ```dart
/// expect(find.text('Save'), findsOne);
/// ```
///
/// See also:
///
///  * [findsNothing], when you want the finder to not find anything.
///  * [findsAny], when you want the finder to find one or more candidates.
///  * [findsExactly], when you want the finder to find a specific number candidates.
///  * [findsAtLeast], when you want the finder to find at least a specific number of candidates.
const Matcher findsOne = _FindsCountMatcher(1, 1);

/// Asserts that the [FinderBase] locates the specified number of widgets in the widget tree.
///
/// This is equivalent to the preferred [findsExactly] method.
///
/// ## Sample code
///
/// ```dart
/// expect(find.text('Save'), findsNWidgets(2));
/// ```
///
/// See also:
///
///  * [findsNothing], when you want the finder to not find anything.
///  * [findsAny], when you want the finder to find one or more candidates.
///  * [findsOne], when you want the finder to find exactly one candidate.
///  * [findsAtLeast], when you want the finder to find at least a specific number of candidates.
Matcher findsNWidgets(int n) => _FindsCountMatcher(n, n);

/// Asserts that the [FinderBase] locates the specified number of candidates.
///
/// ## Sample code
///
/// ```dart
/// expect(find.text('Save'), findsExactly(2));
/// ```
///
/// See also:
///
///  * [findsNothing], when you want the finder to not find anything.
///  * [findsAny], when you want the finder to find one or more candidates.
///  * [findsOne], when you want the finder to find exactly one candidates.
///  * [findsAtLeast], when you want the finder to find at least a specific number of candidates.
Matcher findsExactly(int n) => _FindsCountMatcher(n, n);

/// Asserts that the [FinderBase] locates at least a number of widgets in the widget tree.
///
/// This is equivalent to the preferred [findsAtLeast] method.
///
/// ## Sample code
///
/// ```dart
/// expect(find.text('Save'), findsAtLeastNWidgets(2));
/// ```
///
/// See also:
///
///  * [findsNothing], when you want the finder to not find anything.
///  * [findsAny], when you want the finder to find one or more candidates.
///  * [findsOne], when you want the finder to find exactly one candidate.
///  * [findsExactly], when you want the finder to find a specific number of candidates.
Matcher findsAtLeastNWidgets(int n) => _FindsCountMatcher(n, null);

/// Asserts that the [FinderBase] locates at least the given number of candidates.
///
/// ## Sample code
///
/// ```dart
/// expect(find.text('Save'), findsAtLeast(2));
/// ```
///
/// See also:
///
///  * [findsNothing], when you want the finder to not find anything.
///  * [findsAny], when you want the finder to find one or more candidates.
///  * [findsOne], when you want the finder to find exactly one candidates.
///  * [findsExactly], when you want the finder to find a specific number of candidates.
Matcher findsAtLeast(int n) => _FindsCountMatcher(n, null);

/// Asserts that the [Finder] locates a single widget that has at
/// least one [Offstage] widget ancestor.
///
/// It's important to use a full finder, since by default finders exclude
/// offstage widgets.
///
/// ## Sample code
///
/// ```dart
/// expect(find.text('Save', skipOffstage: false), isOffstage);
/// ```
///
/// See also:
///
///  * [isOnstage], the opposite.
const Matcher isOffstage = _IsOffstage();

/// Asserts that the [Finder] locates a single widget that has no
/// [Offstage] widget ancestors.
///
/// See also:
///
///  * [isOffstage], the opposite.
const Matcher isOnstage = _IsOnstage();

/// Asserts that the [Finder] locates a single widget that has at
/// least one [Card] widget ancestor.
///
/// See also:
///
///  * [isNotInCard], the opposite.
const Matcher isInCard = _IsInCard();

/// Asserts that the [Finder] locates a single widget that has no
/// [Card] widget ancestors.
///
/// This is equivalent to `isNot(isInCard)`.
///
/// See also:
///
///  * [isInCard], the opposite.
const Matcher isNotInCard = _IsNotInCard();

/// Default threshold for [isSameColorAs] and [isSameColorSwatchAs].
const double colorEpsilon = 0.004;

/// Asserts that the object represents the same color swatch as [color] when
/// used to paint.
///
/// Specifically this matcher checks the object is of type [ColorSwatch] and its
/// color components fall below the delta specified by [threshold].
///
/// Note: This doesn't recurse into the swatches [Color] type, instead treating
/// them as [Color]s.
Matcher isSameColorSwatchAs<T>(ColorSwatch<T> color, {double threshold = colorEpsilon}) {
  return _ColorSwatchMatcher<T>(color, threshold);
}

/// Asserts that the object represents the same color as [color] when used to paint.
///
/// Specifically this matcher checks the object is of type [Color] and its color
/// components fall below the delta specified by [threshold].
Matcher isSameColorAs(Color color, {double threshold = colorEpsilon}) {
  return _ColorMatcher(color, threshold);
}

/// Asserts that the object is a [TextScaler] that reflects the user's font
/// scale preferences from the platform's accessibility settings.
///
/// This matcher is useful for verifying the text scaling within a widget subtree
/// respects the user accessibility preferences, and not accidentally being
/// shadowed by a [MediaQuery] with a different type of [TextScaler].
///
/// In widget tests, the value of the system font scale preference can be
/// changed via [TestPlatformDispatcher.textScaleFactorTestValue].
///
/// If `withScaleFactor` is specified and non-null, this matcher also asserts
/// that the [TextScaler]'s' `textScaleFactor` equals `withScaleFactor`.
Matcher isSystemTextScaler({double? withScaleFactor}) => _IsSystemTextScaler(withScaleFactor);

/// Asserts that an object's toString() is a plausible one-line description.
///
/// Specifically, this matcher checks that the string does not contains newline
/// characters, and does not have leading or trailing whitespace, is not
/// empty, and does not contain the default `Instance of ...` string.
const Matcher hasOneLineDescription = _HasOneLineDescription();

/// Asserts that an object's toStringDeep() is a plausible multiline
/// description.
///
/// Specifically, this matcher checks that an object's
/// `toStringDeep(prefixLineOne, prefixOtherLines)`:
///
///  * Does not have leading or trailing whitespace.
///  * Does not contain the default `Instance of ...` string.
///  * The last line has characters other than tree connector characters and
///    whitespace. For example: the line ` │ ║ ╎` has only tree connector
///    characters and whitespace.
///  * Does not contain lines with trailing white space.
///  * Has multiple lines.
///  * The first line starts with `prefixLineOne`
///  * All subsequent lines start with `prefixOtherLines`.
const Matcher hasAGoodToStringDeep = _HasGoodToStringDeep();

/// A matcher for functions that throw [FlutterError].
///
/// This is equivalent to `throwsA(isA<FlutterError>())`.
///
/// If you are trying to test whether a call to [WidgetTester.pumpWidget]
/// results in a [FlutterError], see [TestWidgetsFlutterBinding.takeException].
///
/// See also:
///
///  * [throwsAssertionError], to test if a function throws any [AssertionError].
///  * [throwsArgumentError], to test if a functions throws an [ArgumentError].
///  * [isFlutterError], to test if any object is a [FlutterError].
final Matcher throwsFlutterError = throwsA(isFlutterError);

/// A matcher for functions that throw [AssertionError].
///
/// This is equivalent to `throwsA(isA<AssertionError>())`.
///
/// If you are trying to test whether a call to [WidgetTester.pumpWidget]
/// results in an [AssertionError], see
/// [TestWidgetsFlutterBinding.takeException].
///
/// See also:
///
///  * [throwsFlutterError], to test if a function throws a [FlutterError].
///  * [throwsArgumentError], to test if a functions throws an [ArgumentError].
///  * [isAssertionError], to test if any object is any kind of [AssertionError].
final Matcher throwsAssertionError = throwsA(isAssertionError);

/// A matcher for [FlutterError].
///
/// This is equivalent to `isInstanceOf<FlutterError>()`.
///
/// See also:
///
///  * [throwsFlutterError], to test if a function throws a [FlutterError].
///  * [isAssertionError], to test if any object is any kind of [AssertionError].
final TypeMatcher<FlutterError> isFlutterError = isA<FlutterError>();

/// A matcher for [AssertionError].
///
/// This is equivalent to `isInstanceOf<AssertionError>()`.
///
/// See also:
///
///  * [throwsAssertionError], to test if a function throws any [AssertionError].
///  * [isFlutterError], to test if any object is a [FlutterError].
final TypeMatcher<AssertionError> isAssertionError = isA<AssertionError>();

/// A matcher that compares the type of the actual value to the type argument T.
///
/// This is identical to [isA] and is included for backwards compatibility.
TypeMatcher<T> isInstanceOf<T>() => isA<T>();

/// Asserts that two [double]s are equal, within some tolerated error.
///
/// {@template flutter.flutter_test.moreOrLessEquals}
/// Two values are considered equal if the difference between them is within
/// [precisionErrorTolerance] of the larger one. This is an arbitrary value
/// which can be adjusted using the `epsilon` argument. This matcher is intended
/// to compare floating point numbers that are the result of different sequences
/// of operations, such that they may have accumulated slightly different
/// errors.
/// {@endtemplate}
///
/// See also:
///
///  * [closeTo], which is identical except that the epsilon argument is
///    required and not named.
///  * [inInclusiveRange], which matches if the argument is in a specified
///    range.
///  * [rectMoreOrLessEquals] and [offsetMoreOrLessEquals], which do something
///    similar but for [Rect]s and [Offset]s respectively.
Matcher moreOrLessEquals(double value, {double epsilon = precisionErrorTolerance}) {
  return _MoreOrLessEquals(value, epsilon);
}

/// Asserts that two [Rect]s are equal, within some tolerated error.
///
/// {@macro flutter.flutter_test.moreOrLessEquals}
///
/// See also:
///
///  * [moreOrLessEquals], which is for [double]s.
///  * [offsetMoreOrLessEquals], which is for [Offset]s.
///  * [within], which offers a generic version of this functionality that can
///    be used to match [Rect]s as well as other types.
Matcher rectMoreOrLessEquals(Rect value, {double epsilon = precisionErrorTolerance}) {
  return _IsWithinDistance<Rect>(_rectDistance, value, epsilon);
}

/// Asserts that two [Matrix4]s are equal, within some tolerated error.
///
/// {@macro flutter.flutter_test.moreOrLessEquals}
///
/// See also:
///
///  * [moreOrLessEquals], which is for [double]s.
///  * [offsetMoreOrLessEquals], which is for [Offset]s.
///  * [matrix3MoreOrLessEquals], which is for [Matrix3]s.
Matcher matrixMoreOrLessEquals(Matrix4 value, {double epsilon = precisionErrorTolerance}) {
  return _IsWithinDistance<Matrix4>(_matrixDistance, value, epsilon);
}

/// Asserts that two [Matrix3]s are equal, within some tolerated error.
///
/// {@macro flutter.flutter_test.moreOrLessEquals}
///
/// See also:
///
///  * [moreOrLessEquals], which is for [double]s.
///  * [offsetMoreOrLessEquals], which is for [Offset]s.
///  * [matrixMoreOrLessEquals], which is for [Matrix4]s.
Matcher matrix3MoreOrLessEquals(Matrix3 value, {double epsilon = precisionErrorTolerance}) {
  return _IsWithinDistance<Matrix3>(_matrix3Distance, value, epsilon);
}

/// Asserts that two [Offset]s are equal, within some tolerated error.
///
/// {@macro flutter.flutter_test.moreOrLessEquals}
///
/// See also:
///
///  * [moreOrLessEquals], which is for [double]s.
///  * [rectMoreOrLessEquals], which is for [Rect]s.
///  * [within], which offers a generic version of this functionality that can
///    be used to match [Offset]s as well as other types.
Matcher offsetMoreOrLessEquals(Offset value, {double epsilon = precisionErrorTolerance}) {
  return _IsWithinDistance<Offset>(_offsetDistance, value, epsilon);
}

/// Asserts that two [String]s or `Iterable<String>`s are equal after
/// normalizing likely hash codes.
///
/// A `#` followed by 5 hexadecimal digits is assumed to be a short hash code
/// and is normalized to `#00000`.
///
/// Only [String] or `Iterable<String>` are allowed types for `value`.
///
/// See Also:
///
///  * [describeIdentity], a method that generates short descriptions of objects
///    with ids that match the pattern `#[0-9a-f]{5}`.
///  * [shortHash], a method that generates a 5 character long hexadecimal
///    [String] based on [Object.hashCode].
///  * [DiagnosticableTree.toStringDeep], a method that returns a [String]
///    typically containing multiple hash codes.
Matcher equalsIgnoringHashCodes(Object value) {
  assert(
    value is String || value is Iterable<String>,
    "Only String or Iterable<String> are allowed types for equalsIgnoringHashCodes, it doesn't accept ${value.runtimeType}",
  );
  return _EqualsIgnoringHashCodes(value);
}

/// A matcher for [MethodCall]s, asserting that it has the specified
/// method [name] and [arguments].
///
/// Arguments checking implements deep equality for [List] and [Map] types.
Matcher isMethodCall(String name, {required dynamic arguments}) {
  return _IsMethodCall(name, arguments);
}

/// Asserts that 2 paths cover the same area by sampling multiple points.
///
/// Samples at least [sampleSize]^2 points inside [areaToCompare], and asserts
/// that the [Path.contains] method returns the same value for each of the
/// points for both paths.
///
/// When using this matcher you typically want to use a rectangle larger than
/// the area you expect to paint in for [areaToCompare] to catch errors where
/// the path draws outside the expected area.
Matcher coversSameAreaAs(Path expectedPath, {required Rect areaToCompare, int sampleSize = 20}) =>
    _CoversSameAreaAs(expectedPath, areaToCompare: areaToCompare, sampleSize: sampleSize);

// Examples can assume:
// late Image image;
// late Future<Image> imageFuture;
// typedef MyWidget = Placeholder;
// late Future<ByteData> someFont;
// late WidgetTester tester;

/// Asserts that a [Finder], [Future<ui.Image>], or [ui.Image] matches the
/// golden image file identified by [key], with an optional [version] number.
///
/// For the case of a [Finder], the [Finder] must match exactly one widget and
/// the rendered image of the first [RepaintBoundary] ancestor of the widget is
/// treated as the image for the widget. As such, you may choose to wrap a test
/// widget in a [RepaintBoundary] to specify a particular focus for the test.
///
/// The [key] may be either a [Uri] or a [String] representation of a URL.
///
/// The [version] is a number that can be used to differentiate historical
/// golden files. This parameter is optional.
///
/// This is an asynchronous matcher, meaning that callers should use
/// [expectLater] when using this matcher and await the future returned by
/// [expectLater].
///
/// ## Golden File Testing
///
/// The term __golden file__ refers to a master image that is considered the true
/// rendering of a given widget, state, application, or other visual
/// representation you have chosen to capture.
///
/// The master golden image files that are tested against can be created or
/// updated by running `flutter test --update-goldens` on the test.
///
/// {@tool snippet}
/// Sample invocations of [matchesGoldenFile].
///
/// ```dart
/// await expectLater(
///   find.text('Save'),
///   matchesGoldenFile('save.png'),
/// );
///
/// await expectLater(
///   image,
///   matchesGoldenFile('save.png'),
/// );
///
/// await expectLater(
///   imageFuture,
///   matchesGoldenFile(
///     'save.png',
///     version: 2,
///   ),
/// );
///
/// await expectLater(
///   find.byType(MyWidget),
///   matchesGoldenFile('goldens/myWidget.png'),
/// );
/// ```
/// {@end-tool}
///
/// {@template flutter.flutter_test.matchesGoldenFile.custom_fonts}
/// ## Including Fonts
///
/// Custom fonts may render differently across different platforms, or
/// between different versions of Flutter. For example, a golden file generated
/// on Windows with fonts will likely differ from the one produced by another
/// operating system. Even on the same platform, if the generated golden is
/// tested with a different Flutter version, the test may fail and require an
/// updated image.
///
/// By default, the Flutter framework uses a font called 'Ahem' which shows
/// squares instead of characters, however, it is possible to render images using
/// custom fonts. For example, this is how to load the 'Roboto' font for a
/// golden test:
///
/// {@tool snippet}
/// How to load a custom font for golden images.
/// ```dart
/// testWidgets('Creating a golden image with a custom font', (WidgetTester tester) async {
///   // Assuming the 'Roboto.ttf' file is declared in the pubspec.yaml file
///   final Future<ByteData> font = rootBundle.load('path/to/font-file/Roboto.ttf');
///
///   final FontLoader fontLoader = FontLoader('Roboto')..addFont(font);
///   await fontLoader.load();
///
///   await tester.pumpWidget(const MyWidget());
///
///   await expectLater(
///     find.byType(MyWidget),
///     matchesGoldenFile('myWidget.png'),
///   );
/// });
/// ```
/// {@end-tool}
///
/// The example above loads the desired font only for that specific test. To load
/// a font for all golden file tests, the `FontLoader.load()` call could be
/// moved in the `flutter_test_config.dart`. In this way, the font will always be
/// loaded before a test:
///
/// {@tool snippet}
/// Loading a custom font from the flutter_test_config.dart file.
/// ```dart
/// Future<void> testExecutable(FutureOr<void> Function() testMain) async {
///   setUpAll(() async {
///     final FontLoader fontLoader = FontLoader('SomeFont')..addFont(someFont);
///     await fontLoader.load();
///   });
///
///   await testMain();
/// }
/// ```
/// {@end-tool}
/// {@endtemplate}
///
/// See also:
///
///  * [goldenFileComparator], which acts as the backend for this matcher.
///  * [LocalFileComparator], which is the default [GoldenFileComparator]
///    implementation for `flutter test`.
///  * [matchesReferenceImage], which should be used instead if you want to
///    verify that two different code paths create identical images.
///  * [flutter_test] for a discussion of test configurations, whereby callers
///    may swap out the backend for this matcher.
AsyncMatcher matchesGoldenFile(Object key, {int? version}) {
  return switch (key) {
    Uri() => MatchesGoldenFile(key, version),
    String() => MatchesGoldenFile.forStringPath(key, version),
    _ => throw ArgumentError('Unexpected type for golden file: ${key.runtimeType}'),
  };
}

/// Asserts that a [Finder], [Future<ui.Image>], or [ui.Image] matches a
/// reference image identified by [image].
///
/// For the case of a [Finder], the [Finder] must match exactly one widget and
/// the rendered image of the first [RepaintBoundary] ancestor of the widget is
/// treated as the image for the widget.
///
/// This is an asynchronous matcher, meaning that callers should use
/// [expectLater] when using this matcher and await the future returned by
/// [expectLater].
///
/// ## Sample code
///
/// ```dart
/// testWidgets('matchesReferenceImage', (WidgetTester tester) async {
///   final ui.Paint paint = ui.Paint()
///     ..style = ui.PaintingStyle.stroke
///     ..strokeWidth = 1.0;
///   final ui.PictureRecorder recorder = ui.PictureRecorder();
///   final ui.Canvas pictureCanvas = ui.Canvas(recorder);
///   pictureCanvas.drawCircle(Offset.zero, 20.0, paint);
///   final ui.Picture picture = recorder.endRecording();
///   addTearDown(picture.dispose);
///   ui.Image referenceImage = await picture.toImage(50, 50);
///   addTearDown(referenceImage.dispose);
///
///   await expectLater(find.text('Save'), matchesReferenceImage(referenceImage));
///   await expectLater(image, matchesReferenceImage(referenceImage));
///   await expectLater(imageFuture, matchesReferenceImage(referenceImage));
/// });
/// ```
///
/// See also:
///
///  * [matchesGoldenFile], which should be used instead if you need to verify
///    that a [Finder] or [ui.Image] matches a golden image.
AsyncMatcher matchesReferenceImage(ui.Image image) {
  return _MatchesReferenceImage(image);
}

/// Asserts that a [SemanticsNode] contains the specified information.
///
/// If either the label, hint, value, textDirection, or rect fields are not
/// provided, then they are not part of the comparison. All of the boolean
/// flag and action fields must match, and default to false.
///
/// To find a [SemanticsNode] directly, use [CommonFinders.semantics].
/// These methods will search the semantics tree directly and avoid the edge
/// cases that [SemanticsController.find] sometimes runs into.
///
/// To retrieve the semantics data of a widget, use [SemanticsController.find]
/// with a [FinderBase] that returns a single widget. Semantics must be enabled
/// in order to use this method.
///
/// ## Sample code
///
/// ```dart
/// testWidgets('matchesSemantics', (WidgetTester tester) async {
///   final SemanticsHandle handle = tester.ensureSemantics();
///   // ...
///   expect(tester.getSemantics(find.text('hello')), matchesSemantics(label: 'hello'));
///   handle.dispose();
/// });
/// ```
///
/// See also:
///
///   * [SemanticsController.find] under [WidgetTester.semantics], the tester method which retrieves semantics.
///   * [isSemantics], a similar matcher without default values for flags or actions.
Matcher matchesSemantics({
  String? identifier,
  String? traversalParentIdentifier,
  String? traversalChildIdentifier,
  String? label,
  AttributedString? attributedLabel,
  String? hint,
  AttributedString? attributedHint,
  String? value,
  AttributedString? attributedValue,
  String? increasedValue,
  AttributedString? attributedIncreasedValue,
  String? decreasedValue,
  AttributedString? attributedDecreasedValue,
  String? tooltip,
  TextDirection? textDirection,
  Rect? rect,
  Size? size,
  double? elevation,
  double? thickness,
  int? platformViewId,
  int? maxValueLength,
  int? currentValueLength,
  SemanticsValidationResult validationResult = SemanticsValidationResult.none,
  ui.SemanticsInputType? inputType,
  String? maxValue,
  String? minValue,
  ui.SemanticsRole? role,
  // Flags //
  bool hasCheckedState = false,
  bool isChecked = false,
  bool isCheckStateMixed = false,
  bool isSelected = false,
  bool hasSelectedState = false,
  bool isButton = false,
  bool isSlider = false,
  bool isKeyboardKey = false,
  bool isLink = false,
  bool isFocused = false,
  bool isFocusable = false,
  bool isTextField = false,
  bool isReadOnly = false,
  bool hasEnabledState = false,
  bool isEnabled = false,
  bool isInMutuallyExclusiveGroup = false,
  bool isHeader = false,
  bool isObscured = false,
  bool isMultiline = false,
  bool namesRoute = false,
  bool scopesRoute = false,
  bool isHidden = false,
  bool isImage = false,
  bool isLiveRegion = false,
  bool hasToggledState = false,
  bool isToggled = false,
  bool hasImplicitScrolling = false,
  bool hasExpandedState = false,
  bool isExpanded = false,
  bool hasRequiredState = false,
  bool isRequired = false,
  // Actions //
  bool hasTapAction = false,
  bool hasFocusAction = false,
  bool hasLongPressAction = false,
  bool hasScrollLeftAction = false,
  bool hasScrollRightAction = false,
  bool hasScrollUpAction = false,
  bool hasScrollDownAction = false,
  bool hasIncreaseAction = false,
  bool hasDecreaseAction = false,
  bool hasShowOnScreenAction = false,
  bool hasMoveCursorForwardByCharacterAction = false,
  bool hasMoveCursorBackwardByCharacterAction = false,
  bool hasMoveCursorForwardByWordAction = false,
  bool hasMoveCursorBackwardByWordAction = false,
  bool hasSetTextAction = false,
  bool hasSetSelectionAction = false,
  bool hasCopyAction = false,
  bool hasCutAction = false,
  bool hasPasteAction = false,
  bool hasDidGainAccessibilityFocusAction = false,
  bool hasDidLoseAccessibilityFocusAction = false,
  bool hasDismissAction = false,
  // Custom actions and overrides
  String? onTapHint,
  String? onLongPressHint,
  List<CustomSemanticsAction>? customActions,
  List<Matcher>? children,
}) {
  return _MatchesSemanticsData(
    identifier: identifier,
    traversalParentIdentifier: traversalParentIdentifier,
    traversalChildIdentifier: traversalChildIdentifier,
    label: label,
    attributedLabel: attributedLabel,
    hint: hint,
    attributedHint: attributedHint,
    value: value,
    attributedValue: attributedValue,
    increasedValue: increasedValue,
    attributedIncreasedValue: attributedIncreasedValue,
    decreasedValue: decreasedValue,
    attributedDecreasedValue: attributedDecreasedValue,
    tooltip: tooltip,
    textDirection: textDirection,
    rect: rect,
    size: size,
    platformViewId: platformViewId,
    customActions: customActions,
    maxValueLength: maxValueLength,
    currentValueLength: currentValueLength,
    validationResult: validationResult,
    inputType: inputType,
    minValue: minValue,
    maxValue: maxValue,
    role: role,
    // Flags
    hasCheckedState: hasCheckedState,
    isChecked: isChecked,
    isCheckStateMixed: isCheckStateMixed,
    isSelected: isSelected,
    hasSelectedState: hasSelectedState,
    isButton: isButton,
    isSlider: isSlider,
    isKeyboardKey: isKeyboardKey,
    isLink: isLink,
    isFocused: isFocused,
    isFocusable: isFocusable,
    isTextField: isTextField,
    isReadOnly: isReadOnly,
    hasEnabledState: hasEnabledState,
    isEnabled: isEnabled,
    isInMutuallyExclusiveGroup: isInMutuallyExclusiveGroup,
    isHeader: isHeader,
    isObscured: isObscured,
    isMultiline: isMultiline,
    namesRoute: namesRoute,
    scopesRoute: scopesRoute,
    isHidden: isHidden,
    isImage: isImage,
    isLiveRegion: isLiveRegion,
    hasToggledState: hasToggledState,
    isToggled: isToggled,
    hasImplicitScrolling: hasImplicitScrolling,
    hasExpandedState: hasExpandedState,
    isExpanded: isExpanded,
    hasRequiredState: hasRequiredState,
    isRequired: isRequired,
    // Actions
    hasTapAction: hasTapAction,
    hasFocusAction: hasFocusAction,
    hasLongPressAction: hasLongPressAction,
    hasScrollLeftAction: hasScrollLeftAction,
    hasScrollRightAction: hasScrollRightAction,
    hasScrollUpAction: hasScrollUpAction,
    hasScrollDownAction: hasScrollDownAction,
    hasIncreaseAction: hasIncreaseAction,
    hasDecreaseAction: hasDecreaseAction,
    hasShowOnScreenAction: hasShowOnScreenAction,
    hasMoveCursorForwardByCharacterAction: hasMoveCursorForwardByCharacterAction,
    hasMoveCursorBackwardByCharacterAction: hasMoveCursorBackwardByCharacterAction,
    hasMoveCursorForwardByWordAction: hasMoveCursorForwardByWordAction,
    hasMoveCursorBackwardByWordAction: hasMoveCursorBackwardByWordAction,
    hasSetTextAction: hasSetTextAction,
    hasSetSelectionAction: hasSetSelectionAction,
    hasCopyAction: hasCopyAction,
    hasCutAction: hasCutAction,
    hasPasteAction: hasPasteAction,
    hasDidGainAccessibilityFocusAction: hasDidGainAccessibilityFocusAction,
    hasDidLoseAccessibilityFocusAction: hasDidLoseAccessibilityFocusAction,
    hasDismissAction: hasDismissAction,
    // Custom actions and overrides
    children: children,
    onLongPressHint: onLongPressHint,
    onTapHint: onTapHint,
  );
}

/// Asserts that a [SemanticsNode] contains the specified information.
///
/// There are no default expected values, so no unspecified values will be
/// validated.
///
/// To find a [SemanticsNode] directly, use [CommonFinders.semantics].
/// These methods will search the semantics tree directly and avoid the edge
/// cases that [SemanticsController.find] sometimes runs into.
///
/// To retrieve the semantics data of a widget, use [SemanticsController.find]
/// with a [FinderBase] that returns a single widget. Semantics must be enabled
/// in order to use this method.
///
/// See also:
///
///   * [SemanticsController.find] under [WidgetTester.semantics], the tester method which retrieves semantics.
///   * [matchesSemantics], a similar matcher with default values for flags and actions.
@Deprecated(
  'Migrate to isSemantics instead. '
  'This feature was deprecated after v3.40.0-1.0.pre.',
)
Matcher containsSemantics({
  String? identifier,
  String? traversalParentIdentifier,
  String? traversalChildIdentifier,
  String? label,
  AttributedString? attributedLabel,
  String? hint,
  AttributedString? attributedHint,
  String? value,
  AttributedString? attributedValue,
  String? increasedValue,
  AttributedString? attributedIncreasedValue,
  String? decreasedValue,
  AttributedString? attributedDecreasedValue,
  String? tooltip,
  TextDirection? textDirection,
  Rect? rect,
  Size? size,
  double? elevation,
  double? thickness,
  int? platformViewId,
  int? maxValueLength,
  int? currentValueLength,
  SemanticsValidationResult? validationResult,
  ui.SemanticsInputType? inputType,
  String? maxValue,
  String? minValue,
  // Flags
  bool? hasCheckedState,
  bool? isChecked,
  bool? isCheckStateMixed,
  bool? isSelected,
  bool? hasSelectedState,
  bool? isButton,
  bool? isSlider,
  bool? isKeyboardKey,
  bool? isLink,
  bool? isFocused,
  bool? isFocusable,
  bool? isTextField,
  bool? isReadOnly,
  bool? hasEnabledState,
  bool? isEnabled,
  bool? isInMutuallyExclusiveGroup,
  bool? isHeader,
  bool? isObscured,
  bool? isMultiline,
  bool? namesRoute,
  bool? scopesRoute,
  bool? isHidden,
  bool? isImage,
  bool? isLiveRegion,
  bool? hasToggledState,
  bool? isToggled,
  bool? hasImplicitScrolling,
  bool? hasExpandedState,
  bool? isExpanded,
  bool? hasRequiredState,
  bool? isRequired,
  // Actions
  bool? hasTapAction,
  bool? hasFocusAction,
  bool? hasLongPressAction,
  bool? hasScrollLeftAction,
  bool? hasScrollRightAction,
  bool? hasScrollUpAction,
  bool? hasScrollDownAction,
  bool? hasIncreaseAction,
  bool? hasDecreaseAction,
  bool? hasShowOnScreenAction,
  bool? hasMoveCursorForwardByCharacterAction,
  bool? hasMoveCursorBackwardByCharacterAction,
  bool? hasMoveCursorForwardByWordAction,
  bool? hasMoveCursorBackwardByWordAction,
  bool? hasSetTextAction,
  bool? hasSetSelectionAction,
  bool? hasCopyAction,
  bool? hasCutAction,
  bool? hasPasteAction,
  bool? hasDidGainAccessibilityFocusAction,
  bool? hasDidLoseAccessibilityFocusAction,
  bool? hasDismissAction,
  // Custom actions and overrides
  String? onTapHint,
  String? onLongPressHint,
  List<CustomSemanticsAction>? customActions,
  List<Matcher>? children,
}) => isSemantics(
  identifier: identifier,
  traversalParentIdentifier: traversalParentIdentifier,
  traversalChildIdentifier: traversalChildIdentifier,
  label: label,
  attributedLabel: attributedLabel,
  hint: hint,
  attributedHint: attributedHint,
  value: value,
  attributedValue: attributedValue,
  increasedValue: increasedValue,
  attributedIncreasedValue: attributedIncreasedValue,
  decreasedValue: decreasedValue,
  attributedDecreasedValue: attributedDecreasedValue,
  tooltip: tooltip,
  textDirection: textDirection,
  rect: rect,
  size: size,
  elevation: elevation,
  thickness: thickness,
  platformViewId: platformViewId,
  maxValueLength: maxValueLength,
  currentValueLength: currentValueLength,
  validationResult: validationResult,
  inputType: inputType,
  maxValue: maxValue,
  minValue: minValue,
  // Flags
  hasCheckedState: hasCheckedState,
  isChecked: isChecked,
  isCheckStateMixed: isCheckStateMixed,
  isSelected: isSelected,
  hasSelectedState: hasSelectedState,
  isButton: isButton,
  isSlider: isSlider,
  isKeyboardKey: isKeyboardKey,
  isLink: isLink,
  isFocused: isFocused,
  isFocusable: isFocusable,
  isTextField: isTextField,
  isReadOnly: isReadOnly,
  hasEnabledState: hasEnabledState,
  isEnabled: isEnabled,
  isInMutuallyExclusiveGroup: isInMutuallyExclusiveGroup,
  isHeader: isHeader,
  isObscured: isObscured,
  isMultiline: isMultiline,
  namesRoute: namesRoute,
  scopesRoute: scopesRoute,
  isHidden: isHidden,
  isImage: isImage,
  isLiveRegion: isLiveRegion,
  hasToggledState: hasToggledState,
  isToggled: isToggled,
  hasImplicitScrolling: hasImplicitScrolling,
  hasExpandedState: hasExpandedState,
  isExpanded: isExpanded,
  hasRequiredState: hasRequiredState,
  isRequired: isRequired,
  // Actions
  hasTapAction: hasTapAction,
  hasFocusAction: hasFocusAction,
  hasLongPressAction: hasLongPressAction,
  hasScrollLeftAction: hasScrollLeftAction,
  hasScrollRightAction: hasScrollRightAction,
  hasScrollUpAction: hasScrollUpAction,
  hasScrollDownAction: hasScrollDownAction,
  hasIncreaseAction: hasIncreaseAction,
  hasDecreaseAction: hasDecreaseAction,
  hasShowOnScreenAction: hasShowOnScreenAction,
  hasMoveCursorForwardByCharacterAction: hasMoveCursorForwardByCharacterAction,
  hasMoveCursorBackwardByCharacterAction: hasMoveCursorBackwardByCharacterAction,
  hasMoveCursorForwardByWordAction: hasMoveCursorForwardByWordAction,
  hasMoveCursorBackwardByWordAction: hasMoveCursorBackwardByWordAction,
  hasSetTextAction: hasSetTextAction,
  hasSetSelectionAction: hasSetSelectionAction,
  hasCopyAction: hasCopyAction,
  hasCutAction: hasCutAction,
  hasPasteAction: hasPasteAction,
  hasDidGainAccessibilityFocusAction: hasDidGainAccessibilityFocusAction,
  hasDidLoseAccessibilityFocusAction: hasDidLoseAccessibilityFocusAction,
  hasDismissAction: hasDismissAction,
  // Custom actions and overrides
  onTapHint: onTapHint,
  onLongPressHint: onLongPressHint,
  customActions: customActions,
  children: children,
);

/// Asserts that a [SemanticsNode] contains the specified information.
///
/// There are no default expected values, so no unspecified values will be
/// validated.
///
/// To find a [SemanticsNode] directly, use [CommonFinders.semantics].
/// These methods will search the semantics tree directly and avoid the edge
/// cases that [SemanticsController.find] sometimes runs into.
///
/// To retrieve the semantics data of a widget, use [SemanticsController.find]
/// with a [FinderBase] that returns a single widget. Semantics must be enabled
/// in order to use this method.
///
/// ## Sample code
///
/// ```dart
/// testWidgets('isSemantics', (WidgetTester tester) async {
///   final SemanticsHandle handle = tester.ensureSemantics();
///   // ...
///   expect(tester.getSemantics(find.text('hello')), isSemantics(label: 'hello'));
///   handle.dispose();
/// });
/// ```
///
/// See also:
///
///   * [SemanticsController.find] under [WidgetTester.semantics], the tester method which retrieves semantics.
///   * [matchesSemantics], a similar matcher with default values for flags and actions.
Matcher isSemantics({
  String? identifier,
  String? traversalParentIdentifier,
  String? traversalChildIdentifier,
  String? label,
  AttributedString? attributedLabel,
  String? hint,
  AttributedString? attributedHint,
  String? value,
  AttributedString? attributedValue,
  String? increasedValue,
  AttributedString? attributedIncreasedValue,
  String? decreasedValue,
  AttributedString? attributedDecreasedValue,
  String? tooltip,
  TextDirection? textDirection,
  Rect? rect,
  Size? size,
  double? elevation,
  double? thickness,
  int? platformViewId,
  int? maxValueLength,
  int? currentValueLength,
  SemanticsValidationResult? validationResult,
  ui.SemanticsInputType? inputType,
  String? maxValue,
  String? minValue,
  ui.SemanticsRole? role,
  // Flags
  bool? hasCheckedState,
  bool? isChecked,
  bool? isCheckStateMixed,
  bool? isSelected,
  bool? hasSelectedState,
  bool? isButton,
  bool? isSlider,
  bool? isKeyboardKey,
  bool? isLink,
  bool? isFocused,
  bool? isFocusable,
  bool? isTextField,
  bool? isReadOnly,
  bool? hasEnabledState,
  bool? isEnabled,
  bool? isInMutuallyExclusiveGroup,
  bool? isHeader,
  bool? isObscured,
  bool? isMultiline,
  bool? namesRoute,
  bool? scopesRoute,
  bool? isHidden,
  bool? isImage,
  bool? isLiveRegion,
  bool? hasToggledState,
  bool? isToggled,
  bool? hasImplicitScrolling,
  bool? hasExpandedState,
  bool? isExpanded,
  bool? hasRequiredState,
  bool? isRequired,
  // Actions
  bool? hasTapAction,
  bool? hasFocusAction,
  bool? hasLongPressAction,
  bool? hasScrollLeftAction,
  bool? hasScrollRightAction,
  bool? hasScrollUpAction,
  bool? hasScrollDownAction,
  bool? hasIncreaseAction,
  bool? hasDecreaseAction,
  bool? hasShowOnScreenAction,
  bool? hasMoveCursorForwardByCharacterAction,
  bool? hasMoveCursorBackwardByCharacterAction,
  bool? hasMoveCursorForwardByWordAction,
  bool? hasMoveCursorBackwardByWordAction,
  bool? hasSetTextAction,
  bool? hasSetSelectionAction,
  bool? hasCopyAction,
  bool? hasCutAction,
  bool? hasPasteAction,
  bool? hasDidGainAccessibilityFocusAction,
  bool? hasDidLoseAccessibilityFocusAction,
  bool? hasDismissAction,
  // Custom actions and overrides
  String? onTapHint,
  String? onLongPressHint,
  List<CustomSemanticsAction>? customActions,
  List<Matcher>? children,
}) {
  return _MatchesSemanticsData(
    identifier: identifier,
    traversalChildIdentifier: traversalChildIdentifier,
    traversalParentIdentifier: traversalParentIdentifier,
    label: label,
    attributedLabel: attributedLabel,
    hint: hint,
    attributedHint: attributedHint,
    value: value,
    attributedValue: attributedValue,
    increasedValue: increasedValue,
    attributedIncreasedValue: attributedIncreasedValue,
    decreasedValue: decreasedValue,
    attributedDecreasedValue: attributedDecreasedValue,
    tooltip: tooltip,
    textDirection: textDirection,
    rect: rect,
    size: size,
    platformViewId: platformViewId,
    customActions: customActions,
    maxValueLength: maxValueLength,
    currentValueLength: currentValueLength,
    validationResult: validationResult,
    inputType: inputType,
    minValue: minValue,
    maxValue: maxValue,
    role: role,
    // Flags
    hasCheckedState: hasCheckedState,
    isChecked: isChecked,
    isCheckStateMixed: isCheckStateMixed,
    isSelected: isSelected,
    hasSelectedState: hasSelectedState,
    isButton: isButton,
    isSlider: isSlider,
    isKeyboardKey: isKeyboardKey,
    isLink: isLink,
    isFocused: isFocused,
    isFocusable: isFocusable,
    isTextField: isTextField,
    isReadOnly: isReadOnly,
    hasEnabledState: hasEnabledState,
    isEnabled: isEnabled,
    isInMutuallyExclusiveGroup: isInMutuallyExclusiveGroup,
    isHeader: isHeader,
    isObscured: isObscured,
    isMultiline: isMultiline,
    namesRoute: namesRoute,
    scopesRoute: scopesRoute,
    isHidden: isHidden,
    isImage: isImage,
    isLiveRegion: isLiveRegion,
    hasToggledState: hasToggledState,
    isToggled: isToggled,
    hasImplicitScrolling: hasImplicitScrolling,
    hasExpandedState: hasExpandedState,
    isExpanded: isExpanded,
    hasRequiredState: hasRequiredState,
    isRequired: isRequired,
    // Actions
    hasTapAction: hasTapAction,
    hasFocusAction: hasFocusAction,
    hasLongPressAction: hasLongPressAction,
    hasScrollLeftAction: hasScrollLeftAction,
    hasScrollRightAction: hasScrollRightAction,
    hasScrollUpAction: hasScrollUpAction,
    hasScrollDownAction: hasScrollDownAction,
    hasIncreaseAction: hasIncreaseAction,
    hasDecreaseAction: hasDecreaseAction,
    hasShowOnScreenAction: hasShowOnScreenAction,
    hasMoveCursorForwardByCharacterAction: hasMoveCursorForwardByCharacterAction,
    hasMoveCursorBackwardByCharacterAction: hasMoveCursorBackwardByCharacterAction,
    hasMoveCursorForwardByWordAction: hasMoveCursorForwardByWordAction,
    hasMoveCursorBackwardByWordAction: hasMoveCursorBackwardByWordAction,
    hasSetTextAction: hasSetTextAction,
    hasSetSelectionAction: hasSetSelectionAction,
    hasCopyAction: hasCopyAction,
    hasCutAction: hasCutAction,
    hasPasteAction: hasPasteAction,
    hasDidGainAccessibilityFocusAction: hasDidGainAccessibilityFocusAction,
    hasDidLoseAccessibilityFocusAction: hasDidLoseAccessibilityFocusAction,
    hasDismissAction: hasDismissAction,
    // Custom actions and overrides
    children: children,
    onLongPressHint: onLongPressHint,
    onTapHint: onTapHint,
  );
}

/// Asserts that a [CapturedAccessibilityAnnouncement] matches the expected message.
///
/// The [message] argument matches the [CapturedAccessibilityAnnouncement.message].
/// The [textDirection] argument, if non-null, matches the [CapturedAccessibilityAnnouncement.textDirection].
/// The [assertiveness] argument, if non-null, matches the [CapturedAccessibilityAnnouncement.assertiveness].
///
/// ## Sample code
///
/// ```dart
/// await SemanticsService.sendAnnouncement(tester.view, 'Hello', TextDirection.ltr);
/// expect(tester.takeAnnouncements(), contains(isAccessibilityAnnouncement('Hello')));
/// ```
///
/// See also:
///
///  * [WidgetTester.takeAnnouncements], which retrieves the announcements in unit tests.
///  * [SemanticsService.sendAnnouncement], which sends an announcement.
Matcher isAccessibilityAnnouncement(
  String message, {
  TextDirection? textDirection,
  Assertiveness? assertiveness,
  int? viewId,
}) {
  return _MatchesAccessibilityAnnouncement(
    expectedMessage: message,
    expectedTextDirection: textDirection,
    expectedAssertiveness: assertiveness,
    expectedViewId: viewId,
  );
}

/// Asserts that the currently rendered widget meets the provided accessibility
/// `guideline`.
///
/// This matcher requires the result to be awaited and for semantics to be
/// enabled first.
///
/// ## Sample code
///
/// ```dart
/// testWidgets('isSemantics', (WidgetTester tester) async {
///   final SemanticsHandle handle = tester.ensureSemantics();
///   // ...
///   await expectLater(tester, meetsGuideline(textContrastGuideline));
///   handle.dispose();
/// });
/// ```
///
/// Supported accessibility guidelines:
///
///   * [androidTapTargetGuideline], for Android minimum tappable area guidelines.
///   * [iOSTapTargetGuideline], for iOS minimum tappable area guidelines.
///   * [textContrastGuideline], for WCAG minimum text contrast guidelines.
///   * [labeledTapTargetGuideline], for enforcing labels on tappable areas.
AsyncMatcher meetsGuideline(AccessibilityGuideline guideline) {
  return _MatchesAccessibilityGuideline(guideline);
}

/// The inverse matcher of [meetsGuideline].
///
/// This is needed because the [isNot] matcher does not compose with an
/// [AsyncMatcher].
AsyncMatcher doesNotMeetGuideline(AccessibilityGuideline guideline) {
  return _DoesNotMatchAccessibilityGuideline(guideline);
}

class _FindsCountMatcher extends Matcher {
  const _FindsCountMatcher(this.min, this.max);

  final int? min;
  final int? max;

  @override
  bool matches(covariant FinderBase<dynamic> finder, Map<dynamic, dynamic> matchState) {
    assert(min != null || max != null);
    assert(min == null || max == null || min! <= max!);
    matchState[FinderBase] = finder;
    var count = 0;
    final Iterator<dynamic> iterator = finder.evaluate().iterator;
    if (min != null) {
      while (count < min! && iterator.moveNext()) {
        count += 1;
      }
      if (count < min!) {
        return false;
      }
    }
    if (max != null) {
      while (count <= max! && iterator.moveNext()) {
        count += 1;
      }
      if (count > max!) {
        return false;
      }
    }
    return true;
  }

  @override
  Description describe(Description description) {
    assert(min != null || max != null);
    if (min == max) {
      if (min == 1) {
        return description.add('exactly one matching candidate');
      }
      return description.add('exactly $min matching candidates');
    }
    if (min == null) {
      if (max == 0) {
        return description.add('no matching candidates');
      }
      if (max == 1) {
        return description.add('at most one matching candidate');
      }
      return description.add('at most $max matching candidates');
    }
    if (max == null) {
      if (min == 1) {
        return description.add('at least one matching candidate');
      }
      return description.add('at least $min matching candidates');
    }
    return description.add('between $min and $max matching candidates (inclusive)');
  }

  @override
  Description describeMismatch(
    dynamic item,
    Description mismatchDescription,
    Map<dynamic, dynamic> matchState,
    bool verbose,
  ) {
    final finder = matchState[FinderBase] as FinderBase<dynamic>;
    final int count = finder.found.length;
    if (count == 0) {
      assert(min != null && min! > 0);
      if (min == 1 && max == 1) {
        return mismatchDescription.add('means none were found but one was expected');
      }
      return mismatchDescription.add('means none were found but some were expected');
    }
    if (max == 0) {
      if (count == 1) {
        return mismatchDescription.add('means one was found but none were expected');
      }
      return mismatchDescription.add('means some were found but none were expected');
    }
    if (min != null && count < min!) {
      return mismatchDescription.add('is not enough');
    }
    assert(max != null && count > min!);
    return mismatchDescription.add('is too many');
  }
}

bool _hasAncestorMatching(Finder finder, bool Function(Widget widget) predicate) {
  final Iterable<Element> nodes = finder.evaluate();
  if (nodes.length != 1) {
    return false;
  }
  var result = false;
  nodes.single.visitAncestorElements((Element ancestor) {
    if (predicate(ancestor.widget)) {
      result = true;
      return false;
    }
    return true;
  });
  return result;
}

bool _hasAncestorOfType(Finder finder, Type targetType) {
  return _hasAncestorMatching(finder, (Widget widget) => widget.runtimeType == targetType);
}

class _IsOffstage extends Matcher {
  const _IsOffstage();

  @override
  bool matches(covariant Finder finder, Map<dynamic, dynamic> matchState) {
    return _hasAncestorMatching(finder, (Widget widget) {
      if (widget is Offstage) {
        return widget.offstage;
      }
      return false;
    });
  }

  @override
  Description describe(Description description) => description.add('offstage');
}

class _IsOnstage extends Matcher {
  const _IsOnstage();

  @override
  bool matches(covariant Finder finder, Map<dynamic, dynamic> matchState) {
    final Iterable<Element> nodes = finder.evaluate();
    if (nodes.length != 1) {
      return false;
    }
    var result = true;
    nodes.single.visitAncestorElements((Element ancestor) {
      final Widget widget = ancestor.widget;
      if (widget is Offstage) {
        result = !widget.offstage;
        return false;
      }
      return true;
    });
    return result;
  }

  @override
  Description describe(Description description) => description.add('onstage');
}

class _IsInCard extends Matcher {
  const _IsInCard();

  @override
  bool matches(covariant Finder finder, Map<dynamic, dynamic> matchState) =>
      _hasAncestorOfType(finder, Card);

  @override
  Description describe(Description description) => description.add('in card');
}

class _IsNotInCard extends Matcher {
  const _IsNotInCard();

  @override
  bool matches(covariant Finder finder, Map<dynamic, dynamic> matchState) =>
      !_hasAncestorOfType(finder, Card);

  @override
  Description describe(Description description) => description.add('not in card');
}

class _IsSystemTextScaler extends Matcher {
  const _IsSystemTextScaler(this.expectedUserTextScaleFactor);

  final double? expectedUserTextScaleFactor;

  @override
  bool matches(dynamic item, Map<dynamic, dynamic> matchState) {
    return switch (item) {
      SystemTextScaler(:final double textScaleFactor)
          when expectedUserTextScaleFactor != null &&
              expectedUserTextScaleFactor != textScaleFactor =>
        failWithDescription(
          matchState,
          'expecting a scale factor of $expectedUserTextScaleFactor, but got $textScaleFactor',
        ),
      SystemTextScaler() => true,
      _ => failWithDescription(matchState, '${item.runtimeType} is not a SystemTextScaler'),
    };
  }

  @override
  Description describe(Description description) {
    final scaleFactorExpectation = expectedUserTextScaleFactor == null
        ? ''
        : '(${expectedUserTextScaleFactor}x)';
    return description.add(
      'A SystemTextScaler that reflects the font scale settings in the system user preference $scaleFactorExpectation',
    );
  }

  bool failWithDescription(Map<dynamic, dynamic> matchState, String description) {
    matchState['failure'] = description;
    return false;
  }

  @override
  Description describeMismatch(
    dynamic item,
    Description mismatchDescription,
    Map<dynamic, dynamic> matchState,
    bool verbose,
  ) {
    return mismatchDescription.add(matchState['failure'] as String);
  }
}

class _HasOneLineDescription extends Matcher {
  const _HasOneLineDescription();

  @override
  bool matches(dynamic object, Map<dynamic, dynamic> matchState) {
    final description = object.toString();
    return description.isNotEmpty &&
        !description.contains('\n') &&
        !description.contains('Instance of ') &&
        description.trim() == description;
  }

  @override
  Description describe(Description description) => description.add('one line description');
}

class _EqualsIgnoringHashCodes extends Matcher {
  _EqualsIgnoringHashCodes(Object v)
    : _value = _normalize(v),
      _stringValue = v is String ? _normalizeString(v) : null;

  final Iterable<String> _value;
  final String? _stringValue;

  static final Object _lineNumberValueKey = Object();
  static final Object _expectedLineValueKey = Object();
  static final Object _seenLineValueKey = Object();

  static String _normalizeString(String value) {
    return value.replaceAll(RegExp(r'#[\da-fA-F]{5}'), '#00000');
  }

  static Iterable<String> _normalize(Object value, {bool expected = true}) {
    if (value is String) {
      return LineSplitter.split(
        value,
      ).map<String>((dynamic item) => _normalizeString(item.toString()));
    }
    if (value is Iterable<String>) {
      return value.map<String>((dynamic item) => _normalizeString(item.toString()));
    }
    throw ArgumentError(
      'The specified ${expected ? 'expected' : 'comparison'} value for '
      'equalsIgnoringHashCodes must be a String or an Iterable<String>, '
      'not a ${value.runtimeType}',
    );
  }

  @override
  bool matches(dynamic object, Map<dynamic, dynamic> matchState) {
    final Iterable<String> normalized = _normalize(object as Object, expected: false);
    final Iterator<String> expectedIt = _value.iterator;
    final Iterator<String> seenIt = normalized.iterator;

    var lineNumber = 1;

    bool hasExpected = expectedIt.moveNext();
    bool hasSeen = seenIt.moveNext();
    while (hasExpected && hasSeen) {
      if (!equals(expectedIt.current).matches(seenIt.current, matchState)) {
        matchState[_lineNumberValueKey] = lineNumber;
        matchState[_expectedLineValueKey] = expectedIt.current;
        matchState[_seenLineValueKey] = seenIt.current;
        return false;
      }

      lineNumber += 1;
      hasExpected = expectedIt.moveNext();
      hasSeen = seenIt.moveNext();
    }

    return !hasExpected && !hasSeen;
  }

  @override
  Description describe(Description description) {
    return description.add('normalized value matches\n').addDescriptionOf(_stringValue ?? _value);
  }

  @override
  Description describeMismatch(
    dynamic item,
    Description mismatchDescription,
    Map<dynamic, dynamic> matchState,
    bool verbose,
  ) {
    if (matchState.containsKey(_lineNumberValueKey) &&
        matchState.containsKey(_expectedLineValueKey) &&
        matchState.containsKey(_seenLineValueKey)) {
      final lineNumber = matchState[_lineNumberValueKey] as int;
      if (lineNumber > 1) {
        mismatchDescription = mismatchDescription
            .add('Lines $lineNumber differed, expected: \n')
            .addDescriptionOf(matchState[_expectedLineValueKey])
            .add('\nbut got\n')
            .addDescriptionOf(matchState[_seenLineValueKey]);
      }
    }
    return mismatchDescription;
  }
}

/// Returns true if [c] represents a whitespace code unit.
bool _isWhitespace(int c) => (c <= 0x000D && c >= 0x0009) || c == 0x0020;

/// Returns true if [c] represents a vertical line Unicode line art code unit.
///
/// See [https://en.wikipedia.org/wiki/Box-drawing_character]. This method only
/// specifies vertical line art code units currently used by Flutter line art.
/// There are other line art characters that technically also represent vertical
/// lines.
bool _isVerticalLine(int c) {
  return c == 0x2502 || c == 0x2503 || c == 0x2551 || c == 0x254e;
}

/// Returns whether a [line] is all vertical tree connector characters.
///
/// Example vertical tree connector characters: `│ ║ ╎`.
/// The last line of a text tree contains only vertical tree connector
/// characters indicates a poorly formatted tree.
bool _isAllTreeConnectorCharacters(String line) {
  for (var i = 0; i < line.length; ++i) {
    final int c = line.codeUnitAt(i);
    if (!_isWhitespace(c) && !_isVerticalLine(c)) {
      return false;
    }
  }
  return true;
}

class _HasGoodToStringDeep extends Matcher {
  const _HasGoodToStringDeep();

  static final Object _toStringDeepErrorDescriptionKey = Object();

  @override
  bool matches(dynamic object, Map<dynamic, dynamic> matchState) {
    final issues = <String>[];
    var description = object.toStringDeep() as String; // ignore: avoid_dynamic_calls
    if (description.endsWith('\n')) {
      // Trim off trailing \n as the remaining calculations assume
      // the description does not end with a trailing \n.
      description = description.substring(0, description.length - 1);
    } else {
      issues.add('Not terminated with a line break.');
    }

    if (description.trim() != description) {
      issues.add('Has trailing whitespace.');
    }

    final List<String> lines = description.split('\n');
    if (lines.length < 2) {
      issues.add('Does not have multiple lines.');
    }

    if (description.contains('Instance of ')) {
      issues.add('Contains text "Instance of ".');
    }

    for (var i = 0; i < lines.length; ++i) {
      final String line = lines[i];
      if (line.isEmpty) {
        issues.add('Line ${i + 1} is empty.');
      }

      if (line.trimRight() != line) {
        issues.add('Line ${i + 1} has trailing whitespace.');
      }
    }

    if (_isAllTreeConnectorCharacters(lines.last)) {
      issues.add('Last line is all tree connector characters.');
    }

    // If a toStringDeep method doesn't properly handle nested values that
    // contain line breaks it can fail to add the required prefixes to all
    // lined when toStringDeep is called specifying prefixes.
    const prefixLineOne = 'PREFIX_LINE_ONE____';
    const prefixOtherLines = 'PREFIX_OTHER_LINES_';
    final prefixIssues = <String>[];
    var descriptionWithPrefixes =
        // ignore: avoid_dynamic_calls
        object.toStringDeep(prefixLineOne: prefixLineOne, prefixOtherLines: prefixOtherLines)
            as String;
    if (descriptionWithPrefixes.endsWith('\n')) {
      // Trim off trailing \n as the remaining calculations assume
      // the description does not end with a trailing \n.
      descriptionWithPrefixes = descriptionWithPrefixes.substring(
        0,
        descriptionWithPrefixes.length - 1,
      );
    }
    final List<String> linesWithPrefixes = descriptionWithPrefixes.split('\n');
    if (!linesWithPrefixes.first.startsWith(prefixLineOne)) {
      prefixIssues.add('First line does not contain expected prefix.');
    }

    for (var i = 1; i < linesWithPrefixes.length; ++i) {
      if (!linesWithPrefixes[i].startsWith(prefixOtherLines)) {
        prefixIssues.add('Line ${i + 1} does not contain the expected prefix.');
      }
    }

    final errorDescription = StringBuffer();
    if (issues.isNotEmpty) {
      errorDescription.writeln('Bad toStringDeep():');
      errorDescription.writeln(description);
      errorDescription.writeAll(issues, '\n');
    }

    if (prefixIssues.isNotEmpty) {
      errorDescription.writeln(
        'Bad toStringDeep(prefixLineOne: "$prefixLineOne", prefixOtherLines: "$prefixOtherLines"):',
      );
      errorDescription.writeln(descriptionWithPrefixes);
      errorDescription.writeAll(prefixIssues, '\n');
    }

    if (errorDescription.isNotEmpty) {
      matchState[_toStringDeepErrorDescriptionKey] = errorDescription.toString();
      return false;
    }
    return true;
  }

  @override
  Description describeMismatch(
    dynamic item,
    Description mismatchDescription,
    Map<dynamic, dynamic> matchState,
    bool verbose,
  ) {
    if (matchState.containsKey(_toStringDeepErrorDescriptionKey)) {
      return mismatchDescription.add(matchState[_toStringDeepErrorDescriptionKey] as String);
    }
    return mismatchDescription;
  }

  @override
  Description describe(Description description) {
    return description.add('multi line description');
  }
}

/// Computes the distance between two values.
///
/// The distance should be a metric in a metric space (see
/// https://en.wikipedia.org/wiki/Metric_space). Specifically, if `f` is a
/// distance function then the following conditions should hold:
///
/// - f(a, b) >= 0
/// - f(a, b) == 0 if and only if a == b
/// - f(a, b) == f(b, a)
/// - f(a, c) <= f(a, b) + f(b, c), known as triangle inequality
///
/// This makes it useful for comparing numbers, [Color]s, [Offset]s and other
/// sets of value for which a metric space is defined.
typedef DistanceFunction<T> = num Function(T a, T b);

/// The type of a union of instances of [DistanceFunction<T>] for various types
/// T.
///
/// This type is used to describe a collection of [DistanceFunction<T>]
/// functions which have (potentially) unrelated argument types. Since the
/// argument types of the functions may be unrelated, their type is declared as
/// `Never`, which is the bottom type in dart to which all other types can be
/// assigned to.
///
/// Calling an instance of this type must either be done dynamically, or by
/// first casting it to a [DistanceFunction<T>] for some concrete T.
typedef AnyDistanceFunction = num Function(Never a, Never b);

const Map<Type, AnyDistanceFunction> _kStandardDistanceFunctions = <Type, AnyDistanceFunction>{
  Color: _maxComponentColorDistance,
  HSVColor: _maxComponentHSVColorDistance,
  HSLColor: _maxComponentHSLColorDistance,
  Offset: _offsetDistance,
  int: _intDistance,
  double: _doubleDistance,
  Rect: _rectDistance,
  Size: _sizeDistance,
};

int _intDistance(int a, int b) => (b - a).abs();
double _doubleDistance(double a, double b) => (b - a).abs();
double _offsetDistance(Offset a, Offset b) => (b - a).distance;

double _maxComponentColorDistance(Color a, Color b) {
  int delta = math.max<int>((a.red - b.red).abs(), (a.green - b.green).abs());
  delta = math.max<int>(delta, (a.blue - b.blue).abs());
  delta = math.max<int>(delta, (a.alpha - b.alpha).abs());
  return delta.toDouble();
}

// Compares hue by converting it to a 0.0 - 1.0 range, so that the comparison
// can be a similar error percentage per component.
double _maxComponentHSVColorDistance(HSVColor a, HSVColor b) {
  double delta = math.max<double>((a.saturation - b.saturation).abs(), (a.value - b.value).abs());
  delta = math.max<double>(delta, ((a.hue - b.hue) / 360.0).abs());
  return math.max<double>(delta, (a.alpha - b.alpha).abs());
}

// Compares hue by converting it to a 0.0 - 1.0 range, so that the comparison
// can be a similar error percentage per component.
double _maxComponentHSLColorDistance(HSLColor a, HSLColor b) {
  double delta = math.max<double>(
    (a.saturation - b.saturation).abs(),
    (a.lightness - b.lightness).abs(),
  );
  delta = math.max<double>(delta, ((a.hue - b.hue) / 360.0).abs());
  return math.max<double>(delta, (a.alpha - b.alpha).abs());
}

double _rectDistance(Rect a, Rect b) {
  double delta = math.max<double>((a.left - b.left).abs(), (a.top - b.top).abs());
  delta = math.max<double>(delta, (a.right - b.right).abs());
  delta = math.max<double>(delta, (a.bottom - b.bottom).abs());
  return delta;
}

double _matrixDistance(Matrix4 a, Matrix4 b) {
  var delta = 0.0;
  for (var i = 0; i < 16; i += 1) {
    delta = math.max<double>((a[i] - b[i]).abs(), delta);
  }
  return delta;
}

double _matrix3Distance(Matrix3 a, Matrix3 b) {
  var delta = 0.0;
  for (var i = 0; i < 9; i += 1) {
    delta = math.max<double>((a[i] - b[i]).abs(), delta);
  }
  return delta;
}

double _sizeDistance(Size a, Size b) {
  final delta = (b - a) as Offset;
  return delta.distance;
}

/// Asserts that two values are within a certain distance from each other.
///
/// The distance is computed by a [DistanceFunction].
///
/// If `distanceFunction` is null, a standard distance function is used for the
/// `T` generic argument. Standard functions are defined for the following
/// types:
///
///  * [Color], whose distance is the maximum component-wise delta.
///  * [Offset], whose distance is the Euclidean distance computed using the
///    method [Offset.distance].
///  * [Rect], whose distance is the maximum component-wise delta.
///  * [Size], whose distance is the [Offset.distance] of the offset computed as
///    the difference between two sizes.
///  * [int], whose distance is the absolute difference between two integers.
///  * [double], whose distance is the absolute difference between two doubles.
///
/// See also:
///
///  * [moreOrLessEquals], which is similar to this function, but specializes in
///    [double]s and has an optional `epsilon` parameter.
///  * [rectMoreOrLessEquals], which is similar to this function, but
///    specializes in [Rect]s and has an optional `epsilon` parameter.
///  * [closeTo], which specializes in numbers only.
Matcher within<T>({required num distance, required T from, DistanceFunction<T>? distanceFunction}) {
  distanceFunction ??= _kStandardDistanceFunctions[T] as DistanceFunction<T>?;

  if (distanceFunction == null) {
    throw ArgumentError(
      'The specified distanceFunction was null, and a standard distance '
      'function was not found for type ${from.runtimeType} of the provided '
      '`from` argument.',
    );
  }

  return _IsWithinDistance<T>(distanceFunction, from, distance);
}

class _IsWithinDistance<T> extends Matcher {
  const _IsWithinDistance(this.distanceFunction, this.value, this.epsilon);

  final DistanceFunction<T> distanceFunction;
  final T value;
  final num epsilon;

  @override
  bool matches(dynamic object, Map<dynamic, dynamic> matchState) {
    if (object is! T) {
      return false;
    }
    if (object == value) {
      return true;
    }
    final num distance = distanceFunction(object, value);
    if (distance < 0) {
      throw ArgumentError(
        'Invalid distance function was used to compare a ${value.runtimeType} '
        'to a ${object.runtimeType}. The function must return a non-negative '
        'double value, but it returned $distance.',
      );
    }
    matchState['distance'] = distance;
    return distance <= epsilon;
  }

  @override
  Description describe(Description description) => description.add('$value (±$epsilon)');

  @override
  Description describeMismatch(
    dynamic object,
    Description mismatchDescription,
    Map<dynamic, dynamic> matchState,
    bool verbose,
  ) {
    mismatchDescription.add('was ${matchState['distance']} away from the desired value.');
    return mismatchDescription;
  }
}

class _MoreOrLessEquals extends Matcher {
  const _MoreOrLessEquals(this.value, this.epsilon) : assert(epsilon >= 0);

  final double value;
  final double epsilon;

  @override
  bool matches(dynamic object, Map<dynamic, dynamic> matchState) {
    if (object is! num) {
      return false;
    }
    if (object == value) {
      return true;
    }
    return (object - value).abs() <= epsilon;
  }

  @override
  Description describe(Description description) => description.add('$value (±$epsilon)');

  @override
  Description describeMismatch(
    dynamic item,
    Description mismatchDescription,
    Map<dynamic, dynamic> matchState,
    bool verbose,
  ) {
    return super.describeMismatch(item, mismatchDescription, matchState, verbose)
      ..add('$item is not in the range of $value (±$epsilon).');
  }
}

class _IsMethodCall extends Matcher {
  const _IsMethodCall(this.name, this.arguments);

  final String name;
  final dynamic arguments;

  @override
  bool matches(dynamic item, Map<dynamic, dynamic> matchState) {
    if (item is! MethodCall) {
      return false;
    }
    if (item.method != name) {
      return false;
    }
    return _deepEquals(item.arguments, arguments);
  }

  bool _deepEquals(dynamic a, dynamic b) {
    if (a == b) {
      return true;
    }
    if (a is List) {
      return b is List && _deepEqualsList(a, b);
    }
    if (a is Map) {
      return b is Map && _deepEqualsMap(a, b);
    }
    return false;
  }

  bool _deepEqualsList(List<dynamic> a, List<dynamic> b) {
    if (a.length != b.length) {
      return false;
    }
    for (var i = 0; i < a.length; i++) {
      if (!_deepEquals(a[i], b[i])) {
        return false;
      }
    }
    return true;
  }

  bool _deepEqualsMap(Map<dynamic, dynamic> a, Map<dynamic, dynamic> b) {
    if (a.length != b.length) {
      return false;
    }
    for (final Object? key in a.keys) {
      if (!b.containsKey(key) || !_deepEquals(a[key], b[key])) {
        return false;
      }
    }
    return true;
  }

  @override
  Description describe(Description description) {
    return description
        .add('has method name: ')
        .addDescriptionOf(name)
        .add(' with arguments: ')
        .addDescriptionOf(arguments);
  }
}

/// Asserts that a [Finder] locates a single object whose root RenderObject
/// is a [RenderClipRect] with no clipper set, or an equivalent
/// [RenderClipPath].
const Matcher clipsWithBoundingRect = _ClipsWithBoundingRect();

/// Asserts that a [Finder] locates a single object whose root RenderObject is
/// not a [RenderClipRect], [RenderClipRRect], [RenderClipOval], or
/// [RenderClipPath].
const Matcher hasNoImmediateClip = _MatchAnythingExceptClip();

/// Asserts that a [Finder] locates a single object whose root RenderObject
/// is a [RenderClipRRect] with no clipper set, and border radius equals to
/// [borderRadius], or an equivalent [RenderClipPath].
Matcher clipsWithBoundingRRect({required BorderRadius borderRadius}) {
  return _ClipsWithBoundingRRect(borderRadius: borderRadius);
}

/// Asserts that a [Finder] locates a single object whose root RenderObject
/// is a [RenderClipPath] with a [ShapeBorderClipper] that clips to
/// [shape].
Matcher clipsWithShapeBorder({required ShapeBorder shape}) {
  return _ClipsWithShapeBorder(shape: shape);
}

/// Asserts that a [Finder] locates a single object whose root RenderObject
/// is a [RenderPhysicalModel] or a [RenderPhysicalShape].
///
/// - If the render object is a [RenderPhysicalModel]
///    - If [shape] is non null asserts that [RenderPhysicalModel.shape] is equal to
///   [shape].
///    - If [borderRadius] is non null asserts that [RenderPhysicalModel.borderRadius] is equal to
///   [borderRadius].
///     - If [elevation] is non null asserts that [RenderPhysicalModel.elevation] is equal to
///   [elevation].
/// - If the render object is a [RenderPhysicalShape]
///    - If [borderRadius] is non null asserts that the shape is a rounded
///   rectangle with this radius.
///    - If [borderRadius] is null, asserts that the shape is equivalent to
///   [shape].
///    - If [elevation] is non null asserts that [RenderPhysicalModel.elevation] is equal to
///   [elevation].
Matcher rendersOnPhysicalModel({BoxShape? shape, BorderRadius? borderRadius, double? elevation}) {
  return _RendersOnPhysicalModel(shape: shape, borderRadius: borderRadius, elevation: elevation);
}

/// Asserts that a [Finder] locates a single object whose root RenderObject
/// is [RenderPhysicalShape] that uses a [ShapeBorderClipper] that clips to
/// [shape] as its clipper.
/// If [elevation] is non null asserts that [RenderPhysicalShape.elevation] is
/// equal to [elevation].
Matcher rendersOnPhysicalShape({required ShapeBorder shape, double? elevation}) {
  return _RendersOnPhysicalShape(shape: shape, elevation: elevation);
}

abstract class _FailWithDescriptionMatcher extends Matcher {
  const _FailWithDescriptionMatcher();

  bool failWithDescription(Map<dynamic, dynamic> matchState, String description) {
    matchState['failure'] = description;
    return false;
  }

  @override
  Description describeMismatch(
    dynamic item,
    Description mismatchDescription,
    Map<dynamic, dynamic> matchState,
    bool verbose,
  ) {
    return mismatchDescription.add(matchState['failure'] as String);
  }
}

class _MatchAnythingExceptClip extends _FailWithDescriptionMatcher {
  const _MatchAnythingExceptClip();

  @override
  bool matches(covariant Finder finder, Map<dynamic, dynamic> matchState) {
    final Iterable<Element> nodes = finder.evaluate();
    if (nodes.length != 1) {
      return failWithDescription(matchState, 'did not have a exactly one child element');
    }
    final RenderObject renderObject = nodes.single.renderObject!;

    switch (renderObject.runtimeType) {
      case const (RenderClipPath):
      case const (RenderClipOval):
      case const (RenderClipRect):
      case const (RenderClipRRect):
        return failWithDescription(
          matchState,
          'had a root render object of type: ${renderObject.runtimeType}',
        );
      default:
        return true;
    }
  }

  @override
  Description describe(Description description) {
    return description.add('does not have a clip as an immediate child');
  }
}

abstract class _MatchRenderObject<M extends RenderObject, T extends RenderObject>
    extends _FailWithDescriptionMatcher {
  const _MatchRenderObject();

  bool renderObjectMatchesT(Map<dynamic, dynamic> matchState, T renderObject);
  bool renderObjectMatchesM(Map<dynamic, dynamic> matchState, M renderObject);

  @override
  bool matches(covariant Finder finder, Map<dynamic, dynamic> matchState) {
    final Iterable<Element> nodes = finder.evaluate();
    if (nodes.length != 1) {
      return failWithDescription(matchState, 'did not have a exactly one child element');
    }
    final RenderObject renderObject = nodes.single.renderObject!;

    if (renderObject.runtimeType == T) {
      return renderObjectMatchesT(matchState, renderObject as T);
    }

    if (renderObject.runtimeType == M) {
      return renderObjectMatchesM(matchState, renderObject as M);
    }

    return failWithDescription(
      matchState,
      'had a root render object of type: ${renderObject.runtimeType}',
    );
  }
}

class _RendersOnPhysicalModel extends _MatchRenderObject<RenderPhysicalShape, RenderPhysicalModel> {
  const _RendersOnPhysicalModel({this.shape, this.borderRadius, this.elevation});

  final BoxShape? shape;
  final BorderRadius? borderRadius;
  final double? elevation;

  @override
  bool renderObjectMatchesT(Map<dynamic, dynamic> matchState, RenderPhysicalModel renderObject) {
    if (shape != null && renderObject.shape != shape) {
      return failWithDescription(matchState, 'had shape: ${renderObject.shape}');
    }

    if (borderRadius != null && renderObject.borderRadius != borderRadius) {
      return failWithDescription(matchState, 'had borderRadius: ${renderObject.borderRadius}');
    }

    if (elevation != null && renderObject.elevation != elevation) {
      return failWithDescription(matchState, 'had elevation: ${renderObject.elevation}');
    }

    return true;
  }

  @override
  bool renderObjectMatchesM(Map<dynamic, dynamic> matchState, RenderPhysicalShape renderObject) {
    if (renderObject.clipper.runtimeType != ShapeBorderClipper) {
      return failWithDescription(matchState, 'clipper was: ${renderObject.clipper}');
    }
    final shapeClipper = renderObject.clipper! as ShapeBorderClipper;

    if (borderRadius != null && !assertRoundedRectangle(shapeClipper, borderRadius!, matchState)) {
      return false;
    }

    if (borderRadius == null &&
        shape == BoxShape.rectangle &&
        !assertRoundedRectangle(shapeClipper, BorderRadius.zero, matchState)) {
      return false;
    }

    if (borderRadius == null &&
        shape == BoxShape.circle &&
        !assertCircle(shapeClipper, matchState)) {
      return false;
    }

    if (elevation != null && renderObject.elevation != elevation) {
      return failWithDescription(matchState, 'had elevation: ${renderObject.elevation}');
    }

    return true;
  }

  bool assertRoundedRectangle(
    ShapeBorderClipper shapeClipper,
    BorderRadius borderRadius,
    Map<dynamic, dynamic> matchState,
  ) {
    if (shapeClipper.shape.runtimeType != RoundedRectangleBorder) {
      return failWithDescription(matchState, 'had shape border: ${shapeClipper.shape}');
    }
    final border = shapeClipper.shape as RoundedRectangleBorder;
    if (border.borderRadius != borderRadius) {
      return failWithDescription(matchState, 'had borderRadius: ${border.borderRadius}');
    }
    return true;
  }

  bool assertCircle(ShapeBorderClipper shapeClipper, Map<dynamic, dynamic> matchState) {
    if (shapeClipper.shape.runtimeType != CircleBorder) {
      return failWithDescription(matchState, 'had shape border: ${shapeClipper.shape}');
    }
    return true;
  }

  @override
  Description describe(Description description) {
    description.add('renders on a physical model');
    if (shape != null) {
      description.add(' with shape $shape');
    }
    if (borderRadius != null) {
      description.add(' with borderRadius $borderRadius');
    }
    if (elevation != null) {
      description.add(' with elevation $elevation');
    }
    return description;
  }
}

class _RendersOnPhysicalShape extends _MatchRenderObject<RenderPhysicalShape, RenderPhysicalModel> {
  const _RendersOnPhysicalShape({required this.shape, this.elevation});

  final ShapeBorder shape;
  final double? elevation;

  @override
  bool renderObjectMatchesM(Map<dynamic, dynamic> matchState, RenderPhysicalShape renderObject) {
    if (renderObject.clipper.runtimeType != ShapeBorderClipper) {
      return failWithDescription(matchState, 'clipper was: ${renderObject.clipper}');
    }
    final shapeClipper = renderObject.clipper! as ShapeBorderClipper;

    if (shapeClipper.shape != shape) {
      return failWithDescription(matchState, 'shape was: ${shapeClipper.shape}');
    }

    if (elevation != null && renderObject.elevation != elevation) {
      return failWithDescription(matchState, 'had elevation: ${renderObject.elevation}');
    }

    return true;
  }

  @override
  bool renderObjectMatchesT(Map<dynamic, dynamic> matchState, RenderPhysicalModel renderObject) {
    return false;
  }

  @override
  Description describe(Description description) {
    description.add('renders on a physical model with shape $shape');
    if (elevation != null) {
      description.add(' with elevation $elevation');
    }
    return description;
  }
}

class _ClipsWithBoundingRect extends _MatchRenderObject<RenderClipPath, RenderClipRect> {
  const _ClipsWithBoundingRect();

  @override
  bool renderObjectMatchesT(Map<dynamic, dynamic> matchState, RenderClipRect renderObject) {
    if (renderObject.clipper != null) {
      return failWithDescription(matchState, 'had a non null clipper ${renderObject.clipper}');
    }
    return true;
  }

  @override
  bool renderObjectMatchesM(Map<dynamic, dynamic> matchState, RenderClipPath renderObject) {
    if (renderObject.clipper.runtimeType != ShapeBorderClipper) {
      return failWithDescription(matchState, 'clipper was: ${renderObject.clipper}');
    }
    final shapeClipper = renderObject.clipper! as ShapeBorderClipper;
    if (shapeClipper.shape.runtimeType != RoundedRectangleBorder) {
      return failWithDescription(matchState, 'shape was: ${shapeClipper.shape}');
    }
    final border = shapeClipper.shape as RoundedRectangleBorder;
    if (border.borderRadius != BorderRadius.zero) {
      return failWithDescription(matchState, 'borderRadius was: ${border.borderRadius}');
    }
    return true;
  }

  @override
  Description describe(Description description) => description.add('clips with bounding rectangle');
}

class _ClipsWithBoundingRRect extends _MatchRenderObject<RenderClipPath, RenderClipRRect> {
  const _ClipsWithBoundingRRect({required this.borderRadius});

  final BorderRadius borderRadius;

  @override
  bool renderObjectMatchesT(Map<dynamic, dynamic> matchState, RenderClipRRect renderObject) {
    if (renderObject.clipper != null) {
      return failWithDescription(matchState, 'had a non null clipper ${renderObject.clipper}');
    }

    if (renderObject.borderRadius != borderRadius) {
      return failWithDescription(matchState, 'had borderRadius: ${renderObject.borderRadius}');
    }

    return true;
  }

  @override
  bool renderObjectMatchesM(Map<dynamic, dynamic> matchState, RenderClipPath renderObject) {
    if (renderObject.clipper.runtimeType != ShapeBorderClipper) {
      return failWithDescription(matchState, 'clipper was: ${renderObject.clipper}');
    }
    final shapeClipper = renderObject.clipper! as ShapeBorderClipper;
    if (shapeClipper.shape.runtimeType != RoundedRectangleBorder) {
      return failWithDescription(matchState, 'shape was: ${shapeClipper.shape}');
    }
    final border = shapeClipper.shape as RoundedRectangleBorder;
    if (border.borderRadius != borderRadius) {
      return failWithDescription(matchState, 'had borderRadius: ${border.borderRadius}');
    }
    return true;
  }

  @override
  Description describe(Description description) =>
      description.add('clips with bounding rounded rectangle with borderRadius: $borderRadius');
}

class _ClipsWithShapeBorder extends _MatchRenderObject<RenderClipPath, RenderClipRRect> {
  const _ClipsWithShapeBorder({required this.shape});

  final ShapeBorder shape;

  @override
  bool renderObjectMatchesM(Map<dynamic, dynamic> matchState, RenderClipPath renderObject) {
    if (renderObject.clipper.runtimeType != ShapeBorderClipper) {
      return failWithDescription(matchState, 'clipper was: ${renderObject.clipper}');
    }
    final shapeClipper = renderObject.clipper! as ShapeBorderClipper;
    if (shapeClipper.shape != shape) {
      return failWithDescription(matchState, 'shape was: ${shapeClipper.shape}');
    }
    return true;
  }

  @override
  bool renderObjectMatchesT(Map<dynamic, dynamic> matchState, RenderClipRRect renderObject) {
    return false;
  }

  @override
  Description describe(Description description) => description.add('clips with shape: $shape');
}

class _CoversSameAreaAs extends Matcher {
  _CoversSameAreaAs(this.expectedPath, {required this.areaToCompare, this.sampleSize = 20})
    : maxHorizontalNoise = areaToCompare.width / sampleSize,
      maxVerticalNoise = areaToCompare.height / sampleSize {
    // Use a fixed random seed to make sure tests are deterministic.
    random = math.Random(1);
  }

  final Path expectedPath;
  final Rect areaToCompare;
  final int sampleSize;
  final double maxHorizontalNoise;
  final double maxVerticalNoise;
  late math.Random random;

  @override
  bool matches(covariant Path actualPath, Map<dynamic, dynamic> matchState) {
    for (var i = 0; i < sampleSize; i += 1) {
      for (var j = 0; j < sampleSize; j += 1) {
        final offset = Offset(
          i * (areaToCompare.width / sampleSize),
          j * (areaToCompare.height / sampleSize),
        );

        if (!_samplePoint(matchState, actualPath, offset)) {
          return false;
        }

        final noise = Offset(
          maxHorizontalNoise * random.nextDouble(),
          maxVerticalNoise * random.nextDouble(),
        );

        if (!_samplePoint(matchState, actualPath, offset + noise)) {
          return false;
        }
      }
    }
    return true;
  }

  bool _samplePoint(Map<dynamic, dynamic> matchState, Path actualPath, Offset offset) {
    if (expectedPath.contains(offset) == actualPath.contains(offset)) {
      return true;
    }

    if (actualPath.contains(offset)) {
      return failWithDescription(
        matchState,
        '$offset is contained in the actual path but not in the expected path',
      );
    } else {
      return failWithDescription(
        matchState,
        '$offset is contained in the expected path but not in the actual path',
      );
    }
  }

  bool failWithDescription(Map<dynamic, dynamic> matchState, String description) {
    matchState['failure'] = description;
    return false;
  }

  @override
  Description describeMismatch(
    dynamic item,
    Description mismatchDescription,
    Map<dynamic, dynamic> matchState,
    bool verbose,
  ) {
    return mismatchDescription.add(matchState['failure'] as String);
  }

  @override
  Description describe(Description description) =>
      description.add('covers expected area and only expected area');
}

class _ColorSwatchMatcher<T> extends Matcher {
  _ColorSwatchMatcher(this._target, this._threshold);

  final ColorSwatch<T> _target;
  final double _threshold;

  @override
  Description describe(Description description) {
    return description.add('matches color swatch "$_target" with threshold "$_threshold".');
  }

  @override
  bool matches(dynamic item, Map<dynamic, dynamic> matchState) {
    if (item is ColorSwatch) {
      final matcher = _ColorMatcher(_target, _threshold);
      if (!matcher.matches(item, matchState)) {
        return false;
      }

      for (final T key in _target.keys) {
        final matcher = _ColorMatcher(_target[key]!, _threshold);
        if (!matcher.matches(item[key], matchState)) {
          return false;
        }
      }

      return item.keys.length == _target.keys.length;
    } else {
      return false;
    }
  }
}

class _ColorMatcher extends Matcher {
  _ColorMatcher(this._target, this._threshold);

  final ui.Color _target;
  final double _threshold;

  @override
  Description describe(Description description) {
    return description.add('matches color "$_target" with threshold "$_threshold".');
  }

  @override
  bool matches(dynamic item, Map<dynamic, dynamic> matchState) {
    return item is ui.Color &&
        item.colorSpace == _target.colorSpace &&
        (item.a - _target.a).abs() <= _threshold &&
        (item.r - _target.r).abs() <= _threshold &&
        (item.g - _target.g).abs() <= _threshold &&
        (item.b - _target.b).abs() <= _threshold;
  }
}

int _countDifferentPixels(Uint8List imageA, Uint8List imageB) {
  assert(imageA.length == imageB.length);
  var delta = 0;
  for (var i = 0; i < imageA.length; i += 4) {
    if (imageA[i] != imageB[i] ||
        imageA[i + 1] != imageB[i + 1] ||
        imageA[i + 2] != imageB[i + 2] ||
        imageA[i + 3] != imageB[i + 3]) {
      delta++;
    }
  }
  return delta;
}

class _MatchesReferenceImage extends AsyncMatcher {
  const _MatchesReferenceImage(this.referenceImage);

  final ui.Image referenceImage;

  @override
  Future<String?> matchAsync(dynamic item) async {
    Future<ui.Image> imageFuture;
    final bool
    disposeImage; // set to true if the matcher created and owns the image and must therefore dispose it.
    if (item is Future<ui.Image>) {
      imageFuture = item;
      disposeImage = false;
    } else if (item is ui.Image) {
      imageFuture = Future<ui.Image>.value(item);
      disposeImage = false;
    } else {
      final finder = item as Finder;
      final Iterable<Element> elements = finder.evaluate();
      if (elements.isEmpty) {
        return 'could not be rendered because no widget was found';
      } else if (elements.length > 1) {
        return 'matched too many widgets';
      }
      imageFuture = captureImage(elements.single);
      disposeImage = true;
    }

    final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.instance;
    return binding.runAsync<String?>(() async {
      final ui.Image image = await imageFuture;
      try {
        final ByteData? bytes = await image.toByteData();
        if (bytes == null) {
          return 'could not be encoded.';
        }

        final ByteData? referenceBytes = await referenceImage.toByteData();
        if (referenceBytes == null) {
          return 'could not have its reference image encoded.';
        }

        if (referenceImage.height != image.height || referenceImage.width != image.width) {
          return 'does not match as width or height do not match. $image != $referenceImage';
        }

        final int countDifferentPixels = _countDifferentPixels(
          Uint8List.view(bytes.buffer),
          Uint8List.view(referenceBytes.buffer),
        );
        return countDifferentPixels == 0 ? null : 'does not match on $countDifferentPixels pixels';
      } finally {
        if (disposeImage) {
          image.dispose();
        }
      }
    });
  }

  @override
  Description describe(Description description) {
    return description.add('rasterized image matches that of a $referenceImage reference image');
  }
}

class _MatchesSemanticsData extends Matcher {
  _MatchesSemanticsData({
    required this.identifier,
    required this.traversalParentIdentifier,
    required this.traversalChildIdentifier,
    required this.label,
    required this.attributedLabel,
    required this.hint,
    required this.attributedHint,
    required this.value,
    required this.attributedValue,
    required this.increasedValue,
    required this.attributedIncreasedValue,
    required this.decreasedValue,
    required this.attributedDecreasedValue,
    required this.tooltip,
    required this.textDirection,
    required this.rect,
    required this.size,
    required this.platformViewId,
    required this.maxValueLength,
    required this.currentValueLength,
    required this.validationResult,
    required this.inputType,
    required this.minValue,
    required this.maxValue,
    required this.role,
    // Flags
    required bool? hasCheckedState,
    required bool? isChecked,
    required bool? isCheckStateMixed,
    required bool? isSelected,
    required bool? hasSelectedState,
    required bool? isButton,
    required bool? isSlider,
    required bool? isKeyboardKey,
    required bool? isLink,
    required bool? isFocused,
    required bool? isFocusable,
    required bool? isTextField,
    required bool? isReadOnly,
    required bool? hasEnabledState,
    required bool? isEnabled,
    required bool? isInMutuallyExclusiveGroup,
    required bool? isHeader,
    required bool? isObscured,
    required bool? isMultiline,
    required bool? namesRoute,
    required bool? scopesRoute,
    required bool? isHidden,
    required bool? isImage,
    required bool? isLiveRegion,
    required bool? hasToggledState,
    required bool? isToggled,
    required bool? hasImplicitScrolling,
    required bool? hasExpandedState,
    required bool? isExpanded,
    required bool? hasRequiredState,
    required bool? isRequired,
    // Actions
    required bool? hasTapAction,
    required bool? hasFocusAction,
    required bool? hasLongPressAction,
    required bool? hasScrollLeftAction,
    required bool? hasScrollRightAction,
    required bool? hasScrollUpAction,
    required bool? hasScrollDownAction,
    required bool? hasIncreaseAction,
    required bool? hasDecreaseAction,
    required bool? hasShowOnScreenAction,
    required bool? hasMoveCursorForwardByCharacterAction,
    required bool? hasMoveCursorBackwardByCharacterAction,
    required bool? hasMoveCursorForwardByWordAction,
    required bool? hasMoveCursorBackwardByWordAction,
    required bool? hasSetTextAction,
    required bool? hasSetSelectionAction,
    required bool? hasCopyAction,
    required bool? hasCutAction,
    required bool? hasPasteAction,
    required bool? hasDidGainAccessibilityFocusAction,
    required bool? hasDidLoseAccessibilityFocusAction,
    required bool? hasDismissAction,
    // Custom actions and overrides
    required String? onTapHint,
    required String? onLongPressHint,
    required this.customActions,
    required this.children,
  }) : flags = <String, bool>{
         'hasCheckedState': ?hasCheckedState,
         'isChecked': ?isChecked,
         'isCheckStateMixed': ?isCheckStateMixed,
         'isSelected': ?isSelected,
         'hasSelectedState': ?hasSelectedState,
         'isButton': ?isButton,
         'isSlider': ?isSlider,
         'isKeyboardKey': ?isKeyboardKey,
         'isLink': ?isLink,
         'isTextField': ?isTextField,
         'isReadOnly': ?isReadOnly,
         'isFocused': ?isFocused,
         'isFocusable': ?isFocusable,
         'hasEnabledState': ?hasEnabledState,
         'isEnabled': ?isEnabled,
         'isInMutuallyExclusiveGroup': ?isInMutuallyExclusiveGroup,
         'isHeader': ?isHeader,
         'isObscured': ?isObscured,
         'isMultiline': ?isMultiline,
         'namesRoute': ?namesRoute,
         'scopesRoute': ?scopesRoute,
         'isHidden': ?isHidden,
         'isImage': ?isImage,
         'isLiveRegion': ?isLiveRegion,
         'hasToggledState': ?hasToggledState,
         'isToggled': ?isToggled,
         'hasImplicitScrolling': ?hasImplicitScrolling,
         'hasExpandedState': ?hasExpandedState,
         'isExpanded': ?isExpanded,
         'hasRequiredState': ?hasRequiredState,
         'isRequired': ?isRequired,
       },
       actions = <SemanticsAction, bool>{
         SemanticsAction.tap: ?hasTapAction,
         SemanticsAction.focus: ?hasFocusAction,
         SemanticsAction.longPress: ?hasLongPressAction,
         SemanticsAction.scrollLeft: ?hasScrollLeftAction,
         SemanticsAction.scrollRight: ?hasScrollRightAction,
         SemanticsAction.scrollUp: ?hasScrollUpAction,
         SemanticsAction.scrollDown: ?hasScrollDownAction,
         SemanticsAction.increase: ?hasIncreaseAction,
         SemanticsAction.decrease: ?hasDecreaseAction,
         SemanticsAction.showOnScreen: ?hasShowOnScreenAction,
         SemanticsAction.moveCursorForwardByCharacter: ?hasMoveCursorForwardByCharacterAction,
         SemanticsAction.moveCursorBackwardByCharacter: ?hasMoveCursorBackwardByCharacterAction,
         SemanticsAction.setSelection: ?hasSetSelectionAction,
         SemanticsAction.copy: ?hasCopyAction,
         SemanticsAction.cut: ?hasCutAction,
         SemanticsAction.paste: ?hasPasteAction,
         SemanticsAction.didGainAccessibilityFocus: ?hasDidGainAccessibilityFocusAction,
         SemanticsAction.didLoseAccessibilityFocus: ?hasDidLoseAccessibilityFocusAction,
         SemanticsAction.customAction: ?customActions?.isNotEmpty,
         SemanticsAction.dismiss: ?hasDismissAction,
         SemanticsAction.moveCursorForwardByWord: ?hasMoveCursorForwardByWordAction,
         SemanticsAction.moveCursorBackwardByWord: ?hasMoveCursorBackwardByWordAction,
         SemanticsAction.setText: ?hasSetTextAction,
       },
       hintOverrides = onTapHint == null && onLongPressHint == null
           ? null
           : SemanticsHintOverrides(onTapHint: onTapHint, onLongPressHint: onLongPressHint);

  final String? identifier;
  final String? traversalParentIdentifier;
  final String? traversalChildIdentifier;
  final String? label;
  final AttributedString? attributedLabel;
  final String? hint;
  final AttributedString? attributedHint;
  final String? value;
  final AttributedString? attributedValue;
  final String? increasedValue;
  final AttributedString? attributedIncreasedValue;
  final String? decreasedValue;
  final AttributedString? attributedDecreasedValue;
  final String? tooltip;
  final SemanticsHintOverrides? hintOverrides;
  final List<CustomSemanticsAction>? customActions;
  final TextDirection? textDirection;
  final Rect? rect;
  final Size? size;
  final int? platformViewId;
  final int? maxValueLength;
  final int? currentValueLength;
  final ui.SemanticsInputType? inputType;
  final List<Matcher>? children;
  final SemanticsValidationResult? validationResult;
  final String? maxValue;
  final String? minValue;
  final ui.SemanticsRole? role;

  /// There are three possible states for these two maps:
  ///
  ///  1. If the flag/action maps to `true`, then it must be present in the SemanticData
  ///  2. If the flag/action maps to `false`, then it must not be present in the SemanticData
  ///  3. If the flag/action is not in the map, then it will not be validated against
  final Map<SemanticsAction, bool> actions;
  final Map<String, bool> flags;

  @override
  Description describe(Description description, [String? index]) {
    description.add('${index == null ? '' : 'Child $index '}has semantics');
    if (label != null) {
      description.add(' with label: ${_escape(label!)}');
    }
    if (attributedLabel != null) {
      description.add(' with attributedLabel: ${_escapeAttributedString(attributedLabel!)}');
    }
    if (value != null) {
      description.add(' with value: ${_escape(value!)}');
    }
    if (attributedValue != null) {
      description.add(' with attributedValue: ${_escapeAttributedString(attributedValue!)}');
    }
    if (hint != null) {
      description.add(' with hint: ${_escape(hint!)}');
    }
    if (attributedHint != null) {
      description.add(' with attributedHint: ${_escapeAttributedString(attributedHint!)}');
    }
    if (increasedValue != null) {
      description.add(' with increasedValue: ${_escape(increasedValue!)} ');
    }
    if (attributedIncreasedValue != null) {
      description.add(
        ' with attributedIncreasedValue: ${_escapeAttributedString(attributedIncreasedValue!)}',
      );
    }
    if (decreasedValue != null) {
      description.add(' with decreasedValue: ${_escape(decreasedValue!)} ');
    }
    if (attributedDecreasedValue != null) {
      description.add(
        ' with attributedDecreasedValue: ${_escapeAttributedString(attributedDecreasedValue!)}',
      );
    }
    if (tooltip != null) {
      description.add(' with tooltip: ${_escape(tooltip!)}');
    }
    if (inputType != null) {
      description.add(' with inputType: $inputType');
    }
    if (actions.isNotEmpty) {
      final List<SemanticsAction> expectedActions = actions.entries
          .where((MapEntry<ui.SemanticsAction, bool> e) => e.value)
          .map((MapEntry<ui.SemanticsAction, bool> e) => e.key)
          .toList();
      final List<SemanticsAction> notExpectedActions = actions.entries
          .where((MapEntry<ui.SemanticsAction, bool> e) => !e.value)
          .map((MapEntry<ui.SemanticsAction, bool> e) => e.key)
          .toList();

      if (expectedActions.isNotEmpty) {
        description.add(' with actions: ${_createSemanticsActionSummary(expectedActions)} ');
      }
      if (notExpectedActions.isNotEmpty) {
        description.add(' without actions: ${_createSemanticsActionSummary(notExpectedActions)} ');
      }
    }
    if (flags.isNotEmpty) {
      final List<String> expectedFlags = flags.entries
          .where((MapEntry<String, bool> e) => e.value)
          .map((MapEntry<String, bool> e) => e.key)
          .toList();
      final List<String> notExpectedFlags = flags.entries
          .where((MapEntry<String, bool> e) => !e.value)
          .map((MapEntry<String, bool> e) => e.key)
          .toList();

      if (expectedFlags.isNotEmpty) {
        description.add(' with flags: ${expectedFlags.join(',')} ');
      }
      if (notExpectedFlags.isNotEmpty) {
        description.add(' without flags: ${notExpectedFlags.join(', ')} ');
      }
    }
    if (textDirection != null) {
      description.add(' with textDirection: $textDirection ');
    }
    if (rect != null) {
      description.add(' with rect: $rect');
    }
    if (size != null) {
      description.add(' with size: $size');
    }
    if (platformViewId != null) {
      description.add(' with platformViewId: $platformViewId');
    }
    if (maxValueLength != null) {
      description.add(' with maxValueLength: $maxValueLength');
    }
    if (currentValueLength != null) {
      description.add(' with currentValueLength: $currentValueLength');
    }
    if (customActions != null) {
      description.add(' with custom actions: $customActions');
    }
    if (hintOverrides != null) {
      description.add(' with custom hints: $hintOverrides');
    }
    if (validationResult != null) {
      description.add(' with validation result: $validationResult');
    }
    if (minValue != null) {
      description.add(' with minValue: $minValue');
    }
    if (maxValue != null) {
      description.add(' with maxValue: $maxValue');
    }
    if (role != null) {
      description.add(' with role: $role');
    }
    if (children != null) {
      description.add(' with children:\n  ');
      final List<_MatchesSemanticsData> childMatches = children!.cast<_MatchesSemanticsData>();
      var childIndex = 1;
      for (final child in childMatches) {
        child.describe(description, index != null ? '$index:$childIndex' : '$childIndex');
        if (child != childMatches.last) {
          description.add('\n  ');
        }
        childIndex += 1;
      }
    }
    return description;
  }

  bool _stringAttributesEqual(List<StringAttribute> first, List<StringAttribute> second) {
    if (first.length != second.length) {
      return false;
    }
    for (var i = 0; i < first.length; i++) {
      if (first[i] is SpellOutStringAttribute &&
          (second[i] is! SpellOutStringAttribute || second[i].range != first[i].range)) {
        return false;
      }
      if (first[i] is LocaleStringAttribute &&
          (second[i] is! LocaleStringAttribute ||
              second[i].range != first[i].range ||
              (second[i] as LocaleStringAttribute).locale !=
                  (second[i] as LocaleStringAttribute).locale)) {
        return false;
      }
    }
    return true;
  }

  static String _escape(String string) => string.replaceAll('\u202f', r'\u202f');

  static AttributedString _escapeAttributedString(AttributedString attributedString) {
    return AttributedString(
      _escape(attributedString.string),
      attributes: attributedString.attributes,
    );
  }

  bool _checkStringMismatch(Map<dynamic, dynamic> matchState, String prefixText, String actual) {
    return failWithDescription(matchState, '$prefixText was ${_escape(actual)}');
  }

  bool _checkStringAttributeMismatch(
    Map<dynamic, dynamic> matchState,
    String prefixText,
    AttributedString actual,
  ) {
    return failWithDescription(matchState, '$prefixText was: ${_escapeAttributedString(actual)}');
  }

  @override
  bool matches(dynamic node, Map<dynamic, dynamic> matchState) {
    if (node == null) {
      return failWithDescription(
        matchState,
        'No SemanticsData provided. '
        'Maybe you forgot to enable semantics?',
      );
    }

    final SemanticsData data = switch (node) {
      SemanticsNode() => node.getSemanticsData(),
      FinderBase<SemanticsNode>() => node.evaluate().single.getSemanticsData(),
      _ => node as SemanticsData,
    };

    if (label != null && label != data.label) {
      return _checkStringMismatch(matchState, 'label', data.label);
    }
    if (attributedLabel != null &&
        (attributedLabel!.string != data.attributedLabel.string ||
            !_stringAttributesEqual(
              attributedLabel!.attributes,
              data.attributedLabel.attributes,
            ))) {
      return _checkStringAttributeMismatch(matchState, 'attributedLabel', data.attributedLabel);
    }
    if (hint != null && hint != data.hint) {
      return _checkStringMismatch(matchState, 'hint', data.hint);
    }
    if (attributedHint != null &&
        (attributedHint!.string != data.attributedHint.string ||
            !_stringAttributesEqual(attributedHint!.attributes, data.attributedHint.attributes))) {
      return _checkStringAttributeMismatch(matchState, 'attributedHint', data.attributedHint);
    }
    if (value != null && value != data.value) {
      return _checkStringMismatch(matchState, 'value', data.value);
    }
    if (attributedValue != null &&
        (attributedValue!.string != data.attributedValue.string ||
            !_stringAttributesEqual(
              attributedValue!.attributes,
              data.attributedValue.attributes,
            ))) {
      return _checkStringAttributeMismatch(matchState, 'attributedValue', data.attributedValue);
    }
    if (increasedValue != null && increasedValue != data.increasedValue) {
      return _checkStringMismatch(matchState, 'increasedValue', data.increasedValue);
    }
    if (attributedIncreasedValue != null &&
        (attributedIncreasedValue!.string != data.attributedIncreasedValue.string ||
            !_stringAttributesEqual(
              attributedIncreasedValue!.attributes,
              data.attributedIncreasedValue.attributes,
            ))) {
      return _checkStringAttributeMismatch(
        matchState,
        'attributedIncreasedValue',
        data.attributedIncreasedValue,
      );
    }
    if (decreasedValue != null && decreasedValue != data.decreasedValue) {
      return _checkStringMismatch(matchState, 'decreasedValue', data.decreasedValue);
    }
    if (attributedDecreasedValue != null &&
        (attributedDecreasedValue!.string != data.attributedDecreasedValue.string ||
            !_stringAttributesEqual(
              attributedDecreasedValue!.attributes,
              data.attributedDecreasedValue.attributes,
            ))) {
      return _checkStringAttributeMismatch(
        matchState,
        'attributedDecreasedValue',
        data.attributedDecreasedValue,
      );
    }
    if (tooltip != null && tooltip != data.tooltip) {
      return _checkStringMismatch(matchState, 'tooltip', data.tooltip);
    }
    if (textDirection != null && textDirection != data.textDirection) {
      return failWithDescription(matchState, 'textDirection was: $textDirection');
    }
    if (rect != null && rect != data.rect) {
      return failWithDescription(matchState, 'rect was: ${data.rect}');
    }
    if (size != null && size != data.rect.size) {
      return failWithDescription(matchState, 'size was: ${data.rect.size}');
    }
    if (platformViewId != null && platformViewId != data.platformViewId) {
      return failWithDescription(matchState, 'platformViewId was: ${data.platformViewId}');
    }
    if (currentValueLength != null && currentValueLength != data.currentValueLength) {
      return failWithDescription(matchState, 'currentValueLength was: ${data.currentValueLength}');
    }
    if (maxValueLength != null && maxValueLength != data.maxValueLength) {
      return failWithDescription(matchState, 'maxValueLength was: ${data.maxValueLength}');
    }
    if (validationResult != null && validationResult != data.validationResult) {
      return failWithDescription(matchState, 'validationResult was: ${data.validationResult}');
    }
    if (inputType != null && inputType != data.inputType) {
      return failWithDescription(matchState, 'inputType was: ${data.inputType}');
    }
    if (minValue != null && minValue != data.minValue) {
      return failWithDescription(matchState, 'minValue was: ${data.minValue}');
    }
    if (maxValue != null && maxValue != data.maxValue) {
      return failWithDescription(matchState, 'maxValue was: ${data.maxValue}');
    }
    if (role != null && role != data.role) {
      return failWithDescription(matchState, 'role was: ${data.role}');
    }
    if (actions.isNotEmpty) {
      final unexpectedActions = <SemanticsAction>[];
      final missingActions = <SemanticsAction>[];
      for (final MapEntry<ui.SemanticsAction, bool> actionEntry in actions.entries) {
        final ui.SemanticsAction action = actionEntry.key;
        final bool actionExpected = actionEntry.value;
        final actionPresent = (action.index & data.actions) == action.index;
        if (actionPresent != actionExpected) {
          if (actionExpected) {
            missingActions.add(action);
          } else {
            unexpectedActions.add(action);
          }
        }
      }

      if (unexpectedActions.isNotEmpty || missingActions.isNotEmpty) {
        return failWithDescription(
          matchState,
          'missing actions: ${_createSemanticsActionSummary(missingActions)} unexpected actions: ${_createSemanticsActionSummary(unexpectedActions)}',
        );
      }
    }
    if (customActions != null || hintOverrides != null) {
      final List<CustomSemanticsAction> providedCustomActions =
          data.customSemanticsActionIds?.map<CustomSemanticsAction>((int id) {
            return CustomSemanticsAction.getAction(id)!;
          }).toList() ??
          <CustomSemanticsAction>[];
      final List<CustomSemanticsAction> expectedCustomActions =
          customActions?.toList() ?? <CustomSemanticsAction>[];
      if (hintOverrides?.onTapHint != null) {
        expectedCustomActions.add(
          CustomSemanticsAction.overridingAction(
            hint: hintOverrides!.onTapHint!,
            action: SemanticsAction.tap,
          ),
        );
      }
      if (hintOverrides?.onLongPressHint != null) {
        expectedCustomActions.add(
          CustomSemanticsAction.overridingAction(
            hint: hintOverrides!.onLongPressHint!,
            action: SemanticsAction.longPress,
          ),
        );
      }
      if (expectedCustomActions.length != providedCustomActions.length) {
        return failWithDescription(matchState, 'custom actions were: $providedCustomActions');
      }
      int sortActions(CustomSemanticsAction left, CustomSemanticsAction right) {
        return CustomSemanticsAction.getIdentifier(left) -
            CustomSemanticsAction.getIdentifier(right);
      }

      expectedCustomActions.sort(sortActions);
      providedCustomActions.sort(sortActions);
      for (var i = 0; i < expectedCustomActions.length; i++) {
        if (expectedCustomActions[i] != providedCustomActions[i]) {
          return failWithDescription(matchState, 'custom actions were: $providedCustomActions');
        }
      }
    }
    if (flags.isNotEmpty) {
      final Map<String, bool> foundFlags = _stringsMapFromSemanticsFlags(data.flagsCollection);
      final unexpectedFlags = <String>[];
      final missingFlags = <String>[];
      for (final MapEntry<String, bool> flagEntry in flags.entries) {
        final String flagName = flagEntry.key;
        final bool flagExpected = flagEntry.value;
        final bool flagPresent = foundFlags[flagName]!;
        if (flagPresent != flagExpected) {
          if (flagExpected) {
            missingFlags.add(flagName);
          } else {
            unexpectedFlags.add(flagName);
          }
        }
      }

      if (unexpectedFlags.isNotEmpty || missingFlags.isNotEmpty) {
        return failWithDescription(
          matchState,
          'missing flags: ${missingFlags.join(',')} unexpected flags: ${unexpectedFlags.join(',')}',
        );
      }
    }
    var allMatched = true;
    if (children != null) {
      final int actualChildrenCount = (node as SemanticsNode).childrenCount;
      if (children!.length != actualChildrenCount) {
        return failWithDescription(
          matchState,
          'expected ${children!.length} child${children!.length == 1 ? '' : 'ren'}, found $actualChildrenCount',
        );
      }
      var i = 0;
      node.visitChildren((SemanticsNode child) {
        allMatched = children![i].matches(child, matchState) && allMatched;
        i += 1;
        return allMatched;
      });
    }
    return allMatched;
  }

  bool failWithDescription(Map<dynamic, dynamic> matchState, String description) {
    matchState['failure'] = description;
    return false;
  }

  @override
  Description describeMismatch(
    dynamic item,
    Description mismatchDescription,
    Map<dynamic, dynamic> matchState,
    bool verbose,
  ) {
    return mismatchDescription.add(matchState['failure'] as String);
  }

  static String _createSemanticsActionSummary(List<SemanticsAction> enums) {
    return '[${enums.map((ui.SemanticsAction d) => d.name).join(', ')}]';
  }
}

class _MatchesAccessibilityAnnouncement extends Matcher {
  const _MatchesAccessibilityAnnouncement({
    required this.expectedMessage,
    required this.expectedTextDirection,
    required this.expectedAssertiveness,
    required this.expectedViewId,
  });

  final String expectedMessage;
  final TextDirection? expectedTextDirection;
  final Assertiveness? expectedAssertiveness;
  final int? expectedViewId;

  @override
  bool matches(
    covariant CapturedAccessibilityAnnouncement event,
    Map<dynamic, dynamic> matchState,
  ) {
    return event.message == expectedMessage &&
        (expectedTextDirection == null || event.textDirection == expectedTextDirection) &&
        (expectedAssertiveness == null || event.assertiveness == expectedAssertiveness) &&
        (expectedViewId == null || event.viewId == expectedViewId);
  }

  @override
  Description describe(Description description) {
    description.add('Semantic announcement with message "$expectedMessage"');
    if (expectedTextDirection != null) {
      description.add(', textDirection: $expectedTextDirection');
    }
    if (expectedAssertiveness != null) {
      description.add(', assertiveness: $expectedAssertiveness');
    }
    if (expectedViewId != null) {
      description.add(', viewId: $expectedViewId');
    }
    return description;
  }
}

class _MatchesAccessibilityGuideline extends AsyncMatcher {
  _MatchesAccessibilityGuideline(this.guideline);

  final AccessibilityGuideline guideline;

  @override
  Description describe(Description description) {
    return description.add(guideline.description);
  }

  @override
  Future<String?> matchAsync(covariant WidgetTester tester) async {
    final Evaluation result = await guideline.evaluate(tester);
    if (result.passed) {
      return null;
    }
    return result.reason;
  }
}

class _DoesNotMatchAccessibilityGuideline extends AsyncMatcher {
  _DoesNotMatchAccessibilityGuideline(this.guideline);

  final AccessibilityGuideline guideline;

  @override
  Description describe(Description description) {
    return description.add('Does not ${guideline.description}');
  }

  @override
  Future<String?> matchAsync(covariant WidgetTester tester) async {
    final Evaluation result = await guideline.evaluate(tester);
    if (result.passed) {
      return 'Failed';
    }
    return null;
  }
}

Map<String, bool> _stringsMapFromSemanticsFlags(SemanticsFlags flagsCollection) {
  return <String, bool>{
    'hasCheckedState': flagsCollection.isChecked != ui.CheckedState.none,
    'isChecked': flagsCollection.isChecked == ui.CheckedState.isTrue,
    'isCheckStateMixed': flagsCollection.isChecked == ui.CheckedState.mixed,
    'isSelected': flagsCollection.isSelected == ui.Tristate.isTrue,
    'hasSelectedState': flagsCollection.isSelected != ui.Tristate.none,
    'isButton': flagsCollection.isButton,
    'isSlider': flagsCollection.isSlider,
    'isKeyboardKey': flagsCollection.isKeyboardKey,
    'isLink': flagsCollection.isLink,
    'isFocused': flagsCollection.isFocused == ui.Tristate.isTrue,
    'isFocusable': flagsCollection.isFocused != ui.Tristate.none,
    'isTextField': flagsCollection.isTextField,
    'isReadOnly': flagsCollection.isReadOnly,
    'hasEnabledState': flagsCollection.isEnabled != ui.Tristate.none,
    'isEnabled': flagsCollection.isEnabled == ui.Tristate.isTrue,
    'isInMutuallyExclusiveGroup': flagsCollection.isInMutuallyExclusiveGroup,
    'isHeader': flagsCollection.isHeader,
    'isObscured': flagsCollection.isObscured,
    'isMultiline': flagsCollection.isMultiline,
    'namesRoute': flagsCollection.namesRoute,
    'scopesRoute': flagsCollection.scopesRoute,
    'isHidden': flagsCollection.isHidden,
    'isImage': flagsCollection.isImage,
    'isLiveRegion': flagsCollection.isLiveRegion,
    'hasToggledState': flagsCollection.isToggled != ui.Tristate.none,
    'isToggled': flagsCollection.isToggled == ui.Tristate.isTrue,
    'hasImplicitScrolling': flagsCollection.hasImplicitScrolling,
    'hasExpandedState': flagsCollection.isExpanded != ui.Tristate.none,
    'isExpanded': flagsCollection.isExpanded == ui.Tristate.isTrue,
    'hasRequiredState': flagsCollection.isRequired != ui.Tristate.none,
    'isRequired': flagsCollection.isRequired == ui.Tristate.isTrue,
  };
}
