diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 17af793..701a8e3 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -5,14 +5,17 @@ on: push
jobs:
testing:
runs-on: ubuntu-latest
- container:
- image: lazerg/laravel:php81
+ strategy:
+ matrix:
+ php: ['8.1', '8.2', '8.3', '8.4', '8.5']
steps:
- - uses: actions/checkout@v1
+ - uses: actions/checkout@v4
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
with:
- fetch-depth: 1
- - name: install composer dependencies [by @lazerg]
- run: |
- composer install --no-scripts
- - name: Run Tests [by @lazerg]
- run: php -d memory_limit=2048M ./vendor/bin/pest
\ No newline at end of file
+ php-version: ${{ matrix.php }}
+ coverage: none
+ - name: Install composer dependencies
+ run: composer update --no-interaction --prefer-dist
+ - name: Run Tests
+ run: ./vendor/bin/pest
diff --git a/.gitignore b/.gitignore
index 0af3a88..0b0ba30 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@ vendor/
composer.lock
.phpunit.result.cache
+.phpunit.cache/
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000..0a5e6d8
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,90 @@
+# Laravel Enum Pro - Development Guide
+
+## Coding Rules
+
+### Performance First
+- Use native PHP functions (`array_column`, `array_map`, `array_combine`, `array_filter`, `array_keys`, `array_values`, `implode`, etc.) for better performance
+- Only use `Collection` when the method's return type requires it
+- Base methods should return arrays, Collection methods should wrap them with `collect()`
+
+### Method Organization
+Order methods from base (native PHP) to derived (Collection):
+1. `toArray()` methods first - use native PHP functions
+2. `toString()` methods - use native PHP with array methods
+3. Collection methods - wrap array methods with `collect()`
+4. Lookup methods last
+
+### Example Pattern
+```php
+// 1. Base method - native PHP
+public static function namesToArray(): array
+{
+ return array_column(self::cases(), 'name');
+}
+
+// 2. String method - uses base
+public static function namesToString(string $separator = ', '): string
+{
+ return implode($separator, self::namesToArray());
+}
+
+// 3. Collection method - wraps base
+public static function names(): Collection
+{
+ return collect(self::namesToArray());
+}
+```
+
+## Testing Rules
+
+### Use Pest with `it()` syntax
+- Use `it()` instead of `test()` for BDD-style readability
+- Start descriptions with "can" for success cases: `it('can get...')`
+- Start descriptions with "throws" for exception cases: `it('throws exception when...')`
+
+### Test Naming Convention
+```php
+// Success cases - describe capability
+it('can get all enum names as a collection', function () { ... });
+it('can get enum value by its name with case-insensitive lookup', function () { ... });
+
+// Exception cases - describe failure condition
+it('throws exception when requesting more random values than available', function () { ... });
+it('throws exception when calling non-existent case as static method', function () { ... });
+```
+
+### Best Practices
+- Chain expectations with `->and()` for multiple assertions
+- Keep test descriptions clear and specific
+- Describe what the method does, not how it does it
+- Include context (e.g., "as a collection", "as an array", "by its value")
+- Use `use Tests\DifficultyEnum;` at top of test files
+
+## Project Structure
+
+```
+src/
+├── EnumPro.php # Main trait (combines all)
+├── EnumNames.php # Name methods
+├── EnumValues.php # Value methods
+├── EnumOptions.php # Options/selections for forms
+├── EnumRandom.php # Random selection
+├── EnumStaticCalls.php # Magic methods
+└── Exceptions/
+ ├── UndefinedCaseException.php
+ └── TooManyRandomValuesException.php
+
+tests/
+├── DifficultyEnum.php # Test enum fixture
+├── EnumNamesTest.php
+├── EnumValuesTest.php
+├── EnumOptionsTest.php
+├── EnumRandomTest.php
+└── EnumStaticCallsTest.php
+```
+
+## Testing
+
+```bash
+./vendor/bin/pest
+```
diff --git a/README.md b/README.md
index 7000faa..6c881e3 100644
--- a/README.md
+++ b/README.md
@@ -3,20 +3,12 @@

[](https://packagist.org/packages/lazerg/laravel-enum-pro)
+[](https://packagist.org/packages/lazerg/laravel-enum-pro)
[](https://packagist.org/packages/lazerg/laravel-enum-pro)
-[](https://github.com/lazerg/laravel-enum-pro)
-[](https://github.com/lazerg/laravel-enum-pro)
+[](https://packagist.org/packages/lazerg/laravel-enum-pro)
[](https://packagist.org/packages/lazerg/laravel-enum-pro)
-`Laravel Enum Pro` is a simple trait that extends PHP 8.1+ enums with helpful utilities for Laravel applications. It lets you access enum data in a variety of convenient ways while keeping your code clean and expressive.
-
-## Features
-
-- Works directly with native PHP enums
-- Access case values via static method calls
-- Retrieve enum names and values as collections, arrays or strings
-- Generate random values for testing and factories
-- Build option and selection lists for form inputs
+A powerful trait that supercharges PHP 8.1+ enums with Laravel-friendly utilities. Get values, names, random cases, and form-ready options with a clean, fluent API.
## Installation
@@ -24,12 +16,10 @@
composer require lazerg/laravel-enum-pro
```
-## Basic Usage
-
-Create an enum and include the trait:
+## Enum Example
```php
-enum LevelTypes: int
+enum DifficultyEnum: int
{
use \Lazerg\LaravelEnumPro\EnumPro;
@@ -41,71 +31,102 @@ enum LevelTypes: int
}
```
-### Accessing Values
+## Accessing Value
```php
-LevelTypes::VERY_EASY(); // 1
-LevelTypes::valueOf('very easy'); // 1
+// 1
+DifficultyEnum::VERY_EASY();
+
+// 3
+DifficultyEnum::MEDIUM();
+
+// 5
+DifficultyEnum::VERY_STRONG();
+
+// 3
+$enum = DifficultyEnum::MEDIUM;
+$enum();
```
-### Working With Names
+## Accessing Name
```php
-LevelTypes::names(); // Collection: ['VERY_EASY', 'EASY', 'MEDIUM', 'STRONG', 'VERY_STRONG']
-LevelTypes::namesToArray(); // ['VERY_EASY', 'EASY', 'MEDIUM', 'STRONG', 'VERY_STRONG']
-LevelTypes::namesToString(); // "VERY_EASY, EASY, MEDIUM, STRONG, VERY_STRONG"
-LevelTypes::nameOf(1); // 'VERY_EASY'
+// ['VERY_EASY', 'EASY', 'MEDIUM', 'STRONG', 'VERY_STRONG']
+DifficultyEnum::namesToArray();
+
+// 'VERY_EASY, EASY, MEDIUM, STRONG, VERY_STRONG'
+DifficultyEnum::namesToString();
+
+// Collection(['VERY_EASY', 'EASY', 'MEDIUM', 'STRONG', 'VERY_STRONG'])
+DifficultyEnum::names();
+
+// 'MEDIUM'
+DifficultyEnum::nameOf(3);
```
-### Working With Values
+## Accessing Values
```php
-LevelTypes::values(); // Collection: [1, 2, 3, 4, 5]
-LevelTypes::valuesToArray(); // [1, 2, 3, 4, 5]
-LevelTypes::valuesToString(); // "1,2,3,4,5"
+// [1, 2, 3, 4, 5]
+DifficultyEnum::valuesToArray();
+
+// '1,2,3,4,5'
+DifficultyEnum::valuesToString();
+
+// Collection([1, 2, 3, 4, 5])
+DifficultyEnum::values();
+
+// 1
+DifficultyEnum::valueOf('VERY_EASY');
+
+// 3 (case-insensitive)
+DifficultyEnum::valueOf('medium');
+
+// 5 (spaces converted to underscores)
+DifficultyEnum::valueOf('Very strong');
```
-### Randomization
+## Accessing Options
```php
-LevelTypes::random(); // Collection with one random value
-LevelTypes::randomArray(); // Array with one random value
-LevelTypes::randomFirst(); // Single random value
-```
+// [1 => 'Very Easy', 2 => 'Easy', 3 => 'Medium', 4 => 'Strong', 5 => 'Very Strong']
+DifficultyEnum::optionsToArray();
-### Options and Selections
+// Collection([1 => 'Very Easy', 2 => 'Easy', 3 => 'Medium', 4 => 'Strong', 5 => 'Very Strong'])
+DifficultyEnum::options();
-Use these helpers when building form inputs.
+// 'Very Strong'
+DifficultyEnum::getOption(5);
-```php
-LevelTypes::options(); // Collection of [value => display]
-LevelTypes::optionsToArray();
-LevelTypes::selections(); // Collection of [value => ..., display => ...]
-LevelTypes::selectionsToArray();
+// ['Medium', 'Very Strong']
+DifficultyEnum::getOptions([3, 5]);
+
+// [['value' => 1, 'display' => 'Very Easy'], ['value' => 2, 'display' => 'Easy'], ...]
+DifficultyEnum::selectionsToArray();
+
+// Collection([['value' => 1, 'display' => 'Very Easy'], ['value' => 2, 'display' => 'Easy'], ...])
+DifficultyEnum::selections();
```
-Example output of `options()`:
+## Accessing Random Value
```php
-Illuminate\Support\Collection {
- #items: [
- 1 => "Very Easy",
- 2 => "Easy",
- 3 => "Medium",
- 4 => "Strong",
- 5 => "Very Strong",
- ]
-}
+// [3, 1] (random values)
+DifficultyEnum::randomArray(2);
+
+// 4 (single random value)
+DifficultyEnum::randomFirst();
+
+// Collection([2, 5, 1]) (random values)
+DifficultyEnum::random(3);
```
## Testing
-Run the test suite with [Pest](https://pestphp.com/):
-
```bash
./vendor/bin/pest
```
## License
-This package is open-sourced software licensed under the [MIT license](LICENSE) as specified in `composer.json`.
+This package is open-sourced software licensed under the [MIT license](LICENSE).
diff --git a/composer.json b/composer.json
index eee3190..bf9eeee 100644
--- a/composer.json
+++ b/composer.json
@@ -1,30 +1,44 @@
{
"name": "lazerg/laravel-enum-pro",
- "description": "Laravel Enum Pro",
+ "description": "A powerful PHP enum extension with collection support, random selection, and magic static calls",
"type": "library",
"license": "MIT",
+ "keywords": ["laravel", "enum", "php", "collection", "helper"],
+ "homepage": "https://github.com/lazerg/laravel-enum-pro",
"authors": [
{
"name": "lazerg",
"email": "lazerg2@gmail.com"
}
],
+ "support": {
+ "issues": "https://github.com/lazerg/laravel-enum-pro/issues",
+ "source": "https://github.com/lazerg/laravel-enum-pro"
+ },
"minimum-stability": "stable",
"require": {
- "php": "^8.1|^8.2|^8.3|^8.4",
- "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0"
+ "php": "^8.1",
+ "illuminate/support": "^9.0|^10.0|^11.0|^12.0"
},
"autoload": {
"psr-4": {
"Lazerg\\LaravelEnumPro\\": "src/"
}
},
+ "autoload-dev": {
+ "psr-4": {
+ "Tests\\": "tests/"
+ }
+ },
"require-dev": {
- "pestphp/pest": "^1.22|^2.0|^3.0"
+ "pestphp/pest": "^1.0|^2.0|^3.0"
},
"config": {
"allow-plugins": {
"pestphp/pest-plugin": true
}
+ },
+ "scripts": {
+ "test": "pest"
}
}
diff --git a/phpunit.xml b/phpunit.xml
index 8f4b58c..f22a919 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -3,16 +3,18 @@
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
+ cacheDirectory=".phpunit.cache"
+ stopOnFailure="false"
>
./tests
-
+
+
- ./app
./src
-
+
diff --git a/src/EnumNames.php b/src/EnumNames.php
index 46a72c2..adfcf9d 100644
--- a/src/EnumNames.php
+++ b/src/EnumNames.php
@@ -7,38 +7,62 @@
trait EnumNames
{
/**
- * Return all names of enum as collection
+ * Get all enum case names as an array.
+ *
+ * @return array
+ * @example DifficultyEnum::namesToArray()
+ * // ['VERY_EASY', 'EASY', 'MEDIUM', 'STRONG', 'VERY_STRONG']
*
- * @return Collection
*/
- public static function names(): Collection
+ public static function namesToArray(): array
{
- return collect(self::cases())
- ->map(fn($case) => $case->name);
+ return array_column(self::cases(), 'name');
}
/**
- * Return all names of enum as string separated by comma
+ * Get all enum case names as a string.
*
+ * @param string $separator
* @return string
+ * @example DifficultyEnum::namesToString()
+ * // 'VERY_EASY, EASY, MEDIUM, STRONG, VERY_STRONG'
+ *
+ * @example DifficultyEnum::namesToString(' | ')
+ * // 'VERY_EASY | EASY | MEDIUM | STRONG | VERY_STRONG'
+ *
*/
- public static function namesToString(): string
+ public static function namesToString(string $separator = ', '): string
{
- return self::names()->join(', ');
+ return implode($separator, self::namesToArray());
}
/**
- * Return all names of enum as array
+ * Get all enum case names as a Collection.
+ *
+ * @return Collection
+ * @example DifficultyEnum::names()
+ * // Collection(['VERY_EASY', 'EASY', 'MEDIUM', 'STRONG', 'VERY_STRONG'])
*
- * @return array
*/
- public static function namesToArray(): array
+ public static function names(): Collection
{
- return self::names()->toArray();
+ return collect(self::namesToArray());
}
- public static function nameOf(mixed $case): string
+ /**
+ * Get the enum case name by its value.
+ *
+ * @param mixed $value
+ * @return string|null
+ * @example DifficultyEnum::nameOf(3)
+ * // 'MEDIUM'
+ *
+ * @example DifficultyEnum::nameOf(99)
+ * // null
+ *
+ */
+ public static function nameOf(mixed $value): ?string
{
- return array_column(self::cases(), 'name', 'value')[$case];
+ return array_column(self::cases(), 'name', 'value')[$value] ?? null;
}
}
diff --git a/src/EnumOptions.php b/src/EnumOptions.php
index 4b3576e..dc9c3a2 100644
--- a/src/EnumOptions.php
+++ b/src/EnumOptions.php
@@ -3,103 +3,103 @@
namespace Lazerg\LaravelEnumPro;
use Illuminate\Support\Collection;
-use Illuminate\Support\Str;
-use UnitEnum;
trait EnumOptions
{
/**
- * Convert cases of enum to collection of options
+ * Get all enum cases as key-value array with formatted labels.
*
- * @input
- * case RENTAL_TRUCK = 1;
- * case CONTAINER = 2;
- * case FREIGHT_TRAILER = 3;
+ * @return array
+ * @example DifficultyEnum::optionsToArray()
+ * // [1 => 'Very Easy', 2 => 'Easy', 3 => 'Medium', 4 => 'Strong', 5 => 'Very Strong']
*
- * @output
- * [
- * 1 => "Rental Truck"
- * 2 => "Container"
- * 3 => "Freight Trailer"
- * ]
- *
- * @return Collection
*/
- public static function options(): Collection
+ public static function optionsToArray(): array
{
- return collect(self::cases())->mapWithKeys(fn(UnitEnum $enum) => [
- $enum->value => Str::of($enum->name)
- ->replace('_', ' ')
- ->title()
- ->value()
- ]);
+ return array_combine(
+ array_column(self::cases(), 'value'),
+ array_map(fn($case) => ucwords(strtolower(str_replace('_', ' ', $case->name))), self::cases())
+ );
}
/**
- * Get a value of an option
+ * Get all enum cases as a Collection with formatted labels.
+ *
+ * @return Collection
+ * @example DifficultyEnum::options()
+ * // Collection([1 => 'Very Easy', 2 => 'Easy', 3 => 'Medium', 4 => 'Strong', 5 => 'Very Strong'])
*
- * @param string $value
- * @return string
*/
- public static function getOption(string $value): string
+ public static function options(): Collection
{
- return self::options()[$value];
+ return collect(self::optionsToArray());
}
/**
- * Get values of options
+ * Get a single option label by its value.
+ *
+ * @param mixed $value
+ * @return string|null
+ * @example DifficultyEnum::getOption(5)
+ * // 'Very Strong'
+ *
+ * @example DifficultyEnum::getOption(99)
+ * // null
*
- * @param array $values
- * @return Collection
*/
- public static function getOptions(array $values): Collection
+ public static function getOption(mixed $value): ?string
{
- return self::options()
- ->filter(fn($value, $key) => in_array($key, $values))
- ->values();
+ return self::optionsToArray()[$value] ?? null;
}
/**
- * Convert cases of enum to collection of selections
- *
- * @input
- * case RENTAL_TRUCK = 1;
- * case CONTAINER = 2;
- * case FREIGHT_TRAILER = 3;
+ * Get multiple option labels by their values.
*
- * @output
- * [
- * 0 => ['value' => 1, 'display' => 'Rental Truck'],
- * 1 => ['value' => 2, 'display' => 'Container'],
- * 3 => ['value' => 3, 'display' => 'Freight Trailer']
- * ]
+ * @param array $values
+ * @return array
+ * @example DifficultyEnum::getOptions([3, 5])
+ * // ['Medium', 'Very Strong']
*
- * @return Collection
*/
- public static function selections(): Collection
+ public static function getOptions(array $values): array
{
- return self::options()
- ->map(fn($display, $value) => compact('value', 'display'))
- ->values();
+ return array_values(array_intersect_key(self::optionsToArray(), array_flip($values)));
}
/**
- * Convert cases of enum to array of options
+ * Get all enum cases as array of selections for form inputs.
+ *
+ * @return array
+ * @example DifficultyEnum::selectionsToArray()
+ * // [
+ * // ['value' => 1, 'display' => 'Very Easy'],
+ * // ['value' => 2, 'display' => 'Easy'],
+ * // ['value' => 3, 'display' => 'Medium'],
+ * // ['value' => 4, 'display' => 'Strong'],
+ * // ['value' => 5, 'display' => 'Very Strong'],
+ * // ]
*
- * @return array
*/
- public static function optionsToArray(): array
+ public static function selectionsToArray(): array
{
- return self::options()->toArray();
+ $options = self::optionsToArray();
+ return array_map(fn($value) => ['value' => $value, 'display' => $options[$value]], array_keys($options));
}
/**
- * Convert cases of enum to array of selections
+ * Get all enum cases as Collection of selections for form inputs.
+ *
+ * @return Collection
+ * @example DifficultyEnum::selections()
+ * // Collection([
+ * // ['value' => 1, 'display' => 'Very Easy'],
+ * // ['value' => 2, 'display' => 'Easy'],
+ * // ...
+ * // ])
*
- * @return array
*/
- public static function selectionsToArray(): array
+ public static function selections(): Collection
{
- return self::selections()->toArray();
+ return collect(self::selectionsToArray());
}
}
diff --git a/src/EnumPro.php b/src/EnumPro.php
index f0feda0..e4ff2ee 100644
--- a/src/EnumPro.php
+++ b/src/EnumPro.php
@@ -2,6 +2,26 @@
namespace Lazerg\LaravelEnumPro;
+/**
+ * Supercharge PHP 8.1+ enums with Laravel-friendly utilities.
+ *
+ * @example enum DifficultyEnum: int
+ * {
+ * use \Lazerg\LaravelEnumPro\EnumPro;
+ *
+ * case VERY_EASY = 1;
+ * case EASY = 2;
+ * case MEDIUM = 3;
+ * case STRONG = 4;
+ * case VERY_STRONG = 5;
+ * }
+ *
+ * @see EnumStaticCalls For accessing values: DifficultyEnum::MEDIUM() // 3
+ * @see EnumNames For accessing names: DifficultyEnum::namesToArray() // ['VERY_EASY', ...]
+ * @see EnumValues For accessing values: DifficultyEnum::valuesToArray() // [1, 2, 3, 4, 5]
+ * @see EnumOptions For form options: DifficultyEnum::optionsToArray() // [1 => 'Very Easy', ...]
+ * @see EnumRandom For random values: DifficultyEnum::randomFirst() // 3 (random)
+ */
trait EnumPro
{
use EnumValues,
diff --git a/src/EnumRandom.php b/src/EnumRandom.php
index 0b910a9..bc32196 100644
--- a/src/EnumRandom.php
+++ b/src/EnumRandom.php
@@ -3,43 +3,57 @@
namespace Lazerg\LaravelEnumPro;
use Illuminate\Support\Collection;
-use InvalidArgumentException;
+use Lazerg\LaravelEnumPro\Exceptions\TooManyRandomValuesException;
trait EnumRandom
{
/**
- * Get $count random values in collection
+ * Get random enum values as an array.
*
* @param int $count
- * @return Collection
+ * @return array
+ * @throws TooManyRandomValuesException When requesting more values than available
+ * @example DifficultyEnum::randomArray(2)
+ * // [3, 1] (random)
+ *
*/
- public static function random(int $count = 1): Collection
+ public static function randomArray(int $count = 1): array
{
- if ($count > self::values()->count()) {
- throw new InvalidArgumentException('Count of random values is greater than count of enum values');
+ $values = self::valuesToArray();
+
+ if ($count > count($values)) {
+ throw new TooManyRandomValuesException($count, count($values));
}
- return self::values()->shuffle()->take($count);
+ $keys = array_rand($values, $count);
+ return array_map(fn($key) => $values[$key], (array) $keys);
}
/**
- * Get one random value
+ * Get a single random enum value.
*
* @return int|string
+ * @example DifficultyEnum::randomFirst()
+ * // 4 (random)
+ *
*/
public static function randomFirst(): int|string
{
- return self::random()->first();
+ return self::randomArray()[0];
}
/**
- * Get $count random values in array
+ * Get random enum values as a Collection.
*
* @param int $count
- * @return array
+ * @return Collection
+ * @throws TooManyRandomValuesException When requesting more values than available
+ * @example DifficultyEnum::random(3)
+ * // Collection([2, 5, 1]) (random)
+ *
*/
- public static function randomArray(int $count = 1): array
+ public static function random(int $count = 1): Collection
{
- return self::random($count)->toArray();
+ return collect(self::randomArray($count));
}
}
diff --git a/src/EnumStaticCalls.php b/src/EnumStaticCalls.php
index f379bd6..554f985 100644
--- a/src/EnumStaticCalls.php
+++ b/src/EnumStaticCalls.php
@@ -2,31 +2,44 @@
namespace Lazerg\LaravelEnumPro;
-use Exception;
-use UnitEnum;
+use Lazerg\LaravelEnumPro\Exceptions\UndefinedCaseException;
trait EnumStaticCalls
{
/**
+ * Get the enum value by invoking the instance.
+ *
* @return int|string
+ * @example $enum = DifficultyEnum::MEDIUM;
+ * $enum();
+ * // 3
+ *
*/
public function __invoke(): int|string
{
- /** @type UnitEnum $this */
return $this->value ?? $this->name;
}
/**
- * @throws Exception
+ * Get the enum value using static method call with case name.
+ *
+ * @param string $name
+ * @param array $arguments
+ * @return int|string
+ * @throws UndefinedCaseException When case name does not exist
+ * @example DifficultyEnum::VERY_EASY()
+ * // 1
+ *
+ * @example DifficultyEnum::MEDIUM()
+ * // 3
+ *
+ * @example DifficultyEnum::VERY_STRONG()
+ * // 5
+ *
*/
public static function __callStatic(string $name, array $arguments): int|string
{
- foreach (self::cases() as $case) {
- if ($case->name === $name) {
- return $case->value;
- }
- }
-
- throw new Exception("Case with name $name does not exist");
+ return array_column(self::cases(), 'value', 'name')[$name]
+ ?? throw new UndefinedCaseException($name);
}
}
diff --git a/src/EnumValues.php b/src/EnumValues.php
index 7149681..37b96ad 100644
--- a/src/EnumValues.php
+++ b/src/EnumValues.php
@@ -3,57 +3,73 @@
namespace Lazerg\LaravelEnumPro;
use Illuminate\Support\Collection;
-use Illuminate\Support\Str;
trait EnumValues
{
/**
- * Return all values of enum as collection
+ * Get all enum case values as an array.
+ *
+ * @return array
+ * @example DifficultyEnum::valuesToArray()
+ * // [1, 2, 3, 4, 5]
*
- * @return Collection
*/
- public static function values(): Collection
+ public static function valuesToArray(): array
{
- return collect(self::cases())
- ->map(fn($case) => $case->value ?? $case->name);
+ return array_column(self::cases(), 'value') ?: array_column(self::cases(), 'name');
}
/**
- * Return all values of enum as string separated by comma
+ * Get all enum case values as a string.
*
+ * @param string $separator
* @return string
+ * @example DifficultyEnum::valuesToString()
+ * // '1,2,3,4,5'
+ *
+ * @example DifficultyEnum::valuesToString(' | ')
+ * // '1 | 2 | 3 | 4 | 5'
+ *
*/
- public static function valuesToString(): string
+ public static function valuesToString(string $separator = ','): string
{
- return self::values()->join(',');
+ return implode($separator, self::valuesToArray());
}
/**
- * Return all values of enum as array
+ * Get all enum case values as a Collection.
+ *
+ * @return Collection
+ * @example DifficultyEnum::values()
+ * // Collection([1, 2, 3, 4, 5])
*
- * @return array
*/
- public static function valuesToArray(): array
+ public static function values(): Collection
{
- return self::values()->toArray();
+ return collect(self::valuesToArray());
}
/**
- * Return value of enum by name
+ * Get the enum case value by its name (case-insensitive, spaces become underscores).
*
* @param string $name
* @return int|string|null
+ * @example DifficultyEnum::valueOf('Very Strong')
+ * // 5
+ *
+ * @example DifficultyEnum::valueOf('invalid')
+ * // null
+ *
+ * @example DifficultyEnum::valueOf('VERY_EASY')
+ * // 1
+ *
+ * @example DifficultyEnum::valueOf('medium')
+ * // 3
+ *
*/
public static function valueOf(string $name): null|int|string
{
- $name = Str::replace(' ', '_', Str::upper($name));
-
- foreach (self::cases() as $case) {
- if ($case->name === $name) {
- return $case->value;
- }
- }
-
- return null;
+ $name = strtoupper(str_replace(' ', '_', $name));
+ return array_column(self::cases(), 'value', 'name')[$name] ?? null;
}
}
diff --git a/src/Exceptions/TooManyRandomValuesException.php b/src/Exceptions/TooManyRandomValuesException.php
new file mode 100644
index 0000000..01e5477
--- /dev/null
+++ b/src/Exceptions/TooManyRandomValuesException.php
@@ -0,0 +1,13 @@
+toBeInstanceOf(\Illuminate\Support\Collection::class);
});
-test('Get name of enums', function () {
- expect(LevelTypes::namesToArray())
- ->toBe([
- 0 => 'VERY_EASY',
- 1 => 'EASY',
- 2 => 'MEDIUM',
- 3 => 'STRONG',
- 4 => 'VERY_STRONG'
- ]);
+it('can get all enum names as an array', function () {
+ expect(DifficultyEnum::namesToArray())
+ ->toBe(['VERY_EASY', 'EASY', 'MEDIUM', 'STRONG', 'VERY_STRONG']);
});
-test('Get name of enums as string', function () {
- expect(LevelTypes::names()->implode(', '))
+it('can get all enum names as a comma-separated string', function () {
+ expect(DifficultyEnum::namesToString())
->toBe('VERY_EASY, EASY, MEDIUM, STRONG, VERY_STRONG');
});
-test('Get name of enum', function () {
- expect(LevelTypes::nameOf(LevelTypes::MEDIUM()))
+it('can get enum name by its value', function () {
+ expect(DifficultyEnum::nameOf(DifficultyEnum::MEDIUM()))
->toBe('MEDIUM');
-});
\ No newline at end of file
+});
diff --git a/tests/EnumOptionsTest.php b/tests/EnumOptionsTest.php
index 9ad8994..3f432ff 100644
--- a/tests/EnumOptionsTest.php
+++ b/tests/EnumOptionsTest.php
@@ -1,58 +1,43 @@
toBeInstanceOf(\Illuminate\Support\Collection::class);
});
-test('Get options of enum as array', function () {
- expect(LevelTypes::optionsToArray())->tobe([
- 1 => "Very Easy",
- 2 => "Easy",
- 3 => "Medium",
- 4 => "Strong",
- 5 => "Very Strong"
+it('can get all enum options as key-value array with formatted labels', function () {
+ expect(DifficultyEnum::optionsToArray())->toBe([
+ 1 => 'Very Easy',
+ 2 => 'Easy',
+ 3 => 'Medium',
+ 4 => 'Strong',
+ 5 => 'Very Strong',
]);
});
-test('Get a single options of enum', function () {
- expect(LevelTypes::getOption(LevelTypes::VERY_STRONG()))
+it('can get a single option label by its value', function () {
+ expect(DifficultyEnum::getOption(DifficultyEnum::VERY_STRONG()))
->toBe('Very Strong');
});
-test('Get multiple options of enum', function () {
- $options = LevelTypes::getOptions([
- LevelTypes::MEDIUM(),
- LevelTypes::VERY_STRONG()
- ]);
-
- expect($options->toArray())
- ->toBe([
- "Medium",
- "Very Strong"
- ]);
+it('can get multiple option labels by their values', function () {
+ expect(DifficultyEnum::getOptions([DifficultyEnum::MEDIUM(), DifficultyEnum::VERY_STRONG()]))
+ ->toBe(['Medium', 'Very Strong']);
});
-test('Get selection of enums as collection', function () {
- expect(LevelTypes::selections())
+it('can get all enum selections as a collection for form inputs', function () {
+ expect(DifficultyEnum::selections())
->toBeInstanceOf(\Illuminate\Support\Collection::class);
});
-test('Get selection of enums as array', function () {
- expect(LevelTypes::selectionsToArray())->tobe([[
- "value" => 1,
- "display" => "Very Easy"
- ], [
- "value" => 2,
- "display" => "Easy"
- ], [
- "value" => 3,
- "display" => "Medium"
- ], [
- "value" => 4,
- "display" => "Strong"
- ], [
- "value" => 5,
- "display" => "Very Strong"
- ]]);
-});
\ No newline at end of file
+it('can get all enum selections as array with value and display keys', function () {
+ expect(DifficultyEnum::selectionsToArray())->toBe([
+ ['value' => 1, 'display' => 'Very Easy'],
+ ['value' => 2, 'display' => 'Easy'],
+ ['value' => 3, 'display' => 'Medium'],
+ ['value' => 4, 'display' => 'Strong'],
+ ['value' => 5, 'display' => 'Very Strong'],
+ ]);
+});
diff --git a/tests/EnumRandomTest.php b/tests/EnumRandomTest.php
new file mode 100644
index 0000000..8526bab
--- /dev/null
+++ b/tests/EnumRandomTest.php
@@ -0,0 +1,28 @@
+toBeInstanceOf(\Illuminate\Support\Collection::class);
+});
+
+it('can get a specific count of random enum values', function () {
+ expect(DifficultyEnum::random(3))
+ ->toHaveCount(3);
+});
+
+it('can get a single random enum value', function () {
+ expect(DifficultyEnum::randomFirst())
+ ->toBeIn([1, 2, 3, 4, 5]);
+});
+
+it('can get random enum values as an array', function () {
+ expect(DifficultyEnum::randomArray(2))
+ ->toBeArray()
+ ->toHaveCount(2);
+});
+
+it('throws exception when requesting more random values than available', function () {
+ DifficultyEnum::random(10);
+})->throws(\Lazerg\LaravelEnumPro\Exceptions\TooManyRandomValuesException::class);
diff --git a/tests/EnumStaticCallsTest.php b/tests/EnumStaticCallsTest.php
new file mode 100644
index 0000000..ebf9cd7
--- /dev/null
+++ b/tests/EnumStaticCallsTest.php
@@ -0,0 +1,22 @@
+toBe(1)
+ ->and(DifficultyEnum::MEDIUM())->toBe(3)
+ ->and(DifficultyEnum::VERY_STRONG())->toBe(5);
+});
+
+it('throws exception when calling non-existent case as static method', function () {
+ DifficultyEnum::NON_EXISTENT();
+})->throws(
+ \Lazerg\LaravelEnumPro\Exceptions\UndefinedCaseException::class,
+ 'Case with name NON_EXISTENT does not exist'
+);
+
+it('can get enum value by invoking the enum instance', function () {
+ $enum = DifficultyEnum::MEDIUM;
+
+ expect($enum())->toBe(3);
+});
diff --git a/tests/EnumTest.php b/tests/EnumTest.php
deleted file mode 100644
index f8f36b5..0000000
--- a/tests/EnumTest.php
+++ /dev/null
@@ -1,21 +0,0 @@
-toBeInstanceOf(\Illuminate\Support\Collection::class);
-});
+use Tests\DifficultyEnum;
-test('Get values of enum as string', function () {
- expect(LevelTypes::valuesToString())
- ->toBe('1,2,3,4,5');
+it('can get all enum values as a collection', function () {
+ expect(DifficultyEnum::values())
+ ->toBeInstanceOf(\Illuminate\Support\Collection::class);
});
-test('Get values of enum as array', function () {
- expect(LevelTypes::valuesToArray())
+it('can get all enum values as an array', function () {
+ expect(DifficultyEnum::valuesToArray())
->toBe([1, 2, 3, 4, 5]);
});
-test('Get value of enum', function () {
- expect(LevelTypes::valueOf('VERY_EASY'))
- ->toBe(1);
-
- expect(LevelTypes::valueOf('medium'))
- ->toBe(3);
-
- expect(LevelTypes::valueOf('Very strong'))
- ->toBe(5);
+it('can get all enum values as a comma-separated string', function () {
+ expect(DifficultyEnum::valuesToString())
+ ->toBe('1,2,3,4,5');
+});
- expect(LevelTypes::valueOf('Not found'))
- ->toBeNull();
-});
\ No newline at end of file
+it('can get enum value by its name with case-insensitive lookup', function () {
+ expect(DifficultyEnum::valueOf('VERY_EASY'))->toBe(1)
+ ->and(DifficultyEnum::valueOf('medium'))->toBe(3)
+ ->and(DifficultyEnum::valueOf('Very strong'))->toBe(5)
+ ->and(DifficultyEnum::valueOf('Not found'))->toBeNull();
+});