Skip to content

Commit 19b869e

Browse files
herndlmondrejmirtes
authored andcommitted
Add support for contains, startsWith, startsWithLetter and endsWith
1 parent 9009135 commit 19b869e

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ This extension specifies types of values passed to:
6969
* `Assert::methodExists`
7070
* `Assert::propertyExists`
7171
* `Assert::isArrayAccessible`
72+
* `Assert::contains`
73+
* `Assert::startsWith`
74+
* `Assert::startsWithLetter`
75+
* `Assert::endsWith`
7276
* `Assert::unicodeLetters`
7377
* `Assert::alpha`
7478
* `Assert::digits`

src/Type/WebMozartAssert/AssertTypeSpecifyingExtension.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class AssertTypeSpecifyingExtension implements StaticMethodTypeSpecifyingExtensi
3030

3131
private const ASSERTIONS_RESULTING_IN_NON_EMPTY_STRING = [
3232
'stringNotEmpty',
33+
'startsWithLetter',
3334
'unicodeLetters',
3435
'alpha',
3536
'digits',
@@ -485,6 +486,27 @@ private static function getExpressionResolvers(): array
485486
)
486487
);
487488
},
489+
'contains' => function (Scope $scope, Arg $value, Arg $subString): \PhpParser\Node\Expr {
490+
if ($scope->getType($subString->value)->isNonEmptyString()->yes()) {
491+
return self::createIsNonEmptyStringExpression([$value]);
492+
}
493+
494+
return self::createIsStringExpression([$value]);
495+
},
496+
'startsWith' => function (Scope $scope, Arg $value, Arg $prefix): \PhpParser\Node\Expr {
497+
if ($scope->getType($prefix->value)->isNonEmptyString()->yes()) {
498+
return self::createIsNonEmptyStringExpression([$value]);
499+
}
500+
501+
return self::createIsStringExpression([$value]);
502+
},
503+
'endsWith' => function (Scope $scope, Arg $value, Arg $suffix): \PhpParser\Node\Expr {
504+
if ($scope->getType($suffix->value)->isNonEmptyString()->yes()) {
505+
return self::createIsNonEmptyStringExpression([$value]);
506+
}
507+
508+
return self::createIsStringExpression([$value]);
509+
},
488510
'length' => function (Scope $scope, Arg $value, Arg $length): \PhpParser\Node\Expr {
489511
return new BooleanAnd(
490512
new \PhpParser\Node\Expr\FuncCall(
@@ -687,6 +709,17 @@ private function arrayOrIterable(
687709
);
688710
}
689711

712+
/**
713+
* @param \PhpParser\Node\Arg[] $args
714+
*/
715+
private static function createIsStringExpression(array $args): \PhpParser\Node\Expr
716+
{
717+
return new \PhpParser\Node\Expr\FuncCall(
718+
new \PhpParser\Node\Name('is_string'),
719+
[$args[0]]
720+
);
721+
}
722+
690723
/**
691724
* @param \PhpParser\Node\Arg[] $args
692725
*/

tests/Type/WebMozartAssert/data/string.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,48 @@
77
class TestStrings
88
{
99

10+
/**
11+
* @param non-empty-string $b
12+
*/
13+
public function contains(string $a, string $b): void
14+
{
15+
Assert::contains($a, $a);
16+
\PHPStan\Testing\assertType('string', $a);
17+
18+
Assert::contains($a, $b);
19+
\PHPStan\Testing\assertType('non-empty-string', $a);
20+
}
21+
22+
/**
23+
* @param non-empty-string $b
24+
*/
25+
public function startsWith(string $a, string $b): void
26+
{
27+
Assert::startsWith($a, $a);
28+
\PHPStan\Testing\assertType('string', $a);
29+
30+
Assert::startsWith($a, $b);
31+
\PHPStan\Testing\assertType('non-empty-string', $a);
32+
}
33+
34+
public function startsWithLetter(string $a): void
35+
{
36+
Assert::startsWithLetter($a);
37+
\PHPStan\Testing\assertType('non-empty-string', $a);
38+
}
39+
40+
/**
41+
* @param non-empty-string $b
42+
*/
43+
public function endsWith(string $a, string $b): void
44+
{
45+
Assert::endsWith($a, $a);
46+
\PHPStan\Testing\assertType('string', $a);
47+
48+
Assert::endsWith($a, $b);
49+
\PHPStan\Testing\assertType('non-empty-string', $a);
50+
}
51+
1052
public function length(string $a, string $b): void
1153
{
1254
Assert::length($a, 0);

0 commit comments

Comments
 (0)