diff options
author | Pawel Piech | 2010-10-08 15:49:41 +0000 |
---|---|---|
committer | Pawel Piech | 2010-10-08 15:49:41 +0000 |
commit | c430a195e2308070424637613332c6e29b4887d4 (patch) | |
tree | c6cee64b50216e46c86e85c98293de692f357db5 /org.eclipse.debug.tests | |
parent | 96165aa6c4ba99aef72760b19363a07abe3f26d9 (diff) | |
download | eclipse.platform.debug-c430a195e2308070424637613332c6e29b4887d4.tar.gz eclipse.platform.debug-c430a195e2308070424637613332c6e29b4887d4.tar.xz eclipse.platform.debug-c430a195e2308070424637613332c6e29b4887d4.zip |
Bug 326917 - [Fiexible Hierarchy] View state is not saved correctly when top view element is deep in a tree hierarchy.
Diffstat (limited to 'org.eclipse.debug.tests')
4 files changed, 455 insertions, 31 deletions
diff --git a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/JFaceViewerTopIndexTests.java b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/JFaceViewerTopIndexTests.java index bb7464806..e3a1eef41 100644 --- a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/JFaceViewerTopIndexTests.java +++ b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/JFaceViewerTopIndexTests.java @@ -125,13 +125,18 @@ public class JFaceViewerTopIndexTests extends TestCase implements ITestModelUpda Assert.assertNotNull("Top item should not be null!", originalTopPath); // Bug 116105: On a Mac the reveal call is not reliable. Use the viewer returned path instead. // Assert.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(), TreePath.EMPTY, model.getRootElement()); + fListener.addStateUpdates(getCTargetViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL); fViewer.setInput(null); - while (!fListener.isFinished(STATE_SAVE_COMPLETE)) if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + while (!fListener.isFinished(STATE_SAVE_COMPLETE | STATE_UPDATES)) + if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); // Set the viewer input back to the model to trigger RESTORE operation. fListener.reset(false, false); @@ -212,13 +217,17 @@ public class JFaceViewerTopIndexTests extends TestCase implements ITestModelUpda getCTargetViewer().reveal(TreePath.EMPTY, 1); while(fDisplay.readAndDispatch()) {} final TreePath originalTopPath = getCTargetViewer().getTopElementPath(); + Assert.assertNotNull("Top item should not be null!", originalTopPath); // Bug 116105: On a Mac the reveal call is not reliable. Use the viewer returned path instead. - // Assert.assertNotNull("Top item should not be null!", originalTopPath); - Assert.assertEquals(elements[1], originalTopPath.getLastSegment()); - + //Assert.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(), TreePath.EMPTY, model.getRootElement()); + fListener.addStateUpdates(getCTargetViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL); fViewer.setInput(null); while (!fListener.isFinished(STATE_SAVE_COMPLETE)) if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); @@ -292,13 +301,18 @@ public class JFaceViewerTopIndexTests extends TestCase implements ITestModelUpda while(fDisplay.readAndDispatch()) {} final TreePath originalTopPath = getCTargetViewer().getTopElementPath(); Assert.assertNotNull("Top item should not be null!", originalTopPath); - + + // 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(), TreePath.EMPTY, model.getRootElement()); + fListener.addStateUpdates(getCTargetViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL); fViewer.setInput(null); - while (!fListener.isFinished(STATE_SAVE_COMPLETE)) if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + while (!fListener.isFinished(STATE_SAVE_COMPLETE | STATE_UPDATES)) + if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); // Set the viewer input back to the model. fListener.reset(false, false); @@ -311,4 +325,182 @@ public class JFaceViewerTopIndexTests extends TestCase implements ITestModelUpda Assert.assertNotNull("Top item should not be null!", topPath); Assert.assertEquals(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() { + TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); + 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()); + while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + 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); + while(fDisplay.readAndDispatch()) {} + + // Trigger save of state. + fListener.reset(); + fViewer.setInput(null); + while (!fListener.isFinished(STATE_SAVE_COMPLETE)) fDisplay.sleep (); + + // 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"); + fListener.addUpdates(fViewer, elementPath, model.getElement(elementPath), 1, STATE_UPDATES); + fViewer.setInput(model.getRootElement()); + while (!fListener.isFinished(MODEL_CHANGED_COMPLETE | STATE_UPDATES)) + if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + + // Update the viewer with new selection delta to something new in the view + ModelDelta revealDelta = model.makeElementDelta(model.findElement("2.1"), IModelDelta.REVEAL); + + // Wait for the second model delta to process + fListener.reset(); + model.postDelta(revealDelta); + while (!fListener.isFinished(MODEL_CHANGED_COMPLETE | CONTENT_UPDATES_COMPLETE)) + if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + + // Clear view then reset it again. + fListener.reset(); + fViewer.setInput(null); + while (!fListener.isFinished(STATE_SAVE_COMPLETE)) fDisplay.sleep (); + + autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); + fViewer.setInput(model.getRootElement()); + while (!fListener.isFinished(STATE_RESTORE_COMPLETE)) + if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + 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() { + TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); + 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()); + while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + 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); + while(fDisplay.readAndDispatch()) {} + + // Trigger save of state. + fListener.reset(); + fViewer.setInput(null); + while (!fListener.isFinished(STATE_SAVE_COMPLETE)) fDisplay.sleep (); + + // 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(); + final TreePath elementPath = model.findElement("3"); + fListener.addUpdates(fViewer, elementPath, model.getElement(elementPath), 0, STATE_UPDATES); + fViewer.setInput(model.getRootElement()); + while (!fListener.isFinished(STATE_UPDATES)) + if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + + // Update the viewer with new selection delta to something new in the view + TreePath pathToBeRevealed = model.findElement("2.1"); + ModelDelta revealDelta = model.makeElementDelta(pathToBeRevealed, IModelDelta.REVEAL); + + // Wait for the second model delta to process + fListener.reset(); + model.postDelta(revealDelta); + while (!fListener.isFinished(MODEL_CHANGED_COMPLETE | CONTENT_UPDATES_COMPLETE)) + if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + + while (fDisplay.readAndDispatch ()) {} + // check if REVEAL was restored OK + TreePath topPath = getCTargetViewer().getTopElementPath(); + Assert.assertNotNull("Top item should not be null!", topPath); + Assert.assertEquals(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() { + TreeModelViewerAutopopulateAgent autopopulateAgent = new TreeModelViewerAutopopulateAgent(fViewer); + + 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()); + + while (!fListener.isFinished()) if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + 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); + while(fDisplay.readAndDispatch()) {} + final TreePath originalTopPath = getCTargetViewer().getTopElementPath(); + Assert.assertNotNull("Top item should not be null!", originalTopPath); + + // 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); + while (!fListener.isFinished(STATE_SAVE_COMPLETE)) if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + + // 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()); + while (!fListener.isFinished(STATE_UPDATES | CONTENT_UPDATES_COMPLETE)) if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + + while (fDisplay.readAndDispatch ()) {} + // check if REVEAL was restored OK + final TreePath topPath = getCTargetViewer().getTopElementPath(); + Assert.assertNotNull("Top item should not be null!", topPath); + Assert.assertEquals(originalTopPath, topPath); + + } + } diff --git a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/StateTests.java b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/StateTests.java index 62cd5b9e3..3699b083b 100644 --- a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/StateTests.java +++ b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/StateTests.java @@ -744,10 +744,11 @@ abstract public class StateTests extends TestCase implements ITestModelUpdatesLi 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(), TreePath.EMPTY, model.getRootElement()); + fListener.reset(false, false); + fListener.addStateUpdates(getCTargetViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL); fViewer.setInput(null); - while (!fListener.isFinished(STATE_SAVE_COMPLETE)) if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + while (!fListener.isFinished(STATE_SAVE_COMPLETE | STATE_UPDATES)) + if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); // Set the viewer input back to the model. When view updates are complete // the viewer @@ -794,10 +795,11 @@ abstract public class StateTests extends TestCase implements ITestModelUpdatesLi // Set the viewer input to null. This will trigger the view to save the viewer state. fListener.reset(true, false); - fListener.addStateUpdates(getCTargetViewer(), TreePath.EMPTY, model.getRootElement()); + fListener.addStateUpdates(getCTargetViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL); fViewer.setInput(null); - while (!fListener.isFinished(STATE_SAVE_COMPLETE)) if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + while (!fListener.isFinished(STATE_SAVE_COMPLETE | STATE_UPDATES)) + if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); // Set the viewer input back to the model. When view updates are complete // the viewer @@ -837,12 +839,17 @@ abstract public class StateTests extends TestCase implements ITestModelUpdatesLi fViewer.setSelection(originalSelection); Assert.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(getCTargetViewer(), TreePath.EMPTY, model.getRootElement()); + fListener.addStateUpdates(getCTargetViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL); fViewer.setInput(null); - while (!fListener.isFinished(STATE_SAVE_COMPLETE)) if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + while (!fListener.isFinished(STATE_SAVE_COMPLETE | STATE_UPDATES)) + if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); // Set the viewer input back to the model. When view updates are complete // the viewer @@ -889,12 +896,17 @@ abstract public class StateTests extends TestCase implements ITestModelUpdatesLi fViewer.setSelection(originalSelection); Assert.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(getCTargetViewer(), TreePath.EMPTY, model.getRootElement()); + fListener.addStateUpdates(getCTargetViewer(), originalState, IModelDelta.EXPAND | IModelDelta.SELECT | IModelDelta.REVEAL); fViewer.setInput(null); - while (!fListener.isFinished(STATE_SAVE_COMPLETE)) if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); + while (!fListener.isFinished(STATE_SAVE_COMPLETE | STATE_UPDATES)) + if (!fDisplay.readAndDispatch ()) fDisplay.sleep (); TestElement[] elements = model.getRootElement().getChildren(); diff --git a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModel.java b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModel.java index 8a3287849..609ce9838 100644 --- a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModel.java +++ b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModel.java @@ -624,7 +624,7 @@ public class TestModel implements IElementContentProvider, IElementLabelProvider }) ); return model; } - + public static TestModel compositeMultiLevel() { TestModel m2 = new TestModel(); m2.setRoot( new TestElement(m2, "m2.root", new TestElement[] { @@ -670,5 +670,145 @@ public class TestModel implements IElementContentProvider, IElementLabelProvider return m1; } - + public static TestModel simpleDeepMultiLevel() { + TestModel model = new TestModel(); + model.setRoot( new TestElement(model, "root", new TestElement[] { + new TestElement(model, "1", new TestElement[0]), + new TestElement(model, "2", true, false, new TestElement[] { + new TestElement(model, "2.1", true, true, new TestElement[0]), + new TestElement(model, "2.2", false, true, new TestElement[0]), + new TestElement(model, "2.3", true, false, new TestElement[0]), + }), + new TestElement(model, "3", new TestElement[] { + new TestElement(model, "3.1", new TestElement[] { + new TestElement(model, "3.1.1", new TestElement[0]), + new TestElement(model, "3.1.2", new TestElement[0]), + new TestElement(model, "3.1.3", new TestElement[0]), + }), + new TestElement(model, "3.2", new TestElement[] { + new TestElement(model, "3.2.1", new TestElement[0]), + new TestElement(model, "3.2.2", new TestElement[0]), + new TestElement(model, "3.2.3", new TestElement[0]), + }), + new TestElement(model, "3.3", new TestElement[] { + new TestElement(model, "3.3.1", new TestElement[0]), + new TestElement(model, "3.3.2", new TestElement[0]), + new TestElement(model, "3.3.3", new TestElement[0]), + }), + new TestElement(model, "3.4", new TestElement[] { + new TestElement(model, "3.4.1", new TestElement[0]), + new TestElement(model, "3.4.2", new TestElement[0]), + new TestElement(model, "3.4.3", new TestElement[0]), + }), + new TestElement(model, "3.5", new TestElement[] { + new TestElement(model, "3.5.1", new TestElement[0]), + new TestElement(model, "3.5.2", new TestElement[0]), + new TestElement(model, "3.5.3", new TestElement[0]), + }), + new TestElement(model, "3.6", new TestElement[] { + new TestElement(model, "3.6.1", new TestElement[0]), + new TestElement(model, "3.6.2", new TestElement[0]), + new TestElement(model, "3.6.3", new TestElement[] { + new TestElement(model, "3.6.3.1", new TestElement[0]), + new TestElement(model, "3.6.3.2", new TestElement[0]), + new TestElement(model, "3.6.3.4", new TestElement[0]), + new TestElement(model, "3.6.3.5", new TestElement[0]), + new TestElement(model, "3.6.3.6", new TestElement[0]), + new TestElement(model, "3.6.3.7", new TestElement[0]), + new TestElement(model, "3.6.3.8", new TestElement[0]), + new TestElement(model, "3.6.3.9", new TestElement[0]), + new TestElement(model, "3.6.3.10", new TestElement[0]), + new TestElement(model, "3.6.3.11", new TestElement[0]), + new TestElement(model, "3.6.3.12", new TestElement[0]), + new TestElement(model, "3.6.3.13", new TestElement[0]), + new TestElement(model, "3.6.3.14", new TestElement[0]), + new TestElement(model, "3.6.3.15", new TestElement[0]), + new TestElement(model, "3.6.3.16", new TestElement[] { + new TestElement(model, "3.6.3.16.1", new TestElement[0]), + new TestElement(model, "3.6.3.16.2", new TestElement[0]), + new TestElement(model, "3.6.3.16.4", new TestElement[0]), + new TestElement(model, "3.6.3.16.5", new TestElement[0]), + new TestElement(model, "3.6.3.16.6", new TestElement[0]), + new TestElement(model, "3.6.3.16.7", new TestElement[0]), + new TestElement(model, "3.6.3.16.8", new TestElement[0]), + new TestElement(model, "3.6.3.16.9", new TestElement[0]), + new TestElement(model, "3.6.3.16.10", new TestElement[0]), + new TestElement(model, "3.6.3.16.11", new TestElement[0]), + new TestElement(model, "3.6.3.16.12", new TestElement[0]), + new TestElement(model, "3.6.3.16.13", new TestElement[0]), + new TestElement(model, "3.6.3.16.14", new TestElement[0]), + new TestElement(model, "3.6.3.16.15", new TestElement[0]), + new TestElement(model, "3.6.3.16.16", new TestElement[] { + new TestElement(model, "3.6.3.16.16.1", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.2", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.4", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.5", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.6", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.7", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.8", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.9", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.10", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.11", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.12", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.13", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.14", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.15", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16", new TestElement[] { + new TestElement(model, "3.6.3.16.16.16.1", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.2", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.4", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.5", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.6", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.7", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.8", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.9", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.10", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.11", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.12", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.13", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.14", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.15", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16", new TestElement[] { + new TestElement(model, "3.6.3.16.16.16.16.1", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.2", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.4", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.5", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.6", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.7", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.8", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.9", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.10", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.11", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.12", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.13", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.14", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.15", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.16", new TestElement[] { + new TestElement(model, "3.6.3.16.16.16.16.16.1", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.16.2", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.16.4", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.16.5", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.16.6", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.16.7", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.16.8", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.16.9", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.16.10", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.16.11", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.16.12", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.16.13", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.16.14", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.16.15", new TestElement[0]), + new TestElement(model, "3.6.3.16.16.16.16.16.16", new TestElement[0]), + }), + }), + }), + }), + }), + }), + }), + }) + }) ); + return model; + } + } diff --git a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModelUpdatesListener.java b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModelUpdatesListener.java index 4a0063ce6..0764542ca 100644 --- a/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModelUpdatesListener.java +++ b/org.eclipse.debug.tests/src/org/eclipe/debug/tests/viewer/model/TestModelUpdatesListener.java @@ -11,6 +11,7 @@ *******************************************************************************/ package org.eclipe.debug.tests.viewer.model; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -21,6 +22,11 @@ import java.util.TreeSet; import junit.framework.Assert; import org.eclipe.debug.tests.viewer.model.TestModel.TestElement; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.jobs.IJobChangeEvent; +import org.eclipse.core.runtime.jobs.IJobChangeListener; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.debug.internal.ui.viewers.model.ElementCompareRequest; import org.eclipse.debug.internal.ui.viewers.model.ILabelUpdateListener; import org.eclipse.debug.internal.ui.viewers.model.ITreeModelContentProviderTarget; import org.eclipse.debug.internal.ui.viewers.model.ITreeModelViewer; @@ -38,10 +44,12 @@ import org.eclipse.jface.viewers.TreePath; public class TestModelUpdatesListener implements IViewerUpdateListener, ILabelUpdateListener, IModelChangedListener, ITestModelUpdatesListenerConstants, - IStateUpdateListener + IStateUpdateListener, IJobChangeListener { private final ITreeModelViewer fViewer; + private IStatus fJobError; + private boolean fFailOnRedundantUpdates; private Set fRedundantUpdates = new HashSet(); @@ -87,6 +95,7 @@ public class TestModelUpdatesListener public TestModelUpdatesListener(ITreeModelViewer viewer) { fViewer = viewer; + Job.getJobManager().addJobChangeListener(this); fViewer.addLabelUpdateListener(this); fViewer.addModelChangedListener(this); fViewer.addStateUpdateListener(this); @@ -94,13 +103,25 @@ public class TestModelUpdatesListener } public void dispose() { + Job.getJobManager().removeJobChangeListener(this); fViewer.removeLabelUpdateListener(this); fViewer.removeModelChangedListener(this); fViewer.removeStateUpdateListener(this); fViewer.removeViewerUpdateListener(this); } - + public void aboutToRun(IJobChangeEvent event) {} + public void awake(IJobChangeEvent event) {} + public void running(IJobChangeEvent event) {} + public void scheduled(IJobChangeEvent event) {} + public void sleeping(IJobChangeEvent event) {} + public void done(IJobChangeEvent event) { + IStatus result = event.getJob().getResult(); + if (result != null && result.getSeverity() == IStatus.ERROR) { + fJobError = result; + } + } + public void setFailOnRedundantUpdates(boolean failOnRedundantUpdates) { fFailOnRedundantUpdates = failOnRedundantUpdates; } @@ -138,6 +159,7 @@ public class TestModelUpdatesListener } public void reset() { + fJobError = null; fRedundantUpdates.clear(); fMultipleLabelUpdateSequencesObserved = false; fMultipleModelUpdateSequencesObserved = false; @@ -158,6 +180,7 @@ public class TestModelUpdatesListener fViewerUpdatesComplete = false; fLabelUpdatesStarted = false; fLabelUpdatesComplete = false; + fStateUpdates.clear(); fStateSaveStarted = false; fStateSaveComplete = false; fStateRestoreStarted = false; @@ -221,11 +244,40 @@ public class TestModelUpdatesListener addUpdates(viewer, path, element, -1, STATE_UPDATES); } + public void addStateUpdates(ITreeModelContentProviderTarget viewer, IModelDelta pendingDelta, int deltaFlags) { + TreePath treePath = getViewerTreePath(pendingDelta); + if ( !TreePath.EMPTY.equals(treePath) && (pendingDelta.getFlags() & deltaFlags) != 0 ) { + addUpdates(viewer, treePath, (TestElement)treePath.getLastSegment(), 0, STATE_UPDATES); + } + IModelDelta[] childDeltas = pendingDelta.getChildDeltas(); + for (int i = 0; i < childDeltas.length; i++) { + addStateUpdates(viewer, childDeltas[i], deltaFlags); + } + } + + /** + * Returns a tree path for the node, *not* including the root element. + * + * @param node + * model delta + * @return corresponding tree path + */ + private TreePath getViewerTreePath(IModelDelta node) { + ArrayList list = new ArrayList(); + IModelDelta parentDelta = node.getParentDelta(); + while (parentDelta != null) { + list.add(0, node.getElement()); + node = parentDelta; + parentDelta = node.getParentDelta(); + } + return new TreePath(list.toArray()); + } + public void addUpdates(TreePath path, TestElement element, int levels, int flags) { addUpdates(null, path, element, levels, flags); } - public void addUpdates(ITreeModelContentProviderTarget viewer, TreePath path, TestElement element, int levels, int flags) { + public void addUpdates(ITreeModelContentProviderTarget viewer, TreePath path, TestElement element, int levels, int flags) { if (!path.equals(TreePath.EMPTY)) { if ((flags & LABEL_UPDATES) != 0) { fLabelUpdates.add(path); @@ -233,10 +285,14 @@ public class TestModelUpdatesListener if ((flags & HAS_CHILDREN_UPDATES) != 0) { fHasChildrenUpdatesScheduled.add(path); } + + if ((flags & STATE_UPDATES) != 0 && viewer != null) { + fStateUpdates.add(path); + } } if (levels-- != 0) { - TestElement[] children = element.getChildren(); + TestElement[] children = element.getChildren(); if (children.length > 0 && (viewer == null || path.getSegmentCount() == 0 || viewer.getExpandedState(path))) { if ((flags & CHILD_COUNT_UPDATES) != 0) { fChildCountUpdatesScheduled.add(path); @@ -249,10 +305,6 @@ public class TestModelUpdatesListener fChildrenUpdatesScheduled.put(path, childrenIndexes); } - if ((flags & STATE_UPDATES) != 0 && viewer != null) { - fStateUpdates.add(path); - } - for (int i = 0; i < children.length; i++) { addUpdates(viewer, path.createChildPath(children[i]), children[i], levels, flags); } @@ -277,7 +329,7 @@ public class TestModelUpdatesListener } public boolean isTimedOut() { - return fTimeoutInterval > 0 && fTimeoutTime < System.currentTimeMillis(); + return false && fTimeoutInterval > 0 && fTimeoutTime < System.currentTimeMillis(); } public boolean isFinished(int flags) { @@ -285,6 +337,10 @@ public class TestModelUpdatesListener throw new RuntimeException("Timed Out: " + toString(flags)); } + if (fJobError != null) { + throw new RuntimeException("Job Error: " + fJobError); + } + if (fFailOnRedundantUpdates && !fRedundantUpdates.isEmpty()) { Assert.fail("Redundant Updates: " + fRedundantUpdates.toString()); } @@ -343,6 +399,11 @@ public class TestModelUpdatesListener if ( (flags & STATE_RESTORE_STARTED) != 0) { if (!fStateRestoreStarted) return false; } + if ( (flags & STATE_UPDATES) != 0) { + if (!fStateUpdates.isEmpty()) { + return false; + } + } if ( (flags & MODEL_PROXIES_INSTALLED) != 0) { if (fProxyModels.size() != 0) return false; } @@ -484,6 +545,9 @@ public class TestModelUpdatesListener } public void stateUpdateComplete(Object input, IViewerUpdate update) { + if ( !(update instanceof ElementCompareRequest) || ((ElementCompareRequest)update).isEqual()) { + fStateUpdates.remove(update.getElementPath()); + } } public void stateUpdateStarted(Object input, IViewerUpdate update) { @@ -492,6 +556,18 @@ public class TestModelUpdatesListener private String toString(int flags) { StringBuffer buf = new StringBuffer("Viewer Update Listener"); + if (fJobError != null) { + buf.append("\n\t"); + buf.append("fJobError = " + fJobError); + if (fJobError.getException() != null) { + StackTraceElement[] trace = fJobError.getException().getStackTrace(); + for (int i = 0; i < trace.length; i++) { + buf.append("\n\t\t"); + buf.append(trace[i]); + } + } + } + if (fFailOnRedundantUpdates) { buf.append("\n\t"); buf.append("fRedundantUpdates = " + fRedundantUpdates); @@ -588,6 +664,10 @@ public class TestModelUpdatesListener buf.append("\n\t"); buf.append("fProxyModels = " + fProxyModels); } + if ( (flags & STATE_UPDATES) != 0) { + buf.append("\n\t"); + buf.append("fStateUpdates = " + toString(fStateUpdates)); + } if (fTimeoutInterval > 0) { buf.append("\n\t"); buf.append("fTimeoutInterval = " + fTimeoutInterval); @@ -636,7 +716,7 @@ public class TestModelUpdatesListener } public String toString() { - return toString(ALL_UPDATES_COMPLETE | MODEL_CHANGED_COMPLETE | STATE_RESTORE_COMPLETE | VIEWER_UPDATES_STARTED | LABEL_UPDATES_STARTED); + return toString(ALL_UPDATES_COMPLETE | MODEL_CHANGED_COMPLETE | STATE_RESTORE_COMPLETE | VIEWER_UPDATES_STARTED | LABEL_UPDATES_STARTED | STATE_UPDATES); } } |