8000 Merge pull request #8 from arnedesmedt/master · event-engine/php-data@2989b7d · GitHub
[go: up one dir, main page]

Skip to content

Commit 2989b7d

Browse files
authored
Merge pull request #8 from arnedesmedt/master
Fallback for non php7.4 users to get types from properties + tests
2 parents 4251050 + e1e1235 commit 2989b7d

6 files changed

+194
-17
lines changed

README.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,3 @@ Please find the `settings.zip` [here](https://github.com/event-engine/php-data/b
2828
## Usage
2929

3030
Usage is described in the [documentation](https://event-engine.io/api/immutable_state.html)
31-
32-
## No Tests?
33-
34-
Looks strange, right? A stable open source package without a single test can only be a joke ...
35-
You're right! The situation isn't ideal. However, this is a low level package used by [event-engine/php-json-schema](https://github.com/event-engine/php-json-schema).
36-
The tests included there also cover the implementation of this package. Anyway, a pull request that adds some tests is always welcome!

src/ImmutableRecordLogic.php

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -277,24 +277,38 @@ private static function buildPropTypeMap()
277277
continue;
278278
}
279279

280-
if (! $prop->hasType()) {
281-
throw new \RuntimeException(
282-
\sprintf(
283-
'Missing type hint for property %s of record %s',
284-
$prop->getName(),
285-
__CLASS__
286-
)
287-
);
288-
}
289-
290-
$type = $prop->getType();
280+
$type = self::typeFromProperty($prop, $refObj);
291281

292282
$propTypeMap[$prop->getName()] = [$type->getName(), self::isScalarType($type->getName()), $type->allowsNull()];
293283
}
294284

295285
return $propTypeMap;
296286
}
297287

288+
private static function typeFromProperty(\ReflectionProperty $prop, \ReflectionClass $refObj) : \ReflectionType
289+
{
290+
if ($prop->hasType()) {
291+
return $prop->getType();
292+
}
293+
294+
if ($refObj->hasMethod($prop->getName())) {
295+
$method = $refObj->getMethod($prop->getName());
296+
297+
if ($method->hasReturnType()) {
298+
return $method->getReturnType();
299+
}
300+
}
301+
302+
throw new \RuntimeException(
303+
\sprintf(
304+
'Could not find a type for property %s of record %s. ' .
305+
'No type hint or getter method with a return type is given.',
306+
$prop->getName(),
307+
__CLASS__
308+
)
309+
);
310+
}
311+
298312
private static function isScalarType(string $type): bool
299313
{
300314
switch ($type) {

tests/ImmutableRecordLogicTest.php

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace EventEngineTest\Data;
6+
7+
use EventEngineTest\Data\Stub\ImmutableRecordWithNoTypes;
8+
use EventEngineTest\Data\Stub\ImmutableRecordWithTypedGetters;
9+
use EventEngineTest\Data\Stub\TypeHintedImmutableRecord;
10+
use PHPUnit\Framework\TestCase;
11+
12+
final class ImmutableRecordLogicTest extends TestCase
13+
{
14+
private $data = [];
15+
16+
protected function setUp()
17+
{
18+
parent::setUp();
19+
20+
$this->data = [
21+
'name' => 'test',
22+
'version' => 1,
23+
];
24+
}
25+
26+
/**
27+
* @test
28+
*/
29+
public function it_detects_type_hinted_properties()
30+
{
31+
$typeHinted = TypeHintedImmutableRecord::fromArray($this->data);
32+
33+
$this->data['type'] = null;
34+
35+
$this->assertEquals(
36+
$this->data,
37+
$typeHinted->toArray()
38+
);
39+
}
40+
41+
/**
42+
* @test
43+
*/
44+
public function it_detects_coupled_getters_for_properties()
45+
{
46+
$typedGetters = ImmutableRecordWithTypedGetters::fromArray($this->data);
47+
48+
$this->data['type'] = null;
49+
50+
$this->assertEquals(
51+
$this->data,
52+
$typedGetters->toArray()
53+
);
54+
}
55+
56+
/**
57+
* @test
58+
*/
59+
public function it_throws_an_exception_if_no_type_hint_was_found()
60+
{
61+
$this->expectException(\RuntimeException::class);
62+
$this->expectExceptionMessage(
63+
\sprintf(
64+
'Could not find a type for property %s of record %s. ' .
65+
'No type hint or getter method with a return type is given.',
66+
'name',
67+
ImmutableRecordWithNoTypes::class
68+
)
69+
);
70+
71+
ImmutableRecordWithNoTypes::fromArray($this->data);
72+
}
73+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace EventEngineTest\Data\Stub;
6+
7+
use EventEngine\Data\ImmutableRecord;
8+
use EventEngine\Data\ImmutableRecordLogic;
9+
10+
final class ImmutableRecordWithNoTypes implements ImmutableRecord
11+
{
12+
use ImmutableRecordLogic;
13+
14+
private $name;
15+
private $type;
16+
private $version;
17+
18+
public function name()
19+
{
20+
return $this->name;
21+
}
22+
23+
public function type()
24+
{
25+
return $this->type;
26+
}
27+
28+
public function version()
29+
{
30+
return $this->version;
31+
}
32+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace EventEngineTest\Data\Stub;
6+
7+
use EventEngine\Data\ImmutableRecord;
8+
use EventEngine\Data\ImmutableRecordLogic;
9+
10+
final class ImmutableRecordWithTypedGetters implements ImmutableRecord
11+
{
12+
use ImmutableRecordLogic;
13+
14+
private $name;
15+
private $type;
16+
private $version;
17+
18+
public function name() : string
19+
{
20+
return $this->name;
21+
}
22+
23+
public function type() : ?string
24+
{
25+
return $this->type;
26+
}
27+
28+
public function version() : int
29+
{
30+
return $this->version;
31+
}
32+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
< E7C3 /div>
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace EventEngineTest\Data\Stub;
6+
7+
use EventEngine\Data\ImmutableRecord;
8+
use EventEngine\Data\ImmutableRecordLogic;
9+
10+
final class TypeHintedImmutableRecord implements ImmutableRecord
11+
{
12+
use ImmutableRecordLogic;
13+
14+
private string $name;
15+
private ?string $type = null;
16+
private int $version;
17+
18+
public function name()
19+
{
20+
return $this->name;
21+
}
22+
23+
public function type()
24+
{
25+
return $this->type;
26+
}
27+
28+
public function version()
29+
{
30+
return $this->version;
31+
}
32+
}

0 commit comments

Comments
 (0)
0