| /* |
| * Copyright 2000-2009 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.intellij.execution.junit2.states; |
| |
| import com.intellij.execution.junit2.TestProxy; |
| import com.intellij.execution.junit2.TestProxyListener; |
| import com.intellij.execution.testframework.AbstractTestProxy; |
| import com.intellij.execution.testframework.Printer; |
| import com.intellij.rt.execution.junit.states.PoolOfTestStates; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| |
| public class SuiteState extends TestState { |
| private final TestProxy myTest; |
| private int myMaxMagnitude = PoolOfTestStates.NOT_RUN_INDEX; |
| private boolean myHasRunning; |
| private final StateCache myCache = new StateCache(); |
| |
| public SuiteState(final TestProxy test) { |
| myTest = test; |
| myTest.addListener(new TestProxyListener() { |
| public void onChildAdded(final AbstractTestProxy testProxy, final AbstractTestProxy newChild) { |
| if (newChild.getParent() == myTest) { |
| myCache.invalidate(); |
| } |
| } |
| |
| public void onChanged(final AbstractTestProxy test) { |
| if (test == myTest) myCache.invalidate(); |
| } |
| |
| public void onStatisticsChanged(final AbstractTestProxy test) { |
| if (test == myTest) myCache.invalidate(); |
| } |
| }); |
| } |
| |
| public int getMagnitude() { |
| return myHasRunning ? PoolOfTestStates.RUNNING_INDEX : myMaxMagnitude; |
| } |
| |
| public void update() { |
| myCache.invalidate(); |
| } |
| |
| public void printOn(final Printer printer) { |
| } |
| |
| |
| public boolean isFinal() { |
| return true; |
| } |
| |
| public boolean isDefect() { |
| return getMagnitude() >= PoolOfTestStates.FAILED_INDEX; |
| } |
| |
| public boolean isInProgress() { |
| return myCache.get(IS_IN_PROGRESS).booleanValue(); |
| } |
| |
| public Statistics getStatisticsFor(final TestProxy test) { |
| return myCache.get(GET_STATISTICS); |
| } |
| |
| public List<TestProxy> getAllTestsOf(final TestProxy test) { |
| return myCache.get(ALL_TESTS); |
| } |
| |
| public void changeStateAfterAddingChildTo(final TestProxy test, final TestProxy child) { |
| if (child.getState().getMagnitude() <= getMagnitude()) { |
| test.onStatisticsChanged(); |
| return; |
| } |
| test.onChanged(test); |
| } |
| |
| public void setRunning(boolean running) { |
| myHasRunning = running; |
| } |
| |
| public boolean isRunning() { |
| return myHasRunning; |
| } |
| |
| public void updateMagnitude(int magnitude) { |
| if (myMaxMagnitude == PoolOfTestStates.NOT_RUN_INDEX) { |
| myMaxMagnitude = magnitude; |
| } else if (myMaxMagnitude < magnitude) { |
| myMaxMagnitude = magnitude; |
| } |
| } |
| |
| private static final CachedAcpect<List<TestProxy>> ALL_TESTS = new CachedAcpect<List<TestProxy>>() { |
| public List<TestProxy> calculate(final SuiteState state) { |
| final ArrayList<TestProxy> allTests = new ArrayList<TestProxy>(); |
| state.myTest.collectAllTestsTo(allTests); |
| return allTests; |
| } |
| }; |
| |
| private static final CachedAcpect<Statistics> GET_STATISTICS = new CachedAcpect<Statistics>() { |
| public Statistics calculate(final SuiteState state) { |
| final CumulativeStatistics result = new CumulativeStatistics(); |
| for (final TestProxy testCase : state.myTest.getChildren()) { |
| result.add(testCase.getStatistics()); |
| } |
| return result; |
| } |
| }; |
| |
| private static final CachedAcpect<Boolean> IS_IN_PROGRESS = new CachedAcpect<Boolean>() { |
| public Boolean calculate(final SuiteState state) { |
| final List<TestProxy> children = state.myTest.getChildren(); |
| for (int i = children.size() - 1; i >= 0; i--) { |
| if (children.get(i).isInProgress()) return Boolean.TRUE; |
| } |
| return Boolean.FALSE; |
| } |
| }; |
| |
| |
| private static abstract class CachedAcpect<T> { |
| private static int ourNextInstanceIndex = 0; |
| private final int myId; |
| |
| protected CachedAcpect() { |
| synchronized (CachedAcpect.class) { |
| myId = ourNextInstanceIndex; |
| ourNextInstanceIndex++; |
| } |
| } |
| |
| public abstract T calculate(SuiteState state); |
| |
| public int getId() { |
| return myId; |
| } |
| } |
| |
| |
| private class StateCache { |
| private final Object[] myValues = new Object[3]; |
| |
| public <T> T get(final CachedAcpect<T> aspect) { |
| final int id = aspect.getId(); |
| T value = (T)myValues[id]; |
| if (value == null) { |
| value = aspect.calculate(SuiteState.this); |
| myValues[id] = value; |
| } |
| return value; |
| } |
| |
| public void invalidate() { |
| Arrays.fill(myValues, null); |
| } |
| } |
| } |