craigmcc 01/08/21 21:14:15
Modified: workflow build.xml
workflow/src/java/org/apache/commons/workflow/io
DisplayStep.java PeekStep.java
Added: workflow/src/test/org/apache/commons/workflow/io
IOExecuteTestCase.java
Log:
Add unit tests for the IO steps: get, peek, read, write.
The test for "get" (retrieves data from a URL and pushes it on the stack)
simply displays this value to system output, without trying to validate
it. The URL that is retrieved is defined by the "ioexecute.url" property,
and defaults to "http://localhost:8080/index.html", which is convenient if
you are running Tomcat (or some other servlet container) locally on that
port.
Revision Changes Path
1.6 +15 -2 jakarta-commons-sandbox/workflow/build.xml
Index: build.xml
===================================================================
RCS file: /home/cvs/jakarta-commons-sandbox/workflow/build.xml,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- build.xml 2001/08/19 23:53:10 1.5
+++ build.xml 2001/08/22 04:14:15 1.6
@@ -3,7 +3,7 @@
<!--
"Workflow" component of the Jakarta Commons Subproject
- $Id: build.xml,v 1.5 2001/08/19 23:53:10 craigmcc Exp $
+ $Id: build.xml,v 1.6 2001/08/22 04:14:15 craigmcc Exp $
-->
@@ -14,6 +14,8 @@
<property file="../build.properties"/> <!-- Commons local -->
<property file="${user.home}/build.properties"/> <!-- User local -->
+ <!-- The URL to be retrieved by the IOExecuteTestCase -->
+ <property name="ioexecute.url" value="http://localhost:8080/index.html"/>
<!-- ========== External Dependencies ===================================== -->
@@ -253,7 +255,8 @@
test.BaseActivity,
test.BaseContext,
test.BaseExecute,
- test.CoreExecute"
+ test.CoreExecute,
+ test.IOExecute"
description="Run all unit test cases">
</target>
@@ -291,6 +294,16 @@
<java classname="${test.runner}" fork="yes"
failonerror="${test.failonerror}">
<arg value="org.apache.commons.workflow.core.CoreExecuteTestCase"/>
+ <classpath refid="test.classpath"/>
+ </java>
+ </target>
+
+ <target name="test.IOExecute">
+ <echo message="Running IOExecute tests ..."/>
+ <java classname="${test.runner}" fork="yes"
+ failonerror="${test.failonerror}">
+ <sysproperty key="ioexecute.url" value="${ioexecute.url}"/>
+ <arg value="org.apache.commons.workflow.io.IOExecuteTestCase"/>
<classpath refid="test.classpath"/>
</java>
</target>
1.3 +42 -19
jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/io/DisplayStep.java
Index: DisplayStep.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/io/DisplayStep.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- DisplayStep.java 2001/08/22 01:06:09 1.2
+++ DisplayStep.java 2001/08/22 04:14:15 1.3
@@ -1,7 +1,7 @@
/*
- * $Header:
/home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/io/DisplayStep.java,v
1.2 2001/08/22 01:06:09 craigmcc Exp $
- * $Revision: 1.2 $
- * $Date: 2001/08/22 01:06:09 $
+ * $Header:
/home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/io/DisplayStep.java,v
1.3 2001/08/22 04:14:15 craigmcc Exp $
+ * $Revision: 1.3 $
+ * $Date: 2001/08/22 04:14:15 $
*
* ====================================================================
*
@@ -62,6 +62,7 @@
package org.apache.commons.workflow.io;
+import org.apache.commons.jpath.JPathContext;
import org.apache.commons.workflow.Context;
import org.apache.commons.workflow.StepException;
import org.apache.commons.workflow.base.BaseStep;
@@ -80,9 +81,12 @@
* in the specified scope.</li>
* <li><strong>scope</strong> - Identifier of the scope in which to search for
* this bean, or omitted to search for the bean in any scope.</li>
+ * <li><strong>xpath</strong> - XPath expression identifying the specified
+ * bean or bean property, relative to the local Scope of our execution
+ * Context.</li>
* </ul>
*
- * @version $Revision: 1.2 $ $Date: 2001/08/22 01:06:09 $
+ * @version $Revision: 1.3 $ $Date: 2001/08/22 04:14:15 $
* @author Craig R. McClanahan
*/
@@ -121,13 +125,15 @@
* @param id Step identifier
* @param name Bean name
* @param scope Scope name
+ * @param xpath Xpath expression
*/
- public DisplayStep(String id, String name, String scope) {
+ public DisplayStep(String id, String name, String scope, String xpath) {
super();
setId(id);
setName(name);
setScope(scope);
+ setXpath(xpath);
}
@@ -163,6 +169,20 @@
}
+ /**
+ * The XPath expression identifying the specified bean.
+ */
+ protected String xpath = null;
+
+ public String getXpath() {
+ return (this.xpath);
+ }
+
+ public void setXpath(String xpath) {
+ this.xpath = xpath;
+ }
+
+
// --------------------------------------------------------- Public Methods
@@ -176,23 +196,26 @@
*/
public void execute(Context context) throws StepException {
- // Identify the scope we are interested in
- int scopeId = -1;
- if (scope != null) {
- scopeId = context.getScopeId(scope);
- if (scopeId < 0)
- throw new StepException("Cannot find scope '" + scope + "'",
- this);
- }
-
// Retrieve the specified bean value
Object value = null;
- if (scopeId < 0)
- value = context.get(name);
- else
- value = context.get(name, scopeId);
+ if (xpath != null) {
+ JPathContext jpc = context.getJPathContext();
+ value = jpc.getValue("local/" + xpath);
+ } else {
+ if (scope == null) {
+ value = context.get(name);
+ } else {
+ int scopeId = context.getScopeId(scope);
+ if (scopeId < 0)
+ throw new StepException
+ ("Cannot find scope '" + scope + "'", this);
+ value = context.get(name, scopeId);
+ }
+ }
if (value == null)
- throw new StepException("Cannot find bean '" + name + "'", this);
+ throw new StepException("Cannot find bean '" +
+ (xpath != null ? xpath : name) + "'",
+ this);
// Write the bean value to standard output
System.out.println(value);
1.3 +6 -6
jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/io/PeekStep.java
Index: PeekStep.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/io/PeekStep.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- PeekStep.java 2001/08/22 01:06:09 1.2
+++ PeekStep.java 2001/08/22 04:14:15 1.3
@@ -1,7 +1,7 @@
/*
- * $Header:
/home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/io/PeekStep.java,v
1.2 2001/08/22 01:06:09 craigmcc Exp $
- * $Revision: 1.2 $
- * $Date: 2001/08/22 01:06:09 $
+ * $Header:
/home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/io/PeekStep.java,v
1.3 2001/08/22 04:14:15 craigmcc Exp $
+ * $Revision: 1.3 $
+ * $Date: 2001/08/22 04:14:15 $
*
* ====================================================================
*
@@ -75,7 +75,7 @@
* <p><strong>WARNING</strong> - This will probably be
* replaced later by a more general purpose input/output mechanism.</p>
*
- * @version $Revision: 1.2 $ $Date: 2001/08/22 01:06:09 $
+ * @version $Revision: 1.3 $ $Date: 2001/08/22 04:14:15 $
* @author Craig R. McClanahan
*/
@@ -121,10 +121,10 @@
*/
public void execute(Context context) throws StepException {
- // Retrieve the top value from the evaluation stack
+ // Retrieve a copy of the top value from the evaluation stack
Object value = null;
try {
- value = context.pop();
+ value = context.peek();
} catch (EmptyStackException e) {
throw new StepException("Evaluation stack is empty", e, this);
}
1.1
jakarta-commons-sandbox/workflow/src/test/org/apache/commons/workflow/io/IOExecuteTestCase.java
Index: IOExecuteTestCase.java
===================================================================
/*
* $Header:
/home/cvs/jakarta-commons-sandbox/workflow/src/test/org/apache/commons/workflow/io/IOExecuteTestCase.java,v
1.1 2001/08/22 04:14:15 craigmcc Exp $
* $Revision: 1.1 $
* $Date: 2001/08/22 04:14:15 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.workflow.io;
import java.io.File;
import java.util.EmptyStackException;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.apache.commons.workflow.Activity;
import org.apache.commons.workflow.Context;
import org.apache.commons.workflow.ContextEvent;
import org.apache.commons.workflow.ContextListener;
import org.apache.commons.workflow.Scope;
import org.apache.commons.workflow.Step;
import org.apache.commons.workflow.StepException;
import org.apache.commons.workflow.base.BaseActivity;
import org.apache.commons.workflow.base.BaseContext;
import org.apache.commons.workflow.base.BaseScope;
import org.apache.commons.workflow.core.PopStep;
import org.apache.commons.workflow.core.StringStep;
/**
* <p>Test Case for the <code>io</code> library of <code>Step</code>
* implementations.</p>
*
* @author Craig R. McClanahan
* @version $Revision: 1.1 $ $Date: 2001/08/22 04:14:15 $
*/
public class IOExecuteTestCase extends TestCase
implements ContextListener {
// ----------------------------------------------------- Instance Variables
/**
* The Activity we will use to contain the Steps that we will execute.
*/
protected Activity activity = null;
/**
* The Context we will use to execute the Activity under test.
*/
protected Context context = null;
/**
* The trail of execution, as recorded by our ContextListener methods.
*/
protected StringBuffer trail = new StringBuffer();
// ----------------------------------------------------------- Constructors
/**
* Construct a new instance of this test case.
*
* @param name Name of the test case
*/
public IOExecuteTestCase(String name) {
super(name);
}
// --------------------------------------------------- Overall Test Methods
/**
* Set up instance variables required by this test case.
*/
public void setUp() {
context = new BaseContext();
activity = new BaseActivity();
context.setActivity(activity);
context.addContextListener(this);
}
/**
* Return the tests included in this test suite.
*/
public static Test suite() {
return (new TestSuite(IOExecuteTestCase.class));
}
/**
* Tear down instance variables required by this test case.
*/
public void tearDown() {
context.removeContextListener(this);
activity = null;
context = null;
}
// ------------------------------------------------ Individual Test Methods
/**
* Get and display steps. This test depends on a URL being specified
* by the <code>ioexecute.url</code> system property, and that this
* URL can be successfully retrieved via a <code>URLConnection</code>.
* No validation of the retrieved content is performed - it is merely
* displayed to system output with the <code>peek</code> command.
*/
public void testGetDisplay() {
// Identify the URL path we will be accessing
String url = System.getProperty("ioexecute.url");
assertNotNull("The 'ioexecute.url' system property is set");
// Configure the steps in this activity
activity.addStep(new GetStep("01", url));
activity.addStep(new PeekStep("02"));
activity.addStep(new PopStep("03"));
// Execute the activity and validate results
try {
context.execute();
assertEquals("Trail contents",
"beforeActivity()/" +
"beforeStep(01)/afterStep(01)/" +
"beforeStep(02)/afterStep(02)/" +
"beforeStep(03)/afterStep(03)/" +
"afterActivity()/",
trail.toString());
assertTrue("Stack is empty",
context.isEmpty());
assertTrue("Context was not suspended",
!context.getSuspend());
} catch (StepException e) {
e.printStackTrace(System.out);
if (e.getCause() != null) {
System.out.println("ROOT CAUSE");
e.getCause().printStackTrace(System.out);
}
fail("Threw StepException " + e);
} catch (Throwable e) {
e.printStackTrace();
fail("Threw exception " + e);
}
}
/**
* Read and write steps.
*/
public void testReadWrite() {
// Identify a temporary file that we can manipulate
File file = null;
String path = null;
try {
file = File.createTempFile("IOExecuteTestCase", ".txt");
path = file.getAbsolutePath();
file.delete();
} catch (Throwable t) {
fail("File create threw " + t);
}
// Configure the steps in this activity
activity.addStep
(new StringStep("01", "This is a test. It is only a test."));
activity.addStep(new WriteStep("02", null, path));
activity.addStep(new ReadStep("03", null, path));
// Execute the activity and validate results
try {
context.execute();
assertEquals("Trail contents",
"beforeActivity()/" +
"beforeStep(01)/afterStep(01)/" +
"beforeStep(02)/afterStep(02)/" +
"beforeStep(03)/afterStep(03)/" +
"afterActivity()/",
trail.toString());
assertTrue("Stack is not empty",
!context.isEmpty());
assertEquals("Retrieved written content",
"This is a test. It is only a test.",
(String) context.pop());
assertTrue("Stack is empty",
context.isEmpty());
assertTrue("Context was not suspended",
!context.getSuspend());
} catch (StepException e) {
e.printStackTrace(System.out);
if (e.getCause() != null) {
System.out.println("ROOT CAUSE");
e.getCause().printStackTrace(System.out);
}
fail("Threw StepException " + e);
} catch (Throwable e) {
e.printStackTrace();
fail("Threw exception " + e);
} finally {
file.delete();
}
}
// ------------------------------------------------ ContextListener Methods
/**
* Invoked immediately after execution of the related Activity has
* been completed normally, been suspended, or been aborted by
* the throwing of a StepException. The Step included in this event
* will be the last one to be executed.
*
* @param event The <code>ContextEvent</code> that has occurred
*/
public void afterActivity(ContextEvent event) {
trail.append("afterActivity()/");
}
/**
* Invoked immediately after the specified Step was executed.
*
* @param event The <code>ContextEvent</code> that has occurred
*/
public void afterStep(ContextEvent event) {
trail.append("afterStep(");
trail.append(event.getStep().getId());
trail.append(")");
/*
StepException exception = event.getException();
if (exception != null) {
trail.append("-");
trail.append(exception.toString());
}
*/
trail.append("/");
}
/**
* Invoked immediately before execution of the related Activity has
* started. The Step included in this event will be the first one
* to be executed.
*
* @param event The <code>ContextEvent</code> that has occurred
*/
public void beforeActivity(ContextEvent event) {
trail.setLength(0);
trail.append("beforeActivity()/");
}
/**
* Invoked immediately before the specified Step is executed.
*
* @param event The <code>ContextEvent</code> that has occurred
*/
public void beforeStep(ContextEvent event) {
trail.append("beforeStep(");
trail.append(event.getStep().getId());
trail.append(")/");
}
}