Skip to content

Instantly share code, notes, and snippets.

@Leneshka-jb
Last active August 7, 2019 14:57
Show Gist options
  • Save Leneshka-jb/f422a573cc71253c1fb1c5b322fe4ce9 to your computer and use it in GitHub Desktop.
Save Leneshka-jb/f422a573cc71253c1fb1c5b322fe4ce9 to your computer and use it in GitHub Desktop.
PhpStubComparisonTest
package com.jetbrains.php;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.jetbrains.php.fixtures.PhpCodeInsightFixtureTestCase;
import com.jetbrains.php.lang.documentation.phpdoc.psi.PhpDocComment;
import com.jetbrains.php.lang.psi.PhpFile;
import com.jetbrains.php.lang.psi.PhpPsiUtil;
import com.jetbrains.php.lang.psi.elements.Field;
import com.jetbrains.php.lang.psi.elements.Method;
import com.jetbrains.php.lang.psi.elements.Parameter;
import com.jetbrains.php.lang.psi.elements.PhpClass;
import gnu.trove.TIntHashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public class PhpStubComparisonTest extends PhpCodeInsightFixtureTestCase {
private static final String ourStubPath = "/opt/IDEA mono/phpstorm/php/resources/stubs/redis/Redis.php";
private static final String prStubPath = "/opt/tools/phpredis-phpdoc/src/Redis.php";
private static final List<String> checkedMethods = Arrays.asList(
//add here method names for those that have been checked already
);
public void testStubPR() {
PhpFile ourPsi = getPhpFile(ourStubPath, "our.php");
PhpFile prPsi = getPhpFile(prStubPath, "pr.php");
List<String> fails = new ArrayList<>();
/*
* Here we check only class level entities. Please improve if needed
*/
Collection<PhpClass> ourClasses = PhpPsiUtil.findAllClasses(ourPsi);
for (PhpClass ourClass : ourClasses) {
String ourClassFQN = ourClass.getFQN();
PhpClass prClass = PhpPsiUtil.findClass(prPsi, aClass -> ourClassFQN.equals(aClass.getFQN()));
if (prClass == null) {
fails.add("Failed to find class " + ourClassFQN);
}
compare(ourClass, prClass);
}
for (String fail : fails) {
System.out.println(fail);
}
assertEmpty(fails);
}
private static void compare(PhpClass ourClass, PhpClass prClass) {
compareOwnConstantFields(ourClass, prClass);
compareMethods(ourClass, prClass);
}
private static void compareMethods(PhpClass ourClass, PhpClass prClass) {
Method[] methods = ourClass.getOwnMethods();
for (Method ourMethod : methods) {
String fqn = ourClass.getName() + "." + ourMethod.getName();
System.out.println(fqn);
Method prMethod = prClass.findOwnMethodByName(ourMethod.getName());
if (prMethod == null) {
failTest(fqn, "Failed to find stub method " + ourClass.getName() + "." + ourMethod.getName());
}
else {
String suspicion = getSuspicionOnMethod(fqn, ourMethod, prMethod);
if (suspicion != null) {
failTestWithDiff(fqn, suspicion + " for " + fqn,
adaptToTC(getTextDescription(ourMethod)),
adaptToTC(getTextDescription(prMethod)));
}
}
}
}
private static void failTestWithDiff(String testName, String message, String expected, String actual) {
System.out.println("\n##teamcity[testStarted name='" + testName + "']");
System.out.println("\n##teamcity[testFailed name='" + testName +
"' message='" + message +
"' expected='" + expected +
"' actual='" + actual + " ']");
System.out.println("\n##teamcity[testFinished name='" + testName + "']");
}
private static void failTest(String testName, String message) {
System.out.println("\n##teamcity[testStarted name='" + testName + "']");
System.out.println("\n##teamcity[testFailed name='" + testName +
"' message='" + message + " ']");
System.out.println("\n##teamcity[testFinished name='" + testName + "']");
}
@NotNull
private static String getTextDescription(Method ourMethod) {
return ourMethod.getDocComment().getText() + "\n" + ourMethod.getText();
}
private static String adaptToTC(String text) {
return text.replace("\\", "||")
.replace("\'", "|' ")
.replace("\n", "|n")
.replace("\r", "|r")
.replace("]", "|]");
}
@Nullable
private static String getSuspicionOnMethod(String fqn, Method ourMethod, Method prMethod) {
if (checkedMethods.contains(fqn)) return null;
PhpDocComment ourComment = ourMethod.getDocComment();
PhpDocComment prComment = prMethod.getDocComment();
if (ourComment != null || prComment != null) {
String ourText = ourComment == null ? "" : ourComment.getText();
String prText = prComment == null ? "" : prComment.getText();
if (!StringUtil.equals(ourText, prText)) {
return "Doc comments are changed";
}
}
Parameter[] ourParameters = ourMethod.getParameters();
Parameter[] prParameters = prMethod.getParameters();
if (ourParameters.length != prParameters.length) {
return "Different length of parameters";
}
TIntHashSet indices = new TIntHashSet();
for (int i = 0; i < ourParameters.length; i++) {
Parameter ourParameter = ourParameters[i];
Parameter prParameter = prParameters[i];
if (!looksEqualParameters(ourParameter, prParameter)) {
indices.add(i);
}
}
if (!indices.isEmpty()) {
return ("Suspicious parameter(s) with number " + indices);
}
return null;
}
private static boolean looksEqualParameters(Parameter our, Parameter pr) {
if (!StringUtil.equals(our.getName(), pr.getName())) return false;
/* boolean ourHasDefaultValue = our.getDefaultValue() != null;
boolean prHasDefaultValue = pr.getDefaultValue() != null;
if (ourHasDefaultValue != prHasDefaultValue) return false;
if (ourHasDefaultValue) {
if (!StringUtil.equals(our.getDefaultValuePresentation(), pr.getDefaultValuePresentation())) return false;
} */
if (!StringUtil.equals(our.getText(), pr.getText())) return false;
return true;
}
private static void compareOwnConstantFields(PhpClass ourClass, PhpClass prClass) {
Field[] ourClassFields = ourClass.getOwnFields();
for (Field field : ourClassFields) {
String fqn = ourClass.getName() + "." + field.getName();
System.out.println(fqn);
assertTrue(field.getName(), field.isConstant());
Field prField = prClass.findOwnFieldByName(field.getName(), true);
if (prField == null) {
failTest(fqn, "Failed to find stub field " + ourClass.getName() + "." + field.getName());
}
else {
compareDocComments(field.getDocComment(), prField.getDocComment());
}
}
}
private static void compareDocComments(PhpDocComment ourComment, PhpDocComment prComment) {
if (ourComment != null || prComment != null) {
String ourText = ourComment == null ? "" : ourComment.getText();
String prText = prComment == null ? "" : prComment.getText();
if (!StringUtil.equals(ourText, prText)) {
System.out.println("===Our===\n" + ourText + "\n===");
System.out.println("===Stub===\n" + prText + "\n===\n\n");
}
}
}
private PhpFile getPhpFile(String path, String targetPath) {
VirtualFile ourFile = myFixture.copyFileToProject(path, targetPath);
assertNotNull(ourFile);
VfsUtil.markDirtyAndRefresh(false, true, false, ourFile);
PsiManager psiManager = PsiManager.getInstance(getProject());
PsiFile ourPsiFile = psiManager.findFile(ourFile);
assertTrue(ourPsiFile instanceof PhpFile);
return (PhpFile)ourPsiFile;
}
@Override
protected String getFixtureTestDataFolder() {
return null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment