在运行Intellij Platform插件的测试时未调用自定义参考贡献者

问题描述

我正在为Intellij Platform(实际上是PHPStorm)开发一个插件

我的插件正在用PHP语言在字符串文字表达式中提供引用。 我创建了一个参考贡献者和一些参考提供者类。 当我在PHPStorm中运行它时,我的插件可以完美运行。

我的插件变大了,所以我决定为其编写一些测试。 我使用IntelliJ IDEA“创建测试”操作创建了一个单元测试,并选择了JUnit 3。 当我运行测试(请参见下面的代码)时,根本无法访问类MyPsiReferenceContributor,并且测试可能会失败(“测试失败”)。 parent.getReferences()返回一个空数组(parent是StringLiteralExpressionImpl的一个实例。)

似乎MyPsiReferenceContributor尚未在测试环境中注册

我应该怎么做才能在测试中使用参考贡献者?

我以这个项目https://github.com/Haehnchen/idea-php-symfony2-plugin为例, 但是我的插件没有像他们那样使用Gradle。

这就是我在plugin.xml注册参考贡献者的方式:

<extensions defaultExtensionNs="com.intellij">
    <psi.referenceContributor implementation="com.zenden2k.MyFrameworkIntegration.MyPsiReferenceContributor"/>
</extensions>

这是我的参考贡献者:

public class MyPsiReferenceContributor extends PsiReferenceContributor {
    // This is not being called while running tests! :(
    @Override
    public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
        MyPsiReferenceProvider provider = new MyPsiReferenceProvider();
        registrar.registerReferenceProvider(StandardPatterns.instanceOf(StringLiteralExpression.class),provider);
    }
}

这是我的测试用例:

package com.zenden2k.MyFrameworkIntegration.tests;

import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.testFramework.fixtures.BasePlatformTestCase;

public class MyPsiReferenceContributorTest extends BasePlatformTestCase {
    public void setUp() throws Exception {
        super.setUp();

        myFixture.copyFiletoProject("GetStaticDatasourceFixture.PHP");
        myFixture.copyFiletoProject("user.xml");
    }

    protected String getTestDataPath() {
        return "src/test/com/zenden2k/MyFrameworkIntegration/tests/fixtures";
    }


    public void testThatStaticDatasourceReferenceIsProvided() {
        final ElementPattern<?> pattern = PlatformPatterns.psiElement().withName("test");
        myFixture.configureByText("user.PHP","<?PHP \n" +
                        "class MyClass extends CXMLObject {\n" +
                        "  public function test() {\n" +
                        "     $this->getStaticDatasource('t<caret>est');\n" +
                        "  }\n" +
                        "}\n"
        );

        PsiElement psiElement = myFixture.getFile().findElementAt(myFixture.getCaretoffset());
        if (psiElement == null) {
            fail("Fail to find element in caret");
        }

        PsiElement parent = psiElement.getParent();
        final PsiReference[] ref = parent.getReferences();
        for (PsiReference reference : ref) {
            PsiElement element = reference.resolve();
            if (pattern.accepts(element)) {
                return;
            }
        }
        fail("Test Failed");
    }
}

解决方法

首先-建议使用Gradle开发插件。您可以查看Building Plugins with Gradle文档部分以了解更多详细信息。

Simple Language Sample存储库中有一个IntelliJ Platform SDK Code Samples项目,涉及PSI参考的测试。