package com.google.jstestdriver.idea.execution;
import com.google.jstestdriver.idea.assertFramework.JstdTestMethodNameRefiner;
import com.google.jstestdriver.idea.execution.settings.JstdRunSettings;
import com.google.jstestdriver.idea.execution.settings.ServerType;
import com.google.jstestdriver.idea.execution.settings.TestType;
import com.intellij.execution.configurations.RuntimeConfigurationError;
import com.intellij.execution.configurations.RuntimeConfigurationException;
import com.intellij.execution.configurations.RuntimeConfigurationWarning;
import com.intellij.javascript.testFramework.TestFileStructureManager;
import com.intellij.javascript.testFramework.TestFileStructurePack;
import com.intellij.lang.javascript.psi.JSFile;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiManager;
import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
public class JstdRunConfigurationVerifier {
private JstdRunConfigurationVerifier() {}
public static void verify(@NotNull Project project, @NotNull JstdRunSettings runSettings) throws RuntimeConfigurationException {
if (runSettings.getTestType() == TestType.ALL_CONFIGS_IN_DIRECTORY) {
verifyAllInDirectory(runSettings);
} else if (runSettings.getTestType() == TestType.CONFIG_FILE) {
verifyConfigFile(runSettings);
} else if (runSettings.getTestType() == TestType.JS_FILE) {
verifyJSFileType(runSettings);
} else if (runSettings.getTestType() == TestType.TEST_CASE) {
verifyTestCase(project, runSettings);
} else if (runSettings.getTestType() == TestType.TEST_METHOD) {
verifyTestMethod(project, runSettings);
}
verifyServer(runSettings);
}
private static void verifyAllInDirectory(@NotNull JstdRunSettings runSettings) throws RuntimeConfigurationError {
String directory = runSettings.getDirectory();
if (directory.trim().isEmpty()) {
throw new RuntimeConfigurationError("Directory name is empty.");
}
File dirFile = new File(directory);
if (!dirFile.exists()) {
throw new RuntimeConfigurationError("Specified directory '" + directory + "' does not exist.");
}
if (dirFile.isFile()) {
throw new RuntimeConfigurationError("You have specified file, but directory was expected.");
}
if (!dirFile.isDirectory()) {
throw new RuntimeConfigurationError("Please specify directory correctly.");
}
}
private static void verifyConfigFile(@NotNull JstdRunSettings runSettings) throws RuntimeConfigurationError {
String fileStr = runSettings.getConfigFile();
if (fileStr.trim().isEmpty()) {
throw new RuntimeConfigurationError("Configuration file name is empty.");
}
File configFile = new File(fileStr);
if (!configFile.exists()) {
throw new RuntimeConfigurationError("Configuration file does not exist.");
}
if (configFile.isDirectory()) {
throw new RuntimeConfigurationError("You have specified directory, but file was expected.");
}
if (!configFile.isFile()) {
throw new RuntimeConfigurationError("Please specify configuration file correctly.");
}
}
private static void verifyJSFileType(@NotNull JstdRunSettings runSettings) throws RuntimeConfigurationError {
verifyConfigFile(runSettings);
verifyJSFilePath(runSettings);
}
private static void verifyJSFilePath(@NotNull JstdRunSettings runSettings) throws RuntimeConfigurationError {
String fileStr = runSettings.getJsFilePath();
if (fileStr.trim().isEmpty()) {
throw new RuntimeConfigurationError("JavaScript file name is empty.");
}
File configFile = new File(fileStr);
if (!configFile.exists()) {
throw new RuntimeConfigurationError("JavaScript file does not exist.");
}
if (configFile.isDirectory()) {
throw new RuntimeConfigurationError("You have specified directory, but file was expected.");
}
if (!configFile.isFile()) {
throw new RuntimeConfigurationError("Please specify JavaScript file correctly.");
}
}
@Nullable
private static TestFileStructurePack verifyTestCase(@NotNull Project project,
@NotNull JstdRunSettings runSettings) throws RuntimeConfigurationException {
verifyJSFileType(runSettings);
if (runSettings.getTestCaseName().isEmpty()) {
throw new RuntimeConfigurationError("Test case name is empty.");
}
VirtualFile jsTestVirtualFile = VfsUtil.findFileByIoFile(new File(runSettings.getJsFilePath()), false);
if (jsTestVirtualFile == null) {
throw new RuntimeConfigurationWarning("Can't find JavaScript test file.");
}
JSFile jsFile = ObjectUtils.tryCast(PsiManager.getInstance(project).findFile(jsTestVirtualFile), JSFile.class);
if (jsFile == null) {
throw new RuntimeConfigurationWarning("Wrong JavaScript test file.");
}
TestFileStructurePack pack = TestFileStructureManager.fetchTestFileStructurePackByJsFile(jsFile);
if (pack != null) {
boolean found = pack.contains(runSettings.getTestCaseName(), null, JstdTestMethodNameRefiner.INSTANCE);
if (!found) {
throw new RuntimeConfigurationWarning("Can't find test case with name '" + runSettings.getTestCaseName() + "'.");
}
return pack;
}
return null;
}
private static void verifyTestMethod(@NotNull Project project,
@NotNull JstdRunSettings runSettings) throws RuntimeConfigurationException {
TestFileStructurePack pack = verifyTestCase(project, runSettings);
if (runSettings.getTestMethodName().isEmpty()) {
throw new RuntimeConfigurationError("Test method name is empty.");
}
if (pack != null) {
boolean found = pack.contains(runSettings.getTestCaseName(),
runSettings.getTestMethodName(),
JstdTestMethodNameRefiner.INSTANCE);
if (!found) {
throw new RuntimeConfigurationWarning("Can't find test method with name '" + runSettings.getTestMethodName() + "'.");
}
}
}
private static void verifyServer(@NotNull JstdRunSettings runSettings) throws RuntimeConfigurationError {
if (runSettings.getServerType() == ServerType.EXTERNAL) {
String serverAddressStr = runSettings.getServerAddress();
if (serverAddressStr.trim().isEmpty()) {
throw new RuntimeConfigurationError("Server address is empty.");
}
try {
new URL(serverAddressStr);
} catch (MalformedURLException e) {
throw new RuntimeConfigurationError("Please specify server address correctly.");
}
}
}
}