summaryrefslogtreecommitdiff
path: root/src/test/java/org/javacs/CodeActionsTest.java
blob: b457d858ee21caf5a42e42bb1231ea6838467e12 (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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package org.javacs;

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
import static org.junit.Assert.assertThat;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.lsp4j.CodeActionContext;
import org.eclipse.lsp4j.CodeActionParams;
import org.eclipse.lsp4j.Command;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.DidOpenTextDocumentParams;
import org.eclipse.lsp4j.DidSaveTextDocumentParams;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.TextDocumentIdentifier;
import org.eclipse.lsp4j.TextDocumentItem;
import org.junit.Before;
import org.junit.Test;

public class CodeActionsTest {

    private static List<Diagnostic> diagnostics = new ArrayList<>();

    @Before
    public void before() {
        diagnostics.clear();
    }

    private static final JavaLanguageServer server =
            LanguageServerFixture.getJavaLanguageServer(LanguageServerFixture.DEFAULT_WORKSPACE_ROOT, diagnostics::add);

    @Test
    public void addImport() {
        List<String> titles =
                commands("/org/javacs/example/MissingImport.java", 5, 14)
                        .stream()
                        .map(c -> c.getTitle())
                        .collect(Collectors.toList());

        assertThat(titles, hasItem("Import java.util.ArrayList"));
    }

    @Test
    public void missingImport() {
        String message =
                "cannot find symbol\n" + "  symbol:   class ArrayList\n" + "  location: class org.javacs.MissingImport";

        assertThat(CodeActions.cannotFindSymbolClassName(message), equalTo(Optional.of("ArrayList")));
    }

    private List<? extends Command> commands(String file, int row, int column) {
        URI uri = FindResource.uri(file);
        TextDocumentIdentifier document = new TextDocumentIdentifier(uri.toString());

        try {
            InputStream in = Files.newInputStream(new File(uri).toPath());
            String content = new BufferedReader(new InputStreamReader(in)).lines().collect(Collectors.joining("\n"));
            TextDocumentItem open = new TextDocumentItem();

            open.setText(content);
            open.setUri(uri.toString());
            open.setLanguageId("java");

            server.getTextDocumentService().didOpen(new DidOpenTextDocumentParams(open, content));
            server.getTextDocumentService().didSave(new DidSaveTextDocumentParams(document, content));

            return diagnostics
                    .stream()
                    .filter(diagnostic -> includes(diagnostic.getRange(), row - 1, column - 1))
                    .flatMap(diagnostic -> codeActionsAt(document, diagnostic))
                    .collect(Collectors.toList());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private boolean includes(Range range, int line, int character) {
        boolean startCondition =
                range.getStart().getLine() < line
                        || (range.getStart().getLine() == line && range.getStart().getCharacter() <= character);
        boolean endCondition =
                line < range.getEnd().getLine()
                        || (line == range.getEnd().getLine() && character <= range.getEnd().getCharacter());

        return startCondition && endCondition;
    }

    private Stream<? extends Command> codeActionsAt(TextDocumentIdentifier documentId, Diagnostic diagnostic) {
        CodeActionParams params =
                new CodeActionParams(documentId, diagnostic.getRange(), new CodeActionContext(diagnostics));

        return server.getTextDocumentService().codeAction(params).join().stream();
    }
}