Test Failed
Push — master ( 7d28e2...923481 )
by Gerrit
02:21
created

dataProviderForShouldReplaceNodes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 12
c 1
b 0
f 1
nc 1
nop 0
dl 0
loc 16
rs 9.8666
1
<?php
2
/**
3
 * Copyright (C) 2019  Gerrit Addiks.
4
 * This package (including this file) was released under the terms of the GPL-3.0.
5
 * You should have received a copy of the GNU General Public License along with this program.
6
 * If not, see <http://www.gnu.org/licenses/> or send me a mail so i can send you a copy.
7
 * @license GPL-3.0
8
 * @author Gerrit Addiks <[email protected]>
9
 */
10
11
namespace Addiks\StoredSQL\Tests\Unit\Parsing\AbstractSyntaxTree;
12
13
use PHPUnit\Framework\TestCase;
14
use Addiks\StoredSQL\Parsing\AbstractSyntaxTree\SqlAstBranch;
15
use Addiks\StoredSQL\Parsing\AbstractSyntaxTree\SqlAstNode;
16
use Addiks\StoredSQL\Parsing\AbstractSyntaxTree\SqlAstMutableNode;
17
use Closure;
18
use PHPUnit\Framework\MockObject\MockObject;
19
20
final class SqlAstBranchTest extends TestCase
21
{
22
23
    private SqlAstBranch $subject;
24
25
    /** @var MockObject&SqlAstNode $childA */
26
    private SqlAstNode $childA;
27
28
    /** @var MockObject&SqlAstMutableNode $childB */
29
    private SqlAstMutableNode $childB;
30
31
    /** @var MockObject&SqlAstNode $childC */
32
    private SqlAstNode $childC;
33
34
    public function setUp(): void
35
    {
36
        $this->childA = $this->createMock(SqlAstNode::class);
37
        $this->childB = $this->createMock(SqlAstMutableNode::class);
38
        $this->childC = $this->createMock(SqlAstNode::class);
39
40
        $this->subject = $this->getMockForAbstractClass(SqlAstBranch::class, [
41
            [$this->childA, $this->childB, $this->childC]
42
        ]);
43
    }
44
45
    /**
46
     * @test
47
     * @covers SqlAstBranch::children
48
     */
49
    public function shouldProvideChildren(): void
50
    {
51
        $this->assertSame([$this->childA, $this->childB, $this->childC], $this->subject->children());
52
    }
53
54
    /**
55
     * @test
56
     * @covers SqlAstBranch::hash
57
     */
58
    public function shouldGenerateHash(): void
59
    {
60
        $this->childA->method('hash')->willReturn("hashA");
0 ignored issues
show
Bug introduced by
The method method() does not exist on Addiks\StoredSQL\Parsing...ctSyntaxTree\SqlAstNode. ( Ignorable by Annotation )

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

60
        $this->childA->/** @scrutinizer ignore-call */ 
61
                       method('hash')->willReturn("hashA");

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...
61
        $this->childB->method('hash')->willReturn("hashB");
0 ignored issues
show
Bug introduced by
The method method() does not exist on Addiks\StoredSQL\Parsing...xTree\SqlAstMutableNode. ( Ignorable by Annotation )

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

61
        $this->childB->/** @scrutinizer ignore-call */ 
62
                       method('hash')->willReturn("hashB");

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...
62
        $this->childC->method('hash')->willReturn("hashC");
63
64
        $this->assertSame(md5("hashA.hashB.hashC"), $this->subject->hash());
65
    }
66
67
    /**
68
     * @test
69
     * @covers SqlAstBranch::walk
70
     */
71
    public function shouldWalkChildren(): void
72
    {
73
        $mutatorAExpectedChilds = [$this->childA, $this->childB, $this->childC];
74
        $mutatorA = function (SqlAstNode $child, int $offset, SqlAstMutableNode $subject) use (&$mutatorAExpectedChilds): void {
75
            $this->assertSame($this->subject, $subject);
76
            $this->assertNotEmpty($mutatorAExpectedChilds);
77
            $this->assertEquals(3 - count($mutatorAExpectedChilds), $offset);
78
            $this->assertSame(array_shift($mutatorAExpectedChilds), $child);
79
        };
80
81
        $mutatorBExpectedChilds = [$this->childA, $this->childB, $this->childC];
82
        $mutatorB = function (SqlAstNode $child, int $offset, SqlAstMutableNode $subject) use (&$mutatorBExpectedChilds): void {
83
            $this->assertSame($this->subject, $subject);
84
            $this->assertNotEmpty($mutatorBExpectedChilds);
85
            $this->assertEquals(3 - count($mutatorBExpectedChilds), $offset);
86
            $this->assertSame(array_shift($mutatorBExpectedChilds), $child);
87
        };
88
89
        /** @var array<callable> $mutators */
90
        $mutators = array($mutatorA, $mutatorB);
91
92
        $this->childB->expects($this->exactly(2))->method('walk')->with($this->equalTo($mutators));
0 ignored issues
show
Bug introduced by
The method expects() does not exist on Addiks\StoredSQL\Parsing...xTree\SqlAstMutableNode. ( Ignorable by Annotation )

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

92
        $this->childB->/** @scrutinizer ignore-call */ 
93
                       expects($this->exactly(2))->method('walk')->with($this->equalTo($mutators));

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...
93
94
        $this->subject->walk($mutators);
95
    }
96
97
    /**
98
     * @test
99
     * @covers SqlAstBranch::replace
100
     * @dataProvider dataProviderForShouldReplaceNodes
101
     */
102
    public function shouldReplaceNodes(int $offset, int $length, SqlAstNode $newNode, array $expectedChilds): void
103
    {
104
        $this->subject->replace($offset, $length, $newNode);
105
106
        $expectedChilds = array_map(function ($input) {
107
            if (is_string($input) && isset($this->{$input})) {
108
                $input = $this->{$input};
109
            }
110
            return $input;
111
        }, $expectedChilds);
112
113
        $this->assertSame($expectedChilds, $this->subject->children());
114
    }
115
116
    public function dataProviderForShouldReplaceNodes(): array
117
    {
118
        /** @var MockObject&SqlAstNode $newNode */
119
        $newNode = $this->createMock(SqlAstNode::class);
120
121
        return [
122
            [0, 3, $newNode, [$newNode]],
123
            [0, 2, $newNode, [$newNode, 'childC']],
124
            [1, 2, $newNode, ['childA', $newNode]],
125
            [0, 1, $newNode, [$newNode, 'childB', 'childC']],
126
            [1, 1, $newNode, ['childA', $newNode, 'childC']],
127
            [2, 1, $newNode, ['childA', 'childB', $newNode]],
128
            [0, 0, $newNode, [$newNode, 'childA', 'childB', 'childC']],
129
            [1, 0, $newNode, ['childA', $newNode, 'childB', 'childC']],
130
            [2, 0, $newNode, ['childA', 'childB', $newNode, 'childC']],
131
            [3, 0, $newNode, ['childA', 'childB', 'childC', $newNode]],
132
        ];
133
    }
134
135
136
}
137