Skip to content

Commit

Permalink
Improve error messages in CompletionTest eclipse-platform#906
Browse files Browse the repository at this point in the history
Provide more meaningful error message in case any of the test cases in
CompletionTest fails. Particularly also explicitly validate whether the
proposal list widget has been disposed concurrently. Remove typo in
method name.

Contributes to
eclipse-platform#906
  • Loading branch information
HeikoKlare committed Jul 26, 2023
1 parent 3792903 commit 4c0b7df
Showing 1 changed file with 58 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,24 @@
*******************************************************************************/
package org.eclipse.ui.genericeditor.tests;

import static org.hamcrest.CoreMatchers.endsWith;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import java.util.function.BooleanSupplier;
import java.util.stream.Collectors;

import org.junit.After;
Expand Down Expand Up @@ -76,7 +82,7 @@ public class CompletionTest extends AbstratGenericEditorTest {
@Test
public void testCompletion() throws Exception {
editor.selectAndReveal(3, 0);
this.completionShell= openConentAssist();
completionShell = openContentAssist();
final Table completionProposalList = findCompletionSelectionControl(completionShell);
checkCompletionContent(completionProposalList);
// TODO find a way to actually trigger completion and verify result against Editor content
Expand All @@ -89,7 +95,7 @@ public void testDefaultContentAssistBug570488() throws Exception {
TestLogListener listener= new TestLogListener();
log.addLogListener(listener);
createAndOpenFile("Bug570488.txt", "bar 'bar'");
openConentAssist(false);
openContentAssist(false);
DisplayHelper.driveEventQueue(Display.getCurrent());
assertFalse("There are errors in the log", listener.messages.stream().anyMatch(s -> s.matches(IStatus.ERROR)));
log.removeLogListener(listener);
Expand All @@ -106,7 +112,7 @@ public void testCompletionService() throws Exception {
new Hashtable<>(Collections.singletonMap("contentType", "org.eclipse.ui.genericeditor.tests.content-type")));
DisplayHelper.driveEventQueue(Display.getCurrent());
editor.selectAndReveal(3, 0);
this.completionShell= openConentAssist();
completionShell = openContentAssist();
final Table completionProposalList= findCompletionSelectionControl(completionShell);
checkCompletionContent(completionProposalList);
assertTrue("Service was not called!", service.called);
Expand All @@ -117,36 +123,43 @@ public void testCompletionService() throws Exception {
public void testCompletionUsingViewerSelection() throws Exception {
editor.getDocumentProvider().getDocument(editor.getEditorInput()).set("abc");
editor.selectAndReveal(0, 3);
this.completionShell= openConentAssist();
completionShell = openContentAssist();
final Table completionProposalList = findCompletionSelectionControl(completionShell);
assertTrue(new DisplayHelper() {
waitForProposalRelatedCondition("Proposal list did not contain expected item: ABC", completionProposalList,
() -> Arrays.stream(completionProposalList.getItems()).map(TableItem::getText).anyMatch("ABC"::equals), 5_000);
}

private static void waitForProposalRelatedCondition(String errorMessage, Table completionProposalList, BooleanSupplier condition, int timeoutInMsec) {
assertTrue(errorMessage, new DisplayHelper() {
@Override
protected boolean condition() {
return Arrays.stream(completionProposalList.getItems()).map(TableItem::getText).anyMatch("ABC"::equals);
assertFalse("Completion proposal list was unexpectedly disposed", completionProposalList.isDisposed());
return condition.getAsBoolean();
}
}.waitForCondition(completionProposalList.getDisplay(), 200));
}.waitForCondition(completionProposalList.getDisplay(), timeoutInMsec));
}

@Test
public void testEnabledWhenCompletion() throws Exception {
// Confirm that when disabled, a completion shell is present
EnabledPropertyTester.setEnabled(false);
createAndOpenFile("enabledWhen.txt", "bar 'bar'");
editor.selectAndReveal(3, 0);
assertNull("A new shell was found", openConentAssist(false));
assertNull("A new shell was found", openContentAssist(false));
cleanFileAndEditor();

// Confirm that when enabled, a completion shell is present
EnabledPropertyTester.setEnabled(true);
createAndOpenFile("enabledWhen.txt", "bar 'bar'");
editor.selectAndReveal(3, 0);
assertNotNull(openConentAssist());
assertNotNull(openContentAssist());
}

private Shell openConentAssist() {
return openConentAssist(true);
private Shell openContentAssist() {
return openContentAssist(true);
}
private Shell openConentAssist(boolean expectShell) {

private Shell openContentAssist(boolean expectShell) {
ContentAssistAction action = (ContentAssistAction) editor.getAction(ITextEditorActionConstants.CONTENT_ASSIST);
action.update();
final Set<Shell> beforeShells = Arrays.stream(editor.getSite().getShell().getDisplay().getShells()).filter(Shell::isVisible).collect(Collectors.toSet());
Expand All @@ -165,29 +178,27 @@ private Shell openConentAssist(boolean expectShell) {
*/
private void checkCompletionContent(final Table completionProposalList) {
// should be instantaneous, but happens to go asynchronous on CI so let's allow a wait
assertTrue(new DisplayHelper() {
@Override
protected boolean condition() {
return completionProposalList.getItemCount() == 2;
}
}.waitForCondition(completionProposalList.getDisplay(), 200));
waitForProposalRelatedCondition("Proposal list did not show two initial items", completionProposalList,
() -> completionProposalList.getItemCount() == 2, 200);
assertTrue("Missing computing info entry", isComputingInfoEntry(completionProposalList.getItem(0)));
TableItem completionProposalItem = completionProposalList.getItem(1);
final ICompletionProposal selectedProposal = (ICompletionProposal)completionProposalItem.getData();
assertTrue("Incorrect proposal content", BarContentAssistProcessor.PROPOSAL.endsWith(selectedProposal .getDisplayString()));
completionProposalList.setSelection(completionProposalItem);
assertTrue("Missing computing info entry in proposal list", isComputingInfoEntry(completionProposalList.getItem(0)));
final TableItem initialProposalItem = completionProposalList.getItem(1);
final String initialProposalString = ((ICompletionProposal)initialProposalItem.getData()).getDisplayString();
assertThat("Unexpected initial proposal item",
BarContentAssistProcessor.PROPOSAL, endsWith(initialProposalString));
completionProposalList.setSelection(initialProposalItem);
// asynchronous
new DisplayHelper() {
@Override
protected boolean condition() {
return !isComputingInfoEntry(completionProposalList.getItem(0)) && completionProposalList.getItemCount() == 2;
}
}.waitForCondition(completionProposalList.getDisplay(), LongRunningBarContentAssistProcessor.DELAY + 200);
completionProposalItem = completionProposalList.getItem(0);
assertTrue("Proposal content seems incorrect", BarContentAssistProcessor.PROPOSAL.endsWith(((ICompletionProposal)completionProposalItem.getData()).getDisplayString()));
TableItem otherProposalItem = completionProposalList.getItem(1);
assertTrue("Proposal content seems incorrect", LongRunningBarContentAssistProcessor.PROPOSAL.endsWith(((ICompletionProposal)otherProposalItem.getData()).getDisplayString()));
assertEquals("Addition of completion proposal should keep selection", selectedProposal, completionProposalList.getSelection()[0].getData());
waitForProposalRelatedCondition("Proposal list did not show two items after finishing computing", completionProposalList,
() -> !isComputingInfoEntry(completionProposalList.getItem(0)) && completionProposalList.getItemCount() == 2,
LongRunningBarContentAssistProcessor.DELAY + 200);
final TableItem firstCompletionProposalItem = completionProposalList.getItem(0);
final TableItem secondCompletionProposalItem = completionProposalList.getItem(1);
String firstCompletionProposalText = ((ICompletionProposal)firstCompletionProposalItem.getData()).getDisplayString();
String secondCOmpletionProposalText = ((ICompletionProposal)secondCompletionProposalItem.getData()).getDisplayString();
assertThat("Unexpected first proposal item", BarContentAssistProcessor.PROPOSAL, endsWith(firstCompletionProposalText));
assertThat("Unexpected second proposal item", LongRunningBarContentAssistProcessor.PROPOSAL, endsWith(secondCOmpletionProposalText));
String selectedProposalString = ((ICompletionProposal)completionProposalList.getSelection()[0].getData()).getDisplayString();
assertEquals("Addition of completion proposal should keep selection", initialProposalString, selectedProposalString);
}

private static boolean isComputingInfoEntry(TableItem item) {
Expand All @@ -208,16 +219,11 @@ public static Shell findNewShell(Set<Shell> beforeShells, Display display, boole
@Test
public void testCompletionFreeze_bug521484() throws Exception {
editor.selectAndReveal(3, 0);
this.completionShell=openConentAssist();
final Table completionProposalList = findCompletionSelectionControl(this.completionShell);
completionShell = openContentAssist();
final Table completionProposalList = findCompletionSelectionControl(completionShell);
// should be instantaneous, but happens to go asynchronous on CI so let's allow a wait
new DisplayHelper() {
@Override
protected boolean condition() {
return completionProposalList.getItemCount() == 2;
}
}.waitForCondition(completionShell.getDisplay(), 200);
assertEquals(2, completionProposalList.getItemCount());
waitForProposalRelatedCondition("Proposal list did not show two items", completionProposalList,
() -> completionProposalList.getItemCount() == 2, 200);
assertTrue("Missing computing info entry", isComputingInfoEntry(completionProposalList.getItem(0)));
// Some processors are long running, moving cursor can cause freeze (bug 521484)
// asynchronous
Expand Down Expand Up @@ -251,16 +257,17 @@ private void emulatePressLeftArrowKey() {
}

public static Table findCompletionSelectionControl(Widget control) {
if (control instanceof Table) {
return (Table)control;
} else if (control instanceof Composite) {
for (Widget child : ((Composite)control).getChildren()) {
Table res = findCompletionSelectionControl(child);
if (res != null) {
return res;
}
Queue<Widget> widgetsToProcess = new LinkedList<>();
widgetsToProcess.add(control);
while (!widgetsToProcess.isEmpty()) {
Widget child = widgetsToProcess.poll();
if (child instanceof Table table) {
return table;
} else if (child instanceof Composite composite) {
widgetsToProcess.addAll(Arrays.asList(composite.getChildren()));
}
}
fail("No completion selection control found in widget: " + control);
return null;
}

Expand Down

0 comments on commit 4c0b7df

Please sign in to comment.