diff --git a/src/PresenterMapping/PresenterMapper.php b/src/PresenterMapping/PresenterMapper.php index df3136e..8ad96ec 100644 --- a/src/PresenterMapping/PresenterMapper.php +++ b/src/PresenterMapping/PresenterMapper.php @@ -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( diff --git a/tests/PresenterMapping/PresenterFactoryTest.phpt b/tests/PresenterMapping/PresenterFactoryTest.phpt new file mode 100644 index 0000000..65e069b --- /dev/null +++ b/tests/PresenterMapping/PresenterFactoryTest.phpt @@ -0,0 +1,104 @@ +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();