自定义参考贡献者在运行IntelliJ平台插件的测试时未被调用。

huangapple go评论92阅读模式
英文:

Custom reference contributor is not being called while running tests for Intellij Platform plugin

问题

我正在为Intellij平台(实际上是为PhpStorm)开发插件。

我的插件在PHP语言中的字符串文字表达式中提供引用。
我创建了一个引用贡献者和几个引用提供者类。
当我在PhpStorm中运行它时,我的插件工作得很完美。

我的插件变得越来越大,所以我决定为它编写一些测试。
我使用IntelliJ IDEA的“创建测试”操作创建了一个单元测试,并选择了JUnit 3。
当我运行测试(请参见下面的代码)时,类MyPsiReferenceContributor根本不会被访问,而测试会预期失败(“测试失败”)。
parent.getReferences()返回一个空数组(parentStringLiteralExpressionImpl的实例)。

似乎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 {
    // 这在运行测试时没有被调用! :(
    @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('test');\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");
    }
}

希望这些信息对你有帮助。如果需要更多帮助,请告诉我。

英文:

I'm developing a plugin for Intellij Platform (actually for PhpStorm).

My plugin is providing references within string literal expressions in PHP language.
I created a reference contributor and a few reference provider classes.
My plugin works perfectly when I run it within PhpStorm.

My plugin becomes bigger, so I decided to write a few tests for it.
I created an unit test using IntelliJ IDEA "Create test" action and choosed JUnit 3.
When I run test (see code below), the class MyPsiReferenceContributor is not being accessed at all, and test expectedly fails ("Test failed").
parent.getReferences() returns an empty array (parent is an instance of StringLiteralExpressionImpl).

Is seems that MyPsiReferenceContributor is not being registered in test environment.

What should I do to make my reference contributor available within tests?

I used this project https://github.com/Haehnchen/idea-php-symfony2-plugin as example,
but my plugin is not using Gradle as theirs does.

This is how I registered my reference contributor in plugin.xml:

&lt;extensions defaultExtensionNs=&quot;com.intellij&quot;&gt;
&lt;psi.referenceContributor implementation=&quot;com.zenden2k.MyFrameworkIntegration.MyPsiReferenceContributor&quot;/&gt;
&lt;/extensions&gt;

This is my reference contributor:

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);
}
}

This is my test case:

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(&quot;GetStaticDatasourceFixture.php&quot;);
myFixture.copyFileToProject(&quot;user.xml&quot;);
}
protected String getTestDataPath() {
return &quot;src/test/com/zenden2k/MyFrameworkIntegration/tests/fixtures&quot;;
}
public void testThatStaticDatasourceReferenceIsProvided() {
final ElementPattern&lt;?&gt; pattern = PlatformPatterns.psiElement().withName(&quot;test&quot;);
myFixture.configureByText(&quot;user.php&quot;,
&quot;&lt;?php \n&quot; +
&quot;class MyClass extends CXMLObject {\n&quot; +
&quot;  public function test() {\n&quot; +
&quot;     $this-&gt;getStaticDatasource(&#39;t&lt;caret&gt;est&#39;);\n&quot; +
&quot;  }\n&quot; +
&quot;}\n&quot;
);
PsiElement psiElement = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
if (psiElement == null) {
fail(&quot;Fail to find element in caret&quot;);
}
PsiElement parent = psiElement.getParent();
final PsiReference[] ref = parent.getReferences();
for (PsiReference reference : ref) {
PsiElement element = reference.resolve();
if (pattern.accepts(element)) {
return;
}
}
fail(&quot;Test failed&quot;);
}
}

答案1

得分: 2

首先 - 使用Gradle是开发插件的推荐方式。您可以查阅使用Gradle构建插件文档部分,获取更多详细信息。

IntelliJ平台SDK代码示例存储库中有一个简单语言示例项目,涵盖了测试PSI引用的内容。

英文:

First of all - using Gradle is a recommended way for the development of the plugin. You may check the Building Plugins with Gradle docs section for more details.

There is a Simple Language Sample project available in the IntelliJ Platform SDK Code Samples repository that covers testing of the PSI References.

huangapple
  • 本文由 发表于 2020年8月22日 16:23:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/63534077.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定