SqlAstBranchTest   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 112
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 49
dl 0
loc 112
rs 10
c 0
b 0
f 0
wmc 8

6 Methods

Rating   Name   Duplication   Size   Complexity  
A shouldGenerateHash() 0 7 1
A setUp() 0 8 1
A shouldReplaceNodes() 0 13 3
A dataProviderForShouldReplaceNodes() 0 16 1
A shouldWalkChildren() 0 24 1
A shouldProvideChildren() 0 3 1
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
 *
8
 * @license GPL-3.0
9
 * @author Gerrit Addiks <[email protected]>
10
 */
11
12
namespace Addiks\StoredSQL\Tests\Unit\AbstractSyntaxTree;
13
14
use Addiks\StoredSQL\AbstractSyntaxTree\SqlAstBranch;
15
use Addiks\StoredSQL\AbstractSyntaxTree\SqlAstMutableNode;
16
use Addiks\StoredSQL\AbstractSyntaxTree\SqlAstNode;
17
use PHPUnit\Framework\MockObject\MockObject;
18
use PHPUnit\Framework\TestCase;
19
20
final class SqlAstBranchTest extends TestCase
21
{
22
    private SqlAstBranch $subject;
23
24
    /** @var MockObject&SqlAstNode $childA */
25
    private SqlAstNode $childA;
26
27
    /** @var MockObject&SqlAstMutableNode $childB */
28
    private SqlAstMutableNode $childB;
29
30
    /** @var MockObject&SqlAstNode $childC */
31
    private SqlAstNode $childC;
32
33
    public function setUp(): void
34
    {
35
        $this->childA = $this->createMock(SqlAstNode::class);
36
        $this->childB = $this->createMock(SqlAstMutableNode::class);
37
        $this->childC = $this->createMock(SqlAstNode::class);
38
39
        $this->subject = $this->getMockForAbstractClass(SqlAstBranch::class, [
40
            [$this->childA, $this->childB, $this->childC],
41
        ]);
42
    }
43
44
    /**
45
     * @test
46
     * @covers SqlAstBranch::children
47
     */
48
    public function shouldProvideChildren(): void
49
    {
50
        $this->assertSame([$this->childA, $this->childB, $this->childC], $this->subject->children());
51
    }
52
53
    /**
54
     * @test
55
     * @covers SqlAstBranch::hash
56
     */
57
    public function shouldGenerateHash(): void
58
    {
59
        $this->childA->method('hash')->willReturn('hashA');
0 ignored issues
show
Bug introduced by
The method method() does not exist on Addiks\StoredSQL\AbstractSyntaxTree\SqlAstNode. ( Ignorable by Annotation )

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

59
        $this->childA->/** @scrutinizer ignore-call */ 
60
                       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...
60
        $this->childB->method('hash')->willReturn('hashB');
0 ignored issues
show
Bug introduced by
The method method() does not exist on Addiks\StoredSQL\Abstrac...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

60
        $this->childB->/** @scrutinizer ignore-call */ 
61
                       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...
61
        $this->childC->method('hash')->willReturn('hashC');
62
63
        $this->assertSame(md5('hashA.hashB.hashC'), $this->subject->hash());
64
    }
65
66
    /**
67
     * @test
68
     * @covers SqlAstBranch::walk
69
     */
70
    public function shouldWalkChildren(): void
71
    {
72
        $mutatorAExpectedChilds = [$this->childA, $this->childB, $this->childC];
73
        $mutatorA = function (SqlAstNode $child, int $offset, SqlAstMutableNode $subject) use (&$mutatorAExpectedChilds): void {
74
            $this->assertSame($this->subject, $subject);
75
            $this->assertNotEmpty($mutatorAExpectedChilds);
76
            $this->assertEquals(3 - count($mutatorAExpectedChilds), $offset);
77
            $this->assertSame(array_shift($mutatorAExpectedChilds), $child);
78
        };
79
80
        $mutatorBExpectedChilds = [$this->childA, $this->childB, $this->childC];
81
        $mutatorB = function (SqlAstNode $child, int $offset, SqlAstMutableNode $subject) use (&$mutatorBExpectedChilds): void {
82
            $this->assertSame($this->subject, $subject);
83
            $this->assertNotEmpty($mutatorBExpectedChilds);
84
            $this->assertEquals(3 - count($mutatorBExpectedChilds), $offset);
85
            $this->assertSame(array_shift($mutatorBExpectedChilds), $child);
86
        };
87
88
        /** @var array<callable> $mutators */
89
        $mutators = array($mutatorA, $mutatorB);
90
91
        $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\Abstrac...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

91
        $this->childB->/** @scrutinizer ignore-call */ 
92
                       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...
92
93
        $this->subject->walk($mutators);
94
    }
95
96
    /**
97
     * @test
98
     * @covers SqlAstBranch::replace
99
     * @dataProvider dataProviderForShouldReplaceNodes
100
     */
101
    public function shouldReplaceNodes(int $offset, int $length, SqlAstNode $newNode, array $expectedChilds): void
102
    {
103
        $this->subject->replace($offset, $length, $newNode);
104
105
        $expectedChilds = array_map(function ($input) {
106
            if (is_string($input) && isset($this->{$input})) {
107
                $input = $this->{$input};
108
            }
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