summaryrefslogtreecommitdiff
path: root/src/test/java
diff options
context:
space:
mode:
authorGeorge Fraser <george@fivetran.com>2018-12-28 12:31:18 -0800
committerGeorge Fraser <george@fivetran.com>2018-12-28 12:31:18 -0800
commit1f1267e0c7d89750dbd6ff8806a73f8cfd9e673e (patch)
tree01f65dfc24489fce38f3d18c3f751b13a851ccbd /src/test/java
parentf19f80b3bdfc99f2062710f3d2193c8a16f26ecd (diff)
downloadjava-language-server-1f1267e0c7d89750dbd6ff8806a73f8cfd9e673e.zip
Minimalist LSP implementation
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/org/javacs/lsp/LanguageServerTest.java74
-rw-r--r--src/test/java/org/javacs/lsp/LspTest.java65
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()));
+ }
+}