From 29435d2c47d9a91053c9cf1bdba03bd55696ae7a Mon Sep 17 00:00:00 2001 From: Dominique Devienne Date: Wed, 23 Nov 2005 17:41:51 +0000 Subject: [PATCH] Add new manifestclasspath core task. Make BuildFileTest call tearDown target automatically in build file test if one is defined. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@348500 13f79535-47bb-0310-9956-ffa450edef68 --- WHATSNEW | 3 + docs/manual/CoreTasks/manifestclasspath.html | 98 ++++++++++ docs/manual/coretasklist.html | 1 + .../testcases/taskdefs/manifestclasspath.xml | 164 ++++++++++++++++ .../tools/ant/taskdefs/ManifestClassPath.java | 184 ++++++++++++++++++ .../tools/ant/taskdefs/defaults.properties | 3 +- .../org/apache/tools/ant/BuildFileTest.java | 166 +++++++++------- .../ant/taskdefs/ManifestClassPathTest.java | 139 +++++++++++++ 8 files changed, 685 insertions(+), 73 deletions(-) create mode 100644 docs/manual/CoreTasks/manifestclasspath.html create mode 100644 src/etc/testcases/taskdefs/manifestclasspath.xml create mode 100644 src/main/org/apache/tools/ant/taskdefs/ManifestClassPath.java create mode 100644 src/testcases/org/apache/tools/ant/taskdefs/ManifestClassPathTest.java diff --git a/WHATSNEW b/WHATSNEW index 26c0871e8..a9a10d11b 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -163,6 +163,9 @@ Fixed bugs: Other changes: -------------- +* New task 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. diff --git a/docs/manual/CoreTasks/manifestclasspath.html b/docs/manual/CoreTasks/manifestclasspath.html new file mode 100644 index 000000000..0549ba8d4 --- /dev/null +++ b/docs/manual/CoreTasks/manifestclasspath.html @@ -0,0 +1,98 @@ + + + + + +ManifestClassPath Task + + + + +

Manifestclasspath

+ +

Description

+

Converts a Path into a property +whose value is appropriate for a Manifest's +Class-Path attribute.

+ +

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.

+ +

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 <manifest> element, where the +defined property is re-referenced.

+ +

since Ant 1.7

+ +

Parameters

+ + + + + + + + + + + + + + + + + + + + + +
AttributeDescriptionRequired
propertythe name of the property to set. This property must + not already be set.Yes
jarfile + 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. + Yes
maxParentLevels + 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.No
+ +

Parameters specified as nested elements

+

classpath

+

A Path-like element, which can be +defined in-place, or refer to a path defined elsewhere using the +<classpath refid="pathid" /> syntax. +This classpath must not be empty, and is required.

+ +

Examples

+
+
+    <manifestclasspath property="jar.classpath"
+                       jarfile="build/acme.jar">
+      <classpath refid="classpath" />
+    </manifestclasspath>
+  
+

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 <jar> with a nested + <manifest> element that lists an + <attribute name="Class-Path" value="${jar.classpath}" />. +

+
+ +
+

Copyright © 2005 The Apache Software Foundation. +All rights Reserved.

+ + + diff --git a/docs/manual/coretasklist.html b/docs/manual/coretasklist.html index 56f703146..b97e1c288 100644 --- a/docs/manual/coretasklist.html +++ b/docs/manual/coretasklist.html @@ -69,6 +69,7 @@ Mail
MacroDef
Manifest
+ManifestClassPath
Mkdir
Move
Nice
diff --git a/src/etc/testcases/taskdefs/manifestclasspath.xml b/src/etc/testcases/taskdefs/manifestclasspath.xml new file mode 100644 index 000000000..383785610 --- /dev/null +++ b/src/etc/testcases/taskdefs/manifestclasspath.xml @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/org/apache/tools/ant/taskdefs/ManifestClassPath.java b/src/main/org/apache/tools/ant/taskdefs/ManifestClassPath.java new file mode 100644 index 000000000..df53edcdc --- /dev/null +++ b/src/main/org/apache/tools/ant/taskdefs/ManifestClassPath.java @@ -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 !"); + } + + // 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; + } + +} diff --git a/src/main/org/apache/tools/ant/taskdefs/defaults.properties b/src/main/org/apache/tools/ant/taskdefs/defaults.properties index 44dfd69ba..ee0d59953 100644 --- a/src/main/org/apache/tools/ant/taskdefs/defaults.properties +++ b/src/main/org/apache/tools/ant/taskdefs/defaults.properties @@ -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 \ No newline at end of file +WsdlToDotnet=org.apache.tools.ant.taskdefs.optional.dotnet.WsdlToDotnet diff --git a/src/testcases/org/apache/tools/ant/BuildFileTest.java b/src/testcases/org/apache/tools/ant/BuildFileTest.java index 062aef263..4ad857f77 100644 --- a/src/testcases/org/apache/tools/ant/BuildFileTest.java +++ b/src/testcases/org/apache/tools/ant/BuildFileTest.java @@ -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()); - } } - } diff --git a/src/testcases/org/apache/tools/ant/taskdefs/ManifestClassPathTest.java b/src/testcases/org/apache/tools/ant/taskdefs/ManifestClassPathTest.java new file mode 100644 index 000000000..e65b16bf3 --- /dev/null +++ b/src/testcases/org/apache/tools/ant/taskdefs/ManifestClassPathTest.java @@ -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 !"); + 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 +