Merge remote-tracking branch 'origin/master'
[idea/community.git] / plugins / junit / test / com / intellij / execution / junit / JUnitTreeByDescriptionHierarchyTest.java
1 /*
2  * Copyright 2000-2015 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package com.intellij.execution.junit;
17
18 import com.intellij.junit4.JUnit4TestListener;
19 import com.intellij.openapi.util.text.StringUtil;
20 import junit.framework.Assert;
21 import org.junit.Test;
22 import org.junit.runner.Description;
23 import org.junit.runner.Result;
24 import org.junit.runner.notification.Failure;
25
26 import java.io.IOException;
27 import java.io.OutputStream;
28 import java.io.PrintStream;
29 import java.util.ArrayList;
30 import java.util.Collections;
31 import java.util.List;
32
33 public class JUnitTreeByDescriptionHierarchyTest {
34   @Test
35   public void testEmptySuite() throws Exception {
36     doTest(Description.createSuiteDescription("empty suite"), "##teamcity[enteredTheMatrix]\n" +
37                                                               "##teamcity[treeEnded]\n");
38   }
39
40   @Test
41   public void test2Parameterized() throws Exception {
42     final Description root = Description.createSuiteDescription("root");
43     final ArrayList<Description> tests = new ArrayList<Description>();
44     for (String className : new String[]{"a.TestA", "a.TestB"}) {
45       final Description aTestClass = Description.createSuiteDescription(className);
46       root.addChild(aTestClass);
47       attachParameterizedTests(className, aTestClass, tests);
48     }
49     doTest(root, tests,
50            "##teamcity[enteredTheMatrix]\n" +
51            "##teamcity[suiteTreeStarted name='TestA' locationHint='java:suite://a.TestA']\n" +
52            "##teamcity[suiteTreeStarted name='|[0|]' locationHint='java:suite://a.TestA.|[0|]']\n" +
53            "##teamcity[suiteTreeNode name='testName|[0|]' locationHint='java:test://a.TestA.testName|[0|]']\n" +
54            "##teamcity[suiteTreeEnded name='|[0|]']\n" +
55            "##teamcity[suiteTreeStarted name='|[1|]' locationHint='java:suite://a.TestA.|[1|]']\n" +
56            "##teamcity[suiteTreeNode name='testName|[1|]' locationHint='java:test://a.TestA.testName|[1|]']\n" +
57            "##teamcity[suiteTreeEnded name='|[1|]']\n" +
58            "##teamcity[suiteTreeEnded name='TestA']\n" +
59            "##teamcity[suiteTreeStarted name='TestB' locationHint='java:suite://a.TestB']\n" +
60            "##teamcity[suiteTreeStarted name='|[0|]' locationHint='java:suite://a.TestB.|[0|]']\n" +
61            "##teamcity[suiteTreeNode name='testName|[0|]' locationHint='java:test://a.TestB.testName|[0|]']\n" +
62            "##teamcity[suiteTreeEnded name='|[0|]']\n" +
63            "##teamcity[suiteTreeStarted name='|[1|]' locationHint='java:suite://a.TestB.|[1|]']\n" +
64            "##teamcity[suiteTreeNode name='testName|[1|]' locationHint='java:test://a.TestB.testName|[1|]']\n" +
65            "##teamcity[suiteTreeEnded name='|[1|]']\n" +
66            "##teamcity[suiteTreeEnded name='TestB']\n" +
67            "##teamcity[treeEnded]\n",
68
69
70            "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" +
71            "##teamcity[testSuiteStarted name='TestA']\n" +
72            "##teamcity[testSuiteStarted name='|[0|]']\n" +
73            "\n" +
74            "##teamcity[testStarted name='testName|[0|]' locationHint='java:test://a.TestA.testName|[0|]']\n" +
75            "\n" +
76            "##teamcity[testFinished name='testName|[0|]']\n" +
77            "##teamcity[testSuiteFinished name='|[0|]']\n" +
78            "##teamcity[testSuiteStarted name='|[1|]']\n" +
79            "\n" +
80            "##teamcity[testStarted name='testName|[1|]' locationHint='java:test://a.TestA.testName|[1|]']\n" +
81            "\n" +
82            "##teamcity[testFinished name='testName|[1|]']\n" +
83            "##teamcity[testSuiteFinished name='|[1|]']\n" +
84            "##teamcity[testSuiteFinished name='TestA']\n" +
85            "##teamcity[testSuiteStarted name='TestB']\n" +
86            "##teamcity[testSuiteStarted name='|[0|]']\n" +
87            "\n" +
88            "##teamcity[testStarted name='testName|[0|]' locationHint='java:test://a.TestB.testName|[0|]']\n" +
89            "\n" +
90            "##teamcity[testFinished name='testName|[0|]']\n" +
91            "##teamcity[testSuiteFinished name='|[0|]']\n" +
92            "##teamcity[testSuiteStarted name='|[1|]']\n" +
93            "\n" +
94            "##teamcity[testStarted name='testName|[1|]' locationHint='java:test://a.TestB.testName|[1|]']\n" +
95            "\n" +
96            "##teamcity[testFinished name='testName|[1|]']\n" +
97            "##teamcity[testSuiteFinished name='|[1|]']\n" +
98            "##teamcity[testSuiteFinished name='TestB']\n");
99   }
100
101   @Test
102   public void testClassWithMethodsWithoutSendTreeBefore() throws Exception {
103     Description root = Description.createSuiteDescription("ATest");
104     List<Description> tests = new ArrayList<Description>();
105     tests.add(Description.createTestDescription("ATest", "test1"));
106     tests.add(Description.createTestDescription("ATest", "test2"));
107
108     for (Description test : tests) {
109       root.addChild(test);
110     }
111
112     final StringBuffer buf = new StringBuffer();
113     JUnit4TestListener sender = createListener(buf);
114     
115     sender.testRunStarted(root);
116     for (Description test : tests) {
117       sender.testStarted(test);
118       sender.testFinished(test);
119     }
120     sender.testRunFinished(new Result());
121     Assert.assertEquals("output: " + buf, "##teamcity[enteredTheMatrix]\n" +
122                                           "##teamcity[testSuiteStarted name='ATest' locationHint='java:suite://ATest']\n" +
123                                           "\n" +
124                                           "##teamcity[testStarted name='ATest.test1' locationHint='java:test://ATest.test1']\n" +
125                                           "\n" +
126                                           "##teamcity[testFinished name='ATest.test1']\n" +
127                                           "\n" +
128                                           "##teamcity[testStarted name='ATest.test2' locationHint='java:test://ATest.test2']\n" +
129                                           "\n" +
130                                           "##teamcity[testFinished name='ATest.test2']\n" +
131                                           "##teamcity[testSuiteFinished name='ATest']\n", StringUtil.convertLineSeparators(buf.toString()));
132   }
133
134   @Test
135   public void testSameShortNames() throws Exception {
136     final Description rootDescription = Description.createSuiteDescription("root");
137     final ArrayList<Description> tests = new ArrayList<Description>();
138     for (String className : new String[]{"a.MyTest", "b.MyTest"}) {
139       final Description aTestClass = Description.createSuiteDescription(className);
140       rootDescription.addChild(aTestClass);
141       final Description testDescription = Description.createTestDescription(className, "testMe");
142       tests.add(testDescription);
143       aTestClass.addChild(testDescription);
144     }
145     doTest(rootDescription, tests, "##teamcity[enteredTheMatrix]\n" +
146                                    "##teamcity[suiteTreeStarted name='MyTest' locationHint='java:suite://a.MyTest']\n" +
147                                    "##teamcity[suiteTreeNode name='MyTest.testMe' locationHint='java:test://a.MyTest.testMe']\n" +
148                                    "##teamcity[suiteTreeEnded name='MyTest']\n" +
149                                    "##teamcity[suiteTreeStarted name='MyTest' locationHint='java:suite://b.MyTest']\n" +
150                                    "##teamcity[suiteTreeNode name='MyTest.testMe' locationHint='java:test://b.MyTest.testMe']\n" +
151                                    "##teamcity[suiteTreeEnded name='MyTest']\n" +
152                                    "##teamcity[treeEnded]\n",
153            "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" +
154            "##teamcity[testSuiteStarted name='MyTest']\n" +
155            "\n" +
156            "##teamcity[testStarted name='MyTest.testMe' locationHint='java:test://a.MyTest.testMe']\n" +
157            "\n" +
158            "##teamcity[testFinished name='MyTest.testMe']\n" +
159            "##teamcity[testSuiteFinished name='MyTest']\n" +
160            "##teamcity[testSuiteStarted name='MyTest']\n" +
161            "\n" +
162            "##teamcity[testStarted name='MyTest.testMe' locationHint='java:test://b.MyTest.testMe']\n" +
163            "\n" +
164            "##teamcity[testFinished name='MyTest.testMe']\n" +
165            "##teamcity[testSuiteFinished nam" +
166            "e='MyTest']\n");
167   }
168
169   @Test
170   public void testSingleParameterizedClass() throws Exception {
171     final String className = "a.TestA";
172     final Description aTestClassDescription = Description.createSuiteDescription(className);
173     final ArrayList<Description> tests = new ArrayList<Description>();
174     attachParameterizedTests(className, aTestClassDescription, tests);
175     doTest(aTestClassDescription, tests,
176            //tree
177            "##teamcity[enteredTheMatrix]\n" +
178            "##teamcity[suiteTreeStarted name='|[0|]' locationHint='java:suite://a.TestA.|[0|]']\n" +
179            "##teamcity[suiteTreeNode name='testName|[0|]' locationHint='java:test://a.TestA.testName|[0|]']\n" +
180            "##teamcity[suiteTreeEnded name='|[0|]']\n" +
181            "##teamcity[suiteTreeStarted name='|[1|]' locationHint='java:suite://a.TestA.|[1|]']\n" +
182            "##teamcity[suiteTreeNode name='testName|[1|]' locationHint='java:test://a.TestA.testName|[1|]']\n" +
183            "##teamcity[suiteTreeEnded name='|[1|]']\n" +
184            "##teamcity[treeEnded]\n",
185            //start
186            "##teamcity[rootName name = 'TestA' comment = 'a' location = 'java:suite://a.TestA']\n" +
187            "##teamcity[testSuiteStarted name='|[0|]']\n" +
188            "\n" +
189            "##teamcity[testStarted name='testName|[0|]' locationHint='java:test://a.TestA.testName|[0|]']\n" +
190            "\n" +
191            "##teamcity[testFinished name='testName|[0|]']\n" +
192            "##teamcity[testSuiteFinished name='|[0|]']\n" +
193            "##teamcity[testSuiteStarted name='|[1|]']\n" +
194            "\n" +
195            "##teamcity[testStarted name='testName|[1|]' locationHint='java:test://a.TestA.testName|[1|]']\n" +
196            "\n" +
197            "##teamcity[testFinished name='testName|[1|]']\n" +
198            "##teamcity[testSuiteFinished name='|[1|]']\n");
199   }
200   
201   @Test
202   public void testParameterizedClassWithSameParameters() throws Exception {
203     final String className = "a.TestA";
204     final Description aTestClassDescription = Description.createSuiteDescription(className);
205     final ArrayList<Description> tests = new ArrayList<Description>();
206     for (String paramName : new String[]{"[0]", "[0]"}) {
207       final Description param1 = Description.createSuiteDescription(paramName);
208       aTestClassDescription.addChild(param1);
209       final Description testDescription = Description.createTestDescription(className, "testName" + paramName);
210       tests.add(testDescription);
211       param1.addChild(testDescription);
212     }
213     doTest(aTestClassDescription, tests,
214            //tree
215            "##teamcity[enteredTheMatrix]\n" +
216            "##teamcity[suiteTreeStarted name='|[0|]' locationHint='java:suite://a.TestA.|[0|]']\n" +
217            "##teamcity[suiteTreeNode name='testName|[0|]' locationHint='java:test://a.TestA.testName|[0|]']\n" +
218            "##teamcity[suiteTreeEnded name='|[0|]']\n" +
219            "##teamcity[suiteTreeStarted name='|[0|]' locationHint='java:suite://a.TestA.|[0|]']\n" +
220            "##teamcity[suiteTreeNode name='testName|[0|]' locationHint='java:test://a.TestA.testName|[0|]']\n" +
221            "##teamcity[suiteTreeEnded name='|[0|]']\n" +
222            "##teamcity[treeEnded]\n",
223            //start
224            "##teamcity[rootName name = 'TestA' comment = 'a' location = 'java:suite://a.TestA']\n" +
225            "##teamcity[testSuiteStarted name='|[0|]']\n" +
226            "\n" +
227            "##teamcity[testStarted name='testName|[0|]' locationHint='java:test://a.TestA.testName|[0|]']\n" +
228            "\n" +
229            "##teamcity[testFinished name='testName|[0|]']\n" +
230            "##teamcity[testSuiteFinished name='|[0|]']\n" +
231            "##teamcity[testSuiteStarted name='|[0|]']\n" +
232            "\n" +
233            "##teamcity[testStarted name='testName|[0|]' locationHint='java:test://a.TestA.testName|[0|]']\n" +
234            "\n" +
235            "##teamcity[testFinished name='testName|[0|]']\n" +
236            "##teamcity[testSuiteFinished name='|[0|]']\n");
237   }
238
239   @Test
240   public void testParameterizedClassWithParamsWithDots() throws Exception {
241     final String className = "a.TestA";
242     final Description aTestClassDescription = Description.createSuiteDescription(className);
243     final ArrayList<Description> tests = new ArrayList<Description>();
244     for (String paramName : new String[]{"[0: with - 1.1]", "[1: with - 2.1]"}) {
245       final Description param1 = Description.createSuiteDescription(paramName);
246       aTestClassDescription.addChild(param1);
247       final Description testDescription = Description.createTestDescription(className, "testName" + paramName);
248       tests.add(testDescription);
249       param1.addChild(testDescription);
250     }
251     doTest(aTestClassDescription, tests,
252            //tree
253            "##teamcity[enteredTheMatrix]\n" +
254            "##teamcity[suiteTreeStarted name='|[0: with - 1.1|]' locationHint='java:suite://a.TestA.|[0: with - 1.1|]']\n" +
255            "##teamcity[suiteTreeNode name='testName|[0: with - 1.1|]' locationHint='java:test://a.TestA.testName|[0: with - 1.1|]']\n" +
256            "##teamcity[suiteTreeEnded name='|[0: with - 1.1|]']\n" +
257            "##teamcity[suiteTreeStarted name='|[1: with - 2.1|]' locationHint='java:suite://a.TestA.|[1: with - 2.1|]']\n" +
258            "##teamcity[suiteTreeNode name='testName|[1: with - 2.1|]' locationHint='java:test://a.TestA.testName|[1: with - 2.1|]']\n" +
259            "##teamcity[suiteTreeEnded name='|[1: with - 2.1|]']\n" +
260            "##teamcity[treeEnded]\n",
261            //start
262            "##teamcity[rootName name = 'TestA' comment = 'a' location = 'java:suite://a.TestA']\n" +
263            "##teamcity[testSuiteStarted name='|[0: with - 1.1|]']\n" +
264            "\n" +
265            "##teamcity[testStarted name='testName|[0: with - 1.1|]' locationHint='java:test://a.TestA.testName|[0: with - 1.1|]']\n" +
266            "\n" +
267            "##teamcity[testFinished name='testName|[0: with - 1.1|]']\n" +
268            "##teamcity[testSuiteFinished name='|[0: with - 1.1|]']\n" +
269            "##teamcity[testSuiteStarted name='|[1: with - 2.1|]']\n" +
270            "\n" +
271            "##teamcity[testStarted name='testName|[1: with - 2.1|]' locationHint='java:test://a.TestA.testName|[1: with - 2.1|]']\n" +
272            "\n" +
273            "##teamcity[testFinished name='testName|[1: with - 2.1|]']\n" +
274            "##teamcity[testSuiteFinished name='|[1: with - 2.1|]']\n");
275   }
276
277   @Test
278   public void test2SuitesWithTheSameTest() throws Exception {
279     final Description root = Description.createSuiteDescription("root");
280     final String className = "ATest";
281     final String methodName = "test1";
282     final List<Description> tests = new ArrayList<Description>();
283     for( String suiteName : new String[] {"ASuite1", "ASuite2"}) {
284       final Description aSuite = Description.createSuiteDescription(suiteName);
285       root.addChild(aSuite);
286       final Description aTest = Description.createSuiteDescription(className);
287       aSuite.addChild(aTest);
288       final Description testDescription = Description.createTestDescription(className, methodName);
289       tests.add(testDescription);
290       aTest.addChild(testDescription);
291     }
292
293     doTest(root, tests,
294            //expected tree
295            "##teamcity[enteredTheMatrix]\n" +
296            "##teamcity[suiteTreeStarted name='ASuite1' locationHint='java:suite://ASuite1']\n" +
297            "##teamcity[suiteTreeStarted name='ATest' locationHint='java:suite://ATest']\n" +
298            "##teamcity[suiteTreeNode name='ATest.test1' locationHint='java:test://ATest.test1']\n" +
299            "##teamcity[suiteTreeEnded name='ATest']\n" +
300            "##teamcity[suiteTreeEnded name='ASuite1']\n" +
301            "##teamcity[suiteTreeStarted name='ASuite2' locationHint='java:suite://ASuite2']\n" +
302            "##teamcity[suiteTreeStarted name='ATest' locationHint='java:suite://ATest']\n" +
303            "##teamcity[suiteTreeNode name='ATest.test1' locationHint='java:test://ATest.test1']\n" +
304            "##teamcity[suiteTreeEnded name='ATest']\n" +
305            "##teamcity[suiteTreeEnded name='ASuite2']\n" +
306            "##teamcity[treeEnded]\n",
307
308            //started
309            "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" +
310            "##teamcity[testSuiteStarted name='ASuite1']\n" +
311            "##teamcity[testSuiteStarted name='ATest']\n" +
312            "\n" +
313            "##teamcity[testStarted name='ATest.test1' locationHint='java:test://ATest.test1']\n" +
314            "\n" +
315            "##teamcity[testFinished name='ATest.test1']\n" +
316            "##teamcity[testSuiteFinished name='ATest']\n" +
317            "##teamcity[testSuiteFinished name='ASuite1']\n" +
318            "##teamcity[testSuiteStarted name='ASuite2']\n" +
319            "##teamcity[testSuiteStarted name='ATest']\n" +
320            "\n" +
321            "##teamcity[testStarted name='ATest.test1' locationHint='java:test://ATest.test1']\n" +
322            "\n" +
323            "##teamcity[testFinished name='ATest.test1']\n" +
324            "##teamcity[testSuiteFinished name='ATest']\n" +
325            "##teamcity[testSuiteFinished name='ASuite2']\n");
326   }
327
328   private static void doTest(Description root, List<Description> tests, String expectedTree, String expectedStart) throws Exception {
329     final StringBuffer buf = new StringBuffer();
330     final JUnit4TestListener sender = createListener(buf);
331     sender.sendTree(root);
332
333     Assert.assertEquals("output: " + buf, expectedTree, StringUtil.convertLineSeparators(buf.toString()));
334
335     buf.setLength(0);
336
337     sender.testRunStarted(root);
338     for (Description test : tests) {
339       sender.testStarted(test);
340       sender.testFinished(test);
341     }
342     sender.testRunFinished(new Result());
343
344     Assert.assertEquals("output: " + buf, expectedStart, StringUtil.convertLineSeparators(buf.toString()));
345   }
346
347   @Test
348   public void testSetupClassAssumptionFailure() throws Exception {
349     final Description root = Description.createSuiteDescription("root");
350     final Description testA = Description.createSuiteDescription("TestA");
351     root.addChild(testA);
352     final Description testName = Description.createTestDescription("TestA", "testName");
353     testA.addChild(testName);
354
355     final StringBuffer buf = new StringBuffer();
356     final JUnit4TestListener sender = createListener(buf);
357     sender.sendTree(root);
358
359     Assert.assertEquals("output: " + buf, "##teamcity[enteredTheMatrix]\n" +
360                                           "##teamcity[suiteTreeStarted name='TestA' locationHint='java:suite://TestA']\n" +
361                                           "##teamcity[suiteTreeNode name='TestA.testName' locationHint='java:test://TestA.testName']\n" +
362                                           "##teamcity[suiteTreeEnded name='TestA']\n" +
363                                           "##teamcity[treeEnded]\n", StringUtil.convertLineSeparators(buf.toString()));
364
365     buf.setLength(0);
366
367     sender.testRunStarted(testA);
368     final Exception exception = new Exception();
369     exception.setStackTrace(new StackTraceElement[0]);
370     sender.testAssumptionFailure(new Failure(testA, exception));
371     sender.testRunFinished(new Result());
372
373     Assert.assertEquals("output: " + buf, "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" +
374                                           "##teamcity[testSuiteStarted name='TestA']\n" +
375                                           "\n" +
376                                           "##teamcity[testStarted name='TestA.testName' locationHint='java:test://TestA.testName']\n" +
377                                           "\n" +
378                                           "##teamcity[testIgnored name='TestA.testName' details='java.lang.Exception|n' error='true' message='']\n" +
379                                           "\n" +
380                                           "##teamcity[testFinished name='TestA.testName']\n" +
381                                           "##teamcity[testSuiteFinished name='TestA']\n", StringUtil.convertLineSeparators(buf.toString()));
382   } 
383   
384   @Test
385   public void testSetupClassFailure() throws Exception {
386     final Description root = Description.createSuiteDescription("root");
387     final Description testA = Description.createSuiteDescription("TestA");
388     root.addChild(testA);
389     final Description testName = Description.createTestDescription("TestA", "testName");
390     testA.addChild(testName);
391
392     final StringBuffer buf = new StringBuffer();
393     final JUnit4TestListener sender = createListener(buf);
394     sender.sendTree(root);
395
396     Assert.assertEquals("output: " + buf, "##teamcity[enteredTheMatrix]\n" +
397                                           "##teamcity[suiteTreeStarted name='TestA' locationHint='java:suite://TestA']\n" +
398                                           "##teamcity[suiteTreeNode name='TestA.testName' locationHint='java:test://TestA.testName']\n" +
399                                           "##teamcity[suiteTreeEnded name='TestA']\n" +
400                                           "##teamcity[treeEnded]\n", StringUtil.convertLineSeparators(buf.toString()));
401
402     buf.setLength(0);
403
404     sender.testRunStarted(testA);
405     final Exception exception = new Exception();
406     exception.setStackTrace(new StackTraceElement[0]);
407     sender.testFailure(new Failure(testA, exception));
408     sender.testRunFinished(new Result());
409
410     Assert.assertEquals("output: " + buf, "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" +
411                                           "##teamcity[testStarted name='Class Configuration'  locationHint='java:suite://TestA' ]\n" +
412                                           "\n" +
413                                           "##teamcity[testFailed name='Class Configuration' details='java.lang.Exception|n' error='true' message='']\n" +
414                                           "\n" +
415                                           "##teamcity[testFinished name='Class Configuration']\n" +
416                                           "##teamcity[testSuiteStarted name='TestA']\n" +
417                                           "\n" +
418                                           "##teamcity[testStarted name='TestA.testName' locationHint='java:test://TestA.testName']\n" +
419                                           "\n" +
420                                           "##teamcity[testIgnored name='TestA.testName']\n" +
421                                           "\n" +
422                                           "##teamcity[testFinished name='TestA.testName']\n" +
423                                           "##teamcity[testSuiteFinished name='TestA']\n", StringUtil.convertLineSeparators(buf.toString()));
424   }
425   
426   @Test
427   public void testTearDownClassFailure() throws Exception {
428     final Description root = Description.createSuiteDescription("root");
429     final Description testA = Description.createSuiteDescription("TestA");
430     root.addChild(testA);
431     final Description testName = Description.createTestDescription("TestA", "testName");
432     testA.addChild(testName);
433
434     final StringBuffer buf = new StringBuffer();
435     final JUnit4TestListener sender = createListener(buf);
436     sender.sendTree(root);
437
438     Assert.assertEquals("output: " + buf, "##teamcity[enteredTheMatrix]\n" +
439                                           "##teamcity[suiteTreeStarted name='TestA' locationHint='java:suite://TestA']\n" +
440                                           "##teamcity[suiteTreeNode name='TestA.testName' locationHint='java:test://TestA.testName']\n" +
441                                           "##teamcity[suiteTreeEnded name='TestA']\n" +
442                                           "##teamcity[treeEnded]\n", StringUtil.convertLineSeparators(buf.toString()));
443
444     buf.setLength(0);
445
446     sender.testRunStarted(testA);
447     final Exception exception = new Exception();
448     exception.setStackTrace(new StackTraceElement[0]);
449     sender.testStarted(testName);
450     sender.testFinished(testName);
451     sender.testFailure(new Failure(testA, exception));
452     sender.testRunFinished(new Result());
453
454     Assert.assertEquals("output: " + buf, "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" +
455                                           "##teamcity[testSuiteStarted name='TestA']\n" +
456                                           "\n" +
457                                           "##teamcity[testStarted name='TestA.testName' locationHint='java:test://TestA.testName']\n" +
458                                           "\n" +
459                                           "##teamcity[testFinished name='TestA.testName']\n" +
460                                           "##teamcity[testStarted name='Class Configuration'  locationHint='java:suite://TestA' ]\n" +
461                                           "\n" +
462                                           "##teamcity[testFailed name='Class Configuration' details='java.lang.Exception|n' error='true' message='']\n" +
463                                           "\n" +
464                                           "##teamcity[testFinished name='Class Configuration']\n" +
465                                           "##teamcity[testSuiteFinished name='TestA']\n", StringUtil.convertLineSeparators(buf.toString()));
466   }
467   
468   @Test
469   public void testSetupClassFailureForParameterizedClass() throws Exception {
470     final Description root = Description.createSuiteDescription("root");
471     final Description testA = Description.createSuiteDescription("TestA");
472     root.addChild(testA);
473     final Description paramDescription = Description.createSuiteDescription("param");
474     testA.addChild(paramDescription);
475     final Description testName = Description.createTestDescription("TestA", "testName");
476     paramDescription.addChild(testName);
477
478     final StringBuffer buf = new StringBuffer();
479     final JUnit4TestListener sender = createListener(buf);
480     sender.sendTree(root);
481
482     Assert.assertEquals("output: " + buf, "##teamcity[enteredTheMatrix]\n" +
483                                           "##teamcity[suiteTreeStarted name='TestA' locationHint='java:suite://TestA']\n" +
484                                           "##teamcity[suiteTreeStarted name='param' locationHint='java:suite://param']\n" +
485                                           "##teamcity[suiteTreeNode name='TestA.testName' locationHint='java:test://TestA.testName']\n" +
486                                           "##teamcity[suiteTreeEnded name='param']\n" +
487                                           "##teamcity[suiteTreeEnded name='TestA']\n" +
488                                           "##teamcity[treeEnded]\n", StringUtil.convertLineSeparators(buf.toString()));
489     
490     buf.setLength(0);
491
492     sender.testRunStarted(testA);
493     final Exception exception = new Exception();
494     exception.setStackTrace(new StackTraceElement[0]);
495     sender.testAssumptionFailure(new Failure(testA, exception));
496     sender.testRunFinished(new Result());
497
498     Assert.assertEquals("output: " + buf, "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" +
499                                           "##teamcity[testSuiteStarted name='TestA']\n" +
500                                           "##teamcity[testSuiteStarted name='param']\n" +
501                                           "\n" +
502                                           "##teamcity[testStarted name='TestA.testName' locationHint='java:test://TestA.testName']\n" +
503                                           "\n" +
504                                           "##teamcity[testIgnored name='TestA.testName' details='java.lang.Exception|n' error='true' message='']\n" +
505                                           "\n" +
506                                           "##teamcity[testFinished name='TestA.testName']\n" +
507                                           "##teamcity[testSuiteFinished name='param']\n" +
508                                           "##teamcity[testSuiteFinished name='TestA']\n", StringUtil.convertLineSeparators(buf.toString()));
509     buf.setLength(0);
510
511     //testStarted and testFinished are called by the framework
512     sender.testRunStarted(testA);
513     sender.testAssumptionFailure(new Failure(testName, exception));
514     sender.testRunFinished(new Result());
515
516     Assert.assertEquals("output: " + buf, "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" +
517                                           "\n" +
518                                           "##teamcity[testIgnored name='TestA.testName' details='java.lang.Exception|n' error='true' message='']\n", StringUtil.convertLineSeparators(buf.toString()));
519     
520   }
521
522   @Test
523   public void testSingleMethod() throws Exception {
524     final Description rootDescription = Description.createTestDescription("TestA", "testName");
525     doTest(rootDescription, Collections.singletonList(rootDescription),
526            "##teamcity[enteredTheMatrix]\n" +
527            "##teamcity[treeEnded]\n",
528            "##teamcity[rootName name = 'TestA' location = 'java:suite://TestA']\n" +
529            "\n" +
530            "##teamcity[testStarted name='TestA.testName' locationHint='java:test://TestA.testName']\n" +
531            "\n" +
532            "##teamcity[testFinished name='TestA.testName']\n");
533   }
534
535   @Test
536   public void testPackageWithoutDescriptionBefore() throws Exception {
537     final Description root = Description.createSuiteDescription("root");
538     final ArrayList<Description> tests = new ArrayList<Description>();
539     for (String className : new String[]{"a.TestA", "a.TestB"}) {
540       final Description aTestClass = Description.createSuiteDescription(className);
541       root.addChild(aTestClass);
542       final Description testDescription = Description.createTestDescription(className, "testName");
543       aTestClass.addChild(testDescription);
544       tests.add(testDescription);
545     }
546
547     final StringBuffer buf = new StringBuffer();
548     final JUnit4TestListener sender = createListener(buf);
549   
550     sender.testRunStarted(root);
551     for (Description test : tests) {
552       sender.testStarted(test);
553       sender.testFinished(test);
554     }
555     sender.testRunFinished(new Result());
556
557     Assert.assertEquals("output: " + buf, "##teamcity[enteredTheMatrix]\n" +
558                                           "##teamcity[testSuiteStarted name='TestA' locationHint='java:suite://a.TestA']\n" +
559                                           "\n" +
560                                           "##teamcity[testStarted name='TestA.testName' locationHint='java:test://a.TestA.testName']\n" +
561                                           "\n" +
562                                           "##teamcity[testFinished name='TestA.testName']\n" +
563                                           "##teamcity[testSuiteFinished name='TestA']\n" +
564                                           "##teamcity[testSuiteStarted name='TestB' locationHint='java:suite://a.TestB']\n" +
565                                           "\n" +
566                                           "##teamcity[testStarted name='TestB.testName' locationHint='java:test://a.TestB.testName']\n" +
567                                           "\n" +
568                                           "##teamcity[testFinished name='TestB.testName']\n" +
569                                           "##teamcity[testSuiteFinished name='TestB']\n", StringUtil.convertLineSeparators(buf.toString()));
570   }
571
572   private static JUnit4TestListener createListener(final StringBuffer buf) {
573     return new JUnit4TestListener(new PrintStream(new OutputStream() {
574       @Override
575       public void write(int b) throws IOException {
576         buf.append(new String(new byte[]{(byte)b}));
577       }
578     })) {
579       @Override
580       protected long currentTime() {
581         return 0;
582       }
583
584       @Override
585       protected String getTrace(Failure failure) {
586         return StringUtil.convertLineSeparators(super.getTrace(failure));
587       }
588     };
589   }
590
591   @Test
592   public void testParameterizedTestsUpsideDown() throws Exception {
593     final Description aTestClass = Description.createSuiteDescription("ATest");
594     final ArrayList<Description> tests = new ArrayList<Description>();
595     final Description testMethod = Description.createSuiteDescription("testName");
596     aTestClass.addChild(testMethod);
597     for (String paramName : new String[]{"[0]", "[1]"}) {
598       final Description testDescription = Description.createTestDescription("ATest", "testName" + paramName);
599       tests.add(testDescription);
600       testMethod.addChild(testDescription);
601     }
602     doTest(aTestClass, tests,
603            "##teamcity[enteredTheMatrix]\n" +
604            "##teamcity[suiteTreeStarted name='testName' locationHint='java:suite://testName']\n" +
605            "##teamcity[suiteTreeNode name='ATest.testName|[0|]' locationHint='java:test://ATest.testName|[0|]']\n" +
606            "##teamcity[suiteTreeNode name='ATest.testName|[1|]' locationHint='java:test://ATest.testName|[1|]']\n" +
607            "##teamcity[suiteTreeEnded name='testName']\n" +
608            "##teamcity[treeEnded]\n",
609
610
611            "##teamcity[rootName name = 'ATest' location = 'java:suite://ATest']\n" +
612            "##teamcity[testSuiteStarted name='testName']\n" +
613            "\n" +
614            "##teamcity[testStarted name='ATest.testName|[0|]' locationHint='java:test://ATest.testName|[0|]']\n" +
615            "\n" +
616            "##teamcity[testFinished name='ATest.testName|[0|]']\n" +
617            "\n" +
618            "##teamcity[testStarted name='ATest.testName|[1|]' locationHint='java:test://ATest.testName|[1|]']\n" +
619            "\n" +
620            "##teamcity[testFinished name='ATest.testName|[1|]']\n" +
621            "##teamcity[testSuiteFinished name='testName']\n");
622   }
623
624   @Test
625   public void testSuiteAndParameterizedTestsInOnePackage() throws Exception {
626     final Description root = Description.createSuiteDescription("root");
627     final Description aTestClass = Description.createSuiteDescription("ATest");
628     root.addChild(aTestClass);
629     final ArrayList<Description> tests = new ArrayList<Description>();
630     attachParameterizedTests("ATest", aTestClass, tests);
631     final Description suiteDescription = Description.createSuiteDescription("suite");
632     root.addChild(suiteDescription);
633     final Description aTestClassWithJUnit3Test = Description.createSuiteDescription("ATest");
634     suiteDescription.addChild(aTestClassWithJUnit3Test);
635     final Description testDescription = Description.createTestDescription("ATest", "test");
636     aTestClassWithJUnit3Test.addChild(testDescription);
637     tests.add(testDescription);
638     doTest(root, tests,
639            "##teamcity[enteredTheMatrix]\n" +
640            "##teamcity[suiteTreeStarted name='ATest' locationHint='java:suite://ATest']\n" +
641            "##teamcity[suiteTreeStarted name='|[0|]' locationHint='java:suite://ATest.|[0|]']\n" +
642            "##teamcity[suiteTreeNode name='testName|[0|]' locationHint='java:test://ATest.testName|[0|]']\n" +
643            "##teamcity[suiteTreeEnded name='|[0|]']\n" +
644            "##teamcity[suiteTreeStarted name='|[1|]' locationHint='java:suite://ATest.|[1|]']\n" +
645            "##teamcity[suiteTreeNode name='testName|[1|]' locationHint='java:test://ATest.testName|[1|]']\n" +
646            "##teamcity[suiteTreeEnded name='|[1|]']\n" +
647            "##teamcity[suiteTreeEnded name='ATest']\n" +
648            "##teamcity[suiteTreeStarted name='suite' locationHint='java:suite://suite']\n" +
649            "##teamcity[suiteTreeStarted name='ATest' locationHint='java:suite://ATest']\n" +
650            "##teamcity[suiteTreeNode name='ATest.test' locationHint='java:test://ATest.test']\n" +
651            "##teamcity[suiteTreeEnded name='ATest']\n" +
652            "##teamcity[suiteTreeEnded name='suite']\n" +
653            "##teamcity[treeEnded]\n",
654
655            //start
656            "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" +
657            "##teamcity[testSuiteStarted name='ATest']\n" +
658            "##teamcity[testSuiteStarted name='|[0|]']\n" +
659            "\n" +
660            "##teamcity[testStarted name='testName|[0|]' locationHint='java:test://ATest.testName|[0|]']\n" +
661            "\n" +
662            "##teamcity[testFinished name='testName|[0|]']\n" +
663            "##teamcity[testSuiteFinished name='|[0|]']\n" +
664            "##teamcity[testSuiteStarted name='|[1|]']\n" +
665            "\n" +
666            "##teamcity[testStarted name='testName|[1|]' locationHint='java:test://ATest.testName|[1|]']\n" +
667            "\n" +
668            "##teamcity[testFinished name='testName|[1|]']\n" +
669            "##teamcity[testSuiteFinished name='|[1|]']\n" +
670            "##teamcity[testSuiteFinished name='ATest']\n" +
671            "##teamcity[testSuiteStarted name='suite']\n" +
672            "##teamcity[testSuiteStarted name='ATest']\n" +
673            "\n" +
674            "##teamcity[testStarted name='ATest.test' locationHint='java:test://ATest.test']\n" +
675            "\n" +
676            "##teamcity[testFinished name='ATest.test']\n" +
677            "##teamcity[testSuiteFinished name='ATest']\n" +
678            "##teamcity[testSuiteFinished name='suite']\n");
679   }
680
681
682   private static void attachParameterizedTests(String className, Description aTestClass, List<Description> tests) {
683     for (String paramName : new String[]{"[0]", "[1]"}) {
684       final Description param1 = Description.createSuiteDescription(paramName);
685       aTestClass.addChild(param1);
686       final Description testDescription = Description.createTestDescription(className, "testName" + paramName);
687       tests.add(testDescription);
688       param1.addChild(testDescription);
689     }
690   }
691   
692   private static void doTest(Description description, String expected) {
693     final StringBuffer buf = new StringBuffer();
694     createListener(buf).sendTree(description);
695
696     Assert.assertEquals("output: " + buf, expected, StringUtil.convertLineSeparators(buf.toString()));
697   }
698
699   @Test
700   public void testProcessEmptyTestCase() throws Exception {
701     final Description description = Description.createSuiteDescription("TestA");
702     final Description emptyDescription = Description.createTestDescription(JUnit4TestListener.EMPTY_SUITE_NAME, JUnit4TestListener.EMPTY_SUITE_WARNING);
703     description.addChild(emptyDescription);
704     doTest(description, Collections.singletonList(emptyDescription),
705            "##teamcity[enteredTheMatrix]\n" +
706            "##teamcity[suiteTreeNode name='TestSuite$1.warning' locationHint='java:test://junit.framework.TestSuite$1.warning']\n" +
707            "##teamcity[treeEnded]\n",
708
709            "##teamcity[rootName name = 'TestA' location = 'java:suite://TestA']\n" +
710            "\n" +
711            "##teamcity[testStarted name='TestSuite$1.warning' locationHint='java:test://junit.framework.TestSuite$1.warning']\n" +
712            "\n" +
713            "##teamcity[testFinished name='TestSuite$1.warning']\n");
714   }
715 }