Skip to content

Commit ff749d4

Browse files
committed
optimized Enum::detectConstants()
1 parent 9019505 commit ff749d4

File tree

7 files changed

+96
-27
lines changed

7 files changed

+96
-27
lines changed

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ install:
4949

5050
script:
5151
- if [ "$CODE_COVERAGE" == "1" ]; then
52-
php vendor/bin/phpunit --verbose --coverage-text --coverage-clover=coverage.clover;
52+
php -d 'zend.assertions=1' vendor/bin/phpunit --verbose --coverage-text --coverage-clover=coverage.clover;
5353
else
54-
php vendor/bin/phpunit --verbose;
54+
php -d 'zend.assertions=1' vendor/bin/phpunit --verbose;
5555
fi
5656

5757
after_script:

bench/bootstrap.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
$zendassertions = ini_get('zend.assertions');
4+
if ($zendassertions != -1) {
5+
die(
6+
'Please disable zend.assertions in php.ini (zend.assertions = -1)' . PHP_EOL .
7+
"Current ini setting: zend.assertions = {$zendassertions}]"
8+
);
9+
}
10+
11+
require_once __DIR__ . '/../vendor/autoload.php';

phpbench.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"bootstrap": "vendor/autoload.php",
2+
"bootstrap": "bench/bootstrap.php",
33
"path": "bench/",
44
"retry_threshold": 5
55
}

phpunit.xml.dist

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,8 @@
2121
<directory suffix=".php">./src</directory>
2222
</whitelist>
2323
</filter>
24+
<php>
25+
<ini name="zend.assertions" value="1"/>
26+
<ini name="assert.exception" value="1"/>
27+
</php>
2428
</phpunit>

src/Enum.php

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace MabeEnum;
44

5+
use AssertionError;
56
use ReflectionClass;
67
use InvalidArgumentException;
78
use LogicException;
@@ -337,7 +338,7 @@ final public static function has($value)
337338
*
338339
* @param string $class
339340
* @return array
340-
* @throws LogicException On ambiguous constant values
341+
* @throws AssertionError On ambiguous constant values
341342
*/
342343
private static function detectConstants($class)
343344
{
@@ -347,7 +348,7 @@ private static function detectConstants($class)
347348

348349
do {
349350
$scopeConstants = [];
350-
if (PHP_VERSION_ID >= 70100) {
351+
if (\PHP_VERSION_ID >= 70100) {
351352
// Since PHP-7.1 visibility modifiers are allowed for class constants
352353
// for enumerations we are only interested in public once.
353354
foreach ($reflection->getReflectionConstants() as $reflConstant) {
@@ -363,30 +364,34 @@ private static function detectConstants($class)
363364
$constants = $scopeConstants + $constants;
364365
} while (($reflection = $reflection->getParentClass()) && $reflection->name !== __CLASS__);
365366

366-
// Detect ambiguous values and report names
367-
$ambiguous = [];
368-
foreach ($constants as $value) {
369-
$names = \array_keys($constants, $value, true);
370-
if (\count($names) > 1) {
371-
$ambiguous[\var_export($value, true)] = $names;
372-
}
373-
}
374-
if (!empty($ambiguous)) {
375-
throw new LogicException(
376-
'All possible values needs to be unique. The following are ambiguous: '
377-
. \implode(', ', \array_map(function ($names) use ($constants) {
378-
return \implode('/', $names) . '=' . \var_export($constants[$names[0]], true);
379-
}, $ambiguous))
380-
);
381-
}
382-
383367
self::$constants[$class] = $constants;
384368
self::$names[$class] = \array_keys($constants);
369+
370+
assert('self::assertNonAmbiguous($class)');
385371
}
386372

387373
return self::$constants[$class];
388374
}
389375

376+
/**
377+
* Assert that the given enumeration class doesn't define ambiguous enumerator values
378+
* @param string $class
379+
* @return bool
380+
*/
381+
private static function assertNonAmbiguous($class)
382+
{
383+
$constants = self::$constants[$class];
384+
$ambiguous = [];
385+
foreach ($constants as $value) {
386+
$names = \array_keys($constants, $value, true);
387+
if (\count($names) > 1) {
388+
$ambiguous[\var_export($value, true)] = $names;
389+
}
390+
}
391+
392+
return empty($ambiguous);
393+
}
394+
390395
/**
391396
* Get an enumerator instance by the given name.
392397
*

tests/MabeEnumTest/EnumTest.php

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace MabeEnumTest;
44

5+
use AssertionError;
6+
use Exception;
57
use InvalidArgumentException;
68
use LogicException;
79
use MabeEnum\Enum;
@@ -274,15 +276,57 @@ public function testInstantiateUsingMagicMethod()
274276
$this->assertSame(EnumInheritance::ONE, $enum->getValue());
275277
}
276278

277-
public function testAmbiguousConstantsThrowsLogicException()
279+
public function testEnabledAssertAmbiguousEnumeratorValues()
278280
{
279-
$this->expectException(LogicException::class);
281+
assert_options(ASSERT_ACTIVE, 1);
282+
assert_options(ASSERT_WARNING, 1);
283+
assert_options(ASSERT_BAIL, 0);
284+
assert_options(ASSERT_QUIET_EVAL, 0);
285+
if (\PHP_VERSION_ID >= 70000) {
286+
$this->expectException(AssertionError::class);
287+
} elseif (defined('HHVM_VERSION')) {
288+
// assertion error thrown on HHVM is buggy
289+
$this->expectException(Exception::class);
290+
}
291+
280292
EnumAmbiguous::get('unknown');
281293
}
282294

283-
public function testExtendedAmbiguousCanstantsThrowsLogicException()
295+
public function testDisabledAssertAmbiguousEnumeratorValues()
284296
{
285-
$this->expectException(LogicException::class);
297+
assert_options(ASSERT_ACTIVE, 0);
298+
assert_options(ASSERT_WARNING, 1);
299+
assert_options(ASSERT_BAIL, 0);
300+
assert_options(ASSERT_QUIET_EVAL, 0);
301+
$this->expectException(InvalidArgumentException::class);
302+
303+
EnumAmbiguous::get('unknown');
304+
}
305+
306+
public function testExtendedEnabledAssertAmbiguousEnumeratorValues()
307+
{
308+
assert_options(ASSERT_ACTIVE, 1);
309+
assert_options(ASSERT_WARNING, 1);
310+
assert_options(ASSERT_BAIL, 0);
311+
assert_options(ASSERT_QUIET_EVAL, 0);
312+
if (\PHP_VERSION_ID >= 70000) {
313+
$this->expectException(AssertionError::class);
314+
} elseif (defined('HHVM_VERSION')) {
315+
// assertion error thrown on HHVM is buggy
316+
$this->expectException(Exception::class);
317+
}
318+
319+
EnumExtendedAmbiguous::get('unknown');
320+
}
321+
322+
public function testExtendedDisabledAssertAmbiguousEnumeratorValues()
323+
{
324+
assert_options(ASSERT_ACTIVE, 0);
325+
assert_options(ASSERT_WARNING, 1);
326+
assert_options(ASSERT_BAIL, 0);
327+
assert_options(ASSERT_QUIET_EVAL, 0);
328+
$this->expectException(InvalidArgumentException::class);
329+
286330
EnumExtendedAmbiguous::get('unknown');
287331
}
288332

tests/bootstrap.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
<?php
22

3-
ini_set('error_reporting', E_ALL);
3+
// assert(): Calling assert() with a string argument is deprecated
4+
if (PHP_VERSION_ID >= 70200) {
5+
ini_set('error_reporting', E_ALL ^ E_DEPRECATED);
6+
} else {
7+
ini_set('error_reporting', E_ALL);
8+
}
49

510
// installed itself
611
if (file_exists(__DIR__ . '/../vendor/autoload.php')) {

0 commit comments

Comments
 (0)