问题描述
我正在为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参考的测试。