Skip to content

Commit 292799b

Browse files
author
Alexander Miertsch
authored
Merge pull request #9 from event-engine/feature/psalm_support
psalm support
2 parents 2989b7d + a2d9a0d commit 292799b

20 files changed

+745
-33
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.idea
2+
.php_cs.cache
23
composer.lock
3-
vendor
4+
vendor

.travis.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
language: php
2+
3+
matrix:
4+
fast_finish: true
5+
include:
6+
- php: 7.4
7+
env:
8+
- DEPENDENCIES=""
9+
- EXECUTE_CS_CHECK=true
10+
- TEST_COVERAGE=true
11+
12+
cache:
13+
directories:
14+
- $HOME/.composer/cache
15+
- $HOME/.php-cs-fixer
16+
- $HOME/.local
17+
18+
before_script:
19+
- mkdir -p "$HOME/.php-cs-fixer"
20+
- phpenv config-rm xdebug.ini
21+
- composer self-update
22+
- composer update --prefer-source $DEPENDENCIES
23+
24+
script:
25+
- if [[ $TEST_COVERAGE == 'true' ]]; then php -dzend_extension=xdebug.so ./vendor/bin/phpunit --coverage-text --coverage-clover ./build/logs/clover.xml; else ./vendor/bin/phpunit; fi
26+
# - if [[ $EXECUTE_CS_CHECK == 'true' ]]; then ./vendor/bin/php-cs-fixer fix -v --diff --dry-run; fi
27+
# - if [[ $EXECUTE_CS_CHECK == 'true' ]]; then ./vendor/bin/docheader check examples/ src/ tests/; fi
28+
29+
after_success:
30+
- if [[ $TEST_COVERAGE == 'true' ]]; then php vendor/bin/coveralls -v; fi
31+
32+
notifications:
33+
webhooks:
34+
urls:
35+
- https://webhooks.gitter.im/e/61c75218816eebde4486
36+
on_success: change # options: [always|never|change] default: always
37+
on_failure: always # options: [always|never|change] default: always
38+
on_start: never # options: [always|never|change] default: always

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# EventEngine\Data
22

3+
[![Build Status](https://travis-ci.com/event-engine/php-data.svg?branch=master)](https://travis-ci.com/event-engine/php-data)
4+
[![Coverage Status](https://coveralls.io/repos/github/event-engine/php-data/badge.svg?branch=master)](https://coveralls.io/github/event-engine/php-data?branch=master)
5+
36
Generate Immutable Objects with ease!
47

58
![Value Object Template vo_string](https://event-engine.io/api/img/vo_string.gif)

composer.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"require-dev": {
2323
"phpunit/phpunit": "^7.0",
2424
"prooph/php-cs-fixer-config": "^0.3",
25-
"satooshi/php-coveralls": "^1.0",
25+
"satooshi/php-coveralls": "^2.2",
2626
"malukenho/docheader": "^0.1.4"
2727
},
2828
"autoload": {
@@ -43,8 +43,8 @@
4343
"@test"
4444
],
4545
"docheader": "vendor/bin/docheader check src/ tests/",
46-
"cs": "php-cs-fixer fix -v --diff --dry-run",
47-
"cs-fix": "php-cs-fixer fix -v --diff",
46+
"cs": "php-cs-fixer fix src -v --diff --dry-run",
47+
"cs-fix": "php-cs-fixer fix src -v --diff",
4848
"test": "vendor/bin/phpunit"
4949
}
5050
}

src/DataConverter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
/**
33
* This file is part of event-engine/php-data.
4-
* (c) 2018-2019 prooph software GmbH <contact@prooph.de>
4+
* (c) 2018-2020 prooph software GmbH <contact@prooph.de>
55
*
66
* For the full copyright and license information, please view the LICENSE
77
* file that was distributed with this source code.

src/ImmutableRecord.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
/**
33
* This file is part of event-engine/php-data.
4-
* (c) 2018-2019 prooph software GmbH <contact@prooph.de>
4+
* (c) 2018-2020 prooph software GmbH <contact@prooph.de>
55
*
66
* For the full copyright and license information, please view the LICENSE
77
* file that was distributed with this source code.
@@ -11,6 +11,12 @@
1111

1212
namespace EventEngine\Data;
1313

14+
/**
15+
* Interface ImmutableRecord
16+
*
17+
* @package EventEngine\Data
18+
* @psalm-immutable
19+
*/
1420
interface ImmutableRecord
1521
{
1622
const PHP_TYPE_STRING = 'string';

src/ImmutableRecordDataConverter.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
/**
33
* This file is part of event-engine/php-data.
4-
* (c) 2018-2019 prooph software GmbH <contact@prooph.de>
4+
* (c) 2018-2020 prooph software GmbH <contact@prooph.de>
55
*
66
* For the full copyright and license information, please view the LICENSE
77
* file that was distributed with this source code.
@@ -37,7 +37,7 @@ public function canConvertTypeToData(string $type): bool
3737
{
3838
$class = $this->getClassOfType($type);
3939

40-
if(!class_exists($class)) {
40+
if (!class_exists($class)) {
4141
return false;
4242
}
4343

src/ImmutableRecordLogic.php

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
/**
33
* This file is part of event-engine/php-data.
4-
* (c) 2018-2019 prooph software GmbH <contact@prooph.de>
4+
* (c) 2018-2020 prooph software GmbH <contact@prooph.de>
55
*
66
* For the full copyright and license information, please view the LICENSE
77
* file that was distributed with this source code.
@@ -11,6 +11,12 @@
1111

1212
namespace EventEngine\Data;
1313

14+
/**
15+
* Trait ImmutableRecordLogic
16+
* @package EventEngine\Data
17+
*
18+
* @psalm-immutable
19+
*/
1420
trait ImmutableRecordLogic
1521
{
1622
/**
@@ -36,7 +42,7 @@ private function init(): void
3642
* @param array $recordData
3743
* @return self
3844
*/
39-
public static function fromRecordData(array $recordData)
45+
public static function fromRecordData(array $recordData): self
4046
{
4147
return new self($recordData);
4248
}
@@ -45,7 +51,7 @@ public static function fromRecordData(array $recordData)
4551
* @param array $nativeData
4652
* @return self
4753
*/
48-
public static function fromArray(array $nativeData)
54+
public static function fromArray(array $nativeData): self
4955
{
5056
return new self(null, $nativeData);
5157
}
@@ -73,7 +79,7 @@ private function __construct(array $recordData = null, array $nativeData = null)
7379
* @param array $recordData
7480
* @return self
7581
*/
76-
public function with(array $recordData)
82+
public function with(array $recordData): self
7783
{
7884
$copy = clone $this;
7985
$copy->setRecordData($recordData);
@@ -94,24 +100,24 @@ public function toArray(): array
94100
case ImmutableRecord::PHP_TYPE_BOOL:
95101
case ImmutableRecord::PHP_TYPE_ARRAY:
96102
if (\array_key_exists($key, $arrayPropItemTypeMap) && ! self::isScalarType($arrayPropItemTypeMap[$key])) {
97-
if ($isNullable && $this->{$key}() === null) {
103+
if ($isNullable && $this->{$key} === null) {
98104
$nativeData[$key] = null;
99105
continue 2;
100106
}
101107

102108
$nativeData[$key] = \array_map(function ($item) use ($key, &$arrayPropItemTypeMap) {
103109
return $this->voTypeToNative($item, $key, $arrayPropItemTypeMap[$key]);
104-
}, $this->{$key}());
110+
}, $this->{$key});
105111
} else {
106-
$nativeData[$key] = $this->{$key}();
112+
$nativeData[$key] = $this->{$key};
107113
}
108114
break;
109115
default:
110-
if ($isNullable && $this->{$key}() === null) {
116+
if ($isNullable && (! isset($this->{$key}))) {
111117
$nativeData[$key] = null;
112118
continue 2;
113119
}
114-
$nativeData[$key] = $this->voTypeToNative($this->{$key}(), $key, $type);
120+
$nativeData[$key] = $this->voTypeToNative($this->{$key}, $key, $type);
115121
}
116122
}
117123

@@ -120,22 +126,22 @@ public function toArray(): array
120126

121127
public function equals(ImmutableRecord $other): bool
122128
{
123-
if(get_class($this) !== get_class($other)) {
129+
if (get_class($this) !== get_class($other)) {
124130
return false;
125131
}
126132

127133
return $this->toArray() === $other->toArray();
128134
}
129135

130-
private function setRecordData(array $recordData)
136+
private function setRecordData(array $recordData): void
131137
{
132138
foreach ($recordData as $key => $value) {
133139
$this->assertType($key, $value);
134140
$this->{$key} = $value;
135141
}
136142
}
137143

138-
private function setNativeData(array $nativeData)
144+
private function setNativeData(array $nativeData): void
139145
{
140146
$recordData = [];
141147
$arrayPropItemTypeMap = self::getArrayPropItemTypeMapFromMethodOrCache();
@@ -182,10 +188,10 @@ private function setNativeData(array $nativeData)
182188
$this->setRecordData($recordData);
183189
}
184190

185-
private function assertAllNotNull()
191+
private function assertAllNotNull(): void
186192
{
187193
foreach (self::$__propTypeMap as $key => [$type, $isNative, $isNullable]) {
188-
if (null === $this->{$key} && ! $isNullable) {
194+
if (! isset($this->{$key}) && ! $isNullable) {
189195
throw new \InvalidArgumentException(\sprintf(
190196
'Missing record data for key %s of record %s.',
191197
$key,
@@ -195,7 +201,7 @@ private function assertAllNotNull()
195201
}
196202
}
197203

198-
private function assertType(string $key, $value)
204+
private function assertType(string $key, $value): void
199205
{
200206
if (! isset(self::$__propTypeMap[$key])) {
201207
throw new \InvalidArgumentException(\sprintf(
@@ -264,7 +270,7 @@ private function isType(string $type, string $key, $value): bool
264270
}
265271
}
266272

267-
private static function buildPropTypeMap()
273+
private static function buildPropTypeMap(): array
268274
{
269275
$refObj = new \ReflectionClass(__CLASS__);
270276

@@ -383,12 +389,12 @@ private static function getArrayPropItemTypeMapFromMethodOrCache(): array
383389
}
384390

385391
/**
386-
* @var array
392+
* @var array|null
387393
*/
388394
private static $__propTypeMap;
389395

390396
/**
391-
* @var array
397+
* @var array|null
392398
*/
393399
private static $__arrayPropItemTypeMap;
394400
}

tests/ImmutableRecordLogicTest.php

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,26 @@
11
<?php
2-
2+
/**
3+
* This file is part of event-engine/php-data.
4+
* (c) 2018-2020 prooph software GmbH <contact@prooph.de>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
39
declare(strict_types=1);
410

511
namespace EventEngineTest\Data;
612

13+
use EventEngineTest\Data\Stub\ImmutableItem;
714
use EventEngineTest\Data\Stub\ImmutableRecordWithNoTypes;
815
use EventEngineTest\Data\Stub\ImmutableRecordWithTypedGetters;
916
use EventEngineTest\Data\Stub\TypeHintedImmutableRecord;
17+
use EventEngineTest\Data\Stub\TypeHintedImmutableRecordWithValueObjects;
18+
use EventEngineTest\Data\Stub\ValueObject\Access;
19+
use EventEngineTest\Data\Stub\ValueObject\ItemList;
20+
use EventEngineTest\Data\Stub\ValueObject\Name;
21+
use EventEngineTest\Data\Stub\ValueObject\Percentage;
22+
use EventEngineTest\Data\Stub\ValueObject\Type;
23+
use EventEngineTest\Data\Stub\ValueObject\Version;
1024
use PHPUnit\Framework\TestCase;
1125

1226
final class ImmutableRecordLogicTest extends TestCase
@@ -20,6 +34,8 @@ protected function setUp()
2034
$this->data = [
2135
'name' => 'test',
2236
'version' => 1,
37+
'itemList' => [['name' => 'one']],
38+
'access' => true,
2339
];
2440
}
2541

@@ -31,6 +47,7 @@ public function it_detects_type_hinted_properties()
3147
$typeHinted = TypeHintedImmutableRecord::fromArray($this->data);
3248

3349
$this->data['type'] = null;
50+
$this->data['percentage'] = 0.5;
3451

3552
$this->assertEquals(
3653
$this->data,
@@ -46,13 +63,53 @@ public function it_detects_coupled_getters_for_properties()
4663
$typedGetters = ImmutableRecordWithTypedGetters::fromArray($this->data);
4764

4865
$this->data['type'] = null;
66+
$this->data['percentage'] = 0.5;
4967

5068
$this->assertEquals(
5169
$this->data,
5270
$typedGetters->toArray()
5371
);
5472
}
5573

74+
/**
75+
* @test
76+
*/
77+
public function it_can_handle_value_objects()
78+
{
79+
$valueObjects = TypeHintedImmutableRecordWithValueObjects::fromArray($this->data);
80+
81+
$this->data['type'] = null;
82+
$this->data['percentage'] = 0.5;
83+
84+
$this->assertEquals(
85+
$this->data,
86+
$valueObjects->toArray()
87+
);
88+
}
89+
90+
/**
91+
* @test
92+
*/
93+
public function it_takes_value_object_as_initialization_params()
94+
{
95+
$valueObjects = TypeHintedImmutableRecordWithValueObjects::fromRecordData([
96+
'name' => Name::fromString($this->data['name']),
97+
'type' => Type::fromString('value_object'),
98+
'version' => Version::fromInt($this->data['version']),
99+
'access' => Access::fromBool($this->data['access']),
100+
'percentage' => Percentage::fromFloat(0.9),
101+
'itemList' => ItemList::fromItems(ImmutableItem::fromRecordData(['name' => 'one'])),
102+
]);
103+
104+
$this->data['type'] = 'value_object';
105+
$this->data['percentage'] = 0.9;
106+
107+
$this->assertEquals(
108+
$this->data,
109+
$valueObjects->toArray()
110+
);
111+
}
112+
56113
/**
57114
* @test
58115
*/

0 commit comments

Comments
 (0)