1 /*******************************************************************************
2  * Copyright (c) 2000, 2020 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.jdt.junit.tests;
15 
16 import static org.junit.Assert.assertEquals;
17 
18 import java.io.File;
19 import java.util.Arrays;
20 import java.util.HashSet;
21 
22 import org.junit.After;
23 import org.junit.Before;
24 import org.junit.Test;
25 
26 import org.eclipse.jdt.junit.JUnitCore;
27 import org.eclipse.jdt.testplugin.JavaProjectHelper;
28 import org.eclipse.jdt.testplugin.JavaTestPlugin;
29 import org.eclipse.jdt.testplugin.StringAsserts;
30 
31 import org.eclipse.core.runtime.CoreException;
32 import org.eclipse.core.runtime.Path;
33 
34 import org.eclipse.jdt.core.IClasspathEntry;
35 import org.eclipse.jdt.core.IJavaElement;
36 import org.eclipse.jdt.core.IJavaProject;
37 import org.eclipse.jdt.core.IPackageFragment;
38 import org.eclipse.jdt.core.IPackageFragmentRoot;
39 import org.eclipse.jdt.core.IType;
40 import org.eclipse.jdt.core.JavaCore;
41 
42 import org.eclipse.jdt.internal.junit.launcher.ITestFinder;
43 import org.eclipse.jdt.internal.junit.launcher.ITestKind;
44 import org.eclipse.jdt.internal.junit.launcher.TestKindRegistry;
45 
46 
47 public class JUnit4TestFinderTest {
48 
49 	private IJavaProject fProject;
50 	private IPackageFragmentRoot fRoot;
51 
52 	@Before
setUp()53 	public void setUp() throws Exception {
54 		fProject= JavaProjectHelper.createJavaProject("TestProject", "bin");
55 		JavaProjectHelper.addRTJar(fProject);
56 		IClasspathEntry cpe= JavaCore.newContainerEntry(JUnitCore.JUNIT4_CONTAINER_PATH);
57 		JavaProjectHelper.addToClasspath(fProject, cpe);
58 		JavaProjectHelper.set15CompilerOptions(fProject);
59 
60 		fRoot= JavaProjectHelper.addSourceContainer(fProject, "src");
61 	}
62 
63 	@After
tearDown()64 	public void tearDown() throws Exception {
65 		JavaProjectHelper.delete(fProject);
66 	}
67 
68 	/**
69 	 * Copy from {@link JUnit3TestFinderTest}: All tests must work in Junit 4 as well
70 	 * @throws Exception if it fails
71 	 */
72 	@Test
testTestCase()73 	public void testTestCase() throws Exception {
74 		IPackageFragment p= fRoot.createPackageFragment("p", true, null);
75 		StringBuffer buf= new StringBuffer();
76 		buf.append("package p;\n");
77 		buf.append("import junit.framework.TestCase;\n");
78 		buf.append("\n");
79 		buf.append("public class MyTest extends TestCase {\n");
80 		buf.append("        public void testFoo() {\n");
81 		buf.append("        }\n");
82 		buf.append("}\n");
83 		IType validTest1= p.createCompilationUnit("MyTest.java", buf.toString(), false, null).findPrimaryType();
84 
85 		assertTestFound(validTest1, new String[] { "p.MyTest" });
86 		assertTestFound(validTest1.getCompilationUnit(), new String[] { "p.MyTest" });
87 
88 		buf= new StringBuffer();
89 		buf.append("package p;\n");
90 		buf.append("import junit.framework.TestCase;\n");
91 		buf.append("\n");
92 		buf.append("public class MySuperTest extends MyTest {\n");
93 		buf.append("        public void testFoo() {\n");
94 		buf.append("        }\n");
95 		buf.append("}\n");
96 		IType validTest2= p.createCompilationUnit("MySuperTest.java", buf.toString(), false, null).findPrimaryType();
97 
98 		assertTestFound(validTest2, new String[] { "p.MySuperTest" });
99 		assertTestFound(validTest2.getCompilationUnit(), new String[] { "p.MySuperTest" });
100 
101 		buf= new StringBuffer();
102 		buf.append("package p;\n");
103 		buf.append("import junit.framework.TestCase;\n");
104 		buf.append("\n");
105 		buf.append("class InvisibleTest extends TestCase {\n");
106 		buf.append("        public void testFoo() {\n");
107 		buf.append("        }\n");
108 		buf.append("}\n");
109 		IType validTest3= p.createCompilationUnit("InvisibleTest.java", buf.toString(), false, null).findPrimaryType();
110 
111 		// accept invisible top level types
112 		assertTestFound(validTest3, new String[] { "p.InvisibleTest" });
113 		assertTestFound(validTest3.getCompilationUnit(), new String[] { "p.InvisibleTest" });
114 
115 		buf= new StringBuffer();
116 		buf.append("package p;\n");
117 		buf.append("import junit.framework.TestCase;\n");
118 		buf.append("\n");
119 		buf.append("public class Outer {\n");
120 		buf.append("    public static class InnerTest extends TestCase {\n");
121 		buf.append("        public void testFoo() {\n");
122 		buf.append("        }\n");
123 		buf.append("    }\n");
124 		buf.append("}\n");
125 		IType validTest4= p.createCompilationUnit("Outer.java", buf.toString(), false, null).getType("Outer").getType("InnerTest");
126 
127 		assertTestFound(validTest4, new String[] { "p.Outer.InnerTest" });
128 		assertTestFound(validTest4.getCompilationUnit(), new String[] { "p.Outer.InnerTest" });
129 
130 		buf= new StringBuffer();
131 		buf.append("package p;\n");
132 		buf.append("import junit.framework.TestCase;\n");
133 		buf.append("\n");
134 		buf.append("public class Outer2 {\n");
135 		buf.append("    public class NonStaticInnerTest extends TestCase {\n");
136 		buf.append("        public void testFoo() {\n");
137 		buf.append("        }\n");
138 		buf.append("    }\n");
139 		buf.append("    static class NonVisibleInnerTest extends TestCase {\n");
140 		buf.append("        public void testFoo() {\n");
141 		buf.append("            class LocalTest extends TestCase {\n");
142 		buf.append("                public void testFoo() {\n");
143 		buf.append("                }\n");
144 		buf.append("            }\n");
145 		buf.append("        }\n");
146 		buf.append("    }\n");
147 		buf.append("}\n");
148 		IType[] invalidTests= p.createCompilationUnit("Outer2.java", buf.toString(), false, null).getAllTypes();
149 		for (IType invalidTest : invalidTests) {
150 			assertTestFound(invalidTest, new String[] {});
151 		}
152 		assertTestFound(invalidTests[0].getCompilationUnit(), new String[] {});
153 
154 
155 		buf= new StringBuffer();
156 		buf.append("package p;\n");
157 		buf.append("import junit.framework.TestCase;\n");
158 		buf.append("\n");
159 		buf.append("public abstract class AbstractTest extends TestCase {\n");
160 		buf.append("        public void testFoo() {\n");
161 		buf.append("        }\n");
162 		buf.append("}\n");
163 		IType invalidTest1= p.createCompilationUnit("AbstractTest.java", buf.toString(), false, null).findPrimaryType();
164 
165 		assertTestFound(invalidTest1, new String[] {});
166 		assertTestFound(invalidTest1.getCompilationUnit(), new String[] {});
167 
168 		buf= new StringBuffer();
169 		buf.append("package p;\n");
170 		buf.append("import java.util.Vector;\n");
171 		buf.append("\n");
172 		buf.append("public class NoTest extends Vector {\n");
173 		buf.append("        public void testFoo() {\n");
174 		buf.append("        }\n");
175 		buf.append("}\n");
176 		IType invalidTest3= p.createCompilationUnit("NoTest.java", buf.toString(), false, null).findPrimaryType();
177 
178 		assertTestFound(invalidTest3, new String[] {});
179 		assertTestFound(invalidTest3.getCompilationUnit(), new String[] {});
180 
181 		String[] validTests= { "p.MyTest", "p.MySuperTest", "p.InvisibleTest", "p.Outer.InnerTest" };
182 
183 		assertTestFound(p, validTests);
184 		assertTestFound(fRoot, validTests);
185 		assertTestFound(fProject, validTests);
186 	}
187 
188 	@Test
testSuiteFinder()189 	public void testSuiteFinder() throws Exception {
190 		IPackageFragment p= fRoot.createPackageFragment("p", true, null);
191 		StringBuilder buf= new StringBuilder();
192 		buf.append("package p;\n");
193 		buf.append("import junit.framework.Test;\n");
194 		buf.append("\n");
195 		buf.append("public class SuiteClass {\n");
196 		buf.append("    public static Test suite() {\n");
197 		buf.append("        return null;\n");
198 		buf.append("    }\n");
199 		buf.append("}\n");
200 		IType validTest1= p.createCompilationUnit("SuiteClass.java", buf.toString(), false, null).getType("SuiteClass");
201 
202 		String[] validTests= { "p.SuiteClass" };
203 
204 		assertTestFound(validTest1, validTests);
205 		assertTestFound(validTest1.getCompilationUnit(), validTests);
206 		assertTestFound(p, validTests);
207 		assertTestFound(fRoot, validTests);
208 		assertTestFound(fProject, validTests);
209 	}
210 
211 	@Test
testRunWith()212 	public void testRunWith() throws Exception {
213 		IPackageFragment p= fRoot.createPackageFragment("p", true, null);
214 		StringBuffer buf= new StringBuffer();
215 		buf.append("package p;\n");
216 		buf.append("\n");
217 		buf.append("import org.junit.Test;\n");
218 		buf.append("\n");
219 		buf.append("public class Test1 {\n");
220 		buf.append("        @Test public void testFoo() {\n");
221 		buf.append("        }\n");
222 		buf.append("}\n");
223 		p.createCompilationUnit("Test1.java", buf.toString(), false, null);
224 
225 		buf= new StringBuffer();
226 		buf.append("package p;\n");
227 		buf.append("\n");
228 		buf.append("import org.junit.runner.RunWith;\n");
229 		buf.append("import org.junit.runners.Suite;\n");
230 		buf.append("import org.junit.runners.Suite.SuiteClasses;\n");
231 		buf.append("\n");
232 		buf.append("@RunWith(Suite.class)\n");
233 		buf.append("@SuiteClasses(Test1.class)\n");
234 		buf.append("public class Test2 {\n");
235 		buf.append("    \n");
236 		buf.append("}\n");
237 		IType validTest1= p.createCompilationUnit("Test2.java", buf.toString(), false, null).getType("Test2");
238 
239 		assertTestFound(validTest1, new String[] { "p.Test2" });
240 		assertTestFound(validTest1.getCompilationUnit(), new String[] { "p.Test2" });
241 
242 		buf= new StringBuffer();
243 		buf.append("package p;\n");
244 		buf.append("\n");
245 		buf.append("public class Test3 extends Test2 {\n");
246 		buf.append("    \n");
247 		buf.append("}\n");
248 		IType validTest2= p.createCompilationUnit("Test3.java", buf.toString(), false, null).getType("Test3");
249 
250 		assertTestFound(validTest2, new String[] { "p.Test3" });
251 		assertTestFound(validTest2.getCompilationUnit(), new String[] { "p.Test3" });
252 
253 		buf= new StringBuffer();
254 		buf.append("package p;\n");
255 		buf.append("\n");
256 		buf.append("import org.junit.runner.RunWith;\n");
257 		buf.append("import org.junit.runners.Suite;\n");
258 		buf.append("import org.junit.runners.Suite.SuiteClasses;\n");
259 		buf.append("\n");
260 		buf.append("@RunWith(Suite.class)\n");
261 		buf.append("@SuiteClasses(Test1.class)\n");
262 		buf.append("public interface Test4 {\n");
263 		buf.append("    \n");
264 		buf.append("}\n");
265 		IType invalidTest1= p.createCompilationUnit("Test4.java", buf.toString(), false, null).getType("Test4");
266 
267 		assertTestFound(invalidTest1, new String[] {});
268 		assertTestFound(invalidTest1.getCompilationUnit(), new String[] {});
269 
270 		buf= new StringBuffer();
271 		buf.append("package p;\n");
272 		buf.append("\n");
273 		buf.append("import org.junit.runner.RunWith;\n");
274 		buf.append("import org.junit.runners.Suite;\n");
275 		buf.append("import org.junit.runners.Suite.SuiteClasses;\n");
276 		buf.append("\n");
277 		buf.append("@RunWith(Suite.class)\n");
278 		buf.append("@SuiteClasses(Test1.class)\n");
279 		buf.append("class Test5 {\n");
280 		buf.append("    \n");
281 		buf.append("}\n");
282 		IType validTest3= p.createCompilationUnit("Test5.java", buf.toString(), false, null).getType("Test5");
283 
284 		assertTestFound(validTest3, new String[] { "p.Test5"});
285 		assertTestFound(validTest3.getCompilationUnit(), new String[] { "p.Test5" });
286 
287 		buf= new StringBuffer();
288 		buf.append("package p;\n");
289 		buf.append("\n");
290 		buf.append("import org.junit.runner.RunWith;\n");
291 		buf.append("\n");
292 		buf.append("@SuiteClasses(Test1.class)\n");
293 		buf.append("public class Test6 {\n");
294 		buf.append("    RunWith aRunWith;\n");
295 		buf.append("}\n");
296 		IType invalidTest2= p.createCompilationUnit("Test6.java", buf.toString(), false, null).getType("Test6");
297 
298 		assertTestFound(invalidTest2, new String[] {});
299 		assertTestFound(invalidTest2.getCompilationUnit(), new String[] {});
300 
301 		buf= new StringBuffer();
302 		buf.append("import java.util.Arrays;\n");
303 		buf.append("import java.util.Collection;\n");
304 		buf.append("\n");
305 		buf.append("import org.junit.runners.Parameterized.Parameters;\n");
306 		buf.append("\n");
307 		buf.append("public class Test7 extends StackTest {\n");
308 		buf.append("\n");
309 		buf.append("	public Test7(int num) {\n");
310 		buf.append("		super(num);\n");
311 		buf.append("	}\n");
312 		buf.append("	\n");
313 		buf.append("	@Parameters\n");
314 		buf.append("	 public static Collection data() {\n");
315 		buf.append("	   Object[][] data = new Object[][] { { 1 }, { 2 }, { 3 }, { 4 } };\n");
316 		buf.append("	   return Arrays.asList(data);\n");
317 		buf.append("	}\n");
318 		buf.append("}\n");
319 		IType validTest4= fRoot.getPackageFragment("").createCompilationUnit("Test7.java", buf.toString(), false, null).getType("Test7");
320 
321 		File lib= JavaTestPlugin.getDefault().getFileInPlugin(new Path("testresources/stacktest.jar"));
322 		JavaProjectHelper.addLibrary(fProject, Path.fromOSString(lib.getPath()));
323 
324 		assertTestFound(validTest4, new String[] { "Test7"});
325 		assertTestFound(validTest4.getCompilationUnit(), new String[] { "Test7" });
326 
327 		String[] validTestsP= { "p.Test1", "p.Test2", "p.Test3", "p.Test5"};
328 		assertTestFound(p, validTestsP);
329 
330 		String[] validTests= new String[validTestsP.length + 1];
331 		System.arraycopy(validTestsP, 0, validTests, 0, validTestsP.length);
332 		validTests[validTestsP.length]= "Test7";
333 
334 		assertTestFound(fRoot, validTests);
335 		assertTestFound(fProject, validTests);
336 	}
337 
338 	@Test
testTestAnnotation()339 	public void testTestAnnotation() throws Exception {
340 		IPackageFragment p= fRoot.createPackageFragment("p", true, null);
341 		StringBuffer buf= new StringBuffer();
342 		buf.append("package p;\n");
343 		buf.append("\n");
344 		buf.append("import org.junit.Test;\n");
345 		buf.append("\n");
346 		buf.append("public class Test1 {\n");
347 		buf.append("        @Test public void testFoo() {\n");
348 		buf.append("        }\n");
349 		buf.append("}\n");
350 		IType validTest1= p.createCompilationUnit("Test1.java", buf.toString(), false, null).getType("Test1");
351 
352 		assertTestFound(validTest1, new String[] { "p.Test1" });
353 		assertTestFound(validTest1.getCompilationUnit(), new String[] { "p.Test1" });
354 
355 
356 		buf= new StringBuffer();
357 		buf.append("package p;\n");
358 		buf.append("\n");
359 		buf.append("public class Test2 extends Test1 {\n");
360 		buf.append("        public void testBar() {\n");
361 		buf.append("        }\n");
362 		buf.append("}\n");
363 		IType validTest2= p.createCompilationUnit("Test2.java", buf.toString(), false, null).getType("Test2");
364 
365 		assertTestFound(validTest2, new String[] { "p.Test2" });
366 		assertTestFound(validTest2.getCompilationUnit(), new String[] { "p.Test2" });
367 
368 
369 		buf= new StringBuffer();
370 		buf.append("package p;\n");
371 		buf.append("\n");
372 		buf.append("import org.junit.Test;\n");
373 		buf.append("\n");
374 		buf.append("public class Test3 {\n");
375 		buf.append("        @Test void testFoo() {\n");
376 		buf.append("        }\n");
377 		buf.append("}\n");
378 		IType validTest3= p.createCompilationUnit("Test3.java", buf.toString(), false, null).getType("Test3");
379 
380 		assertTestFound(validTest3, new String[] { "p.Test3" });
381 		assertTestFound(validTest3.getCompilationUnit(), new String[] { "p.Test3" });
382 
383 
384 		buf= new StringBuffer();
385 		buf.append("package p;\n");
386 		buf.append("\n");
387 		buf.append("import org.junit.Test;\n");
388 		buf.append("\n");
389 		buf.append("public abstract class AbstractTest {\n");
390 		buf.append("        @Test public void testBar() {\n");
391 		buf.append("        }\n");
392 		buf.append("}\n");
393 		IType invalidTest4= p.createCompilationUnit("AbstractTest.java", buf.toString(), false, null).getType("AbstractTest");
394 
395 		assertTestFound(invalidTest4, new String[] {});
396 		assertTestFound(invalidTest4.getCompilationUnit(), new String[] {});
397 
398 		String[] validTests= { "p.Test1", "p.Test2", "p.Test3"};
399 
400 		assertTestFound(p, validTests);
401 		assertTestFound(fRoot, validTests);
402 		assertTestFound(fProject, validTests);
403 	}
404 
405 	@Test
testTestAnnotation_bug204682()406 	public void testTestAnnotation_bug204682() throws Exception {
407 
408 		IPackageFragment p= fRoot.createPackageFragment("p", true, null);
409 		StringBuilder buf= new StringBuilder();
410 		buf.append("package p;\n");
411 		buf.append("\n");
412 		buf.append("import org.junit.Test;\n");
413 		buf.append("\n");
414 		buf.append("public class Test1 {\n");
415 		buf.append("        Test testFoo1() {\n");
416 		buf.append("            return null;\n");
417 		buf.append("        }\n");
418 		buf.append("        public void testFoo2() {\n");
419 		buf.append("            Test test;\n");
420 		buf.append("        }\n");
421 		buf.append("}\n");
422 		IType validTest1= p.createCompilationUnit("Test1.java", buf.toString(), false, null).getType("Test1");
423 
424 		assertTestFound(validTest1, new String[] { });
425 		assertTestFound(validTest1.getCompilationUnit(), new String[] { });
426 	}
427 
428 	@Test
testTestAnnotation2()429 	public void testTestAnnotation2() throws Exception {
430 
431 		IPackageFragment p= fRoot.createPackageFragment("p", true, null);
432 		StringBuilder buf= new StringBuilder();
433 		buf.append("package p;\n");
434 		buf.append("\n");
435 		buf.append("import org.junit.Test;\n");
436 		buf.append("\n");
437 		buf.append("@RunWith(Suite.class)\n");
438 		buf.append("@SuiteClasses(Test1.class)\n");
439 		buf.append("public class Test1 {\n");
440 		buf.append("        @Test Test testFoo1() {\n");
441 		buf.append("            return null;\n");
442 		buf.append("        }\n");
443 		buf.append("}\n");
444 		IType validTest1= p.createCompilationUnit("Test1.java", buf.toString(), false, null).getType("Test1");
445 
446 		assertTestFound(validTest1, new String[] { "p.Test1" });
447 		assertTestFound(validTest1.getCompilationUnit(), new String[] { "p.Test1" });
448 	}
449 
450 
assertTestFound(IJavaElement container, String[] expectedTypes)451 	private void assertTestFound(IJavaElement container, String[] expectedTypes) throws CoreException {
452 		ITestKind testKind= TestKindRegistry.getContainerTestKind(container);
453 		assertEquals(TestKindRegistry.JUNIT4_TEST_KIND_ID, testKind.getId());
454 
455 		ITestFinder finder= testKind.getFinder();
456 
457 		if (container instanceof IType) {
458 			IType type= (IType) container;
459 			boolean isTest= expectedTypes.length == 1 && type.getFullyQualifiedName('.').equals(expectedTypes[0]);
460 			assertEquals(type.getFullyQualifiedName(), isTest, finder.isTest(type));
461 		}
462 
463 		HashSet<IType> set= new HashSet<>();
464 //		finder.findTestsInContainer(container, set, null);
465 		set.addAll(Arrays.asList(JUnitCore.findTestTypes(container, null)));
466 
467 		HashSet<String> namesFound= new HashSet<>();
468 		for (IType curr : set) {
469 			namesFound.add(curr.getFullyQualifiedName('.'));
470 		}
471 		String[] actuals= namesFound.toArray(new String[namesFound.size()]);
472 		StringAsserts.assertEqualStringsIgnoreOrder(actuals, expectedTypes);
473 	}
474 
475 
476 }
477