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

import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:vector_math/vector_math_64.dart';

import '../rendering/rendering_tester.dart';

const int kMaxFrameworkAccessibilityIdentifier = (1<<16) - 1;

void main() {
  setUp(() {
    debugResetSemanticsIdCounter();
  });

  group('SemanticsNode', () {
    const SemanticsTag tag1 = SemanticsTag('Tag One');
    const SemanticsTag tag2 = SemanticsTag('Tag Two');
    const SemanticsTag tag3 = SemanticsTag('Tag Three');

    test('tagging', () {
      final SemanticsNode node = SemanticsNode();

      expect(node.isTagged(tag1), isFalse);
      expect(node.isTagged(tag2), isFalse);

      node.tags = <SemanticsTag>{tag1};
      expect(node.isTagged(tag1), isTrue);
      expect(node.isTagged(tag2), isFalse);

      node.tags!.add(tag2);
      expect(node.isTagged(tag1), isTrue);
      expect(node.isTagged(tag2), isTrue);
    });

    test('getSemanticsData includes tags', () {
      final Set<SemanticsTag> tags = <SemanticsTag>{tag1, tag2};

      final SemanticsNode node = SemanticsNode()
        ..rect = const Rect.fromLTRB(0.0, 0.0, 10.0, 10.0)
        ..tags = tags;

      expect(node.getSemanticsData().tags, tags);

      tags.add(tag3);

      final SemanticsConfiguration config = SemanticsConfiguration()
        ..isSemanticBoundary = true
        ..isMergingSemanticsOfDescendants = true;

      node.updateWith(
        config: config,
        childrenInInversePaintOrder: <SemanticsNode>[
          SemanticsNode()
            ..isMergedIntoParent = true
            ..rect = const Rect.fromLTRB(5.0, 5.0, 10.0, 10.0)
            ..tags = tags,
        ],
      );

      expect(node.getSemanticsData().tags, tags);
    });

    test('SemanticsConfiguration can set both string label/value/hint and attributed version', () {
      final SemanticsConfiguration config = SemanticsConfiguration();
      config.label = 'label1';
      expect(config.label, 'label1');
      expect(config.attributedLabel.string, 'label1');
      expect(config.attributedLabel.attributes.isEmpty, isTrue);
      expect(
        (SemanticsNode()..updateWith(config: config)).toString(),
        'SemanticsNode#1(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label1")',
      );

      config.attributedLabel = AttributedString(
        'label2',
        attributes: <StringAttribute>[
          SpellOutStringAttribute(range: const TextRange(start: 0, end:1)),
        ]
      );
      expect(config.label, 'label2');
      expect(config.attributedLabel.string, 'label2');
      expect(config.attributedLabel.attributes.length, 1);
      expect(config.attributedLabel.attributes[0] is SpellOutStringAttribute, isTrue);
      expect(config.attributedLabel.attributes[0].range, const TextRange(start: 0, end: 1));
      expect(
        (SemanticsNode()..updateWith(config: config)).toString(),
        'SemanticsNode#2(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label2" [SpellOutStringAttribute(TextRange(start: 0, end: 1))])',
      );

      config.label = 'label3';
      expect(config.label, 'label3');
      expect(config.attributedLabel.string, 'label3');
      expect(config.attributedLabel.attributes.isEmpty, isTrue);
      expect(
        (SemanticsNode()..updateWith(config: config)).toString(),
        'SemanticsNode#3(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label3")',
      );

      config.value = 'value1';
      expect(config.value, 'value1');
      expect(config.attributedValue.string, 'value1');
      expect(config.attributedValue.attributes.isEmpty, isTrue);
      expect(
        (SemanticsNode()..updateWith(config: config)).toString(),
        'SemanticsNode#4(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label3", value: "value1")',
      );

      config.attributedValue = AttributedString(
          'value2',
          attributes: <StringAttribute>[
            SpellOutStringAttribute(range: const TextRange(start: 0, end:1)),
          ]
      );
      expect(config.value, 'value2');
      expect(config.attributedValue.string, 'value2');
      expect(config.attributedValue.attributes.length, 1);
      expect(config.attributedValue.attributes[0] is SpellOutStringAttribute, isTrue);
      expect(config.attributedValue.attributes[0].range, const TextRange(start: 0, end: 1));
      expect(
        (SemanticsNode()..updateWith(config: config)).toString(),
        'SemanticsNode#5(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label3", value: "value2" [SpellOutStringAttribute(TextRange(start: 0, end: 1))])',
      );

      config.value = 'value3';
      expect(config.value, 'value3');
      expect(config.attributedValue.string, 'value3');
      expect(config.attributedValue.attributes.isEmpty, isTrue);
      expect(
        (SemanticsNode()..updateWith(config: config)).toString(),
        'SemanticsNode#6(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label3", value: "value3")',
      );

      config.hint = 'hint1';
      expect(config.hint, 'hint1');
      expect(config.attributedHint.string, 'hint1');
      expect(config.attributedHint.attributes.isEmpty, isTrue);
      expect(
        (SemanticsNode()..updateWith(config: config)).toString(),
        'SemanticsNode#7(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label3", value: "value3", hint: "hint1")',
      );

      config.attributedHint = AttributedString(
          'hint2',
          attributes: <StringAttribute>[
            SpellOutStringAttribute(range: const TextRange(start: 0, end:1)),
          ]
      );
      expect(config.hint, 'hint2');
      expect(config.attributedHint.string, 'hint2');
      expect(config.attributedHint.attributes.length, 1);
      expect(config.attributedHint.attributes[0] is SpellOutStringAttribute, isTrue);
      expect(config.attributedHint.attributes[0].range, const TextRange(start: 0, end: 1));
      expect(
        (SemanticsNode()..updateWith(config: config)).toString(),
        'SemanticsNode#8(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label3", value: "value3", hint: "hint2" [SpellOutStringAttribute(TextRange(start: 0, end: 1))])',
      );

      config.hint = 'hint3';
      expect(config.hint, 'hint3');
      expect(config.attributedHint.string, 'hint3');
      expect(config.attributedHint.attributes.isEmpty, isTrue);
      expect(
        (SemanticsNode()..updateWith(config: config)).toString(),
        'SemanticsNode#9(STALE, owner: null, Rect.fromLTRB(0.0, 0.0, 0.0, 0.0), invisible, label: "label3", value: "value3", hint: "hint3")',
      );
    });

    test('mutate existing semantic node list errors', () {
      final SemanticsNode node = SemanticsNode()
        ..rect = const Rect.fromLTRB(0.0, 0.0, 10.0, 10.0);

      final SemanticsConfiguration config = SemanticsConfiguration()
        ..isSemanticBoundary = true
        ..isMergingSemanticsOfDescendants = true;

      final List<SemanticsNode> children = <SemanticsNode>[
        SemanticsNode()
          ..isMergedIntoParent = true
          ..rect = const Rect.fromLTRB(5.0, 5.0, 10.0, 10.0),
      ];

      node.updateWith(
        config: config,
        childrenInInversePaintOrder: children,
      );

      children.add(
        SemanticsNode()
          ..isMergedIntoParent = true
          ..rect = const Rect.fromLTRB(42.0, 42.0, 10.0, 10.0),
      );

      {
        late FlutterError error;
        try {
          node.updateWith(
            config: config,
            childrenInInversePaintOrder: children,
          );
        } on FlutterError catch (e) {
          error = e;
        }
        expect(error.toString(), equalsIgnoringHashCodes(
          'Failed to replace child semantics nodes because the list of `SemanticsNode`s was mutated.\n'
          'Instead of mutating the existing list, create a new list containing the desired `SemanticsNode`s.\n'
          'Error details:\n'
          "The list's length has changed from 1 to 2.",
        ));
        expect(
          error.diagnostics.singleWhere((DiagnosticsNode node) => node.level == DiagnosticLevel.hint).toString(),
          'Instead of mutating the existing list, create a new list containing the desired `SemanticsNode`s.',
        );
      }

      {
        late FlutterError error;
        final List<SemanticsNode> modifiedChildren = <SemanticsNode>[
          SemanticsNode()
            ..isMergedIntoParent = true
            ..rect = const Rect.fromLTRB(5.0, 5.0, 10.0, 10.0),
          SemanticsNode()
            ..isMergedIntoParent = true
            ..rect = const Rect.fromLTRB(10.0, 10.0, 20.0, 20.0),
        ];
        node.updateWith(
          config: config,
          childrenInInversePaintOrder: modifiedChildren,
        );
        try {
          modifiedChildren[0] = SemanticsNode()
            ..isMergedIntoParent = true
            ..rect = const Rect.fromLTRB(0.0, 0.0, 20.0, 20.0);
          modifiedChildren[1] = SemanticsNode()
            ..isMergedIntoParent = true
            ..rect = const Rect.fromLTRB(40.0, 14.0, 20.0, 20.0);
          node.updateWith(
            config: config,
            childrenInInversePaintOrder: modifiedChildren,
          );
        } on FlutterError catch (e) {
          error = e;
        }
        expect(error.toStringDeep(), equalsIgnoringHashCodes(
          'FlutterError\n'
          '   Failed to replace child semantics nodes because the list of\n'
          '   `SemanticsNode`s was mutated.\n'
          '   Instead of mutating the existing list, create a new list\n'
          '   containing the desired `SemanticsNode`s.\n'
          '   Error details:\n'
          '   Child node at position 0 was replaced:\n'
          '   Previous child: SemanticsNode#6(STALE, owner: null, merged up ⬆️, Rect.fromLTRB(0.0, 0.0, 20.0, 20.0))\n'
          '   New child: SemanticsNode#4(STALE, owner: null, merged up ⬆️, Rect.fromLTRB(5.0, 5.0, 10.0, 10.0))\n'
          '\n'
          '   Child node at position 1 was replaced:\n'
          '   Previous child: SemanticsNode#7(STALE, owner: null, merged up ⬆️, Rect.fromLTRB(40.0, 14.0, 20.0, 20.0))\n'
          '   New child: SemanticsNode#5(STALE, owner: null, merged up ⬆️, Rect.fromLTRB(10.0, 10.0, 20.0, 20.0))\n',
        ));

        expect(
          error.diagnostics.singleWhere((DiagnosticsNode node) => node.level == DiagnosticLevel.hint).toString(),
          'Instead of mutating the existing list, create a new list containing the desired `SemanticsNode`s.',
        );
        // Two previous children and two new children.
        expect(error.diagnostics.where((DiagnosticsNode node) => node.value is SemanticsNode).length, 4);
      }
    });

    test('after markNeedsSemanticsUpdate() all render objects between two semantic boundaries are asked for annotations', () {
      renderer.pipelineOwner.ensureSemantics();

      TestRender middle;
      final TestRender root = TestRender(
        hasTapAction: true,
        isSemanticBoundary: true,
        child: TestRender(
          hasLongPressAction: true,
          child: middle = TestRender(
            hasScrollLeftAction: true,
            child: TestRender(
              hasScrollRightAction: true,
              child: TestRender(
                hasScrollUpAction: true,
                isSemanticBoundary: true,
              ),
            ),
          ),
        ),
      );

      layout(root);
      pumpFrame(phase: EnginePhase.flushSemantics);

      int expectedActions = SemanticsAction.tap.index | SemanticsAction.longPress.index | SemanticsAction.scrollLeft.index | SemanticsAction.scrollRight.index;
      expect(root.debugSemantics!.getSemanticsData().actions, expectedActions);

      middle
        ..hasScrollLeftAction = false
        ..hasScrollDownAction = true;
      middle.markNeedsSemanticsUpdate();

      pumpFrame(phase: EnginePhase.flushSemantics);

      expectedActions = SemanticsAction.tap.index | SemanticsAction.longPress.index | SemanticsAction.scrollDown.index | SemanticsAction.scrollRight.index;
      expect(root.debugSemantics!.getSemanticsData().actions, expectedActions);
    });
  });

  test('toStringDeep() does not throw with transform == null', () {
    final SemanticsNode child1 = SemanticsNode()
      ..rect = const Rect.fromLTRB(0.0, 0.0, 5.0, 5.0);
    final SemanticsNode child2 = SemanticsNode()
      ..rect = const Rect.fromLTRB(5.0, 0.0, 10.0, 5.0);
    final SemanticsNode root = SemanticsNode()
      ..rect = const Rect.fromLTRB(0.0, 0.0, 10.0, 5.0);
    root.updateWith(
      config: null,
      childrenInInversePaintOrder: <SemanticsNode>[child1, child2],
    );

    expect(root.transform, isNull);
    expect(child1.transform, isNull);
    expect(child2.transform, isNull);

    expect(
      root.toStringDeep(),
      'SemanticsNode#3\n'
      ' │ STALE\n'
      ' │ owner: null\n'
      ' │ Rect.fromLTRB(0.0, 0.0, 10.0, 5.0)\n'
      ' │\n'
      ' ├─SemanticsNode#1\n'
      ' │   STALE\n'
      ' │   owner: null\n'
      ' │   Rect.fromLTRB(0.0, 0.0, 5.0, 5.0)\n'
      ' │\n'
      ' └─SemanticsNode#2\n'
      '     STALE\n'
      '     owner: null\n'
      '     Rect.fromLTRB(5.0, 0.0, 10.0, 5.0)\n',
    );
  });

  test('Incompatible OrdinalSortKey throw AssertionError when compared', () {
    // Different types.
    expect(() {
      const OrdinalSortKey(0.0).compareTo(const CustomSortKey(0.0));
    }, throwsAssertionError);
  });

  test('OrdinalSortKey compares correctly when names are the same', () {
    const List<List<SemanticsSortKey>> tests = <List<SemanticsSortKey>>[
      <SemanticsSortKey>[OrdinalSortKey(0.0), OrdinalSortKey(0.0)],
      <SemanticsSortKey>[OrdinalSortKey(0.0), OrdinalSortKey(1.0)],
      <SemanticsSortKey>[OrdinalSortKey(1.0), OrdinalSortKey(0.0)],
      <SemanticsSortKey>[OrdinalSortKey(1.0), OrdinalSortKey(1.0)],
      <SemanticsSortKey>[OrdinalSortKey(0.0, name: 'a'), OrdinalSortKey(0.0, name: 'a')],
      <SemanticsSortKey>[OrdinalSortKey(0.0, name: 'a'), OrdinalSortKey(1.0, name: 'a')],
      <SemanticsSortKey>[OrdinalSortKey(1.0, name: 'a'), OrdinalSortKey(0.0, name: 'a')],
      <SemanticsSortKey>[OrdinalSortKey(1.0, name: 'a'), OrdinalSortKey(1.0, name: 'a')],
    ];
    final List<int> expectedResults = <int>[0, -1, 1, 0, 0, -1, 1, 0];
    assert(tests.length == expectedResults.length);
    final List<int> results = <int>[
      for (final List<SemanticsSortKey> tuple in tests) tuple[0].compareTo(tuple[1]),
    ];
    expect(results, orderedEquals(expectedResults));

    // Differing types should throw an assertion.
    expect(() => const OrdinalSortKey(0.0).compareTo(const CustomSortKey(0.0)), throwsAssertionError);
  });

  test('OrdinalSortKey compares correctly when the names are different', () {
    const List<List<SemanticsSortKey>> tests = <List<SemanticsSortKey>>[
      <SemanticsSortKey>[OrdinalSortKey(0.0), OrdinalSortKey(0.0, name: 'bar')],
      <SemanticsSortKey>[OrdinalSortKey(0.0), OrdinalSortKey(1.0, name: 'bar')],
      <SemanticsSortKey>[OrdinalSortKey(1.0), OrdinalSortKey(0.0, name: 'bar')],
      <SemanticsSortKey>[OrdinalSortKey(1.0), OrdinalSortKey(1.0, name: 'bar')],
      <SemanticsSortKey>[OrdinalSortKey(0.0, name: 'foo'), OrdinalSortKey(0.0)],
      <SemanticsSortKey>[OrdinalSortKey(0.0, name: 'foo'), OrdinalSortKey(1.0)],
      <SemanticsSortKey>[OrdinalSortKey(1.0, name: 'foo'), OrdinalSortKey(0.0)],
      <SemanticsSortKey>[OrdinalSortKey(1.0, name: 'foo'), OrdinalSortKey(1.0)],
      <SemanticsSortKey>[OrdinalSortKey(0.0, name: 'foo'), OrdinalSortKey(0.0, name: 'bar')],
      <SemanticsSortKey>[OrdinalSortKey(0.0, name: 'foo'), OrdinalSortKey(1.0, name: 'bar')],
      <SemanticsSortKey>[OrdinalSortKey(1.0, name: 'foo'), OrdinalSortKey(0.0, name: 'bar')],
      <SemanticsSortKey>[OrdinalSortKey(1.0, name: 'foo'), OrdinalSortKey(1.0, name: 'bar')],
      <SemanticsSortKey>[OrdinalSortKey(0.0, name: 'bar'), OrdinalSortKey(0.0, name: 'foo')],
      <SemanticsSortKey>[OrdinalSortKey(0.0, name: 'bar'), OrdinalSortKey(1.0, name: 'foo')],
      <SemanticsSortKey>[OrdinalSortKey(1.0, name: 'bar'), OrdinalSortKey(0.0, name: 'foo')],
      <SemanticsSortKey>[OrdinalSortKey(1.0, name: 'bar'), OrdinalSortKey(1.0, name: 'foo')],
    ];
    final List<int> expectedResults = <int>[ -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1];
    assert(tests.length == expectedResults.length);
    final List<int> results = <int>[
      for (final List<SemanticsSortKey> tuple in tests) tuple[0].compareTo(tuple[1]),
    ];
    expect(results, orderedEquals(expectedResults));
  });

  test('toStringDeep respects childOrder parameter', () {
    final SemanticsNode child1 = SemanticsNode()
      ..rect = const Rect.fromLTRB(15.0, 0.0, 20.0, 5.0);
    final SemanticsNode child2 = SemanticsNode()
      ..rect = const Rect.fromLTRB(10.0, 0.0, 15.0, 5.0);
    final SemanticsNode root = SemanticsNode()
      ..rect = const Rect.fromLTRB(0.0, 0.0, 20.0, 5.0);
    root.updateWith(
      config: null,
      childrenInInversePaintOrder: <SemanticsNode>[child1, child2],
    );
    expect(
      root.toStringDeep(),
      'SemanticsNode#3\n'
      ' │ STALE\n'
      ' │ owner: null\n'
      ' │ Rect.fromLTRB(0.0, 0.0, 20.0, 5.0)\n'
      ' │\n'
      ' ├─SemanticsNode#1\n'
      ' │   STALE\n'
      ' │   owner: null\n'
      ' │   Rect.fromLTRB(15.0, 0.0, 20.0, 5.0)\n'
      ' │\n'
      ' └─SemanticsNode#2\n'
      '     STALE\n'
      '     owner: null\n'
      '     Rect.fromLTRB(10.0, 0.0, 15.0, 5.0)\n',
    );

    expect(
      root.toStringDeep(childOrder: DebugSemanticsDumpOrder.inverseHitTest),
      'SemanticsNode#3\n'
      ' │ STALE\n'
      ' │ owner: null\n'
      ' │ Rect.fromLTRB(0.0, 0.0, 20.0, 5.0)\n'
      ' │\n'
      ' ├─SemanticsNode#1\n'
      ' │   STALE\n'
      ' │   owner: null\n'
      ' │   Rect.fromLTRB(15.0, 0.0, 20.0, 5.0)\n'
      ' │\n'
      ' └─SemanticsNode#2\n'
      '     STALE\n'
      '     owner: null\n'
      '     Rect.fromLTRB(10.0, 0.0, 15.0, 5.0)\n',
    );

    final SemanticsNode child3 = SemanticsNode()
      ..rect = const Rect.fromLTRB(0.0, 0.0, 10.0, 5.0);
    child3.updateWith(
      config: null,
      childrenInInversePaintOrder: <SemanticsNode>[
        SemanticsNode()
          ..rect = const Rect.fromLTRB(5.0, 0.0, 10.0, 5.0),
        SemanticsNode()
          ..rect = const Rect.fromLTRB(0.0, 0.0, 5.0, 5.0),
      ],
    );

    final SemanticsNode rootComplex = SemanticsNode()
      ..rect = const Rect.fromLTRB(0.0, 0.0, 25.0, 5.0);
    rootComplex.updateWith(
        config: null,
        childrenInInversePaintOrder: <SemanticsNode>[child1, child2, child3],
    );

    expect(
      rootComplex.toStringDeep(),
      'SemanticsNode#7\n'
      ' │ STALE\n'
      ' │ owner: null\n'
      ' │ Rect.fromLTRB(0.0, 0.0, 25.0, 5.0)\n'
      ' │\n'
      ' ├─SemanticsNode#1\n'
      ' │   STALE\n'
      ' │   owner: null\n'
      ' │   Rect.fromLTRB(15.0, 0.0, 20.0, 5.0)\n'
      ' │\n'
      ' ├─SemanticsNode#2\n'
      ' │   STALE\n'
      ' │   owner: null\n'
      ' │   Rect.fromLTRB(10.0, 0.0, 15.0, 5.0)\n'
      ' │\n'
      ' └─SemanticsNode#4\n'
      '   │ STALE\n'
      '   │ owner: null\n'
      '   │ Rect.fromLTRB(0.0, 0.0, 10.0, 5.0)\n'
      '   │\n'
      '   ├─SemanticsNode#5\n'
      '   │   STALE\n'
      '   │   owner: null\n'
      '   │   Rect.fromLTRB(5.0, 0.0, 10.0, 5.0)\n'
      '   │\n'
      '   └─SemanticsNode#6\n'
      '       STALE\n'
      '       owner: null\n'
      '       Rect.fromLTRB(0.0, 0.0, 5.0, 5.0)\n',
    );

    expect(
      rootComplex.toStringDeep(childOrder: DebugSemanticsDumpOrder.inverseHitTest),
      'SemanticsNode#7\n'
      ' │ STALE\n'
      ' │ owner: null\n'
      ' │ Rect.fromLTRB(0.0, 0.0, 25.0, 5.0)\n'
      ' │\n'
      ' ├─SemanticsNode#1\n'
      ' │   STALE\n'
      ' │   owner: null\n'
      ' │   Rect.fromLTRB(15.0, 0.0, 20.0, 5.0)\n'
      ' │\n'
      ' ├─SemanticsNode#2\n'
      ' │   STALE\n'
      ' │   owner: null\n'
      ' │   Rect.fromLTRB(10.0, 0.0, 15.0, 5.0)\n'
      ' │\n'
      ' └─SemanticsNode#4\n'
      '   │ STALE\n'
      '   │ owner: null\n'
      '   │ Rect.fromLTRB(0.0, 0.0, 10.0, 5.0)\n'
      '   │\n'
      '   ├─SemanticsNode#5\n'
      '   │   STALE\n'
      '   │   owner: null\n'
      '   │   Rect.fromLTRB(5.0, 0.0, 10.0, 5.0)\n'
      '   │\n'
      '   └─SemanticsNode#6\n'
      '       STALE\n'
      '       owner: null\n'
      '       Rect.fromLTRB(0.0, 0.0, 5.0, 5.0)\n',
    );
  });

  test('debug properties', () {
    final SemanticsNode minimalProperties = SemanticsNode();
    expect(
      minimalProperties.toStringDeep(),
      'SemanticsNode#1\n'
      '   Rect.fromLTRB(0.0, 0.0, 0.0, 0.0)\n'
      '   invisible\n',
    );

    expect(
      minimalProperties.toStringDeep(minLevel: DiagnosticLevel.hidden),
      'SemanticsNode#1\n'
      '   owner: null\n'
      '   isMergedIntoParent: false\n'
      '   mergeAllDescendantsIntoThisNode: false\n'
      '   Rect.fromLTRB(0.0, 0.0, 0.0, 0.0)\n'
      '   tags: null\n'
      '   actions: []\n'
      '   customActions: []\n'
      '   flags: []\n'
      '   invisible\n'
      '   isHidden: false\n'
      '   label: ""\n'
      '   value: ""\n'
      '   increasedValue: ""\n'
      '   decreasedValue: ""\n'
      '   hint: ""\n'
      '   textDirection: null\n'
      '   sortKey: null\n'
      '   platformViewId: null\n'
      '   maxValueLength: null\n'
      '   currentValueLength: null\n'
      '   scrollChildren: null\n'
      '   scrollIndex: null\n'
      '   scrollExtentMin: null\n'
      '   scrollPosition: null\n'
      '   scrollExtentMax: null\n'
      '   elevation: 0.0\n'
      '   thickness: 0.0\n',
    );

    final SemanticsConfiguration config = SemanticsConfiguration()
      ..isSemanticBoundary = true
      ..isMergingSemanticsOfDescendants = true
      ..onScrollUp = () { }
      ..onLongPress = () { }
      ..onShowOnScreen = () { }
      ..isChecked = false
      ..isSelected = true
      ..isButton = true
      ..label = 'Use all the properties'
      ..textDirection = TextDirection.rtl
      ..sortKey = const OrdinalSortKey(1.0);
    final SemanticsNode allProperties = SemanticsNode()
      ..rect = const Rect.fromLTWH(50.0, 10.0, 20.0, 30.0)
      ..transform = Matrix4.translation(Vector3(10.0, 10.0, 0.0))
      ..updateWith(config: config);
    expect(
      allProperties.toStringDeep(),
      equalsIgnoringHashCodes(
        'SemanticsNode#2\n'
        '   STALE\n'
        '   owner: null\n'
        '   merge boundary ⛔️\n'
        '   Rect.fromLTRB(60.0, 20.0, 80.0, 50.0)\n'
        '   actions: longPress, scrollUp, showOnScreen\n'
        '   flags: hasCheckedState, isSelected, isButton\n'
        '   label: "Use all the properties"\n'
        '   textDirection: rtl\n'
        '   sortKey: OrdinalSortKey#19df5(order: 1.0)\n',
      ),
    );
    expect(
      allProperties.getSemanticsData().toString(),
      'SemanticsData(Rect.fromLTRB(50.0, 10.0, 70.0, 40.0), [1.0,0.0,0.0,10.0; 0.0,1.0,0.0,10.0; 0.0,0.0,1.0,0.0; 0.0,0.0,0.0,1.0], actions: [longPress, scrollUp, showOnScreen], flags: [hasCheckedState, isSelected, isButton], label: "Use all the properties", textDirection: rtl)',
    );

    final SemanticsNode scaled = SemanticsNode()
      ..rect = const Rect.fromLTWH(50.0, 10.0, 20.0, 30.0)
      ..transform = Matrix4.diagonal3(Vector3(10.0, 10.0, 1.0));
    expect(
      scaled.toStringDeep(),
      'SemanticsNode#3\n'
      '   STALE\n'
      '   owner: null\n'
      '   Rect.fromLTRB(50.0, 10.0, 70.0, 40.0) scaled by 10.0x\n',
    );
    expect(
      scaled.getSemanticsData().toString(),
      'SemanticsData(Rect.fromLTRB(50.0, 10.0, 70.0, 40.0), [10.0,0.0,0.0,0.0; 0.0,10.0,0.0,0.0; 0.0,0.0,1.0,0.0; 0.0,0.0,0.0,1.0])',
    );
  });

  test('Custom actions debug properties', () {
    final SemanticsConfiguration configuration = SemanticsConfiguration();
    const CustomSemanticsAction action1 = CustomSemanticsAction(label: 'action1');
    const CustomSemanticsAction action2 = CustomSemanticsAction(label: 'action2');
    const CustomSemanticsAction action3 = CustomSemanticsAction(label: 'action3');
    configuration.customSemanticsActions = <CustomSemanticsAction, VoidCallback>{
      action1: () { },
      action2: () { },
      action3: () { },
    };
    final SemanticsNode actionNode = SemanticsNode();
    actionNode.updateWith(config: configuration);

    expect(
      actionNode.toStringDeep(minLevel: DiagnosticLevel.hidden),
      'SemanticsNode#1\n'
      '   STALE\n'
      '   owner: null\n'
      '   isMergedIntoParent: false\n'
      '   mergeAllDescendantsIntoThisNode: false\n'
      '   Rect.fromLTRB(0.0, 0.0, 0.0, 0.0)\n'
      '   tags: null\n'
      '   actions: customAction\n'
      '   customActions: action1, action2, action3\n'
      '   flags: []\n'
      '   invisible\n'
      '   isHidden: false\n'
      '   label: ""\n'
      '   value: ""\n'
      '   increasedValue: ""\n'
      '   decreasedValue: ""\n'
      '   hint: ""\n'
      '   textDirection: null\n'
      '   sortKey: null\n'
      '   platformViewId: null\n'
      '   maxValueLength: null\n'
      '   currentValueLength: null\n'
      '   scrollChildren: null\n'
      '   scrollIndex: null\n'
      '   scrollExtentMin: null\n'
      '   scrollPosition: null\n'
      '   scrollExtentMax: null\n'
      '   elevation: 0.0\n'
      '   thickness: 0.0\n',
    );
  });

  test('Attributed String can concate', () {
    final AttributedString string1 = AttributedString(
      'string1',
      attributes: <StringAttribute>[
        SpellOutStringAttribute(range: const TextRange(start:0, end:4)),
      ]
    );
    final AttributedString string2 = AttributedString(
        'string2',
        attributes: <StringAttribute>[
          LocaleStringAttribute(locale: const Locale('es', 'MX'), range: const TextRange(start:0, end:4)),
        ]
    );
    final AttributedString result = string1 + string2;
    expect(result.string, 'string1string2');
    expect(result.attributes.length, 2);
    expect(result.attributes[0].range, const TextRange(start:0, end:4));
    expect(result.attributes[0] is SpellOutStringAttribute, isTrue);
    expect(result.toString(), "AttributedString('string1string2', attributes: [SpellOutStringAttribute(TextRange(start: 0, end: 4)), LocaleStringAttribute(TextRange(start: 7, end: 11), es-MX)])");
  });

  test('Semantics id does not repeat', () {
    final SemanticsOwner owner = SemanticsOwner();
    const int expectId = 1400;
    SemanticsNode? nodeToRemove;
    for (int i = 0; i < kMaxFrameworkAccessibilityIdentifier; i++) {
      final SemanticsNode node = SemanticsNode();
      node.attach(owner);
      if (node.id == expectId) {
        nodeToRemove = node;
      }
    }
    nodeToRemove!.detach();
    final SemanticsNode newNode = SemanticsNode();
    newNode.attach(owner);
    // Id is reused.
    expect(newNode.id, expectId);
  });

  test('Tags show up in debug properties', () {
    final SemanticsNode actionNode = SemanticsNode()
      ..tags = <SemanticsTag>{RenderViewport.useTwoPaneSemantics};

    expect(
      actionNode.toStringDeep(),
      contains('\n   tags: RenderViewport.twoPane\n'),
    );
  });

  test('SemanticsConfiguration getter/setter', () {
    final SemanticsConfiguration config = SemanticsConfiguration();
    const CustomSemanticsAction customAction = CustomSemanticsAction(label: 'test');

    expect(config.isSemanticBoundary, isFalse);
    expect(config.isButton, isFalse);
    expect(config.isLink, isFalse);
    expect(config.isMergingSemanticsOfDescendants, isFalse);
    expect(config.isEnabled, null);
    expect(config.isChecked, null);
    expect(config.isSelected, isFalse);
    expect(config.isBlockingSemanticsOfPreviouslyPaintedNodes, isFalse);
    expect(config.isFocused, isFalse);
    expect(config.isTextField, isFalse);

    expect(config.onShowOnScreen, isNull);
    expect(config.onScrollDown, isNull);
    expect(config.onScrollUp, isNull);
    expect(config.onScrollLeft, isNull);
    expect(config.onScrollRight, isNull);
    expect(config.onLongPress, isNull);
    expect(config.onDecrease, isNull);
    expect(config.onIncrease, isNull);
    expect(config.onMoveCursorForwardByCharacter, isNull);
    expect(config.onMoveCursorBackwardByCharacter, isNull);
    expect(config.onTap, isNull);
    expect(config.customSemanticsActions[customAction], isNull);

    config.isSemanticBoundary = true;
    config.isButton = true;
    config.isLink = true;
    config.isMergingSemanticsOfDescendants = true;
    config.isEnabled = true;
    config.isChecked = true;
    config.isSelected = true;
    config.isBlockingSemanticsOfPreviouslyPaintedNodes = true;
    config.isFocused = true;
    config.isTextField = true;

    void onShowOnScreen() { }
    void onScrollDown() { }
    void onScrollUp() { }
    void onScrollLeft() { }
    void onScrollRight() { }
    void onLongPress() { }
    void onDecrease() { }
    void onIncrease() { }
    void onMoveCursorForwardByCharacter(bool _) { }
    void onMoveCursorBackwardByCharacter(bool _) { }
    void onTap() { }
    void onCustomAction() { }

    config.onShowOnScreen = onShowOnScreen;
    config.onScrollDown = onScrollDown;
    config.onScrollUp = onScrollUp;
    config.onScrollLeft = onScrollLeft;
    config.onScrollRight = onScrollRight;
    config.onLongPress = onLongPress;
    config.onDecrease = onDecrease;
    config.onIncrease = onIncrease;
    config.onMoveCursorForwardByCharacter = onMoveCursorForwardByCharacter;
    config.onMoveCursorBackwardByCharacter = onMoveCursorBackwardByCharacter;
    config.onTap = onTap;
    config.customSemanticsActions[customAction] = onCustomAction;

    expect(config.isSemanticBoundary, isTrue);
    expect(config.isButton, isTrue);
    expect(config.isLink, isTrue);
    expect(config.isMergingSemanticsOfDescendants, isTrue);
    expect(config.isEnabled, isTrue);
    expect(config.isChecked, isTrue);
    expect(config.isSelected, isTrue);
    expect(config.isBlockingSemanticsOfPreviouslyPaintedNodes, isTrue);
    expect(config.isFocused, isTrue);
    expect(config.isTextField, isTrue);

    expect(config.onShowOnScreen, same(onShowOnScreen));
    expect(config.onScrollDown, same(onScrollDown));
    expect(config.onScrollUp, same(onScrollUp));
    expect(config.onScrollLeft, same(onScrollLeft));
    expect(config.onScrollRight, same(onScrollRight));
    expect(config.onLongPress, same(onLongPress));
    expect(config.onDecrease, same(onDecrease));
    expect(config.onIncrease, same(onIncrease));
    expect(config.onMoveCursorForwardByCharacter, same(onMoveCursorForwardByCharacter));
    expect(config.onMoveCursorBackwardByCharacter, same(onMoveCursorBackwardByCharacter));
    expect(config.onTap, same(onTap));
    expect(config.customSemanticsActions[customAction], same(onCustomAction));
  });
}

class TestRender extends RenderProxyBox {

  TestRender({
    this.hasTapAction = false,
    this.hasLongPressAction = false,
    this.hasScrollLeftAction = false,
    this.hasScrollRightAction = false,
    this.hasScrollUpAction = false,
    this.hasScrollDownAction = false,
    this.isSemanticBoundary = false,
    RenderBox? child,
  }) : super(child);

  bool hasTapAction;
  bool hasLongPressAction;
  bool hasScrollLeftAction;
  bool hasScrollRightAction;
  bool hasScrollUpAction;
  bool hasScrollDownAction;
  bool isSemanticBoundary;

  @override
  void describeSemanticsConfiguration(SemanticsConfiguration config) {
    super.describeSemanticsConfiguration(config);

    config.isSemanticBoundary = isSemanticBoundary;
    if (hasTapAction)
      config.onTap = () { };
    if (hasLongPressAction)
      config.onLongPress = () { };
    if (hasScrollLeftAction)
      config.onScrollLeft = () { };
    if (hasScrollRightAction)
      config.onScrollRight = () { };
    if (hasScrollUpAction)
      config.onScrollUp = () { };
    if (hasScrollDownAction)
      config.onScrollDown = () { };
  }
}

class CustomSortKey extends OrdinalSortKey {
  const CustomSortKey(double order, {String? name}) : super(order, name: name);
}
