Skip to content

Commit a2d9fea

Browse files
author
Robin de Graaf
committed
Add optional scalar parameters
1 parent f32e7a7 commit a2d9fea

7 files changed

+94
-8
lines changed

Diff for: CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Parable PHP DI
22

3+
## 0.2.3
4+
5+
_Changes_
6+
- Scalar parameters can now also be handled, but _only if_ they are considered optional. This means _after_ any required parameters, and _with_ a default value.
7+
38
## 0.2.2
49

510
_Changes_

Diff for: src/Container.php

+11-4
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,18 @@ public function getDependenciesFor(
160160
$dependencies = [];
161161
foreach ($parameters as $parameter) {
162162
$class = $parameter->getClass();
163+
163164
if ($class === null) {
164-
throw new ContainerException(sprintf(
165-
'Cannot inject value for constructor parameter `$%s`.',
166-
$parameter->name
167-
));
165+
if (!$parameter->isOptional()) {
166+
throw new ContainerException(sprintf(
167+
'Cannot inject value for non-optional constructor parameter `$%s` without a default value.',
168+
$parameter->name
169+
));
170+
}
171+
172+
$dependencies[] = $parameter->getDefaultValue();
173+
174+
continue;
168175
}
169176

170177
$dependencyName = $this->getDefinitiveName($class->name);

Diff for: tests/Classes/BadDependency.php renamed to tests/Classes/ScalarDependency.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Parable\Di\Tests\Classes;
44

5-
class BadDependency
5+
class ScalarDependency
66
{
77
public function __construct(
88
string $nope

Diff for: tests/Classes/ScalarDependencyWithDefault.php

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Parable\Di\Tests\Classes;
4+
5+
class ScalarDependencyWithDefault
6+
{
7+
public function __construct(
8+
string $nope = 'hello'
9+
) {
10+
}
11+
}
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace Parable\Di\Tests\Classes;
4+
5+
class ScalarDependencyWithDefaultAndNonScalar
6+
{
7+
public function __construct(
8+
NoDependencies $fakeObject,
9+
string $nope = 'hello'
10+
) {
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace Parable\Di\Tests\Classes;
4+
5+
class ScalarDependencyWithDefaultAndNonScalarReverse
6+
{
7+
public function __construct(
8+
string $nope = 'hello',
9+
NoDependencies $fakeObject
10+
) {
11+
}
12+
}

Diff for: tests/DiTest.php

+42-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use Parable\Di\Container;
66
use Parable\Di\Exceptions\ContainerException;
77
use Parable\Di\Exceptions\NotFoundException;
8-
use Parable\Di\Tests\Classes\BadDependency;
8+
use Parable\Di\Tests\Classes\ScalarDependency;
99
use Parable\Di\Tests\Classes\CyclicalDependencyFirst;
1010
use Parable\Di\Tests\Classes\CyclicalDependencySecond;
1111
use Parable\Di\Tests\Classes\Dependencies;
@@ -14,6 +14,9 @@
1414
use Parable\Di\Tests\Classes\FakeWithInterface;
1515
use Parable\Di\Tests\Classes\FakeWithInterfaceDependency;
1616
use Parable\Di\Tests\Classes\NoDependencies;
17+
use Parable\Di\Tests\Classes\ScalarDependencyWithDefault;
18+
use Parable\Di\Tests\Classes\ScalarDependencyWithDefaultAndNonScalar;
19+
use Parable\Di\Tests\Classes\ScalarDependencyWithDefaultAndNonScalarReverse;
1720

1821
class DiTest extends \PHPUnit\Framework\TestCase
1922
{
@@ -156,9 +159,37 @@ public function testGetDependenciesForThrowsOnBadId()
156159
public function testGetDependenciesForThrowsOnStringConstructorParameter()
157160
{
158161
self::expectException(ContainerException::class);
159-
self::expectExceptionMessage('Cannot inject value for constructor parameter `$nope`.');
162+
self::expectExceptionMessage('Cannot inject value for non-optional constructor parameter `$nope` without a default value.');
160163

161-
$this->container->getDependenciesFor(BadDependency::class);
164+
$this->container->getDependenciesFor(ScalarDependency::class);
165+
}
166+
167+
public function testGetDependenciesForScalarWithDefaultSetsDefaultValueAppropriately()
168+
{
169+
$dependencies = $this->container->getDependenciesFor(ScalarDependencyWithDefault::class);
170+
171+
self::assertSame(
172+
['hello'],
173+
$dependencies
174+
);
175+
}
176+
177+
public function testGetDependenciesForWillUseDefaultValueForScalarIfMixedWithActualDependency()
178+
{
179+
$dependencies = $this->container->getDependenciesFor(ScalarDependencyWithDefaultAndNonScalar::class);
180+
181+
self::assertInstanceOf(NoDependencies::class, $dependencies[0]);
182+
self::assertSame('hello', $dependencies[1]);
183+
}
184+
185+
public function testOptionalBeforeRequiredBreaksGetDependenciesFor()
186+
{
187+
self::expectException(ContainerException::class);
188+
self::expectExceptionMessage(
189+
'Cannot inject value for non-optional constructor parameter `$nope` without a default value.'
190+
);
191+
192+
$this->container->getDependenciesFor(ScalarDependencyWithDefaultAndNonScalarReverse::class);
162193
}
163194

164195
public function testGetDependenciesForWithNewDependenciesWorks()
@@ -177,6 +208,14 @@ public function testGetDependenciesForWithNewDependenciesWorks()
177208
self::assertSame('new', $instance->fakeObject->value);
178209
}
179210

211+
public function testGetDependenciesForDoesntLikeInvalidValuePassed()
212+
{
213+
$this->expectException(ContainerException::class);
214+
$this->expectExceptionMessage('Invalid dependency type value passed: `666`');
215+
216+
$this->container->getDependenciesFor(Dependencies::class, 666);
217+
}
218+
180219
public function testIdsAreNormalized()
181220
{
182221
$this->container->get(NoDependencies::class);

0 commit comments

Comments
 (0)