2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4 * Copyright 2010-2011 Sun Microsystems, Inc. All rights reserved.
6 * The contents of this file are subject to the terms of either the GNU
7 * General Public License Version 2 only ("GPL") or the Common
8 * Development and Distribution License("CDDL") (collectively, the
9 * "License"). You may not use this file except in compliance with the
10 * License. You can obtain a copy of the License at
11 * http://www.netbeans.org/cddl-gplv2.html
12 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13 * specific language governing permissions and limitations under the
14 * License. When distributing the software, include this License Header
15 * Notice in each file and include the License file at
16 * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17 * particular file as subject to the "Classpath" exception as provided
18 * by Sun in the GPL Version 2 section of the License file that
19 * accompanied this code. If applicable, add the following below the
20 * License Header, with the fields enclosed by brackets [] replaced by
21 * your own identifying information:
22 * "Portions Copyrighted [year] [name of copyright owner]"
24 * If you wish your version of this file to be governed by only the CDDL
25 * or only the GPL Version 2, indicate your decision by adding
26 * "[Contributor] elects to include this software in this distribution
27 * under the [CDDL or GPL Version 2] license." If you do not indicate a
28 * single choice of license, a recipient has the option to distribute
29 * your version of this file under either the CDDL, the GPL Version 2 or
30 * to extend the choice of license to its licensees as provided above.
31 * However, if you add GPL Version 2 code and therefore, elected the GPL
32 * Version 2 license, then the option applies only if the new code is
33 * made subject to such option by the copyright holder.
37 * Portions Copyrighted 2010-2011 Sun Microsystems, Inc.
40 package org.netbeans.modules.jackpot30.cmdline;
42 import java.io.ByteArrayOutputStream;
44 import java.io.FileOutputStream;
45 import java.io.IOException;
46 import java.io.InputStream;
47 import java.io.PrintStream;
49 import java.net.URISyntaxException;
51 import java.net.URLClassLoader;
52 import java.util.Arrays;
53 import java.util.Collections;
54 import java.util.LinkedList;
55 import java.util.List;
56 import java.util.regex.Matcher;
57 import java.util.regex.Pattern;
58 import javax.tools.SimpleJavaFileObject;
59 import javax.tools.ToolProvider;
60 import org.junit.runner.Result;
61 import org.netbeans.api.java.source.TestUtilities;
62 import org.netbeans.junit.NbTestCase;
63 import org.openide.filesystems.FileUtil;
65 /**XXX: should also test error conditions
69 public class MainTest extends NbTestCase {
71 public MainTest(String name) {
75 public void testRunCompiler1() throws Exception {
78 "public class Test {\n" +
79 " private void test(java.util.Collection c) {\n" +
80 " boolean b = c.isEmpty();\n" +
89 "public class Test {\n" +
90 " private void test(java.util.Collection c) {\n" +
91 " boolean b = c.size() == 0;\n" +
97 "Usage of .size() == 0");
100 public void testDoNotApply() throws Exception {
103 "public class Test {\n" +
104 " private void test(java.util.Collection c) {\n" +
105 " boolean b1 = c.size() == 0;\n" +
106 "\tboolean b2 = c.size() == 0;\n" +
110 doRunCompiler(golden,
111 "${workdir}/src/test/Test.java:4: warning: [Usage_of_size_equals_0] Usage of .size() == 0 can be replaced with .isEmpty()\n" +
112 " boolean b1 = c.size() == 0;\n" +
114 "${workdir}/src/test/Test.java:5: warning: [Usage_of_size_equals_0] Usage of .size() == 0 can be replaced with .isEmpty()\n" +
115 "\tboolean b2 = c.size() == 0;\n" +
118 "src/test/Test.java",
120 "public class Test {\n" +
121 " private void test(java.util.Collection c) {\n" +
122 " boolean b1 = c.size() == 0;\n" +
123 "\tboolean b2 = c.size() == 0;\n" +
128 "Usage of .size() == 0",
132 public void testConfig() throws Exception {
135 "public class Test {\n" +
136 " private int test(String str) {\n" +
137 " if (\"a\" == str) {\n" +
139 " } else if (\"b\" == str) {\n" +
147 doRunCompiler(golden,
150 "src/test/Test.java",
152 "public class Test {\n" +
153 " private int test(String str) {\n" +
154 " if (\"a\" == str) {\n" +
156 " } else if (\"b\" == str) {\n" +
165 "Use switch over Strings where possible.",
167 "also-equals=false");
170 public void testValidSourceLevel() throws Exception {
173 "public class Test {\n" +
174 " private void test(java.util.Collection c) {\n" +
175 " boolean b = c.isEmpty();\n" +
179 doRunCompiler(golden,
182 "src/test/Test.java",
184 "public class Test {\n" +
185 " private void test(java.util.Collection c) {\n" +
186 " boolean b = c.size() == 0;\n" +
192 "Usage of .size() == 0",
197 public void testConfigurationFile() throws Exception {
200 "public class Test {\n" +
201 " private void test(java.util.Collection c) {\n" +
202 " boolean b = c.isEmpty();\n" +
206 doRunCompiler(golden,
209 "src/test/Test.java",
211 "public class Test {\n" +
212 " private void test(java.util.Collection c) {\n" +
213 " boolean b = c.size() == 0;\n" +
217 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
218 "<hints apply=\"true\">\n" +
220 " <org.netbeans.modules.java.hints.perf.SizeEqualsZero check.not.equals=\"false\" enabled=\"true\" hintSeverity=\"VERIFIER\"/>\n" +
225 "${workdir}/settings.xml",
230 public void testConfigurationFileCmdLineOverride() throws Exception {
233 "public class Test {\n" +
234 " private void test(java.util.Collection c) {\n" +
235 " boolean b = c.size() == 0;\n" +
239 doRunCompiler(golden,
240 "${workdir}/src/test/Test.java:4: warning: [Usage_of_size_equals_0] Usage of .size() == 0 can be replaced with .isEmpty()\n" +
241 " boolean b = c.size() == 0;\n" +
244 "src/test/Test.java",
246 "public class Test {\n" +
247 " private void test(java.util.Collection c) {\n" +
248 " boolean b = c.size() == 0;\n" +
252 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
253 "<hints apply=\"true\">\n" +
255 " <org.netbeans.modules.java.hints.perf.SizeEqualsZero check.not.equals=\"false\" enabled=\"true\" hintSeverity=\"VERIFIER\"/>\n" +
260 "${workdir}/settings.xml",
266 public void testHintFile() throws Exception {
269 "public class Test {\n" +
270 " private void test(java.util.Collection c) {\n" +
271 " boolean b = c.size() == 0;\n" +
275 doRunCompiler(golden,
278 "src/test/Test.java",
280 "public class Test {\n" +
281 " private void test(java.util.Collection c) {\n" +
282 " boolean b = c.isEmpty();\n" +
286 "$var.isEmpty() => $var.size() == 0;;",
289 "${workdir}/test-rule.hint",
295 public void testConfigurationFileDeclarative1() throws Exception {
298 "public class Test {\n" +
299 " private void test(java.util.Collection c) {\n" +
300 " boolean b1 = c.isEmpty();\n" +
301 " boolean b2 = c.size() <= 0;\n" +
305 doRunCompiler(golden,
308 "src/test/Test.java",
310 "public class Test {\n" +
311 " private void test(java.util.Collection c) {\n" +
312 " boolean b1 = c.size() == 0;\n" +
313 " boolean b2 = c.size() <= 0;\n" +
316 "META-INF/upgrade/test1.hint",
317 "$c.size() == 0 :: $c instanceof java.util.Collection => $c.isEmpty();;\n",
318 "META-INF/upgrade/test2.hint",
319 "$c.size() <= 0 :: $c instanceof java.util.Collection => $c.isEmpty();;\n",
321 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
322 "<hints apply=\"true\" runDeclarative=\"false\">\n" +
324 " <test1.hint enabled=\"true\"/>\n" +
329 "${workdir}/settings.xml",
334 public void testConfigurationFileDeclarative2() throws Exception {
337 "public class Test {\n" +
338 " private void test(java.util.Collection c) {\n" +
339 " boolean b1 = c.isEmpty();\n" +
340 " boolean b2 = c.isEmpty();\n" +
344 doRunCompiler(golden,
347 "src/test/Test.java",
349 "public class Test {\n" +
350 " private void test(java.util.Collection c) {\n" +
351 " boolean b1 = c.size() == 0;\n" +
352 " boolean b2 = c.size() <= 0;\n" +
355 "META-INF/upgrade/test1.hint",
356 "$c.size() == 0 :: $c instanceof java.util.Collection => $c.isEmpty();;\n",
357 "META-INF/upgrade/test2.hint",
358 "$c.size() <= 0 :: $c instanceof java.util.Collection => $c.isEmpty();;\n",
360 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
361 "<hints apply=\"true\" runDeclarative=\"true\">\n" +
363 " <test1.hint enabled=\"true\"/>\n" +
368 "${workdir}/settings.xml",
373 public void testSourcePath() throws Exception {
376 "public class Test {\n" +
377 " private void test() {\n" +
378 " String s = test2.Test2.C;\n" +
382 doRunCompiler(golden,
385 "src/test/Test.java",
387 "public class Test {\n" +
388 " private void test() {\n" +
389 " String s = test2.Test2.C.intern();\n" +
392 "src/test2/Test2.java",
394 "public class Test2 {\n" +
395 " public static final String C = \"a\";\n" +
401 "String.intern() called on constant",
404 "${workdir}/src/test");
407 public void testWarningsAreErrors() throws Exception {
410 "public class Test {\n" +
411 " private void test(java.util.Collection c) {\n" +
412 " boolean b1 = c.size() == 0;\n" +
413 "\tboolean b2 = c.size() == 0;\n" +
417 doRunCompiler(equivalentValidator(code),
419 "${workdir}/src/test/Test.java:4: warning: [Usage_of_size_equals_0] Usage of .size() == 0 can be replaced with .isEmpty()\n" +
420 " boolean b1 = c.size() == 0;\n" +
422 "${workdir}/src/test/Test.java:5: warning: [Usage_of_size_equals_0] Usage of .size() == 0 can be replaced with .isEmpty()\n" +
423 "\tboolean b2 = c.size() == 0;\n" +
426 equivalentValidator(null),
428 "src/test/Test.java",
432 "Usage of .size() == 0",
434 "--fail-on-warnings");
437 public void testGroups() throws Exception {
439 "${workdir}/src1/test/Test.java:4: warning: [test] test\n" +
440 " boolean b1 = c.size() == 0;\n" +
442 "${workdir}/src2/test/Test.java:5: warning: [test] test\n" +
443 " boolean b2 = c.size() != 0;\n" +
446 "cp1/META-INF/upgrade/test.hint",
447 "$coll.size() == 0 :: $coll instanceof java.util.Collection;;",
448 "src1/test/Test.java",
450 "public class Test {\n" +
451 " private void test(java.util.Collection c) {\n" +
452 " boolean b1 = c.size() == 0;\n" +
453 " boolean b2 = c.size() != 0;\n" +
456 "cp2/META-INF/upgrade/test.hint",
457 "$coll.size() != 0 :: $coll instanceof java.util.Collection;;",
458 "src2/test/Test.java",
460 "public class Test {\n" +
461 " private void test(java.util.Collection c) {\n" +
462 " boolean b1 = c.size() == 0;\n" +
463 " boolean b2 = c.size() != 0;\n" +
469 "--classpath ${workdir}/cp1 ${workdir}/src1",
471 "--classpath ${workdir}/cp2 ${workdir}/src2");
474 public void testGroupsList() throws Exception {
477 @Override public void validate(String content) {
478 assertTrue("Missing expected content, actual content: " + content, content.contains("test\n"));
482 "cp1/META-INF/upgrade/test.hint",
483 "$coll.size() == 0 :: $coll instanceof java.util.Collection;;",
484 "src1/test/Test.java",
486 "cp2/META-INF/upgrade/test.hint",
487 "$coll.size() != 0 :: $coll instanceof java.util.Collection;;",
488 "src2/test/Test.java",
493 "--classpath ${workdir}/cp1 ${workdir}/src1",
495 "--classpath ${workdir}/cp2 ${workdir}/src2",
499 public void testNoHintsFoundWithGroups() throws Exception {
500 doRunCompiler("package test;\n" +
501 "public class Test {\n" +
502 " private void test(java.util.Collection c) {\n" +
503 " boolean b1 = c.isEmpty();\n" +
504 " boolean b2 = c.size() != 0;\n" +
509 "cp/META-INF/upgrade/test.hint",
510 "$coll.size() == 0 :: $coll instanceof java.util.Collection\n" +
512 "$coll.isEmpty()\n" +
514 "src/test/Test.java",
516 "public class Test {\n" +
517 " private void test(java.util.Collection c) {\n" +
518 " boolean b1 = c.size() == 0;\n" +
519 " boolean b2 = c.size() != 0;\n" +
522 "src2/test/Test.java",
524 "public class Test {\n" +
525 " private void test(java.util.Collection c) {\n" +
526 " boolean b1 = c.size() == 0;\n" +
527 " boolean b2 = c.size() != 0;\n" +
533 "--classpath ${workdir}/cp ${workdir}/src",
539 public void testGroupsParamEscape() throws Exception {
540 assertEquals(Arrays.asList("a b", "a\\b"),
541 Arrays.asList(Main.splitGroupArg("a\\ b a\\\\b")));
544 private static final String DONT_APPEND_PATH = new String("DONT_APPEND_PATH");
546 private void doRunCompiler(String golden, String stdOut, String stdErr, String... fileContentAndExtraOptions) throws Exception {
547 doRunCompiler(equivalentValidator(golden), equivalentValidator(stdOut), equivalentValidator(stdErr), fileContentAndExtraOptions);
550 private void doRunCompiler(Validator fileContentValidator, Validator stdOutValidator, Validator stdErrValidator, String... fileContentAndExtraOptions) throws Exception {
551 doRunCompiler(fileContentValidator, stdOutValidator, stdErrValidator, 0, fileContentAndExtraOptions);
554 private void doRunCompiler(Validator fileContentValidator, Validator stdOutValidator, Validator stdErrValidator, int exitcode, String... fileContentAndExtraOptions) throws Exception {
555 List<String> fileAndContent = new LinkedList<String>();
556 List<String> extraOptions = new LinkedList<String>();
557 List<String> fileContentAndExtraOptionsList = Arrays.asList(fileContentAndExtraOptions);
558 int nullPos = fileContentAndExtraOptionsList.indexOf(null);
560 if (nullPos == (-1)) {
561 fileAndContent = fileContentAndExtraOptionsList;
562 extraOptions = Collections.emptyList();
564 fileAndContent = fileContentAndExtraOptionsList.subList(0, nullPos);
565 extraOptions = fileContentAndExtraOptionsList.subList(nullPos + 1, fileContentAndExtraOptionsList.size());
568 assertTrue(fileAndContent.size() % 2 == 0);
572 for (int cntr = 0; cntr < fileAndContent.size(); cntr += 2) {
573 File target = new File(getWorkDir(), fileAndContent.get(cntr));
575 target.getParentFile().mkdirs();
577 TestUtilities.copyStringToFile(target, fileAndContent.get(cntr + 1));
580 File wd = getWorkDir();
581 File source = new File(wd, "src/test/Test.java");
583 List<String> options = new LinkedList<String>();
584 boolean appendPath = true;
586 options.add("--cache");
587 options.add("/tmp/cachex");
588 for (String extraOption : extraOptions) {
589 if (extraOption == DONT_APPEND_PATH) {
593 options.add(extraOption.replace("${workdir}", wd.getAbsolutePath()));
597 options.add(wd.getAbsolutePath());
599 String[] output = new String[2];
601 reallyRunCompiler(wd, exitcode, output, options.toArray(new String[0]));
603 if (fileContentValidator != null) {
604 fileContentValidator.validate(TestUtilities.copyFileToString(source));
606 if (stdOutValidator != null) {
607 stdOutValidator.validate(output[0].replaceAll(Pattern.quote(wd.getAbsolutePath()), Matcher.quoteReplacement("${workdir}")));
609 if (stdErrValidator != null) {
610 stdErrValidator.validate(output[1].replaceAll(Pattern.quote(wd.getAbsolutePath()), Matcher.quoteReplacement("${workdir}")));
614 protected void reallyRunCompiler(File workDir, int exitcode, String[] output, String... params) throws Exception {
615 String oldUserDir = System.getProperty("user.dir");
617 System.setProperty("user.dir", workDir.getAbsolutePath());
619 PrintStream oldOut = System.out;
620 ByteArrayOutputStream outData = new ByteArrayOutputStream();
621 System.setOut(new PrintStream(outData, true, "UTF-8"));
623 PrintStream oldErr = System.err;
624 ByteArrayOutputStream errData = new ByteArrayOutputStream();
625 System.setErr(new PrintStream(errData, true, "UTF-8"));
628 assertEquals(exitcode, Main.compile(params));
630 System.setProperty("user.dir", oldUserDir);
632 output[0] = new String(outData.toByteArray(), "UTF-8");
633 System.setOut(oldOut);
635 output[1] = new String(errData.toByteArray(), "UTF-8");
636 System.setErr(oldErr);
640 //verify that the DeclarativeHintsTestBase works:
641 private static final String CODE_RUN_DECLARATIVE =
642 "package org.netbeans.modules.jackpot30.cmdline.testtool;\n" +
644 "import junit.framework.TestSuite;\n" +
645 "import org.netbeans.modules.java.hints.declarative.test.api.DeclarativeHintsTestBase;\n" +
647 "public class DoRunTests extends DeclarativeHintsTestBase {\n" +
649 " public static TestSuite suite() {\n" +
650 " return suite(DoRunTests.class);\n" +
654 public void testRunTest() throws Exception {
657 File wd = getWorkDir();
658 File classes = new File(wd, "classes");
661 TestUtilities.copyStringToFile(new File(classes, "h.hint"), "$1.equals(\"\") :: $1 instanceof java.lang.String => $1.isEmpty();;");
663 String test = "%%TestCase pos\n" +
665 "public class Test {{\n" +
666 " System.err.println(\"a\".equals(\"\"));\n" +
670 "public class Test {{\n" +
671 " System.err.println(\"a\".isEmpty());\n" +
675 "public class Test {{\n" +
676 " System.err.println(\"a\".equals(\"a\"));\n" +
680 "public class Test {{\n" +
681 " System.err.println(\"a\".isEmpty());\n" +
683 TestUtilities.copyStringToFile(new File(classes, "h.test"), test);
685 List<String> options = Arrays.asList("-d", classes.getAbsolutePath());
686 List<SourceFO> files = Arrays.asList(new SourceFO("DoRunTests.java", CODE_RUN_DECLARATIVE));
688 assertTrue(ToolProvider.getSystemJavaCompiler().getTask(null, null, null, options, null, files).call());
693 private static final class SourceFO extends SimpleJavaFileObject {
695 private final String code;
696 private SourceFO(String name, String code) throws URISyntaxException {
697 super(new URI("mem:///" + name), Kind.SOURCE);
702 public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
708 protected void runAndTest(File classes) throws Exception {
709 ClassLoader cl = new URLClassLoader(new URL[] {classes.toURI().toURL()}, MainTest.class.getClassLoader());
710 Class<?> doRunTests = Class.forName("org.netbeans.modules.jackpot30.cmdline.testtool.DoRunTests", true, cl);
711 Result testResult = org.junit.runner.JUnitCore.runClasses(doRunTests);
713 assertEquals(1, testResult.getFailureCount());
714 assertTrue(testResult.getFailures().toString(), testResult.getFailures().get(0).getDescription().getMethodName().endsWith("/h.test/neg"));
717 private static Validator equivalentValidator(final String expected) {
718 if (expected == null) return null;
720 return new Validator() {
721 @Override public void validate(String content) {
722 assertEquals(expected, content);
727 private static interface Validator {
728 public void validate(String content);