Completed
Push — master ( 3970ef...3e0bdf )
by Jaap
09:34
created

GlobTest::testCanBeSatisfiedBySomethingBelow()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Flyfinder\Specification;
6
7
use Generator;
8
use InvalidArgumentException;
9
use PHPUnit\Framework\TestCase;
10
use function is_array;
11
use function sprintf;
12
13
/**
14
 * @coversDefaultClass \Flyfinder\Specification\Glob
15
 * @covers ::<private>
16
 * @covers ::isSatisfiedBy
17
 * @covers ::__construct
18
 */
19
final class GlobTest extends TestCase
20
{
21
    /**
22
     * @param mixed[] $file
23
     *
24
     * @dataProvider matchingPatternFileProvider
25
     * @dataProvider matchingPatternFileWithEscapeCharProvider
26
     *
27
     * @psalm-param array{basename: string, path: string, stream: resource, dirname: string, type: string, extension: string} $file
28
     */
29
    public function testGlobIsMatching(string $pattern, array $file) : void
30
    {
31
        $glob = new Glob($pattern);
32
33
        $this->assertTrue(
34
            $glob->isSatisfiedBy($file),
35
            sprintf('Failed: %s to match %s', $pattern, $file['path'])
36
        );
37
    }
38
39
    /**
40
     * @param mixed[] $file
41
     *
42
     * @dataProvider notMatchingPatternFileProvider
43
     * @psalm-param array{basename: string, path: string, stream: resource, dirname: string, type: string, extension: string} $file
44
     */
45
    public function testGlobIsNotMatching(string $pattern, array $file) : void
46
    {
47
        $glob = new Glob($pattern);
48
49
        $this->assertFalse(
50
            $glob->isSatisfiedBy($file),
51
            sprintf('Failed: %s to match %s', $pattern, $file['path'])
52
        );
53
    }
54
55
    /**
56
     * @dataProvider invalidPatternProvider
57
     */
58
    public function testInvalidGlobThrows(string $pattern) : void
59
    {
60
        $this->expectException(InvalidArgumentException::class);
61
        new Glob($pattern);
62
    }
63
64
    /**
65
     * @covers ::canBeSatisfiedBySomethingBelow
66
     */
67
    public function testCanBeSatisfiedBySomethingBelow() : void
68
    {
69
        $glob = new Glob('/**/*');
70
        $this->assertTrue($glob->canBeSatisfiedBySomethingBelow(['path' => 'src']));
71
    }
72
73
    public function invalidPatternProvider() : Generator
74
    {
75
        $invalidPatterns = [
76
            '[aaa',
77
            '{aaa',
78
            '{a,{b}',
79
            'aaaa', //path must be absolute
80
        ];
81
82
        foreach ($invalidPatterns as $pattern) {
83
            yield $pattern => [$pattern];
84
        }
85
    }
86
87
    public function matchingPatternFileProvider() : Generator
88
    {
89
        $input = [
90
            '/*.php' => 'test.php',
91
            '/src/*' => 'src/test.php',
92
            '/src/**/*.php' => 'src/subdir/test.php',
93
            '/src/**/*' => 'src/subdir/second/test.php',
94
            '/src/{subdir,other}/*' => [
95
                'src/subdir/test.php',
96
                'src/other/test.php',
97
            ],
98
            '/src/subdir/test-[a-c].php' => [
99
                'src/subdir/test-a.php',
100
                'src/subdir/test-b.php',
101
                'src/subdir/test-c.php',
102
            ],
103
            '/src/subdir/test-[^a-c].php' => 'src/subdir/test-d.php',
104
            '/src/subdir/test-?.php' => [
105
                'src/subdir/test-a.php',
106
                'src/subdir/test-b.php',
107
                'src/subdir/test-c.php',
108
                'src/subdir/test-~.php',
109
            ],
110
            '/src/subdir/test-}.php' => 'src/subdir/test-}.php',
111
        ];
112
113
        yield from $this->toTestData($input);
114
    }
115
116
    public function matchingPatternFileWithEscapeCharProvider() : Generator
117
    {
118
        $escapeChars = [
119
            '*',
120
            '?',
121
            '{',
122
            '}',
123
            '[',
124
            ']',
125
            '-',
126
            '^',
127
            '$',
128
            '~',
129
            '\\',
130
            '\\\\',
131
        ];
132
133
        foreach ($escapeChars as $char) {
134
            $file = sprintf('/src/test\\%s.php', $char);
135
136
            yield $file => [
137
                $file,
138
                ['path' => sprintf('src/test%s.php', $char)],
139
            ];
140
        }
141
    }
142
143
    public function notMatchingPatternFileProvider() : Generator
144
    {
145
        $input = [
146
            '/*.php' => 'test.css',
147
            '/src/*' => 'src/subdir/test.php',
148
            '/src/**/*.php' => 'src/subdir/test.css',
149
            '/src/subdir/test-[a-c].php' => 'src/subdir/test-d.php',
150
            '/src/subdir/test-[^a-c].php' => [
151
                'src/subdir/test-a.php',
152
                'src/subdir/test-b.php',
153
                'src/subdir/test-c.php',
154
            ],
155
            '/src' => 'test/file.php',
156
        ];
157
158
        yield from $this->toTestData($input);
159
    }
160
161
    /**
162
     * @param mixed[] $input
163
     */
164
    private function toTestData(array $input) : Generator
165
    {
166
        foreach ($input as $glob => $path) {
167
            if (!is_array($path)) {
168
                $path = [$path];
169
            }
170
171
            foreach ($path as $key => $item) {
172
                yield ($key !== 0 ? $key . ' - ' : '') . $glob => [
173
                    $glob,
174
                    ['path' => $item],
175
                ];
176
            }
177
        }
178
    }
179
}
180