Passed
Push — master ( 2d1aee...9ce071 )
by Adrien
02:19
created

TypesTrait.php$0 ➔ canCreate()   A

Complexity

Conditions 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GraphQLTests\Doctrine;
6
7
use DateTimeImmutable;
8
use Exception;
9
use GraphQL\Doctrine\Types;
10
use GraphQL\Type\Definition\BooleanType;
11
use GraphQL\Type\Definition\InputType;
12
use GraphQL\Type\Definition\ObjectType;
13
use GraphQL\Type\Definition\OutputType;
14
use GraphQL\Type\Definition\PhpEnumType;
15
use GraphQL\Type\Definition\Type;
16
use GraphQL\Type\Definition\WrappingType;
17
use GraphQL\Type\Schema;
18
use GraphQL\Utils\SchemaPrinter;
19
use GraphQLTests\Doctrine\Blog\Enum\Status;
20
use GraphQLTests\Doctrine\Blog\Types\CustomType;
21
use GraphQLTests\Doctrine\Blog\Types\DateTimeType;
22
use GraphQLTests\Doctrine\Blog\Types\PostStatusType;
23
use Laminas\ServiceManager\Factory\AbstractFactoryInterface;
24
use Laminas\ServiceManager\ServiceManager;
25
use Psr\Container\ContainerInterface;
26
use stdClass;
27
28
/**
29
 * Trait to easily set up types and assert them.
30
 */
31
trait TypesTrait
32
{
33
    use EntityManagerTrait;
34
35
    private Types $types;
36
37
    public function setUp(): void
38
    {
39
        $this->setUpEntityManager();
40
41
        $customTypes = new ServiceManager([
42
            'invokables' => [
43
                BooleanType::class => BooleanType::class,
44
                DateTimeImmutable::class => DateTimeType::class,
45
                stdClass::class => CustomType::class,
46
                'PostStatus' => PostStatusType::class,
47
            ],
48
            'aliases' => [
49
                'datetime_immutable' => DateTimeImmutable::class, // Declare alias for Doctrine type to be used for filters
50
            ],
51
            'abstract_factories' => [
52
                new class() implements AbstractFactoryInterface {
53
                    public function canCreate(ContainerInterface $container, string $requestedName): bool
54
                    {
55
                        return $requestedName === Status::class;
56
                    }
57
58
                    public function __invoke(ContainerInterface $container, string $requestedName, ?array $options = null): PhpEnumType
59
                    {
60
                        return new PhpEnumType(Status::class);
61
                    }
62
                },
63
            ],
64
        ]);
65
66
        $this->types = new Types($this->entityManager, $customTypes);
67
    }
68
69
    private function assertType(string $expectedFile, Type $type): void
70
    {
71
        $actual = SchemaPrinter::printType($type) . "\n";
72
        self::assertStringEqualsFile($expectedFile, $actual, 'Should equals expectation from: ' . $expectedFile);
73
    }
74
75
    private function assertAllTypes(string $expectedFile, Type $type): void
76
    {
77
        $schema = $this->getSchemaForType($type);
78
        $actual = SchemaPrinter::doPrint($schema);
79
80
        self::assertStringEqualsFile($expectedFile, $actual, 'Should equals expectation from: ' . $expectedFile);
81
    }
82
83
    /**
84
     * Create a temporary schema for the given type.
85
     */
86
    private function getSchemaForType(Type $type): Schema
87
    {
88
        if ($type instanceof WrappingType) {
89
            $wrappedType = $type->getInnermostType();
90
        } else {
91
            $wrappedType = $type;
92
        }
93
94
        if ($wrappedType instanceof OutputType) {
95
            $outputType = $type;
96
            $args = [];
97
        } elseif ($wrappedType instanceof InputType) {
98
            $outputType = Type::boolean();
99
            $args = [
100
                'defaultArg' => $type,
101
            ];
102
        } else {
103
            throw new Exception('Unsupported type: ' . $wrappedType::class);
104
        }
105
106
        $config = [
107
            'query' => new ObjectType([
108
                'name' => 'query',
109
                'fields' => [
110
                    'defaultField' => [
111
                        'type' => $outputType,
112
                        'args' => $args,
113
                    ],
114
                ],
115
            ]),
116
        ];
117
118
        $schema = new Schema($config);
119
        $schema->assertValid();
120
121
        return $schema;
122
    }
123
}
124