Path factory

master 0.2.0
Anton Smirnov 2021-11-04 03:38:59 +02:00
parent e581028134
commit f3f2827534
2 changed files with 101 additions and 0 deletions

46
src/PathFactory.php Normal file
View File

@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
namespace Arokettu\Path;
final class PathFactory
{
public static function parse(string $path, array $urlSchemes = [], array $streamSchemes = []): PathInterface
{
if ($path[0] === '/') {
return UnixPath::parse($path);
}
if (preg_match('@^[a-zA-Z]:[\\\\/]@', $path) || str_starts_with($path, '\\\\')) {
return new WindowsPath($path);
}
if (preg_match('@^([-.+a-zA-Z0-9]+)://@', $path, $matches)) {
return self::parseUrlLike($path, $matches[1], $urlSchemes, $streamSchemes);
}
return DIRECTORY_SEPARATOR === '\\' ? RelativePath::windows($path) : RelativePath::unix($path);
}
private static function parseUrlLike(
string $path,
string $scheme,
array $urlSchemes = [],
array $streamSchemes = []
): PathInterface {
if ($urlSchemes === [] && $streamSchemes === []) {
return UrlPath::parse($path);
}
if (\in_array($scheme, $urlSchemes)) {
return UrlPath::parse($path);
}
if (\in_array($scheme, $streamSchemes)) {
return StreamPath::parse($path);
}
throw new \InvalidArgumentException('Unknown scheme: ' . $scheme);
}
}

55
tests/PathFactoryTest.php Normal file
View File

@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
namespace Arokettu\Path\Tests;
use Arokettu\Path\PathFactory;
use Arokettu\Path\RelativePath;
use Arokettu\Path\StreamPath;
use Arokettu\Path\UnixPath;
use Arokettu\Path\UrlPath;
use Arokettu\Path\WindowsPath;
use PHPUnit\Framework\TestCase;
class PathFactoryTest extends TestCase
{
public function testValid(): void
{
self::assertInstanceOf(UnixPath::class, PathFactory::parse('/unix/path'));
self::assertInstanceOf(WindowsPath::class, PathFactory::parse('C:/unixlike/path'));
self::assertInstanceOf(WindowsPath::class, PathFactory::parse('c:\win\path'));
self::assertInstanceOf(WindowsPath::class, PathFactory::parse('\\\\unc\path'));
self::assertInstanceOf(RelativePath::class, PathFactory::parse('../test/path'));
self::assertInstanceOf(RelativePath::class, PathFactory::parse('./test/path'));
self::assertInstanceOf(RelativePath::class, PathFactory::parse('test/path'));
}
public function testValidUrls(): void
{
self::assertInstanceOf(UrlPath::class, PathFactory::parse('https://example.com/test/test'));
self::assertInstanceOf(UrlPath::class, PathFactory::parse('vfs://test/test'));
$urlSchemes = ['http', 'https', 'ftp'];
$streamSchemes = ['vfs', 'php'];
self::assertInstanceOf(
UrlPath::class,
PathFactory::parse('https://example.com/test/test', $urlSchemes, $streamSchemes)
);
self::assertInstanceOf(
StreamPath::class,
PathFactory::parse('vfs://test/test', $urlSchemes, $streamSchemes)
);
}
public function testUnknownScheme(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Unknown scheme: unk');
$urlSchemes = ['http', 'https', 'ftp'];
$streamSchemes = ['vfs', 'php'];
PathFactory::parse('unk://test/test', $urlSchemes, $streamSchemes);
}
}