Skip to content

Commit

Permalink
Merge pull request #51 from matthiasnoback/issue_49
Browse files Browse the repository at this point in the history
Fix reported issue
  • Loading branch information
matthiasnoback authored Feb 2, 2022
2 parents 163d732 + c080da7 commit c021934
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 23 deletions.
57 changes: 39 additions & 18 deletions ArgumentValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,33 @@ public function __construct(

public function validate(\ReflectionParameter $parameter, $argument)
{
if ($parameter->isArray()) {
if ($parameter->allowsNull() && is_null($argument)) {
return;
}
$this->validateArrayArgument($argument);
} elseif ($parameter->getClass()) {
$this->validateObjectArgument($parameter->getClass()->getName(), $argument, $parameter->allowsNull());
$parameterType = $parameter->getType();
if ($parameterType === null) {
return;
}

if ($parameterType->getName() === 'array') {
$this->validateArrayArgument($parameter, $argument);
} elseif (class_exists($parameterType->getName())) {
$this->validateObjectArgument($parameterType->getName(), $argument, $parameter->allowsNull());
}

// other arguments don't need to be or can't be validated
}

private function validateArrayArgument($argument)
private function validateArrayArgument(\ReflectionParameter $parameter, $argument)
{
if (!is_array($argument)) {
if ($parameter->allowsNull() && is_null($argument)) {
return;
}

if (class_exists('Symfony\Component\ExpressionLanguage\Expression') && $argument instanceof Expression) {
$this->validateExpressionArgument('array', $argument, $parameter->allowsNull());
} else {
if (is_array($argument)) {
return;
}

throw new TypeHintMismatchException(sprintf(
'Argument of type "%s" should have been an array',
gettype($argument)
Expand Down Expand Up @@ -95,14 +107,14 @@ private function validateDefinitionArgument($className, Definition $definition)
$this->validateClass($className, $resultingClass);
}

private function validateExpressionArgument($className, Expression $expression, $allowsNull)
private function validateExpressionArgument($type, Expression $expression, $allowsNull)
{
$expressionLanguage = new ExpressionLanguage();

$this->validateExpressionSyntax($expression, $expressionLanguage);

if ($this->evaluateExpressions) {
$this->validateExpressionResult($className, $expression, $allowsNull, $expressionLanguage);
$this->validateExpressionResult($type, $expression, $allowsNull, $expressionLanguage);
}
}

Expand All @@ -115,7 +127,7 @@ private function validateExpressionSyntax(Expression $expression, ExpressionLang
}
}

private function validateExpressionResult($className, Expression $expression, $allowsNull, ExpressionLanguage $expressionLanguage)
private function validateExpressionResult($expectedType, Expression $expression, $allowsNull, ExpressionLanguage $expressionLanguage)
{
try {
$result = $expressionLanguage->evaluate($expression, array('container' => $this->containerBuilder));
Expand All @@ -130,20 +142,29 @@ private function validateExpressionResult($className, Expression $expression, $a

throw new TypeHintMismatchException(sprintf(
'Argument for type-hint "%s" is an expression that evaluates to null, which is not allowed',
$className
$expectedType
));
}

if (!is_object($result)) {
if ($expectedType === 'array' && !is_array($result)) {
throw new TypeHintMismatchException(sprintf(
'Argument for type-hint "%s" is an expression that evaluates to a non-object',
$className
'Argument for type-hint "%s" is an expression that evaluates to a non-array',
$expectedType
));
}

$resultingClass = get_class($result);
if (class_exists($expectedType)) {
if (!is_object($result)) {
throw new TypeHintMismatchException(sprintf(
'Argument for type-hint "%s" is an expression that evaluates to a non-object',
$expectedType
));
}

$this->validateClass($className, $resultingClass);
$resultingClass = get_class($result);

$this->validateClass($expectedType, $resultingClass);
}
}

private function validateClass($expectedClassName, $actualClassName)
Expand Down
2 changes: 1 addition & 1 deletion ArgumentsValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ private function shouldParameterHaveAnArgument(\ReflectionParameter $parameter)
return false;
}

if ($parameter->getClass() && $parameter->allowsNull()) {
if ($parameter->getType() instanceof \ReflectionType && $parameter->getType()->allowsNull()) {
// e.g. LoggerInterface $logger = null
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions Error/ValidationErrorList.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ public function add(ValidationErrorInterface $error)
$this->errors[] = $error;
}

public function count()
public function count(): int
{
return count($this->errors);
}

public function getIterator()
public function getIterator(): \ArrayIterator
{
return new \ArrayIterator($this->errors);
}
Expand Down
2 changes: 1 addition & 1 deletion Exception/InvalidExpressionException.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public function __construct($expression, \Exception $exception)
$expression,
$exception->getMessage()
),
null,
0,
$exception
);
}
Expand Down
2 changes: 1 addition & 1 deletion Exception/InvalidExpressionSyntaxException.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public function __construct($expression, SyntaxError $exception)
$expression,
$exception->getMessage()
),
null,
0,
$exception
);
}
Expand Down
11 changes: 11 additions & 0 deletions Tests/Functional/Fixtures/Issue49.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php
declare(strict_types=1);

namespace Matthias\SymfonyServiceDefinitionValidator\Tests\Functional\Fixtures;

final class Issue49
{
public function __construct(array $values)
{
}
}
12 changes: 12 additions & 0 deletions Tests/Functional/Fixtures/issue_49.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
parameters:
app_config:
abc:
- a
- b
- c

services:
app.services.service_id:
class: Matthias\SymfonyServiceDefinitionValidator\Tests\Functional\Fixtures\Issue49
arguments:
- "@=parameter('app_config')['abc']"
10 changes: 10 additions & 0 deletions Tests/Functional/FunctionalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ public function testIfTheServiceDefinitionsAreCorrectTheContainerWillBeCompiled(
$this->addToAssertionCount(1);
}

public function testIssue49(): void
{
$loader = new YamlFileLoader($this->container, new FileLocator(__DIR__ . '/Fixtures'));
$loader->load('issue_49.yml');

$this->container->compile();

$this->addToAssertionCount(1);
}

public function testIfAServiceDefinitionWithAnExpressionArgumentIsCorrectTheContainerWillBeCompiled()
{
if (!class_exists('Symfony\Component\DependencyInjection\ExpressionLanguage')) {
Expand Down

0 comments on commit c021934

Please sign in to comment.