2 * Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
4 package com
.intellij
.testFramework
;
6 import com
.intellij
.codeInsight
.CodeInsightSettings
;
7 import com
.intellij
.openapi
.Disposable
;
8 import com
.intellij
.openapi
.application
.ApplicationManager
;
9 import com
.intellij
.openapi
.command
.CommandProcessor
;
10 import com
.intellij
.openapi
.fileTypes
.StdFileTypes
;
11 import com
.intellij
.openapi
.project
.Project
;
12 import com
.intellij
.openapi
.util
.Disposer
;
13 import com
.intellij
.openapi
.util
.JDOMExternalizable
;
14 import com
.intellij
.openapi
.util
.JDOMUtil
;
15 import com
.intellij
.openapi
.util
.Key
;
16 import com
.intellij
.openapi
.util
.io
.FileUtil
;
17 import com
.intellij
.openapi
.util
.text
.StringUtil
;
18 import com
.intellij
.psi
.PsiDocumentManager
;
19 import com
.intellij
.psi
.codeStyle
.CodeStyleSettings
;
20 import com
.intellij
.psi
.codeStyle
.CodeStyleSettingsManager
;
21 import com
.intellij
.psi
.impl
.source
.PostprocessReformattingAspect
;
22 import com
.intellij
.util
.Consumer
;
23 import com
.intellij
.util
.Function
;
24 import com
.intellij
.util
.containers
.ContainerUtil
;
25 import com
.intellij
.refactoring
.rename
.inplace
.VariableInplaceRenamer
;
26 import com
.intellij
.testFramework
.exceptionCases
.AbstractExceptionCase
;
27 import gnu
.trove
.THashSet
;
28 import junit
.framework
.Assert
;
29 import junit
.framework
.AssertionFailedError
;
30 import junit
.framework
.TestCase
;
31 import org
.jdom
.Element
;
32 import org
.jetbrains
.annotations
.NonNls
;
33 import org
.jetbrains
.annotations
.Nullable
;
35 import java
.io
.FileReader
;
36 import java
.io
.IOException
;
37 import java
.lang
.reflect
.Field
;
38 import java
.lang
.reflect
.Method
;
39 import java
.lang
.reflect
.Modifier
;
45 public abstract class UsefulTestCase
extends TestCase
{
46 protected final Disposable myTestRootDisposable
= new Disposable() {
47 public void dispose() {
50 private static final String DEFAULT_SETTINGS_EXTERNALIZED
;
51 private static CodeStyleSettings myOldCodeStyleSettings
;
53 protected static final Key
<String
> CREATION_PLACE
= Key
.create("CREATION_PLACE");
57 CodeInsightSettings defaultSettings
= new CodeInsightSettings();
58 Element oldS
= new Element("temp");
59 defaultSettings
.writeExternal(oldS
);
60 DEFAULT_SETTINGS_EXTERNALIZED
= JDOMUtil
.writeElement(oldS
, "\n");
63 throw new RuntimeException(e
);
67 protected void tearDown() throws Exception
{
68 Disposer
.dispose(myTestRootDisposable
);
69 cleanupSwingDataStructures();
73 private static void cleanupSwingDataStructures() throws Exception
{
74 Class
<?
> aClass
= Class
.forName("javax.swing.KeyboardManager");
76 Method get
= aClass
.getMethod("getCurrentManager");
77 get
.setAccessible(true);
78 Object manager
= get
.invoke(null);
80 Field mapF
= aClass
.getDeclaredField("componentKeyStrokeMap");
81 mapF
.setAccessible(true);
82 Object map
= mapF
.get(manager
);
86 Field mapF
= aClass
.getDeclaredField("containerMap");
87 mapF
.setAccessible(true);
88 Object map
= mapF
.get(manager
);
92 //Constructor<?> ctr = aClass.getDeclaredConstructor();
93 //ctr.setAccessible(true);
94 //Object newManager = ctr.newInstance();
95 //Method setter = aClass.getDeclaredMethod("setCurrentManager", aClass);
96 //setter.setAccessible(true);
97 //setter.invoke(null, newManager);
100 protected void checkForSettingsDamage() throws Exception
{
101 if (isPerformanceTest() || ApplicationManager
.getApplication() == null) {
104 final CodeInsightSettings settings
= CodeInsightSettings
.getInstance();
105 Element newS
= new Element("temp");
106 settings
.writeExternal(newS
);
107 Assert
.assertEquals("Code insight settings damaged", DEFAULT_SETTINGS_EXTERNALIZED
, JDOMUtil
.writeElement(newS
, "\n"));
110 CodeStyleSettings codeStyleSettings
= getCurrentCodeStyleSettings();
111 codeStyleSettings
.getIndentOptions(StdFileTypes
.JAVA
);
112 checkSettingsEqual(myOldCodeStyleSettings
, codeStyleSettings
, "Code style settings damaged");
113 codeStyleSettings
.clearCodeStyleSettings();
114 myOldCodeStyleSettings
= null;
116 VariableInplaceRenamer
.checkCleared();
119 protected void storeSettings() {
120 if (!isPerformanceTest() && ApplicationManager
.getApplication() != null) {
121 myOldCodeStyleSettings
= getCurrentCodeStyleSettings().clone();
122 myOldCodeStyleSettings
.getIndentOptions(StdFileTypes
.JAVA
);
126 protected CodeStyleSettings
getCurrentCodeStyleSettings() {
127 return CodeStyleSettingsManager
.getInstance().getCurrentSettings();
130 protected Disposable
getTestRootDisposable() {
131 return myTestRootDisposable
;
135 public static String
toString(Collection
<?
> collection
) {
136 if (collection
.isEmpty()) {
140 final StringBuilder builder
= new StringBuilder();
141 for (final Object o
: collection
) {
142 if (o
instanceof THashSet
) {
143 builder
.append(new TreeSet
<Object
>((Collection
<Object
>)o
));
148 builder
.append("\n");
150 return builder
.toString();
153 public static <T
> void assertOrderedEquals(T
[] actual
, T
... expected
) {
154 assertOrderedEquals(Arrays
.asList(actual
), expected
);
157 public static <T
> void assertOrderedEquals(Collection
<T
> actual
, T
... expected
) {
158 assertOrderedEquals(null, actual
, expected
);
161 public static <T
> void assertOrderedEquals(final String errorMsg
, Collection
<T
> actual
, T
... expected
) {
162 Assert
.assertNotNull(actual
);
163 Assert
.assertNotNull(expected
);
164 assertOrderedEquals(errorMsg
, actual
, Arrays
.asList(expected
));
167 public static <T
> void assertOrderedEquals(final Collection
<?
extends T
> actual
, final Collection
<?
extends T
> expected
) {
168 assertOrderedEquals(null, actual
, expected
);
171 public static <T
> void assertOrderedEquals(final String erroMsg
, final Collection
<?
extends T
> actual
, final Collection
<?
extends T
> expected
) {
172 if (!new ArrayList
<T
>(actual
).equals(new ArrayList
<T
>(expected
))) {
173 Assert
.assertEquals(erroMsg
, toString(expected
), toString(actual
));
178 public static <T
> void assertOrderedCollection(T
[] collection
, Consumer
<T
>... checkers
) {
179 Assert
.assertNotNull(collection
);
180 assertOrderedCollection(Arrays
.asList(collection
), checkers
);
183 public static <T
> void assertSameElements(T
[] collection
, T
... expected
) {
184 assertSameElements(Arrays
.asList(collection
), expected
);
187 public static <T
> void assertSameElements(Collection
<?
extends T
> collection
, T
... expected
) {
188 assertSameElements(collection
, Arrays
.asList(expected
));
190 public static <T
> void assertSameElements(Collection
<?
extends T
> collection
, Collection
<T
> expected
) {
191 if (collection
.size() != expected
.size() || !new HashSet
<T
>(expected
).equals(new HashSet
<T
>(collection
))) {
192 Assert
.assertEquals(toString(expected
, "\n"), toString(collection
, "\n"));
193 Assert
.assertEquals(new HashSet
<T
>(expected
), new HashSet
<T
>(collection
));
197 public static String
toString(Object
[] collection
, String separator
) {
198 return toString(Arrays
.asList(collection
), separator
);
201 public static String
toString(Collection
<?
> collection
, String separator
) {
202 List
<String
> list
= ContainerUtil
.map2List(collection
, new Function
<Object
,String
>() {
203 public String
fun(final Object o
) {
204 return String
.valueOf(o
);
207 Collections
.sort(list
);
208 StringBuilder builder
= new StringBuilder();
209 boolean flag
= false;
210 for (final String o
: list
) {
212 builder
.append(separator
);
217 return builder
.toString();
220 public static <T
> void assertOrderedCollection(Collection
<?
extends T
> collection
, Consumer
<T
>... checkers
) {
221 Assert
.assertNotNull(collection
);
222 if (collection
.size() != checkers
.length
) {
223 Assert
.fail(toString(collection
));
226 for (final T actual
: collection
) {
228 checkers
[i
].consume(actual
);
230 catch (AssertionFailedError e
) {
231 System
.out
.println(i
+ ": " + actual
);
238 public static <T
> void assertUnorderedCollection(T
[] collection
, Consumer
<T
>... checkers
) {
239 assertUnorderedCollection(Arrays
.asList(collection
), checkers
);
242 public static <T
> void assertUnorderedCollection(Collection
<?
extends T
> collection
, Consumer
<T
>... checkers
) {
243 Assert
.assertNotNull(collection
);
244 if (collection
.size() != checkers
.length
) {
245 Assert
.fail(toString(collection
));
247 Set
<Consumer
<T
>> checkerSet
= new HashSet
<Consumer
<T
>>(Arrays
.asList(checkers
));
249 Throwable lastError
= null;
250 for (final T actual
: collection
) {
252 for (final Consumer
<T
> condition
: checkerSet
) {
253 Throwable error
= accepts(condition
, actual
);
255 checkerSet
.remove(condition
);
264 lastError
.printStackTrace();
265 Assert
.fail("Incorrect element(" + i
+ "): " + actual
);
271 private static <T
> Throwable
accepts(final Consumer
<T
> condition
, final T actual
) {
273 condition
.consume(actual
);
276 catch (Throwable e
) {
281 public static <T
> T
assertInstanceOf(Object o
, Class
<T
> aClass
) {
282 Assert
.assertNotNull(o
);
283 Assert
.assertTrue(o
.getClass().getName(), aClass
.isInstance(o
));
287 public static <T
> T
assertOneElement(Collection
<T
> collection
) {
288 Assert
.assertNotNull(collection
);
289 Assert
.assertEquals(toString(collection
), 1, collection
.size());
290 return collection
.iterator().next();
293 public static <T
> T
assertOneElement(T
[] ts
) {
294 Assert
.assertNotNull(ts
);
295 Assert
.assertEquals(1, ts
.length
);
299 public static void printThreadDump() {
300 final Map
<Thread
,StackTraceElement
[]> traces
= Thread
.getAllStackTraces();
301 for (final Map
.Entry
<Thread
, StackTraceElement
[]> entry
: traces
.entrySet()) {
302 System
.out
.println("\n" + entry
.getKey().getName() + "\n");
303 final StackTraceElement
[] value
= entry
.getValue();
304 for (final StackTraceElement stackTraceElement
: value
) {
305 System
.out
.println(" at "+stackTraceElement
);
310 public static void assertEmpty(final Object
[] array
) {
311 assertOrderedEquals(array
);
314 public static void assertEmpty(final Collection
<?
> collection
) {
315 assertEmpty(null, collection
);
318 public static void assertEmpty(final String s
) {
319 assertTrue(s
, StringUtil
.isEmpty(s
));
322 public static void assertEmpty(final String errorMsg
, final Collection
<?
> collection
) {
323 assertOrderedEquals(errorMsg
, collection
);
326 protected <T
extends Disposable
> T
disposeOnTearDown(final T disposable
) {
327 Disposer
.register(myTestRootDisposable
, disposable
);
331 public static void assertSameLines(String expected
, String actual
) {
332 String expectedText
= StringUtil
.convertLineSeparators(expected
.trim());
333 String actualText
= StringUtil
.convertLineSeparators(actual
.trim());
334 Assert
.assertEquals(expectedText
, actualText
);
337 protected String
getTestName(boolean lowercaseFirstLetter
) {
338 String name
= getName();
339 name
= StringUtil
.trimStart(name
, "test");
340 if (StringUtil
.isEmpty(name
)) {
343 if (lowercaseFirstLetter
&& !isAllUppercaseName(name
)) {
344 name
= Character
.toLowerCase(name
.charAt(0)) + name
.substring(1);
349 private static boolean isAllUppercaseName(String name
) {
350 int uppercaseChars
= 0;
351 for(int i
=0; i
<name
.length(); i
++) {
352 if (Character
.isLowerCase(name
.charAt(i
))) {
355 if (Character
.isUpperCase(name
.charAt(i
))) {
359 return uppercaseChars
>= 3;
362 protected String
getTestDirectoryName() {
363 final String testName
= getTestName(true);
364 return testName
.replaceAll("_.*", "");
367 protected static void assertSameLinesWithFile(final String filePath
, final String actualText
) {
370 final FileReader reader
= new FileReader(filePath
);
371 fileText
= FileUtil
.loadTextAndClose(reader
);
373 catch (IOException e
) {
374 throw new RuntimeException(e
);
376 assertSameLines(fileText
, actualText
);
379 public static void clearFields(final Object test
) throws IllegalAccessException
{
380 Class aClass
= test
.getClass();
381 while (aClass
!= null) {
382 clearDeclaredFields(test
, aClass
);
383 aClass
= aClass
.getSuperclass();
387 public static void clearDeclaredFields(Object test
, Class aClass
) throws IllegalAccessException
{
388 if (aClass
== null) return;
389 for (final Field field
: aClass
.getDeclaredFields()) {
390 @NonNls final String name
= field
.getDeclaringClass().getName();
391 if (!name
.startsWith("junit.framework.") && !name
.startsWith("com.intellij.testFramework.")) {
392 final int modifiers
= field
.getModifiers();
393 if ((modifiers
& Modifier
.FINAL
) == 0 && (modifiers
& Modifier
.STATIC
) == 0 && !field
.getType().isPrimitive()) {
394 field
.setAccessible(true);
395 field
.set(test
, null);
401 protected static void checkSettingsEqual(JDOMExternalizable expected
, JDOMExternalizable settings
, String message
) throws Exception
{
402 if (expected
== null) {
405 if (settings
== null) {
408 Element oldS
= new Element("temp");
409 expected
.writeExternal(oldS
);
410 Element newS
= new Element("temp");
411 settings
.writeExternal(newS
);
413 String newString
= JDOMUtil
.writeElement(newS
, "\n");
414 String oldString
= JDOMUtil
.writeElement(oldS
, "\n");
415 Assert
.assertEquals(message
, oldString
, newString
);
418 public boolean isPerformanceTest() {
419 String name
= getName();
420 return name
!= null && name
.contains("Performance") || getClass().getName().contains("Performance");
423 public static void doPostponedFormatting(final Project project
) {
425 CommandProcessor
.getInstance().runUndoTransparentAction(new Runnable() {
427 ApplicationManager
.getApplication().runWriteAction(new Runnable() {
429 PsiDocumentManager
.getInstance(project
).commitAllDocuments();
430 PostprocessReformattingAspect
.getInstance(project
).doPostponedFormatting();
436 catch (Throwable e
) {
441 protected static void checkAllTimersAreDisposed() throws Exception
{
442 Class
<?
> aClass
= Class
.forName("javax.swing.TimerQueue");
444 Method inst
= aClass
.getDeclaredMethod("sharedInstance");
445 inst
.setAccessible(true);
446 Object queue
= inst
.invoke(null);
447 Field field
= aClass
.getDeclaredField("firstTimer");
448 field
.setAccessible(true);
449 Object firstTimer
= field
.get(queue
);
450 if (firstTimer
!= null) {
452 fail("Not disposed Timer: "+firstTimer
.toString()+"; queue:"+queue
);
455 field
.set(queue
, null);
461 * Checks that code block throw corresponding exception.
462 * @param exceptionCase Block annotated with some exception type
465 protected void assertException(final AbstractExceptionCase exceptionCase
) throws Throwable
{
466 assertException(exceptionCase
, null);
470 * Checks that code block throw corresponding exception with expected error msg.
471 * If expected error message is null it will not be checked.
472 * @param exceptionCase Block annotated with some exception type
473 * @param expectedErrorMsg expected error messge
476 protected void assertException(final AbstractExceptionCase exceptionCase
,
477 @Nullable final String expectedErrorMsg
) throws Throwable
{
478 assertExceptionOccurred(true, exceptionCase
, expectedErrorMsg
);
482 * Checks that code block doesn't throw corresponding exception.
483 * @param exceptionCase Block annotated with some exception type
486 protected void assertNoException(final AbstractExceptionCase exceptionCase
) throws Throwable
{
487 assertExceptionOccurred(false, exceptionCase
, null);
490 protected void assertNoThrowable(final Runnable closure
) {
491 String throwableName
= null;
494 } catch (Throwable thr
) {
495 throwableName
= thr
.getClass().getName();
497 assertNull(throwableName
);
500 private void assertExceptionOccurred(boolean shouldOccur
,
501 AbstractExceptionCase exceptionCase
,
502 String expectedErrorMsg
) throws Throwable
{
503 boolean wasThrown
= false;
505 exceptionCase
.tryClosure();
506 } catch (Throwable e
) {
509 final String errorMessage
= exceptionCase
.getAssertionErrorMessage();
510 assertEquals(errorMessage
, exceptionCase
.getExpectedExceptionClass(), e
.getClass());
511 if (expectedErrorMsg
!= null) {
512 assertEquals("Compare error messages", expectedErrorMsg
, e
.getMessage());
514 } else if (exceptionCase
.getExpectedExceptionClass().equals(e
.getClass())) {
517 System
.out
.println("");
518 e
.printStackTrace(System
.out
);
520 fail("Exception isn't expected here. Exception message: " + e
.getMessage());
525 if (shouldOccur
&& !wasThrown
) {
526 fail(exceptionCase
.getAssertionErrorMessage());