diff --git a/.phpstan.neon b/.phpstan.neon index 4d23eabe..cad20e76 100644 --- a/.phpstan.neon +++ b/.phpstan.neon @@ -20,3 +20,10 @@ parameters: - message: '~Call to an undefined method .+::children\(\)\.~' path: "src/Bridges/SymfonyBundle/DependencyInjection/Configuration.php" + - + message: '~Class BackedEnum not found\.~' + path: "src/SqlProcessor.php" + - + message: '~Access to property \$value on an unknown class BackedEnum\.~' + path: "src/SqlProcessor.php" + diff --git a/composer.json b/composer.json index 1e4a3e50..3dba3751 100644 --- a/composer.json +++ b/composer.json @@ -42,5 +42,10 @@ "branch-alias": { "dev-master": "4.0-dev" } + }, + "config": { + "allow-plugins": { + "phpstan/extension-installer": true + } } } diff --git a/src/SqlProcessor.php b/src/SqlProcessor.php index 003f210b..e66d6ed2 100644 --- a/src/SqlProcessor.php +++ b/src/SqlProcessor.php @@ -148,6 +148,10 @@ function ($matches) use ($args, &$j, $last): string { */ public function processModifier(string $type, $value): string { + if ($value instanceof \BackedEnum) { + $value = $value->value; + } + switch (gettype($value)) { case 'string': switch ($type) { diff --git a/tests/cases/unit/SqlProcessorTest.backed_enum.phpt b/tests/cases/unit/SqlProcessorTest.backed_enum.phpt new file mode 100644 index 00000000..74fdfb7d --- /dev/null +++ b/tests/cases/unit/SqlProcessorTest.backed_enum.phpt @@ -0,0 +1,139 @@ += 8.1 + */ + +namespace NextrasTests\Dbal; + + +use Mockery; +use Nextras\Dbal\Drivers\IDriver; +use Nextras\Dbal\Exception\InvalidArgumentException; +use Nextras\Dbal\Platforms\IPlatform; +use Nextras\Dbal\SqlProcessor; +use Tester\Assert; + + +require_once __DIR__ . '/../../bootstrap.php'; + + +enum DirectionEnum: string +{ + case LEFT = 'left'; + case RIGHT = 'right'; +} + + +enum BinaryEnum: int +{ + case ZERO = 0; + case ONE = 1; +} + + +class SqlProcessorBackedEnumTest extends TestCase +{ + /** @var IPlatform|Mockery\MockInterface */ + private $platform; + + /** @var IDriver|Mockery\MockInterface */ + private $driver; + + /** @var SqlProcessor */ + private $parser; + + + protected function setUp() + { + parent::setUp(); + $this->driver = Mockery::mock(IDriver::class); + $this->platform = \Mockery::mock(IPlatform::class); + $this->parser = new SqlProcessor($this->driver, $this->platform); + } + + + public function testString() + { + $cases = DirectionEnum::cases(); + foreach ($cases as $case) { + $this->driver->shouldReceive('convertStringToSql')->once()->with($case->value)->andReturn('hit'); + Assert::same('hit', $this->parser->processModifier('s', $case)); + } + + $cases = BinaryEnum::cases(); + foreach ($cases as $case) { + Assert::exception( + function () use ($case) { + $this->parser->processModifier('s', $case); + }, + InvalidArgumentException::class, + 'Modifier %s expects value to be string, integer given.' + ); + } + + } + + + public function testStringArray() + { + + $cases = DirectionEnum::cases(); + $this->driver->shouldReceive('convertStringToSql')->times(count($cases)) + ->andReturnArg(0); + Assert::same('(left, right)', $this->parser->processModifier('s[]', $cases)); + + Assert::exception( + function () { + $cases = BinaryEnum::cases(); + $this->parser->processModifier('s[]', $cases); + }, + InvalidArgumentException::class, + 'Modifier %s expects value to be string, integer given.' + ); + + } + + + public function testInt() + { + $cases = DirectionEnum::cases(); + foreach ($cases as $case) { + Assert::exception( + function () use ($case) { + $this->parser->processModifier('i', $case); + }, + InvalidArgumentException::class, + 'Modifier %i expects value to be int, string given.' + ); + } + + $cases = BinaryEnum::cases(); + foreach ($cases as $case) { + Assert::same((string) $case->value, $this->parser->processModifier('i', $case)); + } + + } + + + public function testIntArray() + { + $cases = DirectionEnum::cases(); + Assert::exception( + function () use ($cases) { + $this->parser->processModifier('i[]', $cases); + }, + InvalidArgumentException::class, + 'Modifier %i expects value to be int, string given.' + ); + + $cases = BinaryEnum::cases(); + Assert::same('(0, 1)', $this->parser->processModifier('i[]', $cases)); + + } +} + + +$test = new SqlProcessorBackedEnumTest(); +$test->run();