git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@348500 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -163,6 +163,9 @@ Fixed bugs: | |||
| Other changes: | |||
| -------------- | |||
| * New task <manifestclasspath> converts a path into a property | |||
| suitable as the value for a manifest's Class-Path attribute. | |||
| * Fixed references to obsoleted CVS web site. Bugzilla Report 36854. | |||
| * Log fine-grained events at verbose level from JUnit. Bugzilla report 31885. | |||
| @@ -0,0 +1,98 @@ | |||
| <html> | |||
| <head> | |||
| <meta http-equiv="Content-Language" content="en-us"> | |||
| <link rel="stylesheet" type="text/css" href="../stylesheets/style.css"> | |||
| <title>ManifestClassPath Task</title> | |||
| </head> | |||
| <body> | |||
| <h2><a name="manifestclasspath">Manifestclasspath</a></h2> | |||
| <h3>Description</h3> | |||
| <p>Converts a <a href="../using.html#path">Path</a> into a property | |||
| whose value is appropriate for a <a href="manifest.html">Manifest</a>'s | |||
| <code>Class-Path</code> attribute.</p> | |||
| <p>This task is often used to work around command line limitations on Windows | |||
| when using very long class paths when launching an application. The long class | |||
| path normally specified on the command line is replaced by a single (possibly | |||
| empty) jar file which an in-manifest Class-Path attribute whose value lists | |||
| all the jar and zip files the class path should contain. The files referenced | |||
| from this attribute must be found relatively to the jar file itself, usually | |||
| in the same directory. The Java VM automically uses all file entries listed | |||
| in the Class-Path attributes of a jar to locate/load classes. Note though that | |||
| it silently ignores entries for which it cannot find any corresponding file.</p> | |||
| <p>Note that the property value created may be longer than a manifest's maximum | |||
| 72 characters per line, but will be properly wrapped as per the Jar | |||
| specification by the <code><manifest></code> element, where the | |||
| defined property is re-referenced.</p> | |||
| <p><em>since Ant 1.7</em></p> | |||
| <h3>Parameters</h3> | |||
| <table border="1" cellpadding="2" cellspacing="0"> | |||
| <tr> | |||
| <td valign="top"><b>Attribute</b></td> | |||
| <td valign="top"><b>Description</b></td> | |||
| <td align="center" valign="top"><b>Required</b></td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">property</td> | |||
| <td valign="top">the name of the property to set. This property must | |||
| not already be set.</td> | |||
| <td valign="top" align="center">Yes</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">jarfile</td> | |||
| <td valign="top"> | |||
| the filename for the Jar which will contain the manifest that will | |||
| use the property this task will set. This file need not exist yet, | |||
| but its parent directory must exist. | |||
| </td> | |||
| <td valign="top" align="center">Yes</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">maxParentLevels</td> | |||
| <td valign="top"> | |||
| The maximum number of parent directories one is allowed to traverse | |||
| to navigate from the jar file to the path entry. Put differently, the | |||
| maximum number of .. which is allowed in the relative path from the | |||
| jar file to a given class path enty. Specify 0 to enforce a path | |||
| entry to be in the same directory (or one of its sub-directories) | |||
| as the jar file itself. Defaults to 2 levels.</td> | |||
| <td valign="top" align="center">No</td> | |||
| </tr> | |||
| </table> | |||
| <h3>Parameters specified as nested elements</h3> | |||
| <h4>classpath</h4> | |||
| <p>A <a href="../using#path.html">Path-like</a> element, which can be | |||
| defined in-place, or refer to a path defined elsewhere using the | |||
| <code><classpath refid="<em>pathid</em>" /></code> syntax. | |||
| This classpath must not be empty, and is required.</p> | |||
| <h3>Examples</h3> | |||
| <div id="example1"> | |||
| <blockquote><pre> | |||
| <manifestclasspath property="jar.classpath" | |||
| jarfile="build/acme.jar"> | |||
| <classpath refid="classpath" /> | |||
| </manifestclasspath> | |||
| </pre></blockquote> | |||
| <p>Assuming a path of id "classpath" was already defined, convert this | |||
| path relatively to the build/ directory that will contain acme.jar, which | |||
| can later be created with <code><jar></code> with a nested | |||
| <code><manifest></code> element that lists an | |||
| <code><attribute name="Class-Path" value="${jar.classpath}" /></code>. | |||
| </p> | |||
| </div> | |||
| <hr> | |||
| <p align="center">Copyright © 2005 The Apache Software Foundation. | |||
| All rights Reserved.</p> | |||
| </body> | |||
| </html> | |||
| @@ -69,6 +69,7 @@ | |||
| <a href="CoreTasks/mail.html">Mail</a><br> | |||
| <a href="CoreTasks/macrodef.html">MacroDef</a><br> | |||
| <a href="CoreTasks/manifest.html">Manifest</a><br> | |||
| <a href="CoreTasks/manifestclasspath.html">ManifestClassPath</a><br> | |||
| <a href="CoreTasks/mkdir.html">Mkdir</a><br> | |||
| <a href="CoreTasks/move.html">Move</a><br> | |||
| <a href="CoreTasks/nice.html">Nice</a><br> | |||
| @@ -0,0 +1,164 @@ | |||
| <?xml version="1.0"?> | |||
| <project name="manifestclasspath" default="tearDown"> | |||
| <target name="setUp"> | |||
| <property name="tmp" location="${basedir}/${ant.project.name}.tmp" /> | |||
| <mkdir dir="${tmp}" /> | |||
| </target> | |||
| <target name="fullSetUp" depends="setUp"> | |||
| <mkdir dir="${tmp}/lib" /> | |||
| <touch file="${tmp}/lib/acme-core.jar" /> | |||
| <touch file="${tmp}/lib/acme-pres.jar" /> | |||
| <mkdir dir="${tmp}/classes/dsp-core/com/lgc/infra/core" /> | |||
| <mkdir dir="${tmp}/classes/dsp-pres/com/lgc/infra/pres" /> | |||
| <mkdir dir="${tmp}/classes/dsp-void" /> | |||
| <mkdir dir="${tmp}/generated/dsp-core/com/lgc/infra/core/generated" /> | |||
| <mkdir dir="${tmp}/generated/dsp-pres" /> | |||
| <mkdir dir="${tmp}/generated/dsp-void" /> | |||
| <mkdir dir="${tmp}/resources/dsp-core/com/lgc/infra/core" /> | |||
| <mkdir dir="${tmp}/resources/dsp-pres/com/lgc/infra/pres" /> | |||
| <mkdir dir="${tmp}/resources/dsp-void" /> | |||
| </target> | |||
| <target name="tearDown"> | |||
| <delete dir="${tmp}" /> | |||
| </target> | |||
| <target name="test-bad-directory"> | |||
| <manifestclasspath property="jar.classpath" | |||
| jarfile="${tmp}/classpath.jar"> | |||
| <classpath /> | |||
| </manifestclasspath> | |||
| </target> | |||
| <target name="test-bad-no-property" depends="setUp"> | |||
| <manifestclasspath jarfile="${tmp}/classpath.jar"> | |||
| <classpath /> | |||
| </manifestclasspath> | |||
| </target> | |||
| <target name="test-bad-property-exists" depends="setUp"> | |||
| <property name="jar.classpath" value="exists" /> | |||
| <manifestclasspath property="jar.classpath" | |||
| jarfile="${tmp}/classpath.jar"> | |||
| <classpath /> | |||
| </manifestclasspath> | |||
| </target> | |||
| <target name="test-bad-no-jarfile" depends="setUp"> | |||
| <manifestclasspath property="jar.classpath"> | |||
| <classpath /> | |||
| </manifestclasspath> | |||
| </target> | |||
| <target name="test-bad-no-classpath" depends="setUp"> | |||
| <manifestclasspath property="jar.classpath" | |||
| jarfile="${tmp}/classpath.jar" /> | |||
| </target> | |||
| <target name="test-pseudo-tahoe-refid" depends="fullSetUp"> | |||
| <path id="classpath"> | |||
| <!-- All the classes/ directories --> | |||
| <dirset dir="${tmp}/classes" includes="dsp-*" /> | |||
| <!-- All the JAXB generated/ directories --> | |||
| <dirset dir="${tmp}/generated" includes="dsp-*"> | |||
| <!-- Add only non-empty directories to the classpath --> | |||
| <present targetdir="${tmp}/generated" present="both"> | |||
| <mapper type="regexp" from="(.*)" to="\1/com" /> | |||
| </present> | |||
| </dirset> | |||
| <!-- All the resources/ directories --> | |||
| <dirset dir="${tmp}/resources" includes="dsp-*"> | |||
| <!-- Add only non-empty directories to the classpath --> | |||
| <present targetdir="${tmp}/resources" present="both"> | |||
| <mapper type="regexp" from="(.*)" to="\1/com" /> | |||
| </present> | |||
| </dirset> | |||
| </path> | |||
| <manifestclasspath property="jar.classpath" | |||
| jarfile="${tmp}/classpath.jar"> | |||
| <classpath refid="classpath" /> | |||
| </manifestclasspath> | |||
| </target> | |||
| <target name="test-pseudo-tahoe-nested" depends="fullSetUp"> | |||
| <manifestclasspath property="jar.classpath" | |||
| jarfile="${tmp}/classpath.jar"> | |||
| <classpath> | |||
| <!-- All the classes/ directories --> | |||
| <dirset dir="${tmp}/classes" includes="dsp-*" /> | |||
| <!-- All the JAXB generated/ directories --> | |||
| <dirset dir="${tmp}/generated" includes="dsp-*"> | |||
| <!-- Add only non-empty directories to the classpath --> | |||
| <present targetdir="${tmp}/generated" present="both"> | |||
| <mapper type="regexp" from="(.*)" to="\1/com" /> | |||
| </present> | |||
| </dirset> | |||
| <!-- All the resources/ directories --> | |||
| <dirset dir="${tmp}/resources" includes="dsp-*"> | |||
| <!-- Add only non-empty directories to the classpath --> | |||
| <present targetdir="${tmp}/resources" present="both"> | |||
| <mapper type="regexp" from="(.*)" to="\1/com" /> | |||
| </present> | |||
| </dirset> | |||
| </classpath> | |||
| </manifestclasspath> | |||
| </target> | |||
| <target name="test-parent-level1" depends="fullSetUp"> | |||
| <manifestclasspath property="jar.classpath" | |||
| jarfile="${tmp}/classes/classpath.jar"> | |||
| <classpath> | |||
| <dirset dir="${tmp}/classes" includes="dsp-*" /> | |||
| <dirset dir="${tmp}/generated" includes="dsp-*" /> | |||
| <dirset dir="${tmp}/resources" includes="dsp-*" /> | |||
| </classpath> | |||
| </manifestclasspath> | |||
| </target> | |||
| <target name="test-parent-level2" depends="fullSetUp"> | |||
| <mkdir dir="${tmp}/classes/level2" /> | |||
| <manifestclasspath property="jar.classpath" | |||
| jarfile="${tmp}/classes/level2/classpath.jar"> | |||
| <classpath> | |||
| <dirset dir="${tmp}/classes" includes="dsp-*" /> | |||
| <dirset dir="${tmp}/generated" includes="dsp-*" /> | |||
| <dirset dir="${tmp}/resources" includes="dsp-*" /> | |||
| </classpath> | |||
| </manifestclasspath> | |||
| </target> | |||
| <target name="test-parent-level2-too-deep" depends="fullSetUp"> | |||
| <mkdir dir="${tmp}/classes/level2" /> | |||
| <manifestclasspath property="jar.classpath" maxParentLevels="1" | |||
| jarfile="${tmp}/classes/level2/classpath.jar"> | |||
| <classpath> | |||
| <dirset dir="${tmp}/classes" includes="dsp-*" /> | |||
| <dirset dir="${tmp}/generated" includes="dsp-*" /> | |||
| <dirset dir="${tmp}/resources" includes="dsp-*" /> | |||
| </classpath> | |||
| </manifestclasspath> | |||
| </target> | |||
| <target name="test-parent-level2-with-jars" depends="fullSetUp"> | |||
| <mkdir dir="${tmp}/classes/level2" /> | |||
| <manifestclasspath property="jar.classpath" | |||
| jarfile="${tmp}/classes/level2/classpath.jar"> | |||
| <classpath> | |||
| <fileset dir="${tmp}/lib" includes="*.jar" /> | |||
| <dirset dir="${tmp}/classes" includes="dsp-*" /> | |||
| <dirset dir="${tmp}/generated" includes="dsp-*" /> | |||
| <dirset dir="${tmp}/resources" includes="dsp-*" /> | |||
| </classpath> | |||
| </manifestclasspath> | |||
| </target> | |||
| </project> | |||
| @@ -0,0 +1,184 @@ | |||
| /* | |||
| * Copyright 2005 The Apache Software Foundation | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||
| * you may not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| * | |||
| */ | |||
| package org.apache.tools.ant.taskdefs; | |||
| import java.io.File; | |||
| import org.apache.tools.ant.Task; | |||
| import org.apache.tools.ant.types.Path; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.util.FileUtils; | |||
| /** | |||
| * Converts a Path into a property suitable as a Manifest classpath. | |||
| * | |||
| * @since Ant 1.7 | |||
| * | |||
| * @ant.task category="property" | |||
| */ | |||
| public class ManifestClassPath | |||
| extends Task { | |||
| /** The property name to hold the classpath value. */ | |||
| private String _name; | |||
| /** The directory the classpath will be relative from. */ | |||
| private File _dir; | |||
| /** The maximum parent directory level to traverse. */ | |||
| private int _maxParentLevels = 2; | |||
| /** The classpath to convert. */ | |||
| private Path _path; | |||
| /** | |||
| * Sets a property, which must not already exists, with a space | |||
| * separated list of files and directories relative to the jar | |||
| * file's parent directory. | |||
| */ | |||
| public void execute() { | |||
| if (_name == null) { | |||
| throw new BuildException("Missing 'property' attribute!"); | |||
| } | |||
| if (_dir == null) { | |||
| throw new BuildException("Missing 'jarfile' attribute!"); | |||
| } | |||
| if (getProject().getProperty(_name) != null) { | |||
| throw new BuildException("Property '" + _name + "' already set!"); | |||
| } | |||
| if (_path == null) { | |||
| throw new BuildException("Missing nested <classpath>!"); | |||
| } | |||
| // Normalize the reference directory (containing the jar) | |||
| final FileUtils fileUtils = FileUtils.getFileUtils(); | |||
| _dir = fileUtils.normalize(_dir.getAbsolutePath()); | |||
| // Create as many directory prefixes as parent levels to traverse, | |||
| // in addition to the reference directory itself | |||
| File currDir = _dir; | |||
| String[] dirs = new String[_maxParentLevels + 1]; | |||
| for (int i = 0; i < _maxParentLevels + 1; ++i) { | |||
| dirs[i] = currDir.getAbsolutePath() + File.separatorChar; | |||
| currDir = currDir.getParentFile(); | |||
| if (currDir == null) { | |||
| _maxParentLevels = i + 1; | |||
| break; | |||
| } | |||
| } | |||
| String[] elements = _path.list(); | |||
| StringBuffer buffer = new StringBuffer(); | |||
| StringBuffer element = new StringBuffer(); | |||
| for (int i = 0; i < elements.length; ++i) { | |||
| // Normalize the current file | |||
| File pathEntry = new File(elements[i]); | |||
| pathEntry = fileUtils.normalize(pathEntry.getAbsolutePath()); | |||
| String fullPath = pathEntry.getAbsolutePath(); | |||
| // Find the longest prefix shared by the current file | |||
| // and the reference directory. | |||
| String relPath = null; | |||
| for (int j = 0; j <= _maxParentLevels; ++j) { | |||
| String dir = dirs[j]; | |||
| if (!fullPath.startsWith(dir)) { | |||
| continue; | |||
| } | |||
| // We have a match! Add as many ../ as parent | |||
| // directory traversed to get the relative path | |||
| element.setLength(0); | |||
| for (int k = 0; k < j; ++k) { | |||
| element.append(".."); | |||
| element.append(File.separatorChar); | |||
| } | |||
| element.append(fullPath.substring(dir.length())); | |||
| relPath = element.toString(); | |||
| break; | |||
| } | |||
| // No match, so bail out! | |||
| if (relPath == null) { | |||
| throw new BuildException("No suitable relative path from " + | |||
| _dir + " to " + fullPath); | |||
| } | |||
| // Manifest's ClassPath: attribute always uses forward | |||
| // slashes '/', and is space-separated. Ant will properly | |||
| // format it on 72 columns with proper line continuation | |||
| if (File.separatorChar != '/') { | |||
| relPath = relPath.replace(File.separatorChar, '/'); | |||
| } | |||
| buffer.append(relPath); | |||
| if (pathEntry.isDirectory()) { | |||
| buffer.append('/'); | |||
| } | |||
| buffer.append(' '); | |||
| } | |||
| // Get rid of trailing space, if any | |||
| if (buffer.length() > 0) { | |||
| buffer.setLength(buffer.length() - 1); | |||
| } | |||
| // Finally assign the property with the manifest classpath | |||
| getProject().setNewProperty(_name, buffer.toString()); | |||
| } | |||
| /** | |||
| * Sets the property name to hold the classpath value. | |||
| * | |||
| * @param name the property name | |||
| */ | |||
| public void setProperty(String name) { | |||
| _name = name; | |||
| } | |||
| /** | |||
| * The JAR file to contain the classpath attribute in its manifest. | |||
| * | |||
| * @param jarfile the JAR file. Need not exist yet, but its parent | |||
| * directory must exist on the other hand. | |||
| */ | |||
| public void setJarFile(File jarfile) { | |||
| File parent = jarfile.getParentFile(); | |||
| if (!parent.isDirectory()) { | |||
| throw new BuildException("Jar's directory not found: " + parent); | |||
| } | |||
| _dir = parent; | |||
| } | |||
| /** | |||
| * Sets the maximum parent directory levels allowed when computing | |||
| * a relative path. | |||
| * | |||
| * @param levels the max level. Defaults to 2. | |||
| */ | |||
| public void setMaxParentLevels(int levels) { | |||
| _maxParentLevels = levels; | |||
| } | |||
| /** | |||
| * Adds the classpath to convert. | |||
| * | |||
| * @param path the classpath to convert. | |||
| */ | |||
| public void addClassPath(Path path) { | |||
| _path = path; | |||
| } | |||
| } | |||
| @@ -47,6 +47,7 @@ loadproperties=org.apache.tools.ant.taskdefs.LoadProperties | |||
| macrodef=org.apache.tools.ant.taskdefs.MacroDef | |||
| mail=org.apache.tools.ant.taskdefs.email.EmailTask | |||
| manifest=org.apache.tools.ant.taskdefs.ManifestTask | |||
| manifestclasspath=org.apache.tools.ant.taskdefs.ManifestClassPath | |||
| mkdir=org.apache.tools.ant.taskdefs.Mkdir | |||
| move=org.apache.tools.ant.taskdefs.Move | |||
| nice=org.apache.tools.ant.taskdefs.Nice | |||
| @@ -221,4 +222,4 @@ rename=org.apache.tools.ant.taskdefs.Rename | |||
| renameext=org.apache.tools.ant.taskdefs.optional.RenameExtensions | |||
| starteam=org.apache.tools.ant.taskdefs.optional.scm.AntStarTeamCheckOut | |||
| style=org.apache.tools.ant.taskdefs.XSLTProcess | |||
| WsdlToDotnet=org.apache.tools.ant.taskdefs.optional.dotnet.WsdlToDotnet | |||
| WsdlToDotnet=org.apache.tools.ant.taskdefs.optional.dotnet.WsdlToDotnet | |||
| @@ -42,19 +42,42 @@ public abstract class BuildFileTest extends TestCase { | |||
| private BuildException buildException; | |||
| /** | |||
| * Constructor for the BuildFileTest object | |||
| * Default constructor for the BuildFileTest object. | |||
| */ | |||
| public BuildFileTest() { | |||
| super(); | |||
| } | |||
| /** | |||
| * Constructor for the BuildFileTest object. | |||
| * | |||
| *@param name string to pass up to TestCase constructor | |||
| * @param name string to pass up to TestCase constructor | |||
| */ | |||
| public BuildFileTest(String name) { | |||
| super(name); | |||
| } | |||
| /** | |||
| * run a target, expect for any build exception | |||
| * Automatically calls the target called "tearDown" | |||
| * from the build file tested if it exits. | |||
| * | |||
| *@param target target to run | |||
| *@param cause information string to reader of report | |||
| * This allows to use Ant tasks directly in the build file | |||
| * to clean up after each test. Note that no "setUp" target | |||
| * is automatically called, since it's trivial to have a | |||
| * test target depend on it. | |||
| */ | |||
| protected void tearDown() throws Exception { | |||
| final String tearDown = "tearDown"; | |||
| if (project.getTargets().containsKey(tearDown)) { | |||
| project.executeTarget(tearDown); | |||
| } | |||
| } | |||
| /** | |||
| * run a target, expect for any build exception | |||
| * | |||
| * @param target target to run | |||
| * @param cause information string to reader of report | |||
| */ | |||
| protected void expectBuildException(String target, String cause) { | |||
| expectSpecificBuildException(target, cause, null); | |||
| @@ -71,9 +94,8 @@ public abstract class BuildFileTest extends TestCase { | |||
| } | |||
| /** | |||
| * Assert that the given substring is in the log messages | |||
| * Assert that the given substring is in the log messages. | |||
| */ | |||
| protected void assertLogContaining(String substring) { | |||
| String realLog = getLog(); | |||
| assertTrue("expecting log to contain \"" + substring + "\" log was \"" | |||
| @@ -82,16 +104,16 @@ public abstract class BuildFileTest extends TestCase { | |||
| } | |||
| /** | |||
| * Assert that the given substring is in the output messages | |||
| * Assert that the given substring is in the output messages. | |||
| * @since Ant1.7 | |||
| */ | |||
| protected void assertOutputContaining(String substring) { | |||
| String realOutput = getOutput(); | |||
| assertTrue("expecting output to contain \"" + substring + "\" output was \"" | |||
| + realOutput + "\"", | |||
| realOutput.indexOf(substring) >= 0); | |||
| assertTrue("expecting output to contain \"" + substring | |||
| + "\" output was \"" + realOutput + "\"", | |||
| realOutput.indexOf(substring) >= 0); | |||
| } | |||
| /** | |||
| * Assert that the given message has been logged with a priority | |||
| * <= INFO when running the given target. | |||
| @@ -102,9 +124,9 @@ public abstract class BuildFileTest extends TestCase { | |||
| } | |||
| /** | |||
| * Gets the log the BuildFileTest object. | |||
| * only valid if configureProject() has | |||
| * been called. | |||
| * Gets the log the BuildFileTest object. | |||
| * Only valid if configureProject() has been called. | |||
| * | |||
| * @pre logBuffer!=null | |||
| * @return The log value | |||
| */ | |||
| @@ -123,9 +145,8 @@ public abstract class BuildFileTest extends TestCase { | |||
| } | |||
| /** | |||
| * Assert that the given substring is in the log messages | |||
| * Assert that the given substring is in the log messages. | |||
| */ | |||
| protected void assertDebuglogContaining(String substring) { | |||
| String realLog = getFullLog(); | |||
| assertTrue("expecting debug log to contain \"" + substring | |||
| @@ -135,9 +156,10 @@ public abstract class BuildFileTest extends TestCase { | |||
| } | |||
| /** | |||
| * Gets the log the BuildFileTest object. | |||
| * only valid if configureProject() has | |||
| * been called. | |||
| * Gets the log the BuildFileTest object. | |||
| * | |||
| * Only valid if configureProject() has been called. | |||
| * | |||
| * @pre fullLogBuffer!=null | |||
| * @return The log value | |||
| */ | |||
| @@ -146,12 +168,11 @@ public abstract class BuildFileTest extends TestCase { | |||
| } | |||
| /** | |||
| * execute the target, verify output matches expectations | |||
| * execute the target, verify output matches expectations | |||
| * | |||
| *@param target target to execute | |||
| *@param output output to look for | |||
| * @param target target to execute | |||
| * @param output output to look for | |||
| */ | |||
| protected void expectOutput(String target, String output) { | |||
| executeTarget(target); | |||
| String realOutput = getOutput(); | |||
| @@ -159,13 +180,13 @@ public abstract class BuildFileTest extends TestCase { | |||
| } | |||
| /** | |||
| * execute the target, verify output matches expectations | |||
| * and that we got the named error at the end | |||
| *@param target target to execute | |||
| *@param output output to look for | |||
| *@param error Description of Parameter | |||
| * Executes the target, verify output matches expectations | |||
| * and that we got the named error at the end | |||
| * | |||
| * @param target target to execute | |||
| * @param output output to look for | |||
| * @param error Description of Parameter | |||
| */ | |||
| protected void expectOutputAndError(String target, String output, String error) { | |||
| executeTarget(target); | |||
| String realOutput = getOutput(); | |||
| @@ -206,7 +227,7 @@ public abstract class BuildFileTest extends TestCase { | |||
| } | |||
| /** | |||
| * set up to run the named project | |||
| * Sets up to run the named project | |||
| * | |||
| * @param filename name of project file to run | |||
| */ | |||
| @@ -215,7 +236,7 @@ public abstract class BuildFileTest extends TestCase { | |||
| } | |||
| /** | |||
| * set up to run the named project | |||
| * Sets up to run the named project | |||
| * | |||
| * @param filename name of project file to run | |||
| */ | |||
| @@ -232,7 +253,8 @@ public abstract class BuildFileTest extends TestCase { | |||
| } | |||
| /** | |||
| * execute a target we have set up | |||
| * Executes a target we have set up | |||
| * | |||
| * @pre configureProject has been called | |||
| * @param targetName target to run | |||
| */ | |||
| @@ -269,7 +291,8 @@ public abstract class BuildFileTest extends TestCase { | |||
| } | |||
| /** | |||
| * get the directory of the project | |||
| * Gets the directory of the project. | |||
| * | |||
| * @return the base dir of the project | |||
| */ | |||
| protected File getProjectDir() { | |||
| @@ -277,12 +300,12 @@ public abstract class BuildFileTest extends TestCase { | |||
| } | |||
| /** | |||
| * run a target, wait for a build exception | |||
| * Runs a target, wait for a build exception. | |||
| * | |||
| *@param target target to run | |||
| *@param cause information string to reader of report | |||
| *@param msg the message value of the build exception we are waiting for | |||
| set to null for any build exception to be valid | |||
| * @param target target to run | |||
| * @param cause information string to reader of report | |||
| * @param msg the message value of the build exception we are waiting | |||
| * for set to null for any build exception to be valid | |||
| */ | |||
| protected void expectSpecificBuildException(String target, String cause, String msg) { | |||
| try { | |||
| @@ -300,12 +323,12 @@ public abstract class BuildFileTest extends TestCase { | |||
| } | |||
| /** | |||
| * run a target, expect an exception string | |||
| * containing the substring we look for (case sensitive match) | |||
| * run a target, expect an exception string | |||
| * containing the substring we look for (case sensitive match) | |||
| * | |||
| *@param target target to run | |||
| *@param cause information string to reader of report | |||
| *@param contains substring of the build exception to look for | |||
| * @param target target to run | |||
| * @param cause information string to reader of report | |||
| * @param contains substring of the build exception to look for | |||
| */ | |||
| protected void expectBuildExceptionContaining(String target, String cause, String contains) { | |||
| try { | |||
| @@ -320,7 +343,6 @@ public abstract class BuildFileTest extends TestCase { | |||
| fail("Should throw BuildException because: " + cause); | |||
| } | |||
| /** | |||
| * call a target, verify property is as expected | |||
| * | |||
| @@ -328,7 +350,6 @@ public abstract class BuildFileTest extends TestCase { | |||
| * @param property property name | |||
| * @param value expected value | |||
| */ | |||
| protected void expectPropertySet(String target, String property, String value) { | |||
| executeTarget(target); | |||
| assertPropertyEquals(property, value); | |||
| @@ -336,6 +357,7 @@ public abstract class BuildFileTest extends TestCase { | |||
| /** | |||
| * assert that a property equals a value; comparison is case sensitive. | |||
| * | |||
| * @param property property name | |||
| * @param value expected value | |||
| */ | |||
| @@ -345,7 +367,8 @@ public abstract class BuildFileTest extends TestCase { | |||
| } | |||
| /** | |||
| * assert that a property equals "true" | |||
| * assert that a property equals "true". | |||
| * | |||
| * @param property property name | |||
| */ | |||
| protected void assertPropertySet(String property) { | |||
| @@ -353,14 +376,14 @@ public abstract class BuildFileTest extends TestCase { | |||
| } | |||
| /** | |||
| * assert that a property is null | |||
| * assert that a property is null. | |||
| * | |||
| * @param property property name | |||
| */ | |||
| protected void assertPropertyUnset(String property) { | |||
| assertPropertyEquals(property, null); | |||
| } | |||
| /** | |||
| * call a target, verify named property is "true". | |||
| * | |||
| @@ -371,9 +394,9 @@ public abstract class BuildFileTest extends TestCase { | |||
| expectPropertySet(target, property, "true"); | |||
| } | |||
| /** | |||
| * call a target, verify property is null | |||
| * Call a target, verify property is null. | |||
| * | |||
| * @param target build file target | |||
| * @param property property name | |||
| */ | |||
| @@ -385,6 +408,7 @@ public abstract class BuildFileTest extends TestCase { | |||
| * Retrieve a resource from the caller classloader to avoid | |||
| * assuming a vm working directory. The resource path must be | |||
| * relative to the package name or absolute from the root path. | |||
| * | |||
| * @param resource the resource to retrieve its url. | |||
| * @throws AssertionFailureException if resource is not found. | |||
| */ | |||
| @@ -410,77 +434,77 @@ public abstract class BuildFileTest extends TestCase { | |||
| } | |||
| /** | |||
| * our own personal build listener | |||
| * Our own personal build listener. | |||
| */ | |||
| private class AntTestListener implements BuildListener { | |||
| private int logLevel; | |||
| /** | |||
| * Constructs a test listener which will ignore log events | |||
| * above the given level | |||
| * above the given level. | |||
| */ | |||
| public AntTestListener(int logLevel) { | |||
| this.logLevel = logLevel; | |||
| } | |||
| /** | |||
| * Fired before any targets are started. | |||
| * Fired before any targets are started. | |||
| */ | |||
| public void buildStarted(BuildEvent event) { | |||
| } | |||
| /** | |||
| * Fired after the last target has finished. This event | |||
| * will still be thrown if an error occurred during the build. | |||
| * Fired after the last target has finished. This event | |||
| * will still be thrown if an error occurred during the build. | |||
| * | |||
| * @see BuildEvent#getException() | |||
| * @see BuildEvent#getException() | |||
| */ | |||
| public void buildFinished(BuildEvent event) { | |||
| } | |||
| /** | |||
| * Fired when a target is started. | |||
| * Fired when a target is started. | |||
| * | |||
| * @see BuildEvent#getTarget() | |||
| * @see BuildEvent#getTarget() | |||
| */ | |||
| public void targetStarted(BuildEvent event) { | |||
| //System.out.println("targetStarted " + event.getTarget().getName()); | |||
| } | |||
| /** | |||
| * Fired when a target has finished. This event will | |||
| * still be thrown if an error occurred during the build. | |||
| * Fired when a target has finished. This event will | |||
| * still be thrown if an error occurred during the build. | |||
| * | |||
| * @see BuildEvent#getException() | |||
| * @see BuildEvent#getException() | |||
| */ | |||
| public void targetFinished(BuildEvent event) { | |||
| //System.out.println("targetFinished " + event.getTarget().getName()); | |||
| } | |||
| /** | |||
| * Fired when a task is started. | |||
| * Fired when a task is started. | |||
| * | |||
| * @see BuildEvent#getTask() | |||
| * @see BuildEvent#getTask() | |||
| */ | |||
| public void taskStarted(BuildEvent event) { | |||
| //System.out.println("taskStarted " + event.getTask().getTaskName()); | |||
| } | |||
| /** | |||
| * Fired when a task has finished. This event will still | |||
| * be throw if an error occurred during the build. | |||
| * Fired when a task has finished. This event will still | |||
| * be throw if an error occurred during the build. | |||
| * | |||
| * @see BuildEvent#getException() | |||
| * @see BuildEvent#getException() | |||
| */ | |||
| public void taskFinished(BuildEvent event) { | |||
| //System.out.println("taskFinished " + event.getTask().getTaskName()); | |||
| } | |||
| /** | |||
| * Fired whenever a message is logged. | |||
| * Fired whenever a message is logged. | |||
| * | |||
| * @see BuildEvent#getMessage() | |||
| * @see BuildEvent#getPriority() | |||
| * @see BuildEvent#getMessage() | |||
| * @see BuildEvent#getPriority() | |||
| */ | |||
| public void messageLogged(BuildEvent event) { | |||
| if (event.getPriority() > logLevel) { | |||
| @@ -494,9 +518,7 @@ public abstract class BuildFileTest extends TestCase { | |||
| logBuffer.append(event.getMessage()); | |||
| } | |||
| fullLogBuffer.append(event.getMessage()); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,139 @@ | |||
| /* | |||
| * Copyright 2000-2005 The Apache Software Foundation | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||
| * you may not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| * | |||
| */ | |||
| package org.apache.tools.ant.taskdefs; | |||
| import java.io.File; | |||
| import java.util.Map; | |||
| import java.util.Properties; | |||
| import org.apache.tools.ant.BuildFileTest; | |||
| /** | |||
| * Tests <bm:manifestclasspath>. | |||
| */ | |||
| public class ManifestClassPathTest | |||
| extends BuildFileTest { | |||
| public void setUp() { | |||
| configureProject("src/etc/testcases/taskdefs/manifestclasspath.xml"); | |||
| } | |||
| public void testBadDirectory() { | |||
| expectBuildExceptionContaining("test-bad-directory", "bad-jar-dir", | |||
| "Jar's directory not found:"); | |||
| assertPropertyUnset("jar.classpath"); | |||
| } | |||
| public void testBadNoProperty() { | |||
| expectBuildExceptionContaining("test-bad-no-property", "no-property", | |||
| "Missing 'property' attribute!"); | |||
| assertPropertyUnset("jar.classpath"); | |||
| } | |||
| public void testBadPropertyExists() { | |||
| expectBuildExceptionContaining("test-bad-property-exists", | |||
| "property-exits", "Property 'jar.classpath' already set!"); | |||
| assertPropertyEquals("jar.classpath", "exists"); | |||
| } | |||
| public void testBadNoJarfile() { | |||
| expectBuildExceptionContaining("test-bad-no-jarfile", "no-jarfile", | |||
| "Missing 'jarfile' attribute!"); | |||
| assertPropertyUnset("jar.classpath"); | |||
| } | |||
| public void testBadNoClassPath() { | |||
| expectBuildExceptionContaining("test-bad-no-classpath", "no-classpath", | |||
| "Missing nested <classpath>!"); | |||
| assertPropertyUnset("jar.classpath"); | |||
| } | |||
| public void testParentLevel1() { | |||
| executeTarget("test-parent-level1"); | |||
| assertPropertyEquals("jar.classpath", "dsp-core/ " + | |||
| "dsp-pres/ " + | |||
| "dsp-void/ " + | |||
| "../generated/dsp-core/ " + | |||
| "../generated/dsp-pres/ " + | |||
| "../generated/dsp-void/ " + | |||
| "../resources/dsp-core/ " + | |||
| "../resources/dsp-pres/ " + | |||
| "../resources/dsp-void/"); | |||
| } | |||
| public void testParentLevel2() { | |||
| executeTarget("test-parent-level2"); | |||
| assertPropertyEquals("jar.classpath", "../dsp-core/ " + | |||
| "../dsp-pres/ " + | |||
| "../dsp-void/ " + | |||
| "../../generated/dsp-core/ " + | |||
| "../../generated/dsp-pres/ " + | |||
| "../../generated/dsp-void/ " + | |||
| "../../resources/dsp-core/ " + | |||
| "../../resources/dsp-pres/ " + | |||
| "../../resources/dsp-void/"); | |||
| } | |||
| public void testParentLevel2TooDeep() { | |||
| expectBuildExceptionContaining("test-parent-level2-too-deep", "nopath", | |||
| "No suitable relative path from "); | |||
| assertPropertyUnset("jar.classpath"); | |||
| } | |||
| public void testPseudoTahoeRefid() { | |||
| executeTarget("test-pseudo-tahoe-refid"); | |||
| assertPropertyEquals("jar.classpath", "classes/dsp-core/ " + | |||
| "classes/dsp-pres/ " + | |||
| "classes/dsp-void/ " + | |||
| "generated/dsp-core/ " + | |||
| "resources/dsp-core/ " + | |||
| "resources/dsp-pres/"); | |||
| } | |||
| public void testPseudoTahoeNested() { | |||
| executeTarget("test-pseudo-tahoe-nested"); | |||
| assertPropertyEquals("jar.classpath", "classes/dsp-core/ " + | |||
| "classes/dsp-pres/ " + | |||
| "classes/dsp-void/ " + | |||
| "generated/dsp-core/ " + | |||
| "resources/dsp-core/ " + | |||
| "resources/dsp-pres/"); | |||
| } | |||
| public void testParentLevel2WithJars() { | |||
| executeTarget("test-parent-level2-with-jars"); | |||
| assertPropertyEquals("jar.classpath", "../../lib/acme-core.jar " + | |||
| "../../lib/acme-pres.jar " + | |||
| "../dsp-core/ " + | |||
| "../dsp-pres/ " + | |||
| "../dsp-void/ " + | |||
| "../../generated/dsp-core/ " + | |||
| "../../generated/dsp-pres/ " + | |||
| "../../generated/dsp-void/ " + | |||
| "../../resources/dsp-core/ " + | |||
| "../../resources/dsp-pres/ " + | |||
| "../../resources/dsp-void/"); | |||
| } | |||
| } // END class ManifestClassPathTest | |||