Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 1 addition & 17 deletions src/Analyzer/PatternString.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function matches(string $pattern): bool
return $isInThisNamespace || $isThisClass;
}

return $this->startsWithPattern($pattern);
return fnmatch($pattern, $this->value, \FNM_NOESCAPE);
}

public function toString(): string
Expand All @@ -43,20 +43,4 @@ private function containsWildcard(string $pattern): bool
|| str_contains($pattern, '.')
|| str_contains($pattern, '[');
}

private function startsWithPattern(string $pattern): bool
{
return 1 === preg_match('#^'.$this->convertShellToRegExPattern($pattern).'#', $this->value);
}

private function convertShellToRegExPattern(string $pattern): string
{
return strtr($pattern, [
'*' => '.*',
'?' => '.',
'.' => '\.',
'[!' => '[^',
'\\' => '\\\\',
]);
}
}
2 changes: 1 addition & 1 deletion src/Expression/ForClasses/ResideInOneOfTheseNamespaces.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public function evaluate(ClassDescription $theClass, Violations $violations, str
{
$resideInNamespace = false;
foreach ($this->namespaces as $namespace) {
if ($theClass->namespaceMatches($namespace)) {
if ($theClass->namespaceMatches($namespace.'*')) {
Copy link
Member

@micheleorselli micheleorselli Mar 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just out of curiosity, why do we need to add this? cc @AlessandroMinoccheri

Copy link
Contributor Author

@hgraca hgraca Mar 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its from a long time ago, but I guess it was because if a class is in a subnamespace is still in the given namespace.

However, looking at it now, it's out of scope fo this PR, and not having the * is a better option because we can match the namespace exactly or provide the namespace with a * which will match subnamespaces as well.

So, Im adding a fixup commit to remove this change.

The test ResideInOneOfTheseNamespacesTest::test_it_should_match_namespace_and_descendants will fail if this is not there, as it seems this expression has been designed to match the namespace or its descendants.

$resideInNamespace = true;
}
}
Expand Down
30 changes: 26 additions & 4 deletions tests/Unit/Analyzer/PatternStringTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,32 @@ public function test_it_works_for_simple_strings(): void
$this->assertFalse($pattern->matches('Something else'));
}

public function test_wildcard_is_for_alphanumeric(): void
/**
* @dataProvider providePatterns
*/
public function test_wildcard_is_for_alphanumeric(string $string, string $pattern, bool $expectedResult): void
{
$pattern = new PatternString('SoThisIsAnExample');
$this->assertTrue($pattern->matches('*This*'));
$this->assertFalse($pattern->matches('This*'));
$this->assertEquals($expectedResult, (new PatternString($string))->matches($pattern));
}

public function providePatterns(): array
{
return [
['SoThisIsAnExample', '*This*', true],
['SoThisIsAnExample', 'This*', false],
['SoThisIsAnExample', '*This', false],
['SoThisIsAnExample', 'SoThisIsAnExample', true],
['SoThisIsAnExample', 'So????????Example', true],
['SoThisIsAnExample', '*SoThisIsAnExample', true],
['SoThisIsAnExample', 'SoThisIsAnExample*', true],
['SoThisIsAnExample', 'So*Example', true],
['SoThisIsAnExample', '*ThisIsAnExample', true],
['SoThisIsAnExample', 'SoThisIsAn*', true],
['Food\Vegetables\Roots\Carrot', 'Food\*\Roots', false],
['Food\Vegetables\Roots\Orange\Carrot', 'Food\*\Roots', false],
['Food\Vegetables\Carrot', '*\Vegetables', false],
['Food\Vegetables\Roots\Carrot', '*\Vegetables', false],
['Food\Vegetables\Roots\Orange\Carrot', '*\Vegetables', false],
];
}
}