| /******************************************************************************* |
| * Copyright (c) 2000, 2010 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.core.tests.formatter; |
| |
| import java.io.BufferedOutputStream; |
| import java.io.BufferedReader; |
| import java.io.BufferedWriter; |
| import java.io.File; |
| import java.io.FileFilter; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.FileOutputStream; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.InputStreamReader; |
| import java.io.PrintStream; |
| import java.net.URL; |
| import java.text.NumberFormat; |
| import java.text.SimpleDateFormat; |
| import java.util.ArrayList; |
| import java.util.Date; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.StringTokenizer; |
| |
| import junit.framework.AssertionFailedError; |
| import junit.framework.ComparisonFailure; |
| import junit.framework.Test; |
| import junit.framework.TestSuite; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.FileLocator; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.jdt.core.compiler.CategorizedProblem; |
| import org.eclipse.jdt.core.formatter.CodeFormatter; |
| import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants; |
| import org.eclipse.jdt.core.tests.model.ModelTestsUtil; |
| import org.eclipse.jdt.core.tests.util.Util; |
| import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; |
| import org.eclipse.jdt.internal.compiler.problem.DefaultProblem; |
| import org.eclipse.jdt.internal.core.util.CodeSnippetParsingUtil; |
| import org.eclipse.jdt.internal.formatter.DefaultCodeFormatter; |
| import org.eclipse.jdt.internal.formatter.DefaultCodeFormatterOptions; |
| import org.eclipse.text.edits.TextEdit; |
| |
| /** |
| * Comment formatter test suite for massive tests at a given location. |
| * <p> |
| * This test suite has only one generic test. When running this test suite, one test |
| * is created per compilation unit found while traversing the directory specified |
| * using the <code>inputDir</code> system property<br>(e.g. |
| * <code>-DinputDir=D:\eclipse\workspaces\formatter\inputs\full-src-30</code>). |
| * </p><p> |
| * Each test formats twice the compilation unit and compare the result to a |
| * previous formatting already stored at the same location from a root directory |
| * specified using the <code>outputDir</code> system property. |
| * </p><p> |
| * For example, if <code>outputDir</code> is set to the following value:<br> |
| * <code>-DoutputDir=D:\eclipse\workspaces\formatter\outputs</code><br> |
| * then a compilation unit found in <code>...\inputs\full-src-30\test\A.java</code> |
| * will be compared with the previously stored output in: |
| * <code>...\outputs\full-src-30\test\A.java</code> |
| * </p><p> |
| * To store the outputs on a specific input directory using a specific version, |
| * then load a JDT/Core version in the workspace and run this test suite using |
| * the following VM arguments: |
| * <pre> |
| * -DinputDir=D:\eclipse\workspaces\formatter\inputs\full-src-30 |
| * -DoutputDir=D:\eclipse\workspaces\formatter\outputs,clean |
| * </pre> |
| * Note the <code>clean</code> arguments added at the end of the outputDir |
| * system property to signify that the formatter outputs must be cleaned and |
| * stored. |
| * </p><p> |
| * The <code>logDir</code> system property can be set to tell the suite to |
| * write the console output in a file located in the specified directory. That makes |
| * the comparison between version and patches easier to do using the eclipse |
| * file comparison... |
| * </p><p><br> |
| * <b>***************************************<br> |
| * * Process to run massive tests against a patch *<br> |
| * ***************************************</b> |
| * <p> |
| * Here is the full description of the process to run massive tests against a patch |
| * using this test suite and all the compilation units of the JDT/Core performance |
| * <b>full-source-R3_0.zip</b> file... |
| * </p> |
| * <h3>Set-up input directory</h3> |
| * <p> |
| * The test suite needs to know where are the sources which will be used |
| * to massively test the formatter. To make it easy to set-up, only a root directory |
| * is necessary. From there, all compilation units found while traversing the tree of |
| * this directory will be used for the massive tests. |
| * </p><p> |
| * In our example, we will extract the content of the <b>full-source-R3_0.zip</b> |
| * file located in the <b>org.eclipse.jdt.core.tests.performance</b> plugin |
| * somewhere on our local disk... let's say in the |
| * <b>D:\tmp\formatter\inputs\full-src-30</b> directory. |
| * </p> |
| * <h3>Create the output reference</h3> |
| * <p> |
| * The reference from which the patch output will be compared to while running |
| * the massive test needs also to be created. To do this, a launch config |
| * for the <code>FormatterMassiveRegressionTests</code> test suite is necessary. |
| * </p><p> |
| * For example, create a launch config named |
| * <b>FormatterMassiveRegressionTests (Eclipse 3.0 - clean)</b> with the |
| * following VM arguments: |
| * <pre> |
| * -Xmx256M |
| * -DinputDir=D:\tmp\formatter\inputs\full-src-30 |
| * -DoutputDir=D:\tmp\formatter\outputs,clean |
| * -DlogDir=D:\tmp\formatter\log |
| * </pre> |
| * </p><p> |
| * Load the last version of JDT/Core plugins (e.g. <code>v_B11</code>) and |
| * launch this config... |
| * </p><p> |
| * When done, the console should have the following content: |
| * <pre> |
| * Get all files from D:\tmp\formatter\inputs\full-src-30...done |
| * Deleting all files from D:\tmp\formatter\outputs\v37\full-src-30...done |
| * Version : v_B11 |
| * Profiles : none! |
| * Test date : 9/12/10 1:47 PM |
| * Input dir : D:\tmp\formatter\inputs\full-src-30 |
| * 9950 java files to format... |
| * Output dir: D:\tmp\formatter\outputs\v37\full-src-30 |
| * CLEANED |
| * </pre> |
| * Looking at the output directory, it should contain the same folders tree than |
| * the input one... |
| * </p> |
| * <h3>Create the log reference</h3> |
| * <p> |
| * The test suite log several problems which may occur while formatting a unit: |
| * <ul> |
| * <li>the file may have compilation errors preventing the formatter to proceed</li> |
| * <li>there's no output while formatting</li> |
| * <li>the output may be different while formatting twice</li> |
| * <li>the output may be different while formatting twice but only by leading whitespaces</li> |
| * <li>the output may be different while formatting twice but only by whitespaces</li> |
| * </ul> |
| * </p><p> |
| * Even with last version of the formatter, such problems may happen on one or |
| * several tested compilation unit. So, it's important to know which are the existing |
| * issues of the used formatter version (e.g. <code>v_B11</code> in our example...). |
| * </p><p> |
| * To do this, another launch config is necessary to run the massive tests of the |
| * loaded JDT/Core version. |
| * </p><p> |
| * For example, copy the previous launch config and rename it |
| * <b>FormatterMassiveRegressionTests (Eclipse 3.0)</b>. Change the VM |
| * arguments as follows (<i>note that the <code>clean</code> has been removed |
| * from the <code>outputDir</code> system property</i>): |
| * <pre> |
| * -Xmx256M |
| * -DinputDir=D:\tmp\formatter\inputs\full-src-30 |
| * -DoutputDir=D:\tmp\formatter\outputs |
| * -DlogDir=D:\tmp\formatter\log |
| * </pre> |
| * </p><p> |
| * Launch the config... |
| * </p><p> |
| * The log file contains the console output but also the complete list of the units |
| * on which problems were observed. As this run was done with the JDT/Core |
| * version it can be considered as the reference for this version... |
| * </p><p> |
| * Note that for our example, the observed problems for <code>v_B11</code> |
| * version while running massive tests on a Eclipse 3.0 performance workspace |
| * (9951 units) are: |
| * <ul> |
| * <li>1 file has compilation errors which prevent the formatter to proceed!</li> |
| * <li>4 files have different output while reformatting twice!</li> |
| * <li>10 files have different output while reformatting twice but only by leading whitespaces!</li> |
| * <li>4 files have different output while reformatting twice but only by whitespaces!</li> |
| * </ul> |
| * </p> |
| * <h3>Run the massive tests on the patch</h3> |
| * <p> |
| * As the setup has been done for the massive tests, it's now possible to test a |
| * patch applied on the reference version (<code>v_B11</code>). For this, the |
| * patch needs of course to be applied first and also the <b>buildnotes_jdt-core.html</b> |
| * modified. |
| * </p><p> |
| * If the patch vXX of bug XXXXXX is about to be tested, then the line |
| * <code>Patch vXX for bug XXXXXX</code> needs to be added at the |
| * beginning of the first <b>What's new in this drop</b> section of the |
| * <b>buildnotes_jdt-core.html</b> file, e.g.: |
| * <pre> |
| * <h2>What's new in this drop</h2> |
| * Patch v05 for bug 303519 |
| * <ul> |
| * ... |
| * </pre> |
| * </p><p> |
| * Launch the <b>FormatterMassiveRegressionTests (Eclipse 3.0)</b> config... |
| * </p><p> |
| * Like the previous run, the written log file contains the complete list of the units |
| * on which problems were observed. Comparing this log file with the reference one |
| * will show whether the patch implies behavior changes for the formatter or not. |
| * </p> |
| */ |
| public class FormatterMassiveRegressionTests extends FormatterRegressionTests { |
| |
| final File file; |
| final IPath path; |
| private DefaultCodeFormatterOptions preferences; |
| |
| // Directories |
| // private final static File INPUT_DIR = new File(System.getProperty("inputDir")); |
| private final File inputDir; |
| private static File OUTPUT_DIR; // use static to minimize data consumption |
| private static File WRITE_DIR; |
| |
| // Files |
| final static String FILES_FILTER = System.getProperty("filesFilter"); |
| final static int FILES_FILTER_KIND; |
| static { |
| int kind = 0; // No filter |
| if (FILES_FILTER != null) { |
| int length = FILES_FILTER.length(); |
| int idxQM = FILES_FILTER.indexOf('?'); |
| int idxS = FILES_FILTER.indexOf('*'); |
| if (idxQM >= 0 && idxS >= 0) { |
| kind = 4; // Pure pattern match |
| } else if (idxQM >= 0) { |
| while (idxQM < length && FILES_FILTER.charAt(idxQM) == '?') { |
| idxQM++; |
| } |
| if (idxQM == length) { |
| kind = 3; // Starts with + same length |
| } else { |
| kind = 4; // Pure pattern match |
| } |
| } else if (idxS >= 0) { |
| while (idxS < length && FILES_FILTER.charAt(idxQM) == '*') { |
| idxS++; |
| } |
| if (idxS == length) { |
| kind = 2; // Starts with |
| } else { |
| kind = 4; // Pure pattern match |
| } |
| } else { |
| kind = 1; // Equals |
| } |
| } |
| FILES_FILTER_KIND = kind; |
| } |
| |
| // Log |
| private static File LOG_FILE; |
| private static PrintStream LOG_STREAM; |
| |
| // Maintenance |
| private static boolean MAINTENANCE = false; |
| |
| // Comparison |
| private static boolean CLEAN = false; |
| private static boolean CAN_COMPARE = true; |
| private final boolean canCompare; |
| private final int testIndex; |
| |
| // Cleaning |
| private static boolean LIST = false; |
| private final static Map MAX_FILES = new HashMap(); |
| |
| // Formatting behavior |
| final static int FORMAT_REPEAT = Integer.parseInt(System.getProperty("repeat", "2")); |
| private final static boolean NO_COMMENTS = System.getProperty("no_comments", "false").equals("true"); |
| private final static String JOIN_LINES = System.getProperty("join_lines", null); |
| private final static String BRACES = System.getProperty("braces", null); |
| private final static int PRESERVED_LINES; |
| static { |
| String str = System.getProperty("preserved_lines", null); |
| int value = -1; |
| if (str != null) { |
| try { |
| value = Integer.parseInt(str); |
| } |
| catch (NumberFormatException nfe) { |
| // skip |
| } |
| } |
| PRESERVED_LINES = value; |
| } |
| private final int profiles; |
| private final static int PROFILE_NEVER_JOIN_LINES = 1; |
| private final static int PROFILE_JOIN_LINES_ONLY_COMMENTS = 2; |
| private final static int PROFILE_JOIN_LINES_ONLY_CODE = 3; |
| private final static int PROFILE_JOIN_LINES_MASK = 0x0003; |
| private final static int PROFILE_NO_COMMENTS = 1 << 2; |
| private final static int PROFILE_BRACES_NEXT_LINE = 1 << 3; |
| private final static int PROFILE_BRACES_NEXT_LINE_ON_WRAP = 2 << 3; |
| private final static int PROFILE_BRACES_NEXT_LINE_SHIFTED = 3 << 3; |
| private final static int PROFILE_BRACES_MASK = 0x0018; |
| private final static int PROFILE_PRESERVED_LINES_MASK = 0x00E0; |
| |
| // Time measuring |
| static class TimeMeasuring { |
| long[] formatting = new long[FORMAT_REPEAT]; |
| int [] occurences = new int[FORMAT_REPEAT]; |
| int [] null_output = new int[FORMAT_REPEAT]; |
| } |
| private static TimeMeasuring TIME_MEASURES; |
| private static final int ONE_MINUTE = 60000; |
| private static final long ONE_HOUR = 3600000L; |
| |
| // Failures management |
| int failureIndex; |
| final static int UNEXPECTED_FAILURE = 0; |
| final static int NO_OUTPUT_FAILURE = 1; |
| final static int COMPILATION_ERRORS_FAILURE = 2; |
| final static int FILE_NOT_FOUND_FAILURE = 3; |
| final static int COMPARISON_FAILURE = 4; |
| final static int REFORMATTING_FAILURE = 5; |
| final static int REFORMATTING_EXPECTED_FAILURE = 6; |
| final static int REFORMATTING_LEADING_FAILURE = 7; |
| final static int REFORMATTING_WHITESPACES_FAILURE = 8; |
| static class FormattingFailure { |
| String msg; |
| int kind; |
| List failures = new ArrayList(); |
| public FormattingFailure(int kind) { |
| this.kind = kind; |
| } |
| public FormattingFailure(int kind, String msg) { |
| this(kind); |
| this.msg = msg; |
| } |
| int size() { |
| return this.failures.size(); |
| } |
| public String toString() { |
| switch (this.kind) { |
| case UNEXPECTED_FAILURE: |
| return "unexpected failure while formatting"; |
| case NO_OUTPUT_FAILURE: |
| return "no output while formatting"; |
| case COMPILATION_ERRORS_FAILURE: |
| return "compilation errors which prevent the formatter to proceed"; |
| case FILE_NOT_FOUND_FAILURE: |
| return "no formatted output to compare with"; |
| case COMPARISON_FAILURE: |
| return "different output while comparing with previous version"; |
| default: |
| return "different output while "+this.msg; |
| } |
| } |
| |
| } |
| static FormattingFailure[] FAILURES; |
| private static final int MAX_FAILURES = Integer.parseInt(System.getProperty("maxFailures", "100")); // Max failures using string comparison |
| private static boolean ASSERT_EQUALS_STRINGS = MAX_FAILURES > 0; |
| private static String ECLIPSE_VERSION; |
| private static String ECLIPSE_MILESTONE; |
| private static String JDT_CORE_VERSION; |
| private static String PATCH_BUG, PATCH_VERSION; |
| private static String TEMP_OUTPUT; |
| private static boolean JDT_CORE_HEAD; |
| /* |
| private final static IPath[] EXPECTED_FAILURES = INPUT_DIR.getPath().indexOf("v34") < 0 |
| ? new IPath[] { |
| new Path("org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java"), |
| new Path("org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java"), |
| new Path("org/eclipse/jdt/internal/core/DeltaProcessor.java"), |
| new Path("org/eclipse/jdt/internal/core/JavaProject.java"), |
| new Path("org/eclipse/jdt/internal/core/search/indexing/IndexManager.java"), |
| new Path("org/eclipse/team/internal/ccvs/ui/AnnotateView.java"), |
| new Path("org/eclipse/team/internal/ccvs/ui/HistoryView.java"), |
| new Path("org/eclipse/team/internal/ccvs/ui/wizards/UpdateWizard.java"), |
| } |
| : new IPath[] { |
| // Eclipse |
| new Path("org/eclipse/equinox/internal/p2/director/NewDependencyExpander.java"), |
| new Path("org/eclipse/jdt/core/JavaCore.java"), |
| new Path("org/eclipse/jdt/internal/codeassist/CompletionEngine.java"), |
| new Path("org/eclipse/jdt/internal/codeassist/SelectionEngine.java"), |
| new Path("org/eclipse/jdt/internal/compiler/ast/Expression.java"), |
| new Path("org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java"), |
| new Path("org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java"), |
| new Path("org/eclipse/jdt/internal/eval/CodeSnippetSingleNameReference.java"), |
| new Path("org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java"), |
| new Path("org/eclipse/jdt/internal/compiler/batch/Main.java"), |
| new Path("org/eclipse/jdt/internal/compiler/lookup/ParameterizedMethodBinding.java"), |
| new Path("org/eclipse/jdt/internal/core/CompilationUnit.java"), |
| new Path("org/eclipse/jdt/internal/core/ExternalJavaProject.java"), |
| new Path("org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java"), |
| new Path("org/eclipse/jdt/internal/core/hierarchy/TypeHierarchy.java"), |
| new Path("org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java"), |
| new Path("org/eclipse/jdt/internal/core/search/JavaSearchScope.java"), |
| new Path("org/eclipse/jdt/internal/eval/EvaluationContext.java"), |
| new Path("org/eclipse/jdt/internal/ui/text/javadoc/JavadocContentAccess2.java"), |
| new Path("org/eclipse/jdt/internal/apt/pluggable/core/filer/IdeJavaSourceOutputStream.java"), |
| new Path("org/eclipse/team/internal/ccvs/ui/mappings/WorkspaceSubscriberContext.java"), |
| // Ganymede |
| new Path("com/ibm/icu/text/Collator.java"), |
| new Path("org/apache/lucene/analysis/ISOLatin1AccentFilter.java"), |
| }; |
| */ |
| |
| public static Test suite() { |
| return suite(new File(System.getProperty("inputDir")), buildProfileString(), new HashMap()); |
| } |
| |
| protected static Test suite(File inputDir, String profile, Map directories) { |
| |
| String name = "FormatterMassiveRegressionTests on "+inputDir.getName(); |
| if (profile != null && profile.length() > 0) { |
| name += " " + profile; |
| } |
| TestSuite suite = new Suite(name); |
| try { |
| // Init version |
| initVersion(); |
| |
| // Init profiles |
| int profiles = initProfiles(profile); |
| |
| // Init directories |
| initDirectories(inputDir, profiles, true); |
| |
| // Get files from input dir |
| FileFilter filter = new FileFilter() { |
| public boolean accept(File pathname) { |
| String path = pathname.getPath(); |
| if (pathname.isDirectory()) { |
| String dirName = path.substring(path.lastIndexOf(File.separatorChar)+1); |
| return !dirName.equals("bin"); |
| } |
| if (path.endsWith(".java")) { |
| if (FILES_FILTER_KIND > 0) { |
| String fileName = path.substring(path.lastIndexOf(File.separatorChar)+1); |
| switch (FILES_FILTER_KIND) { |
| case 1: // Equals |
| return fileName.equals(FILES_FILTER); |
| case 2: // Starts with |
| return fileName.startsWith(FILES_FILTER); |
| case 3: // Starts with + same length |
| return fileName.startsWith(FILES_FILTER) && fileName.length() == FILES_FILTER.length(); |
| case 4: // Pattern |
| return fileName.matches(FILES_FILTER); |
| } |
| } else { |
| return true; |
| } |
| } |
| return false; |
| } |
| }; |
| File[] allFiles = (File[]) directories.get(inputDir); |
| File listFile = new File(inputDir.getParentFile(), inputDir.getName()+".lst"); |
| BufferedWriter listFileWriter = null; |
| if (allFiles == null) { |
| System.out.print("Get all files from "); |
| if (LIST || !listFile.exists()) { |
| // Get the files list |
| System.out.print(inputDir+"..."); |
| allFiles = ModelTestsUtil.getAllFiles(inputDir, filter); |
| // Delete the files list |
| if (listFile.exists()) { |
| listFile.delete(); |
| } |
| // Initialize the files list writer |
| listFileWriter = new BufferedWriter(new FileWriter(listFile)); |
| listFileWriter.write(Integer.toString(allFiles.length)); |
| listFileWriter.newLine(); |
| } else { |
| System.out.print("stored list in "+listFile.getPath()+"..."); |
| BufferedReader listFileReader = new BufferedReader(new InputStreamReader(new FileInputStream(listFile.getAbsolutePath()))); |
| try { |
| // First line is the number of files |
| String line = listFileReader.readLine(); |
| int maxFiles = Integer.parseInt(line); |
| // Following lines are the files path |
| allFiles = new File[maxFiles]; |
| for (int i=0; i<maxFiles; i++) { |
| allFiles[i] = new File(inputDir, listFileReader.readLine()); |
| if (!allFiles[i].exists()) { |
| throw new IOException("Cannot find file "+allFiles[i]); |
| } |
| } |
| } |
| catch (NumberFormatException nfe) { |
| nfe.printStackTrace(); |
| return null; |
| } |
| catch (IOException ioe) { |
| ioe.printStackTrace(); |
| return null; |
| } |
| finally { |
| listFileReader.close(); |
| } |
| } |
| directories.put(inputDir, allFiles); |
| System.out.println("done"); |
| } |
| int[] maxFiles = new int[2]; |
| maxFiles[0] = allFiles.length; |
| maxFiles[1] = (int) (Math.log(maxFiles[0])/Math.log(10)); |
| MAX_FILES.put(inputDir, maxFiles); |
| |
| // Add tests to clean the output directory and rebuild the references |
| // if (CLEAN) { |
| // suite.addTest(new FormatterMassiveRegressionTests(profiles)); |
| // } |
| |
| // Add one test per found file |
| try { |
| final int inputDirPathLength = inputDir.getPath().length()+1; |
| for (int i=0; i<maxFiles[0]; i++) { |
| if (CLEAN) { |
| suite.addTest(new FormatterMassiveRegressionTests(inputDir, allFiles[i], i, profiles, false/*do not compare while cleaning*/)); |
| } else { |
| suite.addTest(new FormatterMassiveRegressionTests(inputDir, allFiles[i], i, profiles, CAN_COMPARE)); |
| } |
| if (listFileWriter != null) { |
| listFileWriter.write(allFiles[i].getPath().substring(inputDirPathLength)); |
| listFileWriter.newLine(); |
| } |
| } |
| } |
| finally { |
| if (listFileWriter != null) { |
| listFileWriter.close(); |
| } |
| } |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| return suite; |
| } |
| |
| private static String buildProfileString() { |
| boolean hasProfile = NO_COMMENTS || PRESERVED_LINES != -1; |
| if (JOIN_LINES != null) { |
| if (JOIN_LINES.equals("never") || |
| JOIN_LINES.equals("only_comments") || |
| JOIN_LINES.equals("only_code")) { |
| hasProfile = true; |
| } |
| } |
| if (BRACES != null) { |
| if (BRACES.equals(DefaultCodeFormatterConstants.NEXT_LINE) || |
| BRACES.equals(DefaultCodeFormatterConstants.NEXT_LINE_ON_WRAP) || |
| BRACES.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED)) { |
| hasProfile = true; |
| } |
| } |
| String builtProfile = null; |
| if (hasProfile) { |
| StringBuffer buffer = new StringBuffer(); |
| String separator = ""; |
| if (JOIN_LINES != null) { |
| buffer.append("join_lines="+JOIN_LINES); |
| separator = ","; |
| } |
| if (NO_COMMENTS) { |
| buffer.append(separator+"no_comments=true"); |
| separator = ","; |
| } |
| if (BRACES != null) { |
| buffer.append(separator+"braces="+BRACES); |
| separator = ","; |
| } |
| if (PRESERVED_LINES != -1) { |
| buffer.append(separator+"preserved_lines="+PRESERVED_LINES); |
| separator = ","; |
| } |
| builtProfile = buffer.toString(); |
| } |
| |
| // Return built profile string |
| return builtProfile; |
| } |
| |
| private static int initProfiles(String profile) { |
| if (profile == null || profile.length() == 0) return 0; |
| StringTokenizer tokenizer = new StringTokenizer(profile, ","); |
| int profiles = 0; |
| while (tokenizer.hasMoreTokens()) { |
| String token = tokenizer.nextToken(); |
| int idx = token.indexOf('='); |
| if (idx <= 0) { |
| System.err.println("'"+profile+"' is not a valid profile!!!"); |
| return 0; |
| } |
| String profileName = token.substring(0, idx); |
| if (profileName.equals("join_lines")) { |
| String joinLines = token.substring(idx+1); |
| if (joinLines.equals("never")) { |
| profiles += PROFILE_NEVER_JOIN_LINES; |
| } else if (joinLines.equals("only_comments")) { |
| profiles += PROFILE_JOIN_LINES_ONLY_COMMENTS; |
| } else if (joinLines.equals("only_code")) { |
| profiles += PROFILE_JOIN_LINES_ONLY_CODE; |
| } |
| } else if (profileName.equals("no_comments")) { |
| String noComments = token.substring(idx+1); |
| if (noComments.equals(DefaultCodeFormatterConstants.TRUE)) { |
| profiles |= PROFILE_NO_COMMENTS; |
| } |
| } else if (profileName.equals("braces")) { |
| String braces = token.substring(idx+1); |
| if (braces.equals(DefaultCodeFormatterConstants.NEXT_LINE)) { |
| profiles += PROFILE_BRACES_NEXT_LINE; |
| } else if (braces.equals(DefaultCodeFormatterConstants.NEXT_LINE_ON_WRAP)) { |
| profiles += PROFILE_BRACES_NEXT_LINE_ON_WRAP; |
| } else if (braces.equals(DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED)) { |
| profiles += PROFILE_BRACES_NEXT_LINE_SHIFTED; |
| } |
| } else if (profileName.equals("preserved_lines")) { |
| try { |
| String lines = token.substring(idx+1); |
| int value = Integer.parseInt(lines); |
| if (value >= 0 && value < 8) { |
| profiles += value << 5; |
| } |
| } |
| catch (NumberFormatException nfe) { |
| // skip |
| } |
| } |
| } |
| return profiles; |
| } |
| |
| private static void initDirectories(File inputDir, int profiles, boolean verify) { |
| |
| // Verify input directory |
| if (!inputDir.exists() && !inputDir.isDirectory()) { |
| System.err.println(inputDir+" does not exist or is not a directory!"); |
| System.exit(1); |
| } |
| |
| // Get output dir and clean it if specified |
| String dir = System.getProperty("outputDir"); //$NON-NLS-1$ |
| if (dir != null) { |
| StringTokenizer tokenizer = new StringTokenizer(dir, ","); |
| String outputDir = tokenizer.nextToken(); |
| while (tokenizer.hasMoreTokens()) { |
| String token = tokenizer.nextToken(); |
| if (token.equals("clean")) { |
| CLEAN = true; |
| } else if (token.equals("maintenance")) { |
| MAINTENANCE = true; |
| } else if (token.equals("list")) { |
| LIST = true; |
| } else { |
| TEMP_OUTPUT = token; |
| } |
| } |
| setOutputDir(inputDir, outputDir, profiles); |
| if (CLEAN) { |
| if ((PATCH_BUG != null || JDT_CORE_HEAD) && TEMP_OUTPUT == null) { |
| System.err.println("Reference can only be updated using a version (i.e. with a closed buildnotes_jdt-core.html)!"); |
| System.exit(1); |
| } |
| return; |
| } else if (!OUTPUT_DIR.exists()) { |
| System.err.println(" WARNING: The output directory "+OUTPUT_DIR+" does not exist..."); |
| System.err.println(" => NO comparison could be done!"); |
| CAN_COMPARE = false; |
| } |
| try { |
| Thread.sleep(1000); |
| } catch (InterruptedException e) { |
| // skip |
| } |
| } |
| |
| // Get log dir |
| try { |
| setLogDir(inputDir, profiles, verify); |
| } catch (CoreException e) { |
| e.printStackTrace(); |
| } |
| |
| // Get write dir |
| String wdir = System.getProperty("writeDir"); //$NON-NLS-1$ |
| if (wdir != null) { |
| WRITE_DIR = new File(wdir); |
| if (WRITE_DIR.exists()) { |
| Util.delete(WRITE_DIR); |
| } |
| WRITE_DIR.mkdirs(); |
| } |
| } |
| |
| private static void setLogDir(File inputDir, int profiles, boolean verify) throws CoreException { |
| |
| // Compute log dir |
| File rootLogDir = new File(System.getProperty("logDir")); |
| if (!rootLogDir.exists()) { |
| if (!rootLogDir.mkdirs()) { |
| System.err.println("Cannot create specified log directory: "+rootLogDir+"!!!"); |
| return; |
| } |
| } |
| |
| // Compute log sub-directories depending on version |
| rootLogDir = new File(rootLogDir, ECLIPSE_VERSION); |
| String subRootDir; |
| if (PATCH_BUG != null) { |
| rootLogDir = new File(rootLogDir, "tests"); |
| rootLogDir = new File(rootLogDir, PATCH_BUG); |
| subRootDir = PATCH_VERSION; |
| } else if (JDT_CORE_HEAD) { |
| subRootDir = "HEAD"; |
| } else { |
| rootLogDir = new File(rootLogDir, ECLIPSE_MILESTONE); |
| subRootDir = JDT_CORE_VERSION; |
| } |
| |
| // Compute log sub-directories depending on profiles |
| List subDirs = new ArrayList(); |
| if (profiles > 0) { |
| subDirs.add("profiles"); |
| setProfilesDir(profiles, subDirs); |
| } |
| |
| if (FILES_FILTER_KIND > 0) { |
| subDirs.add("filter"); |
| subDirs.add(FILES_FILTER.replace('?', '_').replace('*', '%')); |
| } |
| |
| // Create log stream |
| File logDir = createDir(new File (rootLogDir, subRootDir), subDirs); |
| String filePrefix = inputDir.getName().replaceAll("\\.", ""); |
| String logFileName = filePrefix+".txt"; |
| LOG_FILE = new File(logDir, logFileName); |
| if (verify && LOG_FILE.exists()) { |
| File saveDir = new File(new File(rootLogDir, "save"), subRootDir); |
| saveDir.mkdirs(); |
| int i=0; |
| while (true) { |
| String dirN = Integer.toString(i); |
| if (i<10) dirN = "0" + dirN; |
| saveDir = new File(saveDir, dirN); |
| logDir = createDir(saveDir, subDirs); |
| File renamedFile = new File(logDir, logFileName); |
| if (LOG_FILE.renameTo(renamedFile)) break; |
| i++; |
| } |
| } |
| // LOG_RESOURCE = folder.getFile(logFileName); |
| try { |
| LOG_STREAM = new PrintStream(new BufferedOutputStream(new FileOutputStream(LOG_FILE))); |
| LOG_STREAM.flush(); |
| } |
| catch (FileNotFoundException fnfe) { |
| System.err.println("Can't create log file"+LOG_FILE); //$NON-NLS-1$ |
| } |
| // if (LOG_RESOURCE.exists()) { |
| // Util.delete(LOG_RESOURCE); |
| // } |
| // LOG_BUFFER = new StringBuffer(); |
| } |
| |
| private static File createDir(File rootDir, List subDirs) { |
| File dir = rootDir; |
| for (int i=0, s=subDirs.size(); i<s; i++) { |
| dir = new File (dir, (String) subDirs.get(i)); |
| } |
| dir.mkdirs(); |
| return dir; |
| } |
| |
| private static File setProfilesDir(int profiles, File dir) { |
| List subDirs = new ArrayList(); |
| setProfilesDir(profiles, subDirs); |
| return createDir(dir, subDirs); |
| } |
| |
| private static void setProfilesDir(int profiles, List subDirs) { |
| String joinLines = null; |
| switch (profiles & PROFILE_JOIN_LINES_MASK) { |
| case PROFILE_NEVER_JOIN_LINES: |
| joinLines = "never"; |
| break; |
| case PROFILE_JOIN_LINES_ONLY_COMMENTS: |
| joinLines = "only_comments"; |
| break; |
| case PROFILE_JOIN_LINES_ONLY_CODE: |
| joinLines = "only_code"; |
| break; |
| } |
| if (joinLines != null) { |
| subDirs.add("join_lines"); |
| subDirs.add(joinLines); |
| } |
| if ((profiles & PROFILE_NO_COMMENTS) != 0) { |
| subDirs.add("no_comments"); |
| } |
| String braces = null; |
| switch (profiles & PROFILE_BRACES_MASK) { |
| case PROFILE_BRACES_NEXT_LINE: |
| braces = DefaultCodeFormatterConstants.NEXT_LINE; |
| break; |
| case PROFILE_BRACES_NEXT_LINE_ON_WRAP: |
| braces = DefaultCodeFormatterConstants.NEXT_LINE_ON_WRAP; |
| break; |
| case PROFILE_BRACES_NEXT_LINE_SHIFTED: |
| braces = DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED; |
| break; |
| } |
| if (braces != null) { |
| subDirs.add("braces"); |
| subDirs.add(braces); |
| } |
| if ((profiles & PROFILE_PRESERVED_LINES_MASK) != 0) { |
| int lines = (profiles & PROFILE_PRESERVED_LINES_MASK) >> 5; |
| subDirs.add("preserved_lines"); |
| subDirs.add(Integer.toString(lines)); |
| } |
| } |
| |
| private static void appendProfiles(int profiles, StringBuffer buffer) { |
| String joinLines = null; |
| boolean first = true; |
| switch (profiles & PROFILE_JOIN_LINES_MASK) { |
| case PROFILE_NEVER_JOIN_LINES: |
| joinLines = "never"; |
| break; |
| case PROFILE_JOIN_LINES_ONLY_COMMENTS: |
| joinLines = "only_comments"; |
| break; |
| case PROFILE_JOIN_LINES_ONLY_CODE: |
| joinLines = "only_code"; |
| break; |
| } |
| if (joinLines != null) { |
| buffer.append("join_lines="); |
| buffer.append(joinLines); |
| first = false; |
| } |
| if ((profiles & PROFILE_NO_COMMENTS) != 0) { |
| if (!first) buffer.append(','); |
| buffer.append("no_comments"); |
| first = false; |
| } |
| String braces = null; |
| switch (profiles & PROFILE_BRACES_MASK) { |
| case PROFILE_BRACES_NEXT_LINE: |
| braces = DefaultCodeFormatterConstants.NEXT_LINE; |
| break; |
| case PROFILE_BRACES_NEXT_LINE_ON_WRAP: |
| braces = DefaultCodeFormatterConstants.NEXT_LINE_ON_WRAP; |
| break; |
| case PROFILE_BRACES_NEXT_LINE_SHIFTED: |
| braces = DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED; |
| break; |
| } |
| if (braces != null) { |
| if (!first) buffer.append(','); |
| buffer.append("braces="); |
| buffer.append(braces); |
| first = false; |
| } |
| if ((profiles & PROFILE_PRESERVED_LINES_MASK) != 0) { |
| int lines = (profiles & PROFILE_PRESERVED_LINES_MASK) >> 5; |
| if (!first) buffer.append(','); |
| buffer.append("preserved_lines="); |
| buffer.append(lines); |
| first = false; |
| } |
| if (first) { |
| buffer.append("none!"); |
| } |
| } |
| |
| private static void setOutputDir(File inputDir, String dir, int profiles) { |
| |
| // Find the root of the output directory |
| OUTPUT_DIR = new File(dir); |
| if (OUTPUT_DIR.getName().equals(inputDir.getName())) { |
| OUTPUT_DIR = OUTPUT_DIR.getParentFile(); |
| } |
| if (OUTPUT_DIR.getName().equals(ECLIPSE_VERSION)) { |
| OUTPUT_DIR = OUTPUT_DIR.getParentFile(); |
| } |
| |
| // Add the temporary output if any |
| if (TEMP_OUTPUT != null) { |
| StringTokenizer tokenizer = new StringTokenizer(TEMP_OUTPUT, "/"); |
| while (tokenizer.hasMoreTokens()) { |
| OUTPUT_DIR = new File(OUTPUT_DIR, tokenizer.nextToken()); |
| } |
| } |
| |
| // Compute output sub-directories depending on profiles |
| if (profiles > 0) { |
| OUTPUT_DIR = new File(OUTPUT_DIR, "profiles"); |
| OUTPUT_DIR = setProfilesDir(profiles, OUTPUT_DIR); |
| } |
| |
| // Compute the final output dir |
| File parent = new File(OUTPUT_DIR, ECLIPSE_VERSION); |
| if (MAINTENANCE) { |
| try { |
| int version = Integer.parseInt(ECLIPSE_VERSION.substring(1)); |
| File maintenance = new File(OUTPUT_DIR, "v"+(version-1)); |
| if (maintenance.exists()) { |
| parent = maintenance; |
| } |
| } |
| catch (NumberFormatException nfe) { |
| // skip |
| } |
| } |
| OUTPUT_DIR = new File(parent, inputDir.getName()); |
| } |
| |
| private static void initFailures() { |
| FAILURES = new FormattingFailure[REFORMATTING_WHITESPACES_FAILURE+1]; |
| for (int i=UNEXPECTED_FAILURE; i<=COMPARISON_FAILURE; i++) { |
| FAILURES[i] = new FormattingFailure(i); |
| } |
| FAILURES[REFORMATTING_FAILURE] = new FormattingFailure(REFORMATTING_FAILURE, "reformatting twice"); |
| FAILURES[REFORMATTING_LEADING_FAILURE] = new FormattingFailure(REFORMATTING_LEADING_FAILURE, "reformatting twice but only by leading whitespaces"); |
| FAILURES[REFORMATTING_WHITESPACES_FAILURE] = new FormattingFailure(REFORMATTING_WHITESPACES_FAILURE, "reformatting twice but only by whitespaces"); |
| FAILURES[REFORMATTING_EXPECTED_FAILURE] = new FormattingFailure(REFORMATTING_EXPECTED_FAILURE, "reformatting twice but was expected"); |
| } |
| |
| /* |
| * Read JDT/Core build notes file to see what version is currently running. |
| */ |
| private static void initVersion() { |
| if (JDT_CORE_VERSION == null) { |
| BufferedReader buildnotesReader; |
| try { |
| URL platformURL = Platform.getBundle("org.eclipse.jdt.core").getEntry("/"); |
| String path = new File(FileLocator.toFileURL(platformURL).getFile(), "buildnotes_jdt-core.html").getAbsolutePath(); |
| buildnotesReader = new BufferedReader(new InputStreamReader(new FileInputStream(path))); |
| } catch (IOException ioe) { |
| ioe.printStackTrace(); |
| return; |
| } |
| String line; |
| JDT_CORE_HEAD = true; |
| try { |
| while ((line = buildnotesReader.readLine()) != null) { |
| if (line.startsWith("<a name=\"")) { |
| boolean first = JDT_CORE_VERSION == null; |
| JDT_CORE_VERSION = line.substring(line.indexOf('"')+1, line.lastIndexOf('"')); |
| if (!first) break; |
| } else if (line.startsWith("Eclipse SDK ")) { |
| StringTokenizer tokenizer = new StringTokenizer(line); |
| tokenizer.nextToken(); // 'Eclipse' |
| tokenizer.nextToken(); // 'SDK' |
| String milestone = tokenizer.nextToken(); |
| ECLIPSE_VERSION = "v"+milestone.charAt(0)+milestone.charAt(2); |
| ECLIPSE_MILESTONE = milestone.substring(3); |
| tokenizer.nextToken(); // '-' |
| JDT_CORE_HEAD = tokenizer.nextToken().equals("%date%"); |
| } else if (line.startsWith("<h2>What's new")) { |
| line = buildnotesReader.readLine(); |
| if (line.startsWith("Patch")) { |
| StringTokenizer tokenizer = new StringTokenizer(line); |
| tokenizer.nextToken(); // 'Patch' |
| PATCH_VERSION = tokenizer.nextToken(); |
| while (tokenizer.hasMoreTokens()) { |
| PATCH_BUG = tokenizer.nextToken(); |
| } |
| try { |
| Integer.parseInt(PATCH_BUG); |
| } |
| catch (NumberFormatException nfe) { |
| // try to split |
| StringTokenizer bugTokenizer = new StringTokenizer(PATCH_BUG, "+"); |
| try { |
| while (bugTokenizer.hasMoreTokens()) { |
| Integer.parseInt(bugTokenizer.nextToken()); |
| } |
| } |
| catch (NumberFormatException nfe2) { |
| System.err.println("Invalid patch bug number noticed in JDT/Core buildnotes: "+PATCH_BUG); |
| } |
| } |
| } |
| if (!JDT_CORE_HEAD) break; |
| } |
| } |
| } catch (Exception e) { |
| try { |
| buildnotesReader.close(); |
| } catch (IOException ioe) { |
| ioe.printStackTrace(); |
| } |
| } |
| } |
| } |
| |
| /* |
| * Constructor used to clean the output directory. |
| * |
| public FormatterMassiveRegressionTests(int profiles) { |
| super("testDeleteOutputDir"); |
| this.canCompare = false; |
| this.file = null; |
| this.inputDir = OUTPUT_DIR; |
| this.testIndex = -1; |
| this.profiles = profiles; |
| this.path = new Path(OUTPUT_DIR.getPath()); |
| } |
| |
| /* |
| * Constructor used to dump references in the output directory. |
| * |
| public FormatterMassiveRegressionTests(File[] files) { |
| super("testMakeReferences"); |
| assertNotNull("This test needs some files to proceed!", files); |
| this.canCompare = false; |
| this.file = null; |
| this.inputFiles = files; |
| this.testIndex = -1; |
| this.path = new Path(OUTPUT_DIR.getPath()); |
| } |
| |
| /* |
| * Contructor used to compare outputs. |
| */ |
| public FormatterMassiveRegressionTests(File inputDir, File file, int index, int profiles, boolean compare) { |
| super(CLEAN ? "testReference" : "testCompare"); |
| this.canCompare = compare; |
| this.file = file; |
| this.inputDir = inputDir; |
| this.testIndex = index; |
| this.profiles = profiles; |
| this.path = new Path(file.getPath().substring(inputDir.getPath().length()+1)); |
| } |
| |
| /* (non-Javadoc) |
| * @see junit.framework.TestCase#getName() |
| */ |
| public String getName() { |
| StringBuffer name = new StringBuffer(super.getName()); |
| if (this.testIndex >= 0) { |
| int n = this.testIndex == 0 ? 0 : (int) (Math.log(this.testIndex)/Math.log(10)); |
| int max = ((int[])MAX_FILES.get(this.inputDir))[1]; |
| for (int i=n; i<max; i++) { |
| name.append('0'); |
| } |
| name.append(this.testIndex); |
| } |
| if (this.profiles > 0) { |
| name.append('_'); |
| name.append(this.profiles); |
| } |
| name.append(" - "); |
| name.append(this.path); |
| return name.toString(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.core.tests.formatter.FormatterRegressionTests#setUpSuite() |
| */ |
| public void setUp() throws Exception { |
| super.setUp(); |
| |
| // Setup preferences |
| this.preferences = DefaultCodeFormatterOptions.getEclipseDefaultSettings(); |
| |
| // Setup no comments profile |
| if ((this.profiles & PROFILE_NO_COMMENTS) != 0) { |
| this.preferences.comment_format_javadoc_comment = false; |
| this.preferences.comment_format_block_comment = false; |
| this.preferences.comment_format_line_comment = false; |
| } |
| |
| // Setup join lines profile |
| String joinLines = null; |
| switch (this.profiles & PROFILE_JOIN_LINES_MASK) { |
| case PROFILE_NEVER_JOIN_LINES: |
| joinLines = "never"; |
| break; |
| case PROFILE_JOIN_LINES_ONLY_COMMENTS: |
| joinLines = "only_comments"; |
| break; |
| case PROFILE_JOIN_LINES_ONLY_CODE: |
| joinLines = "only_code"; |
| break; |
| } |
| if (joinLines != null) { |
| if (!joinLines.equals("only_comments")) { |
| this.preferences.join_lines_in_comments = false; |
| } |
| if (!joinLines.equals("only_code")) { |
| this.preferences.join_wrapped_lines = false; |
| } |
| } |
| |
| // Setup braces profile |
| String braces = null; |
| switch (this.profiles & PROFILE_BRACES_MASK) { |
| case PROFILE_BRACES_NEXT_LINE: |
| braces = DefaultCodeFormatterConstants.NEXT_LINE; |
| break; |
| case PROFILE_BRACES_NEXT_LINE_ON_WRAP: |
| braces = DefaultCodeFormatterConstants.NEXT_LINE_ON_WRAP; |
| break; |
| case PROFILE_BRACES_NEXT_LINE_SHIFTED: |
| braces = DefaultCodeFormatterConstants.NEXT_LINE_SHIFTED; |
| break; |
| } |
| if (braces != null) { |
| this.preferences.brace_position_for_annotation_type_declaration = braces; |
| this.preferences.brace_position_for_anonymous_type_declaration = braces; |
| this.preferences.brace_position_for_array_initializer = braces; |
| this.preferences.brace_position_for_block = braces; |
| this.preferences.brace_position_for_block_in_case = braces; |
| this.preferences.brace_position_for_constructor_declaration = braces; |
| this.preferences.brace_position_for_enum_constant = braces; |
| this.preferences.brace_position_for_enum_declaration = braces; |
| this.preferences.brace_position_for_method_declaration = braces; |
| this.preferences.brace_position_for_switch = braces; |
| this.preferences.brace_position_for_type_declaration = braces; |
| } |
| |
| // Setup preserved lines profile |
| if ((this.profiles & PROFILE_PRESERVED_LINES_MASK) != 0) { |
| int lines = (this.profiles & PROFILE_PRESERVED_LINES_MASK) >> 5; |
| this.preferences.number_of_empty_lines_to_preserve = lines; |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.core.tests.formatter.FormatterRegressionTests#setUpSuite() |
| */ |
| public void setUpSuite() throws Exception { |
| |
| // Init directories |
| initDirectories(this.inputDir, this.profiles, false); |
| |
| // Delete output dir before compute reference |
| if (CLEAN) { |
| System.out.print("Deleting all files from "+OUTPUT_DIR+"..."); |
| Util.delete(OUTPUT_DIR); |
| System.out.println("done"); |
| } |
| // Init failure |
| else if (this.canCompare) { |
| initFailures(); |
| } |
| |
| // Dump the version |
| if (CLEAN) { |
| File versionFile = new Path(OUTPUT_DIR.getPath()).append("version.txt").toFile(); |
| OUTPUT_DIR.mkdirs(); |
| String version = JDT_CORE_VERSION; |
| if (TEMP_OUTPUT != null) { |
| version += " + " + TEMP_OUTPUT; |
| if (PATCH_BUG != null) { |
| version += " " + PATCH_VERSION + " of " + PATCH_BUG; |
| } |
| } |
| Util.writeToFile(version, versionFile.getAbsolutePath()); |
| } |
| |
| // Init time measuring |
| TIME_MEASURES = new TimeMeasuring(); |
| |
| // Print |
| print(); |
| } |
| |
| private void print() { |
| |
| StringBuffer buffer = new StringBuffer(); |
| |
| // Log version info |
| buffer.append("Version : "); |
| if (PATCH_BUG != null) { |
| buffer.append("'Patch "); |
| buffer.append(PATCH_VERSION); |
| buffer.append(" for bug "); |
| buffer.append(PATCH_BUG); |
| buffer.append("' applied on "); |
| } |
| if (JDT_CORE_HEAD) { |
| buffer.append("HEAD on top of "); |
| } |
| buffer.append(JDT_CORE_VERSION); |
| buffer.append(LINE_SEPARATOR); |
| |
| // Profiles |
| buffer.append("Profiles : "); |
| appendProfiles(this.profiles, buffer); |
| buffer.append(LINE_SEPARATOR); |
| |
| // Log date of test |
| long start = System.currentTimeMillis(); |
| SimpleDateFormat format = new SimpleDateFormat(); |
| Date now = new Date(start); |
| buffer.append("Test date : "); |
| buffer.append(format.format(now)); |
| buffer.append(LINE_SEPARATOR); |
| |
| // Input dir |
| buffer.append("Input dir : "); |
| buffer.append(this.inputDir); |
| buffer.append(LINE_SEPARATOR); |
| |
| // Files |
| buffer.append(" "); |
| int[] maxFiles = (int[]) MAX_FILES.get(this.inputDir); |
| buffer.append(maxFiles[0]); |
| buffer.append(" java files to format..."); |
| |
| // Flush to console to show startup |
| String firstBuffer = buffer.toString(); |
| System.out.println(firstBuffer); |
| |
| // Output dir |
| buffer.setLength(0); |
| buffer.append("Output dir: "); |
| buffer.append(OUTPUT_DIR); |
| buffer.append(LINE_SEPARATOR); |
| if (CLEAN) { |
| buffer.append(" CLEANED"); |
| buffer.append(LINE_SEPARATOR); |
| } |
| |
| // Log dir |
| if (LOG_FILE != null) { |
| buffer.append("Log file : "); |
| buffer.append(LOG_FILE); |
| buffer.append(LINE_SEPARATOR); |
| } |
| |
| // Write dir |
| if (WRITE_DIR != null) { |
| buffer.append("Write dir : "); |
| buffer.append(WRITE_DIR); |
| buffer.append(LINE_SEPARATOR); |
| } |
| |
| // Comparison |
| if (CAN_COMPARE) { |
| if (!CLEAN) { |
| buffer.append("Compare vs: "); |
| File versionFile = new File(OUTPUT_DIR, "version.txt"); |
| if (versionFile.exists()) { |
| String fileContent = Util.fileContent(versionFile.getAbsolutePath()); |
| if (TEMP_OUTPUT != null) { |
| buffer.append(TEMP_OUTPUT); |
| buffer.append(" on top of "); |
| } |
| buffer.append(fileContent); |
| } else { |
| buffer.append("???"); |
| } |
| } |
| } else { |
| buffer.append("Compare vs: none"); |
| } |
| buffer.append(LINE_SEPARATOR); |
| |
| // Write logs |
| System.out.println(buffer.toString()); |
| if (LOG_STREAM != null) { |
| LOG_STREAM.println(firstBuffer); |
| LOG_STREAM.println(buffer.toString()); |
| LOG_STREAM.flush(); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.core.tests.formatter.FormatterRegressionTests#tearDown() |
| */ |
| public void tearDown() throws Exception { |
| // verify whether the max failures has been reached or not |
| if (ASSERT_EQUALS_STRINGS && FAILURES != null) { |
| ASSERT_EQUALS_STRINGS = FAILURES[COMPARISON_FAILURE].size() < MAX_FAILURES; |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.core.tests.formatter.FormatterRegressionTests#tearDownSuite() |
| */ |
| public void tearDownSuite() throws Exception { |
| |
| // Display time measures |
| StringBuffer buffer1 = new StringBuffer(); |
| if (CLEAN) { |
| // buffer1.append(" cannot be done as the directory was cleaned!"); |
| // buffer1.append(LINE_SEPARATOR); |
| return; |
| } else { |
| buffer1.append("Time measures:"); |
| buffer1.append(LINE_SEPARATOR); |
| for (int i=0; i<FORMAT_REPEAT; i++) { |
| buffer1.append(" - "+counterToString(i+1)).append(" format:").append(LINE_SEPARATOR); |
| buffer1.append(" + elapsed = "+timeString(TIME_MEASURES.formatting[i])).append(LINE_SEPARATOR); |
| buffer1.append(" + occurrences = "+TIME_MEASURES.occurences[i]).append(LINE_SEPARATOR); |
| buffer1.append(" + null output = "+TIME_MEASURES.null_output[i]).append(LINE_SEPARATOR); |
| } |
| } |
| buffer1.append(LINE_SEPARATOR); |
| |
| // Display stored failures |
| int max = FAILURES.length; |
| for (int i=0; i<max; i++) { |
| List failures = FAILURES[i].failures; |
| int size = failures.size(); |
| if (size > 0) { |
| buffer1.append(size); |
| buffer1.append(" file"); |
| if (size == 1) { |
| buffer1.append(" has "); |
| } else { |
| buffer1.append("s have "); |
| } |
| buffer1.append(FAILURES[i]); |
| buffer1.append('!'); |
| buffer1.append(LINE_SEPARATOR); |
| } |
| } |
| buffer1.append(LINE_SEPARATOR); |
| StringBuffer buffer2 = new StringBuffer(LINE_SEPARATOR); |
| for (int i=0; i<max; i++) { |
| List failures = FAILURES[i].failures; |
| int size = failures.size(); |
| if (size > 0) { |
| buffer2.append("List of file(s) with "); |
| buffer2.append(FAILURES[i]); |
| buffer2.append(':'); |
| buffer2.append(LINE_SEPARATOR); |
| for (int j=0; j<size; j++) { |
| buffer2.append(" - "); |
| buffer2.append(failures.get(j)); |
| buffer2.append(LINE_SEPARATOR); |
| } |
| } |
| } |
| |
| // Log failures |
| System.out.println(buffer1.toString()); |
| if (LOG_STREAM == null) { |
| System.out.println(buffer2.toString()); |
| } else { |
| LOG_STREAM.print(buffer1.toString()); |
| LOG_STREAM.print(buffer2.toString()); |
| LOG_STREAM.close(); |
| } |
| // LOG_BUFFER.append(buffer1.toString()); |
| // LOG_BUFFER.append(buffer2.toString()); |
| // InputStream stream= new InputStream() { |
| // private Reader reader= new StringReader(LOG_BUFFER.toString()); |
| // public int read() throws IOException { |
| // return this.reader.read(); |
| // } |
| // }; |
| // if (LOG_RESOURCE.exists()) { |
| // LOG_RESOURCE.setContents( |
| // stream, |
| // IResource.FORCE | IResource.KEEP_HISTORY, |
| // null); |
| // } else { |
| // LOG_RESOURCE.create(stream, IResource.FORCE, null); |
| // } |
| } |
| |
| /* |
| * Asserts that the given actual source (usually coming from a file content) is equal to the expected one. |
| * Note that 'expected' is assumed to have the '\n' line separator. |
| * The line separators in 'actual' are converted to '\n' before the comparison. |
| */ |
| protected void assertSourceEquals(String message, String expected, String actual) { |
| if (expected == null) { |
| assertNull(message, actual); |
| return; |
| } |
| if (actual == null) { |
| assertEquals(message, expected, null); |
| return; |
| } |
| expected = Util.convertToIndependantLineDelimiter(expected); |
| actual = Util.convertToIndependantLineDelimiter(actual); |
| if (ASSERT_EQUALS_STRINGS) { |
| assertEquals(message, expected, actual); |
| } else { |
| assertTrue(message, actual.equals(expected)); |
| } |
| } |
| |
| DefaultCodeFormatter codeFormatter() { |
| DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(this.preferences, getDefaultCompilerOptions()); |
| return codeFormatter; |
| } |
| |
| void compareFormattedSource() throws IOException, Exception { |
| String source = new String(org.eclipse.jdt.internal.compiler.util.Util.getFileCharContent(this.file, null)); |
| String actualResult = null; |
| try { |
| // Format the source |
| actualResult = runFormatter(codeFormatter(), source, CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS, 0, 0, source.length(), null, true); |
| |
| // Look for output to compare with |
| File outputFile = new Path(OUTPUT_DIR.getPath()).append(this.path).toFile(); |
| if (actualResult != null && FAILURES != null && this.canCompare) { |
| try { |
| String expectedResult = new String(org.eclipse.jdt.internal.compiler.util.Util.getFileCharContent(outputFile, null)); |
| assertSourceEquals("Unexpected format output!", expectedResult, actualResult); |
| } |
| catch (FileNotFoundException fnfe) { |
| this.failureIndex = FILE_NOT_FOUND_FAILURE; |
| FAILURES[FILE_NOT_FOUND_FAILURE].failures.add(this.path); |
| return; |
| } |
| catch (ComparisonFailure cf) { |
| this.failureIndex = COMPARISON_FAILURE; |
| throw cf; |
| } |
| catch (AssertionFailedError afe) { |
| this.failureIndex = COMPARISON_FAILURE; |
| throw afe; |
| } |
| } |
| } |
| catch (Exception e) { |
| // System.err.println(e.getMessage()+" occurred in "+getName()); |
| throw e; |
| } |
| finally { |
| // Write file |
| if (actualResult != null) { |
| if (WRITE_DIR != null) { |
| File writtenFile = new Path(WRITE_DIR.getPath()).append(this.path).toFile(); |
| writtenFile.getParentFile().mkdirs(); |
| Util.writeToFile(actualResult, writtenFile.getAbsolutePath()); |
| } |
| } |
| } |
| } |
| |
| private String counterToString(int count) { |
| int reminder = count%10; |
| StringBuffer buffer = new StringBuffer(); |
| buffer.append(count); |
| switch (reminder) { |
| case 1: |
| buffer.append("st"); |
| break; |
| case 2: |
| buffer.append("nd"); |
| break; |
| case 3: |
| buffer.append("rd"); |
| break; |
| default: |
| buffer.append("th"); |
| break; |
| } |
| return buffer.toString(); |
| } |
| |
| private Map getDefaultCompilerOptions() { |
| Map optionsMap = new HashMap(30); |
| optionsMap.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.DO_NOT_GENERATE); |
| optionsMap.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.DO_NOT_GENERATE); |
| optionsMap.put(CompilerOptions.OPTION_SourceFileAttribute, CompilerOptions.DO_NOT_GENERATE); |
| optionsMap.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.PRESERVE); |
| optionsMap.put(CompilerOptions.OPTION_DocCommentSupport, CompilerOptions.DISABLED); |
| optionsMap.put(CompilerOptions.OPTION_ReportMethodWithConstructorName, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportOverridingPackageDefaultMethod, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportOverridingMethodWithoutSuperInvocation, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.DISABLED); |
| optionsMap.put(CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.DISABLED); |
| optionsMap.put(CompilerOptions.OPTION_ReportHiddenCatchBlock, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportUnusedLocal, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportUnusedParameter, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportUnusedImport, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportSyntheticAccessEmulation, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportNoEffectAssignment, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportNonExternalizedStringLiteral, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportNoImplicitStringConversion, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportNonStaticAccessToStatic, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportIndirectStaticAccess, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportIncompatibleNonInheritedInterfaceMethod, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportLocalVariableHiding, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportFieldHiding, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportPossibleAccidentalBooleanAssignment, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportEmptyStatement, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportAssertIdentifier, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportEnumIdentifier, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportUndocumentedEmptyBlock, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportInvalidJavadoc, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportInvalidJavadocTagsVisibility, CompilerOptions.PUBLIC); |
| optionsMap.put(CompilerOptions.OPTION_ReportInvalidJavadocTags, CompilerOptions.DISABLED); |
| optionsMap.put(CompilerOptions.OPTION_ReportMissingJavadocTagDescription, CompilerOptions.RETURN_TAG); |
| optionsMap.put(CompilerOptions.OPTION_ReportInvalidJavadocTagsDeprecatedRef, CompilerOptions.DISABLED); |
| optionsMap.put(CompilerOptions.OPTION_ReportInvalidJavadocTagsNotVisibleRef, CompilerOptions.DISABLED); |
| optionsMap.put(CompilerOptions.OPTION_ReportMissingJavadocTags, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportMissingJavadocTagsVisibility, CompilerOptions.PUBLIC); |
| optionsMap.put(CompilerOptions.OPTION_ReportMissingJavadocTagsOverriding, CompilerOptions.DISABLED); |
| optionsMap.put(CompilerOptions.OPTION_ReportMissingJavadocComments, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportMissingJavadocCommentsVisibility, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportMissingJavadocCommentsOverriding, CompilerOptions.DISABLED); |
| optionsMap.put(CompilerOptions.OPTION_ReportFinallyBlockNotCompletingNormally, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportUnusedDeclaredThrownException, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_ReportUnusedDeclaredThrownExceptionWhenOverriding, CompilerOptions.DISABLED); |
| optionsMap.put(CompilerOptions.OPTION_ReportUnqualifiedFieldAccess, CompilerOptions.IGNORE); |
| optionsMap.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6); |
| optionsMap.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6); |
| optionsMap.put(CompilerOptions.OPTION_TaskTags, ""); //$NON-NLS-1$ |
| optionsMap.put(CompilerOptions.OPTION_TaskPriorities, ""); //$NON-NLS-1$ |
| optionsMap.put(CompilerOptions.OPTION_TaskCaseSensitive, CompilerOptions.DISABLED); |
| optionsMap.put(CompilerOptions.OPTION_ReportUnusedParameterWhenImplementingAbstract, CompilerOptions.DISABLED); |
| optionsMap.put(CompilerOptions.OPTION_ReportUnusedParameterWhenOverridingConcrete, CompilerOptions.DISABLED); |
| optionsMap.put(CompilerOptions.OPTION_ReportSpecialParameterHidingField, CompilerOptions.DISABLED); |
| optionsMap.put(CompilerOptions.OPTION_MaxProblemPerUnit, String.valueOf(100)); |
| optionsMap.put(CompilerOptions.OPTION_InlineJsr, CompilerOptions.DISABLED); |
| optionsMap.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6); |
| return optionsMap; |
| } |
| |
| /* |
| private boolean isExpectedFailure() { |
| int length = EXPECTED_FAILURES.length; |
| for (int i=0; i<length; i++) { |
| IPath expectedFailure= EXPECTED_FAILURES[i]; |
| if (this.path.toString().indexOf(expectedFailure.toString()) >= 0) { |
| this.failureIndex = REFORMATTING_EXPECTED_FAILURE; |
| FAILURES[REFORMATTING_EXPECTED_FAILURE].failures.add(this.path); |
| return true; |
| } |
| } |
| return false; |
| } |
| */ |
| |
| /* |
| private boolean runFormatterWithoutComments(CodeFormatter codeFormatter, String source, int kind, int indentationLevel, int offset, int length, String lineSeparator) { |
| DefaultCodeFormatterOptions preferencesWithoutComment = DefaultCodeFormatterOptions.getEclipseDefaultSettings(); |
| preferencesWithoutComment.comment_format_line_comment = false; |
| preferencesWithoutComment.comment_format_block_comment = false; |
| preferencesWithoutComment.comment_format_javadoc_comment = false; |
| DefaultCodeFormatter codeFormatterWithoutComment = new DefaultCodeFormatter(preferencesWithoutComment); |
| |
| TextEdit edit = codeFormatterWithoutComment.format(kind, source, offset, length, indentationLevel, lineSeparator);//$NON-NLS-1$ |
| if (edit == null) return false; |
| String initialResult = org.eclipse.jdt.internal.core.util.Util.editedString(source, edit); |
| |
| int count = 1; |
| String result = initialResult; |
| String previousResult = result; |
| while (count++ < FORMAT_REPEAT) { |
| edit = codeFormatterWithoutComment.format(kind, result, 0, result.length(), indentationLevel, lineSeparator);//$NON-NLS-1$ |
| if (edit == null) return false; |
| previousResult = result; |
| result = org.eclipse.jdt.internal.core.util.Util.editedString(result, edit); |
| } |
| return previousResult.equals(result); |
| } |
| */ |
| |
| private boolean sourceHasCompilationErrors(String source) { |
| CodeSnippetParsingUtil codeSnippetParsingUtil = new CodeSnippetParsingUtil(); |
| codeSnippetParsingUtil.parseCompilationUnit(source.toCharArray(), getDefaultCompilerOptions(), true); |
| if (codeSnippetParsingUtil.recordedParsingInformation != null) { |
| CategorizedProblem[] problems = codeSnippetParsingUtil.recordedParsingInformation.problems; |
| int length = problems == null ? 0 : problems.length; |
| for (int i=0; i<length; i++) { |
| if (((DefaultProblem)problems[i]).isError()) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| String runFormatter(CodeFormatter codeFormatter, String source, int kind, int indentationLevel, int offset, int length, String lineSeparator, boolean repeat) { |
| long timeStart = System.currentTimeMillis(); |
| TextEdit edit = codeFormatter.format(kind, source, offset, length, indentationLevel, lineSeparator); |
| if (FAILURES != null) { // Comparison has started |
| TIME_MEASURES.formatting[0] += System.currentTimeMillis() - timeStart; |
| TIME_MEASURES.occurences[0]++; |
| if (edit == null) TIME_MEASURES.null_output[0]++; |
| } |
| if (edit == null) { |
| if (sourceHasCompilationErrors(source)) { |
| this.failureIndex = COMPILATION_ERRORS_FAILURE; |
| FAILURES[COMPILATION_ERRORS_FAILURE].failures.add(this.path); |
| return null; |
| } |
| this.failureIndex = NO_OUTPUT_FAILURE; |
| throw new AssertionFailedError("Formatted source should not be null!"); |
| } |
| String initialResult = org.eclipse.jdt.internal.core.util.Util.editedString(source, edit); |
| |
| int count = 0; |
| String result = initialResult; |
| String previousResult = result; |
| while (++count < FORMAT_REPEAT) { |
| timeStart = System.currentTimeMillis(); |
| edit = codeFormatter.format(kind, result, 0, result.length(), indentationLevel, lineSeparator); |
| if (FAILURES != null) { // Comparison has started |
| TIME_MEASURES.formatting[count] += System.currentTimeMillis() - timeStart; |
| TIME_MEASURES.occurences[count]++; |
| if (edit == null) TIME_MEASURES.null_output[count]++; |
| } |
| if (edit == null) return null; |
| previousResult = result; |
| result = org.eclipse.jdt.internal.core.util.Util.editedString(result, edit); |
| } |
| if (!previousResult.equals(result)) { |
| |
| if (FAILURES != null) { |
| // Try to compare without leading spaces |
| String trimmedExpected = ModelTestsUtil.trimLinesLeadingWhitespaces(previousResult); |
| String trimmedActual= ModelTestsUtil.trimLinesLeadingWhitespaces(result); |
| if (trimmedExpected.equals(trimmedActual)) { |
| this.failureIndex = REFORMATTING_LEADING_FAILURE; |
| FAILURES[REFORMATTING_LEADING_FAILURE].failures.add(this.path); |
| return initialResult; |
| } |
| |
| // Try to compare without spaces at all |
| if (ModelTestsUtil.removeWhiteSpace(previousResult).equals(ModelTestsUtil.removeWhiteSpace(result))) { |
| this.failureIndex = REFORMATTING_WHITESPACES_FAILURE; |
| FAILURES[REFORMATTING_WHITESPACES_FAILURE].failures.add(this.path); |
| return initialResult; |
| } |
| } |
| |
| /* |
| // Try to see if the formatting also fails without comments |
| if (!runFormatterWithoutComments(null, source, kind, indentationLevel, offset, length, lineSeparator)) { |
| return initialResult; |
| } |
| |
| // format without comments is OK => there's a problem with comment formatting |
| String counterString = counterToString(count-1); |
| assertSourceEquals(counterString+" formatting is different from first one!", previousResult, result); |
| */ |
| // if (!isExpectedFailure()) { |
| String counterString = counterToString(count); |
| try { |
| assertSourceEquals(counterString+" formatting is different from first one!", previousResult, result); |
| } |
| catch (ComparisonFailure cf) { |
| this.failureIndex = REFORMATTING_FAILURE; |
| throw cf; |
| } |
| catch (AssertionFailedError afe) { |
| this.failureIndex = REFORMATTING_FAILURE; |
| throw afe; |
| } |
| // } |
| } |
| return initialResult; |
| } |
| |
| /** |
| * Returns a string to display the given time as a duration |
| * formatted as: |
| * <ul> |
| * <li>"XXXms" if the duration is less than 0.1s (e.g. "543ms")</li> |
| * <li>"X.YYs" if the duration is less than 1s (e.g. "5.43s")</li> |
| * <li>"XX.Ys" if the duration is less than 1mn (e.g. "54.3s")</li> |
| * <li>"XXmn XXs" if the duration is less than 1h (e.g. "54mn 3s")</li> |
| * <li>"XXh XXmn XXs" if the duration is over than 1h (e.g. "5h 4mn 3s")</li> |
| * </ul> |
| * |
| * @param time The time to format as a long. |
| * @return The formatted string. |
| */ |
| public String timeString(long time) { |
| NumberFormat format = NumberFormat.getInstance(); |
| format.setMaximumFractionDigits(3); |
| StringBuffer buffer = new StringBuffer(); |
| if (time == 0) { |
| // print nothing |
| } else { |
| long h = time / ONE_HOUR; |
| if (h > 0) buffer.append(h).append("h "); //$NON-NLS-1$ |
| long remaining = time % ONE_HOUR; |
| long m = remaining / ONE_MINUTE; |
| if (h > 0 || m > 0) buffer.append(m).append("mn "); //$NON-NLS-1$ |
| remaining = remaining % ONE_MINUTE; |
| if ((remaining % 1000) == 0) { |
| buffer.append(remaining/1000); |
| } else { |
| buffer.append(format.format(remaining/1000.0)); |
| } |
| buffer.append("s"); //$NON-NLS-1$ |
| } |
| return buffer.toString(); |
| } |
| |
| /* |
| * Test to delete the output directory. |
| * |
| public void testDeleteOutputDir() throws IOException, Exception { |
| Util.delete(this.inputDir); |
| } |
| |
| /* |
| * Test to fill the output directory with reference. |
| */ |
| public void testReference() throws IOException, Exception { |
| |
| // Dump the version |
| // if (this.testIndex == 0) { |
| // File versionFile = new Path(OUTPUT_DIR.getPath()).append("version.txt").toFile(); |
| // OUTPUT_DIR.mkdirs(); |
| // Util.writeToFile(JDT_CORE_VERSION, versionFile.getAbsolutePath()); |
| // } |
| |
| // Get the source from file |
| String source = new String(org.eclipse.jdt.internal.compiler.util.Util.getFileCharContent(this.file, null)); |
| try { |
| // Format the source |
| TextEdit edit = codeFormatter().format(CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS, source, 0, source.length(), 0, null); |
| |
| // Write the result |
| if (edit != null) { |
| String formatResult = org.eclipse.jdt.internal.core.util.Util.editedString(source, edit); |
| String inputPath = this.file.getPath().substring(this.inputDir.getPath().length()+1); |
| File writtenFile = new Path(OUTPUT_DIR.getPath()).append(inputPath).toFile(); |
| writtenFile.getParentFile().mkdirs(); |
| Util.writeToFile(formatResult, writtenFile.getAbsolutePath()); |
| } |
| } |
| catch (Exception ex) { |
| // skip silently |
| } |
| } |
| |
| /* |
| * Test to compare the formatter output with an existing file. |
| */ |
| public void testCompare() throws IOException, Exception { |
| try { |
| compareFormattedSource(); |
| } |
| catch (ComparisonFailure cf) { |
| if (this.failureIndex == -1) { |
| FAILURES[UNEXPECTED_FAILURE].failures.add(this.path); |
| } else { |
| FAILURES[this.failureIndex].failures.add(this.path); |
| } |
| throw cf; |
| } |
| catch (AssertionFailedError afe) { |
| if (this.failureIndex == -1) { |
| FAILURES[UNEXPECTED_FAILURE].failures.add(this.path); |
| } else { |
| FAILURES[this.failureIndex].failures.add(this.path); |
| } |
| throw afe; |
| } |
| catch (Exception ex) { |
| FAILURES[UNEXPECTED_FAILURE].failures.add(this.path); |
| throw ex; |
| } |
| } |
| } |