Skip to content

Commit

Permalink
Consistent checks to ensure container factory returns expected class
Browse files Browse the repository at this point in the history
  • Loading branch information
clue committed Jul 27, 2022
1 parent b86a271 commit f4b43d7
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
10 changes: 8 additions & 2 deletions src/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,12 @@ private function load(string $name, int $depth = 64)
throw new \BadMethodCallException('Factory for ' . $name . ' is recursive');
}

$this->container[$name] = $this->load($this->container[$name], $depth - 1);
$value = $this->load($this->container[$name], $depth - 1);
if (!$value instanceof $name) {
throw new \BadMethodCallException('Factory for ' . $name . ' returned unexpected ' . (is_object($value) ? get_class($value) : gettype($value)));
}

$this->container[$name] = $value;
} elseif ($this->container[$name] instanceof \Closure) {
// build list of factory parameters based on parameter types
$closure = new \ReflectionFunction($this->container[$name]);
Expand All @@ -142,7 +147,8 @@ private function load(string $name, int $depth = 64)
}

$value = $this->load($value, $depth - 1);
} elseif (!$value instanceof $name) {
}
if (!$value instanceof $name) {
throw new \BadMethodCallException('Factory for ' . $name . ' returned unexpected ' . (is_object($value) ? get_class($value) : gettype($value)));
}

Expand Down
30 changes: 30 additions & 0 deletions tests/ContainerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,36 @@ public function testCallableReturnsCallableThatThrowsWhenFactoryReturnsInvalidIn
$callable($request);
}

public function testCallableReturnsCallableThatThrowsWhenMapReferencesClassNameThatDoesNotMatchType()
{
$request = new ServerRequest('GET', 'http://example.com/');

$container = new Container([
\stdClass::class => Response::class
]);

$callable = $container->callable(\stdClass::class);

$this->expectException(\BadMethodCallException::class);
$this->expectExceptionMessage('Factory for stdClass returned unexpected React\Http\Message\Response');
$callable($request);
}

public function testCallableReturnsCallableThatThrowsWhenFactoryReturnsClassNameThatDoesNotMatchType()
{
$request = new ServerRequest('GET', 'http://example.com/');

$container = new Container([
\stdClass::class => function () { return Response::class; }
]);

$callable = $container->callable(\stdClass::class);

$this->expectException(\BadMethodCallException::class);
$this->expectExceptionMessage('Factory for stdClass returned unexpected React\Http\Message\Response');
$callable($request);
}

public function testCallableReturnsCallableThatThrowsWhenFactoryRequiresInvalidClassName()
{
$request = new ServerRequest('GET', 'http://example.com/');
Expand Down

0 comments on commit f4b43d7

Please sign in to comment.