Completed
Push — master ( ce5d9a...b8256c )
by Jaap
08:59
created

GlobTest::testInvalidGlobThrows()   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 1
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
    public function invalidPatternProvider() : Generator
65
    {
66
        $invalidPatterns = [
67
            '[aaa',
68
            '{aaa',
69
            '{a,{b}',
70
            'aaaa', //path must be absolute
71
        ];
72
73
        foreach ($invalidPatterns as $pattern) {
74
            yield $pattern => [$pattern];
75
        }
76
    }
77
78
    public function matchingPatternFileProvider() : Generator
79
    {
80
        $input = [
81
            '/*.php' => 'test.php',
82
            '/src/*' => 'src/test.php',
83
            '/src/**/*.php' => 'src/subdir/test.php',
84
            '/src/**/*' => 'src/subdir/second/test.php',
85
            '/src/{subdir,other}/*' => [
86
                'src/subdir/test.php',
87
                'src/other/test.php',
88
            ],
89
            '/src/subdir/test-[a-c].php' => [
90
                'src/subdir/test-a.php',
91
                'src/subdir/test-b.php',
92
                'src/subdir/test-c.php',
93
            ],
94
            '/src/subdir/test-[^a-c].php' => 'src/subdir/test-d.php',
95
            '/src/subdir/test-?.php' => [
96
                'src/subdir/test-a.php',
97
                'src/subdir/test-b.php',
98
                'src/subdir/test-c.php',
99
                'src/subdir/test-~.php',
100
            ],
101
            '/src/subdir/test-}.php' => 'src/subdir/test-}.php',
102
        ];
103
104
        yield from $this->toTestData($input);
105
    }
106
107
    public function matchingPatternFileWithEscapeCharProvider() : Generator
108
    {
109
        $escapeChars = [
110
            '*',
111
            '?',
112
            '{',
113
            '}',
114
            '[',
115
            ']',
116
            '-',
117
            '^',
118
            '$',
119
            '~',
120
            '\\',
121
            '\\\\',
122
        ];
123
124
        foreach ($escapeChars as $char) {
125
            $file = sprintf('/src/test\\%s.php', $char);
126
            yield $file => [
127
                $file,
128
                ['path' => sprintf('src/test%s.php', $char)],
129
            ];
130
        }
131
    }
132
133
    public function notMatchingPatternFileProvider() : Generator
134
    {
135
        $input = [
136
            '/*.php' => 'test.css',
137
            '/src/*' => 'src/subdir/test.php',
138
            '/src/**/*.php' => 'src/subdir/test.css',
139
            '/src/subdir/test-[a-c].php' => 'src/subdir/test-d.php',
140
            '/src/subdir/test-[^a-c].php' => [
141
                'src/subdir/test-a.php',
142
                'src/subdir/test-b.php',
143
                'src/subdir/test-c.php',
144
            ],
145
            '/src' => 'test/file.php',
146
        ];
147
148
        yield from $this->toTestData($input);
149
    }
150
151
    /**
152
     * @param mixed[] $input
153
     */
154
    private function toTestData(array $input) : Generator
155
    {
156
        foreach ($input as $glob => $path) {
157
            if (!is_array($path)) {
158
                $path = [$path];
159
            }
160
161
            foreach ($path as $key => $item) {
162
                yield ($key !== 0 ? $key . ' - ' : '') . $glob => [
163
                    $glob,
164
                    ['path' => $item],
165
                ];
166
            }
167
        }
168
    }
169
}
170