public XDebuggerTree( final @NotNull Project project, final @NotNull XDebuggerEditorsProvider editorsProvider, final @Nullable XSourcePosition sourcePosition, final @NotNull String popupActionGroupId, @Nullable XValueMarkers<?, ?> valueMarkers) { myValueMarkers = valueMarkers; myProject = project; myEditorsProvider = editorsProvider; mySourcePosition = sourcePosition; myTreeModel = new DefaultTreeModel(null); setModel(myTreeModel); setCellRenderer(new XDebuggerTreeRenderer()); new TreeLinkMouseListener(new XDebuggerTreeRenderer()) { @Override protected boolean doCacheLastNode() { return false; } @Override protected void handleTagClick(@Nullable Object tag, @NotNull MouseEvent event) { if (tag instanceof XDebuggerTreeNodeHyperlink) { ((XDebuggerTreeNodeHyperlink) tag).onClick(event); } } }.installOn(this); setRootVisible(false); setShowsRootHandles(true); new DoubleClickListener() { @Override protected boolean onDoubleClick(MouseEvent e) { return expandIfEllipsis(); } }.installOn(this); addKeyListener( new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); if (key == KeyEvent.VK_ENTER || key == KeyEvent.VK_SPACE || key == KeyEvent.VK_RIGHT) { expandIfEllipsis(); } } }); if (Boolean.valueOf(System.getProperty("xdebugger.variablesView.rss"))) { new XDebuggerTreeSpeedSearch(this, SPEED_SEARCH_CONVERTER); } else { new TreeSpeedSearch(this, SPEED_SEARCH_CONVERTER); } final ActionManager actionManager = ActionManager.getInstance(); addMouseListener( new PopupHandler() { @Override public void invokePopup(final Component comp, final int x, final int y) { ActionGroup group = (ActionGroup) actionManager.getAction(popupActionGroupId); actionManager .createActionPopupMenu(ActionPlaces.UNKNOWN, group) .getComponent() .show(comp, x, y); } }); registerShortcuts(); setTransferHandler(DEFAULT_TRANSFER_HANDLER); addComponentListener(myMoveListener); }
/** @author yole */ @SuppressWarnings("UseOfSystemOutOrSystemErr") public class PlatformTestUtil { public static final boolean COVERAGE_ENABLED_BUILD = "true".equals(System.getProperty("idea.coverage.enabled.build")); public static final byte[] EMPTY_JAR_BYTES = { 0x50, 0x4b, 0x05, 0x06, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; public static <T> void registerExtension( final ExtensionPointName<T> name, final T t, final Disposable parentDisposable) { registerExtension(Extensions.getRootArea(), name, t, parentDisposable); } public static <T> void registerExtension( final ExtensionsArea area, final ExtensionPointName<T> name, final T t, final Disposable parentDisposable) { final ExtensionPoint<T> extensionPoint = area.getExtensionPoint(name.getName()); extensionPoint.registerExtension(t); Disposer.register( parentDisposable, new Disposable() { @Override public void dispose() { extensionPoint.unregisterExtension(t); } }); } @Nullable protected static String toString(@Nullable Object node, @Nullable Queryable.PrintInfo printInfo) { if (node instanceof AbstractTreeNode) { if (printInfo != null) { return ((AbstractTreeNode) node).toTestString(printInfo); } else { @SuppressWarnings({"deprecation", "UnnecessaryLocalVariable"}) final String presentation = ((AbstractTreeNode) node).getTestPresentation(); return presentation; } } if (node == null) { return "NULL"; } return node.toString(); } public static String print(JTree tree, boolean withSelection) { return print(tree, withSelection, null); } public static String print( JTree tree, boolean withSelection, @Nullable Condition<String> nodePrintCondition) { StringBuilder buffer = new StringBuilder(); final Collection<String> strings = printAsList(tree, withSelection, nodePrintCondition); for (String string : strings) { buffer.append(string).append("\n"); } return buffer.toString(); } public static Collection<String> printAsList( JTree tree, boolean withSelection, @Nullable Condition<String> nodePrintCondition) { Collection<String> strings = new ArrayList<String>(); Object root = tree.getModel().getRoot(); printImpl(tree, root, strings, 0, withSelection, nodePrintCondition); return strings; } private static void printImpl( JTree tree, Object root, Collection<String> strings, int level, boolean withSelection, @Nullable Condition<String> nodePrintCondition) { DefaultMutableTreeNode defaultMutableTreeNode = (DefaultMutableTreeNode) root; final Object userObject = defaultMutableTreeNode.getUserObject(); String nodeText; if (userObject != null) { nodeText = toString(userObject, null); } else { nodeText = "null"; } if (nodePrintCondition != null && !nodePrintCondition.value(nodeText)) return; final StringBuilder buff = new StringBuilder(); StringUtil.repeatSymbol(buff, ' ', level); final boolean expanded = tree.isExpanded(new TreePath(defaultMutableTreeNode.getPath())); if (!defaultMutableTreeNode.isLeaf()) { buff.append(expanded ? "-" : "+"); } final boolean selected = tree.getSelectionModel().isPathSelected(new TreePath(defaultMutableTreeNode.getPath())); if (withSelection && selected) { buff.append("["); } buff.append(nodeText); if (withSelection && selected) { buff.append("]"); } strings.add(buff.toString()); int childCount = tree.getModel().getChildCount(root); if (expanded) { for (int i = 0; i < childCount; i++) { printImpl( tree, tree.getModel().getChild(root, i), strings, level + 1, withSelection, nodePrintCondition); } } } public static void assertTreeEqual(JTree tree, @NonNls String expected) { assertTreeEqual(tree, expected, false); } public static void assertTreeEqualIgnoringNodesOrder(JTree tree, @NonNls String expected) { assertTreeEqualIgnoringNodesOrder(tree, expected, false); } public static void assertTreeEqual(JTree tree, String expected, boolean checkSelected) { String treeStringPresentation = print(tree, checkSelected); assertEquals(expected, treeStringPresentation); } public static void assertTreeEqualIgnoringNodesOrder( JTree tree, String expected, boolean checkSelected) { final Collection<String> actualNodesPresentation = printAsList(tree, checkSelected, null); final List<String> expectedNodes = StringUtil.split(expected, "\n"); UsefulTestCase.assertSameElements(actualNodesPresentation, expectedNodes); } @TestOnly public static void waitForAlarm(final int delay) throws InterruptedException { assert !ApplicationManager.getApplication().isWriteAccessAllowed() : "It's a bad idea to wait for an alarm under the write action. Somebody creates an alarm which requires read action and you are deadlocked."; assert ApplicationManager.getApplication().isDispatchThread(); final AtomicBoolean invoked = new AtomicBoolean(); final Alarm alarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); alarm.addRequest( new Runnable() { @Override public void run() { ApplicationManager.getApplication() .invokeLater( new Runnable() { @Override public void run() { alarm.addRequest( new Runnable() { @Override public void run() { invoked.set(true); } }, delay); } }); } }, delay); UIUtil.dispatchAllInvocationEvents(); boolean sleptAlready = false; while (!invoked.get()) { UIUtil.dispatchAllInvocationEvents(); //noinspection BusyWait Thread.sleep(sleptAlready ? 10 : delay); sleptAlready = true; } UIUtil.dispatchAllInvocationEvents(); } @TestOnly public static void dispatchAllInvocationEventsInIdeEventQueue() throws InterruptedException { assert SwingUtilities.isEventDispatchThread() : Thread.currentThread(); final EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue(); while (true) { AWTEvent event = eventQueue.peekEvent(); if (event == null) break; AWTEvent event1 = eventQueue.getNextEvent(); if (event1 instanceof InvocationEvent) { IdeEventQueue.getInstance().dispatchEvent(event1); } } } private static Date raidDate(Bombed bombed) { final Calendar instance = Calendar.getInstance(); instance.set(Calendar.YEAR, bombed.year()); instance.set(Calendar.MONTH, bombed.month()); instance.set(Calendar.DAY_OF_MONTH, bombed.day()); instance.set(Calendar.HOUR_OF_DAY, bombed.time()); instance.set(Calendar.MINUTE, 0); return instance.getTime(); } public static boolean bombExplodes(Bombed bombedAnnotation) { Date now = new Date(); return now.after(raidDate(bombedAnnotation)); } public static boolean isRotten(Bombed bomb) { long bombRotPeriod = 30L * 24 * 60 * 60 * 1000; // month return new Date().after(new Date(raidDate(bomb).getTime() + bombRotPeriod)); } public static StringBuilder print( AbstractTreeStructure structure, Object node, int currentLevel, @Nullable Comparator comparator, int maxRowCount, char paddingChar, @Nullable Queryable.PrintInfo printInfo) { StringBuilder buffer = new StringBuilder(); doPrint( buffer, currentLevel, node, structure, comparator, maxRowCount, 0, paddingChar, printInfo); return buffer; } private static int doPrint( StringBuilder buffer, int currentLevel, Object node, AbstractTreeStructure structure, @Nullable Comparator comparator, int maxRowCount, int currentLine, char paddingChar, @Nullable Queryable.PrintInfo printInfo) { if (currentLine >= maxRowCount && maxRowCount != -1) return currentLine; StringUtil.repeatSymbol(buffer, paddingChar, currentLevel); buffer.append(toString(node, printInfo)).append("\n"); currentLine++; Object[] children = structure.getChildElements(node); if (comparator != null) { ArrayList<?> list = new ArrayList<Object>(Arrays.asList(children)); @SuppressWarnings({"UnnecessaryLocalVariable", "unchecked"}) Comparator<Object> c = comparator; Collections.sort(list, c); children = ArrayUtil.toObjectArray(list); } for (Object child : children) { currentLine = doPrint( buffer, currentLevel + 1, child, structure, comparator, maxRowCount, currentLine, paddingChar, printInfo); } return currentLine; } public static String print(Object[] objects) { return print(Arrays.asList(objects)); } public static String print(Collection c) { StringBuilder result = new StringBuilder(); for (Iterator iterator = c.iterator(); iterator.hasNext(); ) { Object each = iterator.next(); result.append(toString(each, null)); if (iterator.hasNext()) { result.append("\n"); } } return result.toString(); } public static String print(ListModel model) { StringBuilder result = new StringBuilder(); for (int i = 0; i < model.getSize(); i++) { result.append(toString(model.getElementAt(i), null)); result.append("\n"); } return result.toString(); } public static String print(JTree tree) { return print(tree, false); } public static void assertTreeStructureEquals( final AbstractTreeStructure treeStructure, final String expected) { assertEquals( expected, print(treeStructure, treeStructure.getRootElement(), 0, null, -1, ' ', null).toString()); } public static void invokeNamedAction(final String actionId) { final AnAction action = ActionManager.getInstance().getAction(actionId); assertNotNull(action); final Presentation presentation = new Presentation(); @SuppressWarnings("deprecation") final DataContext context = DataManager.getInstance().getDataContext(); final AnActionEvent event = new AnActionEvent(null, context, "", presentation, ActionManager.getInstance(), 0); action.update(event); Assert.assertTrue(presentation.isEnabled()); action.actionPerformed(event); } public static void assertTiming(final String message, final long expectedMs, final long actual) { if (COVERAGE_ENABLED_BUILD) return; final long expectedOnMyMachine = Math.max(1, expectedMs * Timings.MACHINE_TIMING / Timings.ETALON_TIMING); // Allow 10% more in case of test machine is busy. String logMessage = message; if (actual > expectedOnMyMachine) { int percentage = (int) (100.0 * (actual - expectedOnMyMachine) / expectedOnMyMachine); logMessage += ". Operation took " + percentage + "% longer than expected"; } logMessage += ". Expected on my machine: " + expectedOnMyMachine + "." + " Actual: " + actual + "." + " Expected on Standard machine: " + expectedMs + ";" + " Actual on Standard: " + actual * Timings.ETALON_TIMING / Timings.MACHINE_TIMING + ";" + " Timings: CPU=" + Timings.CPU_TIMING + ", I/O=" + Timings.IO_TIMING + "." + " (" + (int) (Timings.MACHINE_TIMING * 1.0 / Timings.ETALON_TIMING * 100) + "% of the Standard)" + "."; final double acceptableChangeFactor = 1.1; if (actual < expectedOnMyMachine) { System.out.println(logMessage); TeamCityLogger.info(logMessage); } else if (actual < expectedOnMyMachine * acceptableChangeFactor) { TeamCityLogger.warning(logMessage, null); } else { // throw AssertionFailedError to try one more time throw new AssertionFailedError(logMessage); } } /** * example usage: startPerformanceTest("calculating pi",100, * testRunnable).cpuBound().assertTiming(); */ public static TestInfo startPerformanceTest( @NonNls @NotNull String message, int expectedMs, @NotNull ThrowableRunnable test) { return new TestInfo(test, expectedMs, message); } // calculates average of the median values in the selected part of the array. E.g. for part=3 // returns average in the middle third. public static long averageAmongMedians(@NotNull long[] time, int part) { assert part >= 1; int n = time.length; Arrays.sort(time); long total = 0; for (int i = n / 2 - n / part / 2; i < n / 2 + n / part / 2; i++) { total += time[i]; } return total / (n / part); } public static boolean canRunTest(@NotNull Class testCaseClass) { if (GraphicsEnvironment.isHeadless()) { for (Class<?> clazz = testCaseClass; clazz != null; clazz = clazz.getSuperclass()) { if (clazz.getAnnotation(SkipInHeadlessEnvironment.class) != null) { System.out.println( "Class '" + testCaseClass.getName() + "' is skipped because it requires working UI environment"); return false; } } } return true; } public static void assertPathsEqual(@Nullable String expected, @Nullable String actual) { if (expected != null) expected = FileUtil.toSystemIndependentName(expected); if (actual != null) actual = FileUtil.toSystemIndependentName(actual); assertEquals(expected, actual); } public static class TestInfo { private final ThrowableRunnable test; // runnable to measure private final int expectedMs; // millis the test is expected to run private ThrowableRunnable setup; // to run before each test private boolean usesAllCPUCores; // true if the test runs faster on multi-core private int attempts = 4; // number of retries if performance failed private final String message; // to print on fail private boolean adjustForIO = true; // true if test uses IO, timings need to be re-calibrated according to this agent disk // performance private boolean adjustForCPU = true; // true if test uses CPU, timings need to be re-calibrated according to this agent CPU // speed private TestInfo(@NotNull ThrowableRunnable test, int expectedMs, String message) { this.test = test; this.expectedMs = expectedMs; assert expectedMs > 0 : "Expected must be > 0. Was: " + expectedMs; this.message = message; } public TestInfo setup(@NotNull ThrowableRunnable setup) { assert this.setup == null; this.setup = setup; return this; } public TestInfo usesAllCPUCores() { assert adjustForCPU : "This test configured to be io-bound, it cannot use all cores"; usesAllCPUCores = true; return this; } public TestInfo cpuBound() { adjustForIO = false; adjustForCPU = true; return this; } public TestInfo ioBound() { adjustForIO = true; adjustForCPU = false; return this; } public TestInfo attempts(int attempts) { this.attempts = attempts; return this; } public void assertTiming() { assert expectedMs != 0 : "Must call .expect() before run test"; if (COVERAGE_ENABLED_BUILD) return; while (true) { attempts--; long start; try { if (setup != null) setup.run(); start = System.currentTimeMillis(); test.run(); } catch (Throwable throwable) { throw new RuntimeException(throwable); } long finish = System.currentTimeMillis(); long duration = finish - start; int expectedOnMyMachine = expectedMs; if (adjustForCPU) { expectedOnMyMachine = adjust(expectedOnMyMachine, Timings.CPU_TIMING, Timings.ETALON_CPU_TIMING); expectedOnMyMachine = usesAllCPUCores ? expectedOnMyMachine * 8 / JobSchedulerImpl.CORES_COUNT : expectedOnMyMachine; } if (adjustForIO) { expectedOnMyMachine = adjust(expectedOnMyMachine, Timings.IO_TIMING, Timings.ETALON_IO_TIMING); } // Allow 10% more in case of test machine is busy. String logMessage = message; if (duration > expectedOnMyMachine) { int percentage = (int) (100.0 * (duration - expectedOnMyMachine) / expectedOnMyMachine); logMessage += ": " + percentage + "% longer"; } logMessage += ". Expected: " + formatTime(expectedOnMyMachine) + ". Actual: " + formatTime(duration) + "." + Timings.getStatistics(); final double acceptableChangeFactor = 1.1; if (duration < expectedOnMyMachine) { int percentage = (int) (100.0 * (expectedOnMyMachine - duration) / expectedOnMyMachine); logMessage = percentage + "% faster. " + logMessage; TeamCityLogger.info(logMessage); System.out.println("SUCCESS: " + logMessage); } else if (duration < expectedOnMyMachine * acceptableChangeFactor) { TeamCityLogger.warning(logMessage, null); System.out.println("WARNING: " + logMessage); } else { // try one more time if (attempts == 0) { // try { // Object result = // Class.forName("com.intellij.util.ProfilingUtil").getMethod("captureCPUSnapshot").invoke(null); // System.err.println("CPU snapshot captured in '"+result+"'"); // } // catch (Exception e) { // } throw new AssertionFailedError(logMessage); } System.gc(); System.gc(); System.gc(); String s = "Another epic fail (remaining attempts: " + attempts + "): " + logMessage; TeamCityLogger.warning(s, null); System.err.println(s); // if (attempts == 1) { // try { // // Class.forName("com.intellij.util.ProfilingUtil").getMethod("startCPUProfiling").invoke(null); // } // catch (Exception e) { // } // } continue; } break; } } private static String formatTime(long millis) { String hint = ""; DecimalFormat format = new DecimalFormat("#.0", DecimalFormatSymbols.getInstance(Locale.US)); if (millis >= 60 * 1000) hint = format.format(millis / 60 / 1000.f) + "m"; if (millis >= 1000) hint += (hint.isEmpty() ? "" : " ") + format.format(millis / 1000.f) + "s"; String result = millis + "ms"; if (!hint.isEmpty()) { result = result + " (" + hint + ")"; } return result; } private static int adjust(int expectedOnMyMachine, long thisTiming, long ethanolTiming) { // most of our algorithms are quadratic. sad but true. double speed = 1.0 * thisTiming / ethanolTiming; double delta = speed < 1 ? 0.9 + Math.pow(speed - 0.7, 2) : 0.45 + Math.pow(speed - 0.25, 2); expectedOnMyMachine *= delta; return expectedOnMyMachine; } } public static void assertTiming( String message, long expected, @NotNull Runnable actionToMeasure) { assertTiming(message, expected, 4, actionToMeasure); } public static long measure(@NotNull Runnable actionToMeasure) { long start = System.currentTimeMillis(); actionToMeasure.run(); long finish = System.currentTimeMillis(); return finish - start; } public static void assertTiming( String message, long expected, int attempts, @NotNull Runnable actionToMeasure) { while (true) { attempts--; long duration = measure(actionToMeasure); try { assertTiming(message, expected, duration); break; } catch (AssertionFailedError e) { if (attempts == 0) throw e; System.gc(); System.gc(); System.gc(); String s = "Another epic fail (remaining attempts: " + attempts + "): " + e.getMessage(); TeamCityLogger.warning(s, null); System.err.println(s); } } } private static HashMap<String, VirtualFile> buildNameToFileMap( VirtualFile[] files, @Nullable VirtualFileFilter filter) { HashMap<String, VirtualFile> map = new HashMap<String, VirtualFile>(); for (VirtualFile file : files) { if (filter != null && !filter.accept(file)) continue; map.put(file.getName(), file); } return map; } public static void assertDirectoriesEqual(VirtualFile dirAfter, VirtualFile dirBefore) throws IOException { assertDirectoriesEqual(dirAfter, dirBefore, null); } @SuppressWarnings("UnsafeVfsRecursion") public static void assertDirectoriesEqual( VirtualFile dirAfter, VirtualFile dirBefore, @Nullable VirtualFileFilter fileFilter) throws IOException { FileDocumentManager.getInstance().saveAllDocuments(); VirtualFile[] childrenAfter = dirAfter.getChildren(); if (dirAfter.isInLocalFileSystem() && dirAfter.getFileSystem() != TempFileSystem.getInstance()) { File[] ioAfter = new File(dirAfter.getPath()).listFiles(); shallowCompare(childrenAfter, ioAfter); } VirtualFile[] childrenBefore = dirBefore.getChildren(); if (dirBefore.isInLocalFileSystem() && dirBefore.getFileSystem() != TempFileSystem.getInstance()) { File[] ioBefore = new File(dirBefore.getPath()).listFiles(); shallowCompare(childrenBefore, ioBefore); } HashMap<String, VirtualFile> mapAfter = buildNameToFileMap(childrenAfter, fileFilter); HashMap<String, VirtualFile> mapBefore = buildNameToFileMap(childrenBefore, fileFilter); Set<String> keySetAfter = mapAfter.keySet(); Set<String> keySetBefore = mapBefore.keySet(); assertEquals(dirAfter.getPath(), keySetAfter, keySetBefore); for (String name : keySetAfter) { VirtualFile fileAfter = mapAfter.get(name); VirtualFile fileBefore = mapBefore.get(name); if (fileAfter.isDirectory()) { assertDirectoriesEqual(fileAfter, fileBefore, fileFilter); } else { assertFilesEqual(fileAfter, fileBefore); } } } private static void shallowCompare(VirtualFile[] vfs, @Nullable File[] io) { List<String> vfsPaths = new ArrayList<String>(); for (VirtualFile file : vfs) { vfsPaths.add(file.getPath()); } List<String> ioPaths = new ArrayList<String>(); if (io != null) { for (File file : io) { ioPaths.add(file.getPath().replace(File.separatorChar, '/')); } } assertEquals(sortAndJoin(vfsPaths), sortAndJoin(ioPaths)); } private static String sortAndJoin(List<String> strings) { Collections.sort(strings); StringBuilder buf = new StringBuilder(); for (String string : strings) { buf.append(string); buf.append('\n'); } return buf.toString(); } public static void assertFilesEqual(VirtualFile fileAfter, VirtualFile fileBefore) throws IOException { try { assertJarFilesEqual( VfsUtilCore.virtualToIoFile(fileAfter), VfsUtilCore.virtualToIoFile(fileBefore)); } catch (IOException e) { FileDocumentManager manager = FileDocumentManager.getInstance(); Document docBefore = manager.getDocument(fileBefore); boolean canLoadBeforeText = !fileBefore.getFileType().isBinary() || fileBefore.getFileType() == FileTypes.UNKNOWN; String textB = docBefore != null ? docBefore.getText() : !canLoadBeforeText ? null : LoadTextUtil.getTextByBinaryPresentation( fileBefore.contentsToByteArray(false), fileBefore) .toString(); Document docAfter = manager.getDocument(fileAfter); boolean canLoadAfterText = !fileBefore.getFileType().isBinary() || fileBefore.getFileType() == FileTypes.UNKNOWN; String textA = docAfter != null ? docAfter.getText() : !canLoadAfterText ? null : LoadTextUtil.getTextByBinaryPresentation( fileAfter.contentsToByteArray(false), fileAfter) .toString(); if (textA != null && textB != null) { assertEquals(fileAfter.getPath(), textA, textB); } else { Assert.assertArrayEquals( fileAfter.getPath(), fileAfter.contentsToByteArray(), fileBefore.contentsToByteArray()); } } } public static void assertJarFilesEqual(File file1, File file2) throws IOException { final File tempDirectory1; final File tempDirectory2; final JarFile jarFile1 = new JarFile(file1); try { final JarFile jarFile2 = new JarFile(file2); try { tempDirectory1 = PlatformTestCase.createTempDir("tmp1"); tempDirectory2 = PlatformTestCase.createTempDir("tmp2"); ZipUtil.extract(jarFile1, tempDirectory1, null); ZipUtil.extract(jarFile2, tempDirectory2, null); } finally { jarFile2.close(); } } finally { jarFile1.close(); } final VirtualFile dirAfter = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempDirectory1); assertNotNull(tempDirectory1.toString(), dirAfter); final VirtualFile dirBefore = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempDirectory2); assertNotNull(tempDirectory2.toString(), dirBefore); ApplicationManager.getApplication() .runWriteAction( new Runnable() { @Override public void run() { dirAfter.refresh(false, true); dirBefore.refresh(false, true); } }); assertDirectoriesEqual(dirAfter, dirBefore); } public static void assertElementsEqual(final Element expected, final Element actual) throws IOException { if (!JDOMUtil.areElementsEqual(expected, actual)) { junit.framework.Assert.assertEquals(printElement(expected), printElement(actual)); } } public static String printElement(final Element element) throws IOException { final StringWriter writer = new StringWriter(); JDOMUtil.writeElement(element, writer, "\n"); return writer.getBuffer().toString(); } public static String getCommunityPath() { final String homePath = PathManager.getHomePath(); if (new File(homePath, "community").exists()) { return homePath + File.separatorChar + "community"; } return homePath; } public static Comparator<AbstractTreeNode> createComparator(final Queryable.PrintInfo printInfo) { return new Comparator<AbstractTreeNode>() { @Override public int compare(final AbstractTreeNode o1, final AbstractTreeNode o2) { String displayText1 = o1.toTestString(printInfo); String displayText2 = o2.toTestString(printInfo); return Comparing.compare(displayText1, displayText2); } }; } @NotNull public static <T> T notNull(@Nullable T t) { assertNotNull(t); return t; } @NotNull public static String loadFileText(@NotNull String fileName) throws IOException { return StringUtil.convertLineSeparators(FileUtil.loadFile(new File(fileName))); } public static void tryGcSoftlyReachableObjects() { List<Object> list = ContainerUtil.newArrayList(); for (int i = 0; i < 100; i++) { list.add(new SoftReference<byte[]>(new byte[(int) Runtime.getRuntime().freeMemory() / 2])); } } public static void withEncoding(@NotNull String encoding, @NotNull final Runnable r) { withEncoding( encoding, new ThrowableRunnable() { @Override public void run() throws Throwable { r.run(); } }); } public static void withEncoding(@NotNull String encoding, @NotNull ThrowableRunnable r) { Charset oldCharset = Charset.defaultCharset(); try { try { patchSystemFileEncoding(encoding); r.run(); } finally { patchSystemFileEncoding(oldCharset.name()); } } catch (Throwable t) { throw new RuntimeException(t); } } private static void patchSystemFileEncoding(String encoding) throws NoSuchFieldException, IllegalAccessException { Field charset = Charset.class.getDeclaredField("defaultCharset"); charset.setAccessible(true); charset.set(Charset.class, null); System.setProperty("file.encoding", encoding); } }