Testing Inspections

I've been tasked with fixing a large batch of failing tests in custom code inspections. Presumably these worked at one point in time. They all look something like this:

public class ApiNameInspectionTest extends EndpointTestBase {
  // EndpointTestBase is a local class that extends JavaCodeInsightFixtureTestCase

public void testEmptyApiNameAttribute() {
  doTest();
}

private void doTest() {
  LocalInspectionTool localInspectionTool = new ApiNameInspection();
  String testName = getTestName(true);
  final String testDataPath = getTestDataPath();
  myFixture.setTestDataPath(testDataPath);
  LocalInspectionToolWrapper toolWrapper = new LocalInspectionToolWrapper(localInspectionTool);
  myFixture.testInspection("inspections/apiNameInspection/" + testName, toolWrapper);
}


They all fail like this:

java.lang.AssertionError: Assertion failed: profile name: Default base profile: - key: ApiName
 at com.intellij.testFramework.LoggedErrorProcessor.processError(LoggedErrorProcessor.java:56)
 at com.intellij.testFramework.TestLogger.error(TestLogger.java:67)
 at com.intellij.openapi.diagnostic.Logger.error(Logger.java:130)
 at com.intellij.openapi.diagnostic.Logger.assertTrue(Logger.java:144)
 at com.intellij.codeInspection.ex.InspectionProfileImpl.getErrorLevel(InspectionProfileImpl.java:652)
 at com.intellij.codeInspection.ex.InspectionProfileImpl.initialize(InspectionProfileImpl.java:578)
 at com.intellij.codeInspection.ex.InspectionProfileImpl.createSimple(InspectionProfileImpl.java:148)
 at com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl.createGlobalContextForTool(CodeInsightTestFixtureImpl.java:476)
 at com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl.testInspection(CodeInsightTestFixtureImpl.java:465)
 at com.google.gct.idea.appengine.validation.ApiNameInspectionTest.doTest(ApiNameInspectionTest.java:115)
 at com.google.gct.idea.appengine.validation.ApiNameInspectionTest.testEmptyApiNameAttribute(ApiNameInspectionTest.java:33)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)


as best I guess, the problem is that the inspection being tested isn't properly loaded into ourEPMap in
LocalInspectionToolWrapper. That is I see a lot of standard inspections loaded there when I run it in the debugger, but I don't see the custom ApiNameInspection tool loaded.

Is there a step I'm missing somewhere where I somehow register the name inspectioon I want to test? Or anything else obvious I'm likely to be missing? Is there documentation for JavaCodeInsightFixtureTestCase and/or LocalInspectionToolWrapper somewhere that I should be aware of? Thanks.

4 comments
Comment actions Permalink

It looks like myFixture.enableInspections(localInspectionTool) is missing

On 9/14/2015 10:22 PM, Elliotte Harold wrote:

I've been tasked with fixing a large batch of failing tests in custom code inspections. Presumably these worked at one point in time. They all look something like this:

>

public class ApiNameInspectionTest extends EndpointTestBase {
   // EndpointTestBase is a local class that extends JavaCodeInsightFixtureTestCase

>

public void testEmptyApiNameAttribute() {
   doTest();
}

>

private void doTest() {
   LocalInspectionTool localInspectionTool = new ApiNameInspection();
   String testName = getTestName(true);
   final String testDataPath = getTestDataPath();
   myFixture.setTestDataPath(testDataPath);
   LocalInspectionToolWrapper toolWrapper = new LocalInspectionToolWrapper(localInspectionTool);
   myFixture.testInspection("inspections/apiNameInspection/" + testName, toolWrapper);
}

>
>

They all fail like this:

>

java.lang.AssertionError: Assertion failed: profile name: Default base profile: - key: ApiName
  at com.intellij.testFramework.LoggedErrorProcessor.processError(LoggedErrorProcessor.java:56)
  at com.intellij.testFramework.TestLogger.error(TestLogger.java:67)
  at com.intellij.openapi.diagnostic.Logger.error(Logger.java:130)
  at com.intellij.openapi.diagnostic.Logger.assertTrue(Logger.java:144)
  at com.intellij.codeInspection.ex.InspectionProfileImpl.getErrorLevel(InspectionProfileImpl.java:652)
  at com.intellij.codeInspection.ex.InspectionProfileImpl.initialize(InspectionProfileImpl.java:578)
  at com.intellij.codeInspection.ex.InspectionProfileImpl.createSimple(InspectionProfileImpl.java:148)
  at com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl.createGlobalContextForTool(CodeInsightTestFixtureImpl.java:476)
  at com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl.testInspection(CodeInsightTestFixtureImpl.java:465)
  at com.google.gct.idea.appengine.validation.ApiNameInspectionTest.doTest(ApiNameInspectionTest.java:115)
  at com.google.gct.idea.appengine.validation.ApiNameInspectionTest.testEmptyApiNameAttribute(ApiNameInspectionTest.java:33)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

>
>

as best I guess, the problem is that the inspection being tested isn't properly loaded into ourEPMap in
LocalInspectionToolWrapper. That is I see a lot of standard inspections loaded there when I run it in the debugger, but I don't see the custom ApiNameInspection tool loaded.

>

Is there a step I'm missing somewhere where I somehow register the name inspectioon I want to test? Or anything else obvious I'm likely to be missing? Is there documentation for JavaCodeInsightFixtureTestCase and/or LocalInspectionToolWrapper somewhere that I should be aware of? Thanks.

>
>

---
Original message URL: https://devnet.jetbrains.com/message/5558381#5558381

>

0
Comment actions Permalink

Thanks. I tried that and it didn't help though. FYI, the documentation on this method is weird:

 
/**
* Enables inspections for highlighting tests.
* Should be called BEFORE {@link #setUp()}. And do not forget to call {@link #tearDown()}
*
* @param inspections inspections to be enabled in highlighting tests.
* @see #enableInspections(com.intellij.codeInspection.InspectionToolProvider...)
*/
void enableInspections(@NotNull InspectionProfileEntry... inspections);


However CodeInsightTestFixture doesn't have setUp and I can't run it before the test case setUp because the fixture hasn't been initialized yet.

I am now at the point where I can get the test to pass if I run it in IDEA. However if I run the same test from the command line (gradle) it fails. It looks like there's some difference in the classpath between them. Maybe config file isn't getting loaded? Any idea what that's likely to be.

0
Comment actions Permalink

After much debugging here's what I've figured out:

1. The default inspections (e.g. InconsistentLineSeparators) get loaded. Mine never does.

2. All the inspections get added to InspectionProfileImpl.myTools by this method:

 
@NotNull
private List<InspectionToolWrapper> createTools(Project project) {
    if (mySource != null) {
        return ContainerUtil.map(mySource.getDefaultStates(project), new Function<ScopeToolState, InspectionToolWrapper>() {
            @NotNull
            @Override
            public
InspectionToolWrapper fun(@NotNull ScopeToolState state) {
                return state.getTool();
            }
        });
    }
    //noinspection TestOnlyProblems
    return myRegistrar
.createTools();
}


3. mySource is never null and is always the default. Thus myRegistrar.createTools() does not get called.

4. But if somehow it does get called, it still doesn't work because

 
private boolean initialize(@Nullable Project project) {
    if (myBaseProfile != null) {
        myBaseProfile.initInspectionTools(project);
    }


changes the registrar object in the profile to point to the default! myBaseProfile is not null along this path either because createSimple calls the constructor that does this:

 
myBaseProfile = getDefaultProfile();



Note that createGlobalContext always calls

 
final InspectionProfileImpl profile = InspectionProfileImpl.createSimple("test", project, toolWrappers);


I don't see any code path that starts at

 
myFixture.testInspection("inspections/apiNameInspection/" + testName, toolWrapper);


and actually loads the apiName inspection.

Possibly I'm not supposed to use testInspection for this after all?

Is there a flaw in my reasoning somewhere?

0
Comment actions Permalink

If I change this method:

 
public InspectionProfileImpl(@NotNull final String profileName,
                             @NotNull InspectionToolRegistrar registrar,
                             @NotNull final ProfileManager profileManager) {
    super(profileName);
    myRegistrar = registrar;
    myBaseProfile = getDefaultProfile();
    
setProfileManager(profileManager);
    myUninstalledInspectionsSettings = new TreeMap<String, Element>();
}



to

 
public InspectionProfileImpl(@NotNull final String profileName,
                             @NotNull InspectionToolRegistrar registrar,
                             @NotNull final ProfileManager profileManager) {
    super(profileName);
    myRegistrar = registrar;
    //myBaseProfile = getDefaultProfile();
    
setProfileManager(profileManager);
    myUninstalledInspectionsSettings = new TreeMap<String, Element>();
}



then the tests all pass. I'm not sure what the consequences of doing this for other parts of the system would be.

0

Please sign in to leave a comment.