package fr.adrienbrault.idea.symfony2plugin.tests.util;
import com.intellij.ide.plugins.PluginManager;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.psi.PsiElement;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.php.lang.PhpFileType;
import com.jetbrains.php.lang.psi.PhpPsiElementFactory;
import com.jetbrains.php.lang.psi.elements.ArrayCreationExpression;
import com.jetbrains.php.lang.psi.elements.PhpClass;
import com.jetbrains.php.lang.psi.elements.Variable;
import fr.adrienbrault.idea.symfony2plugin.tests.SymfonyLightCodeInsightFixtureTestCase;
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
/**
* @author Daniel Espendiller <daniel@espendiller.net>
*/
public class PhpElementsUtilTest extends SymfonyLightCodeInsightFixtureTestCase {
public void setUp() throws Exception {
super.setUp();
myFixture.copyFileToProject("PhpElementsUtil.php");
}
public String getTestDataPath() {
return new File(this.getClass().getResource("fixtures").getFile()).getAbsolutePath();
}
/**
* @see fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil#getMethodParameterTypeHint
*/
public void testGetMethodParameterClassHint() {
assertEquals("\\DateTime", PhpElementsUtil.getMethodParameterTypeHint(
PhpPsiElementFactory.createMethod(getProject(), "function foo(\\DateTime $e) {}")
));
assertEquals("\\Iterator", PhpElementsUtil.getMethodParameterTypeHint(
PhpPsiElementFactory.createMethod(getProject(), "function foo(/* foo */ \\Iterator $a, \\DateTime $b")
));
assertNull(PhpElementsUtil.getMethodParameterTypeHint(
PhpPsiElementFactory.createMethod(getProject(), "function foo(/* foo */ $a, \\DateTime $b")
));
}
/**
* @see fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil#getArrayKeyValueMap
*/
public void testGetArrayKeyValueMap() {
assertEquals("foo", PhpElementsUtil.getArrayKeyValueMap(PhpPsiElementFactory.createPhpPsiFromText(getProject(), ArrayCreationExpression.class, "$foo = ['foo' => 'foo'];")).get("foo"));
assertEquals("foo", PhpElementsUtil.getArrayKeyValueMap(PhpPsiElementFactory.createPhpPsiFromText(getProject(), ArrayCreationExpression.class, "$foo = [1 => 'foo'];")).get("1"));
assertSize(0, PhpElementsUtil.getArrayKeyValueMap(PhpPsiElementFactory.createPhpPsiFromText(getProject(), ArrayCreationExpression.class, "$foo = [null => 'foo'];")).keySet());
assertSize(0, PhpElementsUtil.getArrayKeyValueMap(PhpPsiElementFactory.createPhpPsiFromText(getProject(), ArrayCreationExpression.class, "$foo = ['' => 'foo'];")).keySet());
}
/**
* @see fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil#getFirstVariableTypeInScope(Variable)
*/
public void testGetFirstVariableTypeInScope() {
PsiElement psiElement = myFixture.configureByText(PhpFileType.INSTANCE, "<?php" +
"$foo = new \\DateTime();\n" +
"$d->dispatch('foo', $f<caret>oo)->;").findElementAt(myFixture.getCaretOffset()).getParent();
assertEquals("\\DateTime", PhpElementsUtil.getFirstVariableTypeInScope((Variable) psiElement));
psiElement = myFixture.configureByText(PhpFileType.INSTANCE, "<?php" +
"function foo() {" +
" $foo = new \\DateTime();\n" +
" $d->dispatch('foo', $f<caret>oo);\n" +
"}").findElementAt(myFixture.getCaretOffset()).getParent();
assertEquals("\\DateTime", PhpElementsUtil.getFirstVariableTypeInScope((Variable) psiElement));
}
/**
* @see fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil#getFirstVariableTypeInScope(Variable)
*/
public void testGetFirstVariableTypeInScopeNotFound() {
PsiElement psiElement = myFixture.configureByText(PhpFileType.INSTANCE, "<?php" +
"$foo = new \\DateTime();\n" +
"function foo() {\n" +
" $d->dispatch('foo', $f<caret>oo);" +
"}").findElementAt(myFixture.getCaretOffset()).getParent();
assertNull(PhpElementsUtil.getFirstVariableTypeInScope((Variable) psiElement));
}
/**
* @see fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil#getClassInsideNamespaceScope
*/
public void testGetClassInsideNamespaceScope() {
assertNotNull(PhpElementsUtil.getClassInsideNamespaceScope(getProject(), "Foo\\Foo", "\\Foo\\Bar"));
assertNotNull(PhpElementsUtil.getClassInsideNamespaceScope(getProject(), "Foo\\Foo", "Bar"));
assertNotNull(PhpElementsUtil.getClassInsideNamespaceScope(getProject(), "\\Foo\\Foo", "Bar"));
assertNotNull(PhpElementsUtil.getClassInsideNamespaceScope(getProject(), "\\Foo\\Foo", "Bar\\"));
assertNotNull(PhpElementsUtil.getClassInsideNamespaceScope(getProject(), "\\Foo\\Foo\\", "Bar\\"));
assertNull(PhpElementsUtil.getClassInsideNamespaceScope(getProject(), "Fooa", "Bar"));
assertNull(PhpElementsUtil.getClassInsideNamespaceScope(getProject(), "Fooa\\Foo", "Bar"));
}
/**
* @see fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil#isInstanceOf
*/
public void testIsInstanceOf() {
if("162.1121.34".equals(PluginManager.getPlugin(PluginId.getId("com.jetbrains.php")).getVersion())) {
System.out.println("Skipping PhpElementsUtil.testIsInstanceOf for PhpStorm 2016.2 (162.1121.34) inconsistently behavior fixed in 2016.2.1");
return;
}
myFixture.copyFileToProject("InstanceOf.php");
Collection<String[]> providers = new ArrayList<String[]>() {{
add(new String[] {"\\Instance\\Of\\Foo", "\\Instance\\Of\\Bar"});
add(new String[] {"\\Instance\\Of\\Foo", "\\Instance\\Of\\Cool"});
add(new String[] {"\\Instance\\Of\\Car", "\\Instance\\Of\\Bar"});
add(new String[] {"\\Instance\\Of\\Car", "\\Instance\\Of\\Foo"});
add(new String[] {"\\Instance\\Of\\Car", "\\Instance\\Of\\Cool"});
// backslash
add(new String[] {"Instance\\Of\\Car", "Instance\\Of\\Cool"});
add(new String[] {"Instance\\Of\\Car", "\\Instance\\Of\\Cool"});
add(new String[] {"\\Instance\\Of\\Car", "Instance\\Of\\Cool"});
// dups
add(new String[] {"\\Instance\\Of\\Car", "Instance\\Of\\Apple"});
add(new String[] {"\\Instance\\Of\\Foo", "Instance\\Of\\Apple"});
}};
for (String[] provider : providers) {
assertTrue(PhpElementsUtil.isInstanceOf(getProject(), provider[0], provider[1]));
assertTrue(PhpElementsUtil.isInstanceOf(PhpElementsUtil.getClassInterface(getProject(), provider[0]), provider[1]));
assertTrue(PhpElementsUtil.isInstanceOf(
PhpElementsUtil.getClassInterface(getProject(), provider[0]),
PhpElementsUtil.getClassInterface(getProject(), provider[1])
));
}
}
/**
* @see fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil#insertUseIfNecessary
*/
public void testUseImports() {
assertEquals("Bar", PhpElementsUtil.insertUseIfNecessary(PhpPsiElementFactory.createPhpPsiFromText(getProject(), PhpClass.class, "<?php\n" +
"namespace Foo;\n" +
"class Foo{}\n"
), "\\Foo\\Bar"));
assertEquals("Bar", PhpElementsUtil.insertUseIfNecessary(PhpPsiElementFactory.createPhpPsiFromText(getProject(), PhpClass.class, "<?php\n" +
"namespace Foo;\n" +
"use Foo\\Bar;\n" +
"class Foo{}\n"
), "\\Foo\\Bar"));
assertEquals("Apple", PhpElementsUtil.insertUseIfNecessary(PhpPsiElementFactory.createPhpPsiFromText(getProject(), PhpClass.class, "<?php\n" +
"namespace Bar\\Bar;\n" +
"use Foo as Car;\n" +
"class Foo{}\n"
), "Foo\\Cool\\Apple"));
}
/**
* @see fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil#getVariableReferencesInScope
*/
public void testGetVariableReferencesInScopeForVariable() {
myFixture.configureByText(PhpFileType.INSTANCE, "<?php\n" +
"function foobar() {\n" +
" $var = new \\DateTime();" +
" $va<caret>r->format();" +
" $var->modify();" +
"\n}"
);
PsiElement psiElement = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
assertNotNull(psiElement);
Collection<Variable> vars = PhpElementsUtil.getVariableReferencesInScope((Variable) psiElement.getParent());
assertSize(2, vars);
assertNotNull(ContainerUtil.find(vars, variable ->
"$var = new \\DateTime()".equals(variable.getParent().getText()))
);
assertNotNull(ContainerUtil.find(vars, variable ->
"$var->modify()".equals(variable.getParent().getText()))
);
}
/**
* @see fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil#getVariableReferencesInScope
*/
public void testGetVariableReferencesInScopeForVariableDeclaration() {
myFixture.configureByText(PhpFileType.INSTANCE, "<?php\n" +
"function foobar() {\n" +
" $v<caret>ar = new \\DateTime();" +
" $var->format();" +
" $var->modify();" +
"\n}"
);
PsiElement psiElement = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
assertNotNull(psiElement);
Collection<Variable> vars = PhpElementsUtil.getVariableReferencesInScope((Variable) psiElement.getParent());
assertSize(2, vars);
assertNotNull(ContainerUtil.find(vars, variable ->
"$var->format()".equals(variable.getParent().getText()))
);
assertNotNull(ContainerUtil.find(vars, variable ->
"$var->modify()".equals(variable.getParent().getText()))
);
}
/**
* @see fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil#getParameterListArrayValuePattern
*/
public void testGetParameterListArrayValuePattern() {
String[] strings = {
"foo(['<caret>']",
"foo(['<caret>' => 'foo']",
"foo(['foo' => null, '<caret>' => null]"
};
for (String s : strings) {
myFixture.configureByText(PhpFileType.INSTANCE, "<?php\n" + s);
assertTrue(
PhpElementsUtil.getParameterListArrayValuePattern().accepts(myFixture.getFile().findElementAt(myFixture.getCaretOffset()))
);
}
myFixture.configureByText(PhpFileType.INSTANCE, "<?php\n" +
"foobar(['foobar' => '<caret>'])"
);
assertFalse(
PhpElementsUtil.getParameterListArrayValuePattern().accepts(myFixture.getFile().findElementAt(myFixture.getCaretOffset()))
);
}
}