Last active
August 7, 2019 14:57
-
-
Save Leneshka-jb/f422a573cc71253c1fb1c5b322fe4ce9 to your computer and use it in GitHub Desktop.
PhpStubComparisonTest
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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