diff --git a/plugins/junit/src/META-INF/plugin.xml b/plugins/junit/src/META-INF/plugin.xml index a7fa2901f522..c9932f33b0d7 100644 --- a/plugins/junit/src/META-INF/plugin.xml +++ b/plugins/junit/src/META-INF/plugin.xml @@ -40,6 +40,7 @@ + diff --git a/plugins/junit/src/com/intellij/execution/junit/JUnit4Framework.java b/plugins/junit/src/com/intellij/execution/junit/JUnit4Framework.java index 30c271ebe6ed..fca7e28e5520 100644 --- a/plugins/junit/src/com/intellij/execution/junit/JUnit4Framework.java +++ b/plugins/junit/src/com/intellij/execution/junit/JUnit4Framework.java @@ -87,6 +87,12 @@ public class JUnit4Framework extends JavaTestFramework { @Override @Nullable protected PsiMethod findOrCreateSetUpMethod(PsiClass clazz) throws IncorrectOperationException { + String beforeClassAnnotationName = JUnitUtil.BEFORE_CLASS_ANNOTATION_NAME; + String beforeAnnotationName = JUnitUtil.BEFORE_ANNOTATION_NAME; + return findOrCreateSetUpMethod(clazz, beforeClassAnnotationName, beforeAnnotationName); + } + + private PsiMethod findOrCreateSetUpMethod(PsiClass clazz, String beforeClassAnnotationName, String beforeAnnotationName) { PsiMethod method = findSetUpMethod(clazz); if (method != null) return method; @@ -96,14 +102,14 @@ public class JUnit4Framework extends JavaTestFramework { method = createSetUpPatternMethod(factory); PsiMethod existingMethod = clazz.findMethodBySignature(method, false); if (existingMethod != null) { - if (AnnotationUtil.isAnnotated(existingMethod, JUnitUtil.BEFORE_CLASS_ANNOTATION_NAME, false)) return existingMethod; + if (AnnotationUtil.isAnnotated(existingMethod, beforeClassAnnotationName, false)) return existingMethod; int exit = ApplicationManager.getApplication().isUnitTestMode() ? Messages.OK : - Messages.showOkCancelDialog("Method setUp already exist but is not annotated as @Before. Annotate?", - CommonBundle.getWarningTitle(), - Messages.getWarningIcon()); + Messages.showOkCancelDialog("Method setUp already exist but is not annotated as @Before. Annotate?", + CommonBundle.getWarningTitle(), + Messages.getWarningIcon()); if (exit == Messages.OK) { - new AddAnnotationFix(JUnitUtil.BEFORE_ANNOTATION_NAME, existingMethod).invoke(existingMethod.getProject(), null, existingMethod.getContainingFile()); + new AddAnnotationFix(beforeAnnotationName, existingMethod).invoke(existingMethod.getProject(), null, existingMethod.getContainingFile()); return existingMethod; } } diff --git a/plugins/junit/src/com/intellij/execution/junit/JUnit5Framework.java b/plugins/junit/src/com/intellij/execution/junit/JUnit5Framework.java new file mode 100644 index 000000000000..11bb66a98f86 --- /dev/null +++ b/plugins/junit/src/com/intellij/execution/junit/JUnit5Framework.java @@ -0,0 +1,158 @@ +/* + * Copyright 2000-2016 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.execution.junit; + +import com.intellij.CommonBundle; +import com.intellij.codeInsight.AnnotationUtil; +import com.intellij.codeInsight.intention.AddAnnotationFix; +import com.intellij.execution.junit2.info.MethodLocation; +import com.intellij.icons.AllIcons; +import com.intellij.ide.fileTemplates.FileTemplateDescriptor; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.roots.ExternalLibraryDescriptor; +import com.intellij.openapi.ui.Messages; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; +import com.intellij.psi.util.PsiUtil; +import com.intellij.testIntegration.JavaTestFramework; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +public class JUnit5Framework extends JavaTestFramework { + @NotNull + public String getName() { + return "JUnit5"; + } + + @NotNull + @Override + public Icon getIcon() { + return AllIcons.RunConfigurations.Junit; + } + + protected String getMarkerClassFQName() { + return JUnitUtil.TEST5_ANNOTATION; + } + + @Nullable + @Override + public ExternalLibraryDescriptor getFrameworkLibraryDescriptor() { + return JUnitExternalLibraryDescriptor.JUNIT5; + } + + @Nullable + public String getDefaultSuperClass() { + return null; + } + + public boolean isTestClass(PsiClass clazz, boolean canBePotential) { + if (canBePotential) return isUnderTestSources(clazz); + return JUnitUtil.isJUnit4TestClass(clazz); + } + + @Nullable + @Override + protected PsiMethod findSetUpMethod(@NotNull PsiClass clazz) { + for (PsiMethod each : clazz.getMethods()) { + if (AnnotationUtil.isAnnotated(each, JUnitUtil.BEFORE_EACH_ANNOTATION_NAME, false)) return each; + } + return null; + } + + @Nullable + @Override + protected PsiMethod findTearDownMethod(@NotNull PsiClass clazz) { + for (PsiMethod each : clazz.getMethods()) { + if (AnnotationUtil.isAnnotated(each, JUnitUtil.AFTER_EACH_ANNOTATION_NAME, false)) return each; + } + return null; + } + + @Override + @Nullable + protected PsiMethod findOrCreateSetUpMethod(PsiClass clazz) throws IncorrectOperationException { + PsiMethod method = findSetUpMethod(clazz); + if (method != null) return method; + + PsiManager manager = clazz.getManager(); + PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); + + method = createSetUpPatternMethod(factory); + PsiMethod existingMethod = clazz.findMethodBySignature(method, false); + if (existingMethod != null) { + if (AnnotationUtil.isAnnotated(existingMethod, JUnitUtil.BEFORE_ALL_ANNOTATION_NAME, false)) return existingMethod; + int exit = ApplicationManager.getApplication().isUnitTestMode() ? + Messages.OK : + Messages.showOkCancelDialog("Method setUp already exist but is not annotated as @BeforeEach. Annotate?", + CommonBundle.getWarningTitle(), + Messages.getWarningIcon()); + if (exit == Messages.OK) { + new AddAnnotationFix(JUnitUtil.BEFORE_EACH_ANNOTATION_NAME, existingMethod).invoke(existingMethod.getProject(), null, existingMethod.getContainingFile()); + return existingMethod; + } + } + final PsiMethod testMethod = JUnitUtil.findFirstTestMethod(clazz); + if (testMethod != null) { + method = (PsiMethod)clazz.addBefore(method, testMethod); + } else { + method = (PsiMethod)clazz.add(method); + } + JavaCodeStyleManager.getInstance(manager.getProject()).shortenClassReferences(method); + + return method; + } + + @Override + public boolean isIgnoredMethod(PsiElement element) { + final PsiMethod testMethod = element instanceof PsiMethod ? JUnitUtil.getTestMethod(element) : null; + return testMethod != null && AnnotationUtil.isAnnotated(testMethod, JUnitUtil.IGNORE_ANNOTATION, false); + } + + @Override + public boolean isTestMethod(PsiElement element) { + return element instanceof PsiMethod && JUnitUtil.getTestMethod(element) != null; + } + + @Override + public boolean isTestMethod(PsiMethod method, PsiClass myClass) { + return JUnitUtil.isTestMethod(MethodLocation.elementInClass(method, myClass)); + } + + public FileTemplateDescriptor getSetUpMethodFileTemplateDescriptor() { + return new FileTemplateDescriptor("JUnit5 SetUp Method.java"); + } + + public FileTemplateDescriptor getTearDownMethodFileTemplateDescriptor() { + return new FileTemplateDescriptor("JUnit5 TearDown Method.java"); + } + + public FileTemplateDescriptor getTestMethodFileTemplateDescriptor() { + return new FileTemplateDescriptor("JUnit5 Test Method.java"); + } + + @Override + public char getMnemonic() { + return '5'; + } + + @Override + public FileTemplateDescriptor getTestClassFileTemplateDescriptor() { + return new FileTemplateDescriptor("JUnit5 Test Class.java"); + } +} diff --git a/plugins/junit/src/com/intellij/execution/junit/JUnitExternalLibraryDescriptor.java b/plugins/junit/src/com/intellij/execution/junit/JUnitExternalLibraryDescriptor.java index b1dd88b3c2e0..826415e10ac5 100644 --- a/plugins/junit/src/com/intellij/execution/junit/JUnitExternalLibraryDescriptor.java +++ b/plugins/junit/src/com/intellij/execution/junit/JUnitExternalLibraryDescriptor.java @@ -17,8 +17,11 @@ package com.intellij.execution.junit; import com.intellij.openapi.projectRoots.ex.JavaSdkUtil; import com.intellij.openapi.roots.ExternalLibraryDescriptor; +import com.intellij.util.PathUtil; +import com.intellij.util.ReflectionUtil; import org.jetbrains.annotations.NotNull; +import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -40,6 +43,14 @@ public abstract class JUnitExternalLibraryDescriptor extends ExternalLibraryDesc return JavaSdkUtil.getJUnit4JarPaths(); } }; + public static final ExternalLibraryDescriptor JUNIT5 = new ExternalLibraryDescriptor("org.junit.jupiter", "junit-jupiter-api", "5.0.0-M2", null) { + @NotNull + @Override + public List getLibraryClassesRoots() { + return Arrays.asList(PathUtil.getJarPathForClass(ReflectionUtil.forName("org.junit.jupiter.api.Test")), + PathUtil.getJarPathForClass(ReflectionUtil.forName("org.opentest4j.AssertionFailedError"))); + } + }; private final String myVersion; public JUnitExternalLibraryDescriptor(String version) { diff --git a/plugins/junit/src/fileTemplates/code/JUnit5 SetUp Method.java.ft b/plugins/junit/src/fileTemplates/code/JUnit5 SetUp Method.java.ft new file mode 100644 index 000000000000..2d190faed16e --- /dev/null +++ b/plugins/junit/src/fileTemplates/code/JUnit5 SetUp Method.java.ft @@ -0,0 +1,4 @@ +@org.junit.jupiter.api.BeforeEach +void setUp() { + ${BODY} +} \ No newline at end of file diff --git a/plugins/junit/src/fileTemplates/code/JUnit5 SetUp Method.java.html b/plugins/junit/src/fileTemplates/code/JUnit5 SetUp Method.java.html new file mode 100644 index 000000000000..ae3fe6f96b86 --- /dev/null +++ b/plugins/junit/src/fileTemplates/code/JUnit5 SetUp Method.java.html @@ -0,0 +1,26 @@ + + + + + + +
+ This is a template used to create a setUp method in a JUnit 5 test class. +
+ + + + + + + + + + + + + + +
Predefined variables will take the following values:
${NAME} name of the created method.
${BODY} generated method body.
+ + \ No newline at end of file diff --git a/plugins/junit/src/fileTemplates/code/JUnit5 TearDown Method.java.ft b/plugins/junit/src/fileTemplates/code/JUnit5 TearDown Method.java.ft new file mode 100644 index 000000000000..2427c42d8c11 --- /dev/null +++ b/plugins/junit/src/fileTemplates/code/JUnit5 TearDown Method.java.ft @@ -0,0 +1,4 @@ +@org.junit.jupiter.api.AfterEach +void tearDown() { + ${BODY} +} \ No newline at end of file diff --git a/plugins/junit/src/fileTemplates/code/JUnit5 TearDown Method.java.html b/plugins/junit/src/fileTemplates/code/JUnit5 TearDown Method.java.html new file mode 100644 index 000000000000..997de8b9b793 --- /dev/null +++ b/plugins/junit/src/fileTemplates/code/JUnit5 TearDown Method.java.html @@ -0,0 +1,26 @@ + + + + + + +
+ This is a template used to create a tearDown method in a JUnit 5 test class. +
+ + + + + + + + + + + + + + +
Predefined variables will take the following values:
${NAME} name of the created method.
${BODY} generated method body.
+ + \ No newline at end of file diff --git a/plugins/junit/src/fileTemplates/code/JUnit5 Test Class.java.ft b/plugins/junit/src/fileTemplates/code/JUnit5 Test Class.java.ft new file mode 100644 index 000000000000..5d644a003cb4 --- /dev/null +++ b/plugins/junit/src/fileTemplates/code/JUnit5 Test Class.java.ft @@ -0,0 +1,5 @@ +import static org.junit.jupiter.api.Assertions.*; +#parse("File Header.java") +class ${NAME} { + ${BODY} +} \ No newline at end of file diff --git a/plugins/junit/src/fileTemplates/code/JUnit5 Test Class.java.html b/plugins/junit/src/fileTemplates/code/JUnit5 Test Class.java.html new file mode 100644 index 000000000000..bfefdbb0a539 --- /dev/null +++ b/plugins/junit/src/fileTemplates/code/JUnit5 Test Class.java.html @@ -0,0 +1,31 @@ + + + + + + +
+ This is a template used to create JUnit 5 test class. +
+ + + + + + + + + + + + + + + + + + + +
Predefined variables will take the following values:
${NAME} name of the created class.
${CLASS_NAME} name of the tested class.
${BODY} generated class body.
+ + \ No newline at end of file diff --git a/plugins/junit/src/fileTemplates/code/JUnit5 Test Method.java.ft b/plugins/junit/src/fileTemplates/code/JUnit5 Test Method.java.ft new file mode 100644 index 000000000000..b2491497aef4 --- /dev/null +++ b/plugins/junit/src/fileTemplates/code/JUnit5 Test Method.java.ft @@ -0,0 +1,4 @@ +@org.junit.jupiter.api.Test +void ${NAME}() { + ${BODY} +} \ No newline at end of file diff --git a/plugins/junit/src/fileTemplates/code/JUnit5 Test Method.java.html b/plugins/junit/src/fileTemplates/code/JUnit5 Test Method.java.html new file mode 100644 index 000000000000..0864c0954200 --- /dev/null +++ b/plugins/junit/src/fileTemplates/code/JUnit5 Test Method.java.html @@ -0,0 +1,26 @@ + + + + + + +
+ This is a template used to create a test method in a JUnit 5 test class. +
+ + + + + + + + + + + + + + +
Predefined variables will take the following values:
${NAME} name of the created method.
${BODY} generated method body.
+ + \ No newline at end of file