blob: 8af2990c8c01e84160732b412e1414f72d8e9056 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.wst.jsdt.core.tests.compiler.regression;
import java.io.File;
import java.util.ArrayList;
import java.util.Map;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.wst.jsdt.core.tests.junit.extension.TestCase;
import org.eclipse.wst.jsdt.core.tests.util.AbstractCompilerTest;
import org.eclipse.wst.jsdt.core.tests.util.Util;
import org.eclipse.wst.jsdt.internal.compiler.impl.CompilerOptions;
public abstract class JavadocTest extends AbstractRegressionTest {
boolean useLibrary = false;
static String ZIP_FILE = "/TestJavadocVisibility.zip";
static final String LINE_SEPARATOR = System.getProperty("line.separator");
public static ArrayList ALL_CLASSES = null;
static final String DOC_COMMENT_SUPPORT = System.getProperty("doc.support");
static boolean debug = false;
// Javadoc execution
protected static final String JAVADOC_NAME =
File.pathSeparatorChar == ':' ? "javadoc" : "javadoc.exe";
protected static String javadocCommandLineHeader;
static {
ALL_CLASSES = new ArrayList();
ALL_CLASSES.add(JavadocTestForMethod.class);
ALL_CLASSES.add(JavadocTestMixed.class);
ALL_CLASSES.add(JavadocTestForClass.class);
ALL_CLASSES.add(JavadocTestForConstructor.class);
ALL_CLASSES.add(JavadocTestForField.class);
ALL_CLASSES.add(JavadocTestOptions.class);
}
public static void addTest(TestSuite suite, Class testClass) {
TestSuite innerSuite = new TestSuite(testClass);
suite.addTest(innerSuite);
}
public static Test suite() {
TestSuite testSuite = new TestSuite(JavadocTest.class.getName());
// Reset forgotten subsets of tests
TestCase.TESTS_PREFIX = null;
TestCase.TESTS_NAMES = null;
TestCase.TESTS_NUMBERS = null;
TestCase.TESTS_RANGE = null;
TestCase.RUN_ONLY_ID = null;
for (int i = 0, size=ALL_CLASSES.size(); i < size; i++) {
Class testClass = (Class) ALL_CLASSES.get(i);
Test suite = buildAllCompliancesTestSuite(testClass);
testSuite.addTest(suite);
}
return testSuite;
}
public static Test suiteForComplianceLevel(String level, Class testClass) {
Test suite = buildAllCompliancesTestSuite(testClass);
return new RegressionTestSetup(suite, level);
}
public JavadocTest(String name) {
super(name);
}
protected Map getCompilerOptions() {
Map options = super.getCompilerOptions();
options.put(CompilerOptions.OPTION_ReportFieldHiding, CompilerOptions.IGNORE);
// options.put(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, CompilerOptions.IGNORE);
options.put(CompilerOptions.OPTION_DocCommentSupport, CompilerOptions.ENABLED);
// Set default before bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=110964 changes
options.put(CompilerOptions.OPTION_ReportInvalidJavadocTagsVisibility, CompilerOptions.PRIVATE);
options.put(CompilerOptions.OPTION_ReportInvalidJavadocTags, CompilerOptions.ENABLED);
options.put(CompilerOptions.OPTION_ReportInvalidJavadocTagsDeprecatedRef, CompilerOptions.ENABLED);
options.put(CompilerOptions.OPTION_ReportInvalidJavadocTagsNotVisibleRef, CompilerOptions.ENABLED);
options.put(CompilerOptions.OPTION_ReportMissingJavadocTagsVisibility, CompilerOptions.PRIVATE);
// options.put(CompilerOptions.OPTION_ReportMissingSerialVersion, CompilerOptions.IGNORE);
return options;
}
protected String[] getDefaultClassPaths() {
if (useLibrary) {
String[] classLibs = super.getDefaultClassPaths();
final int length = classLibs.length;
String[] newClassPaths = new String[length + 1];
System.arraycopy(classLibs, 0, newClassPaths, 0, length);
newClassPaths[length] = getClass().getResource(ZIP_FILE).getPath();
return newClassPaths;
}
return super.getDefaultClassPaths();
}
static String[] referencedClasses = null;
static {
referencedClasses =
new String[] {
"test/AbstractVisibility.java",
"package test;\n" +
"public abstract class AbstractVisibility {\n" +
" private class AvcPrivate {\n" +
" private int avf_private = 10;\n" +
" public int avf_public = avf_private;\n" +
" private int avm_private() {\n" +
" avf_private = (new AvcPrivate()).avf_private;\n" +
" return avf_private;\n" +
" }\n" +
" public int avm_public() {\n" +
" return avm_private();\n" +
" }\n" +
" }\n" +
" public class AvcPublic {\n" +
" private int avf_private = 10;\n" +
" public int avf_public = avf_private;\n" +
" private int avm_private() {\n" +
" avf_private = (new AvcPrivate()).avf_private;\n" +
" return avf_private;\n" +
" }\n" +
" public int avm_public() {\n" +
" return avm_private();\n" +
" }\n" +
" }\n" +
" private int avf_private = 100;\n" +
" public int avf_public = avf_private;\n" +
" \n" +
" private int avm_private() {\n" +
" avf_private = (new AvcPrivate()).avf_private;\n" +
" return avf_private;\n" +
" }\n" +
" public int avm_public() {\n" +
" return avm_private();\n" +
" }\n" +
"}\n",
"test/Visibility.java",
"package test;\n" +
"public class Visibility extends AbstractVisibility {\n" +
" private class VcPrivate {\n" +
" private int vf_private = 10;\n" +
" public int vf_public = vf_private;\n" +
" private int vm_private() {\n" +
" vf_private = (new VcPrivate()).vf_private;\n" +
" avf_private = vf_private;\n" +
" return vf_private+avf_private;\n" +
" }\n" +
" public int vm_public() {\n" +
" return vm_private();\n" +
" }\n" +
" };\n" +
" public class VcPublic {\n" +
" private int vf_private = 10;\n" +
" public int vf_public = vf_private;\n" +
" private int vm_private() {\n" +
" vf_private = (new VcPrivate()).vf_private;\n" +
" avf_private = vf_private;\n" +
" return vf_private+avf_private;\n" +
" }\n" +
" public int vm_public() {\n" +
" return vm_private();\n" +
" }\n" +
" };\n" +
" private int vf_private = 100;\n" +
" private int avf_private = 100;\n" +
" public int vf_public = vf_private;\n" +
" public int avf_public = vf_private;\n" +
" \n" +
" private int vm_private() {\n" +
" vf_private = (new VcPrivate()).vf_private;\n" +
" avf_private = vf_private;\n" +
" return vf_private+avf_private;\n" +
" }\n" +
" public int vm_public() {\n" +
" return vm_private();\n" +
" }\n" +
"}\n",
"test/copy/VisibilityPackage.java",
"package test.copy;\n" +
"class VisibilityPackage {\n" +
" private class VpPrivate {\n" +
" private int vf_private = 10;\n" +
" public int vf_public = vf_private;\n" +
" private int vm_private() {\n" +
" vf_private = (new VpPrivate()).vf_private;\n" +
" return vf_private;\n" +
" }\n" +
" public int vm_public() {\n" +
" return vm_private();\n" +
" }\n" +
" }\n" +
" public class VpPublic {\n" +
" private int vf_private = 10;\n" +
" public int vf_public = vf_private;\n" +
" private int vm_private() {\n" +
" vf_private = (new VpPrivate()).vf_private;\n" +
" return vf_private;\n" +
" }\n" +
" public int vm_public() {\n" +
" return vm_private();\n" +
" }\n" +
" }\n" +
" private int vf_private = 100;\n" +
" public int vf_public = vf_private;\n" +
" \n" +
" private int vm_private() {\n" +
" vf_private = (new VpPrivate()).vf_private;\n" +
" return vf_private;\n" +
" }\n" +
" public int vm_public() {\n" +
" return vm_private();\n" +
" }\n" +
"}\n",
"test/copy/VisibilityPublic.java",
"package test.copy;\n" +
"public class VisibilityPublic {\n" +
" private class VpPrivate {\n" +
" private int vf_private = 10;\n" +
" public int vf_public = vf_private;\n" +
" private int vm_private() {\n" +
" vf_private = (new VpPrivate()).vf_private;\n" +
" return vf_private;\n" +
" }\n" +
" public int vm_public() {\n" +
" return vm_private();\n" +
" }\n" +
" }\n" +
" public class VpPublic {\n" +
" private int vf_private = 10;\n" +
" public int vf_public = vf_private;\n" +
" private int vm_private() {\n" +
" vf_private = (new VpPrivate()).vf_private;\n" +
" return vf_private;\n" +
" }\n" +
" public int vm_public() {\n" +
" return vm_private();\n" +
" }\n" +
" }\n" +
" private int vf_private = 100;\n" +
" public int vf_public = vf_private;\n" +
" \n" +
" private int vm_private() {\n" +
" vf_private = (new VpPrivate()).vf_private;\n" +
" return vf_private;\n" +
" }\n" +
" public int vm_public() {\n" +
" return vm_private();\n" +
" }\n" +
"}\n" };
}
/* (non-Javadoc)
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
super.setUp();
if (RUN_JAVAC) {
javadocCommandLineHeader =
jdkRootDirPath.append("bin").append(JAVADOC_NAME).toString(); // PREMATURE replace JAVA_NAME and JAVAC_NAME with locals? depends on potential reuse
}
// SHIFT = true;
// INDENT = 3;
}
/* (non-Javadoc)
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
// SHIFT = false;
// INDENT = 2;
super.tearDown();
}
protected void runConformReferenceTest(String[] testFiles) {
String[] completedFiles = testFiles;
if (!useLibrary) {
completedFiles = new String[testFiles.length + referencedClasses.length];
System.arraycopy(referencedClasses, 0, completedFiles, 0, referencedClasses.length);
System.arraycopy(testFiles, 0, completedFiles, referencedClasses.length, testFiles.length);
}
runConformTest(completedFiles);
}
protected void runNegativeReferenceTest(String[] testFiles, String expected) {
String[] completedFiles = testFiles;
if (!useLibrary) {
completedFiles = new String[testFiles.length + referencedClasses.length];
System.arraycopy(referencedClasses, 0, completedFiles, 0, referencedClasses.length);
System.arraycopy(testFiles, 0, completedFiles, referencedClasses.length, testFiles.length);
}
runNegativeTest(completedFiles, expected);
}
/* (non-Javadoc)
* @see org.eclipse.wst.jsdt.core.tests.compiler.regression.AbstractRegressionTest#runConformTest(java.lang.String[], java.lang.String, java.lang.String[], boolean, java.lang.String[], java.util.Map, org.eclipse.wst.jsdt.internal.compiler.ICompilerRequestor)
*
protected void runConformTest(String[] testFiles,
String expectedSuccessOutputString,
String[] classLib,
boolean shouldFlushOutputDirectory,
String[] vmArguments,
Map customOptions,
ICompilerRequestor clientRequestor) {
if (TESTS_NAMES != null || TESTS_PREFIX != null || TESTS_NUMBERS != null || TESTS_RANGE != null) {
writeFiles(testFiles);
}
super.runConformTest(testFiles,
expectedSuccessOutputString,
classLib,
shouldFlushOutputDirectory,
vmArguments,
customOptions,
clientRequestor);
}
/* (non-Javadoc)
* @see org.eclipse.wst.jsdt.core.tests.compiler.regression.AbstractRegressionTest#runNegativeTest(java.lang.String[], java.lang.String, java.lang.String[], boolean, java.util.Map, boolean)
*
protected void runNegativeTest(String[] testFiles,
String expectedProblemLog,
String[] classLib,
boolean shouldFlushOutputDirectory,
Map customOptions,
boolean generateOutput) {
if (TESTS_NAMES != null || TESTS_PREFIX != null || TESTS_NUMBERS != null || TESTS_RANGE != null) {
writeFiles(testFiles);
}
super.runNegativeTest(testFiles,
expectedProblemLog,
classLib,
shouldFlushOutputDirectory,
customOptions,
generateOutput);
}
*/
protected void writeFiles(String[] testFiles) {
String classDirName = getClass().getName().substring(getClass().getName().lastIndexOf('.')+1); //.substring(11);
String testName = getName();
int idx = testName.indexOf(" - ");
if (idx > 0) {
testName = testName.substring(idx+3);
}
// File dir = new File("d:/usr/OTI/tests/javadoc/");
// non portable
createOutputTestDirectory(classDirName);
createOutputTestDirectory(Character.toUpperCase(testName.charAt(0)) +
testName.substring(1));
System.out.println("Write test file to " +
this.outputTestDirectory.getPath() + "...");
for (int i=0, length=testFiles.length; i<length; i++) {
String contents = testFiles[i+1];
String fileName = testFiles[i++];
String dirFileName = this.outputTestDirectory.getPath();
if (fileName.indexOf("Visibility")>0) {
continue;
} else {
int index = fileName.lastIndexOf('/');
if (index > 0) {
String subdirs = fileName.substring(0, index);
String packName = subdirs.replace('/', '.');
contents = "package "+packName+";"+contents.substring(contents.indexOf(';')+1);
File dir = new File(dirFileName, subdirs);
if (!dir.exists()) dir.mkdirs();
if (RUN_JAVAC) {
Util.writeToFile(contents, dirFileName+"/"+fileName);
// PREMATURE this results into a duplicate file.
}
fileName = fileName.substring(index+1);
}
}
Util.writeToFile(contents, dirFileName+"/"+fileName);
// REVIEW don't know why this is created at the default package level
}
}
/*
* Run Sun compilation using javadoc.
* See implementation in parent for details.
*/
protected void runJavac(
String[] testFiles,
final String expectedProblemLog,
final String expectedSuccessOutputString,
boolean shouldFlushOutputDirectory) {
String testName = null;
Process compileProcess = null;
Process execProcess = null;
try {
// Init test name
testName = testName();
// Cleanup javac output dir if needed
File javacOutputDirectory = new File(JAVAC_OUTPUT_DIR);
if (shouldFlushOutputDirectory) {
Util.delete(javacOutputDirectory);
}
// Write files in dir
writeFiles(testFiles);
// Prepare command line
StringBuffer cmdLine = new StringBuffer(javadocCommandLineHeader);
// compute extra classpath
String[] classpath = Util.concatWithClassLibs(JAVAC_OUTPUT_DIR, false);
StringBuffer cp = new StringBuffer(" -classpath ");
int length = classpath.length;
for (int i = 0; i < length; i++) {
if (i > 0)
cp.append(File.pathSeparatorChar);
if (classpath[i].indexOf(" ") != -1) {
cp.append("\"" + classpath[i] + "\"");
} else {
cp.append(classpath[i]);
}
}
cmdLine.append(cp);
// add source files
for (int i = 0; i < testFiles.length; i += 2) {
// *.java is not enough (p1/X.java, p2/Y.java)
cmdLine.append(' ');
cmdLine.append(testFiles[i]);
}
// Launch process
compileProcess = Runtime.getRuntime().exec(
cmdLine.toString(), null, this.outputTestDirectory);
// Log errors
Logger errorLogger = new Logger(compileProcess.getErrorStream(), "ERROR");
// Log output
Logger outputLogger = new Logger(compileProcess.getInputStream(), "OUTPUT");
// start the threads to run outputs (standard/error)
errorLogger.start();
outputLogger.start();
// Wait for end of process
int exitValue = compileProcess.waitFor();
errorLogger.join(); // make sure we get the whole output
outputLogger.join();
// Report raw javadoc results
if (! testName.equals(javacTestName)) {
javacTestName = testName;
javacTestErrorFlag = false;
javacFullLog.println("-----------------------------------------------------------------");
javacFullLog.println(CURRENT_CLASS_NAME + " " + testName);
}
if (exitValue != 0) {
javacTestErrorFlag = true;
}
if (errorLogger.buffer.length() > 0) {
javacFullLog.println("--- javac err: ---");
javacFullLog.println(errorLogger.buffer.toString());
}
if (outputLogger.buffer.length() > 0) {
javacFullLog.println("--- javac out: ---");
javacFullLog.println(outputLogger.buffer.toString());
}
// Compare compilation results
if (expectedProblemLog == null || expectedProblemLog.length() == 0) {
// Eclipse found no error and no warning
if (exitValue != 0) {
// Javac found errors
System.out.println("----------------------------------------");
System.out.println(testName + " - Javadoc has found error(s) but Eclipse expects conform result:\n");
javacFullLog.println("JAVAC_MISMATCH: Javadoc has found error(s) but Eclipse expects conform result");
System.out.println(errorLogger.buffer.toString());
printFiles(testFiles);
DIFF_COUNTERS[0]++;
}
else {
// Javac found no error - may have found warnings
if (errorLogger.buffer.length() > 0) {
System.out.println("----------------------------------------");
System.out.println(testName + " - Javadoc has found warning(s) but Eclipse expects conform result:\n");
javacFullLog.println("JAVAC_MISMATCH: Javadoc has found warning(s) but Eclipse expects conform result");
System.out.println(errorLogger.buffer.toString());
printFiles(testFiles);
DIFF_COUNTERS[0]++;
}
}
}
else {
// Eclipse found errors or warnings
if (errorLogger.buffer.length() == 0) {
System.out.println("----------------------------------------");
System.out.println(testName + " - Eclipse has found error(s)/warning(s) but Javadoc did not find any:");
javacFullLog.println("JAVAC_MISMATCH: Eclipse has found error(s)/warning(s) but Javadoc did not find any");
dualPrintln("eclipse:");
dualPrintln(expectedProblemLog);
printFiles(testFiles);
DIFF_COUNTERS[1]++;
} else if (expectedProblemLog.indexOf("ERROR") > 0 && exitValue == 0){
System.out.println("----------------------------------------");
System.out.println(testName + " - Eclipse has found error(s) but Javadoc only found warning(s):");
javacFullLog.println("JAVAC_MISMATCH: Eclipse has found error(s) but Javadoc only found warning(s)");
dualPrintln("eclipse:");
dualPrintln(expectedProblemLog);
System.out.println("javadoc:");
System.out.println(errorLogger.buffer.toString());
printFiles(testFiles);
DIFF_COUNTERS[1]++;
} else {
// PREMATURE refine comparison
// TODO (frederic) compare warnings in each result and verify they are similar...
// System.out.println(testName+": javac has found warnings :");
// System.out.print(errorLogger.buffer.toString());
// System.out.println(testName+": we're expecting warning results:");
// System.out.println(expectedProblemLog);
}
}
}
catch (InterruptedException e1) {
if (compileProcess != null) compileProcess.destroy();
if (execProcess != null) execProcess.destroy();
System.out.println(testName+": Sun javadoc compilation was aborted!");
javacFullLog.println("JAVAC_WARNING: Sun javadoc compilation was aborted!");
e1.printStackTrace(javacFullLog);
}
catch (Throwable e) {
System.out.println(testName+": could not launch Sun javadoc compilation!");
e.printStackTrace();
javacFullLog.println("JAVAC_ERROR: could not launch Sun javac compilation!");
e.printStackTrace(javacFullLog);
// PREMATURE failing the javac pass or comparison could also fail
// the test itself
}
finally {
Util.delete(outputTestDirectory);
}
}
protected void printJavacResultsSummary() {
if (RUN_JAVAC) {
Integer count = (Integer)TESTS_COUNTERS.get(CURRENT_CLASS_NAME);
if (count != null) {
int newCount = count.intValue()-1;
TESTS_COUNTERS.put(CURRENT_CLASS_NAME, Integer.valueOf(newCount));
if (newCount == 0) {
if (DIFF_COUNTERS[0]!=0 || DIFF_COUNTERS[1]!=0 || DIFF_COUNTERS[2]!=0) {
dualPrintln("===========================================================================");
dualPrintln("Results summary:");
}
if (DIFF_COUNTERS[0]!=0)
dualPrintln(" - "+DIFF_COUNTERS[0]+" test(s) where Javadoc found errors/warnings but Eclipse did not");
if (DIFF_COUNTERS[1]!=0)
dualPrintln(" - "+DIFF_COUNTERS[1]+" test(s) where Eclipse found errors/warnings but Javadoc did not");
System.out.println("\n");
}
}
javacFullLog.flush();
}
}
}