Breaking change

BaseEnum to Array indexes where cast to integers
  This would break enum values that where numeric strings
  ToArray now returns a list of BaseEnums
This commit is contained in:
Jérémy Munsch 2021-03-02 21:24:04 +01:00
parent 43e8dff61c
commit 45a1ccd27f
4 changed files with 64 additions and 17 deletions

View file

@ -19,3 +19,10 @@ All notable changes to `Enum` will be documented in this file.
protected $enumCasts = [
'status' => OrderStatus::class // This is a class that extends \Kwaadpepper\Enum\BaseEnum
];
## Version 0.1.0
### - Changed
- toArray Method now returns an array of BaseEnums
this is because php numeric string array indexes to int, this would break
origin enum values

View file

@ -28,17 +28,14 @@ abstract class BaseEnum implements JsonSerializable, UrlRoutable
private static $definitionCache = [];
/**
* @return string[]
* @return array<string|int, string>
* @return array[BaseEnum]
*/
public static function toArray(): array
{
$array = [];
foreach (static::resolveDefinition() as $definition) {
$array[$definition->value] = $definition->label;
$array[] = static::make($definition->value);
}
return $array;
}
@ -47,7 +44,9 @@ abstract class BaseEnum implements JsonSerializable, UrlRoutable
*/
public static function toValues(): array
{
return array_keys(static::toArray());
return \array_map(function ($baseEnum) {
return $baseEnum->value;
}, static::toArray());
}
/**
@ -55,7 +54,9 @@ abstract class BaseEnum implements JsonSerializable, UrlRoutable
*/
public static function toLabels(): array
{
return array_values(static::toArray());
return \array_map(function ($baseEnum) {
return $baseEnum->label;
}, static::toArray());
}
/**
@ -84,7 +85,6 @@ abstract class BaseEnum implements JsonSerializable, UrlRoutable
{
if (!(is_string($value) || is_int($value))) {
$enumClass = static::class;
throw new TypeError("Only string and integer are allowed values for enum {$enumClass}.");
}
@ -300,11 +300,18 @@ abstract class BaseEnum implements JsonSerializable, UrlRoutable
*/
public function resolveRouteBinding($value, $field = null)
{
// try to cast numeric value first
try {
return static::make(is_numeric($value) ? intval($value) : $value);
} catch (BadMethodCallException $e) {
return null;
}
// try string value after that
try {
return static::make($value);
} catch (BadMethodCallException $e) {
}
// could not find a suitable value
return null;
}
/**

View file

@ -4,6 +4,7 @@ namespace Kwaadpepper\Enum\Tests;
use Kwaadpepper\Enum\Tests\Enums\ContactFormCivility;
use Kwaadpepper\Enum\Tests\Enums\Days;
use Kwaadpepper\Enum\Tests\Enums\ForceStringsFromInteger;
use Orchestra\Testbench\TestCase;
class EnumTest extends TestCase
@ -29,6 +30,9 @@ class EnumTest extends TestCase
$router->get('/civilities/{civility}', function (ContactFormCivility $civility) {
return response()->json([$civility]);
})->middleware('bindings');
$router->get('/force/{force}', function (ForceStringsFromInteger $force) {
return response()->json([$force]);
})->middleware('bindings');
}
@ -69,14 +73,14 @@ class EnumTest extends TestCase
7 => 'Sunday'
], Days::toLabels());
$this->assertEquals([
0 => 'None',
1 => 'Monday',
2 => 'Tuesday',
4 => 'Wednesday',
8 => 'Thursday',
16 => 'Friday',
32 => 'Saturday',
64 => 'Sunday'
0 => Days::none(),
1 => Days::mon(),
2 => Days::tue(),
3 => Days::wed(),
4 => Days::thu(),
5 => Days::fri(),
6 => Days::sat(),
7 => Days::sun()
], Days::toArray());
$this->assertEquals('Monday', (string)$mon);
}
@ -97,4 +101,11 @@ class EnumTest extends TestCase
$response->assertOk();
$response->assertExactJson([ContactFormCivility::mme()]);
}
public function testRoutesWithEnumIntString()
{
$response = $this->call('GET', '/force/1');
$response->assertOk();
$response->assertExactJson([ForceStringsFromInteger::valueB()]);
}
}

View file

@ -0,0 +1,22 @@
<?php
namespace Kwaadpepper\Enum\Tests\Enums;
use Kwaadpepper\Enum\BaseEnum;
/**
* @method static self valueA()
* @method static self valueB()
* @method static self valueC()
*/
final class ForceStringsFromInteger extends BaseEnum
{
protected static function values(): array
{
return [
'valueA' => '0',
'valueB' => '1',
'valueC' => '2'
];
}
}