Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 09e5f94515549883e2089f638571cebc08036d91 (plain) (blame)
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
/*******************************************************************************
 * Copyright (c) 2010, 2014 Wind River Systems and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Wind River Systems - initial API and implementation
 *     Dorin Ciuca - Top index fix (Bug 324100)
 *     IBM Corporation - clean-up
 *     Anton Leherbauer (Wind River) - REVEAL delta does not always work reliably (Bug 438724)
 *******************************************************************************/
package org.eclipse.debug.tests.viewer.model;

import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.internal.ui.viewers.model.IInternalTreeModelViewer;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDeltaVisitor;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.PresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer;
import org.eclipse.debug.tests.TestUtil;
import org.eclipse.debug.tests.viewer.model.TestModel.TestElement;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

/**
 * @since 3.6
 */
public class JFaceViewerTopIndexTests extends AbstractViewerModelTest implements ITestModelUpdatesListenerConstants {

    public JFaceViewerTopIndexTests(String name) {
        super(name);
    }

	@Override
	protected TestModelUpdatesListener createListener(IInternalTreeModelViewer viewer) {
		return new TestModelUpdatesListener(viewer, false, false);
	}

	protected final TreeModelViewer getCTargetViewer() {
		return (TreeModelViewer) fViewer;
    }

    /**
     * @param display the display
     * @param shell the shell
     * @return the new viewer
     */
    @Override
	protected TreeModelViewer createViewer(Display display, Shell shell) {
		return new TreeModelViewer(fShell, SWT.VIRTUAL | SWT.MULTI, new PresentationContext("TestViewer")); //$NON-NLS-1$
    }

    /**
     * Restore REVEAL on simple model with elements without children.
     *
     */
	public void testRestoreTopIndex() throws Exception {
		TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(getCTargetViewer());

    	TestModel model = new TestModel();

        TestElement[] elements = new TestElement[8];
        for (int i = 0; i < elements.length; i++) {
            String text = Integer.toString(i + 1);
        	// elements don't have children
        	elements[i] =
                new TestElement(model, text, new TestElement[0] );

        }
		model.setRoot(new TestElement(model, "root", elements)); //$NON-NLS-1$

        // Create the listener, only check the first level
        fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, false, false);

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());

		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
        model.validateData(fViewer, TreePath.EMPTY, true);

        // Stop forcing view updates.
        autopopulateAgent.dispose();

        // scroll to the 5th element
        int indexRevealElem = 4;
        getCTargetViewer().reveal(TreePath.EMPTY, indexRevealElem);
		TestUtil.processUIEvents();
        final TreePath originalTopPath = getCTargetViewer().getTopElementPath();
		assertNotNull("Top item should not be null!", originalTopPath); //$NON-NLS-1$
        // Bug 116105: On a Mac the reveal call is not reliable.  Use the viewer returned path instead.
        // assertEquals(elements[indexRevealElem], originalTopPath.getLastSegment());

        // Extract the original state from viewer
        ModelDelta originalState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
        fViewer.saveElementState(TreePath.EMPTY, originalState, IModelDelta.EXPAND | IModelDelta.SELECT);

        // Set the viewer input to null.  This will trigger the view to save the viewer state.
        fListener.reset(true, false);
        fListener.addStateUpdates(getCTargetViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL);

        fViewer.setInput(null);
		waitWhile(t -> !fListener.isFinished(STATE_SAVE_COMPLETE | STATE_UPDATES), createListenerErrorMessage());

        // Set the viewer input back to the model to trigger RESTORE operation.
        fListener.reset(false, false);
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE), createListenerErrorMessage());

		TestUtil.processUIEvents();
        // check if REVEAL was restored OK
        final TreePath topPath = getCTargetViewer().getTopElementPath();
		assertNotNull("Top item should not be null!", topPath); //$NON-NLS-1$
        TreePathWrapper.assertEqual(originalTopPath, topPath);
    }

    /**
     * Restore REVEAL when having also to restore an expanded element
     * that is just above the REVEAL element.
     *
     * See bug 324100
     */
	public void testRestoreTopAndExpand() throws Exception {
		TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(getCTargetViewer());

        TestModel model = new TestModel();

        TestElement[] elements = new TestElement[10];
        for (int i = 0; i < elements.length; i++) {
            String text = Integer.toString(i + 1);
            // first element has 2 children
            if (i == 0) {
            	elements[i] =
                    new TestElement(model, text, new TestElement[] {
 new TestElement(model, text + ".1", new TestElement[0]), //$NON-NLS-1$
				new TestElement(model, text + ".2", new TestElement[0]) //$NON-NLS-1$
                    });
            } else {
            	// rest of elements don't have children
            	elements[i] =
                    new TestElement(model, text, new TestElement[0] );
            }

        }
		model.setRoot(new TestElement(model, "root", elements)); //$NON-NLS-1$

        // Create the listener, only check the first level
        fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, false, false);

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());

		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
        model.validateData(fViewer, TreePath.EMPTY, true);

        // Expand first element
        fListener.reset();
        fListener.setFailOnRedundantUpdates(false);
        int indexFirstElem = 0;
        TestElement firstElem = elements[indexFirstElem];
        ModelDelta rootDelta = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
        ModelDelta delta = model.getBaseDelta(rootDelta);
        TreePath firstElemPath = model.findElement(firstElem.getLabel());
        fListener.addUpdates(
            firstElemPath, firstElem, 1,
            CHILD_COUNT_UPDATES | CHILDREN_UPDATES );
        delta.addNode(firstElem, indexFirstElem, IModelDelta.EXPAND, firstElem.getChildren().length);

        model.postDelta(rootDelta);

		waitWhile(t -> !fListener.isFinished(CONTENT_SEQUENCE_COMPLETE | MODEL_CHANGED_COMPLETE), createListenerErrorMessage());

        // Validate that the first node is expanded
        assertTrue(getCTargetViewer().getExpandedState(firstElemPath) == true);

        // Stop forcing view updates.
        autopopulateAgent.dispose();

        // scroll to the 2nd element
        getCTargetViewer().reveal(TreePath.EMPTY, 1);
		TestUtil.processUIEvents();
        final TreePath originalTopPath = getCTargetViewer().getTopElementPath();
		assertNotNull("Top item should not be null!", originalTopPath); //$NON-NLS-1$
        // Bug 116105: On a Mac the reveal call is not reliable.  Use the viewer returned path instead.
        //assertEquals(elements[1], originalTopPath.getLastSegment());

        // Extract the original state from viewer
        ModelDelta originalState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
        fViewer.saveElementState(TreePath.EMPTY, originalState, IModelDelta.EXPAND | IModelDelta.SELECT);

        // Set the viewer input to null.  This will trigger the view to save the viewer state.
        fListener.reset(true, false);
        fListener.addStateUpdates(getCTargetViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL);
        fViewer.setInput(null);
		waitWhile(t -> !fListener.isFinished(STATE_SAVE_COMPLETE), createListenerErrorMessage());

        // Set the viewer input back to the model
        fListener.reset(false, false);
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE), createListenerErrorMessage());

		TestUtil.processUIEvents();
        // check if REVEAL was restored OK
        final TreePath topPath = getCTargetViewer().getTopElementPath();
		assertNotNull("Top item should not be null!", topPath); //$NON-NLS-1$
        TreePathWrapper.assertEqual(originalTopPath, topPath);
    }

    /**
     * Restore REVEAL when this operation triggers restoring of an expanded
     * element.
     *
     * See bug 324100
     */
	public void testRestoreTopTriggersExpand() throws Exception {
		TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(getCTargetViewer());

        TestModel model = new TestModel();

        TestElement[] elements = new TestElement[10];
        for (int i = 0; i < elements.length; i++) {
            String text = Integer.toString(i + 1);
            // last element has 2 children
            if (i == elements.length - 1) {
            	elements[i] =
                    new TestElement(model, text, new TestElement[] {
 new TestElement(model, text + ".1", new TestElement[0]), //$NON-NLS-1$
				new TestElement(model, text + ".2", new TestElement[0]) //$NON-NLS-1$
                    });
            } else {
            	// rest of elements don't have children
            	elements[i] =
                    new TestElement(model, text, new TestElement[0] );
            }

        }

        fViewer.setAutoExpandLevel(-1);
		model.setRoot(new TestElement(model, "root", elements)); //$NON-NLS-1$

        // Create the listener, only check the first level
        fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, false, false);

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());

		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
        model.validateData(fViewer, TreePath.EMPTY, true);

        int indexLastElem = elements.length-1;
        TestElement lastElem = elements[indexLastElem];
        TreePath lastElemePath = model.findElement(lastElem.getLabel());

        // Validate that the last node is expanded
        assertTrue(getCTargetViewer().getExpandedState(lastElemePath) == true);

        // Stop forcing view updates.
        fViewer.setAutoExpandLevel(0);
        autopopulateAgent.dispose();

        // scroll to the element before last element
        getCTargetViewer().reveal(TreePath.EMPTY, indexLastElem-1);
		TestUtil.processUIEvents();
        final TreePath originalTopPath = getCTargetViewer().getTopElementPath();
		assertNotNull("Top item should not be null!", originalTopPath); //$NON-NLS-1$

        // Extract the original state from viewer
        ModelDelta originalState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
        fViewer.saveElementState(TreePath.EMPTY, originalState, IModelDelta.EXPAND | IModelDelta.SELECT);

        // Set the viewer input to null.  This will trigger the view to save the viewer state.
        fListener.reset(true, false);
        fListener.addStateUpdates(getCTargetViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL);

        fViewer.setInput(null);
		waitWhile(t -> !fListener.isFinished(STATE_SAVE_COMPLETE | STATE_UPDATES), createListenerErrorMessage());

        // Set the viewer input back to the model.
        fListener.reset(false, false);
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE), createListenerErrorMessage());

		TestUtil.processUIEvents();
        // check if REVEAL was restored OK
        final TreePath topPath = getCTargetViewer().getTopElementPath();
		assertNotNull("Top item should not be null!", topPath); //$NON-NLS-1$
        TreePathWrapper.assertEqual(originalTopPath, topPath);
    }

    /**
     * Test for bug 326965.<br>
     * This test verifies that canceling a reveal pending state delta is
     * properly handled when a new reveal delta is received from the model.
     */
	public void testRestoreRevealAfterRevealCancel() throws Exception {
		TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(getCTargetViewer());
        TestModel model = TestModel.simpleMultiLevel();

        // Expand all
        fViewer.setAutoExpandLevel(-1);

        // Create the listener.
        fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, false, false);

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
        model.validateData(fViewer, TreePath.EMPTY, true);

        // Stop autopopulating the view.
        autopopulateAgent.dispose();

        // Set top index of view to element "3" and wait for view to repaint.
        getCTargetViewer().reveal(TreePath.EMPTY, 2);
		TestUtil.processUIEvents();

        // Trigger save of state.
        fListener.reset();
        fViewer.setInput(null);
        while (!fListener.isFinished(STATE_SAVE_COMPLETE)) {
			Thread.sleep(0);
		}

        // Set input back to root element.
        // Note: Wait only for the processing of the delta and the start of state restore, not for all updates
        fListener.reset();
		TreePath elementPath = model.findElement("3"); //$NON-NLS-1$
        fListener.addUpdates(fViewer, elementPath, model.getElement(elementPath), 1, STATE_UPDATES);
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE | STATE_UPDATES), createListenerErrorMessage());

        // Update the viewer with new selection delta to something new in the view
		ModelDelta revealDelta = model.makeElementDelta(model.findElement("2.1"), IModelDelta.REVEAL); //$NON-NLS-1$

        // Wait for the second model delta to process
        fListener.reset();
        model.postDelta(revealDelta);
		waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE | CONTENT_SEQUENCE_COMPLETE), createListenerErrorMessage());

        // Clear view then reset it again.
        fListener.reset();
        fViewer.setInput(null);
        while (!fListener.isFinished(STATE_SAVE_COMPLETE)) {
			Thread.sleep(0);
		}

		autopopulateAgent = new TreeModelViewerAutopopulateAgent(getCTargetViewer());
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(STATE_RESTORE_COMPLETE), createListenerErrorMessage());
        autopopulateAgent.dispose();
    }

    /**
     * Test for bug 326965.<br>
     * This test verifies that canceling a reveal pending state delta is
     * properly handled when a new reveal delta is received from the model.
     */
	public void testRestoreRevealAfterRevealCancel2() throws Exception {
    	if (Platform.getOS().equals(Platform.OS_MACOSX)) {
    		// skip this test on Mac - see bug 327557
    		return;
    	}
		TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(getCTargetViewer());
        TestModel model = TestModel.simpleMultiLevel();

        // Expand all
        fViewer.setAutoExpandLevel(-1);

        // Create the listener.
        fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, false, false);

        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
        model.validateData(fViewer, TreePath.EMPTY, true);

        // Stop auto-populating and auto-expanding the view.
        fViewer.setAutoExpandLevel(0);
        autopopulateAgent.dispose();

        // Set top index of view to element "3" and wait for view to repaint.
        getCTargetViewer().reveal(TreePath.EMPTY, 2);
		TestUtil.processUIEvents();

        // Trigger save of state.
        fListener.reset();
        fViewer.setInput(null);
        while (!fListener.isFinished(STATE_SAVE_COMPLETE)) {
			Thread.sleep(0);
		}

        // Set input back to root element.
        // Note: Wait only for the processing of the delta and the start of state restore, not for all updates
        fListener.reset();
		TreePath elementPath = model.findElement("2"); //$NON-NLS-1$
        fListener.addUpdates(fViewer, elementPath, model.getElement(elementPath), 1, STATE_UPDATES | CHILDREN_UPDATES | LABEL_UPDATES);
		elementPath = model.findElement("3"); //$NON-NLS-1$
        fListener.addUpdates(fViewer, elementPath, model.getElement(elementPath), 0, STATE_UPDATES);
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(STATE_UPDATES), createListenerErrorMessage());

        // Update the viewer with new selection delta to something new in the view
		TreePath pathToBeRevealed = model.findElement("2.1"); //$NON-NLS-1$
        ModelDelta revealDelta = model.makeElementDelta(pathToBeRevealed, IModelDelta.REVEAL);
        revealDelta.accept(new IModelDeltaVisitor() {

            @Override
			public boolean visit(IModelDelta delta, int depth) {
                ((ModelDelta)delta).setFlags(delta.getFlags() | IModelDelta.EXPAND);
                return true;
            }
        });

        // Wait for the second model delta to process
        model.postDelta(revealDelta);
		waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE | CHILDREN_UPDATES | LABEL_UPDATES), createListenerErrorMessage());

        // check if REVEAL was triggered by the delta and not by the
        // state restore operation
        TreePath topPath = getCTargetViewer().getTopElementPath();
		assertNotNull("Top item should not be null!", topPath); //$NON-NLS-1$
        TreePathWrapper.assertEqual(pathToBeRevealed, topPath);
    }



    /**
     * Restore REVEAL when having also to restore an expanded element
     * that is just above the REVEAL element.
     *
     * See bug 324100
     */
	public void testRestoreDeepTreeAndReveal() throws Exception {
		TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(getCTargetViewer());

        TestModel model = TestModel.simpleDeepMultiLevel();
        fViewer.setAutoExpandLevel(-1);

        // Create the listener, only check the first level
        fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, false, false);


        // Set the input into the view and update the view.
        fViewer.setInput(model.getRootElement());

		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
        model.validateData(fViewer, TreePath.EMPTY, true);

        // Stop forcing view updates.
        autopopulateAgent.dispose();

        // Scroll down to the last part of the tree.
		getCTargetViewer().reveal(model.findElement("3.6.3.16.16.16.16.16"), 1); //$NON-NLS-1$
		TestUtil.processUIEvents();
        final TreePath originalTopPath = getCTargetViewer().getTopElementPath();
		assertNotNull("Top item should not be null!", originalTopPath); //$NON-NLS-1$

        // Extract the original state from viewer
        ModelDelta originalState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE);
        fViewer.saveElementState(TreePath.EMPTY, originalState, IModelDelta.EXPAND | IModelDelta.SELECT);

        // Set the viewer input to null.  This will trigger the view to save the viewer state.
        fListener.reset(true, false);
        fListener.addStateUpdates(getCTargetViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL);
        fViewer.setInput(null);
		waitWhile(t -> !fListener.isFinished(STATE_SAVE_COMPLETE), createListenerErrorMessage());

        // Set the viewer input back to the model
        fListener.reset(false, false);
        fListener.addUpdates(getCTargetViewer(), originalTopPath, (TestElement)originalTopPath.getLastSegment(), 0, STATE_UPDATES);
        fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(STATE_UPDATES | CONTENT_SEQUENCE_COMPLETE), createListenerErrorMessage());

		TestUtil.processUIEvents();
        // check if REVEAL was restored OK
        final TreePath topPath = getCTargetViewer().getTopElementPath();
		assertNotNull("Top item should not be null!", topPath); //$NON-NLS-1$
        TreePathWrapper.assertEqual(originalTopPath, topPath);

    }

	/**
	 * This test verifies that a revealed node does not get scrolled away due to
	 * structural updates.
	 */
	public void testRevealWithContentChanges() throws Exception {
		@SuppressWarnings("unused")
		TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(getCTargetViewer());
		TestModel model = TestModel.simpleDeepMultiLevel();

		// Expand first level
		fViewer.setAutoExpandLevel(1);

		// Create the listener.
		fListener.reset(false, false);

		// Set the input into the view and update the view.
		fViewer.setInput(model.getRootElement());
		waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage());
		model.validateData(fViewer, TreePath.EMPTY, true);

		// Set top index of view to element "2" and wait for view to repaint.
		getCTargetViewer().reveal(TreePath.EMPTY, 1);
		TestUtil.processUIEvents();
		TreePath element2Path = model.findElement("2"); //$NON-NLS-1$
		TreePath pathToBeRevealed = element2Path;
		TreePath topPath = getCTargetViewer().getTopElementPath();
		assertNotNull("Top item should not be null!", topPath); //$NON-NLS-1$
		TreePathWrapper.assertEqual(pathToBeRevealed, topPath);

		// Update the viewer with new reveal delta
		pathToBeRevealed = model.findElement("3"); //$NON-NLS-1$
		ModelDelta revealDelta = model.makeElementDelta(pathToBeRevealed, IModelDelta.REVEAL);
		// Add CONTENT delta for model element "2"
		ModelDelta element2Delta = model.makeElementDelta(element2Path, IModelDelta.CONTENT);
		element2Delta = (ModelDelta) element2Delta.getChildDeltas()[0];
		revealDelta.addNode(element2Delta.getElement(), element2Delta.getIndex(), element2Delta.getFlags(), element2Delta.getChildCount());

		// Remove some children from element "2"
		model.removeElementChild(element2Path, 0);
		model.removeElementChild(element2Path, 0);

		fListener.reset();

		// Delay updates
		model.setQeueueingUpdate(true);

		// Wait for the model delta to process
		model.postDelta(revealDelta);
		waitWhile(t -> !fListener.isFinished(CHILD_COUNT_UPDATES_STARTED), createListenerErrorMessage());

		model.setQeueueingUpdate(false);

		waitWhile(t -> !fListener.isFinished(ALL_UPDATES_COMPLETE), createListenerErrorMessage());

		// check if REVEAL actually revealed the desired element
		topPath = getCTargetViewer().getTopElementPath();
		assertNotNull("Top item should not be null!", topPath); //$NON-NLS-1$
		TreePathWrapper.assertEqual(pathToBeRevealed, topPath);
	}

}

Back to the top