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;
}
}