package com.google.jstestdriver.idea.assertFramework.qunit; import com.google.common.collect.Lists; import com.google.inject.internal.Maps; import com.google.jstestdriver.idea.assertFramework.AbstractTestFileStructure; import com.google.jstestdriver.idea.assertFramework.JstdRunElement; import com.google.jstestdriver.idea.util.CastUtils; import com.google.jstestdriver.idea.util.JsPsiUtils; import com.intellij.lang.javascript.psi.JSFile; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.Map; public class QUnitFileStructure extends AbstractTestFileStructure { private final List<QUnitModuleStructure> myNonDefaultModuleStructures = Lists.newArrayList(); private final Map<String, QUnitModuleStructure> myNonDefaultModuleStructureByNameMap = Maps.newHashMap(); private final DefaultQUnitModuleStructure myDefaultModuleStructure = new DefaultQUnitModuleStructure(this); public QUnitFileStructure(@NotNull JSFile jsFile) { super(jsFile); } public int getAllModuleCount() { return myNonDefaultModuleStructures.size() + 1; } public int getNonDefaultModuleCount() { return myNonDefaultModuleStructures.size(); } public List<QUnitModuleStructure> getNonDefaultModuleStructures() { return myNonDefaultModuleStructures; } public void addModuleStructure(@NotNull QUnitModuleStructure moduleStructure) { myNonDefaultModuleStructureByNameMap.put(moduleStructure.getName(), moduleStructure); myNonDefaultModuleStructures.add(moduleStructure); } @Nullable public AbstractQUnitModuleStructure getQUnitModuleByName(String qunitModuleName) { AbstractQUnitModuleStructure moduleStructure = myNonDefaultModuleStructureByNameMap.get(qunitModuleName); if (moduleStructure == null) { if (myDefaultModuleStructure.getName().equals(qunitModuleName)) { moduleStructure = myDefaultModuleStructure; } } return moduleStructure; } @NotNull public DefaultQUnitModuleStructure getDefaultModuleStructure() { return myDefaultModuleStructure; } public boolean hasQUnitSymbols() { return getDefaultModuleStructure().getTestCount() > 0 || getNonDefaultModuleCount() > 0; } @Nullable public QUnitModuleStructure findModuleStructureContainingOffset(int offset) { for (QUnitModuleStructure moduleStructure : myNonDefaultModuleStructures) { TextRange moduleTextRange = moduleStructure.getEnclosingCallExpression().getTextRange(); if (JsPsiUtils.containsOffsetStrictly(moduleTextRange, offset)) { return moduleStructure; } } return null; } @Nullable public QUnitTestMethodStructure findTestMethodStructureContainingOffset(int offset) { QUnitTestMethodStructure testMethodStructure = myDefaultModuleStructure.findTestMethodStructureContainingOffset( offset); if (testMethodStructure != null) { return testMethodStructure; } for (QUnitModuleStructure moduleStructure : myNonDefaultModuleStructures) { testMethodStructure = moduleStructure.findTestMethodStructureContainingOffset(offset); if (testMethodStructure != null) { return testMethodStructure; } } return null; } @Override @Nullable public JstdRunElement findJstdRunElement(@NotNull TextRange textRange) { for (QUnitModuleStructure nonDefaultModuleStructure : myNonDefaultModuleStructures) { JstdRunElement jstdRunElement = nonDefaultModuleStructure.findJstdRunElement(textRange); if (jstdRunElement != null) { return jstdRunElement; } } return myDefaultModuleStructure.findJstdRunElement(textRange); } @Override public PsiElement findPsiElement(@NotNull String testCaseName, @Nullable String testMethodName) { AbstractQUnitModuleStructure qunitModuleStructure = getQUnitModuleByName(testCaseName); if (qunitModuleStructure != null) { if (testMethodName != null) { String name = removePrefix(testMethodName, "test "); QUnitTestMethodStructure test = qunitModuleStructure.getTestMethodStructureByName(name); if (test != null) { return test.getCallExpression(); } } else { QUnitModuleStructure nonDefault = CastUtils.tryCast(qunitModuleStructure, QUnitModuleStructure.class); if (nonDefault != null) { return nonDefault.getEnclosingCallExpression(); } } } return null; } @NotNull private static String removePrefix(@NotNull String s, @NotNull String prefix) { if (s.startsWith(prefix)) { return s.substring(prefix.length()); } return s; } }