001: // Modified or written by Object Mentor, Inc. for inclusion with FitNesse.
002: // Copyright (c) 2002 Cunningham & Cunningham, Inc.
003: // Released under the terms of the GNU General Public License version 2 or later.package fit;
004:
005: package fit;
006:
007: import java.lang.reflect.Method;
008: import fit.exception.*;
009:
010: public class ActionFixture extends Fixture {
011: protected Parse cells;
012: public static Fixture actor;
013: protected static Class empty[] = {};
014:
015: // Traversal ////////////////////////////////
016:
017: public void doCells(Parse cells) {
018: this .cells = cells;
019: try {
020: Method action = getClass().getMethod(cells.text(), empty);
021: action.invoke(this );
022: } catch (Exception e) {
023: exception(cells, e);
024: }
025: }
026:
027: // Actions //////////////////////////////////
028:
029: public void start() throws Throwable {
030: Parse fixture = cells.more;
031: if (fixture == null)
032: throw new FitFailureException(
033: "You must specify a fixture to start.");
034: actor = loadFixture(fixture.text());
035: }
036:
037: public void enter() throws Exception {
038: Method method = method(1);
039: Class type = method.getParameterTypes()[0];
040: final Parse argumentCell = cells.more.more;
041: if (argumentCell == null)
042: throw new FitFailureException(
043: "You must specify an argument.");
044: String text = argumentCell.text();
045: Object[] args;
046: try {
047: args = new Object[] { TypeAdapter.on(actor, type).parse(
048: text) };
049: } catch (NumberFormatException e) {
050: throw new CouldNotParseFitFailureException(text, type
051: .getName());
052: }
053: method.invoke(actor, args);
054: }
055:
056: public void press() throws Exception {
057: method(0).invoke(actor);
058: }
059:
060: public void check() throws Throwable {
061: TypeAdapter adapter;
062: Method theMethod = method(0);
063: Class type = theMethod.getReturnType();
064: try {
065: adapter = TypeAdapter.on(actor, theMethod);
066: } catch (Throwable e) {
067: throw new FitFailureException("Can not parse return type: "
068: + type.getName());
069: }
070: Parse checkValueCell = cells.more.more;
071: if (checkValueCell == null)
072: throw new FitFailureException(
073: "You must specify a value to check.");
074:
075: check(checkValueCell, adapter);
076: }
077:
078: // Utility //////////////////////////////////
079:
080: protected Method method(int args) throws NoSuchMethodException {
081: final Parse methodCell = cells.more;
082: if (methodCell == null)
083: throw new FitFailureException("You must specify a method.");
084: return method(camel(methodCell.text()), args);
085: }
086:
087: protected Method method(String test, int args)
088: throws NoSuchMethodException {
089: if (actor == null)
090: throw new FitFailureException(
091: "You must start a fixture using the 'start' keyword.");
092: Method methods[] = actor.getClass().getMethods();
093: Method result = null;
094: for (int i = 0; i < methods.length; i++) {
095: Method m = methods[i];
096: if (m.getName().equals(test)
097: && m.getParameterTypes().length == args) {
098: if (result == null) {
099: result = m;
100: } else {
101: throw new FitFailureException(
102: "You can only have one " + test
103: + "(arg) method in your fixture.");
104: }
105: }
106: }
107: if (result == null) {
108: throw new NoSuchMethodFitFailureException(test);
109: }
110: return result;
111: }
112: }
|