Skip to content

Commit 1700043

Browse files
Merge branch 'master' into serializable-default
2 parents 2b0cda8 + aab502b commit 1700043

File tree

6 files changed

+117
-51
lines changed

6 files changed

+117
-51
lines changed

.travis.yml

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,27 @@
11
language: php
22

33
php:
4-
- 5.3
54
- 5.4
65
- 5.5
76
- 5.6
87
- 7.0
98
- 7.1
10-
- hhvm
9+
- 7.2
10+
- 7.3
11+
12+
matrix:
13+
fast_finish: true
14+
15+
cache:
16+
directories:
17+
- $HOME/.composer/cache
1118

1219
before_script:
13-
- composer install --no-interaction
20+
- travis_retry composer install -n
1421

1522
script:
16-
- vendor/bin/phpunit --coverage-clover=coverage.clover
17-
- vendor/bin/phpcs --standard=PSR2 ./src/
18-
19-
after_script:
20-
- wget https://scrutinizer-ci.com/ocular.phar
21-
- php ocular.phar code-coverage:upload --format=php-clover coverage.clover
23+
- vendor/bin/phpunit
2224

2325
# Use Travis' new container-based infrastructure.
2426
# See http://docs.travis-ci.com/user/migrating-from-legacy/#How-can-I-use-container-based-infrastructure%3F
2527
sudo: false
26-

README.md

100755100644
Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,12 @@ use MyCLabs\Enum\Enum;
3333
*/
3434
class Action extends Enum
3535
{
36-
const VIEW = 'view';
37-
const EDIT = 'edit';
36+
private const VIEW = 'view';
37+
private const EDIT = 'edit';
3838
}
3939
```
4040

41+
Note the `private` keyword requires PHP 7.1 or higher, you can omit it on PHP 7.0.
4142

4243
## Usage
4344

@@ -80,8 +81,8 @@ Static methods:
8081
```php
8182
class Action extends Enum
8283
{
83-
const VIEW = 'view';
84-
const EDIT = 'edit';
84+
private const VIEW = 'view';
85+
private const EDIT = 'edit';
8586
}
8687

8788
// Static method:
@@ -96,7 +97,7 @@ If you care about IDE autocompletion, you can either implement the static method
9697
```php
9798
class Action extends Enum
9899
{
99-
const VIEW = 'view';
100+
private const VIEW = 'view';
100101

101102
/**
102103
* @return Action
@@ -116,11 +117,12 @@ or you can use phpdoc (this is supported in PhpStorm for example):
116117
*/
117118
class Action extends Enum
118119
{
119-
const VIEW = 'view';
120-
const EDIT = 'edit';
120+
private const VIEW = 'view';
121+
private const EDIT = 'edit';
121122
}
122123
```
123124

124125
## Related projects
125126

126127
- [Doctrine enum mapping](https://github.com/acelaya/doctrine-enum-type)
128+
- [Symfony 2/3 ParamConverter integration](https://github.com/Ex3v/MyCLabsEnumParamConverter)

composer.json

100755100644
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@
2222
}
2323
},
2424
"require": {
25-
"php": ">=5.3"
25+
"php": ">=5.4",
26+
"ext-json": "*"
2627
},
2728
"require-dev": {
28-
"phpunit/phpunit": "4.*",
29+
"phpunit/phpunit": "^4.8.35|^5.7|^6.0",
2930
"squizlabs/php_codesniffer": "1.*"
3031
}
3132
}

phpunit.xml

100755100644
File mode changed.

src/Enum.php

100755100644
Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* @author Daniel Costa <[email protected]>
1616
* @author Mirosław Filip <[email protected]>
1717
*/
18-
abstract class Enum
18+
abstract class Enum implements \JsonSerializable
1919
{
2020
/**
2121
* Enum value
@@ -29,7 +29,7 @@ abstract class Enum
2929
*
3030
* @var array
3131
*/
32-
protected static $cache = array();
32+
protected static $cache = [];
3333

3434
/**
3535
* Creates a new value of some type
@@ -40,8 +40,14 @@ abstract class Enum
4040
*/
4141
public function __construct($value)
4242
{
43+
if ($value instanceof static) {
44+
$this->value = $value->getValue();
45+
46+
return;
47+
}
48+
4349
if (!$this->isValid($value)) {
44-
throw new \UnexpectedValueException("Value '$value' is not part of the enum " . get_called_class());
50+
throw new \UnexpectedValueException("Value '$value' is not part of the enum " . \get_called_class());
4551
}
4652

4753
$this->value = $value;
@@ -80,9 +86,9 @@ public function __toString()
8086
*
8187
* @return bool True if Enums are equal, false if not equal
8288
*/
83-
final public function equals(Enum $enum)
89+
final public function equals(Enum $enum = null)
8490
{
85-
return $this->getValue() === $enum->getValue() && get_called_class() == get_class($enum);
91+
return $enum !== null && $this->getValue() === $enum->getValue() && \get_called_class() === \get_class($enum);
8692
}
8793

8894
/**
@@ -92,7 +98,7 @@ final public function equals(Enum $enum)
9298
*/
9399
public static function keys()
94100
{
95-
return array_keys(static::toArray());
101+
return \array_keys(static::toArray());
96102
}
97103

98104
/**
@@ -118,8 +124,8 @@ public static function values()
118124
*/
119125
public static function toArray()
120126
{
121-
$class = get_called_class();
122-
if (!array_key_exists($class, static::$cache)) {
127+
$class = \get_called_class();
128+
if (!isset(static::$cache[$class])) {
123129
$reflection = new \ReflectionClass($class);
124130
static::$cache[$class] = $reflection->getConstants();
125131
}
@@ -136,7 +142,7 @@ public static function toArray()
136142
*/
137143
public static function isValid($value)
138144
{
139-
return in_array($value, static::toArray(), true);
145+
return \in_array($value, static::toArray(), true);
140146
}
141147

142148
/**
@@ -150,7 +156,7 @@ public static function isValidKey($key)
150156
{
151157
$array = static::toArray();
152158

153-
return isset($array[$key]);
159+
return isset($array[$key]) || \array_key_exists($key, $array);
154160
}
155161

156162
/**
@@ -162,7 +168,7 @@ public static function isValidKey($key)
162168
*/
163169
public static function search($value)
164170
{
165-
return array_search($value, static::toArray(), true);
171+
return \array_search($value, static::toArray(), true);
166172
}
167173

168174
/**
@@ -177,10 +183,22 @@ public static function search($value)
177183
public static function __callStatic($name, $arguments)
178184
{
179185
$array = static::toArray();
180-
if (isset($array[$name])) {
186+
if (isset($array[$name]) || \array_key_exists($name, $array)) {
181187
return new static($array[$name]);
182188
}
183189

184-
throw new \BadMethodCallException("No static method or enum constant '$name' in class " . get_called_class());
190+
throw new \BadMethodCallException("No static method or enum constant '$name' in class " . \get_called_class());
191+
}
192+
193+
/**
194+
* Specify data which should be serialized to JSON. This method returns data that can be serialized by json_encode()
195+
* natively.
196+
*
197+
* @return mixed
198+
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php
199+
*/
200+
public function jsonSerialize()
201+
{
202+
return $this->getValue();
185203
}
186204
}

tests/EnumTest.php

Lines changed: 63 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* @author Daniel Costa <[email protected]>
1212
* @author Mirosław Filip <[email protected]>
1313
*/
14-
class EnumTest extends \PHPUnit_Framework_TestCase
14+
class EnumTest extends \PHPUnit\Framework\TestCase
1515
{
1616
/**
1717
* getValue()
@@ -40,22 +40,20 @@ public function testGetKey()
4040

4141
/**
4242
* @dataProvider invalidValueProvider
43+
* @expectedException \UnexpectedValueException
44+
* @expectedExceptionMessage is not part of the enum MyCLabs\Tests\Enum\EnumFixture
4345
*/
4446
public function testCreatingEnumWithInvalidValue($value)
4547
{
46-
$this->setExpectedException(
47-
'\UnexpectedValueException',
48-
'Value \'' . $value . '\' is not part of the enum MyCLabs\Tests\Enum\EnumFixture'
49-
);
50-
5148
new EnumFixture($value);
5249
}
5350

5451
/**
5552
* Contains values not existing in EnumFixture
5653
* @return array
5754
*/
58-
public function invalidValueProvider() {
55+
public function invalidValueProvider()
56+
{
5957
return array(
6058
"string" => array('test'),
6159
"int" => array(1234),
@@ -71,7 +69,8 @@ public function testToString($expected, $enumObject)
7169
$this->assertSame($expected, (string) $enumObject);
7270
}
7371

74-
public function toStringProvider() {
72+
public function toStringProvider()
73+
{
7574
return array(
7675
array(EnumFixture::FOO, new EnumFixture(EnumFixture::FOO)),
7776
array(EnumFixture::BAR, new EnumFixture(EnumFixture::BAR)),
@@ -165,22 +164,23 @@ public function testIsValid($value, $isValid)
165164
$this->assertSame($isValid, EnumFixture::isValid($value));
166165
}
167166

168-
public function isValidProvider() {
169-
return array(
167+
public function isValidProvider()
168+
{
169+
return [
170170
/**
171171
* Valid values
172172
*/
173-
array('foo', true),
174-
array(42, true),
175-
array(null, true),
176-
array(0, true),
177-
array('', true),
178-
array(false, true),
173+
['foo', true],
174+
[42, true],
175+
[null, true],
176+
[0, true],
177+
['', true],
178+
[false, true],
179179
/**
180180
* Invalid values
181181
*/
182-
array('baz', false)
183-
);
182+
['baz', false]
183+
];
184184
}
185185

186186
/**
@@ -190,6 +190,7 @@ public function testIsValidKey()
190190
{
191191
$this->assertTrue(EnumFixture::isValidKey('FOO'));
192192
$this->assertFalse(EnumFixture::isValidKey('BAZ'));
193+
$this->assertTrue(EnumFixture::isValidKey('PROBLEMATIC_NULL'));
193194
}
194195

195196
/**
@@ -202,7 +203,8 @@ public function testSearch($value, $expected)
202203
$this->assertSame($expected, EnumFixture::search($value));
203204
}
204205

205-
public function searchProvider() {
206+
public function searchProvider()
207+
{
206208
return array(
207209
array('foo', 'FOO'),
208210
array(0, 'PROBLEMATIC_NUMBER'),
@@ -226,6 +228,7 @@ public function testEquals()
226228
$this->assertTrue($foo->equals($foo));
227229
$this->assertFalse($foo->equals($number));
228230
$this->assertTrue($foo->equals($anotherFoo));
231+
$this->assertFalse($foo->equals(null));
229232
}
230233

231234
/**
@@ -251,6 +254,47 @@ public function testEqualsConflictValues()
251254
$this->assertFalse(EnumFixture::FOO()->equals(EnumConflict::FOO()));
252255
}
253256

257+
/**
258+
* jsonSerialize()
259+
*/
260+
public function testJsonSerialize()
261+
{
262+
$this->assertJsonEqualsJson('"foo"', json_encode(new EnumFixture(EnumFixture::FOO)));
263+
$this->assertJsonEqualsJson('"bar"', json_encode(new EnumFixture(EnumFixture::BAR)));
264+
$this->assertJsonEqualsJson('42', json_encode(new EnumFixture(EnumFixture::NUMBER)));
265+
$this->assertJsonEqualsJson('0', json_encode(new EnumFixture(EnumFixture::PROBLEMATIC_NUMBER)));
266+
$this->assertJsonEqualsJson('null', json_encode(new EnumFixture(EnumFixture::PROBLEMATIC_NULL)));
267+
$this->assertJsonEqualsJson('""', json_encode(new EnumFixture(EnumFixture::PROBLEMATIC_EMPTY_STRING)));
268+
$this->assertJsonEqualsJson('false', json_encode(new EnumFixture(EnumFixture::PROBLEMATIC_BOOLEAN_FALSE)));
269+
}
270+
271+
public function testNullableEnum()
272+
{
273+
$this->assertNull(EnumFixture::PROBLEMATIC_NULL()->getValue());
274+
$this->assertNull((new EnumFixture(EnumFixture::PROBLEMATIC_NULL))->getValue());
275+
$this->assertNull((new EnumFixture(EnumFixture::PROBLEMATIC_NULL))->jsonSerialize());
276+
}
277+
278+
public function testBooleanEnum()
279+
{
280+
$this->assertFalse(EnumFixture::PROBLEMATIC_BOOLEAN_FALSE()->getValue());
281+
$this->assertFalse((new EnumFixture(EnumFixture::PROBLEMATIC_BOOLEAN_FALSE))->jsonSerialize());
282+
}
283+
284+
public function testConstructWithSameEnumArgument()
285+
{
286+
$enum = new EnumFixture(EnumFixture::FOO);
287+
288+
$enveloped = new EnumFixture($enum);
289+
290+
$this->assertEquals($enum, $enveloped);
291+
}
292+
293+
private function assertJsonEqualsJson($json1, $json2)
294+
{
295+
$this->assertJsonStringEqualsJsonString($json1, $json2);
296+
}
297+
254298
public function testSerialize()
255299
{
256300
$this->assertEquals(

0 commit comments

Comments
 (0)