Add support to test harness for checking highlights.

This commit is contained in:
Kris De Volder
2017-10-24 12:52:49 -07:00
parent 5652e8402e
commit c71d4cbf02
7 changed files with 115 additions and 13 deletions

View File

@@ -11,12 +11,14 @@
package org.springframework.ide.vscode.languageserver.testharness;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.springframework.ide.vscode.languageserver.testharness.TestAsserts.assertContains;
import static org.springframework.ide.vscode.languageserver.testharness.TestAsserts.assertDoesNotContain;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -26,6 +28,10 @@ import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -46,11 +52,13 @@ import org.eclipse.lsp4j.TextDocumentPositionParams;
import org.eclipse.lsp4j.TextEdit;
import org.eclipse.lsp4j.jsonrpc.messages.Either;
import org.junit.Assert;
import org.springframework.ide.vscode.commons.languageserver.HighlightParams;
import org.springframework.ide.vscode.commons.util.StringUtil;
import org.springframework.ide.vscode.commons.util.Unicodes;
import org.springframework.ide.vscode.commons.util.text.LanguageId;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import reactor.core.publisher.Flux;
@@ -109,8 +117,21 @@ public class Editor {
return p1.getCharacter() - p2.getCharacter();
}
};
private static final Comparator<Range> RANGE_COMPARATOR = new Comparator<Range>() {
@Override
public int compare(Range o1, Range o2) {
int diff = compare(o1.getStart(), o2.getStart());
if (diff!=0) return diff;
return compare(o1.getEnd(), o2.getEnd());
}
private int compare(Position p1, Position p2) {
int d = p1.getLine() - p2.getLine();
if (d!=0) return d;
return p1.getCharacter() - p2.getCharacter();
}
};
private LanguageServerHarness harness;
private LanguageServerHarness<?> harness;
private TextDocumentInfo doc;
private int selectionEnd;
@@ -190,6 +211,19 @@ public class Editor {
return buf.toString();
}
public List<Range> assertHighlights(String... expectedHighlights) throws Exception {
HighlightParams highlights = harness.getHighlights(doc);
List<Range> ranges = new ArrayList<>(highlights.getRanges());
Collections.sort(ranges, RANGE_COMPARATOR);
List<String> actualHighlights = ranges.stream()
.map(this::getText)
.collect(Collectors.toList());
assertEquals(ImmutableList.copyOf(expectedHighlights), actualHighlights);
return ranges;
}
/**
* Get the editor text, with cursor markers inserted (for easy textual comparison
* after applying a proposal)
@@ -806,5 +840,4 @@ public class Editor {
public void setCursor(Position position) {
this.selectionStart = this.selectionEnd = doc.toOffset(position);
}
}

View File

@@ -24,8 +24,10 @@ import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -34,7 +36,10 @@ import java.util.Map.Entry;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;
import org.assertj.core.api.Condition;
@@ -99,6 +104,8 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multimap;
import com.google.common.collect.MultimapBuilder;
import reactor.core.publisher.Mono;
@@ -116,6 +123,7 @@ public class LanguageServerHarness<S extends SimpleLanguageServer> {
private InitializeResult initResult;
private Map<String,TextDocumentInfo> documents = new HashMap<>();
private Multimap<String, CompletableFuture<HighlightParams>> highlights = MultimapBuilder.hashKeys().linkedListValues().build();
private Map<String, PublishDiagnosticsParams> diagnostics = new HashMap<>();
private List<Editor> activeEditors = new ArrayList<>();
@@ -125,6 +133,8 @@ public class LanguageServerHarness<S extends SimpleLanguageServer> {
this.defaultLanguageId = defaultLanguageId;
}
public static final Duration HIGHLIGHTS_TIMEOUT = Duration.ofMinutes(1000);
public LanguageServerHarness(Callable<S> factory) throws Exception {
this(factory, LanguageId.PLAINTEXT);
}
@@ -176,6 +186,21 @@ public class LanguageServerHarness<S extends SimpleLanguageServer> {
this.diagnostics.put(diags.getUri(), diags);
}
private void receiveHighlights(HighlightParams highlights) {
Collection<CompletableFuture<HighlightParams>>requestors = ImmutableList.of();
synchronized (this) {
String uri = highlights.getDoc().getUri();
if (uri!=null) {
requestors = ImmutableList.copyOf(this.highlights.get(uri));
//Carefull!! Must make a copy above. Because the returned collection is cleared when we call removeAll below.
this.highlights.removeAll(uri); //futures can only be completed once, so no point holding any longer
}
}
for (CompletableFuture<HighlightParams> future : requestors) {
future.complete(highlights);
}
}
public InitializeResult intialize(File workspaceRoot) throws Exception {
server = factory.call();
int parentPid = random.nextInt(40000)+1000;
@@ -220,6 +245,11 @@ public class LanguageServerHarness<S extends SimpleLanguageServer> {
receiveDiagnostics(diagnostics);
}
@Override
public void highlight(HighlightParams highlights) {
receiveHighlights(highlights);
}
@Override
public void logMessage(MessageParams message) {
// TODO Auto-generated method stub
@@ -254,11 +284,6 @@ public class LanguageServerHarness<S extends SimpleLanguageServer> {
}
return CompletableFuture.completedFuture(new ApplyWorkspaceEditResponse(false));
}
@Override
public void highlight(HighlightParams highlights) {
// TODO Auto-generated method stub
}
});
}
@@ -372,6 +397,16 @@ public class LanguageServerHarness<S extends SimpleLanguageServer> {
return diagnostics.get(doc.getUri());
}
public synchronized Future<HighlightParams> getHighlightsFuture(TextDocumentInfo doc) {
CompletableFuture<HighlightParams> future = new CompletableFuture<HighlightParams>();
highlights.put(doc.getUri(), future);
return future;
}
public HighlightParams getHighlights(TextDocumentInfo doc) throws Exception {
return getHighlightsFuture(doc).get(HIGHLIGHTS_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
}
public static Condition<Diagnostic> isDiagnosticWithSeverity(DiagnosticSeverity severity) {
return new Condition<>(
(d) -> d.getSeverity()==severity,