Skip to content

Commit

Permalink
Adjustments
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremynikolic committed Jun 15, 2023
1 parent e368eac commit 5e01e52
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 56 deletions.
31 changes: 18 additions & 13 deletions src/Definition/PhpEnumType.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@

namespace Worksome\GraphQLHelpers\Definition;

use BackedEnum;
use GraphQL\Error\SerializationError;
use GraphQL\Type\Definition\Deprecated;
use GraphQL\Type\Definition\Description;
use GraphQL\Type\Definition\EnumType;
use GraphQL\Utils\PhpDoc;
use GraphQL\Utils\Utils;
use Jawira\CaseConverter\Convert;
use ReflectionEnum;
use UnitEnum;

/**
* @phpstan-import-type PartialEnumValueConfig from EnumType
Expand All @@ -22,34 +23,38 @@ class PhpEnumType extends EnumType
public const MULTIPLE_DEPRECATIONS_DISALLOWED = 'Using more than 1 Deprecated attribute is not supported.';

/**
* @var class-string<BackedEnum>
* @var class-string<UnitEnum>
*/
protected string $enumClass;

/**
* @param class-string<BackedEnum> $enum
* @param class-string<UnitEnum> $enumClass
*/
public function __construct(string $enum, string $name = null)
public function __construct(string $enumClass, string $name = null)
{
$this->enumClass = $enum;
$reflection = new \ReflectionEnum($enum);
$this->enumClass = $enumClass;
$reflection = new ReflectionEnum($enumClass);
/**
* @var array<string, PartialEnumValueConfig> $enumDefinitions
*/
$enumDefinitions = [];
foreach ($reflection->getCases() as $case) {
$enumDefinitions[(new Convert($case->name))->toMacro()] = [
'value' => $case->getBackingValue(),
$upperCaseName = (new Convert($case->name))->toMacro();

$enumDefinitions[$upperCaseName] = [
'value' => $reflection->isBacked() ? $case->getValue()->value : $upperCaseName,
'description' => $this->extractDescription($case),
'deprecationReason' => $this->deprecationReason($case),
];
}

parent::__construct([
'name' => $name ?? $this->baseName($enum),
'values' => $enumDefinitions,
'description' => $this->extractDescription($reflection),
]);
parent::__construct(
[
'name' => $name ?? $this->baseName($enumClass),
'values' => $enumDefinitions,
'description' => $this->extractDescription($reflection),
]
);
}

public function serialize($value): string
Expand Down
151 changes: 108 additions & 43 deletions tests/PhpEnumTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,18 @@
use Worksome\GraphQLHelpers\Definition\PhpEnumType;

#[Description('Dummy enum description')]
enum DummyEnum: string
enum DummyEnum
{
#[Description('PascalCase description')]
case PascalCase;
#[Description('SCREAMING_SNAKE_CASE description')]
case SCREAMING_SNAKE_CASE; // phpcs:ignore
#[Description('snake_case description')]
case snake_case; // phpcs:ignore
}

#[Description('Dummy enum description')]
enum DummyStringEnum: string
{
#[Description('PascalCase description')]
case PascalCase = 'pascal-case';
Expand All @@ -20,51 +31,105 @@ enum DummyEnum: string
case snake_case = 'snake-case'; // phpcs:ignore
}

it('generates correct GQL name from enum cases', function () {
$type = new PhpEnumType(DummyEnum::class);
expect($type->name)->toBe("DummyEnum");

$name = Collection::make($type->getValues())
->map(fn (EnumValueDefinition $definition) => $definition->name)
->all();
expect($name)->toBe(
[
'PASCAL_CASE',
'SCREAMING_SNAKE_CASE',
'SNAKE_CASE',
],
);
});

it('generates correct GQL value from enum cases', function () {
$type = new PhpEnumType(DummyEnum::class);

$values = Collection::make($type->getValues())
->map(fn (EnumValueDefinition $definition) => $definition->value)
->all();

expect($values)->toBe(
[
DummyEnum::PascalCase->value,
DummyEnum::SCREAMING_SNAKE_CASE->value,
DummyEnum::snake_case->value,
],
);
});

it('extracts description from php attribute', function () {
$type = new PhpEnumType(DummyEnum::class);

$descriptions = Collection::make($type->getValues())->map(
fn (EnumValueDefinition $definition) => $definition->description,
)->all();

expect($type->description)->toBe('Dummy enum description')
->and($descriptions)->toBe(
#[Description('Dummy enum description')]
enum DummyIntEnum: int
{
#[Description('PascalCase description')]
case PascalCase = 1;
#[Description('SCREAMING_SNAKE_CASE description')]
case SCREAMING_SNAKE_CASE = 2; // phpcs:ignore
#[Description('snake_case description')]
case snake_case = 3; // phpcs:ignore
}

dataset(
'dummy-enums',
[
DummyEnum::class,
DummyIntEnum::class,
DummyStringEnum::class,
],
);
it(
'generates correct GQL name from enum cases',
function ($enumClass) {
$type = new PhpEnumType($enumClass);
expect($type->name)->toBe(class_basename($enumClass));

$names = Collection::make($type->getValues())
->map(fn(EnumValueDefinition $definition) => $definition->name)
->all();
expect($names)->toBe(
[
'PASCAL_CASE',
'SCREAMING_SNAKE_CASE',
'SNAKE_CASE',
],
);
},
)->with('dummy-enums');

it(
'generates correct GQL value from backed enum cases',
function ($enumClass) {
$type = new PhpEnumType($enumClass);

$values = Collection::make($type->getValues())
->map(fn(EnumValueDefinition $definition) => $definition->value)
->all();

expect($values)->toBe(
[
$enumClass::PascalCase->value,
$enumClass::SCREAMING_SNAKE_CASE->value,
$enumClass::snake_case->value,
],
);
},
)->with(
[
DummyStringEnum::class,
DummyIntEnum::class,
],
);

it(
'generates correct GQL value from non-backed enum cases',
function ($enumClass) {
$type = new PhpEnumType($enumClass);

$values = Collection::make($type->getValues())
->map(fn(EnumValueDefinition $definition) => $definition->value)
->all();

expect($values)->toBe(
[
'PASCAL_CASE',
'SCREAMING_SNAKE_CASE',
'SNAKE_CASE'
],
);
},
)->with(
[
DummyEnum::class,
],
);

it(
'extracts description from php attribute',
function ($enumClass) {
$type = new PhpEnumType($enumClass);
$descriptions = Collection::make($type->getValues())->map(
fn(EnumValueDefinition $definition) => $definition->description,
)->all();

expect($type->description)->toBe('Dummy enum description')->and($descriptions)->toBe(
[
'PascalCase description',
'SCREAMING_SNAKE_CASE description',
'snake_case description',
],
);
});
},
)->with('dummy-enums');

0 comments on commit 5e01e52

Please sign in to comment.