track running test: cleanup user selection (allow to track further) when newly starte...
[idea/community.git] / plugins / junit / src / com / intellij / execution / junit2 / ui / actions / RunningTestTracker.java
1 /*
2  * Copyright 2000-2009 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.intellij.execution.junit2.ui.actions;
18
19 import com.intellij.execution.junit2.TestProxy;
20 import com.intellij.execution.junit2.events.StateChangedEvent;
21 import com.intellij.execution.junit2.events.TestEvent;
22 import com.intellij.execution.junit2.ui.model.JUnitAdapter;
23 import com.intellij.execution.junit2.ui.model.JUnitRunningModel;
24 import com.intellij.execution.junit2.ui.properties.JUnitConsoleProperties;
25 import com.intellij.execution.testframework.AbstractTestProxy;
26 import com.intellij.execution.testframework.TestFrameworkPropertyListener;
27 import com.intellij.execution.testframework.TrackRunningTestUtil;
28 import com.intellij.execution.testframework.actions.TestFrameworkActions;
29 import com.intellij.openapi.diagnostic.Logger;
30 import com.intellij.openapi.util.Pass;
31 import com.intellij.rt.execution.junit.states.PoolOfTestStates;
32
33 import javax.swing.*;
34
35 class RunningTestTracker extends JUnitAdapter implements TestFrameworkPropertyListener<Boolean> {
36   private static final Logger LOG = Logger.getInstance("#com.intellij.execution.junit2.ui.actions.TrackRunningTestAction");
37
38   private final JUnitRunningModel myModel;
39   private TrackingPolicy myTrackingPolicy;
40   private TestProxy myLastRan = null;
41   private TestProxy myLastSelected = null;
42
43   private RunningTestTracker(final JUnitRunningModel model) {
44     myModel = model;
45     final JTree tree = myModel.getTree();
46     TrackRunningTestUtil.installStopListeners(tree, myModel, new Pass<AbstractTestProxy>() {
47       @Override
48       public void pass(AbstractTestProxy testProxy) {
49         myLastSelected = (TestProxy)testProxy;
50       }
51     });
52     choosePolicy();
53   }
54
55   public void onChanged(final Boolean value) {
56     choosePolicy();
57     myTrackingPolicy.apply();
58   }
59
60   public void onTestChanged(final TestEvent event) {
61     if (event instanceof StateChangedEvent) {
62       final TestProxy proxy = event.getSource();
63       final boolean isRunning = isRunningState(proxy);
64       if (isRunning) {
65         if (proxy.isLeaf()) {
66           myLastRan = proxy;
67         }
68         if (myLastSelected == proxy) {
69           myLastSelected = null;
70         }
71       }
72       else if (proxy == myLastRan) {
73         myLastRan = null;
74       }
75       myTrackingPolicy.applyTo(proxy);
76     }
77   }
78
79   public static void install(final JUnitRunningModel model) {
80     final RunningTestTracker testTracker = new RunningTestTracker(model);
81     model.addListener(testTracker);
82     TestFrameworkActions.addPropertyListener(JUnitConsoleProperties.TRACK_RUNNING_TEST, testTracker, model, false);
83   }
84
85   private static boolean isRunningState(final TestProxy test) {
86     return test.getState().getMagnitude() == PoolOfTestStates.RUNNING_INDEX;
87   }
88
89   private abstract static class TrackingPolicy {
90     protected abstract void applyTo(TestProxy test);
91     protected abstract void apply();
92   }
93
94   private void choosePolicy() {
95     final boolean shouldTrack = JUnitConsoleProperties.TRACK_RUNNING_TEST.value(myModel.getProperties());
96     myTrackingPolicy = shouldTrack ? TRACK_RUNNING : DONT_TRACK;
97   }
98
99   private static final TrackingPolicy DONT_TRACK = new TrackingPolicy() {
100     protected void applyTo(final TestProxy test) {}
101     protected void apply() {}
102   };
103
104   private final TrackingPolicy TRACK_RUNNING = new TrackingPolicy() {
105     protected void applyTo(final TestProxy test) {
106       LOG.assertTrue(myModel != null);
107       selectLastTest();
108       if (!test.isLeaf() && test.getState().isPassed())
109         myModel.collapse(test);
110     }
111
112     protected void apply() {
113       LOG.assertTrue(myModel != null);
114       selectLastTest();
115     }
116
117     private void selectLastTest() {
118       if (myLastRan != null && isRunningState(myLastRan)) {
119         if (myLastSelected == null) {
120           myModel.selectTest(myLastRan);
121         }
122         else {
123           myModel.expandTest(myLastRan);
124         }
125       }
126     }
127   };
128 }