Package com.johnlindquist.flexunit

Source Code of com.johnlindquist.flexunit.ActionScriptTestFinder

/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.johnlindquist.flexunit;

import com.intellij.codeInsight.TestUtil;
import com.intellij.lang.javascript.psi.ecmal4.JSClass;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.codeStyle.NameUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiShortNamesCache;
import com.intellij.testIntegration.TestFinder;
import com.intellij.testIntegration.TestIntegrationUtils;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.*;
import java.util.regex.Pattern;

/*
*
* This is how you "should" do it (through extension points), but the TestFinderHelper typing doesn't allow it
*
* */

public class ActionScriptTestFinder implements TestFinder{
    public PsiClass findSourceElement(@NotNull PsiElement element){
        while (!(element instanceof JSClass)){
            element = element.getContext();
        }

        return (PsiClass) element;
    }

    @NotNull
    public Collection<PsiElement> findClassesForTest(@NotNull PsiElement element){
        PsiClass klass = findSourceElement(element);
        if (klass == null) return Collections.emptySet();

        GlobalSearchScope scope;
        Module module = getModule(element);
        if (module != null){
            scope = GlobalSearchScope.moduleWithDependenciesScope(module);
        }
        else{
            scope = GlobalSearchScope.projectScope(element.getProject());
        }

        PsiShortNamesCache cache = JavaPsiFacade.getInstance(element.getProject()).getShortNamesCache();

        List<Pair<PsiClass, Integer>> classesWithWeights = new ArrayList<Pair<PsiClass, Integer>>();
        for (Pair<String, Integer> eachNameWithWeight : collectPossibleClassNamesWithWeights(klass.getName())){
            for (PsiClass eachClass : cache.getClassesByName(eachNameWithWeight.first, scope)){
                if (isTestSubjectClass(eachClass)){
                    classesWithWeights.add(new Pair<PsiClass, Integer>(eachClass, eachNameWithWeight.second));
                }
            }
        }

        Collections.sort(classesWithWeights, new Comparator<Pair<PsiClass, Integer>>(){
            public int compare(Pair<PsiClass, Integer> o1, Pair<PsiClass, Integer> o2){
                int result = o2.second.compareTo(o1.second);
                if (result == 0){
                    result = o1.first.getName().compareTo(o2.first.getName());
                }
                return result;
            }
        });

        List<PsiElement> result = new ArrayList<PsiElement>();
        for (Pair<PsiClass, Integer> each : classesWithWeights){
            result.add(each.first);
        }

        return result;
    }

    private static boolean isTestSubjectClass(PsiClass klass){
        if (klass.isEnum()
                || klass.isInterface()
                || klass.isAnnotationType()
                || TestUtil.isTestClass(klass)){
            return false;
        }
        return true;
    }

    private static List<Pair<String, Integer>> collectPossibleClassNamesWithWeights(String testName){
        String[] words = NameUtil.splitNameIntoWords(testName);
        List<Pair<String, Integer>> result = new ArrayList<Pair<String, Integer>>();

        for (int from = 0; from < words.length; from++){
            for (int to = from; to < words.length; to++){
                result.add(new Pair<String, Integer>(StringUtil.join(words, from, to + 1, ""),
                        words.length - from + to));
            }
        }

        return result;
    }

    @NotNull
    public Collection<PsiElement> findTestsForClass(@NotNull PsiElement element){
        PsiClass klass = findSourceElement(element);
        if (klass == null) return Collections.emptySet();

        GlobalSearchScope scope;
        Module module = getModule(element);
        if (module != null){
            scope = GlobalSearchScope.moduleWithDependentsScope(module);
        }
        else{
            scope = GlobalSearchScope.projectScope(element.getProject());
        }

        PsiShortNamesCache cache = JavaPsiFacade.getInstance(element.getProject()).getShortNamesCache();

        String klassName = klass.getName();
        Pattern pattern = Pattern.compile(".*" + klassName + ".*");

        List<Pair<PsiClass, Integer>> classesWithProximities = new ArrayList<Pair<PsiClass, Integer>>();

        HashSet<String> names = new HashSet<String>();
        cache.getAllClassNames(names);
        for (String eachName : names){
            if (pattern.matcher(eachName).matches()){
                for (PsiClass eachClass : cache.getClassesByName(eachName, scope)){
                    if (TestUtil.isTestClass(eachClass)){
                        classesWithProximities.add(
                                new Pair<PsiClass, Integer>(eachClass, calcTestNameProximity(klassName, eachName)));
                    }
                }
            }
        }

        Collections.sort(classesWithProximities, new Comparator<Pair<PsiClass, Integer>>(){
            public int compare(Pair<PsiClass, Integer> o1, Pair<PsiClass, Integer> o2){
                int result = o1.second.compareTo(o2.second);
                if (result == 0){
                    result = o1.first.getName().compareTo(o2.first.getName());
                }
                return result;
            }
        });

        List<PsiElement> result = new ArrayList<PsiElement>();
        for (Pair<PsiClass, Integer> each : classesWithProximities){
            result.add(each.first);
        }

        return result;
    }

    private static Integer calcTestNameProximity(String klassName, String testName){
        int posProximity = testName.indexOf(klassName);
        int sizeProximity = testName.length() - klassName.length();

        return posProximity + sizeProximity;
    }

    @Nullable
    private static Module getModule(PsiElement element){
        ProjectFileIndex index = ProjectRootManager.getInstance(element.getProject()).getFileIndex();
        return index.getModuleForFile(element.getContainingFile().getVirtualFile());
    }

    public boolean isTest(@NotNull PsiElement element){
        return TestIntegrationUtils.isTest(element);
    }
}
TOP

Related Classes of com.johnlindquist.flexunit.ActionScriptTestFinder

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.