// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
// for details. 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:checks/checks.dart';
import 'package:test/scaffolding.dart';

import '../test_shared.dart';

void main() {
  group('StringChecks', () {
    test('contains', () {
      check('bob').contains('bo');
      check('bob').isRejectedBy((it) => it.contains('kayleb'),
          which: ["Does not contain 'kayleb'"]);
    });
    test('length', () {
      check('bob').length.equals(3);
    });
    test('isEmpty', () {
      check('').isEmpty();
      check('bob').isRejectedBy((it) => it.isEmpty(), which: ['is not empty']);
    });
    test('isNotEmpty', () {
      check('bob').isNotEmpty();
      check('').isRejectedBy((it) => it.isNotEmpty(), which: ['is empty']);
    });
    test('startsWith', () {
      check('bob').startsWith('bo');
      check('bob').isRejectedBy((it) => it.startsWith('kayleb'),
          which: ["does not start with 'kayleb'"]);
    });
    test('endsWith', () {
      check('bob').endsWith('ob');
      check('bob').isRejectedBy((it) => it.endsWith('kayleb'),
          which: ["does not end with 'kayleb'"]);
    });

    group('matches', () {
      test('succeeds for strings that match a regex', () {
        check('123').matchesPattern(RegExp(r'\d\d\d'));
      });
      test('succeeds for strings that match a string pattern', () {
        check(r'\d').matchesPattern(r'\d');
      });
      test('fails for non-matching regex', () {
        check('abc').isRejectedBy((it) => it.matchesPattern(RegExp(r'\d\d\d')),
            which: [r'does not match <RegExp: pattern=\d\d\d flags=>']);
      });
      test('fails for non-matching string pattern', () {
        // A string is _not_ converted to a regex, string patterns must match
        // directly.
        check('123').isRejectedBy((it) => it.matchesPattern(r'\d\d\d'),
            which: [r"does not match '\\d\\d\\d'"]);
      });
      test('can be described', () {
        check((Subject<String> it) => it.matchesPattern(RegExp(r'\d\d\d')))
            .description
            .deepEquals([r'  matches <RegExp: pattern=\d\d\d flags=>']);
        check((Subject<String> it) => it.matchesPattern('abc'))
            .description
            .deepEquals([r"  matches 'abc'"]);
      });
    });

    group('containsInOrder', () {
      test('happy case', () {
        check('foo bar baz').containsInOrder(['foo', 'baz']);
      });
      test('reports when first substring is missing', () {
        check('baz').isRejectedBy((it) => it.containsInOrder(['foo', 'baz']),
            which: ['does not have a match for the substring \'foo\'']);
      });
      test('reports when substring is missing following a match', () {
        check('foo bar')
            .isRejectedBy((it) => it.containsInOrder(['foo', 'baz']), which: [
          'does not have a match for the substring \'baz\'',
          'following the other matches up to character 3'
        ]);
      });
    });

    group('equals', () {
      test('succeeeds for happy case', () {
        check('foo').equals('foo');
      });
      test('succeeeds for equal empty strings', () {
        check('').equals('');
      });
      test('reports extra characters for long string', () {
        check('foobar').isRejectedBy((it) => it.equals('foo'),
            which: ['is too long with unexpected trailing characters:', 'bar']);
      });
      test('reports extra characters for long string against empty', () {
        check('foo').isRejectedBy((it) => it.equals(''),
            which: ['is not the empty string']);
      });
      test('reports truncated extra characters for very long string', () {
        check('foobar baz more stuff').isRejectedBy((it) => it.equals('foo'),
            which: [
              'is too long with unexpected trailing characters:',
              'bar baz mo ...'
            ]);
      });
      test('reports missing characters for short string', () {
        check('foo').isRejectedBy((it) => it.equals('foobar'),
            which: ['is too short with missing trailing characters:', 'bar']);
      });
      test('reports missing characters for empty string', () {
        check('').isRejectedBy((it) => it.equals('foo bar baz'),
            actual: ['an empty string'],
            which: ['is missing all expected characters:', 'foo bar ba ...']);
      });
      test('reports truncated missing characters for very short string', () {
        check('foo').isRejectedBy((it) => it.equals('foobar baz more stuff'),
            which: [
              'is too short with missing trailing characters:',
              'bar baz mo ...'
            ]);
      });
      test('reports index of different character', () {
        check('hit').isRejectedBy((it) => it.equals('hat'), which: [
          'differs at offset 1:',
          'hat',
          'hit',
          ' ^',
        ]);
      });
      test('reports truncated index of different character in large string',
          () {
        check('blah blah blah hit blah blah blah').isRejectedBy(
            (it) => it.equals('blah blah blah hat blah blah blah'),
            which: [
              'differs at offset 16:',
              '... lah blah hat blah bl ...',
              '... lah blah hit blah bl ...',
              '              ^',
            ]);
      });
    });

    group('equalsIgnoringCase', () {
      test('succeeeds for happy case', () {
        check('FOO').equalsIgnoringCase('foo');
        check('foo').equalsIgnoringCase('FOO');
      });
      test('reports original extra characters for long string', () {
        check('FOOBAR').isRejectedBy((it) => it.equalsIgnoringCase('foo'),
            which: ['is too long with unexpected trailing characters:', 'BAR']);
      });
      test('reports original missing characters for short string', () {
        check('FOO').isRejectedBy((it) => it.equalsIgnoringCase('fooBAR'),
            which: ['is too short with missing trailing characters:', 'BAR']);
      });
      test('reports index of different character with original characters', () {
        check('HiT').isRejectedBy((it) => it.equalsIgnoringCase('hAt'), which: [
          'differs at offset 1:',
          'hAt',
          'HiT',
          ' ^',
        ]);
      });
    });

    group('equalsIgnoringWhitespace', () {
      test('allows differing internal whitespace', () {
        check('foo \t\n bar').equalsIgnoringWhitespace('foo bar');
      });
      test('allows extra leading/trailing whitespace', () {
        check(' foo ').equalsIgnoringWhitespace('foo');
      });
      test('allows missing leading/trailing whitespace', () {
        check('foo').equalsIgnoringWhitespace(' foo ');
      });
      test('reports original extra characters for long string', () {
        check('foo \t bar \n baz').isRejectedBy(
            (it) => it.equalsIgnoringWhitespace('foo bar'),
            which: [
              'is too long with unexpected trailing characters:',
              ' baz'
            ]);
      });
      test('reports original missing characters for short string', () {
        check('foo  bar').isRejectedBy(
            (it) => it.equalsIgnoringWhitespace('foo bar baz'),
            which: ['is too short with missing trailing characters:', ' baz']);
      });
      test('reports index of different character with original characters', () {
        check('x  hit  x').isRejectedBy(
            (it) => it.equalsIgnoringWhitespace('x hat x'),
            which: [
              'differs at offset 3:',
              'x hat x',
              'x hit x',
              '   ^',
            ]);
      });
    });
  });
}
