Failed Conditions
Push — master ( 84a52c...ed1746 )
by Vladimir
10:32
created

Issue396Test::testInterfaceResolveType()   A

Complexity

Conditions 4
Paths 1

Size

Total Lines 64
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 36
dl 0
loc 64
rs 9.344
c 0
b 0
f 0
cc 4
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace GraphQL\Tests\Regression;
6
7
use GraphQL\GraphQL;
8
use GraphQL\Type\Definition\InterfaceType;
9
use GraphQL\Type\Definition\ObjectType;
10
use GraphQL\Type\Definition\ResolveInfo;
11
use GraphQL\Type\Definition\Type;
12
use GraphQL\Type\Definition\UnionType;
13
use GraphQL\Type\Schema;
14
use PHPUnit\Framework\TestCase;
15
use function stristr;
16
17
/**
18
 * @see https://github.com/webonyx/graphql-php/issues/396
19
 */
20
class Issue396Test extends TestCase
21
{
22
    public function testUnionResolveType()
23
    {
24
        $a = new ObjectType(['name' => 'A', 'fields' => ['name' => Type::string()]]);
25
        $b = new ObjectType(['name' => 'B', 'fields' => ['name' => Type::string()]]);
26
        $c = new ObjectType(['name' => 'C', 'fields' => ['name' => Type::string()]]);
27
28
        $log = [];
29
30
        $unionResult = new UnionType([
31
            'name' => 'UnionResult',
32
            'types' => [$a, $b, $c],
33
            'resolveType' => static function ($result, $root, ResolveInfo $info) use ($a, $b, $c, &$log) : Type {
34
                $log[] = [$result, $info->path];
35
                if (stristr($result['name'], 'A')) {
36
                    return $a;
37
                }
38
                if (stristr($result['name'], 'B')) {
39
                    return $b;
40
                }
41
                if (stristr($result['name'], 'C')) {
42
                    return $c;
43
                }
0 ignored issues
show
Bug Best Practice introduced by
The function implicitly returns null when the if condition on line 41 is false. This is incompatible with the type-hinted return GraphQL\Type\Definition\Type. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
44
            },
45
        ]);
46
47
        $exampleType = new ObjectType([
48
            'name' => 'Example',
49
            'fields' => [
50
                'field' => [
51
                    'type' => Type::nonNull(Type::listOf(Type::nonNull($unionResult))),
52
                    'resolve' => static function () : array {
53
                        return [
54
                            ['name' => 'A 1'],
55
                            ['name' => 'B 2'],
56
                            ['name' => 'C 3'],
57
                        ];
58
                    },
59
                ],
60
            ],
61
        ]);
62
63
        $schema = new Schema(['query' => $exampleType]);
64
65
        $query = '
66
            query {
67
                field {
68
                    ... on A {
69
                        name
70
                    }
71
                    ... on B {
72
                        name
73
                    }
74
                    ... on C {
75
                        name
76
                    }
77
                }
78
            }
79
        ';
80
81
        GraphQL::executeQuery($schema, $query);
82
83
        $expected = [
84
            [['name' => 'A 1'], ['field', 0]],
85
            [['name' => 'B 2'], ['field', 1]],
86
            [['name' => 'C 3'], ['field', 2]],
87
        ];
88
        self::assertEquals($expected, $log);
89
    }
90
91
    public function testInterfaceResolveType()
92
    {
93
        $log = [];
94
95
        $interfaceResult = new InterfaceType([
96
            'name' => 'InterfaceResult',
97
            'fields' => [
98
                'name' => Type::string(),
99
            ],
100
            'resolveType' => static function ($result, $root, ResolveInfo $info) use (&$a, &$b, &$c, &$log) : Type {
101
                $log[] = [$result, $info->path];
102
                if (stristr($result['name'], 'A')) {
103
                    return $a;
104
                }
105
                if (stristr($result['name'], 'B')) {
106
                    return $b;
107
                }
108
                if (stristr($result['name'], 'C')) {
109
                    return $c;
110
                }
0 ignored issues
show
Bug Best Practice introduced by
The function implicitly returns null when the if condition on line 108 is false. This is incompatible with the type-hinted return GraphQL\Type\Definition\Type. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
111
            },
112
        ]);
113
114
        $a = new ObjectType(['name' => 'A', 'fields' => ['name' => Type::string()], 'interfaces' => [$interfaceResult]]);
115
        $b = new ObjectType(['name' => 'B', 'fields' => ['name' => Type::string()], 'interfaces' => [$interfaceResult]]);
116
        $c = new ObjectType(['name' => 'C', 'fields' => ['name' => Type::string()], 'interfaces' => [$interfaceResult]]);
117
118
        $exampleType = new ObjectType([
119
            'name' => 'Example',
120
            'fields' => [
121
                'field' => [
122
                    'type' => Type::nonNull(Type::listOf(Type::nonNull($interfaceResult))),
123
                    'resolve' => static function () : array {
124
                        return [
125
                            ['name' => 'A 1'],
126
                            ['name' => 'B 2'],
127
                            ['name' => 'C 3'],
128
                        ];
129
                    },
130
                ],
131
            ],
132
        ]);
133
134
        $schema = new Schema([
135
            'query' => $exampleType,
136
            'types' => [$a, $b, $c],
137
        ]);
138
139
        $query = '
140
            query {
141
                field {
142
                    name
143
                }
144
            }
145
        ';
146
147
        GraphQL::executeQuery($schema, $query);
148
149
        $expected = [
150
            [['name' => 'A 1'], ['field', 0]],
151
            [['name' => 'B 2'], ['field', 1]],
152
            [['name' => 'C 3'], ['field', 2]],
153
        ];
154
        self::assertEquals($expected, $log);
155
    }
156
}
157