package jetbrains.mps.baseLanguage.unitTest.execution.client; /*Generated by MPS */ import org.apache.log4j.Logger; import org.apache.log4j.LogManager; import java.util.List; import jetbrains.mps.internal.collections.runtime.ListSequence; import java.util.ArrayList; import java.util.Map; import jetbrains.mps.internal.collections.runtime.MapSequence; import java.util.LinkedHashMap; import java.util.Set; import jetbrains.mps.internal.collections.runtime.SetSequence; import java.util.HashSet; import com.intellij.openapi.util.Key; import jetbrains.mps.project.Project; import jetbrains.mps.internal.collections.runtime.IWhereFilter; import jetbrains.mps.internal.collections.runtime.Sequence; import jetbrains.mps.baseLanguage.unitTest.execution.TestEvent; import jetbrains.mps.internal.collections.runtime.IVisitor; import org.apache.log4j.Level; import org.jetbrains.annotations.NotNull; import java.util.LinkedList; public class TestRunState { private static final Logger LOG = LogManager.getLogger(TestRunState.class); private static final Object lock = new Object(); private final List<String> myTestMethods = ListSequence.fromList(new ArrayList<String>()); private Map<ITestNodeWrapper, List<ITestNodeWrapper>> myTestToMethodsMap = MapSequence.fromMap(new LinkedHashMap<ITestNodeWrapper, List<ITestNodeWrapper>>(16, (float) 0.75, false)); private final Set<TestView> myViewsList = SetSequence.fromSet(new HashSet<TestView>()); private final List<TestStateListener> myListeners = ListSequence.fromList(new ArrayList<TestStateListener>()); private String myCurrentClass; private String myCurrentMethod; private String myCurrentToken; private volatile boolean myCompletedGracefully = true; private String myLostTest; private String myLostMethod; private int myTotalTests = 0; private int myCompletedTests = 0; private int myFailedTests = 0; private boolean myIsTerminated; private String myAvailableText = null; private Key myKey = null; private final Project myProject; public TestRunState(List<ITestNodeWrapper> tests, Project project) { myProject = project; initTestState(ListSequence.fromList(tests).where(new IWhereFilter<ITestNodeWrapper>() { public boolean accept(ITestNodeWrapper it) { return it.isTestCase(); } }).toListSequence(), ListSequence.fromList(tests).where(new IWhereFilter<ITestNodeWrapper>() { public boolean accept(ITestNodeWrapper it) { return !(it.isTestCase()); } }).toListSequence()); } private void initTestState(final List<ITestNodeWrapper> testCases, final List<ITestNodeWrapper> testMethods) { myProject.getModelAccess().runReadAction(new Runnable() { public void run() { TestRunState.this.addTestCases(testCases); TestRunState.this.addTestMethods(testMethods); for (ITestNodeWrapper testCase : MapSequence.fromMap(TestRunState.this.myTestToMethodsMap).keySet()) { for (ITestNodeWrapper testMethod : MapSequence.fromMap(TestRunState.this.myTestToMethodsMap).get(testCase)) { ListSequence.fromList(TestRunState.this.myTestMethods).addElement(testCase.getFqName() + '.' + testMethod.getName()); } } } }); this.myTotalTests = ListSequence.fromList(this.myTestMethods).count(); this.initView(); } private void addTestCases(List<ITestNodeWrapper> testCases) { for (ITestNodeWrapper testCase : ListSequence.fromList(testCases)) { List<ITestNodeWrapper> testMethods = ListSequence.fromList(new ArrayList<ITestNodeWrapper>()); ListSequence.fromList(testMethods).addSequence(Sequence.fromIterable(testCase.getTestMethods())); MapSequence.fromMap(this.myTestToMethodsMap).put(testCase, testMethods); } } private void addTestMethods(List<ITestNodeWrapper> testMethods) { for (ITestNodeWrapper testMethod : ListSequence.fromList(testMethods)) { ITestNodeWrapper testCase = testMethod.getTestCase(); List<ITestNodeWrapper> curTestMethods = MapSequence.fromMap(this.myTestToMethodsMap).get(testCase); if (curTestMethods == null) { curTestMethods = ListSequence.fromList(new ArrayList<ITestNodeWrapper>()); MapSequence.fromMap(this.myTestToMethodsMap).put(testCase, curTestMethods); } if (!(ListSequence.fromList(curTestMethods).contains(testMethod))) { ListSequence.fromList(curTestMethods).addElement(testMethod); } } } private void updateView() { for (TestView view : this.myViewsList) { view.update(); } } private void initView() { for (TestView view : this.myViewsList) { view.init(); } } public void addView(TestView testView) { SetSequence.fromSet(this.myViewsList).addElement(testView); } public void onTestStarted(final TestEvent event) { ListSequence.fromList(this.myListeners).visitAll(new IVisitor<TestStateListener>() { public void visit(TestStateListener it) { it.onTestStart(event); } }); this.startTest(event.getTestCaseName(), event.getTestMethodName()); } public void onTestFinished(final TestEvent event) { ListSequence.fromList(this.myListeners).visitAll(new IVisitor<TestStateListener>() { public void visit(TestStateListener it) { it.onTestFinish(event); } }); this.finishTest(); this.completeTestEvent(event); } public void onTestFailure(final TestEvent event) { ListSequence.fromList(this.myListeners).visitAll(new IVisitor<TestStateListener>() { public void visit(TestStateListener it) { it.onTestFailure(event); } }); this.failTest(); } public void onTestAssumptionFailure(final TestEvent event) { ListSequence.fromList(this.myListeners).visitAll(new IVisitor<TestStateListener>() { public void visit(TestStateListener it) { it.onTestAssumptionFailure(event); } }); this.ignoreTest(); } public void looseTest(final String className, final String testName) { ListSequence.fromList(this.myListeners).visitAll(new IVisitor<TestStateListener>() { public void visit(TestStateListener it) { it.onLooseTest(className, testName); } }); this.looseTestInternal(className, testName); } private void startTest(String className, String methodName) { synchronized (lock) { if (myCurrentMethod != null && myCurrentClass != null) { if (LOG.isEnabledFor(Level.ERROR)) { LOG.error("Seems that the previous test is not finished yet"); } } checkConsistency(); this.myCurrentClass = className; this.myCurrentMethod = methodName; this.myCompletedGracefully = true; this.updateView(); } } private void finishTest() { synchronized (lock) { if (this.myCompletedGracefully) { this.myCompletedTests++; } this.updateView(); this.myCurrentClass = null; this.myCurrentMethod = null; } } private void failTest() { synchronized (lock) { this.myFailedTests++; this.updateView(); } } private void ignoreTest() { synchronized (lock) { this.myCompletedGracefully = false; this.updateView(); } } private void looseTestInternal(String test, String method) { synchronized (lock) { this.myLostTest = test; this.myLostMethod = method; this.updateView(); this.myLostTest = null; this.myLostMethod = null; } } public void terminate() { synchronized (lock) { checkConsistency(); this.myIsTerminated = true; this.updateView(); } } private void checkConsistency() { assert this.myCompletedTests <= this.myTotalTests; assert this.myFailedTests <= this.myCompletedTests; } public void outputText(String text, @NotNull Key key) { synchronized (lock) { this.myAvailableText = text; this.myKey = key; this.updateView(); this.myAvailableText = null; this.myKey = null; } } private void completeTestEvent(TestEvent event) { String testCaseName = event.getTestCaseName(); String testMethodName = event.getTestMethodName(); if (testMethodName == null) { removeUsedTestCase(testCaseName); } else { removeUsedMethod(testCaseName, testMethodName); } } private void removeUsedMethod(String testCaseName, String testMethodName) { String methodKey = testCaseName + '.' + testMethodName; synchronized (this.myTestMethods) { if (ListSequence.fromList(this.myTestMethods).contains(methodKey)) { ListSequence.fromList(this.myTestMethods).removeElement(methodKey); } } } private void removeUsedTestCase(final String testCaseName) { final List<String> methodsToRemove = ListSequence.fromList(new LinkedList<String>()); myProject.getModelAccess().runReadAction(new Runnable() { public void run() { for (ITestNodeWrapper testCase : MapSequence.fromMap(TestRunState.this.myTestToMethodsMap).keySet()) { if (testCase.getFqName().equals(testCaseName)) { for (ITestNodeWrapper testMethod : MapSequence.fromMap(myTestToMethodsMap).get(testCase)) { String methodKey = testCaseName + '.' + testMethod.getName(); ListSequence.fromList(methodsToRemove).addElement(methodKey); } } } } }); synchronized (this.myTestMethods) { for (String methodKey : methodsToRemove) { if (ListSequence.fromList(this.myTestMethods).contains(methodKey)) { ListSequence.fromList(this.myTestMethods).removeElement(methodKey); } } } } public List<String> getUnusedMethods() { return this.myTestMethods; } public int getTotalTests() { return this.myTotalTests; } public int getFailedTests() { return this.myFailedTests; } public int getCompletedTests() { return this.myCompletedTests; } public String getCurrentClass() { return this.myCurrentClass; } public String getCurrentMethod() { return this.myCurrentMethod; } public void setToken(String token) { this.myCurrentToken = token; } public String getToken() { return this.myCurrentToken; } public String getLostMethod() { return this.myLostMethod; } public String getLostClass() { return this.myLostTest; } public boolean isTerminated() { return this.myIsTerminated; } public String getAvailableText() { return this.myAvailableText; } public Key getKey() { return this.myKey; } public void addListener(TestStateListener listener) { ListSequence.fromList(this.myListeners).addElement(listener); } public void removeListener(TestStateListener listener) { ListSequence.fromList(this.myListeners).removeElement(listener); } public Map<ITestNodeWrapper, List<ITestNodeWrapper>> getTestsMap() { return this.myTestToMethodsMap; } }