Skip to content

Commit

Permalink
Fix issue with special characters in constant/enum-case names
Browse files Browse the repository at this point in the history
  • Loading branch information
sunkan committed Jan 10, 2025
1 parent 31508b8 commit 91b3fba
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/PhpConstant.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public function getName(): string
$currentName = $this->identifier;
$sanitizedName = (string)preg_replace('/^(\d)/', '_$0', $currentName);
$sanitizedName = str_replace('-', '_', $sanitizedName);
$sanitizedName = (string)preg_replace('/[^A-Za-z0-9_]/', '_s_', $sanitizedName);

if ($this->case === self::CASE_NONE) {
return $sanitizedName;
Expand Down
5 changes: 3 additions & 2 deletions src/Renderer/Php7Renderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,9 @@ public function renderEnum(PhpEnum $enum): array

foreach ($enum->getCases() as $case) {
$value = $case instanceof EnumBackedCase ? $case->getValue() : null;
$enum->addConstant(PhpConstant::public($case->getName(), $value)->setCase(PhpConstant::CASE_NONE));
$tryFromCtorSource[] = 'if ($value === self::' . $case->getName() . ') {';
$const = PhpConstant::public($case->getName(), $value)->setCase(PhpConstant::CASE_NONE);
$enum->addConstant($const);
$tryFromCtorSource[] = 'if ($value === self::' . $const->getName() . ') {';
$tryFromCtorSource[] = ['return new self($value);'];
$tryFromCtorSource[] = '}';
}
Expand Down
8 changes: 7 additions & 1 deletion src/ValueObject/EnumCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ public function __construct(

public function getName(): string
{
return $this->name;
$currentName = $this->name;
$sanitizedName = str_replace('-', '_', $currentName);
$sanitizedName = str_replace(' ', '', ucwords(str_replace('_', ' ', $sanitizedName)));
$sanitizedName = (string)preg_replace('/[^A-Za-z0-9_]/', '_s_', $sanitizedName);
$sanitizedName = (string)preg_replace('/^(\d)/', '_$0', $sanitizedName);

return $sanitizedName;
}
}
8 changes: 8 additions & 0 deletions tests/Renderer/PhpConstantTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,12 @@ public function testUpperCaseWithLeadingDigit(): void

$this->assertSame(['public const _3DS = \'3DS\';'], $render->renderConstant($const));
}

public function testSanitizeConstNameFromSpecialCharacters(): void
{
$const = PhpConstant::public(identifier: '>2m');
$render = new Php7Renderer();

$this->assertSame(['public const _S_2M = \'>2m\';'], $render->renderConstant($const));
}
}
33 changes: 33 additions & 0 deletions tests/Renderer/PhpEnumTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Stefna\PhpCodeBuilder\PhpFile;
use Stefna\PhpCodeBuilder\Renderer\Php74Renderer;
use Stefna\PhpCodeBuilder\Renderer\Php81Renderer;
use Stefna\PhpCodeBuilder\Renderer\Php8Renderer;
use Stefna\PhpCodeBuilder\ValueObject\EnumBackedCase;
use Stefna\PhpCodeBuilder\ValueObject\EnumCase;
use Stefna\PhpCodeBuilder\ValueObject\Type;
Expand Down Expand Up @@ -76,4 +77,36 @@ public function testRenderEnumInFile(): void

$this->assertSourceResult($renderer->render($file), 'PhpEnumTest.' . __FUNCTION__);
}

public function testCaseWithSpecialCharacters(): void
{
$renderer = new Php8Renderer();
$enum = new PhpEnum(
'Test',
Type::fromString('string'),
cases: [
new EnumBackedCase('2m', '2m'),
new EnumBackedCase('>2m', '>2m'),
],
);
$file = PhpFile::createFromClass($enum);

$this->assertSourceResult($renderer->render($file), 'PhpEnumTest.' . __FUNCTION__);
}

public function testCaseWithSpecialCharactersNative(): void
{
$renderer = new Php81Renderer();
$enum = new PhpEnum(
'Test',
Type::fromString('string'),
cases: [
new EnumBackedCase('2m', '2m'),
new EnumBackedCase('>2m', '>2m'),
],
);
$file = PhpFile::createFromClass($enum);

$this->assertSourceResult($renderer->render($file), 'PhpEnumTest.' . __FUNCTION__);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php declare(strict_types=1);

final class Test
{
public const _2m = '2m';
public const _s_2m = '>2m';


private function __construct(
public string $value,
) {}

public static function from(string $value): self
{
$self = self::tryFrom($value);
if ($self) {
return $self;
}
throw new \ValueError('Enum not found: ' . $value);
}

public static function tryFrom(string $value): ?self
{
if ($value === self::_2m) {
return new self($value);
}
if ($value === self::_s_2m) {
return new self($value);
}
return null;
}

public function __toString(): string
{
return (string)$this->value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php declare(strict_types=1);

enum Test: string
{
case _2m = '2m';
case _s_2m = '>2m';
}

0 comments on commit 91b3fba

Please sign in to comment.