Testing Highlighting

Hi Guys,

I'm following this document (and this one, also saw this, and this) to get my plugin testing going, but having trouble achieving my goal.

I've tried a few angles but I keep hitting the wall, mainly due to:


    1. com.intellij.codeInsight.daemon.impl.HighlightInfo does not expose it's inner "PsiElement psiElement" member, making it cumbersome to try and assert the results of what comes back from calling myFixture.doHighlighting().
    2. If I try using myFixture.checkHighlighting() with the highlight testing DSL markup, things go sideways as well becuase deep inside the underlying document gets committed and the resulting changes get picked up by my plugin and pollute the test. This is also the case with testHighlighting() since they use a very similar code path.
    3. Also, even primitive types like Strings are marked with "Cannot resolve symbol 'String'" error when enabling inspections, which pollutes the resulting highlight infos. I suspect this is due to the tests using a mock JDK, which does not actually resolve types. What can be done to overcome this? Using a real JDK causes other problems, as it complains about the XML markup DSL insinde the java files.
    4. There's also the option of using the com.intellij.testFramework.InspectionTestCase , but this does not give me the fine grained control over what gets highlighted, since in the expected.xml file I seem to be able to only mention the line number, and not the psi element in question.


What would be the way to achieve proper highlighting testing in light of the above mentioned issues?



I would deeply appreciate your help and any words of wisdom!


Thank you in advance,
Stas
6 comments

A small update, configuring the JDK with a real JDK seems to make the XML DSL work, i.e., tests adhere to the XML mark up.

  override def getProjectDescriptor = new DefaultLightProjectDescriptor {     override def configureModule(module: Module, model: ModifiableRootModel, contentEntry: ContentEntry) = {       val extension = model.getModuleExtension(classOf[LanguageLevelModuleExtension])       extension.setLanguageLevel(LanguageLevel.HIGHEST)       val jdk = JavaAwareProjectJdkTableImpl.getInstanceEx.getInternalJdk //    val jdk = IdeaTestUtil.getMockJdk17       model.setSdk(jdk)     }   }



However, invoking myFixture.doHighlighting() still gives back highlight infos indicating the underlying mechanism is rejecting the mark up and thinking its tags are syntax errors.
This is somewhat inconsistent, since on one hand I have a working test suite, on the other hand, if I look into the generated highlight infos myself, they look a bit off, and have extra errors that should not really be there.

So basically the question still stands.

0

Hello,

3) see com.intellij.testFramework.IdeaTestUtil#getPathForJdkNamed, a mockJDK has to be present (by default taken from IntelliJ Community Sources, you can set com.intellij.openapi.application.PathManager#PROPERTY_HOME_PATH accordingly in your tests run configuration VM parameters)

Is your plugin opensource? If yes, please post link to sources. It's always easier to debug problems and answer questions like these here with full sources.

What exactly do you want to assert in your tests highlighting expectations?

Best regards,
Yann

0

Hi Yann,

Thanks for your quick reply.

Unfortunately my plugin is not an open source at this point in time, but I'll try to make myself clearer using an existing sample found in the community edition.

If I take the famous "comparingReferences" sample (intellij-community/samples/comparingReferences) and inspect the result of :

 
List<HighlightInfo> highlightInfos = myFixture.doHighlighting();
 
highlightInfos look like so:
      
  • [0] = {com.intellij.codeInsight.daemon.impl.HighlightInfo@9730}""   
  • [1] = {com.intellij.codeInsight.daemon.impl.HighlightInfo@9731}""   
  • [2] = {com.intellij.codeInsight.daemon.impl.HighlightInfo@9732}"Cannot resolve symbol 'java'"   
  • [3] = {com.intellij.codeInsight.daemon.impl.HighlightInfo@9733}"Cannot resolve symbol 'java'"   
  • [4] = {com.intellij.codeInsight.daemon.impl.HighlightInfo@9734}"Suspicious comparison s1 == s2"   
  • [5] = {com.intellij.codeInsight.daemon.impl.HighlightInfo@9735}""   
  • [6] = {com.intellij.codeInsight.daemon.impl.HighlightInfo@9736}""


Why does it say "Cannot resolve symbol 'java'"? Is it because the test is using a mock JDK?

What is the proper way of making these highlight infos go away?
I don't want them to interfere with my own highlighting (just as they interfere with the "Suspicious comparison s1 == s2" highlight in the example above).


Thank you in advance,
Stas

0

AFAIU if there's references to Java classes in test data a proper Mock JDK must be supplied. Otherwise (as you noted) all these irrelevant highlightings will just add noise.

Usually using com.intellij.testFramework.fixtures.CodeInsightTestFixture#testHighlighting() and using embedded highlighting markers in test data is easier to manage.

0

I see, thanks!

Just in case I do need to have an actual type resolution (or some other stuff that need a real JDK), do you see any problems with settings the JDK in the following manner?

val jdk = JavaAwareProjectJdkTableImpl.getInstanceEx.getInternalJdk


Thanks again,
Stas

0

I'd suggest to use the approach shown in http://confluence.jetbrains.com/display/IntelliJIDEA/Tests+Prerequisites and point to mockJDK bundled in community sources.


0

Please sign in to leave a comment.