package krasa.console; import krasa.actions.AutotestUtils; import org.jetbrains.annotations.*; import com.intellij.execution.filters.*; import com.intellij.lang.xml.XMLLanguage; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diff.*; import com.intellij.openapi.diff.ex.DiffContentFactory; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.*; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.search.PsiShortNamesCache; import com.intellij.testFramework.LightVirtualFile; import com.intellij.ui.awt.RelativePoint; public class ResponseComparatorFilter implements Filter { public static final String prefix = "Response does not match file: "; Data data; @Nullable @Override public Result applyFilter(String line, int entireLength) { if (line == null) { return null; } if (line.substring(0, Math.min(line.length(), 100)).contains("AssertEqualResponseBuilder")) { int path = line.indexOf(prefix); int actual = actualIndex(line); if (path > 0) { data = new Data(); data.path = line.substring(path + prefix.length()).trim(); return new Result(entireLength - line.length() + path, entireLength, new GoToFile(data.path)); } else if (actual > 0 && data != null) { data.actual = line.substring(actual + "Actual: ".length()).trim(); Result result = new Result(entireLength - line.length(), entireLength, new DiffFile(data)); data = null; return result; } } return null; } private int actualIndex(String line) { int i = line.indexOf("Actual: "); if (i <= 0) { i = line.indexOf("actual: "); } return i; } private class GoToFile implements HyperlinkInfo { private String path; public GoToFile(String path) { this.path = path; } @Override public void navigate(Project project) { new OpenFileDescriptor(project, findFile(project, path)).navigate(true); } } private class DiffFile extends HyperlinkInfoBase { private Data data; public DiffFile(Data data) { this.data = data; } @Override public void navigate(@NotNull final Project project, @Nullable RelativePoint hyperlinkLocationPoint) { VirtualFile expected = findFile(project, data.path); if (expected == null) { ConsoleFilterProvider.notificationGroup.createNotification( "File not found " + data.path, MessageType.ERROR).notify(project); return; } String reformat = FormatUtils.reformat(project, data.actual); VirtualFile actualVF = new LightVirtualFile("Actual", XMLLanguage.INSTANCE, reformat); SimpleDiffRequest diffData = DiffContentFactory.compareVirtualFiles(project, actualVF, expected, data.path); // noinspection ConstantConditions diffData.setContentTitles("Actual", expected.getPath()); final DiffContent[] contents = diffData.getContents(); ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { for (DiffContent content : contents) { Document document = content.getDocument(); if (document != null) { FileDocumentManager.getInstance().saveDocument(document); } } } }); DiffManager.getInstance().getDiffTool().show(diffData); } } private VirtualFile findFile(Project project, String path1) { VirtualFile file = null; PsiShortNamesCache instance = PsiShortNamesCache.getInstance(project); String fileName = AutotestUtils.getFileName(path1); PsiFile[] filesByName = getFilesByName(instance, fileName); if (!path1.startsWith("/")) { path1 = "/" + path1; } for (PsiFile psiFile : filesByName) { VirtualFile virtualFile = psiFile.getVirtualFile(); String path = virtualFile.getPath(); if (path.contains(path1)) { file = virtualFile; } } return file; } private PsiFile[] getFilesByName(PsiShortNamesCache instance, String fileName) { PsiFile[] filesByName = instance.getFilesByName(fileName); if (filesByName.length == 0) { filesByName = instance.getFilesByName(fileName + ".xml"); } if (filesByName.length == 0) { filesByName = instance.getFilesByName(fileName + ".json"); } return filesByName; } private static class Data { String path; String actual; @Override public String toString() { final StringBuilder sb = new StringBuilder("Data{"); sb.append("path='").append(path).append('\''); sb.append(", actual='").append(actual).append('\''); sb.append('}'); return sb.toString(); } } }