summaryrefslogtreecommitdiff
path: root/src/test/java/org/javacs/lsp/LanguageServerTest.java
blob: 43304031251aeaa2b3ba1b6519d71c0f27ca21f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
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(10, TimeUnit.SECONDS);
        // Send exit message and wait for exit
        sendToServer(exitMessage);
        main.join(10_000);
        assertThat("Main thread has quit", main.isAlive(), equalTo(false));
    }

    @Test
    public void endOfStreamKillsServer()
            throws IOException, InterruptedException, ExecutionException, TimeoutException {
        // Send initialize message and wait for ack
        sendToServer(initializeMessage);
        receivedInitialize.get(10, TimeUnit.SECONDS);
        // Close stream
        writeClientToServer.close();
        clientToServer.close();
        // Wait for exit
        main.join(10_000);
        assertThat("Main thread has quit", main.isAlive(), equalTo(false));
    }
}