Package com.google.jstestdriver.idea.execution

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

package com.google.jstestdriver.idea.execution;

import com.google.common.collect.Maps;
import com.google.jstestdriver.idea.assertFramework.JstdTestMethodNameRefiner;
import com.intellij.execution.Location;
import com.intellij.execution.PsiLocation;
import com.intellij.execution.testframework.sm.FileUrlProvider;
import com.intellij.javascript.testFramework.JsTestFileByTestNameIndex;
import com.intellij.javascript.testFramework.jasmine.JasmineFileStructure;
import com.intellij.javascript.testFramework.jasmine.JasmineFileStructureBuilder;
import com.intellij.javascript.testFramework.jasmine.JasmineSpecStructure;
import com.intellij.javascript.testFramework.jasmine.JasmineSuiteStructure;
import com.intellij.javascript.testFramework.qunit.DefaultQUnitModuleStructure;
import com.intellij.javascript.testFramework.qunit.QUnitFileStructure;
import com.intellij.javascript.testFramework.qunit.QUnitFileStructureBuilder;
import com.intellij.javascript.testFramework.util.EscapeUtils;
import com.intellij.lang.javascript.psi.JSFile;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.testIntegration.TestLocationProvider;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
* @author Sergey Simonchik
*/
public class JstdTestLocationProvider implements TestLocationProvider {

  private static final String PROTOCOL_ID__CONFIG_FILE = "config";
  private static final String PROTOCOL_ID__TEST_CASE = "testCase";
  private static final String PROTOCOL_ID__TEST = "test";
  private static final String PROTOCOL_ID__BROWSER_ERROR = "browserError";

  @NotNull
  @Override
  public List<Location> getLocation(@NotNull String protocolId, @NotNull String locationData, Project project) {
    final Location location;
    if (PROTOCOL_ID__CONFIG_FILE.equals(protocolId)) {
      location = findConfigFile(locationData, project);
    }
    else if (PROTOCOL_ID__TEST_CASE.equals(protocolId) || PROTOCOL_ID__TEST.equals(protocolId)) {
      location = findTest(locationData, project);
    }
    else if (PROTOCOL_ID__BROWSER_ERROR.equals(protocolId)) {
      location = findJsFile(locationData, project);
    }
    else {
      location = null;
    }
    if (location != null) {
      return Collections.singletonList(location);
    }
    return Collections.emptyList();
  }

  @Nullable
  private static Location findJsFile(@NotNull String locationData, Project project) {
    List<String> components = EscapeUtils.split(locationData, ':');
    if (components.size() != 3) {
      return null;
    }
    String jsFilePath = components.get(0);
    Integer lineNumber = toInteger(components.get(1));
    int line = lineNumber != null ? lineNumber : 1;

    VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(new File(jsFilePath));
    if (virtualFile != null && virtualFile.isValid()) {
      return FileUrlProvider.createLocationFor(project, virtualFile, line);
    }
    return null;
  }

  private static Integer toInteger(@NotNull String s) {
    try {
      return Integer.parseInt(s);
    }
    catch (NumberFormatException e) {
      return null;
    }
  }

  @Nullable
  private static Location<PsiElement> findTest(final @NotNull String locationData, Project project) {
    List<String> path = EscapeUtils.split(locationData, ':');
    if (path.size() < 2) {
      return null;
    }
    String jsTestFilePath = path.get(0);
    String testCaseName = path.get(1);
    String testMethodName = path.size() > 2 ? path.get(2) : null;

    File jsTestFile = new File(jsTestFilePath);

    final PsiElement psiElement;
    if (jsTestFile.isFile() && jsTestFile.isAbsolute()) {
      VirtualFile jsTestVirtualFile = VfsUtil.findFileByIoFile(jsTestFile, false);
      if (jsTestVirtualFile == null || !jsTestVirtualFile.isValid()) {
        return null;
      }
      if (testMethodName != null
          && testCaseName.equals(DefaultQUnitModuleStructure.NAME)
          && StringUtil.startsWithIgnoreCase(jsTestVirtualFile.getName(), "QUnitAdapter")) {
        psiElement = findTestFromQUnitDefaultModule(project, testMethodName);
      }
      else {
        psiElement = NavUtils.findPsiLocation(
          project,
          jsTestVirtualFile,
          testCaseName,
          testMethodName,
          JstdTestMethodNameRefiner.INSTANCE
        );
      }
    }
    else {
      psiElement = findJasmineTestLocation(project, testCaseName, testMethodName);
    }
    if (psiElement != null && psiElement.isValid()) {
      return PsiLocation.fromPsiElement(psiElement);
    }
    return null;
  }

  @Nullable
  private static PsiElement findTestFromQUnitDefaultModule(@NotNull Project project,
                                                           @NotNull String testMethodName) {
    GlobalSearchScope scope = GlobalSearchScope.projectScope(project);
    testMethodName = StringUtil.trimStart(testMethodName, "test ");
    String key = JsTestFileByTestNameIndex.createQUnitKeyForTestFromDefaultModule(testMethodName);
    List<VirtualFile> jsTestVirtualFiles = JsTestFileByTestNameIndex.findJsTestFilesByNameInScope(key, scope);
    List<VirtualFile> validJsTestVirtualFiles = filterVirtualFiles(jsTestVirtualFiles);

    for (VirtualFile jsTestVirtualFile : validJsTestVirtualFiles) {
      PsiFile psiFile = PsiManager.getInstance(project).findFile(jsTestVirtualFile);
      if (psiFile instanceof JSFile) {
        JSFile jsFile = (JSFile) psiFile;
        QUnitFileStructureBuilder builder = QUnitFileStructureBuilder.getInstance();
        QUnitFileStructure qunitFileStructure = builder.fetchCachedTestFileStructure(jsFile);
        PsiElement element = qunitFileStructure.findPsiElement(DefaultQUnitModuleStructure.NAME, testMethodName);
        if (element != null && element.isValid()) {
          return element;
        }
      }
    }
    return null;
  }

  @Nullable
  private static PsiElement findJasmineTestLocation(@NotNull Project project,
                                                    @NotNull String testCaseName,
                                                    @Nullable String testMethodName) {
    VirtualFile file = findJasmineTestFileSource(project, testCaseName);
    if (file == null) {
      return null;
    }
    PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
    if (psiFile instanceof JSFile) {
      JSFile jsFile = (JSFile) psiFile;
      JasmineFileStructureBuilder builder = JasmineFileStructureBuilder.getInstance();
      JasmineFileStructure jasmineFileStructure = builder.fetchCachedTestFileStructure(jsFile);
      Map<String, JasmineSuiteStructure> map = Maps.newHashMap();
      for (JasmineSuiteStructure suite : jasmineFileStructure.getSuites()) {
        visitSuite("", map, suite);
      }
      JasmineSuiteStructure suite = map.get(testCaseName);
      if (suite != null) {
        if (testMethodName == null) {
          return suite.getEnclosingCallExpression();
        }
        JasmineSpecStructure spec = suite.getInnerSpecByName(testMethodName);
        if (spec != null) {
          return spec.getEnclosingCallExpression();
        }
      }
    }
    return null;
  }

  private static void visitSuite(@NotNull String prefix,
                                 @NotNull Map<String, JasmineSuiteStructure> map,
                                 @NotNull JasmineSuiteStructure suite) {
    final String joinedSuitesName;
    if (prefix.isEmpty()) {
      joinedSuitesName = suite.getName();
    }
    else {
      joinedSuitesName = prefix + " " + suite.getName();
    }
    map.put(joinedSuitesName, suite);
    for (JasmineSuiteStructure child : suite.getSuites()) {
      visitSuite(joinedSuitesName, map, child);
    }
  }

  @Nullable
  private static VirtualFile findJasmineTestFileSource(@NotNull Project project, @NotNull String joinedSuites) {
    GlobalSearchScope scope = GlobalSearchScope.projectScope(project);
    joinedSuites += ' ';
    int lastSpaceInd = joinedSuites.indexOf(' ');
    while (lastSpaceInd >= 0) {
      String topLevelSuiteName = joinedSuites.substring(0, lastSpaceInd);
      String key = JsTestFileByTestNameIndex.createJasmineKey(Collections.singletonList(topLevelSuiteName));
      List<VirtualFile> files = JsTestFileByTestNameIndex.findJsTestFilesByNameInScope(key, scope);
      for (VirtualFile file : files) {
        if (file.isValid()) {
          return file;
        }
      }
      lastSpaceInd = joinedSuites.indexOf(' ', lastSpaceInd + 1);
    }
    return null;
  }

  private static List<VirtualFile> filterVirtualFiles(@NotNull List<VirtualFile> files) {
    boolean ok = true;
    for (VirtualFile file : files) {
      if (!file.isValid()) {
        ok = false;
        break;
      }
    }
    if (ok) {
      return files;
    }
    return ContainerUtil.filter(files, new Condition<VirtualFile>() {
      @Override
      public boolean value(VirtualFile file) {
        return file.isValid();
      }
    });
  }

  @Nullable
  private static Location findConfigFile(@NotNull String locationData, Project project) {
    VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(new File(locationData));
    if (virtualFile != null && virtualFile.isValid()) {
      PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
      if (psiFile != null && psiFile.isValid()) {
        return PsiLocation.fromPsiElement(psiFile);
      }
    }
    return null;
  }
}
TOP

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

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.