| // 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', ' ^'], | |
| ); | |
| }); | |
| }); | |
| }); | |
| } |