textDocument = new class($this->args) extends Client\TextDocument { private $args; public function __construct(&$args) { parent::__construct(new ClientHandler(new MockProtocolStream, new MockProtocolStream), new JsonMapper); $this->args = &$args; } public function publishDiagnostics(string $uri, array $diagnostics): Promise { $this->args = func_get_args(); return Promise\resolve(null); } }; $project = new Project($client, new FileSystemContentRetriever); $this->textDocument = new Server\TextDocument($project, $client); } private function openFile($file) { $textDocumentItem = new TextDocumentItem(); $textDocumentItem->uri = 'whatever'; $textDocumentItem->languageId = 'php'; $textDocumentItem->version = 1; $textDocumentItem->text = file_get_contents($file); $this->textDocument->didOpen($textDocumentItem); } public function testParseErrorsArePublishedAsDiagnostics() { $this->openFile(__DIR__ . '/../../../fixtures/invalid_file.php'); $this->assertEquals([ 'whatever', [[ 'range' => [ 'start' => [ 'line' => 2, 'character' => 10 ], 'end' => [ 'line' => 2, 'character' => 15 ] ], 'severity' => DiagnosticSeverity::ERROR, 'code' => null, 'source' => 'php', 'message' => "Syntax error, unexpected T_CLASS, expecting T_STRING" ]] ], json_decode(json_encode($this->args), true)); } public function testParseErrorsWithOnlyStartLine() { $this->openFile(__DIR__ . '/../../../fixtures/namespace_not_first.php'); $this->assertEquals([ 'whatever', [[ 'range' => [ 'start' => [ 'line' => 4, 'character' => 0 ], 'end' => [ 'line' => 4, 'character' => 0 ] ], 'severity' => DiagnosticSeverity::ERROR, 'code' => null, 'source' => 'php', 'message' => "Namespace declaration statement has to be the very first statement in the script" ]] ], json_decode(json_encode($this->args), true)); } }