diff --git a/src/DefaultPathStrategy.php b/src/DefaultPathStrategy.php index 787a3ce..5122181 100644 --- a/src/DefaultPathStrategy.php +++ b/src/DefaultPathStrategy.php @@ -7,11 +7,11 @@ class DefaultPathStrategy implements PathStrategy /** * @inheritDoc */ - public function updatePath(array $items, ?string $suffix = null): string + public function updatePath(array $items, string $separator, ?string $suffix = null): string { if (empty($items)) { return ''; } - return $suffix ? implode('/', $items) . $suffix : implode('/', $items); + return $suffix ? implode($separator, $items) . $suffix : implode($separator, $items); } } \ No newline at end of file diff --git a/src/DefaultUrlStrategy.php b/src/DefaultUrlStrategy.php index 66a30bf..5fa73dc 100644 --- a/src/DefaultUrlStrategy.php +++ b/src/DefaultUrlStrategy.php @@ -63,7 +63,7 @@ public function updateQuery(array $items): string /** * @inheritDoc */ - public function updatePath(array $items, ?string $suffix = null): string + public function updatePath(array $items, string $separator, ?string $suffix = null): string { if (empty($items)) { return ''; diff --git a/src/Path.php b/src/Path.php index e841a61..b8fa76a 100644 --- a/src/Path.php +++ b/src/Path.php @@ -9,15 +9,17 @@ class Path extends AbstractPath protected PathStrategy $strategy; protected ?string $suffix = null; + protected string $separator; /** * @param string $source + * @param string $separator * @param PathStrategy|null $strategy */ - public function __construct(string $source, ?PathStrategy $strategy = null) + public function __construct(string $source, string $separator = DIRECTORY_SEPARATOR, ?PathStrategy $strategy = null) { $this->assertNotEmpty($source); - $this->initUrlPath($strategy); + $this->initUrlPath($separator, $strategy); parent::__construct($source); } @@ -33,20 +35,23 @@ private function assertNotEmpty($source) } /** + * @param string $separator * @param PathStrategy|null $strategy * @return $this */ - protected function initUrlPath(?PathStrategy $strategy = null): static + protected function initUrlPath(string $separator, ?PathStrategy $strategy = null): static { $this->strategy = $strategy ?? new DefaultPathStrategy(); + $this->separator = $separator; return $this; } /** + * @param string $separator * @param PathStrategy|null $strategy * @return static */ - public static function createBlank(?PathStrategy $strategy = null): static + public static function createBlank(string $separator = DIRECTORY_SEPARATOR, ?PathStrategy $strategy = null): static { static $prototypePath; if (!$prototypePath instanceof Path) { @@ -56,7 +61,7 @@ public static function createBlank(?PathStrategy $strategy = null): static $prototypePath->items = []; $prototypePath->source = ''; } - return (clone $prototypePath)->initUrlPath($strategy); + return (clone $prototypePath)->initUrlPath($separator, $strategy); } /** @@ -93,7 +98,7 @@ protected function parse(string $source) */ public function getSeparator(): string { - return '/'; + return $this->separator; } /** @@ -135,7 +140,7 @@ public function setSuffix(?string $suffix): void */ public function updateSource(): void { - $this->source = $this->strategy->updatePath($this->items, $this->suffix); + $this->source = $this->strategy->updatePath($this->items, $this->separator, $this->suffix); } /** @@ -213,7 +218,8 @@ private function replaceIn(int $idx, string $search, string $replace, string $pa */ public function setBy(string $currentValue, string $newValue): void { - if (!$key = $this->getKey($currentValue)) { + $key = $this->getKey($currentValue); + if ($key === null) { throw new InvalidPathException(sprintf('You are trying to replace "%s" with "%s", but there is no such item in the path.', $currentValue, $newValue)); } $this->items[$key] = $newValue; diff --git a/src/PathStrategy.php b/src/PathStrategy.php index 9bef405..c82c7aa 100644 --- a/src/PathStrategy.php +++ b/src/PathStrategy.php @@ -7,8 +7,9 @@ interface PathStrategy /** * @param array $items + * @param string $separator * @param string|null $suffix * @return string */ - public function updatePath(array $items, ?string $suffix = null): string; + public function updatePath(array $items, string $separator, ?string $suffix = null): string; } \ No newline at end of file diff --git a/src/Url.php b/src/Url.php index 4ed9a6e..82b8c2d 100644 --- a/src/Url.php +++ b/src/Url.php @@ -4,18 +4,6 @@ use Compass\Exception\InvalidUrlException; -/** - * - * |--------------------------------------absolute url-----------------------------------| - * | | - * |----------------base url----------------|------------------relative url--------------| - * | | | - * | authority | path query fragment | - * | /‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾\|/‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾\ /‾‾‾‾‾‾‾‾‾\ /‾‾‾‾‾‾\ | - * http://grigor:password@vinograd.soft:8080/path/to/resource.json?query=value#fragment - * \__/ \___/ \_____/ \___________/ \__/ \___/ - * scheme user password host port suffix - */ class Url extends AbstractPath { /** @@ -32,22 +20,22 @@ class Url extends AbstractPath const SUFFIX = ':suffix'; /** - * key state + * state keys */ const USER_STATE = 1 << 0; const PASSWORD_STATE = 1 << 1; const HOST_STATE = 1 << 2; - const PORT_KEY = 1 << 3; + const PORT_STATE = 1 << 3; const PATH_STATE = 1 << 0; const QUERY_STATE = 1 << 1; - const FRAGMENT_KEY = 1 << 2; + const FRAGMENT_STATE = 1 << 2; - const AUTHORITY_WHOLE = self::USER_STATE | self::PASSWORD_STATE | self::HOST_STATE | self::PORT_KEY; - const RELATIVE_URL_WHOLE = self::PATH_STATE | self::QUERY_STATE | self::FRAGMENT_KEY; + const AUTHORITY_WHOLE = self::USER_STATE | self::PASSWORD_STATE | self::HOST_STATE | self::PORT_STATE; + const RELATIVE_URL_WHOLE = self::PATH_STATE | self::QUERY_STATE | self::FRAGMENT_STATE; /** - * current state + * current states */ protected int $authoritySate = self::AUTHORITY_WHOLE; protected int $relativeUrlState = self::RELATIVE_URL_WHOLE; @@ -90,7 +78,7 @@ protected function initUrl( { $this->isIdnToAscii = $isIdnToAscii; $this->updateStrategy = $updateStrategy ?? new DefaultUrlStrategy(); - $this->path = Path::createBlank($this->updateStrategy); + $this->path = Path::createBlank('/', $this->updateStrategy); $this->urlQuery = Query::createBlank($this->updateStrategy); return $this; } @@ -155,7 +143,7 @@ public function setUpdateStrategy(UrlStrategy $updateStrategy): void $this->authoritySate &= ~self::PASSWORD_STATE; $this->relativeUrlState &= ~self::QUERY_STATE; $this->relativeUrlState &= ~self::PATH_STATE; - $this->relativeUrlState &= ~self::FRAGMENT_KEY; + $this->relativeUrlState &= ~self::FRAGMENT_STATE; } /** @@ -209,7 +197,7 @@ public function clearRelativeUrl(): void { $this->relativeUrlState &= ~self::QUERY_STATE; $this->relativeUrlState &= ~self::PATH_STATE; - $this->relativeUrlState &= ~self::FRAGMENT_KEY; + $this->relativeUrlState &= ~self::FRAGMENT_STATE; $this->relativeUrl = null; $this->path->reset(); $this->urlQuery->reset(); @@ -248,7 +236,7 @@ protected function parse(string $source) if (isset($data['port'])) { $this->items[self::PORT] = $data['port']; - $this->authoritySate &= ~self::PORT_KEY; + $this->authoritySate &= ~self::PORT_STATE; } if (isset($data['path'])) { @@ -263,7 +251,7 @@ protected function parse(string $source) if (isset($data['fragment'])) { $this->items[self::FRAGMENT] = rawurldecode($data['fragment']); - $this->relativeUrlState &= ~self::FRAGMENT_KEY; + $this->relativeUrlState &= ~self::FRAGMENT_STATE; } if (!isset($data['host']) && !isset($data['scheme'])) { @@ -321,7 +309,7 @@ public function getPort(): ?string public function setPort(string $port): static { $this->items[self::PORT] = $port; - $this->authoritySate &= ~self::PORT_KEY; + $this->authoritySate &= ~self::PORT_STATE; return $this; } @@ -367,7 +355,7 @@ public function setAll(array $items): void $this->authoritySate &= ~self::PASSWORD_STATE; $this->relativeUrlState &= ~self::QUERY_STATE; $this->relativeUrlState &= ~self::PATH_STATE; - $this->relativeUrlState &= ~self::FRAGMENT_KEY; + $this->relativeUrlState &= ~self::FRAGMENT_STATE; if (empty($items)) { $this->reset(); @@ -445,7 +433,7 @@ public function getFragment(): ?string public function setFragment(string $fragment): static { $this->items[self::FRAGMENT] = $fragment; - $this->relativeUrlState &= ~self::FRAGMENT_KEY; + $this->relativeUrlState &= ~self::FRAGMENT_STATE; return $this; } diff --git a/tests/Cases/Dummy/DummyUrlStrategy.php b/tests/Cases/Dummy/DummyUrlStrategy.php index 2b87c16..d17375e 100644 --- a/tests/Cases/Dummy/DummyUrlStrategy.php +++ b/tests/Cases/Dummy/DummyUrlStrategy.php @@ -41,12 +41,13 @@ public function updateQuery(array $items): string /** * @param array $items + * @param string $separator * @param string|null $suffix * @return string */ - public function updatePath(array $items, ?string $suffix = null): string + public function updatePath(array $items, string $separator, ?string $suffix = null): string { - return implode('/', $items); + return implode($separator, $items); } /** diff --git a/tests/DefaultUrlPathStrategyTest.php b/tests/DefaultPathStrategyTest.php similarity index 88% rename from tests/DefaultUrlPathStrategyTest.php rename to tests/DefaultPathStrategyTest.php index 22be801..42a84bc 100644 --- a/tests/DefaultUrlPathStrategyTest.php +++ b/tests/DefaultPathStrategyTest.php @@ -5,7 +5,7 @@ use Compass\DefaultPathStrategy; use PHPUnit\Framework\TestCase; -class DefaultUrlPathStrategyTest extends TestCase +class DefaultPathStrategyTest extends TestCase { /** * @dataProvider getData @@ -13,7 +13,7 @@ class DefaultUrlPathStrategyTest extends TestCase public function testUpdatePath(array $items, ?string $suffix, $expected) { $strategy = new DefaultPathStrategy(); - $path = $strategy->updatePath($items, $suffix); + $path = $strategy->updatePath($items, '/', $suffix); self::assertEquals($expected, $path); } diff --git a/tests/DefaultUpdateStrategyTest.php b/tests/DefaultUrlStrategyTest.php similarity index 96% rename from tests/DefaultUpdateStrategyTest.php rename to tests/DefaultUrlStrategyTest.php index ce3fc07..ca55bff 100644 --- a/tests/DefaultUpdateStrategyTest.php +++ b/tests/DefaultUrlStrategyTest.php @@ -8,7 +8,7 @@ use Compass\Path; use Compass\Query; -class DefaultUpdateStrategyTest extends TestCase +class DefaultUrlStrategyTest extends TestCase { /** * @dataProvider getItems @@ -109,7 +109,7 @@ public function getDataBaseUrl(): array public function testUpdateRelativeUrl(array $items, string $pathString, string $queryString, string $expected) { $updateStrategy = new DefaultUrlStrategy(); - $path = Path::createBlank($updateStrategy); + $path = Path::createBlank('/', $updateStrategy); if (!empty($pathString)) { $path->setSource($pathString); } @@ -141,7 +141,7 @@ public function testUpdateAbsoluteUrl(string $baseUrl, string $relativeUrl, stri { $updateStrategy = new DefaultUrlStrategy(); - $path = Path::createBlank($updateStrategy); + $path = Path::createBlank('/', $updateStrategy); $query = Query::createBlank($updateStrategy); $result = $updateStrategy->updateAbsoluteUrl( @@ -172,7 +172,7 @@ public function getDataAbsoluteUrl(): array public function testUpdatePath(array $items, ?string $suffix, string $expected) { $updateStrategy = new DefaultUrlStrategy(); - $result = $updateStrategy->updatePath($items, $suffix); + $result = $updateStrategy->updatePath($items, '/', $suffix); self::assertEquals($expected, $result); } diff --git a/tests/PathTest.php b/tests/PathTest.php index ff188fe..202c617 100644 --- a/tests/PathTest.php +++ b/tests/PathTest.php @@ -45,6 +45,16 @@ public function testReplaceAll() $path->updateSource(); self::assertEquals('/sUserUserrc/UserScanner/DriverUser/FiUser2le', $path->getSource()); self::assertEquals('UserScanner', $path->get(2)); + + $path = new Path('\\s__NAME____NAME__rc\\__NAME__Scanner\\Driver__NAME__\\Fi__NAME2__le\\', '\\'); + + $path->replaceAll([ + '__NAME__' => 'User', + '__NAME2__' => 'User2', + ]); + $path->updateSource(); + self::assertEquals('\\sUserUserrc\\UserScanner\\DriverUser\\FiUser2le', $path->getSource()); + self::assertEquals('UserScanner', $path->get(2)); } /** @@ -73,11 +83,12 @@ public function getCasesDirname(): array * @param $source * @param $currentValue * @param $newValue + * @param $separator * @param $expect */ - public function testSetBy($source, $currentValue, $newValue, $expect) + public function testSetBy($source, $currentValue, $newValue, $separator, $expect) { - $path = new Path($source); + $path = new Path($source, $separator); $path->setBy($currentValue, $newValue); $path->updateSource(); self::assertEquals($expect, $path->getSource()); @@ -89,11 +100,14 @@ public function testSetBy($source, $currentValue, $newValue, $expect) public function getCasesSetBy(): array { return [ - ['/src/Scanner/Driver/File/index.php', 'src', 'test', '/test/Scanner/Driver/File/index.php'], - ['/src/Scanner/Driver/File/index.php', 'Scanner', 'test', '/src/test/Driver/File/index.php'], - ['/src/Scanner/Driver/File/index.php', 'Driver', 'test', '/src/Scanner/test/File/index.php'], - ['/src/Scanner/Driver/File/index.php', 'File', 'test', '/src/Scanner/Driver/test/index.php'], - ['/src/Scanner/Driver/File/index.php', 'index.php', 'test', '/src/Scanner/Driver/File/test'], + ['src/Scanner/Driver/File/index.php', 'src', 'test', '/', 'test/Scanner/Driver/File/index.php'], + ['/src/Scanner/Driver/File/index.php', 'src', 'test', '/', '/test/Scanner/Driver/File/index.php'], + ['/src/Scanner/Driver/File/index.php', 'Scanner', 'test', '/', '/src/test/Driver/File/index.php'], + ['/src/Scanner/Driver/File/index.php', 'Driver', 'test', '/', '/src/Scanner/test/File/index.php'], + ['/src/Scanner/Driver/File/index.php', 'File', 'test', '/', '/src/Scanner/Driver/test/index.php'], + ['/src/Scanner/Driver/File/index.php', 'index.php', 'test', '/', '/src/Scanner/Driver/File/test'], + ['c:\\src\\Scanner\\Driver\\File\\index.php', 'index.php', 'test', '\\', 'c:\\src\\Scanner\\Driver\\File\\test'], + ['c:\\src\\Scanner\\Driver\\File\\index.php', 'Driver', 'test', '\\', 'c:\\src\\Scanner\\test\\File\\index.php'], ]; } @@ -107,9 +121,9 @@ public function testSetByAssertion() /** * @dataProvider getCasesSetAll */ - public function testSetAll($source, $newValue, $expect) + public function testSetAll($source, $newValue, $separator, $expect) { - $path = new Path($source); + $path = new Path($source, $separator); $path->setAll($newValue); $path->updateSource(); self::assertEquals($expect, $path->getSource()); @@ -118,17 +132,18 @@ public function testSetAll($source, $newValue, $expect) public function getCasesSetAll(): array { return [ - ['/src/Scanner/Driver/File/index.php', ['c:', 'method', 'getSeparator',], 'c:/method/getSeparator'], - ['/src/Scanner/Driver/File/index.php', ['', 'index.php', 'File',], '/index.php/File'], + ['/src/Scanner/Driver/File/index.php', ['c:', 'method', 'getSeparator',], '/', 'c:/method/getSeparator'], + ['/src/Scanner/Driver/File/index.php', ['', 'index.php', 'File',], '/', '/index.php/File'], + ['src\\Scanner\\Driver\\File\\index.php', ['c:', 'method', 'getSeparator',], '\\', 'c:\method\getSeparator'], ]; } /** * @dataProvider getCasesSet */ - public function testSet($source, $index, $newValue, $expect) + public function testSet($source, $index, $newValue, $separator, $expect) { - $path = new Path($source); + $path = new Path($source, $separator); $path->set($index, $newValue); $path->updateSource(); self::assertEquals($expect, $path->getSource()); @@ -137,12 +152,20 @@ public function testSet($source, $index, $newValue, $expect) public function getCasesSet(): array { return [ - ['/src/Scanner/Driver/File/index.php', 0, 'test', 'test/src/Scanner/Driver/File/index.php'], - ['/src/Scanner/Driver/File/index.php', 1, 'test', '/test/Scanner/Driver/File/index.php'], - ['/src/Scanner/Driver/File/index.php', 2, 'test', '/src/test/Driver/File/index.php'], - ['/src/Scanner/Driver/File/index.php', 3, 'test', '/src/Scanner/test/File/index.php'], - ['/src/Scanner/Driver/File/index.php', 4, 'test', '/src/Scanner/Driver/test/index.php'], - ['/src/Scanner/Driver/File/index.php', 5, 'test', '/src/Scanner/Driver/File/test'], + ['src/Scanner/Driver/File/index.php', 0, 'test', '/', 'test/Scanner/Driver/File/index.php'], + ['/src/Scanner/Driver/File/index.php', 0, 'test', '/', 'test/src/Scanner/Driver/File/index.php'], + ['/src/Scanner/Driver/File/index.php', 1, 'test', '/', '/test/Scanner/Driver/File/index.php'], + ['/src/Scanner/Driver/File/index.php', 2, 'test', '/', '/src/test/Driver/File/index.php'], + ['/src/Scanner/Driver/File/index.php', 3, 'test', '/', '/src/Scanner/test/File/index.php'], + ['/src/Scanner/Driver/File/index.php', 4, 'test', '/', '/src/Scanner/Driver/test/index.php'], + ['/src/Scanner/Driver/File/index.php', 5, 'test', '/', '/src/Scanner/Driver/File/test'], + ['\\src\\Scanner\\Driver\\File\\index.php', 0, 'test', '\\', 'test\\src\\Scanner\\Driver\\File\\index.php'], + ['\\src\\Scanner\\Driver\\File\\index.php', 1, 'test', '\\', '\\test\\Scanner\\Driver\\File\\index.php'], + ['\\src\\Scanner\\Driver\\File\\index.php', 2, 'test', '\\', '\\src\\test\\Driver\\File\\index.php'], + ['\\src\\Scanner\\Driver\\File\\index.php', 3, 'test', '\\', '\\src\\Scanner\\test\\File\\index.php'], + ['\\src\\Scanner\\Driver\\File\\index.php', 4, 'test', '\\', '\\src\\Scanner\\Driver\\test\\index.php'], + ['\\src\\Scanner\\Driver\\File\\index.php', 5, 'test', '\\', '\\src\\Scanner\\Driver\\File\\test'], + ['src\\Scanner\\Driver\\File\\index.php', 4, 'test', '\\', 'src\\Scanner\\Driver\\File\\test'], ]; } diff --git a/tests/UrlPathTest.php b/tests/UrlPathTest.php index c92ffd0..e434f28 100644 --- a/tests/UrlPathTest.php +++ b/tests/UrlPathTest.php @@ -18,7 +18,7 @@ public function testConstruct() self::assertEquals($path, $urlPath->getSource()); self::assertInstanceOf(DefaultPathStrategy::class, $urlPath->getStrategy()); - $urlPath = new Path($path, $strategy = new DummyUrlStrategy()); + $urlPath = new Path($path, '/', $strategy = new DummyUrlStrategy()); self::assertSame($strategy, $urlPath->getStrategy()); } @@ -31,7 +31,7 @@ public function testConstructBad() public function testGetSeparator() { $updateStrategy = $this->getMockForAbstractClass(UrlStrategy::class); - $urlPath = new Path('path', $updateStrategy); + $urlPath = new Path('path', '/', $updateStrategy); self::assertEquals('/', $urlPath->getSeparator()); } @@ -39,7 +39,7 @@ public function testSetUpdateStrategy() { $updateStrategy = $this->getMockForAbstractClass(UrlStrategy::class); $updateStrategy2 = $this->getMockForAbstractClass(UrlStrategy::class); - $urlPath = new Path('path', $updateStrategy); + $urlPath = new Path('path', '/', $updateStrategy); $reflection = new \ReflectionObject($urlPath); $property = $reflection->getProperty('strategy'); $property->setAccessible(true); @@ -56,14 +56,14 @@ public function testEqualsStrategy() { $updateStrategy = $this->getMockForAbstractClass(UrlStrategy::class); $updateStrategy2 = $this->getMockForAbstractClass(UrlStrategy::class); - $urlPath = new Path('path', $updateStrategy); + $urlPath = new Path('path', '/', $updateStrategy); self::assertFalse($urlPath->equalsStrategy($updateStrategy2)); self::assertTrue($urlPath->equalsStrategy($updateStrategy)); } public function testEqualsSuffix() { - $urlPath = new Path('path'); + $urlPath = new Path('path', '/'); $urlPath->setSuffix('suff1'); self::assertFalse($urlPath->equalsSuffix('suff')); self::assertTrue($urlPath->equalsSuffix('suff1')); @@ -75,7 +75,7 @@ public function testEqualsSuffix() public function testGetSuffix() { - $urlPath = new Path('path'); + $urlPath = new Path('path', '/'); self::assertEmpty($urlPath->getSuffix()); $urlPath->setSuffix('suff'); self::assertEquals('suff', $urlPath->getSuffix()); @@ -84,7 +84,7 @@ public function testGetSuffix() public function testSetSuffix() { - $urlPath = new Path('path'); + $urlPath = new Path('path', '/'); $urlPath->setSuffix(null); self::assertEmpty($urlPath->getSuffix()); $urlPath->setSuffix('suff'); @@ -95,7 +95,7 @@ public function testSetSuffix() public function testUpdateSource() { - $urlPath = new Path('assert/update/'); + $urlPath = new Path('assert/update/', '/'); self::assertEquals('assert/update', (string)$urlPath); $urlPath->updateSource(); self::assertEquals('assert/update', (string)$urlPath); @@ -103,7 +103,7 @@ public function testUpdateSource() public function testReset() { - $urlPath = new Path('assert/update/'); + $urlPath = new Path('assert/update/', '/'); $urlPath->setSuffix('suff'); $urlPath->reset(); @@ -115,7 +115,7 @@ public function testReset() public function testSetSource() { - $urlPath = new Path('assert/update/'); + $urlPath = new Path('assert/update/', '/'); self::assertEquals('assert/update', (string)$urlPath); $urlPath->setSource('assert2/update2/'); self::assertEquals('assert2/update2', (string)$urlPath); @@ -127,7 +127,7 @@ public function testSetSource() public function testSetSourceEmpty() { - $urlPath = new Path('assert/update/'); + $urlPath = new Path('assert/update/', '/'); self::assertEquals('assert/update', (string)$urlPath); $urlPath->setSource(''); self::assertEmpty((string)$urlPath); @@ -150,7 +150,7 @@ public function testCreateBlank() self::assertEmpty($urlPath->getAll()); self::assertEmpty($urlPath->getSuffix()); - $urlPath2 = Path::createBlank($updateStrategy = new DummyUrlStrategy()); + $urlPath2 = Path::createBlank('/', $updateStrategy = new DummyUrlStrategy()); self::assertSame($updateStrategy, $urlPath2->getStrategy()); self::assertEmpty($urlPath2->getSource()); self::assertEmpty($urlPath2->getAll());