Package com.google.jstestdriver.idea.execution

Source Code of com.google.jstestdriver.idea.execution.JstdRunConfigurationProducer

package com.google.jstestdriver.idea.execution;

import com.google.jstestdriver.idea.config.JstdConfigFileUtils;
import com.google.jstestdriver.idea.config.JstdTestFilePathIndex;
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.Location;
import com.intellij.execution.actions.ConfigurationContext;
import com.intellij.execution.actions.RunConfigurationProducer;
import com.intellij.execution.configurations.ConfigurationTypeUtil;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.javascript.testFramework.JstdRunElement;
import com.intellij.javascript.testFramework.TestFileStructureManager;
import com.intellij.javascript.testFramework.TestFileStructurePack;
import com.intellij.lang.javascript.JavaScriptSupportLoader;
import com.intellij.lang.javascript.index.JSIndexEntry;
import com.intellij.lang.javascript.index.JavaScriptIndex;
import com.intellij.lang.javascript.psi.JSFile;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.util.Arrays;
import java.util.List;

public class JstdRunConfigurationProducer extends RunConfigurationProducer<JstdRunConfiguration> {

  private static final Logger LOG = Logger.getInstance(JstdRunConfigurationProducer.class);

  private static final JstdRunSettingsProvider[] RUN_SETTINGS_PROVIDERS = {
      new JstdDirectoryRunSettingsProvider(),
      new JstdConfigFileRunSettingsProvider(),
      new TestElementRunSettingsProvider(),
      new JsFileRunSettingsProvider()
  };

  public JstdRunConfigurationProducer() {
    super(JstdConfigurationType.getInstance());
  }

  private static void logTakenTime(String actionName, long startTimeNano, String... args) {
    final long NANO_IN_MS = 1000000;
    long durationNano = System.nanoTime() - startTimeNano;
    if (durationNano > 100 * NANO_IN_MS) {
      String message = String.format("[JsTD] Time taken by '" + actionName + "': %.2f ms, extra args: %s\n",
                                     durationNano / (1.0 * NANO_IN_MS),
                                     Arrays.toString(args)
      );
      LOG.info(message);
    }
  }

  private static void logDoneCreateConfigurationByElement(long startTimeNano, String... args) {
    logTakenTime("createConfigurationByElement", startTimeNano, args);
  }

  @Nullable
  private static JstdRunSettings buildRunSettingsContext(@Nullable Location<?> location) {
    if (location != null) {
      PsiElement element = location.getPsiElement();
      JstdRunSettings runSettings = findJstdRunSettings(element);
      if (runSettings != null) {
        return runSettings;
      }
    }
    return null;
  }

  @Nullable
  private static JstdRunSettings findJstdRunSettings(@NotNull PsiElement element) {
    for (JstdRunSettingsProvider jstdRunSettingsProvider : RUN_SETTINGS_PROVIDERS) {
      JstdRunSettings runSettings = jstdRunSettingsProvider.provideSettings(element);
      if (runSettings != null) {
        return runSettings;
      }
    }
    return null;
  }

  @Override
  protected boolean setupConfigurationFromContext(JstdRunConfiguration configuration,
                                                  ConfigurationContext context,
                                                  Ref<PsiElement> sourceElement) {
    RunConfiguration original = context.getOriginalConfiguration(null);
    if (original != null && !ConfigurationTypeUtil.equals(original.getType(), JstdConfigurationType.getInstance())) {
      return false;
    }
    Project project = configuration.getProject();
    if (project != null) {
      if (!JstdSettingsUtil.areJstdConfigFilesInProjectCached(project)) {
        return false;
      }
    }
    long startTimeNano = System.nanoTime();
    @SuppressWarnings({"unchecked"})
    JstdRunSettings settings = buildRunSettingsContext(context.getLocation());
    if (settings == null) {
      logDoneCreateConfigurationByElement(startTimeNano, "1");
      return false;
    }

    if (settings.getConfigFile().isEmpty()) {
      JstdRunSettings clonedSettings = configuration.getRunSettings();
      JstdRunSettings.Builder builder = new JstdRunSettings.Builder(settings);
      builder.setConfigFile(clonedSettings.getConfigFile());
      settings = builder.build();
    }
    configuration.setRunSettings(settings);

    String configurationName = configuration.resetGeneratedName();
    configuration.setName(configurationName);

    logDoneCreateConfigurationByElement(startTimeNano, "3");

    return true;
  }

  @Override
  public boolean isConfigurationFromContext(JstdRunConfiguration configuration, ConfigurationContext context) {
    JstdRunSettings patternRunSettings = buildRunSettingsContext(context.getLocation());
    if (patternRunSettings == null) {
      return false;
    }
    JstdRunSettings candidateRunSettings = configuration.getRunSettings();
    TestType patternTestType = patternRunSettings.getTestType();
    if (patternTestType != candidateRunSettings.getTestType()) {
      return false;
    }
    if (patternTestType == TestType.ALL_CONFIGS_IN_DIRECTORY) {
      File dir1 = new File(patternRunSettings.getDirectory());
      File dir2 = new File(candidateRunSettings.getDirectory());
      if (dir1.isDirectory() && dir2.isDirectory() && FileUtil.filesEqual(dir1, dir2)) {
        return true;
      }
    } else if (patternTestType == TestType.CONFIG_FILE) {
      File configFilePattern = new File(patternRunSettings.getConfigFile());
      File configFileCandidate = new File(candidateRunSettings.getConfigFile());
      if (configFilePattern.isFile()
          && configFileCandidate.isFile()
          && FileUtil.filesEqual(configFilePattern, configFileCandidate)) {
        return true;
      }
    } else if (patternTestType == TestType.JS_FILE
               || patternTestType == TestType.TEST_CASE
               || patternTestType == TestType.TEST_METHOD) {
      File patternJsFile = new File(patternRunSettings.getJsFilePath());
      File candidateJsFile = new File(candidateRunSettings.getJsFilePath());
      boolean eq = candidateJsFile.isFile() && FileUtil.filesEqual(patternJsFile, candidateJsFile);
      if (patternTestType == TestType.TEST_CASE) {
        eq = eq && patternRunSettings.getTestCaseName().equals(candidateRunSettings.getTestCaseName());
      }
      if (patternTestType == TestType.TEST_METHOD) {
        eq = eq && patternRunSettings.getTestCaseName().equals(candidateRunSettings.getTestCaseName());
        eq = eq && patternRunSettings.getTestMethodName().equals(candidateRunSettings.getTestMethodName());
      }
      if (eq) {
        return true;
       }
    }
    return false;
  }

  private interface JstdRunSettingsProvider {
    @Nullable
    JstdRunSettings provideSettings(@NotNull PsiElement psiElement);
  }

  private static class JsFileRunSettingsProvider implements JstdRunSettingsProvider {

    @Override
    @Nullable
    public JstdRunSettings provideSettings(@NotNull PsiElement psiElement) {
      PsiFile psiFile = psiElement.getContainingFile();
      if (psiFile == null) {
        return null;
      }
      final VirtualFile virtualFile = psiFile.getVirtualFile();
      if (virtualFile == null || virtualFile.getFileType() != JavaScriptSupportLoader.JAVASCRIPT) {
        return null;
      }
      Project project = psiFile.getProject();
      JSIndexEntry entry = JavaScriptIndex.getInstance(project).getEntryForFile(psiFile);
      if (entry == null || !entry.isTestFile()) {
        return null;
      }
      JstdRunSettings.Builder builder = new JstdRunSettings.Builder();
      builder.setTestType(TestType.JS_FILE);
      List<VirtualFile> jstdConfigFiles = JstdTestFilePathIndex.findConfigFilesInProject(virtualFile, project);
      if (jstdConfigFiles.size() == 1) {
        builder.setConfigFile(getPath(jstdConfigFiles.get(0)));
      }
      builder.setJSFilePath(getPath(virtualFile));
      builder.setServerType(ServerType.INTERNAL);
      return builder.build();
    }
  }

  private static class JstdConfigFileRunSettingsProvider implements JstdRunSettingsProvider {

    @Override
    public JstdRunSettings provideSettings(@NotNull PsiElement psiElement) {
      PsiFile psiFile = psiElement.getContainingFile();
      if (psiFile != null) {
        VirtualFile virtualFile = psiFile.getVirtualFile();
        if (virtualFile != null && JstdConfigFileUtils.isJstdConfigFile(virtualFile)) {
          JstdRunSettings.Builder builder = new JstdRunSettings.Builder();
          builder.setConfigFile(getPath(virtualFile))
                 .setServerType(ServerType.INTERNAL);
          return builder.build();
        }
      }
      return null;
    }
  }

  private static class JstdDirectoryRunSettingsProvider implements JstdRunSettingsProvider {

    @Override
    public JstdRunSettings provideSettings(@NotNull PsiElement psiElement) {
      PsiDirectory psiDirectory = ObjectUtils.tryCast(psiElement, PsiDirectory.class);
      if (psiDirectory == null) {
        return null;
      }
      VirtualFile directory = psiDirectory.getVirtualFile();
      boolean jstdConfigs = JstdSettingsUtil.areJstdConfigFilesInDirectory(psiDirectory.getProject(), directory);
      if (!jstdConfigs) {
        return null;
      }
      JstdRunSettings.Builder builder = new JstdRunSettings.Builder();
      builder.setTestType(TestType.ALL_CONFIGS_IN_DIRECTORY)
             .setDirectory(getPath(directory))
             .setServerType(ServerType.INTERNAL);
      return builder.build();
    }
  }

  private static class TestElementRunSettingsProvider implements JstdRunSettingsProvider {

    @Override
    public JstdRunSettings provideSettings(@NotNull PsiElement psiElement) {
      JSFile jsFile = ObjectUtils.tryCast(psiElement.getContainingFile(), JSFile.class);
      if (jsFile == null) {
        return null;
      }
      VirtualFile virtualFile = jsFile.getVirtualFile();
      if (virtualFile == null || virtualFile.getFileType() != JavaScriptSupportLoader.JAVASCRIPT) {
        return null;
      }
      TestFileStructurePack pack = TestFileStructureManager.fetchTestFileStructurePackByJsFile(jsFile);
      if (pack == null) {
        return null;
      }
      JstdRunElement jstdRunElement = pack.getJstdRunElement(psiElement);
      if (jstdRunElement != null) {
        Project project = jsFile.getProject();
        JstdRunSettings.Builder builder = new JstdRunSettings.Builder();
        builder.setJSFilePath(getPath(virtualFile));
        builder.setTestCaseName(jstdRunElement.getTestCaseName());
        List<VirtualFile> jstdConfigs = JstdTestFilePathIndex.findConfigFilesInProject(virtualFile, project);
        if (jstdConfigs.size() == 1) {
          builder.setConfigFile(getPath(jstdConfigs.get(0)));
        }
        String testMethodName = jstdRunElement.getTestMethodName();
        if (testMethodName != null) {
          builder.setTestType(TestType.TEST_METHOD);
          builder.setTestMethodName(testMethodName);
        } else {
          builder.setTestType(TestType.TEST_CASE);
        }
        return builder.build();
      }
      return null;
    }

  }

  private static String getPath(@NotNull VirtualFile virtualFile) {
    return FileUtil.toSystemDependentName(virtualFile.getPath());
  }

}
TOP

Related Classes of com.google.jstestdriver.idea.execution.JstdRunConfigurationProducer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.