| /******************************************************************************* |
| * Copyright (c) 2009, 2013 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 |
| * IBM Corporation - clean-up |
| *******************************************************************************/ |
| package org.eclipse.debug.tests.viewer.model; |
| |
| import java.util.Arrays; |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| 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.ModelDelta; |
| import org.eclipse.debug.tests.TestUtil; |
| import org.eclipse.debug.tests.viewer.model.TestModel.TestElement; |
| import org.eclipse.jface.viewers.ITreeSelection; |
| import org.eclipse.jface.viewers.TreePath; |
| import org.eclipse.jface.viewers.TreeSelection; |
| |
| /** |
| * Tests to verify that the viewer can save and restore correctly the expansion |
| * state of elements. |
| * |
| * @since 3.6 |
| */ |
| abstract public class StateTests extends AbstractViewerModelTest implements ITestModelUpdatesListenerConstants { |
| |
| public StateTests(String name) { |
| super(name); |
| } |
| |
| @Override |
| protected TestModelUpdatesListener createListener(IInternalTreeModelViewer viewer) { |
| return new TestModelUpdatesListener(viewer, false, false); |
| } |
| |
| protected IInternalTreeModelViewer getInternalViewer() { |
| return fViewer; |
| } |
| |
| public void testUpdateViewer() throws Exception { |
| //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); |
| |
| TestModel model = TestModel.simpleMultiLevel(); |
| |
| // Create the listener |
| fListener.reset(); |
| fListener.addChildreUpdate(TreePath.EMPTY, 0); |
| fListener.addChildreUpdate(TreePath.EMPTY, 1); |
| fListener.addChildreUpdate(TreePath.EMPTY, 2); |
| |
| // 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); |
| |
| // Create the update delta |
| TestElement element = model.getRootElement(); |
| TreePath path0 = TreePath.EMPTY; |
| ModelDelta delta = new ModelDelta(model.getRootElement(), -1, IModelDelta.EXPAND, element.getChildren().length); |
| ModelDelta updateDelta = delta; |
| element = element.getChildren()[2]; |
| TreePath path1 = path0.createChildPath(element); |
| delta = delta.addNode(element, 2, IModelDelta.EXPAND, element.fChildren.length); |
| element = element.getChildren()[1]; |
| TreePath path2 = path1.createChildPath(element); |
| delta = delta.addNode(element, 1, IModelDelta.EXPAND, element.fChildren.length); |
| element = element.getChildren()[1]; |
| TreePath path3 = path2.createChildPath(element); |
| delta = delta.addNode(element, 1, IModelDelta.SELECT); |
| |
| fListener.reset(false, false); |
| |
| fListener.addChildreUpdate(path0, 2); |
| fListener.addHasChildrenUpdate(path1); |
| fListener.addChildreCountUpdate(path1); |
| fListener.addLabelUpdate(path1); |
| fListener.addChildreUpdate(path1, 1); |
| fListener.addHasChildrenUpdate(path2); |
| fListener.addChildreCountUpdate(path2); |
| fListener.addLabelUpdate(path2); |
| fListener.addHasChildrenUpdate(path2); |
| fListener.addChildreCountUpdate(path2); |
| fListener.addChildreUpdate(path2, 1); |
| fListener.addHasChildrenUpdate(path3); |
| fListener.addLabelUpdate(path3); |
| |
| fViewer.updateViewer(updateDelta); |
| waitWhile(t -> !fListener.isFinished(CONTENT_SEQUENCE_COMPLETE | LABEL_UPDATES), createListenerErrorMessage()); |
| |
| // Extract the new state from viewer |
| ModelDelta savedDelta = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE); |
| fViewer.saveElementState(path0, savedDelta, IModelDelta.EXPAND | IModelDelta.SELECT); |
| |
| if (!deltaMatches(updateDelta, savedDelta) ) { |
| fail("Expected:\n" + updateDelta.toString() + "\nGot:\n" + savedDelta); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| |
| boolean deltaMatches(ModelDelta requested, ModelDelta received) { |
| if ( requested.getElement().equals(received.getElement()) && |
| requested.getFlags() == received.getFlags() && |
| ( requested.getChildCount() == -1 || requested.getChildCount() == received.getChildCount() )&& |
| ( requested.getIndex() == -1 || requested.getIndex() == received.getIndex()) && |
| ((requested.getReplacementElement() != null && requested.getReplacementElement().equals(received.getReplacementElement())) || |
| (requested.getReplacementElement() == null && received.getReplacementElement() == null)) && |
| requested.getChildDeltas().length == received.getChildDeltas().length) |
| { |
| for (int i = 0; i < requested.getChildDeltas().length; i++) { |
| ModelDelta requestedChildDelta = (ModelDelta)requested.getChildDeltas()[i]; |
| ModelDelta receivedChildDelta = received.getChildDelta(requestedChildDelta.getElement()); |
| if ( receivedChildDelta == null || !deltaMatches(requestedChildDelta, receivedChildDelta) ) { |
| return false; |
| } |
| } |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Creates a model in the pattern of: |
| * |
| * root |
| * 1 |
| * 1.1 |
| * 1.1.1 |
| * 2 |
| * 2.1 |
| * 2.1.1 |
| * 3 |
| * 3.1 |
| * 3.1.1 |
| * ... |
| * (size) |
| * (size).1 |
| * (size).1.1 |
| */ |
| static TestModel alternatingSubsreesModel(int size) { |
| TestModel model = new TestModel(); |
| |
| TestElement[] elements = new TestElement[size]; |
| for (int i = 0; i < size; i++) { |
| String text = Integer.toString(i + 1); |
| elements[i] = |
| new TestElement(model, text, new TestElement[] { |
| new TestElement(model, text + ".1", new TestElement[] { //$NON-NLS-1$ |
| new TestElement(model, text + ".1.1", new TestElement[0]) //$NON-NLS-1$ |
| }) |
| }); |
| } |
| model.setRoot(new TestElement(model, "root", elements)); //$NON-NLS-1$ |
| |
| return model; |
| } |
| |
| static boolean areTreeSelectionsEqual(ITreeSelection sel1, ITreeSelection sel2) { |
| Set<TreePath> sel1Set = new HashSet<TreePath>(); |
| sel1Set.addAll( Arrays.asList(sel1.getPaths()) ); |
| |
| Set<TreePath> sel2Set = new HashSet<TreePath>(); |
| sel2Set.addAll( Arrays.asList(sel2.getPaths()) ); |
| |
| return sel1Set.equals(sel2Set); |
| } |
| |
| static void expandAlternateElements(TestModelUpdatesListener listener, TestModel model, boolean waitForAllUpdates) throws Exception { |
| listener.reset(); |
| listener.setFailOnRedundantUpdates(false); |
| |
| TestElement rootElement = model.getRootElement(); |
| TestElement[] children = rootElement.getChildren(); |
| ModelDelta rootDelta = new ModelDelta(rootElement, IModelDelta.NO_CHANGE); |
| ModelDelta expandDelta = model.getBaseDelta(rootDelta); |
| for (int i = 0; i < children.length; i++) { |
| // Expand only odd children |
| if (i % 2 == 1) { |
| continue; |
| } |
| |
| // Expand the element and the first child of each sub-element |
| TestElement element = children[i]; |
| ModelDelta delta = expandDelta; |
| int index = i; |
| while (element.getChildren().length != 0) { |
| TreePath elementPath = model.findElement(element.getLabel()); |
| listener.addUpdates( |
| elementPath, element, 1, |
| CHILD_COUNT_UPDATES | (waitForAllUpdates ? CHILDREN_UPDATES : 0) ); |
| delta = delta.addNode(element, index, IModelDelta.EXPAND, element.getChildren().length); |
| element = element.getChildren()[0]; |
| index = 0; |
| } |
| } |
| model.postDelta(rootDelta); |
| |
| TestUtil.waitWhile(t -> !listener.isFinished(CONTENT_SEQUENCE_COMPLETE | MODEL_CHANGED_COMPLETE), null, 30000, t -> "Listener not finished: " + listener); |
| } |
| |
| public void testPreserveExpandedOnRemove() throws Exception { |
| //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); |
| TestModel model = alternatingSubsreesModel(6); |
| |
| // NOTE: WE ARE NOT EXPANDING ANY CHILDREN |
| |
| // Create the listener, only check the first level |
| fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, true, 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); |
| |
| expandAlternateElements(fListener, model, true); |
| |
| // Set a selection in view |
| TreeSelection originalSelection = new TreeSelection(model.findElement("5.1")); //$NON-NLS-1$ |
| fViewer.setSelection(originalSelection); |
| |
| // Update the model |
| ModelDelta delta = model.removeElementChild(TreePath.EMPTY, 0); |
| |
| // Remove delta should not generate any new updates |
| fListener.reset(); |
| model.postDelta(delta); |
| waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE), createListenerErrorMessage()); |
| |
| // Validate data |
| model.validateData(fViewer, TreePath.EMPTY, true); |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("2")) == false); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("4")) == false); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("5")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("5.1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("6")) == false); //$NON-NLS-1$ |
| assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) ); |
| } |
| |
| public void testPreserveExpandedOnInsert() throws Exception { |
| //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); |
| TestModel model = alternatingSubsreesModel(6); |
| |
| // NOTE: WE ARE NOT EXPANDING ANY CHILDREN |
| |
| // Create the listener, only check the first level |
| fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, true, 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); |
| |
| expandAlternateElements(fListener, model, true); |
| |
| // Set a selection in view |
| TreeSelection originalSelection = new TreeSelection(model.findElement("5.1")); //$NON-NLS-1$ |
| fViewer.setSelection(originalSelection); |
| |
| // Update the model |
| ModelDelta delta = model.insertElementChild(TreePath.EMPTY, 0, new TestElement(model, "0 - new", new TestElement[0])); //$NON-NLS-1$ |
| |
| // Insert delta should generate updates only for the new element |
| TreePath path = model.findElement("0 - new"); //$NON-NLS-1$ |
| // Note: redundant label updates on insert. |
| fListener.reset(path, (TestElement)path.getLastSegment(), 0, false, false); |
| fListener.addChildreUpdate(TreePath.EMPTY, 0); |
| model.postDelta(delta); |
| waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE | ALL_UPDATES_COMPLETE), createListenerErrorMessage()); |
| |
| // Validate data |
| model.validateData(fViewer, TreePath.EMPTY, true); |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("1.1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("2")) == false); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("4")) == false); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("5")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("5.1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("6")) == false); //$NON-NLS-1$ |
| assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) ); |
| } |
| |
| public void testPreserveExpandedOnMultLevelContent() throws Exception { |
| //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); |
| TestModel model = alternatingSubsreesModel(6); |
| |
| // NOTE: WE ARE NOT EXPANDING ANY CHILDREN |
| |
| // Create the listener, only check the first level |
| fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, true, 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); |
| |
| expandAlternateElements(fListener, model, true); |
| |
| // Set a selection in view |
| // Set a selection in view |
| TreeSelection originalSelection = new TreeSelection( |
| new TreePath[] { model.findElement("5"), model.findElement("5.1"), model.findElement("6") }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| fViewer.setSelection(originalSelection); |
| assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) ); |
| |
| // Update the model |
| model.removeElementChild(TreePath.EMPTY, 0); |
| |
| // Note: Re-expanding nodes causes redundant updates. |
| fListener.reset(false, false); |
| fListener.addUpdates(getInternalViewer(), TreePath.EMPTY, model.getRootElement(), -1, ALL_UPDATES_COMPLETE); |
| |
| // Create the delta which has nodes with CONTENT flag set at multiple levels. |
| ModelDelta rootDelta = new ModelDelta(model.getRootElement(), IModelDelta.CONTENT); |
| ModelDelta elementDelta = model.getElementDelta(rootDelta, model.findElement("3.1.1"), true); //$NON-NLS-1$ |
| elementDelta.setFlags(IModelDelta.CONTENT); |
| |
| // Post the multi-content update delta |
| model.postDelta(rootDelta); |
| waitWhile(t -> !fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE), createListenerErrorMessage()); |
| |
| // Validate data |
| model.validateData(fViewer, TreePath.EMPTY, true); |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("2")) == false); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("4")) == false); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("5")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("5.1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("6")) == false); //$NON-NLS-1$ |
| assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) ); |
| |
| // Note: in past it was observed sub-optimal coalescing in this test due |
| // to scattered update requests from viewer. |
| assertTrue( fListener.checkCoalesced(TreePath.EMPTY, 0, 5) ); |
| } |
| |
| |
| public void testPreserveExpandedOnSubTreeContent() throws Exception { |
| //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); |
| TestModel model = TestModel.simpleMultiLevel(); |
| |
| // Expand all |
| fViewer.setAutoExpandLevel(-1); |
| |
| // Create the listener, |
| fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, true, 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); |
| |
| // Turn off auto-expansion |
| fViewer.setAutoExpandLevel(0); |
| |
| // Set a selection in view |
| TreeSelection originalSelection = new TreeSelection(model.findElement("3.3.1")); //$NON-NLS-1$ |
| fViewer.setSelection(originalSelection); |
| |
| // Update the model |
| model.addElementChild(model.findElement("3"), null, 0, new TestElement(model, "3.0 - new", new TestElement[0])); //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| // Create the delta for element "3" with content update. |
| TreePath elementPath = model.findElement("3"); //$NON-NLS-1$ |
| ModelDelta rootDelta = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE); |
| ModelDelta elementDelta = model.getElementDelta(rootDelta, elementPath, true); |
| elementDelta.setFlags(IModelDelta.CONTENT); |
| |
| // Note: Re-expanding nodes causes redundant updates. |
| fListener.reset(false, false); |
| fListener.addUpdates(getInternalViewer(), elementPath, model.getElement(elementPath), -1, ALL_UPDATES_COMPLETE); |
| |
| // Post the sub-tree update |
| model.postDelta(rootDelta); |
| waitWhile(t -> !fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE), createListenerErrorMessage()); |
| |
| // Validate data |
| model.validateData(fViewer, TreePath.EMPTY, true); |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3")) == true); //$NON-NLS-1$ |
| // On windows, getExpandedState() may return true for an element with no children: |
| // assertTrue(getCTargetViewer().getExpandedState(model.findElement("3.0 - new")) == false); |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3.2")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3.3")) == true); //$NON-NLS-1$ |
| assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) ); |
| } |
| |
| public void testPreserveExpandedOnContentStress() throws Exception { |
| //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); |
| TestModel model = alternatingSubsreesModel(6); |
| |
| // NOTE: WE ARE NOT EXPANDING ANY CHILDREN |
| |
| // Create the listener, only check the first level |
| fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, true, 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); |
| |
| expandAlternateElements(fListener, model, true); |
| |
| // Set a selection in view |
| // TreeSelection originalSelection = new TreeSelection( |
| // new TreePath[] { model.findElement("5"), model.findElement("5.1"), model.findElement("6") }); |
| TreeSelection originalSelection = new TreeSelection(model.findElement("5.1.1")); //$NON-NLS-1$ |
| fViewer.setSelection(originalSelection); |
| assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) ); |
| |
| // Run this test ten times as we've seen intermittent failures related |
| // to timing in it. |
| for (int i = 0; i < 10; i++) { |
| // Update the model |
| model.removeElementChild(TreePath.EMPTY, 0); |
| |
| // Note: Re-expanding nodes causes redundant updates. |
| fListener.reset(false, false); |
| fListener.addUpdates(getInternalViewer(), TreePath.EMPTY, model.getRootElement(), -1, ALL_UPDATES_COMPLETE); |
| model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT)); |
| waitWhile(t -> !fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE), createListenerErrorMessage()); |
| |
| // Validate data |
| model.validateData(fViewer, TreePath.EMPTY, true); |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("2")) == false); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("4")) == false); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("5")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("5.1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("6")) == false); //$NON-NLS-1$ |
| assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) ); |
| |
| // Update the model again |
| model.addElementChild(TreePath.EMPTY, null, 0, new TestElement(model, "1", new TestElement[0])); //$NON-NLS-1$ |
| |
| // Note: Re-expanding nodes causes redundant updates. |
| fListener.reset(false, false); |
| fListener.addUpdates(getInternalViewer(), TreePath.EMPTY, model.getRootElement(), -1, ALL_UPDATES_COMPLETE); |
| model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT)); |
| waitWhile(t -> !fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE), createListenerErrorMessage()); |
| |
| // Validate data |
| model.validateData(fViewer, TreePath.EMPTY, true); |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("2")) == false); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("4")) == false); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("5")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("5.1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("6")) == false); //$NON-NLS-1$ |
| assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) ); |
| } |
| } |
| |
| public void testPreserveLargeModelOnContent() throws Exception { |
| //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); |
| TestModel model = alternatingSubsreesModel(100); |
| |
| // NOTE: WE ARE NOT EXPANDING ANY CHILDREN |
| |
| // Create the listener, only check the first level |
| fListener.reset(); |
| |
| // Set the input into the view and update the view. |
| fViewer.setInput(model.getRootElement()); |
| waitWhile(t -> !fListener.isFinished(CONTENT_SEQUENCE_COMPLETE), createListenerErrorMessage()); |
| |
| expandAlternateElements(fListener, model, false); |
| |
| // Set a selection in view |
| TreeSelection originalSelection = new TreeSelection(model.findElement("5.1.1")); //$NON-NLS-1$ |
| fViewer.setSelection(originalSelection); |
| assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) ); |
| |
| // Update the model |
| model.removeElementChild(TreePath.EMPTY, 0); |
| |
| // Note: Re-expanding nodes causes redundant updates. |
| fListener.reset(false, false); |
| model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT)); |
| waitWhile(t -> !fListener.isFinished(CONTENT_SEQUENCE_COMPLETE), createListenerErrorMessage()); |
| |
| // Validate data |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("2")) == false); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("4")) == false); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("5")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("5.1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("6")) == false); //$NON-NLS-1$ |
| assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) ); |
| |
| // Update the model again |
| model.addElementChild(TreePath.EMPTY, null, 0, new TestElement(model, "1", new TestElement[0])); //$NON-NLS-1$ |
| |
| // Note: Re-expanding nodes causes redundant updates. |
| fListener.reset(false, false); |
| model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT)); |
| waitWhile(t -> !fListener.isFinished(CONTENT_SEQUENCE_COMPLETE), createListenerErrorMessage()); |
| |
| // Validate data |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("2")) == false); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("4")) == false); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("5")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("5.1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("6")) == false); //$NON-NLS-1$ |
| assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) ); |
| } |
| |
| /** |
| * This test verifies that if the model selects a new element |
| * following a content refresh, the state restore logic will |
| * not override the selection requested by the model. |
| */ |
| public void testPreserveSelectionDeltaAfterContent() throws Exception { |
| //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); |
| TestModel model = TestModel.simpleMultiLevel(); |
| |
| // Expand all |
| fViewer.setAutoExpandLevel(-1); |
| |
| // Create the listener. |
| fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, true, 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 a selection in view |
| fViewer.setSelection(new TreeSelection(model.findElement("3.1.1"))); //$NON-NLS-1$ |
| |
| // Reset the listener (ignore redundant updates) |
| fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, false, false); |
| |
| // Refresh content. |
| // Note: Wait only for the processing of the delta, not for all updates |
| model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT)); |
| waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE), createListenerErrorMessage()); |
| |
| // Update the viewer with new selection delta to something new in the view |
| ModelDelta selectDelta = model.makeElementDelta(model.findElement("2.1"), IModelDelta.SELECT); //$NON-NLS-1$ |
| |
| // Wait for the second model delta to process |
| fListener.resetModelChanged(); |
| model.postDelta(selectDelta); |
| waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE), createListenerErrorMessage()); |
| |
| // Wait for all the updates to complete (note: we're not resetting the listener. |
| model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT)); |
| waitWhile(t -> !fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE), createListenerErrorMessage()); |
| |
| // Check to make sure that the state restore didn't change the selection. |
| assertEquals(new TreeSelection(model.findElement("2.1")), fViewer.getSelection()); //$NON-NLS-1$ |
| } |
| |
| public void testPreserveCollapseDeltaAfterContent() throws Exception { |
| //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); |
| TestModel model = TestModel.simpleMultiLevel(); |
| |
| // Expand all |
| fViewer.setAutoExpandLevel(-1); |
| |
| // Create the listener. |
| fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, true, 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); |
| |
| // Turn off auto-expand |
| fViewer.setAutoExpandLevel(0); |
| |
| // Reset the listener (ignore redundant updates) |
| fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, false, false); |
| |
| // Refresh content. |
| // Note: Wait only for the processing of the delta, not for all updates |
| model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT)); |
| waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE), createListenerErrorMessage()); |
| |
| // Update the viewer to collapse an element |
| ModelDelta collapseDelta = model.makeElementDelta(model.findElement("3.1"), IModelDelta.COLLAPSE); //$NON-NLS-1$ |
| |
| // Remove updates for the collapsed element from listener, because they |
| // will never happen if the element remains collapsed. |
| fListener.resetModelChanged(); |
| fListener.removeLabelUpdate(model.findElement("3.1.1")); //$NON-NLS-1$ |
| fListener.removeLabelUpdate(model.findElement("3.1.2")); //$NON-NLS-1$ |
| fListener.removeLabelUpdate(model.findElement("3.1.3")); //$NON-NLS-1$ |
| fListener.removeHasChildrenUpdate(model.findElement("3.1.1")); //$NON-NLS-1$ |
| fListener.removeHasChildrenUpdate(model.findElement("3.1.2")); //$NON-NLS-1$ |
| fListener.removeHasChildrenUpdate(model.findElement("3.1.3")); //$NON-NLS-1$ |
| fListener.removeChildreCountUpdate(model.findElement("3.1")); //$NON-NLS-1$ |
| fListener.removeChildrenUpdate(model.findElement("3.1"), 0); //$NON-NLS-1$ |
| fListener.removeChildrenUpdate(model.findElement("3.1"), 1); //$NON-NLS-1$ |
| fListener.removeChildrenUpdate(model.findElement("3.1"), 2); //$NON-NLS-1$ |
| |
| // Wait for the second model delta to process |
| model.postDelta(collapseDelta); |
| waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE), createListenerErrorMessage()); |
| |
| // Wait for all the updates to complete (note: we're not resetting the listener. |
| model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT)); |
| waitWhile(t -> !fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE), createListenerErrorMessage()); |
| |
| // Check to make sure that the state restore didn't change the selection. |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == false); //$NON-NLS-1$ |
| } |
| |
| public void testPreserveExpandDeltaAfterContent() throws Exception { |
| //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); |
| TestModel model = TestModel.simpleMultiLevel(); |
| |
| // Note: Do not auto-expand! |
| |
| // Create the listener. |
| fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, true, 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); |
| |
| // Reset the listener (ignore redundant updates) |
| fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, false, false); |
| |
| // Refresh content. |
| // Note: Wait only for the processing of the delta, not for all updates |
| model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT)); |
| waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE), createListenerErrorMessage()); |
| |
| // Update the viewer to expand an element |
| ModelDelta expandDelta = model.makeElementDelta(model.findElement("3.1"), IModelDelta.EXPAND); //$NON-NLS-1$ |
| |
| // Wait for the second model delta to process |
| fListener.resetModelChanged(); |
| model.postDelta(expandDelta); |
| waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE), createListenerErrorMessage()); |
| |
| // Wait for all the updates to complete (note: we're not resetting the listener. |
| model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT)); |
| waitWhile(t -> !fListener.isFinished(ALL_UPDATES_COMPLETE | STATE_RESTORE_COMPLETE), createListenerErrorMessage()); |
| |
| // Check to make sure that the state restore didn't change the selection. |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == true); //$NON-NLS-1$ |
| } |
| |
| |
| public void testSaveAndRestore1() throws Exception { |
| //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); |
| TestModel model = alternatingSubsreesModel(6); |
| |
| // NOTE: WE ARE NOT EXPANDING ANY CHILDREN |
| |
| // Create the listener, only check the first level |
| fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, true, 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 some, but not all elements |
| expandAlternateElements(fListener, model, true); |
| |
| // Set a selection in view |
| fViewer.setSelection(new TreeSelection(new TreePath[] { model.findElement("5.1"), model.findElement("5.1.1"), model.findElement("6.1.1") })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| |
| // 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(false, false); |
| fListener.addStateUpdates(getInternalViewer(), 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. When view updates are complete |
| // the viewer |
| // Note: disable redundant updates because the reveal delta triggers one. |
| fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, false, false); |
| // TODO: add state updates somehow? |
| fViewer.setInput(model.getRootElement()); |
| waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage()); |
| |
| // Extract the restored state from viewer |
| ModelDelta restoredState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE); |
| fViewer.saveElementState(TreePath.EMPTY, restoredState, IModelDelta.EXPAND | IModelDelta.SELECT); |
| |
| if (!deltaMatches(originalState, restoredState)) { |
| fail("Expected:\n" + originalState.toString() + "\nGot:\n" + restoredState); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| |
| public void testSaveAndRestore2() throws Exception { |
| //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); |
| TestModel model = TestModel.simpleMultiLevel(); |
| |
| // expand all elements |
| fViewer.setAutoExpandLevel(-1); |
| |
| // Create the listener, only check the first level |
| fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, true, 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); |
| |
| // Set a selection in view |
| fViewer.setSelection(new TreeSelection(new TreePath[] { model.findElement("3.2"), model.findElement("3.2.1"), model.findElement("2") })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| fViewer.setSelection(new TreeSelection(model.findElement("3.2.3"))); //$NON-NLS-1$ |
| |
| // Turn off the auto-expand now since we want to text the auto-expand logic |
| fViewer.setAutoExpandLevel(-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(getInternalViewer(), 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. When view updates are complete |
| // the viewer |
| // Note: disable redundant updates because the reveal delta triggers one. |
| fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, false, false); |
| // TODO: add state updates somehow? |
| fViewer.setInput(model.getRootElement()); |
| waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage()); |
| |
| // Extract the restored state from viewer |
| ModelDelta restoredState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE); |
| fViewer.saveElementState(TreePath.EMPTY, restoredState, IModelDelta.EXPAND | IModelDelta.SELECT); |
| |
| if (!deltaMatches(originalState, restoredState)) { |
| fail("Expected:\n" + originalState.toString() + "\nGot:\n" + restoredState); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| |
| public void testSaveAndRestoreInputInstance() throws Exception { |
| //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); |
| TestModel model = alternatingSubsreesModel(6); |
| |
| // NOTE: WE ARE NOT EXPANDING ANY CHILDREN |
| |
| // Create the listener, only check the first level |
| fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, true, 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 some, but not all elements |
| expandAlternateElements(fListener, model, true); |
| |
| // Set a selection in view |
| fViewer.setSelection(new TreeSelection(new TreePath[] { model.findElement("5.1"), model.findElement("5.1.1"), model.findElement("6.1.1") })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| |
| // Extract the original state from viewer |
| ModelDelta originalState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE); |
| fViewer.saveElementState(TreePath.EMPTY, originalState, IModelDelta.EXPAND | IModelDelta.SELECT); |
| |
| // Do not reset to null, just reset input to the same object. |
| |
| // Set the viewer input back to the model. When view updates are complete |
| // the viewer |
| // Note: disable redundant updates because the reveal delta triggers one. |
| fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, false, false); |
| fViewer.setInput(model.getRootElement()); |
| waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage()); |
| |
| // Extract the restored state from viewer |
| ModelDelta restoredState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE); |
| fViewer.saveElementState(TreePath.EMPTY, restoredState, IModelDelta.EXPAND | IModelDelta.SELECT); |
| |
| if (!deltaMatches(originalState, restoredState)) { |
| fail("Expected:\n" + originalState.toString() + "\nGot:\n" + restoredState); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| |
| public void testSaveAndRestoreInputInstanceEquals() throws Exception { |
| //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); |
| TestModel model = alternatingSubsreesModel(6); |
| |
| // NOTE: WE ARE NOT EXPANDING ANY CHILDREN |
| |
| // Create the listener, only check the first level |
| fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, true, 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 some, but not all elements |
| expandAlternateElements(fListener, model, true); |
| |
| // Set a selection in view |
| fViewer.setSelection(new TreeSelection(new TreePath[] { model.findElement("5.1"), model.findElement("5.1.1"), model.findElement("6.1.1") })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| |
| // Extract the original state from viewer |
| ModelDelta originalState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE); |
| fViewer.saveElementState(TreePath.EMPTY, originalState, IModelDelta.EXPAND | IModelDelta.SELECT); |
| |
| // Create a copy of the input object and set it to model. |
| TestElement newRoot = new TestElement(model, model.getRootElement().getID(), model.getRootElement().getChildren()); |
| model.setRoot(newRoot); |
| |
| // Set the viewer input back to the model. When view updates are complete |
| // the viewer |
| // Note: disable redundant updates because the reveal delta triggers one. |
| fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, false, false); |
| |
| fViewer.setInput(model.getRootElement()); |
| waitWhile(t -> !fListener.isFinished(), createListenerErrorMessage()); |
| |
| // Extract the restored state from viewer |
| ModelDelta restoredState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE); |
| fViewer.saveElementState(TreePath.EMPTY, restoredState, IModelDelta.EXPAND | IModelDelta.SELECT); |
| |
| if (!deltaMatches(originalState, restoredState)) { |
| fail("Expected:\n" + originalState.toString() + "\nGot:\n" + restoredState); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| |
| |
| public void testSaveAndRestoreLarge() throws Exception { |
| //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); |
| TestModel model = alternatingSubsreesModel(100); |
| |
| // NOTE: WE ARE NOT EXPANDING ANY CHILDREN |
| |
| // Create the listener, only check the first level |
| fListener.reset(); |
| |
| // Set the input into the view and update the view. |
| fViewer.setInput(model.getRootElement()); |
| waitWhile(t -> !fListener.isFinished(CONTENT_SEQUENCE_COMPLETE), createListenerErrorMessage()); |
| |
| expandAlternateElements(fListener, model, false); |
| |
| // Set a selection in view |
| TreeSelection originalSelection = new TreeSelection(model.findElement("5.1.1")); //$NON-NLS-1$ |
| fViewer.setSelection(originalSelection); |
| assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) ); |
| |
| // 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(); |
| fListener.addStateUpdates(getInternalViewer(), 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. When view updates are complete |
| // the viewer |
| // Note: disable redundant updates because the reveal delta triggers one. |
| fListener.reset(); |
| fViewer.setInput(model.getRootElement()); |
| waitWhile(t -> !fListener.isFinished(CONTENT_SEQUENCE_COMPLETE), createListenerErrorMessage()); |
| |
| // Validate data (only select visible elements). |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("1.1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("2")) == false); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("4")) == false); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("5")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("5.1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("6")) == false); //$NON-NLS-1$ |
| assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) ); |
| } |
| |
| /** |
| * This test saves state of a large tree. Then the tree is modified |
| * to contain much fewer elements. The restore logic should discard the |
| * rest of the saved state delta once all the elements are visible. |
| */ |
| public void testSaveAndRestorePartialStateLarge() throws Exception { |
| //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); |
| TestModel model = alternatingSubsreesModel(100); |
| |
| // NOTE: WE ARE NOT EXPANDING ANY CHILDREN |
| |
| // Create the listener, only check the first level |
| fListener.reset(); |
| |
| // Set the input into the view and update the view. |
| fViewer.setInput(model.getRootElement()); |
| waitWhile(t -> !fListener.isFinished(CONTENT_SEQUENCE_COMPLETE), createListenerErrorMessage()); |
| |
| expandAlternateElements(fListener, model, false); |
| |
| // Set a selection in view |
| TreeSelection originalSelection = new TreeSelection(model.findElement("5.1.1")); //$NON-NLS-1$ |
| fViewer.setSelection(originalSelection); |
| assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) ); |
| |
| // 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(); |
| fListener.addStateUpdates(getInternalViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL); |
| |
| fViewer.setInput(null); |
| waitWhile(t -> !fListener.isFinished(STATE_SAVE_COMPLETE | STATE_UPDATES), createListenerErrorMessage()); |
| |
| |
| TestElement[] elements = model.getRootElement().getChildren(); |
| TestElement[] newElements = new TestElement[10]; |
| System.arraycopy(elements, 0, newElements, 0, newElements.length); |
| model.setElementChildren(TreePath.EMPTY, newElements); |
| |
| // Set the viewer input back to the model. When view updates are complete |
| // the viewer |
| // Note: disable redundant updates because the reveal delta triggers one. |
| fListener.reset(); |
| fViewer.setInput(model.getRootElement()); |
| |
| // MONITOR FOR THE STATE RESTORE TO COMPLETE |
| waitWhile(t -> !fListener.isFinished(CONTENT_SEQUENCE_COMPLETE | STATE_RESTORE_COMPLETE), createListenerErrorMessage()); |
| |
| // Validate data |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("1.1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("2")) == false); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3.1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("4")) == false); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("5")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("5.1")) == true); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("6")) == false); //$NON-NLS-1$ |
| assertTrue( areTreeSelectionsEqual(originalSelection, (ITreeSelection)fViewer.getSelection()) ); |
| } |
| |
| public void testPreserveCollapseAndSelectDeltaAfterSaveAndRestore() throws Exception { |
| //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); |
| TestModel model = TestModel.simpleMultiLevel(); |
| |
| // Expand all |
| fViewer.setAutoExpandLevel(-1); |
| |
| // Create the listener. |
| fListener.reset(TreePath.EMPTY, model.getRootElement(), -1, true, 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); |
| |
| fViewer.setSelection(new TreeSelection(model.findElement("3"))); //$NON-NLS-1$ |
| |
| // Turn off auto-expand |
| fViewer.setAutoExpandLevel(0); |
| |
| // Set the viewer input to null. This will trigger the view to save the viewer state. |
| fListener.reset(false, false); |
| fViewer.setInput(null); |
| waitWhile(t -> !fListener.isFinished(STATE_SAVE_COMPLETE), createListenerErrorMessage()); |
| |
| // Set the viewer input back to the model. When view updates are complete |
| // the viewer |
| // Note: disable redundant updates because the reveal delta triggers one. |
| fListener.reset(TreePath.EMPTY, model.getRootElement(), 1, false, false); |
| fViewer.setInput(model.getRootElement()); |
| TreePath path = model.findElement("2"); //$NON-NLS-1$ |
| fListener.addUpdates(null, path, (TestElement)path.getLastSegment(), 0, STATE_UPDATES); |
| path = model.findElement("3"); //$NON-NLS-1$ |
| fListener.addUpdates(null, path, (TestElement)path.getLastSegment(), 0, STATE_UPDATES); |
| |
| // Wait till we restore state of elements we want to collapse and select |
| // Bug 372619 - Need to wait until proxy installed delta is processed before |
| // posting the next delta. |
| waitWhile(t -> !fListener.isFinished(STATE_RESTORE_STARTED | STATE_UPDATES | CHILDREN_UPDATES | MODEL_CHANGED_COMPLETE), createListenerErrorMessage()); |
| |
| // Post first collapse delta |
| fListener.resetModelChanged(); |
| model.postDelta(model.makeElementDelta(model.findElement("2"), IModelDelta.COLLAPSE)); //$NON-NLS-1$ |
| waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE), createListenerErrorMessage()); |
| |
| // Post second collapse delta |
| fListener.resetModelChanged(); |
| model.postDelta(model.makeElementDelta(model.findElement("3"), IModelDelta.COLLAPSE)); //$NON-NLS-1$ |
| waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE), createListenerErrorMessage()); |
| |
| // Post select delta |
| model.postDelta(model.makeElementDelta(model.findElement("1"), IModelDelta.SELECT)); //$NON-NLS-1$ |
| waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE), createListenerErrorMessage()); |
| |
| // Wait for all the updates to complete (note: we're not resetting the listener). |
| waitWhile(t -> !fListener.isFinished(STATE_RESTORE_COMPLETE), createListenerErrorMessage()); |
| |
| // Check to make sure that the state restore didn't change the selection. |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("2")) == false); //$NON-NLS-1$ |
| assertTrue(getInternalViewer().getExpandedState(model.findElement("3")) == false); //$NON-NLS-1$ |
| assertEquals(new TreeSelection(model.findElement("1")), fViewer.getSelection()); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Test for bug 359859.<br> |
| * This test verifies that RESTORE state is handled after SAVE previous state was completed |
| */ |
| public void testSaveRestoreOrder() throws Exception { |
| //TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); |
| TestModel model = TestModel.simpleMultiLevel(); |
| model.setDelayUpdates(true); |
| |
| // 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); |
| |
| // a new similar model |
| TestModel copyModel = TestModel.simpleMultiLevel(); |
| |
| // Trigger save - restore sequence. |
| fListener.reset(); |
| fListener.expectRestoreAfterSaveComplete(); |
| fViewer.setInput(copyModel.getRootElement()); |
| waitWhile(t -> !fListener.isFinished(STATE_RESTORE_STARTED), createListenerErrorMessage()); |
| assertTrue("RESTORE started before SAVE to complete", fListener.isFinished(STATE_SAVE_COMPLETE)); //$NON-NLS-1$ |
| } |
| |
| /** |
| * This test tries to restore a viewer state while input == null. |
| * See: Bug 380288 - NPE switching to the Breakpoints View |
| */ |
| public void testUpdateWithNullInput() throws Exception { |
| TestModel model = TestModel.simpleMultiLevel(); |
| 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); |
| |
| ModelDelta expandedState = new ModelDelta(model.getRootElement(), IModelDelta.NO_CHANGE); |
| fViewer.saveElementState(TreePath.EMPTY, expandedState, IModelDelta.EXPAND); |
| |
| // Refresh the viewer so that updates are generated. |
| fListener.reset(); |
| fListener.addChildreCountUpdate(TreePath.EMPTY); |
| model.postDelta(new ModelDelta(model.getRootElement(), IModelDelta.CONTENT)); |
| |
| // Wait for the delta to be processed. |
| waitWhile(t -> !fListener.isFinished(MODEL_CHANGED_COMPLETE | CHILD_COUNT_UPDATES), createListenerErrorMessage()); |
| |
| fViewer.setInput(null); |
| fViewer.updateViewer(expandedState); |
| |
| waitWhile(t -> !fListener.isFinished(CONTENT_COMPLETE | VIEWER_UPDATES_RUNNING), createListenerErrorMessage()); |
| |
| } |
| } |