Skip to content

Commit

Permalink
Add support for contains, startsWith, startsWithLetter and endsWith
Browse files Browse the repository at this point in the history
  • Loading branch information
herndlm authored and ondrejmirtes committed Jan 9, 2022
1 parent 9009135 commit 19b869e
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 0 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ This extension specifies types of values passed to:
* `Assert::methodExists`
* `Assert::propertyExists`
* `Assert::isArrayAccessible`
* `Assert::contains`
* `Assert::startsWith`
* `Assert::startsWithLetter`
* `Assert::endsWith`
* `Assert::unicodeLetters`
* `Assert::alpha`
* `Assert::digits`
Expand Down
33 changes: 33 additions & 0 deletions src/Type/WebMozartAssert/AssertTypeSpecifyingExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class AssertTypeSpecifyingExtension implements StaticMethodTypeSpecifyingExtensi

private const ASSERTIONS_RESULTING_IN_NON_EMPTY_STRING = [
'stringNotEmpty',
'startsWithLetter',
'unicodeLetters',
'alpha',
'digits',
Expand Down Expand Up @@ -485,6 +486,27 @@ private static function getExpressionResolvers(): array
)
);
},
'contains' => function (Scope $scope, Arg $value, Arg $subString): \PhpParser\Node\Expr {
if ($scope->getType($subString->value)->isNonEmptyString()->yes()) {
return self::createIsNonEmptyStringExpression([$value]);
}

return self::createIsStringExpression([$value]);
},
'startsWith' => function (Scope $scope, Arg $value, Arg $prefix): \PhpParser\Node\Expr {
if ($scope->getType($prefix->value)->isNonEmptyString()->yes()) {
return self::createIsNonEmptyStringExpression([$value]);
}

return self::createIsStringExpression([$value]);
},
'endsWith' => function (Scope $scope, Arg $value, Arg $suffix): \PhpParser\Node\Expr {
if ($scope->getType($suffix->value)->isNonEmptyString()->yes()) {
return self::createIsNonEmptyStringExpression([$value]);
}

return self::createIsStringExpression([$value]);
},
'length' => function (Scope $scope, Arg $value, Arg $length): \PhpParser\Node\Expr {
return new BooleanAnd(
new \PhpParser\Node\Expr\FuncCall(
Expand Down Expand Up @@ -687,6 +709,17 @@ private function arrayOrIterable(
);
}

/**
* @param \PhpParser\Node\Arg[] $args
*/
private static function createIsStringExpression(array $args): \PhpParser\Node\Expr
{
return new \PhpParser\Node\Expr\FuncCall(
new \PhpParser\Node\Name('is_string'),
[$args[0]]
);
}

/**
* @param \PhpParser\Node\Arg[] $args
*/
Expand Down
42 changes: 42 additions & 0 deletions tests/Type/WebMozartAssert/data/string.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,48 @@
class TestStrings
{

/**
* @param non-empty-string $b
*/
public function contains(string $a, string $b): void
{
Assert::contains($a, $a);
\PHPStan\Testing\assertType('string', $a);

Assert::contains($a, $b);
\PHPStan\Testing\assertType('non-empty-string', $a);
}

/**
* @param non-empty-string $b
*/
public function startsWith(string $a, string $b): void
{
Assert::startsWith($a, $a);
\PHPStan\Testing\assertType('string', $a);

Assert::startsWith($a, $b);
\PHPStan\Testing\assertType('non-empty-string', $a);
}

public function startsWithLetter(string $a): void
{
Assert::startsWithLetter($a);
\PHPStan\Testing\assertType('non-empty-string', $a);
}

/**
* @param non-empty-string $b
*/
public function endsWith(string $a, string $b): void
{
Assert::endsWith($a, $a);
\PHPStan\Testing\assertType('string', $a);

Assert::endsWith($a, $b);
\PHPStan\Testing\assertType('non-empty-string', $a);
}

public function length(string $a, string $b): void
{
Assert::length($a, 0);
Expand Down

0 comments on commit 19b869e

Please sign in to comment.