Skip to content

Commit

Permalink
WIP to discuss with Owen
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremynikolic committed Jun 12, 2023
1 parent 23ae996 commit feb1758
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 9 deletions.
22 changes: 13 additions & 9 deletions src/Definition/PhpEnumType.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,57 @@

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 Illuminate\Support\Str;
use Illuminate\Support\Collection;
use Jawira\CaseConverter\Convert;
use ReflectionEnumBackedCase;
use ReflectionEnumPureCase;
use UnitEnum;

/**
* @phpstan-import-type PartialEnumValueConfig from EnumType
*/
class PhpEnumType extends EnumType
{

public const MULTIPLE_DESCRIPTIONS_DISALLOWED = 'Using more than 1 Description attribute is not supported.';
public const MULTIPLE_DEPRECATIONS_DISALLOWED = 'Using more than 1 Deprecated attribute is not supported.';

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

/**
* @param class-string<\UnitEnum> $enum
* @param class-string<BackedEnum> $enum
*/
public function __construct(string $enum, string $name = null)
{
$this->enumClass = $enum;
$reflection = new \ReflectionEnum($enum);

/**
* @var array<string, PartialEnumValueConfig> $enumDefinitions
*/
$enumDefinitions = [];
foreach ($reflection->getCases() as $case) {
$enumDefinitions[(new Convert($case->name))->toMacro()] = [
'value' => $case->getValue(),
'value' => $case->getBackingValue(),
'description' => $this->extractDescription($case),
'deprecationReason' => $this->deprecationReason($case),
];
}

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

public function serialize($value): string
Expand Down
83 changes: 83 additions & 0 deletions tests/PhpEnumTypeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

declare(strict_types=1);

namespace Worksome\GraphQLHelpers\Tests;

use GraphQL\Type\Definition\Description;
use GraphQL\Type\Definition\EnumValueDefinition;
use Illuminate\Support\Collection;
use Worksome\GraphQLHelpers\Definition\PhpEnumType;

/** @codingStandardsIgnoreStart */
#[Description('Dummy enum description')]
enum DummyEnum: string
{

#[Description('PascalCase description')]
case PascalCase = 'pascal-case';
#[Description('SCREAMING_SNAKE_CASE description')]
case SCREAMING_SNAKE_CASE = 'screaming-snake-case';
#[Description('snake_case description')]
case snake_case = 'snake-case';
}

/** @codingStandardsIgnoreEnd */

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(
[
'PascalCase description',
'SCREAMING_SNAKE_CASE description',
'snake_case description',
],
);
},
);

0 comments on commit feb1758

Please sign in to comment.