package com.google.jstestdriver.idea.rt;
import com.google.jstestdriver.*;
import com.google.jstestdriver.hooks.TestListener;
import com.google.jstestdriver.idea.rt.execution.TestPath;
import com.google.jstestdriver.idea.rt.execution.TestPathFactory;
import com.google.jstestdriver.idea.rt.execution.tree.TreeManager;
import com.google.jstestdriver.idea.rt.util.TestFileScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
/**
* @author Sergey Simonchik
*/
public class IdeaTestListener implements TestListener {
private static final String PREFIX = "/test/";
private final TreeManager myTreeManager;
private final File myBasePath;
private final Object MONITOR = new Object();
private final boolean myDryRun;
private final TestFileScope myTestFileScope;
private final TestPathFactory myTestPathFactory;
private final Set<FileLoadError> myDryRunErrors = new HashSet<>();
public IdeaTestListener(@NotNull TreeManager treeManager,
@NotNull File jstdConfigFile,
@NotNull File singleBasePath,
boolean dryRun,
@NotNull TestFileScope testFileScope) {
myTreeManager = treeManager;
myBasePath = singleBasePath;
myDryRun = dryRun;
myTestFileScope = testFileScope;
myTestPathFactory = new TestPathFactory(jstdConfigFile);
}
@Override
public void onFileLoad(BrowserInfo browserInfo, FileResult fileResult) {
if (fileResult.isSuccess()) {
return;
}
synchronized (MONITOR) {
FileSource jsFileSource = fileResult.getFileSource();
String jsFilePath = jsFileSource != null ? jsFileSource.getBasePath() : null;
FileLoadError error = new FileLoadError(browserInfo, jsFilePath, fileResult.getMessage());
final boolean reportError;
if (myDryRun) {
myDryRunErrors.add(error);
reportError = true;
}
else {
reportError = myDryRunErrors.contains(error);
}
if (reportError) {
myTreeManager.onFileLoadError(browserInfo.toString(), jsFilePath, fileResult.getMessage());
}
}
}
@Override
public void onTestRegistered(BrowserInfo browser, TestCase testCase) {
synchronized (MONITOR) {
String testCaseName = testCase.getName();
if (!myTestFileScope.containsTestCase(testCaseName)) {
return;
}
for (String testName : testCase.getTests()) {
if (!myTestFileScope.containsTestCaseAndMethod(testCaseName, testName)) {
continue;
}
File jsTestFile = resolveTestFile(testCase.getFileName());
TestPath testPath = myTestPathFactory.createTestPath(
browser,
jsTestFile,
testCase.getName(),
testName
);
myTreeManager.onTestRegistered(testPath);
}
}
}
@Override
public void onTestComplete(TestResult testResult) {
synchronized (MONITOR) {
TestPath testPath = myTestPathFactory.createTestPath(testResult);
myTreeManager.onTestCompleted(testPath, testResult);
}
}
@Override
public void finish() {
}
@Nullable
private File resolveTestFile(@Nullable String jsTestFilePath) {
if (jsTestFilePath == null) {
return null;
}
if (jsTestFilePath.startsWith(PREFIX)) {
String filePath = jsTestFilePath.substring(PREFIX.length());
File resolved = doResolveTestFile(filePath);
if (resolved != null) {
return resolved;
}
}
return doResolveTestFile(jsTestFilePath);
}
@Nullable
private File doResolveTestFile(@NotNull String filePath) {
File absoluteFile = new File(filePath);
if (absoluteFile.isAbsolute() && absoluteFile.isFile()) {
return absoluteFile;
}
File localFile = new File(myBasePath, filePath);
if (localFile.isFile()) {
return localFile;
}
return null;
}
private static class FileLoadError {
private final Long myBrowserId;
private final String myJsFilePath;
private final String myErrorMessage;
private FileLoadError(@NotNull BrowserInfo browserInfo,
@Nullable String jsFilePath,
@Nullable String errorMessage) {
myBrowserId = browserInfo.getId();
myJsFilePath = jsFilePath;
myErrorMessage = errorMessage;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
FileLoadError that = (FileLoadError)o;
return equalsNullable(myBrowserId, that.myBrowserId) &&
equalsNullable(myJsFilePath, that.myJsFilePath) &&
equalsNullable(myErrorMessage, that.myErrorMessage);
}
public static <T> boolean equalsNullable(@Nullable T a, @Nullable T b) {
return a == null ? b == null : a.equals(b);
}
@Override
public int hashCode() {
int result = myBrowserId != null ? myBrowserId.hashCode() : 0;
result = 31 * result + (myJsFilePath != null ? myJsFilePath.hashCode() : 0);
result = 31 * result + (myErrorMessage != null ? myErrorMessage.hashCode() : 0);
return result;
}
}
}