Some updates to the URL registry (feat. tests).
This commit is contained in:
parent
05455d2be8
commit
eb0f65c5ef
7 changed files with 279 additions and 19 deletions
2
TODO.md
2
TODO.md
|
@ -1,5 +1,3 @@
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
- Create similarly addressable GD2/Imagick wrappers.
|
- Create similarly addressable GD2/Imagick wrappers.
|
||||||
|
|
||||||
- Create a URL formatter.
|
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
0.2410.32326
|
0.2410.42042
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
// ArrayUrlRegistry.php
|
// ArrayUrlRegistry.php
|
||||||
// Created: 2024-10-03
|
// Created: 2024-10-03
|
||||||
// Updated: 2024-10-03
|
// Updated: 2024-10-04
|
||||||
|
|
||||||
namespace Index\Urls;
|
namespace Index\Urls;
|
||||||
|
|
||||||
|
@ -15,15 +15,22 @@ class ArrayUrlRegistry implements UrlRegistry {
|
||||||
/** @var array<string, array{path: string, query: array<string, string>, fragment: string}> */
|
/** @var array<string, array{path: string, query: array<string, string>, fragment: string}> */
|
||||||
private array $urls = [];
|
private array $urls = [];
|
||||||
|
|
||||||
public function register(string $name, string $path, array $query = [], string $fragment = ''): void {
|
public function register(UrlSource|string $nameOrSource, string $path = '', array $query = [], string $fragment = ''): void {
|
||||||
if(array_key_exists($name, $this->urls))
|
if($nameOrSource instanceof UrlSource) {
|
||||||
throw new InvalidArgumentException('A URL format with $name has already been registered.');
|
$nameOrSource->registerUrls($this);
|
||||||
if($path === '')
|
return;
|
||||||
throw new InvalidArgumentException('$path may not be empty.');
|
}
|
||||||
if($path[0] !== '/')
|
|
||||||
throw new InvalidArgumentException('$path must begin with /.');
|
|
||||||
|
|
||||||
$this->urls[$name] = [
|
if($nameOrSource === '')
|
||||||
|
throw new InvalidArgumentException('$nameOrSource may not be empty');
|
||||||
|
if(array_key_exists($nameOrSource, $this->urls))
|
||||||
|
throw new InvalidArgumentException('A URL format with $nameOrSource has already been registered');
|
||||||
|
if($path === '')
|
||||||
|
throw new InvalidArgumentException('$path may not be empty');
|
||||||
|
if(!str_starts_with($path, '/'))
|
||||||
|
throw new InvalidArgumentException('$path must begin with /');
|
||||||
|
|
||||||
|
$this->urls[$nameOrSource] = [
|
||||||
'path' => $path,
|
'path' => $path,
|
||||||
'query' => $query,
|
'query' => $query,
|
||||||
'fragment' => $fragment,
|
'fragment' => $fragment,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
// ScopedUrlRegistry.php
|
// ScopedUrlRegistry.php
|
||||||
// Created: 2024-10-03
|
// Created: 2024-10-03
|
||||||
// Updated: 2024-10-03
|
// Updated: 2024-10-04
|
||||||
|
|
||||||
namespace Index\Urls;
|
namespace Index\Urls;
|
||||||
|
|
||||||
|
@ -26,9 +26,21 @@ class ScopedUrlRegistry implements UrlRegistry {
|
||||||
throw new InvalidArgumentException('$pathPrefix must start with a / if it is non-empty');
|
throw new InvalidArgumentException('$pathPrefix must start with a / if it is non-empty');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function register(string $name, string $path, array $query = [], string $fragment = ''): void {
|
public function register(UrlSource|string $nameOrSource, string $path = '', array $query = [], string $fragment = ''): void {
|
||||||
|
if($nameOrSource instanceof UrlSource) {
|
||||||
|
$nameOrSource->registerUrls($this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($nameOrSource === '')
|
||||||
|
throw new InvalidArgumentException('$nameOrSource may not be empty');
|
||||||
|
if($path === '')
|
||||||
|
throw new InvalidArgumentException('$path may not be empty');
|
||||||
|
if(!str_starts_with($path, '/'))
|
||||||
|
throw new InvalidArgumentException('$path must begin with /');
|
||||||
|
|
||||||
$this->registry->register(
|
$this->registry->register(
|
||||||
$this->namePrefix . $name,
|
$this->namePrefix . $nameOrSource,
|
||||||
$this->pathPrefix . $path,
|
$this->pathPrefix . $path,
|
||||||
$query,
|
$query,
|
||||||
$fragment
|
$fragment
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
// UrlRegistry.php
|
// UrlRegistry.php
|
||||||
// Created: 2024-10-03
|
// Created: 2024-10-03
|
||||||
// Updated: 2024-10-03
|
// Updated: 2024-10-04
|
||||||
|
|
||||||
namespace Index\Urls;
|
namespace Index\Urls;
|
||||||
|
|
||||||
|
@ -16,14 +16,14 @@ interface UrlRegistry {
|
||||||
*
|
*
|
||||||
* TODO: explain formatting system
|
* TODO: explain formatting system
|
||||||
*
|
*
|
||||||
* @param string $name Name of the format.
|
* @param UrlSource|string $nameOrSource Name of the format or a URL source object.
|
||||||
* @param string $path Path portion of the URL.
|
* @param string $path Path portion of the URL. Required if $nameOrSource is a name string.
|
||||||
* @param array<string, string> $query Query string variables of the URL.
|
* @param array<string, string> $query Query string variables of the URL.
|
||||||
* @param string $fragment Fragment portion of the URL.
|
* @param string $fragment Fragment portion of the URL.
|
||||||
* @throws InvalidArgumentException If $name has already been registered.
|
* @throws InvalidArgumentException If $name has already been registered.
|
||||||
* @throws InvalidArgumentException If $path if empty or does not start with a /.
|
* @throws InvalidArgumentException If $path if empty or does not start with a /.
|
||||||
*/
|
*/
|
||||||
function register(string $name, string $path, array $query = [], string $fragment = ''): void;
|
function register(UrlSource|string $nameOrSource, string $path = '', array $query = [], string $fragment = ''): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format a URL.
|
* Format a URL.
|
||||||
|
|
16
src/Urls/UrlSourceTrait.php
Normal file
16
src/Urls/UrlSourceTrait.php
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
// UrlSourceTrait.php
|
||||||
|
// Created: 2024-10-04
|
||||||
|
// Updated: 2024-10-04
|
||||||
|
|
||||||
|
namespace Index\Urls;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides an implementation of UrlSource::registerUrls that uses the attributes.
|
||||||
|
* For more advanced use, everything can be use'd separately and UrlFormat::register called manually.
|
||||||
|
*/
|
||||||
|
trait UrlSourceTrait {
|
||||||
|
public function registerUrls(UrlRegistry $registry): void {
|
||||||
|
UrlFormat::register($registry, $this);
|
||||||
|
}
|
||||||
|
}
|
227
tests/UrlRegistryTest.php
Normal file
227
tests/UrlRegistryTest.php
Normal file
|
@ -0,0 +1,227 @@
|
||||||
|
<?php
|
||||||
|
// UrlRegistryTest.php
|
||||||
|
// Created: 2024-10-04
|
||||||
|
// Updated: 2024-10-04
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use PHPUnit\Framework\Attributes\{CoversClass,UsesClass};
|
||||||
|
use Index\Urls\{ArrayUrlRegistry,ScopedUrlRegistry,UrlFormat,UrlRegistry,UrlSource,UrlSourceTrait};
|
||||||
|
|
||||||
|
#[CoversClass(ArrayUrlRegistry::class)]
|
||||||
|
#[CoversClass(ScopedUrlRegistry::class)]
|
||||||
|
#[CoversClass(UrlFormat::class)]
|
||||||
|
#[CoversClass(UrlSourceTrait::class)]
|
||||||
|
#[UsesClass(UrlRegistry::class)]
|
||||||
|
#[UsesClass(UrlSource::class)]
|
||||||
|
final class UrlRegistryTest extends TestCase {
|
||||||
|
public function testUrlRegistration(): void {
|
||||||
|
$arrReg = new ArrayUrlRegistry;
|
||||||
|
|
||||||
|
$arrReg->register('soap', '/soap/<soap>/soap-<soap>', ['soap' => '<soap>'], '<soap>');
|
||||||
|
$this->assertEquals('/soap/beans/soap-beans?soap=beans#beans', $arrReg->format('soap', ['soap' => 'beans']));
|
||||||
|
|
||||||
|
$this->assertEquals('', $arrReg->format('does-not-exist', ['test' => 'test']));
|
||||||
|
|
||||||
|
$nameScopeOnly = $arrReg->scopeTo(namePrefix: 'pfx-');
|
||||||
|
$nameScopeOnly->register('cat', '/meow', ['id' => 'c<id>']);
|
||||||
|
$this->assertEquals('/meow?id=c50', $nameScopeOnly->format('cat', ['id' => '50']));
|
||||||
|
$this->assertEquals('/meow?id=c', $arrReg->format('pfx-cat')); // this is a little undesirable but just keep your query args clean :)
|
||||||
|
$this->assertEquals('', $arrReg->format('cat', ['id' => '84']));
|
||||||
|
|
||||||
|
$pathScopeOnly = $arrReg->scopeTo(pathPrefix: '/prefix');
|
||||||
|
$pathScopeOnly->register('dog', '/woof', ['type' => '<woof>']);
|
||||||
|
$this->assertEquals('/prefix/woof', $pathScopeOnly->format('dog'));
|
||||||
|
$this->assertEquals('/prefix/woof?type=borf', $arrReg->format('dog', ['woof' => 'borf']));
|
||||||
|
|
||||||
|
// we cannot access dog cus pfx- gets prepended
|
||||||
|
$this->assertEquals('', $nameScopeOnly->format('dog'));
|
||||||
|
|
||||||
|
// we CAN access cat because path prefixing only applies to registration
|
||||||
|
// not sure when you'd want this behaviour but its entirely transparent to implement soooooooo why not lmao
|
||||||
|
$this->assertEquals('/meow?id=cactuallydog', $pathScopeOnly->format('pfx-cat', ['id' => 'actuallydog']));
|
||||||
|
|
||||||
|
// this is debatably the only scope impl that makes sense, but again zero overhead
|
||||||
|
$scopedReg = $arrReg->scopeTo('pfx2-', '/also');
|
||||||
|
$scopedReg->register('fragmented', '/this/one/has/a/fragment', fragment: 'p<post>');
|
||||||
|
$this->assertEquals('/also/this/one/has/a/fragment#p9001', $scopedReg->format('fragmented', ['post' => 9001]));
|
||||||
|
$this->assertEquals('/also/this/one/has/a/fragment#p20001', $arrReg->format('pfx2-fragmented', ['post' => 20001]));
|
||||||
|
|
||||||
|
$sourceClass = new class implements UrlSource {
|
||||||
|
use UrlSourceTrait;
|
||||||
|
|
||||||
|
#[UrlFormat('method-a', '/method-a')]
|
||||||
|
public function a(): void {}
|
||||||
|
|
||||||
|
#[UrlFormat('method-b', '/method-b', ['beans' => '<count>', 'test' => '<mode>'])]
|
||||||
|
public function b(): void {}
|
||||||
|
|
||||||
|
#[UrlFormat('method-c', '/method-c', fragment: '<count>')]
|
||||||
|
public function c(): void {}
|
||||||
|
|
||||||
|
#[UrlFormat('method-d', '/method-d', fragment: '<count>')]
|
||||||
|
public function d(): void {}
|
||||||
|
|
||||||
|
#[UrlFormat('method-e', '/method-e/<mode>', ['count' => '<count>'])]
|
||||||
|
public function e(): void {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// can't use path scope only because of the names
|
||||||
|
$arrReg->register($sourceClass);
|
||||||
|
$nameScopeOnly->register($sourceClass);
|
||||||
|
$scopedReg->register($sourceClass);
|
||||||
|
|
||||||
|
$this->assertEquals('/method-a', $arrReg->format('method-a'));
|
||||||
|
$this->assertEquals('/method-b', $arrReg->format('method-b'));
|
||||||
|
$this->assertEquals('/method-b?beans=720', $arrReg->format('method-b', ['count' => 720]));
|
||||||
|
$this->assertEquals('/method-b?beans=720&test=wowzers', $arrReg->format('method-b', ['count' => 720, 'mode' => 'wowzers']));
|
||||||
|
$this->assertEquals('/method-c', $arrReg->format('method-c'));
|
||||||
|
$this->assertEquals('/method-c#720', $arrReg->format('method-c', ['count' => 720]));
|
||||||
|
$this->assertEquals('/method-d', $arrReg->format('method-d'));
|
||||||
|
$this->assertEquals('/method-d#98342389', $arrReg->format('method-d', ['count' => 98342389]));
|
||||||
|
$this->assertEquals('/method-e/', $arrReg->format('method-e'));
|
||||||
|
$this->assertEquals('/method-e/wowzers', $arrReg->format('method-e', ['mode' => 'wowzers']));
|
||||||
|
$this->assertEquals('/method-e/wowzers?count=720', $arrReg->format('method-e', ['count' => 720, 'mode' => 'wowzers']));
|
||||||
|
|
||||||
|
$this->assertEquals('/method-a', $arrReg->format('pfx-method-a'));
|
||||||
|
$this->assertEquals('/method-b', $arrReg->format('pfx-method-b'));
|
||||||
|
$this->assertEquals('/method-b?beans=720', $arrReg->format('pfx-method-b', ['count' => 720]));
|
||||||
|
$this->assertEquals('/method-b?beans=720&test=wowzers', $arrReg->format('pfx-method-b', ['count' => 720, 'mode' => 'wowzers']));
|
||||||
|
$this->assertEquals('/method-c', $arrReg->format('pfx-method-c'));
|
||||||
|
$this->assertEquals('/method-c#720', $arrReg->format('pfx-method-c', ['count' => 720]));
|
||||||
|
$this->assertEquals('/method-d', $arrReg->format('pfx-method-d'));
|
||||||
|
$this->assertEquals('/method-d#98342389', $arrReg->format('pfx-method-d', ['count' => 98342389]));
|
||||||
|
$this->assertEquals('/method-e/', $arrReg->format('pfx-method-e'));
|
||||||
|
$this->assertEquals('/method-e/wowzers', $arrReg->format('pfx-method-e', ['mode' => 'wowzers']));
|
||||||
|
$this->assertEquals('/method-e/wowzers?count=720', $arrReg->format('pfx-method-e', ['count' => 720, 'mode' => 'wowzers']));
|
||||||
|
|
||||||
|
$this->assertEquals('/also/method-a', $arrReg->format('pfx2-method-a'));
|
||||||
|
$this->assertEquals('/also/method-b', $arrReg->format('pfx2-method-b'));
|
||||||
|
$this->assertEquals('/also/method-b?beans=720', $arrReg->format('pfx2-method-b', ['count' => 720]));
|
||||||
|
$this->assertEquals('/also/method-b?beans=720&test=wowzers', $arrReg->format('pfx2-method-b', ['count' => 720, 'mode' => 'wowzers']));
|
||||||
|
$this->assertEquals('/also/method-c', $arrReg->format('pfx2-method-c'));
|
||||||
|
$this->assertEquals('/also/method-c#720', $arrReg->format('pfx2-method-c', ['count' => 720]));
|
||||||
|
$this->assertEquals('/also/method-d', $arrReg->format('pfx2-method-d'));
|
||||||
|
$this->assertEquals('/also/method-d#98342389', $arrReg->format('pfx2-method-d', ['count' => 98342389]));
|
||||||
|
$this->assertEquals('/also/method-e/', $arrReg->format('pfx2-method-e'));
|
||||||
|
$this->assertEquals('/also/method-e/wowzers', $arrReg->format('pfx2-method-e', ['mode' => 'wowzers']));
|
||||||
|
$this->assertEquals('/also/method-e/wowzers?count=720', $arrReg->format('pfx2-method-e', ['count' => 720, 'mode' => 'wowzers']));
|
||||||
|
|
||||||
|
$this->assertEquals('/method-a', $nameScopeOnly->format('method-a'));
|
||||||
|
$this->assertEquals('/method-b', $nameScopeOnly->format('method-b'));
|
||||||
|
$this->assertEquals('/method-b?beans=720', $nameScopeOnly->format('method-b', ['count' => 720]));
|
||||||
|
$this->assertEquals('/method-b?beans=720&test=wowzers', $nameScopeOnly->format('method-b', ['count' => 720, 'mode' => 'wowzers']));
|
||||||
|
$this->assertEquals('/method-c', $nameScopeOnly->format('method-c'));
|
||||||
|
$this->assertEquals('/method-c#720', $nameScopeOnly->format('method-c', ['count' => 720]));
|
||||||
|
$this->assertEquals('/method-d', $nameScopeOnly->format('method-d'));
|
||||||
|
$this->assertEquals('/method-d#98342389', $nameScopeOnly->format('method-d', ['count' => 98342389]));
|
||||||
|
$this->assertEquals('/method-e/', $nameScopeOnly->format('method-e'));
|
||||||
|
$this->assertEquals('/method-e/wowzers', $nameScopeOnly->format('method-e', ['mode' => 'wowzers']));
|
||||||
|
$this->assertEquals('/method-e/wowzers?count=720', $nameScopeOnly->format('method-e', ['count' => 720, 'mode' => 'wowzers']));
|
||||||
|
|
||||||
|
$this->assertEquals('/also/method-a', $scopedReg->format('method-a'));
|
||||||
|
$this->assertEquals('/also/method-b', $scopedReg->format('method-b'));
|
||||||
|
$this->assertEquals('/also/method-b?beans=720', $scopedReg->format('method-b', ['count' => 720]));
|
||||||
|
$this->assertEquals('/also/method-b?beans=720&test=wowzers', $scopedReg->format('method-b', ['count' => 720, 'mode' => 'wowzers']));
|
||||||
|
$this->assertEquals('/also/method-c', $scopedReg->format('method-c'));
|
||||||
|
$this->assertEquals('/also/method-c#720', $scopedReg->format('method-c', ['count' => 720]));
|
||||||
|
$this->assertEquals('/also/method-d', $scopedReg->format('method-d'));
|
||||||
|
$this->assertEquals('/also/method-d#98342389', $scopedReg->format('method-d', ['count' => 98342389]));
|
||||||
|
$this->assertEquals('/also/method-e/', $scopedReg->format('method-e'));
|
||||||
|
$this->assertEquals('/also/method-e/wowzers', $scopedReg->format('method-e', ['mode' => 'wowzers']));
|
||||||
|
$this->assertEquals('/also/method-e/wowzers?count=720', $scopedReg->format('method-e', ['count' => 720, 'mode' => 'wowzers']));
|
||||||
|
|
||||||
|
// now that there's more going on within the registry lets try this again!
|
||||||
|
$this->assertEquals('', $arrReg->format('does-not-exist', ['test' => 'test']));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUrlVariableSerialisation(): void {
|
||||||
|
$registry = new ArrayUrlRegistry;
|
||||||
|
$registry->register('test', '/<value>', ['p' => '<page>']);
|
||||||
|
|
||||||
|
$this->assertEquals('/', $registry->format('test'));
|
||||||
|
$this->assertEquals('/string', $registry->format('test', ['value' => 'string']));
|
||||||
|
$this->assertEquals('/1234567890', $registry->format('test', ['value' => 1234567890]));
|
||||||
|
$this->assertEquals('/1234.5678', $registry->format('test', ['value' => 1234.5678]));
|
||||||
|
$this->assertEquals('/a,b,c', $registry->format('test', ['value' => ['a', 'b', 'c']]));
|
||||||
|
$this->assertEquals('/12,b,4.5', $registry->format('test', ['value' => [12, 'b', 4.5]]));
|
||||||
|
$this->assertEquals('/1', $registry->format('test', ['value' => true]));
|
||||||
|
$this->assertEquals('/', $registry->format('test', ['value' => false]));
|
||||||
|
$this->assertEquals('/', $registry->format('test', ['value' => null]));
|
||||||
|
$this->assertEquals('/', $registry->format('test', ['value' => []]));
|
||||||
|
|
||||||
|
// "page" is a special case where 1 is considered default
|
||||||
|
// idk if it makes sense for this to be hardcoded, probably not but it makes sense 99.9% of the times so eat pant.
|
||||||
|
$this->assertEquals('/', $registry->format('test', ['value' => 0, 'page' => 0]));
|
||||||
|
$this->assertEquals('/1', $registry->format('test', ['value' => 1, 'page' => 1]));
|
||||||
|
$this->assertEquals('/2?p=2', $registry->format('test', ['value' => 2, 'page' => 2]));
|
||||||
|
$this->assertEquals('/?p=2', $registry->format('test', ['value' => 0, 'page' => 2]));
|
||||||
|
|
||||||
|
$stringable = new class implements Stringable {
|
||||||
|
public function __toString(): string {
|
||||||
|
return 'meow';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$this->assertEquals('/meow', $registry->format('test', ['value' => $stringable]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUrlRegistrationBlankNameException(): void {
|
||||||
|
$this->expectException(InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionMessage('$nameOrSource may not be empty');
|
||||||
|
|
||||||
|
(new ArrayUrlRegistry)->register('');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUrlRegistrationDupeNameException(): void {
|
||||||
|
$this->expectException(InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionMessage('A URL format with $nameOrSource has already been registered');
|
||||||
|
|
||||||
|
$registry = new ArrayUrlRegistry;
|
||||||
|
$registry->register('test', '/path1');
|
||||||
|
$registry->register('test', '/path2');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUrlRegistrationBlankPathException(): void {
|
||||||
|
$this->expectException(InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionMessage('$path may not be empty');
|
||||||
|
|
||||||
|
(new ArrayUrlRegistry)->register('test', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUrlRegistrationNonRootPathException(): void {
|
||||||
|
$this->expectException(InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionMessage('$path must begin with /');
|
||||||
|
|
||||||
|
(new ArrayUrlRegistry)->register('test', 'soap');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUrlRegistrationScopedNonRootPrefixException(): void {
|
||||||
|
$this->expectException(InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionMessage('$pathPrefix must start with a / if it is non-empty');
|
||||||
|
|
||||||
|
(new ArrayUrlRegistry)->scopeTo('beans', 'beans');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUrlRegistrationScopedBlankNameException(): void {
|
||||||
|
$this->expectException(InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionMessage('$nameOrSource may not be empty');
|
||||||
|
|
||||||
|
(new ArrayUrlRegistry)->scopeTo('beans', '/beans')->register('');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUrlRegistrationScopedBlankPathException(): void {
|
||||||
|
$this->expectException(InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionMessage('$path may not be empty');
|
||||||
|
|
||||||
|
(new ArrayUrlRegistry)->scopeTo('beans', '/beans')->register('test', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUrlRegistrationScopedNonRootPathException(): void {
|
||||||
|
$this->expectException(InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionMessage('$path must begin with /');
|
||||||
|
|
||||||
|
(new ArrayUrlRegistry)->scopeTo('beans', '/beans')->register('test', 'soap');
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue