Skip to content

Commit

Permalink
Add support for scalar unions (#7)
Browse files Browse the repository at this point in the history
* Support scalar union types

* refactor tests to not include php8 syntax on php 7

Co-authored-by: thisispiers <[email protected]>
  • Loading branch information
cseufert and thisispiers authored Oct 4, 2022
1 parent 9b54e76 commit d6f16f4
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 10 deletions.
28 changes: 20 additions & 8 deletions src/Dice.php
Original file line number Diff line number Diff line change
Expand Up @@ -431,15 +431,27 @@ private function getParams(\ReflectionMethod $method, array $rule)
// Support PHP 7 scalar type hinting, is_a('string', 'foo') doesn't work so this is a hacky AF workaround: call_user_func('is_' . $type, '')
//Find a match in $args for scalar types
elseif ($args && $param->getType()) {
$type = $param->getType();

This comment has been minimized.

Copy link
@olekhy

olekhy Oct 23, 2022

@cseufert after i made composer update and get latest v4.1.5 on my PC, then i get error:
Argument 2 passed to Dummy::__construct() must be of the type array, string given
my config

'Dummy'               => [
        'shared'          => true,
        'instanceOf'      => Dummy::class,
        'constructParams' => [
           'bar',
           ['a', 'b', 'c'],
           'foo',
        ],
    ],
    

one line from trace
#0 [internal function]: Dummy->__construct('bar', 'foo', Array, '')

maybe u can fix this?

thx in advance

if ($type instanceof \ReflectionNamedType) {
$types = [$type];
} elseif (
version_compare(PHP_VERSION, "8.0.0", ">=") &&
$type instanceof \ReflectionUnionType
) {
$types = $type->getTypes();
}
for ($i = 0; $i < count($args); $i++) {
if (
call_user_func(
"is_" . $param->getType()->getName(),
$args[$i]
)
) {
$parameters[] = array_splice($args, $i, 1)[0];
break;
foreach ($types as $type) {
if (
call_user_func(
"is_" . $type->getName(),
$args[$i]
)
) {
$parameters[] = array_splice($args, $i, 1)[0];
$i--;
break;
}
}
}
} elseif ($args) {
Expand Down
17 changes: 17 additions & 0 deletions tests/ConstructParamsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,21 @@ public function testNullableClassTypeHint()

$this->assertEquals(null, $nullableClassTypeHint->obj);
}

public function testUnionScalarTypeHint()
{
if (version_compare(PHP_VERSION, "8.0.0", ">=")) {
require_once __DIR__ . "/TestData/UnionParameters.php";
$rule = [];
$rule["constructParams"] = ["someString"];
$dice = $this->dice->addRule("UnionScalar", $rule);

$unionScalar = $dice->create("UnionScalar");
$this->assertEquals("someString", $unionScalar->a);
} else {
$this->markTestSkipped(
"PHP < 8.0.0 does not support union type hints"
);
}
}
}
13 changes: 13 additions & 0 deletions tests/CreateArgsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,17 @@ public function testScalarConstructorArgs()
$this->assertEquals("string", $obj->string);
$this->assertEquals(null, $obj->null);
}

public function testUnionScalarConstructorArgs()
{
if (version_compare(PHP_VERSION, "8.0.0", ">=")) {
require_once __DIR__ . "/TestData/UnionParameters.php";
$unionScalar = $this->dice->create("UnionScalar", ["someString"]);
$this->assertEquals("someString", $unionScalar->a);
} else {
$this->markTestSkipped(
"PHP < 8.0.0 does not support union type hints"
);
}
}
}
10 changes: 10 additions & 0 deletions tests/ShareInstancesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public function testShareInstances()
$this->assertInstanceOf("SharedInstanceTest1", $shareTest->share1);
$this->assertInstanceOf("SharedInstanceTest2", $shareTest->share2);

$this->assertSame($shareTest->shared, $shareTest->share1->shared);
$this->assertSame($shareTest->shared, $shareTest->share1->shared);
$this->assertSame(
$shareTest->share1->shared,
Expand All @@ -29,6 +30,10 @@ public function testShareInstances()
$shareTest->shared->uniq,
$shareTest->share1->shared->uniq
);
$this->assertEquals(
$shareTest->shared->uniq,
$shareTest->share1->shared->uniq
);
$this->assertEquals(
$shareTest->share1->shared->uniq,
$shareTest->share2->shared->uniq
Expand Down Expand Up @@ -92,7 +97,12 @@ public function testShareInstancesMultiple()

$this->assertinstanceOf("TestSharedInstancesTop", $shareTest);

$this->assertSame($shareTest->shared, $shareTest->share1->shared);
$this->assertInstanceOf("SharedInstanceTest1", $shareTest->share1);
$this->assertEquals(
$shareTest->shared->uniq,
$shareTest->share1->shared->uniq
);
$this->assertInstanceOf("SharedInstanceTest2", $shareTest->share2);

$this->assertSame($shareTest->shared, $shareTest->share1->shared);
Expand Down
2 changes: 0 additions & 2 deletions tests/TestData/ConstructParams.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ class MethodWithTwoDefaultNullC
{
public $a;
public $b;

public function __construct($a = null, NB $b = null)
{
$this->a = $a;
Expand All @@ -98,7 +97,6 @@ class MethodWithTwoDefaultNullCC
public $a;
public $b;
public $c;

public function __construct($a = null, NB $b = null, NC $c = null)
{
$this->a = $a;
Expand Down
11 changes: 11 additions & 0 deletions tests/TestData/UnionParameters.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

class UnionScalar
{
public $a;

public function __construct(int|string $a)
{
$this->a = $a;
}
}

0 comments on commit d6f16f4

Please sign in to comment.