diff options
author | George Fraser <george@fivetran.com> | 2018-12-28 12:31:18 -0800 |
---|---|---|
committer | George Fraser <george@fivetran.com> | 2018-12-28 12:31:18 -0800 |
commit | 1f1267e0c7d89750dbd6ff8806a73f8cfd9e673e (patch) | |
tree | 01f65dfc24489fce38f3d18c3f751b13a851ccbd /src/test/java | |
parent | f19f80b3bdfc99f2062710f3d2193c8a16f26ecd (diff) | |
download | java-language-server-1f1267e0c7d89750dbd6ff8806a73f8cfd9e673e.zip |
Minimalist LSP implementation
Diffstat (limited to 'src/test/java')
-rw-r--r-- | src/test/java/org/javacs/lsp/LanguageServerTest.java | 74 | ||||
-rw-r--r-- | src/test/java/org/javacs/lsp/LspTest.java | 65 |
2 files changed, 139 insertions, 0 deletions
diff --git a/src/test/java/org/javacs/lsp/LanguageServerTest.java b/src/test/java/org/javacs/lsp/LanguageServerTest.java new file mode 100644 index 0000000..75a1faf --- /dev/null +++ b/src/test/java/org/javacs/lsp/LanguageServerTest.java @@ -0,0 +1,74 @@ +package org.javacs.lsp; + +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; + +import java.io.IOException; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import org.javacs.Main; +import org.junit.Before; +import org.junit.Test; + +public class LanguageServerTest { + PipedInputStream clientToServer = new PipedInputStream(10 * 1024 * 1024), + serverToClient = new PipedInputStream(10 * 1024 * 1024); + PipedOutputStream writeClientToServer, writeServerToClient; + LanguageServer mockServer; + Thread main; + CompletableFuture<Void> receivedInitialize = new CompletableFuture<>(); + + class TestLanguageServer extends LanguageServer { + @Override + public InitializeResult initialize(InitializeParams params) { + receivedInitialize.complete(null); + return new InitializeResult(); + } + } + + static { + Main.setRootFormat(); + } + + @Before + public void connectServerAndInitialize() throws IOException { + writeClientToServer = new PipedOutputStream(clientToServer); + writeServerToClient = new PipedOutputStream(serverToClient); + main = new Thread(this::runServer, "runServer"); + main.start(); + } + + private void runServer() { + LSP.connect(this::serverFactory, clientToServer, writeServerToClient); + } + + private LanguageServer serverFactory(LanguageClient client) { + mockServer = new TestLanguageServer(); + return mockServer; + } + + private void sendToServer(String message) throws IOException { + var header = String.format("Content-Length: %d\r\n\r\n", message.getBytes().length); + writeClientToServer.write(header.getBytes()); + writeClientToServer.write(message.getBytes()); + } + + String initializeMessage = "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{}}"; + String exitMessage = "{\"jsonrpc\":\"2.0\",\"method\":\"exit\"}"; + + @Test + public void exitMessageKillsServer() + throws IOException, InterruptedException, ExecutionException, TimeoutException { + // Send initialize message and wait for ack + sendToServer(initializeMessage); + receivedInitialize.get(1, TimeUnit.SECONDS); + // Send exit message and wait for exit + sendToServer(exitMessage); + main.join(1000); + assertThat("Main thread has quit", main.isAlive(), equalTo(false)); + } +} diff --git a/src/test/java/org/javacs/lsp/LspTest.java b/src/test/java/org/javacs/lsp/LspTest.java new file mode 100644 index 0000000..3f65774 --- /dev/null +++ b/src/test/java/org/javacs/lsp/LspTest.java @@ -0,0 +1,65 @@ +package org.javacs.lsp; + +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; + +import com.google.common.base.Charsets; +import com.google.gson.JsonObject; +import java.io.IOException; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import org.junit.Before; +import org.junit.Test; + +public class LspTest { + PipedInputStream buffer = new PipedInputStream(10 * 1024 * 1024); // 10 MB buffer + PipedOutputStream writer = new PipedOutputStream(); + + @Before + public void connectBuffer() throws IOException { + writer.connect(buffer); + } + + String bufferToString() { + try { + var available = buffer.available(); + var bytes = new byte[available]; + var read = buffer.read(bytes); + assert read == available; + return new String(bytes, Charsets.UTF_8); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Test + public void writeResponse() { + LSP.respond(writer, 1, 2); + var expected = "Content-Length: 35\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":2}"; + assertThat(bufferToString(), equalTo(expected)); + } + + @Test + public void writeMultibyteCharacters() { + LSP.respond(writer, 1, "🔥"); + var expected = "Content-Length: 40\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":1,\"result\":\"🔥\"}"; + assertThat(bufferToString(), equalTo(expected)); + } + + @Test + public void readMessage() throws IOException { + var message = "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{}}"; + var header = String.format("Content-Length: %d\r\n\r\n", message.getBytes().length); + writer.write(header.getBytes()); + writer.write(message.getBytes()); + + var token = LSP.nextToken(buffer); + assertThat(token, equalTo(message)); + + var parse = LSP.parseMessage(token); + assertThat(parse.jsonrpc, equalTo("2.0")); + assertThat(parse.id, equalTo(1)); + assertThat(parse.method, equalTo("initialize")); + assertThat(parse.params, equalTo(new JsonObject())); + } +} |