Passed
Push — master ( aa4419...7e0f99 )
by James
01:57
created

ComparatorTest::classBasedComparatorWillBeCalled()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 0
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace RoaveTest\ApiCompare;
5
6
use PHPUnit\Framework\MockObject\MockObject;
7
use Roave\ApiCompare\Change;
8
use Roave\ApiCompare\Changes;
9
use Roave\ApiCompare\Comparator;
10
use PHPUnit\Framework\TestCase;
11
use Roave\ApiCompare\Comparator\BackwardsCompatibility\ClassBased\ClassBased;
12
use Roave\ApiCompare\Factory\DirectoryReflectorFactory;
13
14
/**
15
 * @covers \Roave\ApiCompare\Comparator
16
 */
17
final class ComparatorTest extends TestCase
18
{
19
    /** @var StringReflectorFactory|null */
20
    private static $stringReflectorFactory;
21
22
    /** @var ClassBased|MockObject */
23
    private $classBasedComparison;
24
25
    /** @var Comparator */
26
    private $comparator;
27
28
    public static function setUpBeforeClass() : void
29
    {
30
        self::$stringReflectorFactory = new StringReflectorFactory();
31
    }
32
33
    protected function setUp() : void
34
    {
35
        parent::setUp();
36
37
        $this->classBasedComparison = $this->createMock(ClassBased::class);
38
        $this->comparator           = new Comparator($this->classBasedComparison);
39
    }
40
41
    /**
42
     * @param mixed $expected
43
     * @param mixed $actual
44
     */
45
    private static function assertEqualsIgnoringOrder($expected, $actual): void
46
    {
47
        self::assertEquals($expected, $actual, '', 0.0, 10, true);
48
    }
49
50
    public function testCompare(): void
51
    {
52
        $this->classBasedComparatorWillBeCalled();
53
54
        $reflectorFactory = new DirectoryReflectorFactory();
55
        self::assertEqualsIgnoringOrder(
56
            Changes::fromArray([
57
                Change::removed('Parameter something (position 0) in Thing::__construct has been deleted', true),
58
                Change::removed('Method methodGone in class Thing has been deleted', true),
59
                Change::removed('Class ClassGone has been deleted', true),
60
            ]),
61
            $this->comparator->compare(
62
                $reflectorFactory->__invoke(__DIR__ . '/../asset/api/old'),
63
                $reflectorFactory->__invoke(__DIR__ . '/../asset/api/new')
64
            )
65
        );
66
    }
67
68
    public function testRemovingAClassCausesABreak(): void
69
    {
70
        $this->classBasedComparatorWillNotBeCalled();
71
72
        self::assertEqualsIgnoringOrder(
73
            Changes::fromArray([
74
                Change::removed('Class A has been deleted', true),
75
            ]),
76
            $this->comparator->compare(
77
                self::$stringReflectorFactory->__invoke('<?php class A { private function foo() {} }'),
0 ignored issues
show
Bug introduced by
The method __invoke() does not exist on null. ( Ignorable by Annotation )

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

77
                self::$stringReflectorFactory->/** @scrutinizer ignore-call */ 
78
                                               __invoke('<?php class A { private function foo() {} }'),

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
78
                self::$stringReflectorFactory->__invoke('<?php ')
79
            )
80
        );
81
    }
82
83
    public function testRemovingAPrivateMethodDoesNotCauseBreak(): void
84
    {
85
        $this->classBasedComparatorWillBeCalled();
86
87
        self::assertEqualsIgnoringOrder(
88
            Changes::new(),
89
            $this->comparator->compare(
90
                self::$stringReflectorFactory->__invoke('<?php class A { private function foo() {} }'),
91
                self::$stringReflectorFactory->__invoke('<?php class A { }')
92
            )
93
        );
94
    }
95
96
    public function testRenamingParametersDoesNotCauseBcBreak(): void
97
    {
98
        $this->classBasedComparatorWillBeCalled();
99
100
        self::assertEqualsIgnoringOrder(
101
            Changes::new(),
102
            $this->comparator->compare(
103
                self::$stringReflectorFactory->__invoke('<?php class A { function foo(int $a, string $b) {} }'),
104
                self::$stringReflectorFactory->__invoke('<?php class A { function foo(int $b, string $a) {} }')
105
            )
106
        );
107
    }
108
109
    public function testMakingAClassFinal(): void
110
    {
111
        $this->classBasedComparatorWillBeCalled();
112
113
        self::assertEqualsIgnoringOrder(
114
            Changes::fromArray([
115
                Change::changed('Class A is now final', true),
116
            ]),
117
            $this->comparator->compare(
118
                self::$stringReflectorFactory->__invoke('<?php class A { }'),
119
                self::$stringReflectorFactory->__invoke('<?php final class A { }')
120
            )
121
        );
122
    }
123
124
    private function classBasedComparatorWillBeCalled() : void
125
    {
126
        $this
127
            ->classBasedComparison
128
            ->expects(self::atLeastOnce())
0 ignored issues
show
Bug introduced by
The method expects() does not exist on Roave\ApiCompare\Compara...y\ClassBased\ClassBased. ( Ignorable by Annotation )

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

128
            ->/** @scrutinizer ignore-call */ 
129
              expects(self::atLeastOnce())

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
129
            ->method('compare')
130
            ->willReturn(Changes::new());
131
    }
132
133
    private function classBasedComparatorWillNotBeCalled() : void
134
    {
135
        $this
136
            ->classBasedComparison
137
            ->expects(self::never())
138
            ->method('compare');
139
    }
140
}
141