[jvm] Convert TestCaseWithNoTestMethods inspection to JVM

#IDEA-331938 Fixed

GitOrigin-RevId: 9ecdc3d6e03d52cb54865067483b4c97e29d3236
This commit is contained in:
Bart van Helvert
2023-09-08 13:43:23 +02:00
committed by intellij-monorepo-bot
parent 6a706d72a4
commit cc61bc25c7
16 changed files with 297 additions and 292 deletions

View File

@@ -823,7 +823,6 @@ continue.or.break.from.finally.block.display.name='continue' or 'break' inside '
abstract.method.with.missing.implementations.display.name=Abstract method with missing implementations
object.allocation.in.loop.display.name=Object allocation in loop
wait.called.on.condition.display.name='wait()' called on 'java.util.concurrent.locks.Condition' object
test.case.with.no.test.methods.display.name=Test class with no tests
abstract.class.never.implemented.display.name=Abstract class which has no concrete subclass
interface.never.implemented.display.name=Interface which has no concrete subclass
constant.declared.in.interface.display.name=Constant declared in interface
@@ -1070,7 +1069,6 @@ assert.without.message.problem.descriptor=<code>#ref()</code> without message #l
assert.without.message.quick.fix.family.name=Add error message
misordered.assert.equals.arguments.problem.descriptor=Arguments to <code>#ref()</code> in wrong order #loc
simplifiable.junit.assertion.problem.descriptor=<code>#ref()</code> can be simplified to ''{0}'' #loc
test.case.with.no.test.methods.problem.descriptor=Test class <code>#ref</code> has no tests #loc
deserializable.class.in.secure.context.problem.descriptor=Class <code>#ref</code> may be deserialized, compromising security #loc
serializable.class.in.secure.context.problem.descriptor=Class <code>#ref</code> may be serialized, compromising security #loc
serializable.deserializable.class.in.secure.context.problem.descriptor=Class <code>#ref</code> may be serialized and deserialized, compromising security #loc
@@ -1799,7 +1797,6 @@ boxing.boxed.value.quickfix=Remove unnecessary boxing
unnecessary.javadoc.link.option=Ignore inline links to super methods
constant.junit.assert.argument.display.name=Constant assert argument
constant.junit.assert.argument.problem.descriptor=Argument <code>#ref</code> is constant #loc
test.case.with.no.test.methods.option=Ignore test cases which have superclasses with test methods
package.dot.html.may.be.package.info.display.name='package.html' may be converted to 'package-info.java'
package.dot.html.may.be.package.info.exists.problem.descriptor=<code>package.html</code> is ignored because <code>package-info.java</code> exists
package.dot.html.may.be.package.info.problem.descriptor=<code>package.html</code> may be converted to <code>package-info.java</code>

View File

@@ -1400,10 +1400,6 @@
groupKey="group.names.test.frameworks.issues" enabledByDefault="true" level="WARNING"
implementationClass="com.siyeh.ig.testFrameworks.SimplifiableAssertionInspection" cleanupTool="true"/>
<inspectionElementsMerger implementation="com.siyeh.ig.testFrameworks.SimplifiableAssertionMerger"/>
<localInspection groupPath="Java" language="JAVA" suppressId="JUnitTestCaseWithNoTests" shortName="TestCaseWithNoTestMethods" bundle="messages.InspectionGadgetsBundle"
key="test.case.with.no.test.methods.display.name" groupBundle="messages.InspectionsBundle"
groupKey="group.names.junit.issues" enabledByDefault="false" level="WARNING"
implementationClass="com.siyeh.ig.junit.TestCaseWithNoTestMethodsInspection"/>
<localInspection groupPath="Java" language="JAVA" shortName="UseOfObsoleteAssert" bundle="messages.InspectionGadgetsBundle" key="usage.of.obsolete.assert.display.name"
groupBundle="messages.InspectionsBundle" groupKey="group.names.junit.issues" enabledByDefault="false" level="WARNING"
implementationClass="com.siyeh.ig.junit.UseOfObsoleteAssertInspection" cleanupTool="true"/>

View File

@@ -1,148 +0,0 @@
/*
* Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
*
* 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.siyeh.ig.junit;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.TestFrameworks;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.options.OptPane;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.util.PsiUtil;
import com.intellij.testIntegration.JavaTestFramework;
import com.intellij.testIntegration.TestFramework;
import com.intellij.util.containers.ContainerUtil;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.fixes.ChangeModifierFix;
import org.intellij.lang.annotations.Pattern;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
import java.util.stream.Collectors;
import static com.intellij.codeInspection.options.OptPane.checkbox;
import static com.intellij.codeInspection.options.OptPane.pane;
public class TestCaseWithNoTestMethodsInspection extends BaseInspection {
@SuppressWarnings("PublicField")
public boolean ignoreSupers = true;
@Pattern(VALID_ID_PATTERN)
@Override
@NotNull
public String getID() {
return "JUnitTestCaseWithNoTests";
}
@Override
@NotNull
protected String buildErrorString(Object... infos) {
return InspectionGadgetsBundle.message(
"test.case.with.no.test.methods.problem.descriptor");
}
@Override
protected @Nullable LocalQuickFix buildFix(Object... infos) {
return (Boolean)infos[0] ? new ChangeModifierFix(PsiModifier.ABSTRACT) : null;
}
@Override
public @NotNull OptPane getOptionsPane() {
return pane(
checkbox("ignoreSupers", InspectionGadgetsBundle.message(
"test.case.with.no.test.methods.option")));
}
@Override
public BaseInspectionVisitor buildVisitor() {
return new TestCaseWithNoTestMethodsVisitor();
}
private class TestCaseWithNoTestMethodsVisitor extends BaseInspectionVisitor {
@Override
public void visitClass(@NotNull PsiClass aClass) {
if (aClass.isInterface()
|| aClass.isEnum()
|| aClass.isAnnotationType()
|| PsiUtil.isLocalOrAnonymousClass(aClass)
|| aClass.hasModifierProperty(PsiModifier.ABSTRACT)
|| AnnotationUtil.isAnnotated(aClass, JUnitCommonClassNames.ORG_JUNIT_IGNORE, 0)) {
return;
}
if (aClass instanceof PsiTypeParameter) {
return;
}
Set<TestFramework> applicableFrameworks = TestFrameworks.detectApplicableFrameworks(aClass);
if (applicableFrameworks.isEmpty()) {
return;
}
Set<TestFramework> applicableToNestedClasses = applicableFrameworks.stream()
.filter(framework -> framework instanceof JavaTestFramework && ((JavaTestFramework)framework).acceptNestedClasses())
.collect(Collectors.toSet());
if (hasTestMethods(aClass, applicableFrameworks, applicableToNestedClasses, true)) {
return;
}
if (ignoreSupers) {
PsiManager manager = aClass.getManager();
PsiClass superClass = aClass.getSuperClass();
while (superClass != null && manager.isInProject(superClass)) {
if (hasTestMethods(superClass, applicableFrameworks, applicableToNestedClasses, false)) {
return;
}
superClass = superClass.getSuperClass();
}
}
registerClassError(aClass, ClassInheritorsSearch.search(aClass, aClass.getUseScope(), false).findFirst() != null);
}
private static boolean hasTestMethods(@NotNull PsiClass aClass,
Set<TestFramework> selfFrameworks,
Set<TestFramework> nestedTestFrameworks,
boolean checkSuite) {
PsiMethod[] methods = aClass.getMethods();
for (TestFramework framework : selfFrameworks) {
if (checkSuite && framework instanceof JavaTestFramework && ((JavaTestFramework)framework).isSuiteClass(aClass)) {
return true;
}
if (ContainerUtil.exists(methods, method -> framework.isTestMethod(method, false))) {
return true;
}
}
if (!nestedTestFrameworks.isEmpty()) {
for (PsiClass innerClass : aClass.getInnerClasses()) {
if (!innerClass.hasModifierProperty(PsiModifier.STATIC) &&
hasTestMethods(innerClass, nestedTestFrameworks, nestedTestFrameworks, false)) {
return true;
}
}
}
return false;
}
}
}

View File

@@ -1,20 +0,0 @@
<html>
<body>
Reports non-<code>abstract</code> test cases without any test methods.
<p>Such test cases usually indicate unfinished code
or could be a refactoring leftover that should be removed.</p>
<p>Example:</p>
<pre><code>
<b>public class</b> CrucialTest {
@Before
<b>public void</b> setUp() {
System.out.println("setting up");
}
}
</code></pre>
<!-- tooltip end -->
<p>Use the <b>Ignore test cases which have superclasses with test methods</b> option to ignore test cases which have super classes
with test methods.<p>
</body>
</html>

View File

@@ -1,55 +0,0 @@
public class <warning descr="Test class 'TestCaseWithNoTestMethods' has no tests">TestCaseWithNoTestMethods</warning> extends junit.framework.TestCase {
public int testOne() {
return 1;
}
public static void testTwo() {}
void testThree() {}
public void testFour(int i) {}
public void setUp() throws Exception {
super.setUp();
}
public void tearDown() throws Exception {
super.tearDown();
}
}
abstract class AbstractTest extends junit.framework.TestCase {
public void testInAbstract() {}
}
class MyImplTest extends AbstractTest {}
class MyImplImplTest extends MyImplTest {}
class NotATestClass {}
class MySuite {
public static junit.framework.Test suite() {
return null;
}
}
<error descr="Class 'TestCaseWithInner' is public, should be declared in a file named 'TestCaseWithInner.java'">public class <warning descr="Test class 'TestCaseWithInner' has no tests">TestCaseWithInner</warning> extends junit.framework.TestCase</error> {
public static class Inner extends junit.framework.TestCase {
public void test1() {}
}
}
class Test5WithInner {
@org.junit.jupiter.api.Nested
class Inner {
@org.junit.jupiter.api.Test
void test1() {}
}
}
class <warning descr="Test class 'Test5WithInner1' has no tests">Test5WithInner1</warning> {
@org.junit.jupiter.api.Nested
class <warning descr="Test class 'Inner' has no tests">Inner</warning> {
void test1() {}
}
}
@org.junit.Ignore
class IgnoredTest extends junit.framework.TestCase {}

View File

@@ -1,11 +0,0 @@
<error descr="Class 'SomeTest' is public, should be declared in a file named 'SomeTest.java'">public class SomeTest extends SomeParentClass</error> {
public SomeTest() {
super("");
}
}
<error descr="Class 'SomeParentClass' is public, should be declared in a file named 'SomeParentClass.java'">public class SomeParentClass extends junit.framework.TestCase</error> {
protected SomeParentClass(String name) {}
public void testInParent() {}
}

View File

@@ -1,50 +0,0 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.siyeh.ig.junit;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.siyeh.ig.LightJavaInspectionTestCase;
import org.jetbrains.annotations.Nullable;
/**
* @author Bas Leijdekkers
*/
public class TestCaseWithNoTestMethodsInspectionTest extends LightJavaInspectionTestCase {
public void testTestCaseWithNoTestMethods() { doTest(); }
public void testTestCaseWithTestMethods() { doTest(); }
@Nullable
@Override
protected InspectionProfileEntry getInspection() {
TestCaseWithNoTestMethodsInspection inspection = new TestCaseWithNoTestMethodsInspection();
inspection.ignoreSupers = true;
return inspection;
}
@Override
protected String[] getEnvironmentClasses() {
return new String[] {
"package junit.framework;" +
"public abstract class TestCase {" +
" protected void setUp() throws Exception {}" +
" protected void tearDown() throws Exception {}" +
"}",
"""
package junit.framework;
public interface Test {
int countTestCases();
void run(TestResult result);
}""",
"package org.junit; public @interface Ignore {}",
"package org.junit.jupiter.api;" +
"import org.junit.platform.commons.annotation.Testable;" +
"@Testable\n" +
"public @interface Test {}",
"package org.junit.jupiter.api;" +
"public @interface Nested {}",
"package org.junit.platform.commons.annotation;" +
"public @interface Testable {}"
};
}
}

View File

@@ -29,6 +29,12 @@
groupPathKey="jvm.inspections.group.name" groupKey="jvm.inspections.test.frameworks.group.name"
key="jvm.inspections.test.method.without.assertion.display.name"
implementationClass="com.intellij.codeInspection.test.TestMethodWithoutAssertionInspection"/>
<localInspection language="UAST" enabledByDefault="false" level="WARNING" shortName="TestCaseWithNoTestMethods"
suppressId="JUnitTestCaseWithNoTests"
groupBundle="messages.JvmAnalysisBundle" bundle="messages.JvmAnalysisBundle"
groupPathKey="jvm.inspections.group.name" groupKey="jvm.inspections.test.frameworks.group.name"
key="jvm.inspections.test.case.without.test.methods.display.name"
implementationClass="com.intellij.codeInspection.test.TestCaseWithoutTestsInspection"/>
<localInspection language="UAST" enabledByDefault="false" level="WARNING" shortName="TestCaseWithConstructor"
suppressId="JUnitTestCaseWithNonTrivialConstructors"
groupBundle="messages.JvmAnalysisBundle" bundle="messages.JvmAnalysisBundle"

View File

@@ -0,0 +1,20 @@
<html>
<body>
Reports non-<code>abstract</code> test cases without any test methods. Such test cases usually indicate unfinished code or could be a
refactoring leftover that should be removed.
<p>Example:</p>
<pre><code>
public class CrucialTest {
@Before
public void setUp() {
System.out.println("setting up");
}
}
</code></pre>
<!-- tooltip end -->
<p>
Use the <b>Ignore test cases which have superclasses with test methods</b> option to ignore test cases which have super classes
with test methods.
<p>
</body>
</html>

View File

@@ -133,6 +133,11 @@ jvm.inspections.testonly.visiblefortesting=@VisibleForTesting makes little sense
jvm.inspections.test.method.without.assertion.display.name=Test method without assertions
jvm.inspections.test.method.without.assertion.problem.descriptor=Test method <code>#ref()</code> contains no assertions #loc
jvm.inspections.test.case.without.test.methods.display.name=Test class without tests
jvm.inspections.test.case.without.test.methods.option=Ignore test cases which have superclasses with test methods
jvm.inspections.test.case.without.test.methods.problem.descriptor=Test class <code>#ref</code> has no tests #loc
jvm.inspections.test.case.with.constructor.display.name=TestCase with non-trivial constructors
jvm.inspections.test.case.with.constructor.problem.descriptor=Initialization logic in constructor <code>#ref()</code> instead of 'setup()' life cycle method #loc
jvm.inspections.test.case.with.constructor.problem.descriptor.initializer=Initialization logic in initializer instead of 'setup()' life cycle method

View File

@@ -0,0 +1,93 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.test
import com.intellij.analysis.JvmAnalysisBundle
import com.intellij.codeInsight.TestFrameworks
import com.intellij.codeInspection.options.OptPane
import com.intellij.lang.jvm.DefaultJvmElementVisitor
import com.intellij.lang.jvm.JvmClass
import com.intellij.lang.jvm.JvmElementVisitor
import com.intellij.lang.jvm.JvmModifier
import com.intellij.lang.jvm.inspection.JvmLocalInspection
import com.intellij.openapi.project.Project
import com.intellij.psi.*
import com.intellij.psi.search.searches.ClassInheritorsSearch
import com.intellij.psi.util.PsiUtil
import com.intellij.testIntegration.JavaTestFramework
import com.intellij.testIntegration.TestFramework
import com.siyeh.ig.junit.JUnitCommonClassNames
class TestCaseWithoutTestsInspection : JvmLocalInspection() {
@JvmField
var ignoreSupers = true
override fun getOptionsPane() = OptPane.pane(OptPane.checkbox(
"ignoreSupers",
JvmAnalysisBundle.message("jvm.inspections.test.case.without.test.methods.option")
))
override fun buildVisitor(project: Project, sink: HighlightSink, isOnTheFly: Boolean): JvmElementVisitor<Boolean> {
return TestCaseWithoutTestsVisitor(sink, ignoreSupers)
}
}
private class TestCaseWithoutTestsVisitor(
private val sink: JvmLocalInspection.HighlightSink,
private val ignoreSupers: Boolean
) : DefaultJvmElementVisitor<Boolean> {
override fun visitClass(clazz: JvmClass): Boolean? {
if (clazz !is PsiClass) return true
if (clazz is PsiTypeParameter) return true
if (clazz.isEnum || clazz.isAnnotationType || clazz.isInterface || PsiUtil.isLocalOrAnonymousClass(clazz)) return true
if (clazz.hasModifier(JvmModifier.ABSTRACT)) return true
if (clazz.hasAnnotation(JUnitCommonClassNames.ORG_JUNIT_IGNORE)) return true
val applicableFrameworks = TestFrameworks.detectApplicableFrameworks(clazz)
if (applicableFrameworks.isEmpty()) return true
val applicableToNestedClasses = applicableFrameworks
.filter { framework -> framework is JavaTestFramework && framework.acceptNestedClasses() }
.toSet()
if (hasTestMethods(clazz, applicableFrameworks, applicableToNestedClasses, true)) return true
if (ignoreSupers) {
var superClass = clazz.getSuperClass()
while (superClass != null && clazz.getManager().isInProject(superClass)) {
if (hasTestMethods(superClass, applicableFrameworks, applicableToNestedClasses, false)) return true
superClass = superClass.getSuperClass()
}
}
sink.highlight(JvmAnalysisBundle.message(
"jvm.inspections.test.case.without.test.methods.problem.descriptor",
ClassInheritorsSearch.search(clazz, clazz.getUseScope(), false).findFirst() != null
))
return true
}
private fun hasTestMethods(
aClass: PsiClass,
selfFrameworks: Set<TestFramework>,
nestedTestFrameworks: Set<TestFramework>,
checkSuite: Boolean
): Boolean {
val methods = aClass.getMethods()
for (framework in selfFrameworks) {
if (checkSuite && framework is JavaTestFramework && framework.isSuiteClass(aClass)) return true
if (methods.any { method ->
framework.isTestMethod(method)
}) return true
}
if (!nestedTestFrameworks.isEmpty()) {
for (innerClass in aClass.getInnerClasses()) {
if (!innerClass.hasModifierProperty(PsiModifier.STATIC)
&& hasTestMethods(innerClass, nestedTestFrameworks, nestedTestFrameworks, false)
) return true
}
}
return false
}
}

View File

@@ -0,0 +1,74 @@
package com.intellij.codeInspection.tests.java.test
import com.intellij.codeInspection.tests.JvmLanguage
import com.intellij.codeInspection.tests.test.TestCaseWithoutTestsInspectionTestBase
class JavaTestCaseWithoutTestsInspectionTest : TestCaseWithoutTestsInspectionTestBase() {
fun `test case without test methods`() {
myFixture.testHighlighting(JvmLanguage.JAVA, """
public class <warning descr="Test class 'TestCaseWithNoTestMethods' has no tests">TestCaseWithNoTestMethods</warning> extends junit.framework.TestCase {
public void setUp() throws Exception {
super.setUp();
}
public void tearDown() throws Exception {
super.tearDown();
}
public int testOne() {
return 1;
}
public static void testTwo() { }
void testThree() {}
public void testFour(int i) { }
}
""".trimIndent(), fileName = "TestCaseWithNoTestMethods")
}
fun `test case with JUnit 3 inner class without test methods`() {
myFixture.testHighlighting(JvmLanguage.JAVA, """
public class <warning descr="Test class 'TestCaseWithInner' has no tests">TestCaseWithInner</warning> extends junit.framework.TestCase {
public static class Inner extends junit.framework.TestCase {
public void test1() { }
}
}
""".trimIndent(), fileName = "TestCaseWithInner")
}
fun `test case with JUnit 5 nested class without test methods`() {
myFixture.testHighlighting(JvmLanguage.JAVA, """
public class <warning descr="Test class 'TestCaseWithInner' has no tests">TestCaseWithInner</warning> {
@org.junit.jupiter.api.Nested
class <warning descr="Test class 'Inner' has no tests">Inner</warning> {
void test1() {}
}
}
""".trimIndent(), "TestCaseWithInner")
}
fun `test case without test methods but class is ignored`() {
myFixture.testHighlighting(JvmLanguage.JAVA, """
@org.junit.Ignore
public class IgnoredTest extends junit.framework.TestCase {}
""".trimIndent(), "IgnoredTest")
}
fun `test case with test in parent class`() {
myFixture.addClass("""
public class SomeParentClass extends junit.framework.TestCase {
protected SomeParentClass(String name) {}
public void testInParent() {}
}
""".trimIndent())
myFixture.testHighlighting(JvmLanguage.JAVA, """
public class SomeTestClass extends SomeParentClass {
public SomeTestClass() {
super("");
}
}
""".trimIndent(), "SomeTestClass")
}
}

View File

@@ -0,0 +1,68 @@
package com.intellij.codeInspection.tests.kotlin.test
import com.intellij.codeInspection.tests.JvmLanguage
import com.intellij.codeInspection.tests.test.TestCaseWithoutTestsInspectionTestBase
class KotlinTestCaseWithoutTestsInspectionTest : TestCaseWithoutTestsInspectionTestBase() {
// Wait for KotlinJUnit framework to be fixed
fun `_test case without test methods`() {
myFixture.testHighlighting(JvmLanguage.KOTLIN, """
class <warning descr="Test class 'TestCaseWithNoTestMethods' has no tests">TestCaseWithNoTestMethods</warning> : junit.framework.TestCase() {
override fun setUp() {
super.setUp()
}
override fun tearDown() {
super.tearDown()
}
fun testOne(): Int {
return 1
}
fun testThree() {}
fun testFour(i: Int) { i + 1 }
}
""".trimIndent(), fileName = "TestCaseWithNoTestMethods")
}
fun `test case with JUnit 3 inner class without test methods`() {
myFixture.testHighlighting(JvmLanguage.KOTLIN, """
class <warning descr="Test class 'TestCaseWithInner' has no tests">TestCaseWithInner</warning> : junit.framework.TestCase() {
class Inner : junit.framework.TestCase() {
fun test1() {}
}
}
""".trimIndent(), fileName = "TestCaseWithInner")
}
// Wait for KotlinJUnit framework to be fixed
fun `_test case with JUnit 5 nested class without test methods`() {
myFixture.testHighlighting(JvmLanguage.KOTLIN, """
class <warning descr="Test class 'TestCaseWithInner' has no tests">TestCaseWithInner</warning> {
@org.junit.jupiter.api.Nested
class <warning descr="Test class 'Inner' has no tests">Inner</warning> {
fun test1() { }
}
}
""".trimIndent(), "TestCaseWithInner")
}
fun `test case without test methods but class is ignored`() {
myFixture.testHighlighting(JvmLanguage.KOTLIN, """
@org.junit.Ignore
class IgnoredTest : junit.framework.TestCase() { }
""".trimIndent(), "IgnoredTest")
}
fun `test case with test in parent class`() {
myFixture.testHighlighting(JvmLanguage.KOTLIN, """
open class SomeParentClass(val name: String) : junit.framework.TestCase() {
fun testInParent() { }
}
class SomeTestClass : SomeParentClass("") { }
""".trimIndent(), "SomeTestClass")
}
}

View File

@@ -0,0 +1,24 @@
package com.intellij.codeInspection.tests.test
import com.intellij.codeInspection.test.TestCaseWithoutTestsInspection
import com.intellij.codeInspection.tests.JvmInspectionTestBase
import com.intellij.openapi.module.Module
import com.intellij.openapi.roots.ContentEntry
import com.intellij.openapi.roots.ModifiableRootModel
import com.intellij.pom.java.LanguageLevel
import com.intellij.testFramework.LightProjectDescriptor
abstract class TestCaseWithoutTestsInspectionTestBase : JvmInspectionTestBase() {
override val inspection: TestCaseWithoutTestsInspection = TestCaseWithoutTestsInspection()
override fun getProjectDescriptor(): LightProjectDescriptor = JUnitProjectDescriptor(sdkLevel)
private class JUnitProjectDescriptor(languageLevel: LanguageLevel) : ProjectDescriptor(languageLevel) {
override fun configureModule(module: Module, model: ModifiableRootModel, contentEntry: ContentEntry) {
super.configureModule(module, model, contentEntry)
model.addJUnit3Library()
model.addJUnit4Library()
model.addJUnit5Library()
}
}
}

View File

@@ -127,7 +127,6 @@ com.siyeh.ig.j2me.OverlyLargePrimitiveArrayInitializerInspection
com.siyeh.ig.javabeans.ClassWithoutNoArgConstructorInspection
com.siyeh.ig.javadoc.UnnecessaryJavaDocLinkInspection
com.siyeh.ig.jdk.AutoBoxingInspection
com.siyeh.ig.junit.TestCaseWithNoTestMethodsInspection
com.siyeh.ig.logging.ClassWithMultipleLoggersInspection
com.siyeh.ig.logging.ClassWithoutLoggerInspection
com.siyeh.ig.logging.LoggerInitializedWithForeignClassInspection

View File

@@ -5,6 +5,7 @@ import com.intellij.java.library.JavaLibraryUtil
import com.intellij.util.Processor
import com.intellij.util.ThreeState
import com.intellij.util.ThreeState.*
import org.jetbrains.kotlin.idea.base.psi.kotlinFqName
import org.jetbrains.kotlin.idea.base.util.module
import org.jetbrains.kotlin.idea.stubindex.KotlinFullClassNameIndex
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelTypeAliasFqNameIndex
@@ -62,6 +63,8 @@ abstract class AbstractKotlinPsiBasedTestFramework : KotlinPsiBasedTestFramework
declaration.isLocal -> false
declaration.hasModifier(KtTokens.PRIVATE_KEYWORD) -> false
declaration.hasModifier(KtTokens.ABSTRACT_KEYWORD) -> false
declaration.hasModifier(KtTokens.SUSPEND_KEYWORD) -> false // suspend functions pass implicit argument
declaration.typeReference != null && declaration.typeReference?.kotlinFqName?.asString() != "kotlin.Unit" -> false
declaration.isExtensionDeclaration() -> false
else -> {
val ktClassOrObject =
@@ -132,4 +135,8 @@ abstract class AbstractKotlinPsiBasedTestFramework : KotlinPsiBasedTestFramework
}
return null
}
companion object {
val KOTLIN_UNIT: String? = "kotlin.Unit"
}
}