// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:ui' show SemanticsFlag;

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

export 'dart:ui' show SemanticsFlag, SemanticsAction;
export 'package:flutter/rendering.dart' show SemanticsData;

const String _matcherHelp = 'Try dumping the semantics with debugDumpSemanticsTree(DebugSemanticsDumpOrder.inverseHitTest) from the package:flutter/rendering.dart library to see what the semantics tree looks like.';

/// Test semantics data that is compared against real semantics tree.
///
/// Useful with [hasSemantics] and [SemanticsTester] to test the contents of the
/// semantics tree.
class TestSemantics {
  /// Creates an object with some test semantics data.
  ///
  /// The [id] field is required. The root node has an id of zero. Other nodes
  /// are given a unique id when they are created, in a predictable fashion, and
  /// so these values can be hard-coded.
  ///
  /// The [rect] field is required and has no default. Convenient values are
  /// available:
  ///
  ///  * [TestSemantics.rootRect]: 2400x1600, the test screen's size in physical
  ///    pixels, useful for the node with id zero.
  ///
  ///  * [TestSemantics.fullScreen] 800x600, the test screen's size in logical
  ///    pixels, useful for other full-screen widgets.
  TestSemantics({
    this.id,
    this.flags = 0,
    this.actions = 0,
    this.label = '',
    this.value = '',
    this.increasedValue = '',
    this.decreasedValue = '',
    this.hint = '',
    this.textDirection,
    this.rect,
    this.transform,
    this.elevation,
    this.thickness,
    this.textSelection,
    this.children = const <TestSemantics>[],
    this.scrollIndex,
    this.scrollChildren,
    Iterable<SemanticsTag> tags,
  }) : assert(flags is int || flags is List<SemanticsFlag>),
       assert(actions is int || actions is List<SemanticsAction>),
       assert(label != null),
       assert(value != null),
       assert(increasedValue != null),
       assert(decreasedValue != null),
       assert(hint != null),
       assert(children != null),
       tags = tags?.toSet() ?? <SemanticsTag>{};

  /// Creates an object with some test semantics data, with the [id] and [rect]
  /// set to the appropriate values for the root node.
  TestSemantics.root({
    this.flags = 0,
    this.actions = 0,
    this.label = '',
    this.value = '',
    this.increasedValue = '',
    this.decreasedValue = '',
    this.hint = '',
    this.textDirection,
    this.transform,
    this.textSelection,
    this.children = const <TestSemantics>[],
    this.scrollIndex,
    this.scrollChildren,
    Iterable<SemanticsTag> tags,
  }) : id = 0,
       assert(flags is int || flags is List<SemanticsFlag>),
       assert(actions is int || actions is List<SemanticsAction>),
       assert(label != null),
       assert(increasedValue != null),
       assert(decreasedValue != null),
       assert(value != null),
       assert(hint != null),
       rect = TestSemantics.rootRect,
       elevation = 0.0,
       thickness = 0.0,
       assert(children != null),
       tags = tags?.toSet() ?? <SemanticsTag>{};

  /// Creates an object with some test semantics data, with the [id] and [rect]
  /// set to the appropriate values for direct children of the root node.
  ///
  /// The [transform] is set to a 3.0 scale (to account for the
  /// [Window.devicePixelRatio] being 3.0 on the test pseudo-device).
  ///
  /// The [rect] field is required and has no default. The
  /// [TestSemantics.fullScreen] property may be useful as a value; it describes
  /// an 800x600 rectangle, which is the test screen's size in logical pixels.
  TestSemantics.rootChild({
    this.id,
    this.flags = 0,
    this.actions = 0,
    this.label = '',
    this.hint = '',
    this.value = '',
    this.increasedValue = '',
    this.decreasedValue = '',
    this.textDirection,
    this.rect,
    Matrix4 transform,
    this.elevation,
    this.thickness,
    this.textSelection,
    this.children = const <TestSemantics>[],
    this.scrollIndex,
    this.scrollChildren,
    Iterable<SemanticsTag> tags,
  }) : assert(flags is int || flags is List<SemanticsFlag>),
       assert(actions is int || actions is List<SemanticsAction>),
       assert(label != null),
       assert(value != null),
       assert(increasedValue != null),
       assert(decreasedValue != null),
       assert(hint != null),
       transform = _applyRootChildScale(transform),
       assert(children != null),
       tags = tags?.toSet() ?? <SemanticsTag>{};

  /// The unique identifier for this node.
  ///
  /// The root node has an id of zero. Other nodes are given a unique id when
  /// they are created.
  final int id;

  /// The [SemanticsFlag]s set on this node.
  ///
  /// There are two ways to specify this property: as an `int` that encodes the
  /// flags as a bit field, or as a `List<SemanticsFlag>` that are _on_.
  ///
  /// Using `List<SemanticsFlag>` is recommended due to better readability.
  final dynamic flags;

  /// The [SemanticsAction]s set on this node.
  ///
  /// There are two ways to specify this property: as an `int` that encodes the
  /// actions as a bit field, or as a `List<SemanticsAction>`.
  ///
  /// Using `List<SemanticsAction>` is recommended due to better readability.
  ///
  /// The tester does not check the function corresponding to the action, but
  /// only its existence.
  final dynamic actions;

  /// A textual description of this node.
  final String label;

  /// A textual description for the value of this node.
  final String value;

  /// What [value] will become after [SemanticsAction.increase] has been
  /// performed.
  final String increasedValue;

  /// What [value] will become after [SemanticsAction.decrease] has been
  /// performed.
  final String decreasedValue;

  /// A brief textual description of the result of the action that can be
  /// performed on this node.
  final String hint;

  /// The reading direction of the [label].
  ///
  /// Even if this is not set, the [hasSemantics] matcher will verify that if a
  /// label is present on the [SemanticsNode], a [SemanticsNode.textDirection]
  /// is also set.
  final TextDirection textDirection;

  /// The bounding box for this node in its coordinate system.
  ///
  /// Convenient values are available:
  ///
  ///  * [TestSemantics.rootRect]: 2400x1600, the test screen's size in physical
  ///    pixels, useful for the node with id zero.
  ///
  ///  * [TestSemantics.fullScreen] 800x600, the test screen's size in logical
  ///    pixels, useful for other full-screen widgets.
  final Rect rect;

  /// The test screen's size in physical pixels, typically used as the [rect]
  /// for the node with id zero.
  ///
  /// See also [new TestSemantics.root], which uses this value to describe the
  /// root node.
  static final Rect rootRect = Rect.fromLTWH(0.0, 0.0, 2400.0, 1800.0);

  /// The test screen's size in logical pixels, useful for the [rect] of
  /// full-screen widgets other than the root node.
  static final Rect fullScreen = Rect.fromLTWH(0.0, 0.0, 800.0, 600.0);

  /// The transform from this node's coordinate system to its parent's coordinate system.
  ///
  /// By default, the transform is null, which represents the identity
  /// transformation (i.e., that this node has the same coordinate system as its
  /// parent).
  final Matrix4 transform;

  /// The elevation of this node relative to the parent node.
  ///
  /// See also:
  ///
  ///  * [SemanticsConfiguration.elevation] for a detailed discussion regarding
  ///    elevation and semantics.
  final double elevation;

  /// The extend that this node occupies in z-direction starting at [elevation].
  ///
  /// See also:
  ///
  ///  * [SemanticsConfiguration.thickness] for a more detailed definition.
  final double thickness;

  /// The index of the first visible semantic node within a scrollable.
  final int scrollIndex;

  /// The total number of semantic nodes within a scrollable.
  final int scrollChildren;

  final TextSelection textSelection;

  static Matrix4 _applyRootChildScale(Matrix4 transform) {
    final Matrix4 result = Matrix4.diagonal3Values(3.0, 3.0, 1.0);
    if (transform != null)
      result.multiply(transform);
    return result;
  }

  /// The children of this node.
  final List<TestSemantics> children;

  /// The tags of this node.
  final Set<SemanticsTag> tags;

  bool _matches(
    SemanticsNode node,
    Map<dynamic, dynamic> matchState, {
    bool ignoreRect = false,
    bool ignoreTransform = false,
    bool ignoreId = false,
    DebugSemanticsDumpOrder childOrder = DebugSemanticsDumpOrder.inverseHitTest,
  }) {
    bool fail(String message) {
      matchState[TestSemantics] = '$message';
      return false;
    }

    if (node == null)
      return fail('could not find node with id $id.');
    if (!ignoreId && id != node.id)
      return fail('expected node id $id but found id ${node.id}.');

    final SemanticsData nodeData = node.getSemanticsData();

    final int flagsBitmask = flags is int
      ? flags
      : flags.fold<int>(0, (int bitmask, SemanticsFlag flag) => bitmask | flag.index);
    if (flagsBitmask != nodeData.flags)
      return fail('expected node id $id to have flags $flags but found flags ${nodeData.flags}.');

    final int actionsBitmask = actions is int
        ? actions
        : actions.fold<int>(0, (int bitmask, SemanticsAction action) => bitmask | action.index);
    if (actionsBitmask != nodeData.actions)
      return fail('expected node id $id to have actions $actions but found actions ${nodeData.actions}.');

    if (label != nodeData.label)
      return fail('expected node id $id to have label "$label" but found label "${nodeData.label}".');
    if (value != nodeData.value)
      return fail('expected node id $id to have value "$value" but found value "${nodeData.value}".');
    if (increasedValue != nodeData.increasedValue)
      return fail('expected node id $id to have increasedValue "$increasedValue" but found value "${nodeData.increasedValue}".');
    if (decreasedValue != nodeData.decreasedValue)
      return fail('expected node id $id to have decreasedValue "$decreasedValue" but found value "${nodeData.decreasedValue}".');
    if (hint != nodeData.hint)
      return fail('expected node id $id to have hint "$hint" but found hint "${nodeData.hint}".');
    if (textDirection != null && textDirection != nodeData.textDirection)
      return fail('expected node id $id to have textDirection "$textDirection" but found "${nodeData.textDirection}".');
    if ((nodeData.label != '' || nodeData.value != '' || nodeData.hint != '' || node.increasedValue != '' || node.decreasedValue != '') && nodeData.textDirection == null)
      return fail('expected node id $id, which has a label, value, or hint, to have a textDirection, but it did not.');
    if (!ignoreRect && rect != nodeData.rect)
      return fail('expected node id $id to have rect $rect but found rect ${nodeData.rect}.');
    if (!ignoreTransform && transform != nodeData.transform)
      return fail('expected node id $id to have transform $transform but found transform:\n${nodeData.transform}.');
    if (elevation != null && elevation != nodeData.elevation) {
      return fail('expected node id $id to have elevation $elevation but found elevation:\n${nodeData.elevation}.');
    }
    if (thickness != null && thickness != nodeData.thickness) {
      return fail('expected node id $id to have thickness $thickness but found thickness:\n${nodeData.thickness}.');
    }
    if (textSelection?.baseOffset != nodeData.textSelection?.baseOffset || textSelection?.extentOffset != nodeData.textSelection?.extentOffset) {
      return fail('expected node id $id to have textSelection [${textSelection?.baseOffset}, ${textSelection?.end}] but found: [${nodeData.textSelection?.baseOffset}, ${nodeData.textSelection?.extentOffset}].');
    }
    if (scrollIndex != null && scrollIndex != nodeData.scrollIndex) {
      return fail('expected node id $id to have scrollIndex $scrollIndex but found scrollIndex ${nodeData.scrollIndex}.');
    }
    if (scrollChildren != null && scrollChildren != nodeData.scrollChildCount) {
      return fail('expected node id $id to have scrollIndex $scrollChildren but found scrollIndex ${nodeData.scrollChildCount}.');
    }
    final int childrenCount = node.mergeAllDescendantsIntoThisNode ? 0 : node.childrenCount;
    if (children.length != childrenCount)
      return fail('expected node id $id to have ${children.length} child${ children.length == 1 ? "" : "ren" } but found $childrenCount.');

    if (children.isEmpty)
      return true;
    bool result = true;
    final Iterator<TestSemantics> it = children.iterator;
    for (final SemanticsNode child in node.debugListChildrenInOrder(childOrder)) {
      it.moveNext();
      final bool childMatches = it.current._matches(
        child,
        matchState,
        ignoreRect: ignoreRect,
        ignoreTransform: ignoreTransform,
        ignoreId: ignoreId,
        childOrder: childOrder,
      );
      if (!childMatches) {
        result = false;
        return false;
      }
      return true;
    }
    return result;
  }

  @override
  String toString([ int indentAmount = 0 ]) {
    final String indent = '  ' * indentAmount;
    final StringBuffer buf = StringBuffer();
    buf.writeln('$indent$runtimeType(');
    if (id != null)
      buf.writeln('$indent  id: $id,');
    if (flags is int && flags != 0 || flags is List<SemanticsFlag> && flags.isNotEmpty)
      buf.writeln('$indent  flags: ${SemanticsTester._flagsToSemanticsFlagExpression(flags)},');
    if (actions is int && actions != 0 || actions is List<SemanticsAction> && actions.isNotEmpty)
      buf.writeln('$indent  actions: ${SemanticsTester._actionsToSemanticsActionExpression(actions)},');
    if (label != null && label != '')
      buf.writeln('$indent  label: \'$label\',');
    if (value != null && value != '')
      buf.writeln('$indent  value: \'$value\',');
    if (increasedValue != null && increasedValue != '')
      buf.writeln('$indent  increasedValue: \'$increasedValue\',');
    if (decreasedValue != null && decreasedValue != '')
      buf.writeln('$indent  decreasedValue: \'$decreasedValue\',');
    if (hint != null && hint != '')
      buf.writeln('$indent  hint: \'$hint\',');
    if (textDirection != null)
      buf.writeln('$indent  textDirection: $textDirection,');
    if (textSelection?.isValid == true)
      buf.writeln('$indent  textSelection:\n[${textSelection.start}, ${textSelection.end}],');
    if (scrollIndex != null)
      buf.writeln('$indent scrollIndex: $scrollIndex,');
    if (rect != null)
      buf.writeln('$indent  rect: $rect,');
    if (transform != null)
      buf.writeln('$indent  transform:\n${transform.toString().trim().split('\n').map<String>((String line) => '$indent    $line').join('\n')},');
    if (elevation != null)
      buf.writeln('$indent  elevation: $elevation,');
    if (thickness != null)
      buf.writeln('$indent  thickness: $thickness,');
    buf.writeln('$indent  children: <TestSemantics>[');
    for (TestSemantics child in children) {
      buf.writeln('${child.toString(indentAmount + 2)},');
    }
    buf.writeln('$indent  ],');
    buf.write('$indent)');
    return buf.toString();
  }
}

/// Ensures that the given widget tester has a semantics tree to test.
///
/// Useful with [hasSemantics] to test the contents of the semantics tree.
class SemanticsTester {
  /// Creates a semantics tester for the given widget tester.
  ///
  /// You should call [dispose] at the end of a test that creates a semantics
  /// tester.
  SemanticsTester(this.tester) {
    _semanticsHandle = tester.binding.pipelineOwner.ensureSemantics();

    // This _extra_ clean-up is needed for the case when a test fails and
    // therefore fails to call dispose() explicitly. The test is still required
    // to call dispose() explicitly, because the semanticsOwner check is
    // performed irrespective of whether the owner was created via
    // SemanticsTester or directly. When the test succeeds, this tear-down
    // becomes a no-op.
    addTearDown(dispose);
  }

  /// The widget tester that this object is testing the semantics of.
  final WidgetTester tester;
  SemanticsHandle _semanticsHandle;

  /// Release resources held by this semantics tester.
  ///
  /// Call this function at the end of any test that uses a semantics tester. It
  /// is OK to call this function multiple times. If the resources have already
  /// been released, the subsequent calls have no effect.
  @mustCallSuper
  void dispose() {
    _semanticsHandle?.dispose();
    _semanticsHandle = null;
  }

  @override
  String toString() => 'SemanticsTester for ${tester.binding.pipelineOwner.semanticsOwner?.rootSemanticsNode}';

  /// Returns all semantics nodes in the current semantics tree whose properties
  /// match the non-null arguments.
  ///
  /// If multiple arguments are non-null, each of the returned nodes must match
  /// on all of them.
  ///
  /// If `ancestor` is not null, only the descendants of it are returned.
  Iterable<SemanticsNode> nodesWith({
    String label,
    String value,
    String hint,
    TextDirection textDirection,
    List<SemanticsAction> actions,
    List<SemanticsFlag> flags,
    double scrollPosition,
    double scrollExtentMax,
    double scrollExtentMin,
    SemanticsNode ancestor,
  }) {
    bool checkNode(SemanticsNode node) {
      if (label != null && node.label != label)
        return false;
      if (value != null && node.value != value)
        return false;
      if (hint != null && node.hint != hint)
        return false;
      if (textDirection != null && node.textDirection != textDirection)
        return false;
      if (actions != null) {
        final int expectedActions = actions.fold<int>(0, (int value, SemanticsAction action) => value | action.index);
        final int actualActions = node.getSemanticsData().actions;
        if (expectedActions != actualActions)
          return false;
      }
      if (flags != null) {
        final int expectedFlags = flags.fold<int>(0, (int value, SemanticsFlag flag) => value | flag.index);
        final int actualFlags = node.getSemanticsData().flags;
        if (expectedFlags != actualFlags)
          return false;
      }
      if (scrollPosition != null && !nearEqual(node.scrollPosition, scrollPosition, 0.1))
        return false;
      if (scrollExtentMax != null && !nearEqual(node.scrollExtentMax, scrollExtentMax, 0.1))
        return false;
      if (scrollExtentMin != null && !nearEqual(node.scrollExtentMin, scrollExtentMin, 0.1))
        return false;
      return true;
    }

    final List<SemanticsNode> result = <SemanticsNode>[];
    bool visit(SemanticsNode node) {
      if (checkNode(node)) {
        result.add(node);
      }
      node.visitChildren(visit);
      return true;
    }
    if (ancestor != null) {
      visit(ancestor);
    } else {
      visit(tester.binding.pipelineOwner.semanticsOwner.rootSemanticsNode);
    }
    return result;
  }

  /// Generates an expression that creates a [TestSemantics] reflecting the
  /// current tree of [SemanticsNode]s.
  ///
  /// Use this method to generate code for unit tests. It works similar to
  /// screenshot testing. The very first time you add semantics to a widget you
  /// verify manually that the widget behaves correctly. You then use this
  /// method to generate test code for this widget.
  ///
  /// Example:
  ///
  /// ```dart
  /// testWidgets('generate code for MyWidget', (WidgetTester tester) async {
  ///   var semantics = SemanticsTester(tester);
  ///   await tester.pumpWidget(MyWidget());
  ///   print(semantics.generateTestSemanticsExpressionForCurrentSemanticsTree());
  ///   semantics.dispose();
  /// });
  /// ```
  ///
  /// You can now copy the code printed to the console into a unit test:
  ///
  /// ```dart
  /// testWidgets('generate code for MyWidget', (WidgetTester tester) async {
  ///   var semantics = SemanticsTester(tester);
  ///   await tester.pumpWidget(MyWidget());
  ///   expect(semantics, hasSemantics(
  ///     // Generated code:
  ///     TestSemantics(
  ///       ... properties and child nodes ...
  ///     ),
  ///     ignoreRect: true,
  ///     ignoreTransform: true,
  ///     ignoreId: true,
  ///   ));
  ///   semantics.dispose();
  /// });
  /// ```
  ///
  /// At this point the unit test should automatically pass because it was
  /// generated from the actual [SemanticsNode]s. Next time the semantics tree
  /// changes, the test code may either be updated manually, or regenerated and
  /// replaced using this method again.
  ///
  /// Avoid submitting huge piles of generated test code. This will make test
  /// code hard to review and it will make it tempting to regenerate test code
  /// every time and ignore potential regressions. Make sure you do not
  /// over-test. Prefer breaking your widgets into smaller widgets and test them
  /// individually.
  String generateTestSemanticsExpressionForCurrentSemanticsTree(DebugSemanticsDumpOrder childOrder) {
    final SemanticsNode node = tester.binding.pipelineOwner.semanticsOwner?.rootSemanticsNode;
    return _generateSemanticsTestForNode(node, 0, childOrder);
  }

  static String _flagsToSemanticsFlagExpression(dynamic flags) {
    Iterable<SemanticsFlag> list;
    if (flags is int) {
      list = SemanticsFlag.values.values
          .where((SemanticsFlag flag) => (flag.index & flags) != 0);
    } else {
      list = flags;
    }
    return '<SemanticsFlag>[${list.join(', ')}]';
  }

  static String _tagsToSemanticsTagExpression(Set<SemanticsTag> tags) {
    return '<SemanticsTag>[${tags.map<String>((SemanticsTag tag) => 'const SemanticsTag(\'${tag.name}\')').join(', ')}]';
  }

  static String _actionsToSemanticsActionExpression(dynamic actions) {
    Iterable<SemanticsAction> list;
    if (actions is int) {
      list = SemanticsAction.values.values
          .where((SemanticsAction action) => (action.index & actions) != 0);
    } else {
      list = actions;
    }
    return '<SemanticsAction>[${list.join(', ')}]';
  }

  /// Recursively generates [TestSemantics] code for [node] and its children,
  /// indenting the expression by `indentAmount`.
  static String _generateSemanticsTestForNode(SemanticsNode node, int indentAmount, DebugSemanticsDumpOrder childOrder) {
    if (node == null)
      return 'null';
    final String indent = '  ' * indentAmount;
    final StringBuffer buf = StringBuffer();
    final SemanticsData nodeData = node.getSemanticsData();
    final bool isRoot = node.id == 0;
    buf.writeln('TestSemantics${isRoot ? '.root': ''}(');
    if (!isRoot)
      buf.writeln('  id: ${node.id},');
    if (nodeData.tags != null)
      buf.writeln('  tags: ${_tagsToSemanticsTagExpression(nodeData.tags)},');
    if (nodeData.flags != 0)
      buf.writeln('  flags: ${_flagsToSemanticsFlagExpression(nodeData.flags)},');
    if (nodeData.actions != 0)
      buf.writeln('  actions: ${_actionsToSemanticsActionExpression(nodeData.actions)},');
    if (node.label != null && node.label.isNotEmpty) {
      final String escapedLabel = node.label.replaceAll('\n', r'\n');
      if (escapedLabel != node.label) {
        buf.writeln('  label: r\'$escapedLabel\',');
      } else {
        buf.writeln('  label: \'$escapedLabel\',');
      }
    }
    if (node.value != null && node.value.isNotEmpty)
      buf.writeln('  value: \'${node.value}\',');
    if (node.increasedValue != null && node.increasedValue.isNotEmpty)
      buf.writeln('  increasedValue: \'${node.increasedValue}\',');
    if (node.decreasedValue != null && node.decreasedValue.isNotEmpty)
      buf.writeln('  decreasedValue: \'${node.decreasedValue}\',');
    if (node.hint != null && node.hint.isNotEmpty)
      buf.writeln('  hint: \'${node.hint}\',');
    if (node.textDirection != null)
      buf.writeln('  textDirection: ${node.textDirection},');

    if (node.hasChildren) {
      buf.writeln('  children: <TestSemantics>[');
      for (final SemanticsNode child in node.debugListChildrenInOrder(childOrder)) {
        buf
          ..write(_generateSemanticsTestForNode(child, 2, childOrder))
          ..writeln(',');
      }
      buf.writeln('  ],');
    }

    buf.write(')');
    return buf.toString().split('\n').map<String>((String l) => '$indent$l').join('\n');
  }
}

class _HasSemantics extends Matcher {
  const _HasSemantics(
    this._semantics, {
    @required this.ignoreRect,
    @required this.ignoreTransform,
    @required this.ignoreId,
    @required this.childOrder,
  }) : assert(_semantics != null),
       assert(ignoreRect != null),
       assert(ignoreId != null),
       assert(ignoreTransform != null),
       assert(childOrder != null);

  final TestSemantics _semantics;
  final bool ignoreRect;
  final bool ignoreTransform;
  final bool ignoreId;
  final DebugSemanticsDumpOrder childOrder;

  @override
  bool matches(covariant SemanticsTester item, Map<dynamic, dynamic> matchState) {
    final bool doesMatch = _semantics._matches(
      item.tester.binding.pipelineOwner.semanticsOwner?.rootSemanticsNode,
      matchState,
      ignoreTransform: ignoreTransform,
      ignoreRect: ignoreRect,
      ignoreId: ignoreId,
      childOrder: childOrder,
    );
    if (!doesMatch) {
      matchState['would-match'] = item.generateTestSemanticsExpressionForCurrentSemanticsTree(childOrder);
    }
    if (item.tester.binding.pipelineOwner.semanticsOwner == null) {
      matchState['additional-notes'] = '(Check that the SemanticsTester has not been disposed early.)';
    }
    return doesMatch;
  }

  @override
  Description describe(Description description) {
    return description.add('semantics node matching:\n$_semantics');
  }

  String _indent(String text) {
    return text.toString().trimRight().split('\n').map<String>((String line) => '  $line').join('\n');
  }

  @override
  Description describeMismatch(dynamic item, Description mismatchDescription, Map<dynamic, dynamic> matchState, bool verbose) {
    Description result = mismatchDescription
      .add('${matchState[TestSemantics]}\n')
      .add('Current SemanticsNode tree:\n')
      .add(_indent(RendererBinding.instance?.renderView?.debugSemantics?.toStringDeep(childOrder: childOrder)))
      .add('\n')
      .add('The semantics tree would have matched the following configuration:\n')
      .add(_indent(matchState['would-match']));
    if (matchState.containsKey('additional-notes')) {
      result = result
        .add('\n')
        .add(matchState['additional-notes']);
    }
    return result;
  }
}

/// Asserts that a [SemanticsTester] has a semantics tree that exactly matches the given semantics.
Matcher hasSemantics(
  TestSemantics semantics, {
  bool ignoreRect = false,
  bool ignoreTransform = false,
  bool ignoreId = false,
  DebugSemanticsDumpOrder childOrder = DebugSemanticsDumpOrder.traversalOrder,
}) {
  return _HasSemantics(
    semantics,
    ignoreRect: ignoreRect,
    ignoreTransform: ignoreTransform,
    ignoreId: ignoreId,
    childOrder: childOrder,
  );
}

class _IncludesNodeWith extends Matcher {
  const _IncludesNodeWith({
    this.label,
    this.value,
    this.hint,
    this.textDirection,
    this.actions,
    this.flags,
    this.scrollPosition,
    this.scrollExtentMax,
    this.scrollExtentMin,
}) : assert(label != null || value != null || actions != null || flags != null || scrollPosition != null || scrollExtentMax != null || scrollExtentMin != null);

  final String label;
  final String value;
  final String hint;
  final TextDirection textDirection;
  final List<SemanticsAction> actions;
  final List<SemanticsFlag> flags;
  final double scrollPosition;
  final double scrollExtentMax;
  final double scrollExtentMin;

  @override
  bool matches(covariant SemanticsTester item, Map<dynamic, dynamic> matchState) {
    return item.nodesWith(
      label: label,
      value: value,
      hint: hint,
      textDirection: textDirection,
      actions: actions,
      flags: flags,
      scrollPosition: scrollPosition,
      scrollExtentMax: scrollExtentMax,
      scrollExtentMin: scrollExtentMin,
    ).isNotEmpty;
  }

  @override
  Description describe(Description description) {
    return description.add('includes node with $_configAsString');
  }

  @override
  Description describeMismatch(dynamic item, Description mismatchDescription, Map<dynamic, dynamic> matchState, bool verbose) {
    return mismatchDescription.add('could not find node with $_configAsString.\n$_matcherHelp');
  }

  String get _configAsString {
    final List<String> strings = <String>[];
    if (label != null)
      strings.add('label "$label"');
    if (value != null)
      strings.add('value "$value"');
    if (hint != null)
      strings.add('hint "$hint"');
    if (textDirection != null)
      strings.add(' (${describeEnum(textDirection)})');
    if (actions != null)
      strings.add('actions "${actions.join(', ')}"');
    if (flags != null)
      strings.add('flags "${flags.join(', ')}"');
    if (scrollPosition != null)
      strings.add('scrollPosition "$scrollPosition"');
    if (scrollExtentMax != null)
      strings.add('scrollExtentMax "$scrollExtentMax"');
    if (scrollExtentMin != null)
      strings.add('scrollExtentMin "$scrollExtentMin"');
    return strings.join(', ');
  }
}

/// Asserts that a node in the semantics tree of [SemanticsTester] has `label`,
/// `textDirection`, and `actions`.
///
/// If null is provided for an argument, it will match against any value.
Matcher includesNodeWith({
  String label,
  String value,
  String hint,
  TextDirection textDirection,
  List<SemanticsAction> actions,
  List<SemanticsFlag> flags,
  double scrollPosition,
  double scrollExtentMax,
  double scrollExtentMin,
}) {
  return _IncludesNodeWith(
    label: label,
    value: value,
    hint: hint,
    textDirection: textDirection,
    actions: actions,
    flags: flags,
    scrollPosition: scrollPosition,
    scrollExtentMax: scrollExtentMax,
    scrollExtentMin: scrollExtentMin,
  );
}
