Home > OS >  Why is the kotlin-gradle-plugin failing to create a PSIFile from CodeInsightTestFixture.configureByT
Why is the kotlin-gradle-plugin failing to create a PSIFile from CodeInsightTestFixture.configureByT

Time:09-26

I created an IntelliJ plugin using the template https://github.com/JetBrains/intellij-platform-plugin-template. The template comes with a test that runs on an XML file. I want to create a similar test for a Kotlin file. Here's the template test file plus my added test (test2):

package org.jetbrains.plugins.template

import com.intellij.ide.highlighter.XmlFileType
import com.intellij.psi.xml.XmlFile
import com.intellij.testFramework.TestDataPath
import com.intellij.testFramework.fixtures.BasePlatformTestCase
import com.intellij.util.PsiErrorElementUtil

@TestDataPath("\$CONTENT_ROOT/src/test/testData")
class MyPluginTest : BasePlatformTestCase() {

    fun testXMLFile() {
        val psiFile = myFixture.configureByText(XmlFileType.INSTANCE, "<foo>bar</foo>")
        val xmlFile = assertInstanceOf(psiFile, XmlFile::class.java)

        assertFalse(PsiErrorElementUtil.hasErrors(project, xmlFile.virtualFile))

        assertNotNull(xmlFile.rootTag)

        xmlFile.rootTag?.let {
            assertEquals("foo", it.name)
            assertEquals("bar", it.value.text)
        }
    }

    override fun getTestDataPath() = "src/test/testData/rename"

    fun testRename() {
        myFixture.testRename("foo.xml", "foo_after.xml", "a2")
    }
    
    // Here's my test
    fun test2() {
        val fileText: String = """
package com.loganmay.test

data class MyClass(val myString: String)
        """.trimIndent()
        val psiFile = myFixture.configureByText("a.kt", fileText)
        val xmlFile = assertInstanceOf(psiFile, XmlFile::class.java)
    }

}

Without changing the build.gradle file, that test fails with:

Expected instance of: com.intellij.psi.xml.XmlFile actual: com.intellij.psi.impl.source.PsiPlainTextFileImpl

I want it to parse the text as a PsiFile that's also a KtFile. From various sources, I've been led to believe that the fixture is parsing it as a plain text file because the test project doesn't have access to the Kotlin compiler. So, I added:

dependencies {
    testImplementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10")
}

to the build.gradle. Then, when I run the test, configureByText throws an exception with a big trace, the root exception of which is:

Caused by: java.lang.Throwable: 'filetype.archive.display.name' is not found in java.util.PropertyResourceBundle@4ecbb519(messages.CoreBundle)
    ... 53 more
org.jetbrains.plugins.template.MyPluginTest > test2 FAILED
    com.intellij.diagnostic.PluginException at ComponentManagerImpl.kt:511
        Caused by: java.util.MissingResourceException at Registry.java:164

Does anyone have any insight into what the issue is or know how to resolve it?

Notes:

  • I also tried importing the kotlin compiler and casting psiFile as KtFile, which produced the same error, an idea I got from here
  • This project has a test like this that may be working
  • This post and this post recommend adding the kotlin gradle plugin, which I did
  • This question seems similar

CodePudding user response:

Yann Cebron replied on the jetbrains help forum with an answer for Java, which also worked for Kotlin.

The solution is to add a dependency to the IntelliJ gradle plugin. The template comes with these lines in the build.gradle:

intellij {
    pluginName.set(properties("pluginName"))
    version.set(properties("platformVersion"))
    type.set(properties("platformType"))

    // Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file.
    plugins.set(properties("platformPlugins").split(',').map(String::trim).filter(String::isNotEmpty))
}

So, didn't need to do anything there. In my gradle.properties, I added

platformPlugins = com.intellij.java, org.jetbrains.kotlin

To my plugin.xml, I added:

    <depends>com.intellij.modules.java</depends>
    <depends>org.jetbrains.kotlin</depends>

I was able to remove

dependencies {
    testImplementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10")
}

from the build.gradle which I mentioned above.

Now, the test works for Java and Kotlin files.

  • Related