Skip to content

Commit

Permalink
update: added enum support for defined rule set names
Browse files Browse the repository at this point in the history
  • Loading branch information
erik-perri committed Jun 11, 2024
1 parent 6c8d6cb commit 945ae30
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 10 deletions.
6 changes: 4 additions & 2 deletions src/Contracts/DefinedRuleSets.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@

namespace Sourcetoad\RuleHelper\Contracts;

use BackedEnum;
use Sourcetoad\RuleHelper\RuleSet;
use UnitEnum;

interface DefinedRuleSets
{
public function define(string $name, RuleSet $ruleSet): void;
public function define(string|BackedEnum|UnitEnum $name, RuleSet $ruleSet): void;

public function useDefined(string $name): RuleSet;
public function useDefined(string|BackedEnum|UnitEnum $name): RuleSet;
}
33 changes: 27 additions & 6 deletions src/DefinedRuleSets.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,43 @@

namespace Sourcetoad\RuleHelper;

use BackedEnum;
use InvalidArgumentException;
use UnitEnum;

class DefinedRuleSets implements Contracts\DefinedRuleSets
{
/** @var array<string, RuleSet> */
private array $definedRules = [];

public function define(string $name, RuleSet $ruleSet): void
public function define(string|BackedEnum|UnitEnum $name, RuleSet $ruleSet): void
{
$key = $this->getKey($name);

$this->definedRules[$key] = $ruleSet;
}

public function useDefined(string|BackedEnum|UnitEnum $name): RuleSet
{
$this->definedRules[$name] = $ruleSet;
$key = $this->getKey($name);

if (!array_key_exists($key, $this->definedRules)) {
throw new InvalidArgumentException('No rule defined with name '.$key);
}

return $this->definedRules[$key];
}

public function useDefined(string $name): RuleSet
private function getKey(string|BackedEnum|UnitEnum $value): string
{
if (!array_key_exists($name, $this->definedRules)) {
throw new \InvalidArgumentException('No rule defined with name '.$name);
if ($value instanceof UnitEnum) {
return sprintf(
'%s::%s',
$value::class,
$value instanceof BackedEnum ? $value->value : $value->name,
);
}

return $this->definedRules[$name];
return $value;
}
}
4 changes: 2 additions & 2 deletions src/RuleSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,15 @@ public static function create(array $rules = []): self
/**
* Defines a rule set to be re-used later.
*/
public static function define(string $name, RuleSet $ruleSet): void
public static function define(string|BackedEnum|UnitEnum $name, RuleSet $ruleSet): void
{
static::getDefinedRuleSets()->define($name, $ruleSet);
}

/**
* Uses a previously defined rule set.
*/
public static function useDefined(string $name): RuleSet
public static function useDefined(string|BackedEnum|UnitEnum $name): RuleSet
{
return static::getDefinedRuleSets()->useDefined($name);
}
Expand Down
10 changes: 10 additions & 0 deletions tests/Stubs/ExampleNonBackedEnum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Sourcetoad\RuleHelper\Tests\Stubs;

enum ExampleNonBackedEnum
{
case Value;
}
10 changes: 10 additions & 0 deletions tests/Stubs/ExampleStringDuplicateEnum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Sourcetoad\RuleHelper\Tests\Stubs;

enum ExampleStringDuplicateEnum: string
{
case Another = 'another';
}
30 changes: 30 additions & 0 deletions tests/Unit/DefinedRuleSetsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
use Sourcetoad\RuleHelper\Contracts\DefinedRuleSets;
use Sourcetoad\RuleHelper\RuleHelperServiceProvider;
use Sourcetoad\RuleHelper\RuleSet;
use Sourcetoad\RuleHelper\Tests\Stubs\ExampleNonBackedEnum;
use Sourcetoad\RuleHelper\Tests\Stubs\ExampleStringDuplicateEnum;
use Sourcetoad\RuleHelper\Tests\Stubs\ExampleStringEnum;
use Sourcetoad\RuleHelper\Tests\TestCase;

class DefinedRuleSetsTest extends TestCase
Expand Down Expand Up @@ -88,4 +91,31 @@ public function testConcatDefinedRuleSet(): void
// Assert
$this->assertSame(['required', 'email'], $ruleSet->toArray());
}

public function testWorksWithNonBackedEnums(): void
{
// Arrange
RuleSet::define(ExampleNonBackedEnum::Value, RuleSet::create()->email());

// Act
$ruleSet = RuleSet::useDefined(ExampleNonBackedEnum::Value);

// Assert
$this->assertSame(['email'], $ruleSet->toArray());
}

public function testDefinedEnumsWithDuplicateValuesAreTreatedAsDifferent(): void
{
// Arrange
RuleSet::define(ExampleStringEnum::Another, RuleSet::create()->email());
RuleSet::define(ExampleStringDuplicateEnum::Another, RuleSet::create()->required());

// Act
$ruleSetOne = RuleSet::useDefined(ExampleStringEnum::Another);
$ruleSetTwo = RuleSet::useDefined(ExampleStringDuplicateEnum::Another);

// Assert
$this->assertSame(['email'], $ruleSetOne->toArray());
$this->assertSame(['required'], $ruleSetTwo->toArray());
}
}

0 comments on commit 945ae30

Please sign in to comment.