* SPDX-License-Identifier: MIT */ declare(strict_types=1); namespace Respect\Validation; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\Attributes\Test; use Respect\Validation\Exceptions\ComponentException; use Respect\Validation\Exceptions\InvalidClassException; use Respect\Validation\Test\Rules\Invalid; use Respect\Validation\Test\Rules\MyAbstractClass; use Respect\Validation\Test\Rules\Stub; use Respect\Validation\Test\Rules\Valid; use Respect\Validation\Test\TestCase; use function assert; use function sprintf; #[Group('core')] #[CoversClass(Factory::class)] final class FactoryTest extends TestCase { private const string TEST_RULES_NAMESPACE = 'Respect\\Validation\\Test\\Rules'; #[Test] public function shouldCreateRuleByNameBasedOnNamespace(): void { $factory = (new Factory()) ->withRuleNamespace(self::TEST_RULES_NAMESPACE); self::assertInstanceOf(Valid::class, $factory->rule('valid')); } #[Test] public function shouldLookUpToAllNamespacesUntilRuleIsFound(): void { $factory = (new Factory()) ->withRuleNamespace(__NAMESPACE__) ->withRuleNamespace(self::TEST_RULES_NAMESPACE); self::assertInstanceOf(Valid::class, $factory->rule('valid')); } #[Test] public function shouldDefineConstructorArgumentsWhenCreatingRule(): void { $constructorArguments = [true, false, true, false]; $factory = (new Factory())->withRuleNamespace(self::TEST_RULES_NAMESPACE); $rule = $factory->rule('stub', $constructorArguments); assert($rule instanceof Stub); self::assertSame($constructorArguments, $rule->validations); } #[Test] public function shouldThrowsAnExceptionWhenRuleIsInvalid(): void { $factory = (new Factory())->withRuleNamespace(self::TEST_RULES_NAMESPACE); $this->expectException(InvalidClassException::class); $this->expectExceptionMessage(sprintf('"%s" must be an instance of "%s"', Invalid::class, Rule::class)); $factory->rule('invalid'); } #[Test] public function shouldThrowsAnExceptionWhenRuleIsNotInstantiable(): void { $factory = (new Factory())->withRuleNamespace(self::TEST_RULES_NAMESPACE); $this->expectException(InvalidClassException::class); $this->expectExceptionMessage(sprintf('"%s" must be instantiable', MyAbstractClass::class)); $factory->rule('myAbstractClass'); } #[Test] public function shouldThrowsAnExceptionWhenRuleIsNotFound(): void { $factory = (new Factory())->withRuleNamespace(self::TEST_RULES_NAMESPACE); $this->expectException(ComponentException::class); $this->expectExceptionMessage('"nonExistingRule" is not a valid rule name'); $factory->rule('nonExistingRule'); } }