// 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 'dart:convert' show jsonDecode;

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  group('TextEditingDeltaInsertion', () {
    test('Verify creation of insertion delta when inserting at a collapsed selection.', () {
      const String jsonInsertionDelta = '{'
          '"oldText": "",'
          ' "deltaText": "let there be text",'
          ' "deltaStart": 0,'
          ' "deltaEnd": 0,'
          ' "selectionBase": 17,'
          ' "selectionExtent": 17,'
          ' "selectionAffinity" : "TextAffinity.downstream" ,'
          ' "selectionIsDirectional": false,'
          ' "composingBase": -1,'
          ' "composingExtent": -1}';
      final TextEditingDeltaInsertion delta = TextEditingDelta.fromJSON(jsonDecode(jsonInsertionDelta) as Map<String, dynamic>) as TextEditingDeltaInsertion;
      const TextRange expectedComposing = TextRange.empty;
      const int expectedInsertionOffset = 0;
      const TextSelection expectedSelection = TextSelection.collapsed(offset: 17);

      expect(delta.oldText, '');
      expect(delta.textInserted, 'let there be text');
      expect(delta.insertionOffset, expectedInsertionOffset);
      expect(delta.selection, expectedSelection);
      expect(delta.composing, expectedComposing);
    });

    test('Verify creation of insertion delta when inserting at end of composing region.', () {
      const String jsonInsertionDelta = '{'
          '"oldText": "hello worl",'
          ' "deltaText": "world",'
          ' "deltaStart": 6,'
          ' "deltaEnd": 10,'
          ' "selectionBase": 11,'
          ' "selectionExtent": 11,'
          ' "selectionAffinity" : "TextAffinity.downstream",'
          ' "selectionIsDirectional": false,'
          ' "composingBase": 6,'
          ' "composingExtent": 11}';

      final TextEditingDeltaInsertion delta = TextEditingDelta.fromJSON(jsonDecode(jsonInsertionDelta) as Map<String, dynamic>) as TextEditingDeltaInsertion;
      const TextRange expectedComposing = TextRange(start: 6, end: 11);
      const int expectedInsertionOffset = 10;
      const TextSelection expectedSelection = TextSelection.collapsed(offset: 11);

      expect(delta.oldText, 'hello worl');
      expect(delta.textInserted, 'd');
      expect(delta.insertionOffset, expectedInsertionOffset);
      expect(delta.selection, expectedSelection);
      expect(delta.composing, expectedComposing);
    });

    test('Verify invalid TextEditingDeltaInsertion fails to apply', () {
      const TextEditingDeltaInsertion delta =
              TextEditingDeltaInsertion(
                oldText: 'hello worl',
                textInserted: 'd',
                insertionOffset: 11,
                selection: TextSelection.collapsed(offset: 11),
                composing: TextRange.empty,
              );

      expect(() { delta.apply(TextEditingValue.empty); }, throwsAssertionError);
    });

    test('Verify TextEditingDeltaInsertion debugFillProperties', () {
      final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
      const TextEditingDeltaInsertion insertionDelta = TextEditingDeltaInsertion(
          oldText: 'hello worl',
          textInserted: 'd',
          insertionOffset: 10,
          selection: TextSelection.collapsed(offset: 11),
          composing: TextRange.empty,
      );

      insertionDelta.debugFillProperties(builder);

      final List<String> description = builder.properties
        .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
        .map((DiagnosticsNode node) => node.toString()).toList();

      expect(
        description,
        <String>[
          'oldText: hello worl',
          'textInserted: d',
          'insertionOffset: 10',
          'selection: TextSelection.collapsed(offset: 11, affinity: TextAffinity.downstream, isDirectional: false)',
          'composing: TextRange(start: -1, end: -1)',
        ],
      );
    });
  });

  group('TextEditingDeltaDeletion', () {
    test('Verify creation of deletion delta when deleting.', () {
      const String jsonDeletionDelta = '{'
          '"oldText": "let there be text.",'
          ' "deltaText": "",'
          ' "deltaStart": 1,'
          ' "deltaEnd": 2,'
          ' "selectionBase": 1,'
          ' "selectionExtent": 1,'
          ' "selectionAffinity" : "TextAffinity.downstream" ,'
          ' "selectionIsDirectional": false,'
          ' "composingBase": -1,'
          ' "composingExtent": -1}';

      final TextEditingDeltaDeletion delta = TextEditingDelta.fromJSON(jsonDecode(jsonDeletionDelta) as Map<String, dynamic>) as TextEditingDeltaDeletion;
      const TextRange expectedComposing = TextRange.empty;
      const TextRange expectedDeletedRange = TextRange(start: 1, end: 2);
      const TextSelection expectedSelection = TextSelection.collapsed(offset: 1);

      expect(delta.oldText, 'let there be text.');
      expect(delta.textDeleted, 'e');
      expect(delta.deletedRange, expectedDeletedRange);
      expect(delta.selection, expectedSelection);
      expect(delta.composing, expectedComposing);
    });

    test('Verify creation of deletion delta when deleting at end of composing region.', () {
      const String jsonDeletionDelta = '{'
          '"oldText": "hello world",'
          ' "deltaText": "worl",'
          ' "deltaStart": 6,'
          ' "deltaEnd": 11,'
          ' "selectionBase": 10,'
          ' "selectionExtent": 10,'
          ' "selectionAffinity" : "TextAffinity.downstream",'
          ' "selectionIsDirectional": false,'
          ' "composingBase": 6,'
          ' "composingExtent": 10}';

      final TextEditingDeltaDeletion delta = TextEditingDelta.fromJSON(jsonDecode(jsonDeletionDelta) as Map<String, dynamic>) as TextEditingDeltaDeletion;
      const TextRange expectedComposing = TextRange(start: 6, end: 10);
      const TextRange expectedDeletedRange = TextRange(start: 10, end: 11);
      const TextSelection expectedSelection = TextSelection.collapsed(offset: 10);

      expect(delta.oldText, 'hello world');
      expect(delta.textDeleted, 'd');
      expect(delta.deletedRange, expectedDeletedRange);
      expect(delta.selection, expectedSelection);
      expect(delta.composing, expectedComposing);
    });

    test('Verify invalid TextEditingDeltaDeletion fails to apply', () {
      const TextEditingDeltaDeletion delta =
              TextEditingDeltaDeletion(
                oldText: 'hello world',
                deletedRange: TextRange(start: 5, end: 12),
                selection: TextSelection.collapsed(offset: 5),
                composing: TextRange.empty,
              );

      expect(() { delta.apply(TextEditingValue.empty); }, throwsAssertionError);
    });

    test('Verify TextEditingDeltaDeletion debugFillProperties', () {
      final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
      const TextEditingDeltaDeletion deletionDelta = TextEditingDeltaDeletion(
        oldText: 'hello world',
        deletedRange: TextRange(start: 6, end: 10),
        selection: TextSelection.collapsed(offset: 6),
        composing: TextRange.empty,
      );

      deletionDelta.debugFillProperties(builder);

      final List<String> description = builder.properties
        .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
        .map((DiagnosticsNode node) => node.toString()).toList();

      expect(
        description,
        <String>[
          'oldText: hello world',
          'textDeleted: worl',
          'deletedRange: TextRange(start: 6, end: 10)',
          'selection: TextSelection.collapsed(offset: 6, affinity: TextAffinity.downstream, isDirectional: false)',
          'composing: TextRange(start: -1, end: -1)',
        ],
      );
    });
  });

  group('TextEditingDeltaReplacement', () {
    test('Verify creation of replacement delta when replacing with longer.', () {
      const String jsonReplacementDelta = '{'
          '"oldText": "hello worfi",'
          ' "deltaText": "working",'
          ' "deltaStart": 6,'
          ' "deltaEnd": 11,'
          ' "selectionBase": 13,'
          ' "selectionExtent": 13,'
          ' "selectionAffinity" : "TextAffinity.downstream",'
          ' "selectionIsDirectional": false,'
          ' "composingBase": 6,'
          ' "composingExtent": 13}';

      final TextEditingDeltaReplacement delta = TextEditingDelta.fromJSON(jsonDecode(jsonReplacementDelta) as Map<String, dynamic>) as TextEditingDeltaReplacement;
      const TextRange expectedComposing = TextRange(start: 6, end: 13);
      const TextRange expectedReplacedRange = TextRange(start: 6, end: 11);
      const TextSelection expectedSelection = TextSelection.collapsed(offset: 13);

      expect(delta.oldText, 'hello worfi');
      expect(delta.textReplaced, 'worfi');
      expect(delta.replacementText, 'working');
      expect(delta.replacedRange, expectedReplacedRange);
      expect(delta.selection, expectedSelection);
      expect(delta.composing, expectedComposing);
    });

    test('Verify creation of replacement delta when replacing with shorter.', () {
      const String jsonReplacementDelta = '{'
          '"oldText": "hello world",'
          ' "deltaText": "h",'
          ' "deltaStart": 6,'
          ' "deltaEnd": 11,'
          ' "selectionBase": 7,'
          ' "selectionExtent": 7,'
          ' "selectionAffinity" : "TextAffinity.downstream",'
          ' "selectionIsDirectional": false,'
          ' "composingBase": 6,'
          ' "composingExtent": 7}';

      final TextEditingDeltaReplacement delta = TextEditingDelta.fromJSON(jsonDecode(jsonReplacementDelta) as Map<String, dynamic>) as TextEditingDeltaReplacement;
      const TextRange expectedComposing = TextRange(start: 6, end: 7);
      const TextRange expectedReplacedRange = TextRange(start: 6, end: 11);
      const TextSelection expectedSelection = TextSelection.collapsed(offset: 7);

      expect(delta.oldText, 'hello world');
      expect(delta.textReplaced, 'world');
      expect(delta.replacementText, 'h');
      expect(delta.replacedRange, expectedReplacedRange);
      expect(delta.selection, expectedSelection);
      expect(delta.composing, expectedComposing);
    });

    test('Verify creation of replacement delta when replacing with same.', () {
      const String jsonReplacementDelta = '{'
          '"oldText": "hello world",'
          ' "deltaText": "words",'
          ' "deltaStart": 6,'
          ' "deltaEnd": 11,'
          ' "selectionBase": 11,'
          ' "selectionExtent": 11,'
          ' "selectionAffinity" : "TextAffinity.downstream",'
          ' "selectionIsDirectional": false,'
          ' "composingBase": 6,'
          ' "composingExtent": 11}';

      final TextEditingDeltaReplacement delta = TextEditingDelta.fromJSON(jsonDecode(jsonReplacementDelta) as Map<String, dynamic>) as TextEditingDeltaReplacement;
      const TextRange expectedComposing = TextRange(start: 6, end: 11);
      const TextRange expectedReplacedRange = TextRange(start: 6, end: 11);
      const TextSelection expectedSelection = TextSelection.collapsed(offset: 11);

      expect(delta.oldText, 'hello world');
      expect(delta.textReplaced, 'world');
      expect(delta.replacementText, 'words');
      expect(delta.replacedRange, expectedReplacedRange);
      expect(delta.selection, expectedSelection);
      expect(delta.composing, expectedComposing);
    });

    test('Verify invalid TextEditingDeltaReplacement fails to apply', () {
      const TextEditingDeltaReplacement delta =
              TextEditingDeltaReplacement(
                oldText: 'hello worl',
                replacementText: 'world',
                replacedRange: TextRange(start: 5, end: 11),
                selection: TextSelection.collapsed(offset: 11),
                composing: TextRange.empty,
              );

      expect(() { delta.apply(TextEditingValue.empty); }, throwsAssertionError);
    });

    test('Verify TextEditingDeltaReplacement debugFillProperties', () {
      final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
      const TextEditingDeltaReplacement replacementDelta = TextEditingDeltaReplacement(
        oldText: 'hello world',
        replacementText: 'h',
        replacedRange: TextRange(start: 6, end: 11),
        selection: TextSelection.collapsed(offset: 7),
        composing: TextRange(start: 6, end: 7),
      );

      replacementDelta.debugFillProperties(builder);

      final List<String> description = builder.properties
        .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
        .map((DiagnosticsNode node) => node.toString()).toList();

      expect(
        description,
        <String>[
          'oldText: hello world',
          'textReplaced: world',
          'replacementText: h',
          'replacedRange: TextRange(start: 6, end: 11)',
          'selection: TextSelection.collapsed(offset: 7, affinity: TextAffinity.downstream, isDirectional: false)',
          'composing: TextRange(start: 6, end: 7)',
        ],
      );
    });
  });

  group('TextEditingDeltaNonTextUpdate', () {
    test('Verify non text update delta created.', () {
      const String jsonNonTextUpdateDelta = '{'
          '"oldText": "hello world",'
          ' "deltaText": "",'
          ' "deltaStart": -1,'
          ' "deltaEnd": -1,'
          ' "selectionBase": 10,'
          ' "selectionExtent": 10,'
          ' "selectionAffinity" : "TextAffinity.downstream",'
          ' "selectionIsDirectional": false,'
          ' "composingBase": 6,'
          ' "composingExtent": 11}';

      final TextEditingDeltaNonTextUpdate delta = TextEditingDelta.fromJSON(jsonDecode(jsonNonTextUpdateDelta) as Map<String, dynamic>) as TextEditingDeltaNonTextUpdate;
      const TextRange expectedComposing = TextRange(start: 6, end: 11);
      const TextSelection expectedSelection = TextSelection.collapsed(offset: 10);

      expect(delta.oldText, 'hello world');
      expect(delta.selection, expectedSelection);
      expect(delta.composing, expectedComposing);
    });

    test('Verify invalid TextEditingDeltaNonTextUpdate fails to apply', () {
      const TextEditingDeltaNonTextUpdate delta =
              TextEditingDeltaNonTextUpdate(
                oldText: 'hello world',
                selection: TextSelection.collapsed(offset: 12),
                composing: TextRange.empty,
              );

      expect(() { delta.apply(TextEditingValue.empty); }, throwsAssertionError);
    });

    test('Verify TextEditingDeltaNonTextUpdate debugFillProperties', () {
      final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
      const TextEditingDeltaNonTextUpdate nonTextUpdateDelta = TextEditingDeltaNonTextUpdate(
        oldText: 'hello world',
        selection: TextSelection.collapsed(offset: 7),
        composing: TextRange(start: 6, end: 7),
      );

      nonTextUpdateDelta.debugFillProperties(builder);

      final List<String> description = builder.properties
        .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
        .map((DiagnosticsNode node) => node.toString()).toList();

      expect(
        description,
        <String>[
          'oldText: hello world',
          'selection: TextSelection.collapsed(offset: 7, affinity: TextAffinity.downstream, isDirectional: false)',
          'composing: TextRange(start: 6, end: 7)',
        ],
      );
    });
  });
}
