mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-05 01:50:56 +07:00
IdeaTestAssistant initial version
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2000-2010 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.intellij.testFramework;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Specifies the path to testdata for the current test case class.
|
||||
* May use the variable $CONTENT_ROOT to specify the module content root.
|
||||
*
|
||||
* @author yole
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@Target({ElementType.TYPE})
|
||||
public @interface TestDataPath {
|
||||
String value();
|
||||
}
|
||||
@@ -363,6 +363,10 @@ public abstract class UsefulTestCase extends TestCase {
|
||||
if (StringUtil.isEmpty(name)) {
|
||||
return "";
|
||||
}
|
||||
return getTestName(name, lowercaseFirstLetter);
|
||||
}
|
||||
|
||||
public static String getTestName(String name, boolean lowercaseFirstLetter) {
|
||||
if (lowercaseFirstLetter && !isAllUppercaseName(name)) {
|
||||
name = Character.toLowerCase(name.charAt(0)) + name.substring(1);
|
||||
}
|
||||
|
||||
13
plugins/IdeaTestAssistant/IdeaTestAssistant.iml
Normal file
13
plugins/IdeaTestAssistant/IdeaTestAssistant.iml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="openapi" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
13
plugins/IdeaTestAssistant/layout.xml
Normal file
13
plugins/IdeaTestAssistant/layout.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<project name="Layout IdeaTestAssistant plugin distribution" default="layout">
|
||||
<target name="layout">
|
||||
<layout todir="${deploy}/plugins" xmlns="antlib:jetbrains.antlayout">
|
||||
<dir name="IdeaTestAssistant">
|
||||
<dir name="lib">
|
||||
<jar name="IdeaTestAssistant.jar">
|
||||
<module name="IdeaTestAssistant"/>
|
||||
</jar>
|
||||
</dir>
|
||||
</dir>
|
||||
</layout>
|
||||
</target>
|
||||
</project>
|
||||
15
plugins/IdeaTestAssistant/src/META-INF/plugin.xml
Normal file
15
plugins/IdeaTestAssistant/src/META-INF/plugin.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<idea-plugin>
|
||||
<id>com.intellij.testAssistant</id>
|
||||
<name>IDEA Test Assistant</name>
|
||||
<description>Assists in writing and maintaining tests for IntelliJ IDEA's code</description>
|
||||
<version>1.0.0</version>
|
||||
<vendor url="http://www.jetbrains.com" logo="/general/ijLogo.png">JetBrains</vendor>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<codeInsight.lineMarkerProvider language="JAVA" implementationClass="com.intellij.testAssistant.TestDataLineMarkerProvider"/>
|
||||
</extensions>
|
||||
|
||||
<actions>
|
||||
</actions>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
package com.intellij.testAssistant;
|
||||
|
||||
import com.intellij.codeHighlighting.Pass;
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.daemon.GutterIconNavigationHandler;
|
||||
import com.intellij.codeInsight.daemon.LineMarkerInfo;
|
||||
import com.intellij.codeInsight.daemon.LineMarkerProvider;
|
||||
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
import com.intellij.ui.ColoredListCellRenderer;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import com.intellij.util.Icons;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class TestDataLineMarkerProvider implements LineMarkerProvider {
|
||||
public LineMarkerInfo getLineMarkerInfo(PsiElement element) {
|
||||
if (!(element instanceof PsiMethod)) {
|
||||
return null;
|
||||
}
|
||||
final PsiMethod method = (PsiMethod)element;
|
||||
String name = method.getName();
|
||||
if (!name.startsWith("test")) {
|
||||
return null;
|
||||
}
|
||||
String testDataPath = getTestDataBasePath(method.getContainingClass());
|
||||
if (testDataPath != null) {
|
||||
List<String> fileNames = collectTestDataReferences(method, testDataPath, name.substring(4));
|
||||
if (fileNames.size() > 0) {
|
||||
return new LineMarkerInfo<PsiMethod>(method, method.getTextOffset(), Icons.TEST_SOURCE_FOLDER, Pass.UPDATE_ALL, null,
|
||||
new TestDataNavigationHandler(fileNames));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void collectSlowLineMarkers(List<PsiElement> elements, Collection<LineMarkerInfo> result) {
|
||||
}
|
||||
|
||||
private static List<String> collectTestDataReferences(final PsiMethod method, final String testDataPath, final String testName) {
|
||||
final List<String> result = new ArrayList<String>();
|
||||
method.accept(new JavaRecursiveElementVisitor() {
|
||||
@Override
|
||||
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
|
||||
String callText = expression.getMethodExpression().getText();
|
||||
if (callText.equals("configureByFile") || callText.equals("checkResultByFile")) {
|
||||
final PsiExpression[] arguments = expression.getArgumentList().getExpressions();
|
||||
if (arguments.length == 1) {
|
||||
String testDataFile = getReferencedFile(arguments [0], testName);
|
||||
if (testDataFile != null) {
|
||||
result.add(testDataPath + testDataFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (callText.startsWith("do") && callText.endsWith("Test")) {
|
||||
final PsiMethod doTestMethod = expression.resolveMethod();
|
||||
if (doTestMethod != null) {
|
||||
result.addAll(collectTestDataReferences(doTestMethod, testDataPath, testName));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getTestDataBasePath(PsiClass psiClass) {
|
||||
final PsiAnnotation annotation = AnnotationUtil.findAnnotationInHierarchy(psiClass, Collections.singleton("com.intellij.testFramework.TestDataPath"));
|
||||
if (annotation != null) {
|
||||
final PsiAnnotationMemberValue value = annotation.findAttributeValue(PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME);
|
||||
if (value instanceof PsiExpression) {
|
||||
final PsiConstantEvaluationHelper evaluationHelper = JavaPsiFacade.getInstance(value.getProject()).getConstantEvaluationHelper();
|
||||
final Object constantValue = evaluationHelper.computeConstantExpression(value, false);
|
||||
if (constantValue instanceof String) {
|
||||
String path = (String) constantValue;
|
||||
if (path.indexOf("$CONTENT_ROOT") >= 0) {
|
||||
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(psiClass.getProject()).getFileIndex();
|
||||
final VirtualFile contentRoot = fileIndex.getContentRootForFile(psiClass.getContainingFile().getVirtualFile());
|
||||
if (contentRoot == null) return null;
|
||||
path = path.replace("$CONTENT_ROOT", contentRoot.getPath());
|
||||
}
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getReferencedFile(PsiExpression expression, String testName) {
|
||||
if (expression instanceof PsiBinaryExpression) {
|
||||
PsiBinaryExpression binaryExpression = (PsiBinaryExpression)expression;
|
||||
if (binaryExpression.getOperationTokenType() == JavaTokenType.PLUS) {
|
||||
String lhs = getReferencedFile(binaryExpression.getLOperand(), testName);
|
||||
String rhs = getReferencedFile(binaryExpression.getROperand(), testName);
|
||||
if (lhs != null && rhs != null) {
|
||||
return lhs + rhs;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (expression instanceof PsiLiteralExpression) {
|
||||
final Object value = ((PsiLiteralExpression)expression).getValue();
|
||||
if (value instanceof String) {
|
||||
return (String) value;
|
||||
}
|
||||
}
|
||||
else if (expression instanceof PsiReferenceExpression) {
|
||||
final PsiElement result = ((PsiReferenceExpression)expression).resolve();
|
||||
if (result instanceof PsiVariable) {
|
||||
final PsiExpression initializer = ((PsiVariable)result).getInitializer();
|
||||
if (initializer != null) {
|
||||
return getReferencedFile(initializer, testName);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if (expression instanceof PsiMethodCallExpression) {
|
||||
final PsiMethodCallExpression methodCall = (PsiMethodCallExpression)expression;
|
||||
final String callText = methodCall.getMethodExpression().getText();
|
||||
if (callText.equals("getTestName")) {
|
||||
final PsiExpression[] psiExpressions = methodCall.getArgumentList().getExpressions();
|
||||
if (psiExpressions.length == 1) {
|
||||
if (psiExpressions[0].getText().equals("true")) {
|
||||
return UsefulTestCase.getTestName(testName, true);
|
||||
}
|
||||
return testName;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class TestDataNavigationHandler implements GutterIconNavigationHandler<PsiMethod> {
|
||||
private List<String> myFileNames;
|
||||
|
||||
public TestDataNavigationHandler(List<String> fileNames) {
|
||||
myFileNames = fileNames;
|
||||
}
|
||||
|
||||
public void navigate(MouseEvent e, final PsiMethod elt) {
|
||||
if (myFileNames.size() == 1) {
|
||||
openFileByIndex(elt.getProject(), 0);
|
||||
}
|
||||
else {
|
||||
List<String> shortNames = new ArrayList<String>();
|
||||
for (String fileName : myFileNames) {
|
||||
shortNames.add(new File(fileName).getName());
|
||||
}
|
||||
final JList list = new JList(shortNames.toArray(new String[shortNames.size()]));
|
||||
list.setCellRenderer(new ColoredListCellRenderer() {
|
||||
@Override
|
||||
protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
|
||||
String fileName = (String) value;
|
||||
final FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(fileName);
|
||||
setIcon(fileType.getIcon());
|
||||
append(fileName);
|
||||
}
|
||||
});
|
||||
PopupChooserBuilder builder = new PopupChooserBuilder(list);
|
||||
builder.setItemChoosenCallback(new Runnable() {
|
||||
public void run() {
|
||||
final int[] indices = list.getSelectedIndices();
|
||||
for (int index : indices) {
|
||||
openFileByIndex(elt.getProject(), index);
|
||||
}
|
||||
}
|
||||
}).createPopup().show(new RelativePoint(e));
|
||||
}
|
||||
}
|
||||
|
||||
private void openFileByIndex(final Project project, final int index) {
|
||||
final VirtualFile file = LocalFileSystem.getInstance().findFileByPath(myFileNames.get(index));
|
||||
if (file != null) {
|
||||
new OpenFileDescriptor(project, file).navigate(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user