Skip to content

Commit

Permalink
improve argument pattern matching and add a test
Browse files Browse the repository at this point in the history
  • Loading branch information
mindplay-dk committed Jan 21, 2016
1 parent 27937e9 commit bdb3264
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 7 deletions.
16 changes: 9 additions & 7 deletions src/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 20,7 @@ class Container implements ContainerInterface, FactoryInterface
* @type string pattern for parsing an argument type from a ReflectionParameter string
* @see getArgumentType()
*/
const ARG_PATTERN = '/.*\[\s*(?:\<required\>|\<optional\>)\s*([^\s] )/';
const ARG_PATTERN = '/(?:\<required\>|\<optional\>)\\s ([\\w\\\\] )/';

/**
* @var mixed[] map where component name => value
Expand Down Expand Up @@ -282,9 282,11 @@ public function configure($name_or_func, $func_or_map = null, $map = [])
list($param) = $this->reflect($func)->getParameters();
}

preg_match(self::ARG_PATTERN, $param->__toString(), $matches);
// obtain the type-hint, but avoid triggering autoload:

$name = $matches[1];
$name = preg_match(self::ARG_PATTERN, $param->__toString(), $matches) === 1
? $matches[1] // infer component name from type-hint
: $param->name; // infer component name from parameter name

if (!$this->has($name) && $this->has($param->name)) {
$name = $param->name;
Expand Down Expand Up @@ -493,11 495,11 @@ protected function resolve(array $params, $map)
} else {
// as on optimization, obtain the argument type without triggering autoload:

preg_match(self::ARG_PATTERN, $param->__toString(), $matches);
$type = preg_match(self::ARG_PATTERN, $param->__toString(), $matches)
? $matches[1]
: null; // no type-hint available

$type = $matches[1];

if (isset($map[$type])) {
if ($type && isset($map[$type])) {
$value = $map[$type]; // resolve as user-provided type-hinted argument
} elseif ($type && $this->has($type)) {
$value = $this->get($type); // resolve as component registered by class/interface name
Expand Down
30 changes: 30 additions & 0 deletions test/test.php
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 513,36 @@ function () use ($c, $bar) {
}
);

test(
'Container::ARG_PATTERN works as intended',
function () {
$cases = [
[function (Foo $foo) {}, 'Foo'],
[function (Foo $foo = null) {}, 'Foo'],
[function (Foo\Bar $foo) {}, 'Foo\\Bar'],
[function ($foo) {}, null],
[function ($foo = null) {}, null],
[function ($foo = "string") {}, null],
];

foreach ($cases as $case) {
list($function, $expected) = $case;

$reflection = new ReflectionFunction($function);

$params = $reflection->getParameters();

$pattern_str = $params[0]->__toString();

if (preg_match(Container::ARG_PATTERN, $pattern_str, $matches) === 1) {
eq($matches[1], $expected, "{$pattern_str} should match: " . format($expected));
} else {
eq(null, $expected, "{$pattern_str} should match: " . format($expected));
}
}
}
);

configure()->enableCodeCoverage(__DIR__ . '/build/clover.xml', dirname(__DIR__) . '/src');

exit(run()); // exits with errorlevel (for CI tools etc.)

0 comments on commit bdb3264

Please sign in to comment.