ParameterTypeChangedTest::testDiffs()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 7
nc 1
nop 3
dl 0
loc 13
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace RoaveTest\BackwardCompatibility\DetectChanges\BCBreak\FunctionBased;
6
7
use PHPUnit\Framework\TestCase;
8
use Roave\BackwardCompatibility\Change;
9
use Roave\BackwardCompatibility\DetectChanges\BCBreak\FunctionBased\ParameterTypeChanged;
10
use Roave\BetterReflection\BetterReflection;
11
use Roave\BetterReflection\Reflection\ReflectionFunctionAbstract;
12
use Roave\BetterReflection\Reflector\ClassReflector;
13
use Roave\BetterReflection\Reflector\FunctionReflector;
14
use Roave\BetterReflection\SourceLocator\Type\StringSourceLocator;
15
use function array_combine;
16
use function array_map;
17
use function iterator_to_array;
18
19
/**
20
 * @covers \Roave\BackwardCompatibility\DetectChanges\BCBreak\FunctionBased\ParameterTypeChanged
21
 */
22
final class ParameterTypeChangedTest extends TestCase
23
{
24
    /**
25
     * @dataProvider functionsToBeTested
26
     *
27
     * @param string[] $expectedMessages
28
     */
29
    public function testDiffs(
30
        ReflectionFunctionAbstract $fromFunction,
31
        ReflectionFunctionAbstract $toFunction,
32
        array $expectedMessages
33
    ) : void {
34
        $changes = (new ParameterTypeChanged())
35
            ->__invoke($fromFunction, $toFunction);
36
37
        self::assertSame(
38
            $expectedMessages,
39
            array_map(function (Change $change) : string {
40
                return $change->__toString();
41
            }, iterator_to_array($changes))
42
        );
43
    }
44
45
    /**
46
     * @return array<string, array<int, ReflectionFunctionAbstract|array<int, string>>>
47
     *
48
     * @psalm-return array<string, array{0: ReflectionFunctionAbstract, 1: ReflectionFunctionAbstract, 2: list<string>}>
49
     */
50
    public function functionsToBeTested() : array
51
    {
52
        $astLocator = (new BetterReflection())->astLocator();
53
54
        $fromLocator = new StringSourceLocator(
55
            <<<'PHP'
56
<?php
57
58
namespace {
59
   function changed(int $a, int $b) {}
60
   function untouched(int $a, int $b) {}
61
}
62
63
namespace N1 {
64
   class A {}
65
   function changed(A $a, A $b) {}
66
   function untouched(A $a, A $b) {}
67
}
68
69
namespace N2 {
70
   class A {}
71
   function changed(A $a, A $b) {}
72
   function untouched(A $a, A $b) {}
73
}
74
75
namespace N3 {
76
   function changed(?int $a, ?int $b) {}
77
   function untouched(?int $a, ?int $b) {}
78
}
79
80
namespace N4 {
81
   class C {
82
       static function changed1($a, $b) {}
83
       function changed2($a, $b) {}
84
   }
85
}
86
PHP
87
            ,
88
            $astLocator
89
        );
90
91
        $toLocator = new StringSourceLocator(
92
            <<<'PHP'
93
<?php
94
95
namespace {
96
   function changed(float $a, float $b) {}
97
   function untouched(int $a, int $b) {}
98
}
99
100
namespace N1 {
101
   class A {}
102
   function changed(\N2\A $a, \N2\A $b) {}
103
   function untouched(A $a, A $b) {}
104
}
105
106
namespace N2 {
107
   class A {}
108
   function changed(\N3\A $b) {}
109
   function untouched(A $a, A $b) {}
110
}
111
112
namespace N3 {
113
   class A {}
114
   function changed(int $d, int $e, int $f) {}
115
   function untouched(?int $a, ?int $b) {}
116
}
117
118
namespace N4 {
119
   class C {
120
       static function changed1(int $a, int $b) {}
121
       function changed2(int $a, int $b) {}
122
   }
123
}
124
PHP
125
            ,
126
            $astLocator
127
        );
128
129
        $fromClassReflector = new ClassReflector($fromLocator);
130
        $toClassReflector   = new ClassReflector($toLocator);
131
        $fromReflector      = new FunctionReflector($fromLocator, $fromClassReflector);
132
        $toReflector        = new FunctionReflector($toLocator, $toClassReflector);
133
134
        $functions = [
135
            'changed'      => [
136
                '[BC] CHANGED: The parameter $a of changed() changed from int to float',
137
                '[BC] CHANGED: The parameter $b of changed() changed from int to float',
138
            ],
139
            'untouched'    => [],
140
            'N1\changed'   => [
141
                '[BC] CHANGED: The parameter $a of N1\changed() changed from N1\A to N2\A',
142
                '[BC] CHANGED: The parameter $b of N1\changed() changed from N1\A to N2\A',
143
            ],
144
            'N1\untouched' => [],
145
            'N2\changed'   => [
146
                '[BC] CHANGED: The parameter $a of N2\changed() changed from N2\A to N3\A',
147
            ],
148
            'N2\untouched' => [],
149
            'N3\changed'   => [
150
                '[BC] CHANGED: The parameter $a of N3\changed() changed from ?int to int',
151
                '[BC] CHANGED: The parameter $b of N3\changed() changed from ?int to int',
152
            ],
153
            'N3\untouched' => [],
154
        ];
155
156
        return array_merge(
157
            array_combine(
0 ignored issues
show
Bug introduced by
It seems like array_combine(array_keys...unctions), $functions)) can also be of type false; however, parameter $array1 of array_merge() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

157
            /** @scrutinizer ignore-type */ array_combine(
Loading history...
158
                array_keys($functions),
159
                array_map(
160
                    /** @psalm-param list<string> $errorMessages https://github.com/vimeo/psalm/issues/2772 */
161
                    static function (string $function, array $errorMessages) use ($fromReflector, $toReflector) : array {
162
                        return [
163
                            $fromReflector->reflect($function),
164
                            $toReflector->reflect($function),
165
                            $errorMessages,
166
                        ];
167
                    },
168
                    array_keys($functions),
169
                    $functions
170
                )
171
            ),
172
            [
173
                'N4\C::changed1' => [
174
                    $fromClassReflector->reflect('N4\C')->getMethod('changed1'),
175
                    $toClassReflector->reflect('N4\C')->getMethod('changed1'),
176
                    [
177
                        '[BC] CHANGED: The parameter $a of N4\C::changed1() changed from no type to int',
178
                        '[BC] CHANGED: The parameter $b of N4\C::changed1() changed from no type to int',
179
180
                    ],
181
                ],
182
                'N4\C#changed2'  => [
183
                    $fromClassReflector->reflect('N4\C')->getMethod('changed2'),
184
                    $toClassReflector->reflect('N4\C')->getMethod('changed2'),
185
                    [
186
                        '[BC] CHANGED: The parameter $a of N4\C#changed2() changed from no type to int',
187
                        '[BC] CHANGED: The parameter $b of N4\C#changed2() changed from no type to int',
188
                    ]
189
                ],
190
            ]
191
        );
192
    }
193
}
194