Skip to content

Commit 880ed66

Browse files
committed
Initial stub implementations and test cases
1 parent 339c2c8 commit 880ed66

File tree

3 files changed

+191
-0
lines changed

3 files changed

+191
-0
lines changed

src/Util/FileMatcher.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* This file is part of PHPUnit.
4+
*
5+
* (c) Sebastian Bergmann <[email protected]>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
namespace PHPUnit\Util;
11+
12+
use RuntimeException;
13+
use const DIRECTORY_SEPARATOR;
14+
use function basename;
15+
use function dirname;
16+
use function is_dir;
17+
use function mkdir;
18+
use function realpath;
19+
use function str_starts_with;
20+
21+
/**
22+
* @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
23+
*
24+
* @internal This class is not covered by the backward compatibility promise for PHPUnit
25+
*/
26+
final readonly class FileMatcher
27+
{
28+
public static function match(string $path, FileMatcherPattern $pattern): bool
29+
{
30+
if (substr($path, 0, 1) !== '/') {
31+
throw new RuntimeException(sprintf(
32+
'Path "%s" must be absolute',
33+
$path
34+
));
35+
}
36+
return false;
37+
}
38+
}
39+

src/Util/FileMatcherPattern.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace PHPUnit\Util;
4+
5+
class FileMatcherPattern
6+
{
7+
public function __construct(public string $path)
8+
{
9+
}
10+
11+
}

tests/unit/Util/FileMatcherTest.php

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?php
2+
3+
namespace PHPUnit\Util;
4+
5+
use Generator;
6+
use PHPUnit\Framework\Attributes\DataProvider;
7+
use PHPUnit\Framework\TestCase;
8+
use RuntimeException;
9+
10+
class FileMatcherTest extends TestCase
11+
{
12+
public function testExceptionIfPathIsNotAbsolute(): void
13+
{
14+
$this->expectException(RuntimeException::class);
15+
$this->expectExceptionMessage('Path "foo/bar" must be absolute');
16+
FileMatcher::match('foo/bar', new FileMatcherPattern(''));
17+
}
18+
19+
/**
20+
* @param array<FileMatcherPattern,bool> $matchMap
21+
*/
22+
#[DataProvider('provideMatch')]
23+
public function testMatch(FileMatcherPattern $pattern, array $matchMap): void
24+
{
25+
self::assertMap($pattern, $matchMap);
26+
}
27+
28+
/**
29+
* @param array<FileMatcherPattern,bool> $matchMap
30+
*/
31+
#[DataProvider('provideWildcard')]
32+
public function testWildcard(FileMatcherPattern $pattern, array $matchMap): void
33+
{
34+
self::assertMap($pattern, $matchMap);
35+
}
36+
37+
/**
38+
* @return Generator<string,array{FileMatcherPattern,array<string,bool>}>
39+
*/
40+
public static function provideMatch(): Generator
41+
{
42+
yield 'exact path' => [
43+
new FileMatcherPattern('/path/to/example/Foo.php'),
44+
[
45+
'/path/to/example/Foo.php' => true,
46+
'/path/to/example/Bar.php' => false,
47+
],
48+
];
49+
50+
yield 'directory' => [
51+
new FileMatcherPattern('/path/to'),
52+
[
53+
'/path/to' => true,
54+
'/path/to/example/Foo.php' => true,
55+
'/path/foo/Bar.php' => false,
56+
],
57+
];
58+
}
59+
60+
/**
61+
* @return Generator<string,array{FileMatcherPattern,array<string,bool>}>
62+
*/
63+
public static function provideWildcard(): Generator
64+
{
65+
66+
yield 'leaf wildcard' => [
67+
new FileMatcherPattern('/path/*'),
68+
[
69+
'/path/foo/bar' => true,
70+
'/path/foo/baz' => true,
71+
'/path/baz.php' => true,
72+
'/path/foo/baz/boo.php' => true,
73+
'/path/example/file.php' => false,
74+
'/' => false,
75+
'' => false,
76+
],
77+
];
78+
79+
yield 'leaf directory wildcard' => [
80+
new FileMatcherPattern('/path/*'),
81+
[
82+
'/path/foo/bar' => true,
83+
'/path/foo/baz' => true,
84+
'/path/foo/baz/boo.php' => true,
85+
'/path/example/file.php' => false,
86+
'/' => false,
87+
'' => false,
88+
],
89+
];
90+
yield 'segment directory wildcard' => [
91+
new FileMatcherPattern('/path/*/bar'),
92+
[
93+
'/path/foo/bar' => true,
94+
'/path/foo/baz' => false,
95+
'/path/foo/bar/boo.php' => true,
96+
'/foo/bar/file.php' => false,
97+
],
98+
];
99+
100+
yield 'multiple segment directory wildcards' => [
101+
new FileMatcherPattern('/path/*/example/*/bar'),
102+
[
103+
'/path/zz/example/aa/bar' => true,
104+
'/path/zz/example/aa/bar/foo' => true,
105+
'/path/example/aa/bar/foo' => false,
106+
'/path/zz/example/bb/foo' => false,
107+
],
108+
];
109+
110+
yield 'partial wildcard' => [
111+
new FileMatcherPattern('/path/f*'),
112+
[
113+
'/path/foo/bar' => true,
114+
'/path/foo/baz' => true,
115+
'/path/boo' => false,
116+
'/path/boo/example/file.php' => false,
117+
],
118+
];
119+
120+
yield 'partial segment wildcard' => [
121+
new FileMatcherPattern('/path/f*/bar'),
122+
[
123+
'/path/foo/bar' => true,
124+
'/path/faa/bar' => true,
125+
'/path/foo/baz' => false,
126+
'/path/boo' => false,
127+
'/path/boo/example/file.php' => false,
128+
],
129+
];
130+
}
131+
132+
/**
133+
* @param array<FileMatcherPattern,bool> $matchMap
134+
*/
135+
private static function assertMap(FileMatcherPattern $pattern, array $matchMap): void
136+
{
137+
foreach ($matchMap as $candidate => $shouldMatch) {
138+
self::assertSame($shouldMatch, FileMatcher::match($candidate, $pattern));
139+
}
140+
}
141+
}

0 commit comments

Comments
 (0)