Skip to content

Commit

Permalink
Merge pull request #1 from MarkBaker/develop
Browse files Browse the repository at this point in the history
New Trait for case name validation against an enum
  • Loading branch information
MarkBaker authored Dec 8, 2021
2 parents c9e8ebc + a695bf9 commit 756973d
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 13 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

All notable changes to `EnumHelper` will be documented in this file.

## 1.0.1 - 2021-12-08

- Added `EnumValidatableCase` trait, providing an `isValidCase()` method to validate a string value against the set of case names defined for an enum.

## 1.0.0 - 2021-12-07

- Initial release

Created `EnumValidatableCase` trait, providing a `fromName()` method that allows a string value which matches an enum case to be used to create an instance of that enum.
File renamed without changes.
50 changes: 44 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
# A trait that allows you to create an enum from a string name in PHP 8.1
# A library of helper traits for working with PHP 8.1 enums

[![Build Status](https://github.com/MarkBaker/EnumHelper/workflows/main/badge.svg)](https://github.com/MarkBaker/EnumHelper/actions)
[![Total Downloads](https://img.shields.io/packagist/dt/markbaker/enumhelper)](https://packagist.org/packages/markbaker/enumhelper)
[![Latest Stable Version](https://img.shields.io/github/v/release/MarkBaker/EnumHelper)](https://packagist.org/packages/markbaker/enumhelper)
[![License](https://img.shields.io/github/license/MarkBaker/EnumHelper)](https://packagist.org/packages/markbaker/enumhelper)

This package provides a trait that allows you to create a PHP 8.1 enum from a name string.
This package provides a series of traits that allows you to:
- RestorableFromName Trait

Create/restore a PHP 8.1 enum from a name string.
- EnumValidatableCase

Validate an enum name from a name string.

## Installation

Expand All @@ -17,6 +23,8 @@ composer require markbaker/enumhelper

## Usage

### RestorableFromName Trait

In PHP 8.1, it is possible to create a backed enum from a value using the enum's `from()` or `tryFrom()` methods.

```php
Expand Down Expand Up @@ -50,19 +58,49 @@ enum Suit: string

$suit = Suit::Diamonds;

$name = $suit->name; // Returns 'Diamonds'
$suitName = $suit->name; // Returns 'Diamonds'

$newSuit = Suit::fromName($name);
$newSuit = Suit::fromName($suitName);
```

An invalid name will throw an exception. Note that names are case-sensitive.

This could be useful if you wanted to store the name in a database for readability (particularly appropriate for unbacked enums); then recreate the enum in the model when you load the database record.

This works with both backed and unbacked enums.

### EnumValidatableCase Trait

Useful to validate if a name has been defined in the case set for an enum:

```php
enum Suit: string
{
use EnumHelper\EnumValidatableCase;

case Hearts = 'H';
case Diamonds = 'D';
case Clubs = 'C';
case Spades = 'S';
}

$suit = Suit::Diamonds;

$validCaseName = Suit::Hearts;
$isCaseNameValid = Suit::isValidCase($validCaseName); // Returns boolean true

$invalidCaseName = 'HeArTs';
$isCaseNameValid = Suit::isValidCase($invalidCaseName); // Returns boolean false
```

Note that names are case-sensitive.

This works with both backed and unbacked enums.

## Changelog

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.
Please see the [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

## License

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
This librar is released under the MIT License (MIT). Please see [License File](LICENSE.md) for more information.
4 changes: 2 additions & 2 deletions src/EnumRestorableFromName.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

trait EnumRestorableFromName
{
public static function fromName(string $name)
public static function fromName(string $name): self
{
$reflector = new \ReflectionEnum(self::class);
try {
$reflector = new \ReflectionEnum(self::class);
$enumReflector = $reflector->getCase($name);
return $enumReflector->getValue();
} catch (\ReflectionException $e) {
Expand Down
18 changes: 18 additions & 0 deletions src/EnumValidatableCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace EnumHelper;

trait EnumValidatableCase
{
public static function isValidCase(string $name): bool
{
$reflector = new \ReflectionEnum(self::class);
try {
$reflector->getCase($name);
} catch (\ReflectionException $e) {
return false;
}

return true;
}
}
3 changes: 2 additions & 1 deletion tests/data/BackedEnumSuit.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
namespace EnumHelper\TestData;

use EnumHelper\EnumRestorableFromName;
use EnumHelper\EnumValidatableCase;

enum BackedEnumSuit: string
{
use EnumRestorableFromName;
use EnumRestorableFromName, EnumValidatableCase;

case Clubs = 'C';
case Diamonds = 'D';
Expand Down
3 changes: 2 additions & 1 deletion tests/data/EnumSuit.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
namespace EnumHelper\TestData;

use EnumHelper\EnumRestorableFromName;
use EnumHelper\EnumValidatableCase;

enum EnumSuit
{
use EnumRestorableFromName;
use EnumRestorableFromName, EnumValidatableCase;

case Clubs;
case Diamonds;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use EnumHelper\TestData\BackedEnumSuit;
use PHPUnit\Framework\TestCase;

class BackedEnumSuitTest extends TestCase
class RestoreFromNameBackedEnumSuitTest extends TestCase
{
/**
* @dataProvider providerBackedEnumSuit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use EnumHelper\TestData\NotAnEnum;
use PHPUnit\Framework\TestCase;

class EnumSuitTest extends TestCase
class RestoreFromNameEnumSuitTest extends TestCase
{
/**
* @dataProvider providerEnumSuit
Expand All @@ -29,8 +29,9 @@ public function testBackedEnumThrowsExceptionFromInvalidName()

public function testFromNameThrowsExceptionIfNotEnum()
{
$fqClassName = NotAnEnum::class;
self::expectException(\Exception::class);
self::expectExceptionMessage('Undefined enum name');
self::expectExceptionMessage(sprintf('Class "%s" is not an enum', $fqClassName));

NotAnEnum::fromName('Mark');
}
Expand Down
32 changes: 32 additions & 0 deletions tests/src/ValidateNameInBackedEnumSuitTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace EnumHelper\Tests;

use EnumHelper\TestData\BackedEnumSuit;
use PHPUnit\Framework\TestCase;

class ValidateNameInBackedEnumSuitTest extends TestCase
{
/**
* @dataProvider providerBackedEnumSuit
*/
public function testBackedEnumValidateName(string $caseName, bool $validity)
{
$caseValidity = BackedEnumSuit::isValidCase($caseName);

self::assertSame($validity, $caseValidity);
}

public function providerBackedEnumSuit(): array
{
return [
[BackedEnumSuit::Clubs->name, true],
[BackedEnumSuit::Diamonds->name, true],
[BackedEnumSuit::Hearts->name, true],
[BackedEnumSuit::Spades->name, true],
[strtoupper(BackedEnumSuit::Hearts->name), false],
['NoTrumps', false],
['', false],
];
}
}
32 changes: 32 additions & 0 deletions tests/src/ValidateNameInEnumSuitTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace EnumHelper\Tests;

use EnumHelper\TestData\EnumSuit;
use PHPUnit\Framework\TestCase;

class ValidateNameInEnumSuitTest extends TestCase
{
/**
* @dataProvider providerEnumSuit
*/
public function testBackedEnumValidateName(string $caseName, bool $validity)
{
$caseValidity = EnumSuit::isValidCase($caseName);

self::assertSame($validity, $caseValidity);
}

public function providerEnumSuit(): array
{
return [
[EnumSuit::Clubs->name, true],
[EnumSuit::Diamonds->name, true],
[EnumSuit::Hearts->name, true],
[EnumSuit::Spades->name, true],
[strtoupper(EnumSuit::Hearts->name), false],
['NoTrumps', false],
['', false],
];
}
}

0 comments on commit 756973d

Please sign in to comment.