Skip to content

Commit

Permalink
Fix compatibility with default Nette implementation
Browse files Browse the repository at this point in the history
When string mask does not explcitily specify module
mapping, default behavior should be to use '*Module\'.
Bug was introduced in 2.1.0.
  • Loading branch information
xificurk committed Oct 27, 2022
1 parent 05a1acf commit 450ecc4
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/PresenterMapping/PresenterMapper.php
Expand Up @@ -78,10 +78,12 @@ public function setModuleMapping(string $module, $mask): self
} elseif (is_string($mask)) {
$m = Strings::match($mask, '#^\\\\?([\w\\\\]*\\\\)?(\w*\*\w*?\\\\)?([\w\\\\]*\*\w*)\z#');
if ($m === null) {
$module = $module === '' ? '*' : $module;
throw new \InvalidArgumentException("Invalid mapping mask '$mask' for module '$module'.");
}
$this->moduleMapping[$module] = [$m[1], $m[2] ?? '*Module\\', $m[3]];
$this->moduleMapping[$module] = [$m[1], $m[2] !== '' ? $m[2] : '*Module\\', $m[3]];
} else {
$module = $module === '' ? '*' : $module;
throw new \InvalidArgumentException("Invalid mapping mask for module '$module'.");
}
uksort(
Expand Down
104 changes: 104 additions & 0 deletions tests/PresenterMapping/PresenterFactoryTest.phpt
@@ -0,0 +1,104 @@
<?php
declare(strict_types = 1);

namespace NepadaTests\PresenterMapping;

use Nepada\PresenterMapping\PresenterFactory;
use Nepada\PresenterMapping\PresenterMapper;
use NepadaTests\TestCase;
use Tester\Assert;

require_once __DIR__ . '/../bootstrap.php';


/**
* Based on Nette test cases to ensure compatibility with default implementation.
*
* @testCase
*/
class PresenterFactoryTest extends TestCase
{

private PresenterFactory $presenterFactory;

protected function setUp(): void
{
$mapper = new PresenterMapper();
$this->presenterFactory = new PresenterFactory($mapper);
}

public function testStandardMapping(): void
{
$factory = $this->presenterFactory;
$factory->setMapping([
'Foo2' => 'App2\*\*Presenter',
'Foo3' => 'My\App\*Mod\*Presenter',
]);

Assert::same('FooPresenter', $factory->formatPresenterClass('Foo'));
Assert::same('FooModule\BarPresenter', $factory->formatPresenterClass('Foo:Bar'));
Assert::same('FooModule\BarModule\BazPresenter', $factory->formatPresenterClass('Foo:Bar:Baz'));

Assert::same('Foo2Presenter', $factory->formatPresenterClass('Foo2'));
Assert::same('App2\BarPresenter', $factory->formatPresenterClass('Foo2:Bar'));
Assert::same('App2\Bar\BazPresenter', $factory->formatPresenterClass('Foo2:Bar:Baz'));

Assert::same('My\App\BarPresenter', $factory->formatPresenterClass('Foo3:Bar'));
Assert::same('My\App\BarMod\BazPresenter', $factory->formatPresenterClass('Foo3:Bar:Baz'));

Assert::same('NetteModule\FooPresenter', $factory->formatPresenterClass('Nette:Foo'));
}

public function testMappingWithUnspecifiedModule(): void
{
$factory = $this->presenterFactory;
$factory->setMapping([
'Foo2' => 'App2\*Presenter',
'Foo3' => 'My\App\*Presenter',
]);

Assert::same('Foo2Presenter', $factory->formatPresenterClass('Foo2'));
Assert::same('App2\BarPresenter', $factory->formatPresenterClass('Foo2:Bar'));
Assert::same('App2\BarModule\BazPresenter', $factory->formatPresenterClass('Foo2:Bar:Baz'));

Assert::same('My\App\BarPresenter', $factory->formatPresenterClass('Foo3:Bar'));
Assert::same('My\App\BarModule\BazPresenter', $factory->formatPresenterClass('Foo3:Bar:Baz'));
}

public function testMappingToSubnamespaces(): void
{
$factory = $this->presenterFactory;
$factory->setMapping([
'*' => ['App', 'Module\*', 'Presenter\*'],
]);
Assert::same('App\Module\Foo\Presenter\Bar', $factory->formatPresenterClass('Foo:Bar'));
Assert::same('App\Module\Universe\Module\Foo\Presenter\Bar', $factory->formatPresenterClass('Universe:Foo:Bar'));
}

public function testMappingDirectToNamespace(): void
{
$factory = $this->presenterFactory;
$factory->setMapping([
'*' => ['', '*', '*'],
]);
Assert::same('Module\Foo\Bar', $factory->formatPresenterClass('Module:Foo:Bar'));
}

public function testInvalidMapping(): void
{
Assert::exception(
function (): void {
$factory = $this->presenterFactory;
$factory->setMapping([
'*' => ['*', '*'],
]);
},
\InvalidArgumentException::class,
"Invalid mapping mask for module '*'.",
);
}

}


(new PresenterFactoryTest())->run();

0 comments on commit 450ecc4

Please sign in to comment.