AncestorRemovedTest   A
last analyzed

Complexity

Total Complexity 2

Size/Duplication

Total Lines 124
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 49
c 1
b 0
f 0
dl 0
loc 124
rs 10
wmc 2

2 Methods

Rating   Name   Duplication   Size   Complexity  
A classesToBeTested() 0 96 1
A testDiffs() 0 13 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace RoaveTest\BackwardCompatibility\DetectChanges\BCBreak\ClassBased;
6
7
use PHPUnit\Framework\TestCase;
8
use Roave\BackwardCompatibility\Change;
9
use Roave\BackwardCompatibility\DetectChanges\BCBreak\ClassBased\AncestorRemoved;
10
use Roave\BetterReflection\BetterReflection;
11
use Roave\BetterReflection\Reflection\ReflectionClass;
12
use Roave\BetterReflection\Reflector\ClassReflector;
13
use Roave\BetterReflection\SourceLocator\Type\StringSourceLocator;
14
use RoaveTest\BackwardCompatibility\TypeRestriction;
15
use function array_combine;
16
use function array_keys;
17
use function array_map;
18
use function iterator_to_array;
19
20
/**
21
 * @covers \Roave\BackwardCompatibility\DetectChanges\BCBreak\ClassBased\AncestorRemoved
22
 */
23
final class AncestorRemovedTest extends TestCase
24
{
25
    /**
26
     * @param string[] $expectedMessages
27
     *
28
     * @dataProvider classesToBeTested
29
     */
30
    public function testDiffs(
31
        ReflectionClass $fromClass,
32
        ReflectionClass $toClass,
33
        array $expectedMessages
34
    ) : void {
35
        $changes = (new AncestorRemoved())
36
            ->__invoke($fromClass, $toClass);
37
38
        self::assertSame(
39
            $expectedMessages,
40
            array_map(static function (Change $change) : string {
41
                return $change->__toString();
42
            }, iterator_to_array($changes))
43
        );
44
    }
45
46
    /**
47
     * @return array<string, array<int, ReflectionClass|array<int, string>>>
48
     *
49
     * @psalm-return array<string, array{0: ReflectionClass, 1: ReflectionClass, 2: list<string>}>
50
     */
51
    public function classesToBeTested() : array
52
    {
53
        $locator       = (new BetterReflection())->astLocator();
54
        $fromReflector = new ClassReflector(new StringSourceLocator(
55
            <<<'PHP'
56
<?php
57
58
class A {}
59
class B extends A {}
60
class C extends A {}
61
class D extends C {}
62
interface IA {}
63
interface IB extends IA {}
64
interface IC extends IA {}
65
interface ID extends IB, IE {}
66
interface IE {}
67
interface IG {}
68
class ClassWithNoAncestors {}
69
class ClassWithAddedAncestors {}
70
class ClassWithAddedInterface {}
71
class ClassWithRemovedAncestor extends A {}
72
class ClassWithRemovedIndirectAncestor extends B {}
73
class ClassWithRemovedVeryIndirectAncestor extends D {}
74
class ClassWithRemovedInterface implements IA {}
75
class ClassWithRemovedIndirectInterface implements IB {}
76
class ClassWithRemovedVeryIndirectInterface implements ID {}
77
class ClassWithInvertedInterfaceNames implements IE, IG {}
78
PHP
79
            ,
80
            $locator
81
        ));
82
        $toReflector   = new ClassReflector(new StringSourceLocator(
83
            <<<'PHP'
84
<?php
85
86
class A {}
87
class B {}
88
class C {}
89
class D extends C {}
90
interface IA {}
91
interface IB {}
92
interface IC extends IA {}
93
interface ID extends IB, IE {}
94
interface IE {}
95
interface IG {}
96
class ClassWithNoAncestors {}
97
class ClassWithAddedAncestors extends A {}
98
class ClassWithAddedInterface implements IA {}
99
class ClassWithRemovedAncestor {}
100
class ClassWithRemovedIndirectAncestor extends B {}
101
class ClassWithRemovedVeryIndirectAncestor extends D {}
102
class ClassWithRemovedInterface {}
103
class ClassWithRemovedIndirectInterface implements IB {}
104
class ClassWithRemovedVeryIndirectInterface implements ID {}
105
class ClassWithInvertedInterfaceNames implements IG, IE {}
106
PHP
107
            ,
108
            $locator
109
        ));
110
111
        $classes = [
112
            'A' => [],
113
            'B' => ['[BC] REMOVED: These ancestors of B have been removed: ["A"]'],
114
            'C' => ['[BC] REMOVED: These ancestors of C have been removed: ["A"]'],
115
            'D' => ['[BC] REMOVED: These ancestors of D have been removed: ["A"]'],
116
            'IA' => [],
117
            'IB' => ['[BC] REMOVED: These ancestors of IB have been removed: ["IA"]'],
118
            'IC' => [],
119
            'ID' => ['[BC] REMOVED: These ancestors of ID have been removed: ["IA"]'],
120
            'IE' => [],
121
            'IG' => [],
122
            'ClassWithNoAncestors' => [],
123
            'ClassWithAddedAncestors' => [],
124
            'ClassWithAddedInterface' => [],
125
            'ClassWithRemovedAncestor' => ['[BC] REMOVED: These ancestors of ClassWithRemovedAncestor have been removed: ["A"]'],
126
            'ClassWithRemovedIndirectAncestor' => ['[BC] REMOVED: These ancestors of ClassWithRemovedIndirectAncestor have been removed: ["A"]'],
127
            'ClassWithRemovedVeryIndirectAncestor' => ['[BC] REMOVED: These ancestors of ClassWithRemovedVeryIndirectAncestor have been removed: ["A"]'],
128
            'ClassWithRemovedInterface' => ['[BC] REMOVED: These ancestors of ClassWithRemovedInterface have been removed: ["IA"]'],
129
            'ClassWithRemovedIndirectInterface' => ['[BC] REMOVED: These ancestors of ClassWithRemovedIndirectInterface have been removed: ["IA"]'],
130
            'ClassWithRemovedVeryIndirectInterface' => ['[BC] REMOVED: These ancestors of ClassWithRemovedVeryIndirectInterface have been removed: ["IA"]'],
131
            'ClassWithInvertedInterfaceNames' => [],
132
        ];
133
134
        return TypeRestriction::array(array_combine(
135
            array_keys($classes),
136
            array_map(
137
                /** @psalm-param list<string> $errors https://github.com/vimeo/psalm/issues/2772 */
138
                static function (string $className, array $errors) use ($fromReflector, $toReflector) : array {
139
                    return [
140
                        $fromReflector->reflect($className),
141
                        $toReflector->reflect($className),
142
                        $errors,
143
                    ];
144
                },
145
                array_keys($classes),
146
                $classes
147
            )
148
        ));
149
    }
150
}
151