v1.0 Initial commit of project

This commit is contained in:
2026-01-01 10:54:18 +01:00
commit 768cf78b57
990 changed files with 241213 additions and 0 deletions

10
vendor/myclabs/php-enum/.gitattributes vendored Normal file
View File

@@ -0,0 +1,10 @@
# Auto detect text files and perform LF normalization
* text=auto
.gitattributes export-ignore
.github export-ignore
.gitignore export-ignore
tests/ export-ignore
phpunit.xml export-ignore
psalm.xml export-ignore
static-analysis/ export-ignore

View File

@@ -0,0 +1,12 @@
# These are supported funding model platforms
github: mnapoli # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: "packagist/myclabs/php-enum"
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@@ -0,0 +1,46 @@
name: "CI"
on:
pull_request:
push:
branches:
- "master"
jobs:
phpunit:
name: "PHPUnit"
runs-on: "ubuntu-20.04"
strategy:
matrix:
php-version:
- "7.3"
- "7.4"
- "8.0"
- "8.1"
- "8.2"
dependencies:
- "highest"
include:
- dependencies: "lowest"
php-version: "7.3"
steps:
- name: "Checkout"
uses: "actions/checkout@v4"
with:
fetch-depth: 2
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php-version }}"
ini-values: "zend.assertions=1"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
with:
dependency-versions: "${{ matrix.dependencies }}"
- name: "Run PHPUnit"
run: "vendor/bin/phpunit"

View File

@@ -0,0 +1,31 @@
name: "Static Analysis"
on:
pull_request:
push:
branches:
- "master"
jobs:
static-analysis-psalm:
name: "Static Analysis with Psalm"
runs-on: "ubuntu-20.04"
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Psalm
uses: docker://vimeo/psalm-github-actions:4.9.3
with:
args: --shepherd
composer_ignore_platform_reqs: true
composer_require_dev: true
security_analysis: true
report_file: results.sarif
env:
CHECK_PLATFORM_REQUIREMENTS: "false"
- name: Upload Security Analysis results to GitHub
uses: github/codeql-action/upload-sarif@v1
with:
sarif_file: results.sarif

6
vendor/myclabs/php-enum/.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
.DS_Store
nbproject/*
.idea/*
vendor/*
composer.phar
composer.lock

18
vendor/myclabs/php-enum/LICENSE vendored Normal file
View File

@@ -0,0 +1,18 @@
The MIT License (MIT)
Copyright (c) 2015 My C-Labs
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

196
vendor/myclabs/php-enum/README.md vendored Normal file
View File

@@ -0,0 +1,196 @@
# PHP Enum implementation inspired from SplEnum
[![GitHub Actions][GA Image]][GA Link]
[![Latest Stable Version](https://poser.pugx.org/myclabs/php-enum/version.png)](https://packagist.org/packages/myclabs/php-enum)
[![Total Downloads](https://poser.pugx.org/myclabs/php-enum/downloads.png)](https://packagist.org/packages/myclabs/php-enum)
[![Psalm Shepherd][Shepherd Image]][Shepherd Link]
Maintenance for this project is [supported via Tidelift](https://tidelift.com/subscription/pkg/packagist-myclabs-php-enum?utm_source=packagist-myclabs-php-enum&utm_medium=referral&utm_campaign=readme).
## Why?
First, and mainly, `SplEnum` is not integrated to PHP, you have to install the extension separately.
Using an enum instead of class constants provides the following advantages:
- You can use an enum as a parameter type: `function setAction(Action $action) {`
- You can use an enum as a return type: `function getAction() : Action {`
- You can enrich the enum with methods (e.g. `format`, `parse`, …)
- You can extend the enum to add new values (make your enum `final` to prevent it)
- You can get a list of all the possible values (see below)
This Enum class is not intended to replace class constants, but only to be used when it makes sense.
## Installation
```
composer require myclabs/php-enum
```
## Declaration
```php
use MyCLabs\Enum\Enum;
/**
* Action enum
*
* @extends Enum<Action::*>
*/
final class Action extends Enum
{
private const VIEW = 'view';
private const EDIT = 'edit';
}
```
## Usage
```php
$action = Action::VIEW();
// or with a dynamic key:
$action = Action::$key();
// or with a dynamic value:
$action = Action::from($value);
// or
$action = new Action($value);
```
As you can see, static methods are automatically implemented to provide quick access to an enum value.
One advantage over using class constants is to be able to use an enum as a parameter type:
```php
function setAction(Action $action) {
// ...
}
```
## Documentation
- `__construct()` The constructor checks that the value exist in the enum
- `__toString()` You can `echo $myValue`, it will display the enum value (value of the constant)
- `getValue()` Returns the current value of the enum
- `getKey()` Returns the key of the current value on Enum
- `equals()` Tests whether enum instances are equal (returns `true` if enum values are equal, `false` otherwise)
Static methods:
- `from()` Creates an Enum instance, checking that the value exist in the enum
- `toArray()` method Returns all possible values as an array (constant name in key, constant value in value)
- `keys()` Returns the names (keys) of all constants in the Enum class
- `values()` Returns instances of the Enum class of all Enum constants (constant name in key, Enum instance in value)
- `isValid()` Check if tested value is valid on enum set
- `isValidKey()` Check if tested key is valid on enum set
- `assertValidValue()` Assert the value is valid on enum set, throwing exception otherwise
- `search()` Return key for searched value
### Static methods
```php
final class Action extends Enum
{
private const VIEW = 'view';
private const EDIT = 'edit';
}
// Static method:
$action = Action::VIEW();
$action = Action::EDIT();
```
Static method helpers are implemented using [`__callStatic()`](http://www.php.net/manual/en/language.oop5.overloading.php#object.callstatic).
If you care about IDE autocompletion, you can either implement the static methods yourself:
```php
final class Action extends Enum
{
private const VIEW = 'view';
/**
* @return Action
*/
public static function VIEW() {
return new Action(self::VIEW);
}
}
```
or you can use phpdoc (this is supported in PhpStorm for example):
```php
/**
* @method static Action VIEW()
* @method static Action EDIT()
*/
final class Action extends Enum
{
private const VIEW = 'view';
private const EDIT = 'edit';
}
```
## Native enums and migration
Native enum arrived to PHP in version 8.1: https://www.php.net/enumerations
If your project is running PHP 8.1+ or your library has it as a minimum requirement you should use it instead of this library.
When migrating from `myclabs/php-enum`, the effort should be small if the usage was in the recommended way:
- private constants
- final classes
- no method overridden
Changes for migration:
- Class definition should be changed from
```php
/**
* @method static Action VIEW()
* @method static Action EDIT()
*/
final class Action extends Enum
{
private const VIEW = 'view';
private const EDIT = 'edit';
}
```
to
```php
enum Action: string
{
case VIEW = 'view';
case EDIT = 'edit';
}
```
All places where the class was used as a type will continue to work.
Usages and the change needed:
| Operation | myclabs/php-enum | native enum |
|----------------------------------------------------------------|----------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Obtain an instance will change from | `$enumCase = Action::VIEW()` | `$enumCase = Action::VIEW` |
| Create an enum from a backed value | `$enumCase = new Action('view')` | `$enumCase = Action::from('view')` |
| Get the backed value of the enum instance | `$enumCase->getValue()` | `$enumCase->value` |
| Compare two enum instances | `$enumCase1 == $enumCase2` <br/> or <br/> `$enumCase1->equals($enumCase2)` | `$enumCase1 === $enumCase2` |
| Get the key/name of the enum instance | `$enumCase->getKey()` | `$enumCase->name` |
| Get a list of all the possible instances of the enum | `Action::values()` | `Action::cases()` |
| Get a map of possible instances of the enum mapped by name | `Action::values()` | `array_combine(array_map(fn($case) => $case->name, Action::cases()), Action::cases())` <br/> or <br/> `(new ReflectionEnum(Action::class))->getConstants()` |
| Get a list of all possible names of the enum | `Action::keys()` | `array_map(fn($case) => $case->name, Action::cases())` |
| Get a list of all possible backed values of the enum | `Action::toArray()` | `array_map(fn($case) => $case->value, Action::cases())` |
| Get a map of possible backed values of the enum mapped by name | `Action::toArray()` | `array_combine(array_map(fn($case) => $case->name, Action::cases()), array_map(fn($case) => $case->value, Action::cases()))` <br/> or <br/> `array_map(fn($case) => $case->value, (new ReflectionEnum(Action::class))->getConstants()))` |
## Related projects
- [PHP 8.1+ native enum](https://www.php.net/enumerations)
- [Doctrine enum mapping](https://github.com/acelaya/doctrine-enum-type)
- [Symfony ParamConverter integration](https://github.com/Ex3v/MyCLabsEnumParamConverter)
- [PHPStan integration](https://github.com/timeweb/phpstan-enum)
[GA Image]: https://github.com/myclabs/php-enum/workflows/CI/badge.svg
[GA Link]: https://github.com/myclabs/php-enum/actions?query=workflow%3A%22CI%22+branch%3Amaster
[Shepherd Image]: https://shepherd.dev/github/myclabs/php-enum/coverage.svg
[Shepherd Link]: https://shepherd.dev/github/myclabs/php-enum

11
vendor/myclabs/php-enum/SECURITY.md vendored Normal file
View File

@@ -0,0 +1,11 @@
# Security Policy
## Supported Versions
Only the latest stable release is supported.
## Reporting a Vulnerability
To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security).
Tidelift will coordinate the fix and disclosure.

19
vendor/myclabs/php-enum/phpunit.xml vendored Normal file
View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
colors="true"
bootstrap="./tests/bootstrap.php"
>
<testsuites>
<testsuite name="PHP Enum Test Suite">
<directory suffix=".php">./tests</directory>
</testsuite>
</testsuites>
<coverage>
<include>
<directory suffix=".php">src</directory>
</include>
</coverage>
</phpunit>

35
vendor/myclabs/php-enum/psalm.xml vendored Normal file
View File

@@ -0,0 +1,35 @@
<?xml version="1.0"?>
<psalm
totallyTyped="true"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<directory name="src" />
<directory name="static-analysis" />
<ignoreFiles>
<directory name="vendor" />
<directory name="src/PHPUnit" />
</ignoreFiles>
</projectFiles>
<issueHandlers>
<MixedAssignment errorLevel="info" />
<ImpureStaticProperty>
<!-- self::$... usages in Enum are used to populate an internal cache, and cause no side-effects -->
<errorLevel type="suppress">
<file name="src/Enum.php"/>
</errorLevel>
</ImpureStaticProperty>
<ImpureVariable>
<!-- $this usages in Enum point themselves to an immutable instance -->
<errorLevel type="suppress">
<file name="src/Enum.php"/>
</errorLevel>
</ImpureVariable>
</issueHandlers>
</psalm>

319
vendor/myclabs/php-enum/src/Enum.php vendored Normal file
View File

@@ -0,0 +1,319 @@
<?php
/**
* @link http://github.com/myclabs/php-enum
* @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
*/
namespace MyCLabs\Enum;
/**
* Base Enum class
*
* Create an enum by implementing this class and adding class constants.
*
* @author Matthieu Napoli <matthieu@mnapoli.fr>
* @author Daniel Costa <danielcosta@gmail.com>
* @author Mirosław Filip <mirfilip@gmail.com>
*
* @psalm-template T
* @psalm-immutable
* @psalm-consistent-constructor
*/
abstract class Enum implements \JsonSerializable, \Stringable
{
/**
* Enum value
*
* @var mixed
* @psalm-var T
*/
protected $value;
/**
* Enum key, the constant name
*
* @var string
*/
private $key;
/**
* Store existing constants in a static cache per object.
*
*
* @var array
* @psalm-var array<class-string, array<string, mixed>>
*/
protected static $cache = [];
/**
* Cache of instances of the Enum class
*
* @var array
* @psalm-var array<class-string, array<string, static>>
*/
protected static $instances = [];
/**
* Creates a new value of some type
*
* @psalm-pure
* @param mixed $value
*
* @psalm-param T $value
* @throws \UnexpectedValueException if incompatible type is given.
*/
public function __construct($value)
{
if ($value instanceof static) {
/** @psalm-var T */
$value = $value->getValue();
}
/** @psalm-suppress ImplicitToStringCast assertValidValueReturningKey returns always a string but psalm has currently an issue here */
$this->key = static::assertValidValueReturningKey($value);
/** @psalm-var T */
$this->value = $value;
}
/**
* This method exists only for the compatibility reason when deserializing a previously serialized version
* that didn't had the key property
*/
public function __wakeup()
{
/** @psalm-suppress DocblockTypeContradiction key can be null when deserializing an enum without the key */
if ($this->key === null) {
/**
* @psalm-suppress InaccessibleProperty key is not readonly as marked by psalm
* @psalm-suppress PossiblyFalsePropertyAssignmentValue deserializing a case that was removed
*/
$this->key = static::search($this->value);
}
}
/**
* @param mixed $value
* @return static
*/
public static function from($value): self
{
$key = static::assertValidValueReturningKey($value);
return self::__callStatic($key, []);
}
/**
* @psalm-pure
* @return mixed
* @psalm-return T
*/
public function getValue()
{
return $this->value;
}
/**
* Returns the enum key (i.e. the constant name).
*
* @psalm-pure
* @return string
*/
public function getKey()
{
return $this->key;
}
/**
* @psalm-pure
* @psalm-suppress InvalidCast
* @return string
*/
public function __toString()
{
return (string)$this->value;
}
/**
* Determines if Enum should be considered equal with the variable passed as a parameter.
* Returns false if an argument is an object of different class or not an object.
*
* This method is final, for more information read https://github.com/myclabs/php-enum/issues/4
*
* @psalm-pure
* @psalm-param mixed $variable
* @return bool
*/
final public function equals($variable = null): bool
{
return $variable instanceof self
&& $this->getValue() === $variable->getValue()
&& static::class === \get_class($variable);
}
/**
* Returns the names (keys) of all constants in the Enum class
*
* @psalm-pure
* @psalm-return list<string>
* @return array
*/
public static function keys()
{
return \array_keys(static::toArray());
}
/**
* Returns instances of the Enum class of all Enum constants
*
* @psalm-pure
* @psalm-return array<string, static>
* @return static[] Constant name in key, Enum instance in value
*/
public static function values()
{
$values = array();
/** @psalm-var T $value */
foreach (static::toArray() as $key => $value) {
/** @psalm-suppress UnsafeGenericInstantiation */
$values[$key] = new static($value);
}
return $values;
}
/**
* Returns all possible values as an array
*
* @psalm-pure
* @psalm-suppress ImpureStaticProperty
*
* @psalm-return array<string, mixed>
* @return array Constant name in key, constant value in value
*/
public static function toArray()
{
$class = static::class;
if (!isset(static::$cache[$class])) {
/** @psalm-suppress ImpureMethodCall this reflection API usage has no side-effects here */
$reflection = new \ReflectionClass($class);
/** @psalm-suppress ImpureMethodCall this reflection API usage has no side-effects here */
static::$cache[$class] = $reflection->getConstants();
}
return static::$cache[$class];
}
/**
* Check if is valid enum value
*
* @param $value
* @psalm-param mixed $value
* @psalm-pure
* @psalm-assert-if-true T $value
* @return bool
*/
public static function isValid($value)
{
return \in_array($value, static::toArray(), true);
}
/**
* Asserts valid enum value
*
* @psalm-pure
* @psalm-assert T $value
* @param mixed $value
*/
public static function assertValidValue($value): void
{
self::assertValidValueReturningKey($value);
}
/**
* Asserts valid enum value
*
* @psalm-pure
* @psalm-assert T $value
* @param mixed $value
* @return string
*/
private static function assertValidValueReturningKey($value): string
{
if (false === ($key = static::search($value))) {
throw new \UnexpectedValueException("Value '$value' is not part of the enum " . static::class);
}
return $key;
}
/**
* Check if is valid enum key
*
* @param $key
* @psalm-param string $key
* @psalm-pure
* @return bool
*/
public static function isValidKey($key)
{
$array = static::toArray();
return isset($array[$key]) || \array_key_exists($key, $array);
}
/**
* Return key for value
*
* @param mixed $value
*
* @psalm-param mixed $value
* @psalm-pure
* @return string|false
*/
public static function search($value)
{
return \array_search($value, static::toArray(), true);
}
/**
* Returns a value when called statically like so: MyEnum::SOME_VALUE() given SOME_VALUE is a class constant
*
* @param string $name
* @param array $arguments
*
* @return static
* @throws \BadMethodCallException
*
* @psalm-pure
*/
public static function __callStatic($name, $arguments)
{
$class = static::class;
if (!isset(self::$instances[$class][$name])) {
$array = static::toArray();
if (!isset($array[$name]) && !\array_key_exists($name, $array)) {
$message = "No static method or enum constant '$name' in class " . static::class;
throw new \BadMethodCallException($message);
}
/** @psalm-suppress UnsafeGenericInstantiation */
return self::$instances[$class][$name] = new static($array[$name]);
}
return clone self::$instances[$class][$name];
}
/**
* Specify data which should be serialized to JSON. This method returns data that can be serialized by json_encode()
* natively.
*
* @return mixed
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php
*/
#[\ReturnTypeWillChange]
public function jsonSerialize()
{
return $this->getValue();
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace MyCLabs\Enum\PHPUnit;
use MyCLabs\Enum\Enum;
use SebastianBergmann\Comparator\ComparisonFailure;
/**
* Use this Comparator to get nice output when using PHPUnit assertEquals() with Enums.
*
* Add this to your PHPUnit bootstrap PHP file:
*
* \SebastianBergmann\Comparator\Factory::getInstance()->register(new \MyCLabs\Enum\PHPUnit\Comparator());
*/
final class Comparator extends \SebastianBergmann\Comparator\Comparator
{
public function accepts($expected, $actual)
{
return $expected instanceof Enum && (
$actual instanceof Enum || $actual === null
);
}
/**
* @param Enum $expected
* @param Enum|null $actual
*
* @return void
*/
public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false)
{
if ($expected->equals($actual)) {
return;
}
throw new ComparisonFailure(
$expected,
$actual,
$this->formatEnum($expected),
$this->formatEnum($actual),
false,
'Failed asserting that two Enums are equal.'
);
}
private function formatEnum(?Enum $enum = null)
{
if ($enum === null) {
return "null";
}
return get_class($enum)."::{$enum->getKey()}()";
}
}

View File

@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace MyCLabs\Tests\Enum\StaticAnalysis;
use MyCLabs\Enum\Enum;
/**
* @method static PureEnum A()
* @method static PureEnum C()
*
* @psalm-immutable
* @psalm-template T of 'A'|'B'
* @template-extends Enum<T>
*/
final class PureEnum extends Enum
{
const A = 'A';
const C = 'C';
}
/** @psalm-pure */
function enumFetchViaMagicMethodIsPure(): PureEnum
{
return PureEnum::A();
}
/** @psalm-pure */
function enumFetchViaExplicitMagicCallIsPure(): PureEnum
{
return PureEnum::__callStatic('A', []);
}

View File

@@ -0,0 +1,11 @@
<?php
if (\PHP_VERSION_ID < 80000 && !interface_exists('Stringable')) {
interface Stringable
{
/**
* @return string
*/
public function __toString();
}
}

View File

@@ -0,0 +1,23 @@
<?php
/**
* @link http://github.com/myclabs/php-enum
* @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
*/
namespace MyCLabs\Tests\Enum;
use MyCLabs\Enum\Enum;
/**
* Class EnumConflict
*
* @method static EnumConflict FOO()
* @method static EnumConflict BAR()
*
* @author Daniel Costa <danielcosta@gmail.com>
* @author Mirosław Filip <mirfilip@gmail.com>
*/
class EnumConflict extends Enum
{
const FOO = "foo";
const BAR = "bar";
}

View File

@@ -0,0 +1,39 @@
<?php
/**
* @link http://github.com/myclabs/php-enum
* @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
*/
namespace MyCLabs\Tests\Enum;
use MyCLabs\Enum\Enum;
/**
* Class EnumFixture
*
* @method static EnumFixture FOO()
* @method static EnumFixture BAR()
* @method static EnumFixture NUMBER()
*
* @method static EnumFixture PROBLEMATIC_NUMBER()
* @method static EnumFixture PROBLEMATIC_NULL()
* @method static EnumFixture PROBLEMATIC_EMPTY_STRING()
* @method static EnumFixture PROBLEMATIC_BOOLEAN_FALSE()
*
* @author Daniel Costa <danielcosta@gmail.com>
* @author Mirosław Filip <mirfilip@gmail.com>
*/
class EnumFixture extends Enum
{
const FOO = "foo";
const BAR = "bar";
const NUMBER = 42;
/**
* Values that are known to cause problems when used with soft typing
*/
const PROBLEMATIC_NUMBER = 0;
const PROBLEMATIC_NULL = null;
const PROBLEMATIC_EMPTY_STRING = '';
const PROBLEMATIC_BOOLEAN_FALSE = false;
}

View File

@@ -0,0 +1,384 @@
<?php
/**
* @link http://github.com/myclabs/php-enum
* @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
*/
namespace MyCLabs\Tests\Enum;
/**
* @author Matthieu Napoli <matthieu@mnapoli.fr>
* @author Daniel Costa <danielcosta@gmail.com>
* @author Mirosław Filip <mirfilip@gmail.com>
*/
class EnumTest extends \PHPUnit\Framework\TestCase
{
/**
* getValue()
*/
public function testGetValue()
{
$value = new EnumFixture(EnumFixture::FOO);
$this->assertEquals(EnumFixture::FOO, $value->getValue());
$value = new EnumFixture(EnumFixture::BAR);
$this->assertEquals(EnumFixture::BAR, $value->getValue());
$value = new EnumFixture(EnumFixture::NUMBER);
$this->assertEquals(EnumFixture::NUMBER, $value->getValue());
}
/**
* getKey()
*/
public function testGetKey()
{
$value = new EnumFixture(EnumFixture::FOO);
$this->assertEquals('FOO', $value->getKey());
$this->assertNotEquals('BA', $value->getKey());
}
/** @dataProvider invalidValueProvider */
public function testCreatingEnumWithInvalidValue($value)
{
$this->expectException(\UnexpectedValueException::class);
$this->expectExceptionMessage('is not part of the enum ' . EnumFixture::class);
new EnumFixture($value);
}
/**
* @dataProvider invalidValueProvider
* @param mixed $value
*/
public function testFailToCreateEnumWithInvalidValueThroughNamedConstructor($value): void
{
$this->expectException(\UnexpectedValueException::class);
$this->expectExceptionMessage('is not part of the enum MyCLabs\Tests\Enum\EnumFixture');
EnumFixture::from($value);
}
public function testFailToCreateEnumWithEnumItselfThroughNamedConstructor(): void
{
$this->expectException(\UnexpectedValueException::class);
$this->expectExceptionMessage("Value 'foo' is not part of the enum " . EnumFixture::class);
EnumFixture::from(EnumFixture::FOO());
}
/**
* Contains values not existing in EnumFixture
* @return array
*/
public function invalidValueProvider()
{
return array(
"string" => array('test'),
"int" => array(1234),
);
}
/**
* __toString()
* @dataProvider toStringProvider
*/
public function testToString($expected, $enumObject)
{
$this->assertSame($expected, (string) $enumObject);
}
public function toStringProvider()
{
return array(
array(EnumFixture::FOO, new EnumFixture(EnumFixture::FOO)),
array(EnumFixture::BAR, new EnumFixture(EnumFixture::BAR)),
array((string) EnumFixture::NUMBER, new EnumFixture(EnumFixture::NUMBER)),
);
}
/**
* keys()
*/
public function testKeys()
{
$values = EnumFixture::keys();
$expectedValues = array(
"FOO",
"BAR",
"NUMBER",
"PROBLEMATIC_NUMBER",
"PROBLEMATIC_NULL",
"PROBLEMATIC_EMPTY_STRING",
"PROBLEMATIC_BOOLEAN_FALSE",
);
$this->assertSame($expectedValues, $values);
}
/**
* values()
*/
public function testValues()
{
$values = EnumFixture::values();
$expectedValues = array(
"FOO" => new EnumFixture(EnumFixture::FOO),
"BAR" => new EnumFixture(EnumFixture::BAR),
"NUMBER" => new EnumFixture(EnumFixture::NUMBER),
"PROBLEMATIC_NUMBER" => new EnumFixture(EnumFixture::PROBLEMATIC_NUMBER),
"PROBLEMATIC_NULL" => new EnumFixture(EnumFixture::PROBLEMATIC_NULL),
"PROBLEMATIC_EMPTY_STRING" => new EnumFixture(EnumFixture::PROBLEMATIC_EMPTY_STRING),
"PROBLEMATIC_BOOLEAN_FALSE" => new EnumFixture(EnumFixture::PROBLEMATIC_BOOLEAN_FALSE),
);
$this->assertEquals($expectedValues, $values);
}
/**
* toArray()
*/
public function testToArray()
{
$values = EnumFixture::toArray();
$expectedValues = array(
"FOO" => EnumFixture::FOO,
"BAR" => EnumFixture::BAR,
"NUMBER" => EnumFixture::NUMBER,
"PROBLEMATIC_NUMBER" => EnumFixture::PROBLEMATIC_NUMBER,
"PROBLEMATIC_NULL" => EnumFixture::PROBLEMATIC_NULL,
"PROBLEMATIC_EMPTY_STRING" => EnumFixture::PROBLEMATIC_EMPTY_STRING,
"PROBLEMATIC_BOOLEAN_FALSE" => EnumFixture::PROBLEMATIC_BOOLEAN_FALSE,
);
$this->assertSame($expectedValues, $values);
}
/**
* __callStatic()
*/
public function testStaticAccess()
{
$this->assertEquals(new EnumFixture(EnumFixture::FOO), EnumFixture::FOO());
$this->assertEquals(new EnumFixture(EnumFixture::BAR), EnumFixture::BAR());
$this->assertEquals(new EnumFixture(EnumFixture::NUMBER), EnumFixture::NUMBER());
$this->assertNotSame(EnumFixture::NUMBER(), EnumFixture::NUMBER());
}
public function testBadStaticAccess()
{
$this->expectException(\BadMethodCallException::class);
$this->expectExceptionMessage('No static method or enum constant \'UNKNOWN\' in class ' . EnumFixture::class);
EnumFixture::UNKNOWN();
}
/**
* isValid()
* @dataProvider isValidProvider
*/
public function testIsValid($value, $isValid)
{
$this->assertSame($isValid, EnumFixture::isValid($value));
}
public function isValidProvider()
{
return [
/**
* Valid values
*/
['foo', true],
[42, true],
[null, true],
[0, true],
['', true],
[false, true],
/**
* Invalid values
*/
['baz', false]
];
}
/**
* isValidKey()
*/
public function testIsValidKey()
{
$this->assertTrue(EnumFixture::isValidKey('FOO'));
$this->assertFalse(EnumFixture::isValidKey('BAZ'));
$this->assertTrue(EnumFixture::isValidKey('PROBLEMATIC_NULL'));
}
/**
* search()
* @see https://github.com/myclabs/php-enum/issues/13
* @dataProvider searchProvider
*/
public function testSearch($value, $expected)
{
$this->assertSame($expected, EnumFixture::search($value));
}
public function searchProvider()
{
return array(
array('foo', 'FOO'),
array(0, 'PROBLEMATIC_NUMBER'),
array(null, 'PROBLEMATIC_NULL'),
array('', 'PROBLEMATIC_EMPTY_STRING'),
array(false, 'PROBLEMATIC_BOOLEAN_FALSE'),
array('bar I do not exist', false),
array(array(), false),
);
}
/**
* equals()
*/
public function testEquals()
{
$foo = new EnumFixture(EnumFixture::FOO);
$number = new EnumFixture(EnumFixture::NUMBER);
$anotherFoo = new EnumFixture(EnumFixture::FOO);
$objectOfDifferentClass = new \stdClass();
$notAnObject = 'foo';
$this->assertTrue($foo->equals($foo));
$this->assertFalse($foo->equals($number));
$this->assertTrue($foo->equals($anotherFoo));
$this->assertFalse($foo->equals(null));
$this->assertFalse($foo->equals($objectOfDifferentClass));
$this->assertFalse($foo->equals($notAnObject));
}
/**
* equals()
*/
public function testEqualsComparesProblematicValuesProperly()
{
$false = new EnumFixture(EnumFixture::PROBLEMATIC_BOOLEAN_FALSE);
$emptyString = new EnumFixture(EnumFixture::PROBLEMATIC_EMPTY_STRING);
$null = new EnumFixture(EnumFixture::PROBLEMATIC_NULL);
$this->assertTrue($false->equals($false));
$this->assertFalse($false->equals($emptyString));
$this->assertFalse($emptyString->equals($null));
$this->assertFalse($null->equals($false));
}
/**
* equals()
*/
public function testEqualsConflictValues()
{
$this->assertFalse(EnumFixture::FOO()->equals(EnumConflict::FOO()));
}
/**
* jsonSerialize()
*/
public function testJsonSerialize()
{
$this->assertJsonEqualsJson('"foo"', json_encode(new EnumFixture(EnumFixture::FOO)));
$this->assertJsonEqualsJson('"bar"', json_encode(new EnumFixture(EnumFixture::BAR)));
$this->assertJsonEqualsJson('42', json_encode(new EnumFixture(EnumFixture::NUMBER)));
$this->assertJsonEqualsJson('0', json_encode(new EnumFixture(EnumFixture::PROBLEMATIC_NUMBER)));
$this->assertJsonEqualsJson('null', json_encode(new EnumFixture(EnumFixture::PROBLEMATIC_NULL)));
$this->assertJsonEqualsJson('""', json_encode(new EnumFixture(EnumFixture::PROBLEMATIC_EMPTY_STRING)));
$this->assertJsonEqualsJson('false', json_encode(new EnumFixture(EnumFixture::PROBLEMATIC_BOOLEAN_FALSE)));
}
public function testNullableEnum()
{
$this->assertNull(EnumFixture::PROBLEMATIC_NULL()->getValue());
$this->assertNull((new EnumFixture(EnumFixture::PROBLEMATIC_NULL))->getValue());
$this->assertNull((new EnumFixture(EnumFixture::PROBLEMATIC_NULL))->jsonSerialize());
}
public function testBooleanEnum()
{
$this->assertFalse(EnumFixture::PROBLEMATIC_BOOLEAN_FALSE()->getValue());
$this->assertFalse((new EnumFixture(EnumFixture::PROBLEMATIC_BOOLEAN_FALSE))->jsonSerialize());
}
public function testConstructWithSameEnumArgument()
{
$enum = new EnumFixture(EnumFixture::FOO);
$enveloped = new EnumFixture($enum);
$this->assertEquals($enum, $enveloped);
}
private function assertJsonEqualsJson($json1, $json2)
{
$this->assertJsonStringEqualsJsonString($json1, $json2);
}
public function testSerialize()
{
// split string for Pretty CI: "Line exceeds 120 characters"
$bin = '4f3a33303a224d79434c6162735c54657374735c456e756d5c456e756d4669787'.
'4757265223a323a7b733a383a22002a0076616c7565223b733a333a22666f6f223b73'.
'3a32323a22004d79434c6162735c456e756d5c456e756d006b6579223b733a333a22464f4f223b7d';
$this->assertEquals($bin, bin2hex(serialize(EnumFixture::FOO())));
}
public function testUnserializeVersionWithoutKey()
{
// split string for Pretty CI: "Line exceeds 120 characters"
$bin = '4f3a33303a224d79434c6162735c54657374735c456e756d5c456e756d4669787'.
'4757265223a313a7b733a383a22002a0076616c7565223b733a333a22666f6f223b7d';
/* @var $value EnumFixture */
$value = unserialize(pack('H*', $bin));
$this->assertEquals(EnumFixture::FOO, $value->getValue());
$this->assertTrue(EnumFixture::FOO()->equals($value));
$this->assertTrue(EnumFixture::FOO() == $value);
}
public function testUnserialize()
{
// split string for Pretty CI: "Line exceeds 120 characters"
$bin = '4f3a33303a224d79434c6162735c54657374735c456e756d5c456e756d4669787'.
'4757265223a323a7b733a383a22002a0076616c7565223b733a333a22666f6f223b73'.
'3a32323a22004d79434c6162735c456e756d5c456e756d006b6579223b733a333a22464f4f223b7d';
/* @var $value EnumFixture */
$value = unserialize(pack('H*', $bin));
$this->assertEquals(EnumFixture::FOO, $value->getValue());
$this->assertTrue(EnumFixture::FOO()->equals($value));
$this->assertTrue(EnumFixture::FOO() == $value);
}
/**
* @see https://github.com/myclabs/php-enum/issues/95
*/
public function testEnumValuesInheritance()
{
$this->expectException(\UnexpectedValueException::class);
$this->expectExceptionMessage("Value 'value' is not part of the enum MyCLabs\Tests\Enum\EnumFixture");
$inheritedEnumFixture = InheritedEnumFixture::VALUE();
new EnumFixture($inheritedEnumFixture);
}
/**
* @dataProvider isValidProvider
*/
public function testAssertValidValue($value, $isValid): void
{
if (!$isValid) {
$this->expectException(\UnexpectedValueException::class);
$this->expectExceptionMessage("Value '$value' is not part of the enum " . EnumFixture::class);
}
EnumFixture::assertValidValue($value);
self::assertTrue(EnumFixture::isValid($value));
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace MyCLabs\Tests\Enum;
/**
* Class InheritedEnumFixture.
* @package MyCLabs\Tests\Enum
*
* @method static InheritedEnumFixture VALUE()
*/
class InheritedEnumFixture extends EnumFixture
{
const VALUE = 'value';
}

View File

@@ -0,0 +1,3 @@
<?php
\SebastianBergmann\Comparator\Factory::getInstance()->register(new \MyCLabs\Enum\PHPUnit\Comparator());