Passed
Pull Request — master (#48)
by Marco
02:39
created

ComparatorTest::testMakingAClassFinal()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 8
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace RoaveTest\ApiCompare;
6
7
use PHPUnit\Framework\MockObject\MockObject;
8
use PHPUnit\Framework\TestCase;
9
use Roave\ApiCompare\Change;
10
use Roave\ApiCompare\Changes;
11
use Roave\ApiCompare\Comparator;
12
use Roave\ApiCompare\Comparator\BackwardsCompatibility\ClassBased\ClassBased;
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 testSkipsReflectingUndefinedApi() : void
51
    {
52
        $this->classBasedComparatorWillNotBeCalled();
53
54
        self::assertEqualsIgnoringOrder(
55
            Changes::new(),
56
            $this->comparator->compare(
57
                self::$stringReflectorFactory->__invoke('<?php '),
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

57
                self::$stringReflectorFactory->/** @scrutinizer ignore-call */ 
58
                                               __invoke('<?php '),

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...
58
                self::$stringReflectorFactory->__invoke('<?php class A { private function foo() {} }'),
59
                self::$stringReflectorFactory->__invoke('<?php ')
60
            )
61
        );
62
    }
63
64
    public function testRemovingAClassCausesABreak() : void
65
    {
66
        $this->classBasedComparatorWillNotBeCalled();
67
68
        self::assertEqualsIgnoringOrder(
69
            Changes::fromArray([
70
                Change::removed('Class A has been deleted', true),
71
            ]),
72
            $this->comparator->compare(
73
                self::$stringReflectorFactory->__invoke('<?php class A { private function foo() {} }'),
74
                self::$stringReflectorFactory->__invoke('<?php class A { private function foo() {} }'),
75
                self::$stringReflectorFactory->__invoke('<?php ')
76
            )
77
        );
78
    }
79
80
    public function testRemovingAPrivateMethodDoesNotCauseBreak() : void
81
    {
82
        $this->classBasedComparatorWillBeCalled();
83
84
        self::assertEqualsIgnoringOrder(
85
            Changes::new(),
86
            $this->comparator->compare(
87
                self::$stringReflectorFactory->__invoke('<?php class A { private function foo() {} }'),
88
                self::$stringReflectorFactory->__invoke('<?php class A { private function foo() {} }'),
89
                self::$stringReflectorFactory->__invoke('<?php class A { }')
90
            )
91
        );
92
    }
93
94
    public function testRenamingParametersDoesNotCauseBcBreak() : void
95
    {
96
        $this->classBasedComparatorWillBeCalled();
97
98
        self::assertEqualsIgnoringOrder(
99
            Changes::new(),
100
            $this->comparator->compare(
101
                self::$stringReflectorFactory->__invoke('<?php class A { function foo(int $a, string $b) {} }'),
102
                self::$stringReflectorFactory->__invoke('<?php class A { function foo(int $a, string $b) {} }'),
103
                self::$stringReflectorFactory->__invoke('<?php class A { function foo(int $b, string $a) {} }')
104
            )
105
        );
106
    }
107
108
    public function testMakingAClassFinal() : void
109
    {
110
        $this->classBasedComparatorWillBeCalled();
111
112
        self::assertEqualsIgnoringOrder(
113
            Changes::fromArray([
114
                Change::changed('Class A is now final', true),
115
            ]),
116
            $this->comparator->compare(
117
                self::$stringReflectorFactory->__invoke('<?php class A { }'),
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