restore settings after fail
[fedora-idea.git] / platform / testFramework / src / com / intellij / testFramework / UsefulTestCase.java
blob39a7eb0757fbcffb7ac22b78376d3dd4ad0656a3
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.testFramework;
18 import com.intellij.codeInsight.CodeInsightSettings;
19 import com.intellij.openapi.Disposable;
20 import com.intellij.openapi.application.ApplicationManager;
21 import com.intellij.openapi.command.CommandProcessor;
22 import com.intellij.openapi.fileTypes.StdFileTypes;
23 import com.intellij.openapi.project.Project;
24 import com.intellij.openapi.util.Disposer;
25 import com.intellij.openapi.util.JDOMExternalizable;
26 import com.intellij.openapi.util.JDOMUtil;
27 import com.intellij.openapi.util.Key;
28 import com.intellij.openapi.util.io.FileUtil;
29 import com.intellij.openapi.util.text.StringUtil;
30 import com.intellij.psi.PsiDocumentManager;
31 import com.intellij.psi.codeStyle.CodeStyleSettings;
32 import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
33 import com.intellij.psi.impl.source.PostprocessReformattingAspect;
34 import com.intellij.util.Consumer;
35 import com.intellij.util.Function;
36 import com.intellij.util.containers.ContainerUtil;
37 import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer;
38 import com.intellij.testFramework.exceptionCases.AbstractExceptionCase;
39 import gnu.trove.THashSet;
40 import junit.framework.Assert;
41 import junit.framework.AssertionFailedError;
42 import junit.framework.TestCase;
43 import org.jdom.Element;
44 import org.jetbrains.annotations.NonNls;
45 import org.jetbrains.annotations.Nullable;
47 import java.io.FileReader;
48 import java.io.IOException;
49 import java.lang.reflect.Field;
50 import java.lang.reflect.Method;
51 import java.lang.reflect.Modifier;
52 import java.util.*;
54 /**
55 * @author peter
57 public abstract class UsefulTestCase extends TestCase {
58 protected final Disposable myTestRootDisposable = new Disposable() {
59 public void dispose() {
62 private static final String DEFAULT_SETTINGS_EXTERNALIZED;
63 private static CodeStyleSettings myOldCodeStyleSettings;
65 protected static final Key<String> CREATION_PLACE = Key.create("CREATION_PLACE");
67 static {
68 try {
69 CodeInsightSettings defaultSettings = new CodeInsightSettings();
70 Element oldS = new Element("temp");
71 defaultSettings.writeExternal(oldS);
72 DEFAULT_SETTINGS_EXTERNALIZED = JDOMUtil.writeElement(oldS, "\n");
74 catch (Exception e) {
75 throw new RuntimeException(e);
79 protected void tearDown() throws Exception {
80 Disposer.dispose(myTestRootDisposable);
81 cleanupSwingDataStructures();
82 super.tearDown();
85 private static void cleanupSwingDataStructures() throws Exception {
86 Class<?> aClass = Class.forName("javax.swing.KeyboardManager");
88 Method get = aClass.getMethod("getCurrentManager");
89 get.setAccessible(true);
90 Object manager = get.invoke(null);
92 Field mapF = aClass.getDeclaredField("componentKeyStrokeMap");
93 mapF.setAccessible(true);
94 Object map = mapF.get(manager);
95 ((Map)map).clear();
98 Field mapF = aClass.getDeclaredField("containerMap");
99 mapF.setAccessible(true);
100 Object map = mapF.get(manager);
101 ((Map)map).clear();
104 //Constructor<?> ctr = aClass.getDeclaredConstructor();
105 //ctr.setAccessible(true);
106 //Object newManager = ctr.newInstance();
107 //Method setter = aClass.getDeclaredMethod("setCurrentManager", aClass);
108 //setter.setAccessible(true);
109 //setter.invoke(null, newManager);
112 protected void checkForSettingsDamage() throws Exception {
113 if (isPerformanceTest() || ApplicationManager.getApplication() == null) {
114 return;
116 final CodeInsightSettings settings = CodeInsightSettings.getInstance();
117 Element newS = new Element("temp");
118 settings.writeExternal(newS);
119 Assert.assertEquals("Code insight settings damaged", DEFAULT_SETTINGS_EXTERNALIZED, JDOMUtil.writeElement(newS, "\n"));
122 CodeStyleSettings codeStyleSettings = getCurrentCodeStyleSettings();
123 codeStyleSettings.getIndentOptions(StdFileTypes.JAVA);
124 try {
125 checkSettingsEqual(myOldCodeStyleSettings, codeStyleSettings, "Code style settings damaged");
127 finally {
128 codeStyleSettings.clearCodeStyleSettings();
130 myOldCodeStyleSettings = null;
132 VariableInplaceRenamer.checkCleared();
135 protected void storeSettings() {
136 if (!isPerformanceTest() && ApplicationManager.getApplication() != null) {
137 myOldCodeStyleSettings = getCurrentCodeStyleSettings().clone();
138 myOldCodeStyleSettings.getIndentOptions(StdFileTypes.JAVA);
142 protected CodeStyleSettings getCurrentCodeStyleSettings() {
143 return CodeStyleSettingsManager.getInstance().getCurrentSettings();
146 protected Disposable getTestRootDisposable() {
147 return myTestRootDisposable;
150 @NonNls
151 public static String toString(Collection<?> collection) {
152 if (collection.isEmpty()) {
153 return "<empty>";
156 final StringBuilder builder = new StringBuilder();
157 for (final Object o : collection) {
158 if (o instanceof THashSet) {
159 builder.append(new TreeSet<Object>((Collection<Object>)o));
161 else {
162 builder.append(o);
164 builder.append("\n");
166 return builder.toString();
169 public static <T> void assertOrderedEquals(T[] actual, T... expected) {
170 assertOrderedEquals(Arrays.asList(actual), expected);
173 public static <T> void assertOrderedEquals(Collection<T> actual, T... expected) {
174 assertOrderedEquals(null, actual, expected);
177 public static <T> void assertOrderedEquals(final String errorMsg, Collection<T> actual, T... expected) {
178 Assert.assertNotNull(actual);
179 Assert.assertNotNull(expected);
180 assertOrderedEquals(errorMsg, actual, Arrays.asList(expected));
183 public static <T> void assertOrderedEquals(final Collection<? extends T> actual, final Collection<? extends T> expected) {
184 assertOrderedEquals(null, actual, expected);
187 public static <T> void assertOrderedEquals(final String erroMsg, final Collection<? extends T> actual, final Collection<? extends T> expected) {
188 if (!new ArrayList<T>(actual).equals(new ArrayList<T>(expected))) {
189 Assert.assertEquals(erroMsg, toString(expected), toString(actual));
190 Assert.fail();
194 public static <T> void assertOrderedCollection(T[] collection, Consumer<T>... checkers) {
195 Assert.assertNotNull(collection);
196 assertOrderedCollection(Arrays.asList(collection), checkers);
199 public static <T> void assertSameElements(T[] collection, T... expected) {
200 assertSameElements(Arrays.asList(collection), expected);
203 public static <T> void assertSameElements(Collection<? extends T> collection, T... expected) {
204 assertSameElements(collection, Arrays.asList(expected));
206 public static <T> void assertSameElements(Collection<? extends T> collection, Collection<T> expected) {
207 if (collection.size() != expected.size() || !new HashSet<T>(expected).equals(new HashSet<T>(collection))) {
208 Assert.assertEquals(toString(expected, "\n"), toString(collection, "\n"));
209 Assert.assertEquals(new HashSet<T>(expected), new HashSet<T>(collection));
213 public static String toString(Object[] collection, String separator) {
214 return toString(Arrays.asList(collection), separator);
217 public static String toString(Collection<?> collection, String separator) {
218 List<String> list = ContainerUtil.map2List(collection, new Function<Object,String>() {
219 public String fun(final Object o) {
220 return String.valueOf(o);
223 Collections.sort(list);
224 StringBuilder builder = new StringBuilder();
225 boolean flag = false;
226 for (final String o : list) {
227 if (flag) {
228 builder.append(separator);
230 builder.append(o);
231 flag = true;
233 return builder.toString();
236 public static <T> void assertOrderedCollection(Collection<? extends T> collection, Consumer<T>... checkers) {
237 Assert.assertNotNull(collection);
238 if (collection.size() != checkers.length) {
239 Assert.fail(toString(collection));
241 int i = 0;
242 for (final T actual : collection) {
243 try {
244 checkers[i].consume(actual);
246 catch (AssertionFailedError e) {
247 System.out.println(i + ": " + actual);
248 throw e;
250 i++;
254 public static <T> void assertUnorderedCollection(T[] collection, Consumer<T>... checkers) {
255 assertUnorderedCollection(Arrays.asList(collection), checkers);
258 public static <T> void assertUnorderedCollection(Collection<? extends T> collection, Consumer<T>... checkers) {
259 Assert.assertNotNull(collection);
260 if (collection.size() != checkers.length) {
261 Assert.fail(toString(collection));
263 Set<Consumer<T>> checkerSet = new HashSet<Consumer<T>>(Arrays.asList(checkers));
264 int i = 0;
265 Throwable lastError = null;
266 for (final T actual : collection) {
267 boolean flag = true;
268 for (final Consumer<T> condition : checkerSet) {
269 Throwable error = accepts(condition, actual);
270 if (error == null) {
271 checkerSet.remove(condition);
272 flag = false;
273 break;
275 else {
276 lastError = error;
279 if (flag) {
280 lastError.printStackTrace();
281 Assert.fail("Incorrect element(" + i + "): " + actual);
283 i++;
287 private static <T> Throwable accepts(final Consumer<T> condition, final T actual) {
288 try {
289 condition.consume(actual);
290 return null;
292 catch (Throwable e) {
293 return e;
297 public static <T> T assertInstanceOf(Object o, Class<T> aClass) {
298 Assert.assertNotNull(o);
299 Assert.assertTrue(o.getClass().getName(), aClass.isInstance(o));
300 return (T)o;
303 public static <T> T assertOneElement(Collection<T> collection) {
304 Assert.assertNotNull(collection);
305 Assert.assertEquals(toString(collection), 1, collection.size());
306 return collection.iterator().next();
309 public static <T> T assertOneElement(T[] ts) {
310 Assert.assertNotNull(ts);
311 Assert.assertEquals(1, ts.length);
312 return ts[0];
315 public static void printThreadDump() {
316 final Map<Thread,StackTraceElement[]> traces = Thread.getAllStackTraces();
317 for (final Map.Entry<Thread, StackTraceElement[]> entry : traces.entrySet()) {
318 System.out.println("\n" + entry.getKey().getName() + "\n");
319 final StackTraceElement[] value = entry.getValue();
320 for (final StackTraceElement stackTraceElement : value) {
321 System.out.println(" at "+stackTraceElement);
326 public static void assertEmpty(final Object[] array) {
327 assertOrderedEquals(array);
330 public static void assertEmpty(final Collection<?> collection) {
331 assertEmpty(null, collection);
334 public static void assertEmpty(final String s) {
335 assertTrue(s, StringUtil.isEmpty(s));
338 public static void assertEmpty(final String errorMsg, final Collection<?> collection) {
339 assertOrderedEquals(errorMsg, collection);
342 protected <T extends Disposable> T disposeOnTearDown(final T disposable) {
343 Disposer.register(myTestRootDisposable, disposable);
344 return disposable;
347 public static void assertSameLines(String expected, String actual) {
348 String expectedText = StringUtil.convertLineSeparators(expected.trim());
349 String actualText = StringUtil.convertLineSeparators(actual.trim());
350 Assert.assertEquals(expectedText, actualText);
353 protected String getTestName(boolean lowercaseFirstLetter) {
354 String name = getName();
355 name = StringUtil.trimStart(name, "test");
356 if (StringUtil.isEmpty(name)) {
357 return "";
359 if (lowercaseFirstLetter && !isAllUppercaseName(name)) {
360 name = Character.toLowerCase(name.charAt(0)) + name.substring(1);
362 return name;
365 public static boolean isAllUppercaseName(String name) {
366 int uppercaseChars = 0;
367 for(int i=0; i<name.length(); i++) {
368 if (Character.isLowerCase(name.charAt(i))) {
369 return false;
371 if (Character.isUpperCase(name.charAt(i))) {
372 uppercaseChars++;
375 return uppercaseChars >= 3;
378 protected String getTestDirectoryName() {
379 final String testName = getTestName(true);
380 return testName.replaceAll("_.*", "");
383 protected static void assertSameLinesWithFile(final String filePath, final String actualText) {
384 String fileText;
385 try {
386 final FileReader reader = new FileReader(filePath);
387 fileText = FileUtil.loadTextAndClose(reader);
389 catch (IOException e) {
390 throw new RuntimeException(e);
392 assertSameLines(fileText, actualText);
395 public static void clearFields(final Object test) throws IllegalAccessException {
396 Class aClass = test.getClass();
397 while (aClass != null) {
398 clearDeclaredFields(test, aClass);
399 aClass = aClass.getSuperclass();
403 public static void clearDeclaredFields(Object test, Class aClass) throws IllegalAccessException {
404 if (aClass == null) return;
405 for (final Field field : aClass.getDeclaredFields()) {
406 @NonNls final String name = field.getDeclaringClass().getName();
407 if (!name.startsWith("junit.framework.") && !name.startsWith("com.intellij.testFramework.")) {
408 final int modifiers = field.getModifiers();
409 if ((modifiers & Modifier.FINAL) == 0 && (modifiers & Modifier.STATIC) == 0 && !field.getType().isPrimitive()) {
410 field.setAccessible(true);
411 field.set(test, null);
417 protected static void checkSettingsEqual(JDOMExternalizable expected, JDOMExternalizable settings, String message) throws Exception {
418 if (expected == null) {
419 return;
421 if (settings == null) {
422 return;
424 Element oldS = new Element("temp");
425 expected.writeExternal(oldS);
426 Element newS = new Element("temp");
427 settings.writeExternal(newS);
429 String newString = JDOMUtil.writeElement(newS, "\n");
430 String oldString = JDOMUtil.writeElement(oldS, "\n");
431 Assert.assertEquals(message, oldString, newString);
434 public boolean isPerformanceTest() {
435 String name = getName();
436 return name != null && name.contains("Performance") || getClass().getName().contains("Performance");
439 public static void doPostponedFormatting(final Project project) {
440 try {
441 CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() {
442 public void run() {
443 ApplicationManager.getApplication().runWriteAction(new Runnable() {
444 public void run() {
445 PsiDocumentManager.getInstance(project).commitAllDocuments();
446 PostprocessReformattingAspect.getInstance(project).doPostponedFormatting();
452 catch (Throwable e) {
453 // Way to go...
457 protected static void checkAllTimersAreDisposed() throws Exception {
458 Class<?> aClass = Class.forName("javax.swing.TimerQueue");
460 Method inst = aClass.getDeclaredMethod("sharedInstance");
461 inst.setAccessible(true);
462 Object queue = inst.invoke(null);
463 Field field = aClass.getDeclaredField("firstTimer");
464 field.setAccessible(true);
465 Object firstTimer = field.get(queue);
466 if (firstTimer != null) {
467 try {
468 fail("Not disposed Timer: "+firstTimer.toString()+"; queue:"+queue);
470 finally {
471 field.set(queue, null);
477 * Checks that code block throw corresponding exception.
478 * @param exceptionCase Block annotated with some exception type
479 * @throws Throwable
481 protected void assertException(final AbstractExceptionCase exceptionCase) throws Throwable {
482 assertException(exceptionCase, null);
486 * Checks that code block throw corresponding exception with expected error msg.
487 * If expected error message is null it will not be checked.
488 * @param exceptionCase Block annotated with some exception type
489 * @param expectedErrorMsg expected error messge
490 * @throws Throwable
492 protected void assertException(final AbstractExceptionCase exceptionCase,
493 @Nullable final String expectedErrorMsg) throws Throwable {
494 assertExceptionOccurred(true, exceptionCase, expectedErrorMsg);
498 * Checks that code block doesn't throw corresponding exception.
499 * @param exceptionCase Block annotated with some exception type
500 * @throws Throwable
502 protected void assertNoException(final AbstractExceptionCase exceptionCase) throws Throwable {
503 assertExceptionOccurred(false, exceptionCase, null);
506 protected void assertNoThrowable(final Runnable closure) {
507 String throwableName = null;
508 try{
509 closure.run();
510 } catch (Throwable thr) {
511 throwableName = thr.getClass().getName();
513 assertNull(throwableName);
516 private void assertExceptionOccurred(boolean shouldOccur,
517 AbstractExceptionCase exceptionCase,
518 String expectedErrorMsg) throws Throwable {
519 boolean wasThrown = false;
520 try {
521 exceptionCase.tryClosure();
522 } catch (Throwable e) {
523 if (shouldOccur) {
524 wasThrown = true;
525 final String errorMessage = exceptionCase.getAssertionErrorMessage();
526 assertEquals(errorMessage, exceptionCase.getExpectedExceptionClass(), e.getClass());
527 if (expectedErrorMsg != null) {
528 assertEquals("Compare error messages", expectedErrorMsg, e.getMessage());
530 } else if (exceptionCase.getExpectedExceptionClass().equals(e.getClass())) {
531 wasThrown = true;
533 System.out.println("");
534 e.printStackTrace(System.out);
536 fail("Exception isn't expected here. Exception message: " + e.getMessage());
537 } else {
538 throw e;
540 } finally {
541 if (shouldOccur && !wasThrown) {
542 fail(exceptionCase.getAssertionErrorMessage());