File tree Expand file tree Collapse file tree 3 files changed +114
-0
lines changed
Expand file tree Collapse file tree 3 files changed +114
-0
lines changed Original file line number Diff line number Diff line change @@ -40,6 +40,7 @@ class ExampleTest extends PHPUnit\Framework\TestCase
4040* [ IsURL] ( ./src/Constraint/IsURL.php ) : asserts that a string contains only an URL
4141* [ IsEmail] ( ./src/Constraint/IsEmail.php ) : asserts that a string contains only an email address
4242* [ StringStartsWith] ( ./src/Constraint/StringStartsWith.php ) : asserts that a string starts with another string
43+ * [ StringEndsWith] ( ./src/Constraint/StringEndsWith.php ) : asserts that a string ends with another string
4344
4445## Tests
4546
Original file line number Diff line number Diff line change 1+ <?php
2+
3+ declare (strict_types=1 );
4+
5+ namespace PHPUnitExtraConstraints \Constraint ;
6+
7+ use PHPUnit \Framework \Constraint \Constraint ;
8+
9+ use function is_string ;
10+ use function strlen ;
11+ use function substr_compare ;
12+
13+ /**
14+ * Constraint that asserts that a string ends with another string.
15+ */
16+ final class StringEndsWith extends Constraint
17+ {
18+ /** @var string */
19+ private $ needle ;
20+
21+ public function __construct (string $ needle )
22+ {
23+ $ this ->needle = $ needle ;
24+ }
25+
26+ /**
27+ * @inheritDoc
28+ */
29+ protected function matches ($ other ): bool
30+ {
31+ return is_string ($ other )
32+ && self ::endsWith ($ other , $ this ->needle );
33+ }
34+
35+ private static function endsWith (string $ haystack , string $ needle ): bool
36+ {
37+ return '' === $ needle || ('' !== $ haystack && 0 === substr_compare ($ haystack , $ needle , -strlen ($ needle )));
38+ }
39+
40+ /**
41+ * @inheritDoc
42+ */
43+ public function toString (): string
44+ {
45+ return 'ends with ' . $ this ->needle ;
46+ }
47+ }
Original file line number Diff line number Diff line change 1+ <?php
2+
3+ declare (strict_types=1 );
4+
5+ namespace Tests \PHPUnitExtraConstraints \Constraint ;
6+
7+ use PHPUnitExtraConstraints \Constraint \StringEndsWith ;
8+ use Tests \PHPUnitExtraConstraints \CustomTestCase ;
9+
10+ class StringEndsWithTest extends CustomTestCase
11+ {
12+ /**
13+ * @dataProvider provideValidStrings
14+ * @testdox testWithValidString: $value ends with $needle
15+ *
16+ * @param string $needle
17+ * @param string $value
18+ */
19+ public function testWithValidString (string $ needle , string $ value ): void
20+ {
21+ $ constraint = new StringEndsWith ($ needle );
22+ self ::assertThat ($ value , $ constraint );
23+ }
24+
25+ /**
26+ * @return iterable<array<string>>
27+ */
28+ public function provideValidStrings (): iterable
29+ {
30+ yield ['c ' , 'abc ' ];
31+ yield ['bc ' , 'abc ' ];
32+ yield ['abc ' , 'abc ' ];
33+ yield ['' , 'abc ' ];
34+ yield ['0 ' , '00 ' ];
35+ }
36+
37+ /**
38+ * @dataProvider provideInvalidStrings
39+ * @testdox testWithInvalidString: $value doesn't end with $needle
40+ *
41+ * @param string $needle
42+ * @param mixed $value
43+ */
44+ public function testWithInvalidString (string $ needle , $ value ): void
45+ {
46+ $ constraint = new StringEndsWith ($ needle );
47+ $ this ->expectAssertionFailedError ('ends with ' . $ needle );
48+ self ::assertThat ($ value , $ constraint );
49+ }
50+
51+ /**
52+ * @return iterable<array<mixed>>
53+ */
54+ public function provideInvalidStrings (): iterable
55+ {
56+ yield ['zzz ' , null ];
57+ yield ['zzz ' , true ];
58+ yield ['zzz ' , false ];
59+ yield ['zzz ' , 0 ];
60+ yield ['zzz ' , 1 ];
61+ yield ['zzz ' , []];
62+ yield ['zzz ' , (object ) []];
63+ yield ['zzz ' , 'abc ' ];
64+ yield ['zzz ' , 'z ' ];
65+ }
66+ }
You can’t perform that action at this time.
0 commit comments