Throw exception on invalid file URI
parent
a43d2b2a0f
commit
6611a30d90
|
@ -3,6 +3,8 @@ declare(strict_types = 1);
|
|||
|
||||
namespace LanguageServer;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Recursively Searches files with matching filename, starting at $path.
|
||||
*
|
||||
|
@ -29,18 +31,30 @@ function findFilesRecursive(string $path, string $pattern): array {
|
|||
*/
|
||||
function pathToUri(string $filepath): string {
|
||||
$filepath = trim(str_replace('\\', '/', $filepath), '/');
|
||||
$filepath = implode('/', array_map('urlencode', explode('/', $filepath)));
|
||||
$parts = explode('/', $filepath);
|
||||
// Don't %-encode the colon after a Windows drive letter
|
||||
$first = array_shift($parts);
|
||||
if (substr($first, -1) !== ':') {
|
||||
$first = urlencode($first);
|
||||
}
|
||||
$parts = array_map('urlencode', $parts);
|
||||
array_unshift($parts, $first);
|
||||
$filepath = implode('/', $parts);
|
||||
return 'file:///' . $filepath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms URI into file path
|
||||
*
|
||||
*
|
||||
* @param string $uri
|
||||
* @return string
|
||||
*/
|
||||
function uriToPath(string $uri)
|
||||
{
|
||||
$filepath = urldecode(parse_url($uri)['path']);
|
||||
$fragments = parse_url($uri);
|
||||
if ($fragments === null || !isset($fragments['scheme']) || $fragments['scheme'] !== 'file') {
|
||||
throw new InvalidArgumentException("Not a valid file URI: $uri");
|
||||
}
|
||||
$filepath = urldecode($fragments['path']);
|
||||
return strpos($filepath, ':') === false ? $filepath : str_replace('/', '\\', $filepath);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ class FormatterTest extends TestCase
|
|||
$input = file_get_contents(__DIR__ . '/../fixtures/format.php');
|
||||
$output = file_get_contents(__DIR__ . '/../fixtures/format_expected.php');
|
||||
|
||||
$edits = $formatter->format($input, 'whatever');
|
||||
$edits = $formatter->format($input, 'file:///whatever');
|
||||
$this->assertSame($output, $edits[0]->newText);
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ class FormatterTest extends TestCase
|
|||
$formatter = new Formatter();
|
||||
$expected = file_get_contents(__DIR__ . '/../fixtures/format_expected.php');
|
||||
|
||||
$edits = $formatter->format($expected, 'whatever');
|
||||
$edits = $formatter->format($expected, 'file:///whatever');
|
||||
$this->assertSame([], $edits);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ use PHPUnit\Framework\TestCase;
|
|||
use LanguageServer\Tests\MockProtocolStream;
|
||||
use LanguageServer\{Server, Client, LanguageClient, Project};
|
||||
use LanguageServer\Protocol\{TextDocumentIdentifier, TextDocumentItem, FormattingOptions};
|
||||
use function LanguageServer\{pathToUri, uriToPath};
|
||||
|
||||
class FormattingTest extends TestCase
|
||||
{
|
||||
|
@ -27,19 +28,21 @@ class FormattingTest extends TestCase
|
|||
$client = new LanguageClient(new MockProtocolStream());
|
||||
$project = new Project($client);
|
||||
$textDocument = new Server\TextDocument($project, $client);
|
||||
$path = realpath(__DIR__ . '/../../../fixtures/format.php');
|
||||
$uri = pathToUri($path);
|
||||
|
||||
// Trigger parsing of source
|
||||
$textDocumentItem = new TextDocumentItem();
|
||||
$textDocumentItem->uri = 'whatever';
|
||||
$textDocumentItem->uri = $uri;
|
||||
$textDocumentItem->languageId = 'php';
|
||||
$textDocumentItem->version = 1;
|
||||
$textDocumentItem->text = file_get_contents(__DIR__ . '/../../../fixtures/format.php');
|
||||
$textDocumentItem->text = file_get_contents($path);
|
||||
$textDocument->didOpen($textDocumentItem);
|
||||
|
||||
// how code should look after formatting
|
||||
$expected = file_get_contents(__DIR__ . '/../../../fixtures/format_expected.php');
|
||||
// Request formatting
|
||||
$result = $textDocument->formatting(new TextDocumentIdentifier('whatever'), new FormattingOptions());
|
||||
$result = $textDocument->formatting(new TextDocumentIdentifier($uri), new FormattingOptions());
|
||||
$this->assertEquals([0 => [
|
||||
'range' => [
|
||||
'start' => [
|
||||
|
|
|
@ -4,6 +4,7 @@ declare(strict_types = 1);
|
|||
namespace LanguageServer\Tests\Utils;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use InvalidArgumentException;
|
||||
use function LanguageServer\{pathToUri, uriToPath};
|
||||
|
||||
class FileUriTest extends TestCase
|
||||
|
@ -24,11 +25,11 @@ class FileUriTest extends TestCase
|
|||
|
||||
// special chars are escaped
|
||||
$uri = pathToUri('c:/path/to/file/dürüm döner.php');
|
||||
$this->assertEquals('file:///c%3A/path/to/file/d%C3%BCr%C3%BCm+d%C3%B6ner.php', $uri);
|
||||
$this->assertEquals('file:///c:/path/to/file/d%C3%BCr%C3%BCm+d%C3%B6ner.php', $uri);
|
||||
|
||||
//backslashes are transformed
|
||||
$uri = pathToUri('c:\\foo\\bar.baz');
|
||||
$this->assertEquals('file:///c%3A/foo/bar.baz', $uri);
|
||||
$this->assertEquals('file:///c:/foo/bar.baz', $uri);
|
||||
}
|
||||
|
||||
public function testUriToPath()
|
||||
|
@ -51,4 +52,18 @@ class FileUriTest extends TestCase
|
|||
$uri = 'file:///c:/foo/bar.baz';
|
||||
$this->assertEquals('c:\\foo\\bar.baz', uriToPath($uri));
|
||||
}
|
||||
|
||||
public function testUriToPathForUnknownProtocol()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$uri = 'vfs:///whatever';
|
||||
uriToPath($uri);
|
||||
}
|
||||
|
||||
public function testUriToPathForInvalidProtocol()
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$uri = 'http://www.google.com';
|
||||
uriToPath($uri);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue