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