1313 *******************************************************************************/
1414package org .eclipse .ui .genericeditor .tests ;
1515
16+ import static org .hamcrest .CoreMatchers .endsWith ;
17+ import static org .hamcrest .MatcherAssert .assertThat ;
1618import static org .junit .Assert .assertEquals ;
1719import static org .junit .Assert .assertFalse ;
1820import static org .junit .Assert .assertNotNull ;
1921import static org .junit .Assert .assertNull ;
2022import static org .junit .Assert .assertTrue ;
23+ import static org .junit .Assert .fail ;
2124
2225import java .util .ArrayList ;
2326import java .util .Arrays ;
2427import java .util .Collections ;
2528import java .util .Hashtable ;
29+ import java .util .LinkedList ;
2630import java .util .List ;
31+ import java .util .Queue ;
2732import java .util .Set ;
33+ import java .util .function .BooleanSupplier ;
2834import java .util .stream .Collectors ;
2935
3036import org .junit .After ;
@@ -76,7 +82,7 @@ public class CompletionTest extends AbstratGenericEditorTest {
7682 @ Test
7783 public void testCompletion () throws Exception {
7884 editor .selectAndReveal (3 , 0 );
79- this . completionShell = openConentAssist ();
85+ completionShell = openContentAssist ();
8086 final Table completionProposalList = findCompletionSelectionControl (completionShell );
8187 checkCompletionContent (completionProposalList );
8288 // TODO find a way to actually trigger completion and verify result against Editor content
@@ -89,7 +95,7 @@ public void testDefaultContentAssistBug570488() throws Exception {
8995 TestLogListener listener = new TestLogListener ();
9096 log .addLogListener (listener );
9197 createAndOpenFile ("Bug570488.txt" , "bar 'bar'" );
92- openConentAssist (false );
98+ openContentAssist (false );
9399 DisplayHelper .driveEventQueue (Display .getCurrent ());
94100 assertFalse ("There are errors in the log" , listener .messages .stream ().anyMatch (s -> s .matches (IStatus .ERROR )));
95101 log .removeLogListener (listener );
@@ -106,7 +112,7 @@ public void testCompletionService() throws Exception {
106112 new Hashtable <>(Collections .singletonMap ("contentType" , "org.eclipse.ui.genericeditor.tests.content-type" )));
107113 DisplayHelper .driveEventQueue (Display .getCurrent ());
108114 editor .selectAndReveal (3 , 0 );
109- this . completionShell = openConentAssist ();
115+ completionShell = openContentAssist ();
110116 final Table completionProposalList = findCompletionSelectionControl (completionShell );
111117 checkCompletionContent (completionProposalList );
112118 assertTrue ("Service was not called!" , service .called );
@@ -117,36 +123,43 @@ public void testCompletionService() throws Exception {
117123 public void testCompletionUsingViewerSelection () throws Exception {
118124 editor .getDocumentProvider ().getDocument (editor .getEditorInput ()).set ("abc" );
119125 editor .selectAndReveal (0 , 3 );
120- this . completionShell = openConentAssist ();
126+ completionShell = openContentAssist ();
121127 final Table completionProposalList = findCompletionSelectionControl (completionShell );
122- assertTrue (new DisplayHelper () {
128+ waitForProposalRelatedCondition ("Proposal list did not contain expected item: ABC" , completionProposalList ,
129+ () -> Arrays .stream (completionProposalList .getItems ()).map (TableItem ::getText ).anyMatch ("ABC" ::equals ), 5_000 );
130+ }
131+
132+ private static void waitForProposalRelatedCondition (String errorMessage , Table completionProposalList , BooleanSupplier condition , int timeoutInMsec ) {
133+ assertTrue (errorMessage , new DisplayHelper () {
123134 @ Override
124135 protected boolean condition () {
125- return Arrays .stream (completionProposalList .getItems ()).map (TableItem ::getText ).anyMatch ("ABC" ::equals );
136+ assertFalse ("Completion proposal list was unexpectedly disposed" , completionProposalList .isDisposed ());
137+ return condition .getAsBoolean ();
126138 }
127- }.waitForCondition (completionProposalList .getDisplay (), 200 ));
139+ }.waitForCondition (completionProposalList .getDisplay (), timeoutInMsec ));
128140 }
129-
141+
130142 @ Test
131143 public void testEnabledWhenCompletion () throws Exception {
132144 // Confirm that when disabled, a completion shell is present
133145 EnabledPropertyTester .setEnabled (false );
134146 createAndOpenFile ("enabledWhen.txt" , "bar 'bar'" );
135147 editor .selectAndReveal (3 , 0 );
136- assertNull ("A new shell was found" , openConentAssist (false ));
148+ assertNull ("A new shell was found" , openContentAssist (false ));
137149 cleanFileAndEditor ();
138150
139151 // Confirm that when enabled, a completion shell is present
140152 EnabledPropertyTester .setEnabled (true );
141153 createAndOpenFile ("enabledWhen.txt" , "bar 'bar'" );
142154 editor .selectAndReveal (3 , 0 );
143- assertNotNull (openConentAssist ());
155+ assertNotNull (openContentAssist ());
144156 }
145157
146- private Shell openConentAssist () {
147- return openConentAssist (true );
158+ private Shell openContentAssist () {
159+ return openContentAssist (true );
148160 }
149- private Shell openConentAssist (boolean expectShell ) {
161+
162+ private Shell openContentAssist (boolean expectShell ) {
150163 ContentAssistAction action = (ContentAssistAction ) editor .getAction (ITextEditorActionConstants .CONTENT_ASSIST );
151164 action .update ();
152165 final Set <Shell > beforeShells = Arrays .stream (editor .getSite ().getShell ().getDisplay ().getShells ()).filter (Shell ::isVisible ).collect (Collectors .toSet ());
@@ -165,29 +178,27 @@ private Shell openConentAssist(boolean expectShell) {
165178 */
166179 private void checkCompletionContent (final Table completionProposalList ) {
167180 // should be instantaneous, but happens to go asynchronous on CI so let's allow a wait
168- assertTrue (new DisplayHelper () {
169- @ Override
170- protected boolean condition () {
171- return completionProposalList .getItemCount () == 2 ;
172- }
173- }.waitForCondition (completionProposalList .getDisplay (), 200 ));
181+ waitForProposalRelatedCondition ("Proposal list did not show two initial items" , completionProposalList ,
182+ () -> completionProposalList .getItemCount () == 2 , 200 );
174183 assertTrue ("Missing computing info entry" , isComputingInfoEntry (completionProposalList .getItem (0 )));
175- TableItem completionProposalItem = completionProposalList .getItem (1 );
176- final ICompletionProposal selectedProposal = (ICompletionProposal )completionProposalItem .getData ();
177- assertTrue ("Incorrect proposal content" , BarContentAssistProcessor .PROPOSAL .endsWith (selectedProposal .getDisplayString ()));
178- completionProposalList .setSelection (completionProposalItem );
184+ assertTrue ("Missing computing info entry in proposal list" , isComputingInfoEntry (completionProposalList .getItem (0 )));
185+ final TableItem initialProposalItem = completionProposalList .getItem (1 );
186+ final String initialProposalString = ((ICompletionProposal )initialProposalItem .getData ()).getDisplayString ();
187+ assertThat ("Unexpected initial proposal item" ,
188+ BarContentAssistProcessor .PROPOSAL , endsWith (initialProposalString ));
189+ completionProposalList .setSelection (initialProposalItem );
179190 // asynchronous
180- new DisplayHelper () {
181- @ Override
182- protected boolean condition () {
183- return ! isComputingInfoEntry ( completionProposalList .getItem (0 )) && completionProposalList . getItemCount () == 2 ;
184- }
185- }. waitForCondition ( completionProposalList . getDisplay (), LongRunningBarContentAssistProcessor . DELAY + 200 );
186- completionProposalItem = completionProposalList . getItem ( 0 );
187- assertTrue ( "Proposal content seems incorrect " , BarContentAssistProcessor .PROPOSAL . endsWith ((( ICompletionProposal ) completionProposalItem . getData ()). getDisplayString () ));
188- TableItem otherProposalItem = completionProposalList . getItem ( 1 );
189- assertTrue ( "Proposal content seems incorrect" , LongRunningBarContentAssistProcessor . PROPOSAL . endsWith ((( ICompletionProposal )otherProposalItem . getData ()).getDisplayString ()) );
190- assertEquals ("Addition of completion proposal should keep selection" , selectedProposal , completionProposalList . getSelection ()[ 0 ]. getData () );
191+ waitForProposalRelatedCondition ( "Proposal list did not show two items after finishing computing" , completionProposalList ,
192+ () -> ! isComputingInfoEntry ( completionProposalList . getItem ( 0 )) && completionProposalList . getItemCount () == 2 ,
193+ LongRunningBarContentAssistProcessor . DELAY + 200 );
194+ final TableItem firstCompletionProposalItem = completionProposalList .getItem (0 );
195+ final TableItem secondCompletionProposalItem = completionProposalList . getItem ( 1 );
196+ String firstCompletionProposalText = (( ICompletionProposal ) firstCompletionProposalItem . getData ()). getDisplayString ( );
197+ String secondCOmpletionProposalText = (( ICompletionProposal ) secondCompletionProposalItem . getData ()). getDisplayString ( );
198+ assertThat ( "Unexpected first proposal item " , BarContentAssistProcessor .PROPOSAL , endsWith (firstCompletionProposalText ));
199+ assertThat ( "Unexpected second proposal item" , LongRunningBarContentAssistProcessor . PROPOSAL , endsWith ( secondCOmpletionProposalText ) );
200+ String selectedProposalString = (( ICompletionProposal )completionProposalList . getSelection ()[ 0 ]. getData ()).getDisplayString ();
201+ assertEquals ("Addition of completion proposal should keep selection" , initialProposalString , selectedProposalString );
191202 }
192203
193204 private static boolean isComputingInfoEntry (TableItem item ) {
@@ -208,16 +219,11 @@ public static Shell findNewShell(Set<Shell> beforeShells, Display display, boole
208219 @ Test
209220 public void testCompletionFreeze_bug521484 () throws Exception {
210221 editor .selectAndReveal (3 , 0 );
211- this . completionShell = openConentAssist ();
212- final Table completionProposalList = findCompletionSelectionControl (this . completionShell );
222+ completionShell = openContentAssist ();
223+ final Table completionProposalList = findCompletionSelectionControl (completionShell );
213224 // should be instantaneous, but happens to go asynchronous on CI so let's allow a wait
214- new DisplayHelper () {
215- @ Override
216- protected boolean condition () {
217- return completionProposalList .getItemCount () == 2 ;
218- }
219- }.waitForCondition (completionShell .getDisplay (), 200 );
220- assertEquals (2 , completionProposalList .getItemCount ());
225+ waitForProposalRelatedCondition ("Proposal list did not show two items" , completionProposalList ,
226+ () -> completionProposalList .getItemCount () == 2 , 200 );
221227 assertTrue ("Missing computing info entry" , isComputingInfoEntry (completionProposalList .getItem (0 )));
222228 // Some processors are long running, moving cursor can cause freeze (bug 521484)
223229 // asynchronous
@@ -251,16 +257,17 @@ private void emulatePressLeftArrowKey() {
251257 }
252258
253259 public static Table findCompletionSelectionControl (Widget control ) {
254- if ( control instanceof Table ) {
255- return ( Table ) control ;
256- } else if ( control instanceof Composite ) {
257- for ( Widget child : (( Composite ) control ). getChildren ()) {
258- Table res = findCompletionSelectionControl (child );
259- if ( res != null ) {
260- return res ;
261- }
260+ Queue < Widget > widgetsToProcess = new LinkedList <>();
261+ widgetsToProcess . add ( control ) ;
262+ while (! widgetsToProcess . isEmpty () ) {
263+ Widget child = widgetsToProcess . poll ();
264+ if (child instanceof Table table ) {
265+ return table ;
266+ } else if ( child instanceof Composite composite ) {
267+ widgetsToProcess . addAll ( Arrays . asList ( composite . getChildren ()));
262268 }
263269 }
270+ fail ("No completion selection control found in widget: " + control );
264271 return null ;
265272 }
266273
0 commit comments