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