Index: /home/marcos/workspaces/test/jmock2/src/org/jmock/Assert.java =================================================================== --- /home/marcos/workspaces/test/jmock2/src/org/jmock/Assert.java (revision 0) +++ /home/marcos/workspaces/test/jmock2/src/org/jmock/Assert.java (revision 0) @@ -0,0 +1,23 @@ +package org.jmock; + +import junit.framework.AssertionFailedError; + +import org.hamcrest.Factory; +import org.hamcrest.Matcher; +import org.jmock.internal.StatePredicate; + + +public class Assert { + + @Factory public static Matcher isCurrently(String state) { + return new IsCurrently(state); + } + + @Factory public static Matcher isNotCurrently(String state) { + return new IsNotCurrently(state); + } +} Index: /home/marcos/workspaces/test/jmock2/src/org/jmock/internal/StateMachine.java =================================================================== --- /home/marcos/workspaces/test/jmock2/src/org/jmock/internal/StateMachine.java (revision 1280) +++ /home/marcos/workspaces/test/jmock2/src/org/jmock/internal/StateMachine.java (working copy) @@ -3,14 +3,15 @@ import org.hamcrest.Description; import org.jmock.States; + public class StateMachine implements States { private final String name; private String currentState = null; public StateMachine(String name) { this.name = name; } public States startsAs(String initialState) { become(initialState); return this; @@ -15,7 +16,7 @@ become(initialState); return this; } public void become(String nextState) { currentState = nextState; } @@ -31,11 +32,12 @@ } public void describeTo(Description description) { - description.appendText(name).appendText(" is ").appendText(state); + description.appendText(name).appendText(" is ") + .appendText(state); } }; } public StatePredicate isNot(final String state) { return new StatePredicate() { public boolean isActive() { @@ -43,13 +45,21 @@ } public void describeTo(Description description) { - description.appendText(name).appendText(" is not ").appendText(state); + description.appendText(name).appendText(" is not ") + .appendText(state); } }; } public void describeTo(Description description) { description.appendText(name) - .appendText(currentState == null ? " has no current state" : (" is " + currentState)); + .appendText( + currentState == null ? " has no current state" + : (" is " + currentState)); + } + + public String toString() { + return currentState; } + } Index: /home/marcos/workspaces/test/jmock2/src/org/jmock/IsCurrently.java =================================================================== --- /home/marcos/workspaces/test/jmock2/src/org/jmock/IsCurrently.java (revision 0) +++ /home/marcos/workspaces/test/jmock2/src/org/jmock/IsCurrently.java (revision 0) @@ -0,0 +1,27 @@ +package org.jmock; + +import org.hamcrest.Description; +import org.hamcrest.TypeSafeMatcher; + + +public class IsCurrently extends TypeSafeMatcher { + private String state; + + public IsCurrently(String state) { + this.state = state; + } + + // public boolean matches(Object item) { + // if (!item.getClass().equals(String.class)) throw new + // IllegalArgumentException(); + // return machine.is((String)item).isActive(); + // } + + @Override public boolean matchesSafely(States machine) { + return machine.is(state).isActive(); + } + + public void describeTo(Description description) { + description.appendText("<").appendText(state).appendText(">"); + } +} Index: /home/marcos/workspaces/test/jmock2/src/org/jmock/IsNotCurrently.java =================================================================== --- /home/marcos/workspaces/test/jmock2/src/org/jmock/IsNotCurrently.java (revision 0) +++ /home/marcos/workspaces/test/jmock2/src/org/jmock/IsNotCurrently.java (revision 0) @@ -0,0 +1,21 @@ +package org.jmock; + +import org.hamcrest.Description; +import org.hamcrest.TypeSafeMatcher; + + +public class IsNotCurrently extends TypeSafeMatcher { + private String state; + + public IsNotCurrently(String state) { + this.state = state; + } + + @Override public boolean matchesSafely(States machine) { + return machine.isNot(state).isActive(); + } + + public void describeTo(Description description) { + description.appendText("Not <").appendText(state).appendText(">"); + } +} Index: /home/marcos/workspaces/test/jmock2/src/org/jmock/Assert.java =================================================================== --- /home/marcos/workspaces/test/jmock2/src/org/jmock/Assert.java (revision 0) +++ /home/marcos/workspaces/test/jmock2/src/org/jmock/Assert.java (revision 0) @@ -0,0 +1,22 @@ +package org.jmock; + +import junit.framework.AssertionFailedError; + +import org.hamcrest.Factory; +import org.hamcrest.Matcher; +import org.jmock.internal.StatePredicate; + +public class Assert { + + public static void assertStateMachine(StatePredicate state) { + if (!state.isActive()) throw new AssertionFailedError(); + } + + @Factory public static Matcher isCurrently(String state) { + return new IsCurrently(state); + } + + @Factory public static Matcher isNotCurrently(String state) { + return new IsNotCurrently(state); + } +} Index: /home/marcos/workspaces/test/jmock2/src/org/jmock/internal/StateMachine.java =================================================================== --- /home/marcos/workspaces/test/jmock2/src/org/jmock/internal/StateMachine.java (revision 1280) +++ /home/marcos/workspaces/test/jmock2/src/org/jmock/internal/StateMachine.java (working copy) @@ -49,7 +49,14 @@ } public void describeTo(Description description) { - description.appendText(name) - .appendText(currentState == null ? " has no current state" : (" is " + currentState)); + description.appendText(toString()); + } + + public String toString() { + return name + (currentState == null ? " has no current state" : (" is " + currentState)); } + + public String getName() { + return name; + } } Index: /home/marcos/workspaces/test/jmock2/src/org/jmock/IsCurrently.java =================================================================== --- /home/marcos/workspaces/test/jmock2/src/org/jmock/IsCurrently.java (revision 0) +++ /home/marcos/workspaces/test/jmock2/src/org/jmock/IsCurrently.java (revision 0) @@ -0,0 +1,24 @@ +package org.jmock; + +import org.hamcrest.Description; +import org.hamcrest.TypeSafeMatcher; + + +public class IsCurrently extends TypeSafeMatcher { + private String state; + private States machine; + + public IsCurrently(String state) { + this.state = state; + } + + public boolean matchesSafely(States states) { + machine = states; + if (state == null) return false; + return machine.is(state).isActive(); + } + + public void describeTo(Description description) { + description.appendText(machine.getName() + " to be " + state); + } +} Index: /home/marcos/workspaces/test/jmock2/src/org/jmock/IsNotCurrently.java =================================================================== --- /home/marcos/workspaces/test/jmock2/src/org/jmock/IsNotCurrently.java (revision 0) +++ /home/marcos/workspaces/test/jmock2/src/org/jmock/IsNotCurrently.java (revision 0) @@ -0,0 +1,24 @@ +package org.jmock; + +import org.hamcrest.Description; +import org.hamcrest.TypeSafeMatcher; + + +public class IsNotCurrently extends TypeSafeMatcher { + private String state; + private States machine; + + public IsNotCurrently(String state) { + this.state = state; + } + + public boolean matchesSafely(States states) { + machine = states; + if (state == null) return false; + return machine.isNot(state).isActive(); + } + + public void describeTo(Description description) { + description.appendText(machine.getName() + " to not be " + state); + } +} Index: /home/marcos/workspaces/test/jmock2/src/org/jmock/States.java =================================================================== --- /home/marcos/workspaces/test/jmock2/src/org/jmock/States.java (revision 1280) +++ /home/marcos/workspaces/test/jmock2/src/org/jmock/States.java (working copy) @@ -28,4 +28,12 @@ * The next state of the state machine. */ void become(String nextState); + + /** + * Get the name of the state machine. + * + * @return + * The name. + */ + String getName(); } Index: /home/marcos/workspaces/test/jmock2/test/org/jmock/test/acceptance/IsCurrentlyAcceptanceTests.java =================================================================== --- /home/marcos/workspaces/test/jmock2/test/org/jmock/test/acceptance/IsCurrentlyAcceptanceTests.java (revision 0) +++ /home/marcos/workspaces/test/jmock2/test/org/jmock/test/acceptance/IsCurrentlyAcceptanceTests.java (revision 0) @@ -0,0 +1,39 @@ +package org.jmock.test.acceptance; + +import static org.hamcrest.Matchers.endsWith; +import static org.jmock.Assert.isCurrently; + +import static org.junit.Assert.assertThat; + +import junit.framework.TestCase; + +import org.jmock.Mockery; +import org.jmock.States; +import org.jmock.test.unit.support.AssertThat; + + +public class IsCurrentlyAcceptanceTests extends TestCase { + Mockery context = new Mockery(); + + public void testPassesOnCorrectState() { + final States statMach = context.states("statMach").startsAs("metalic"); + + assertThat(statMach, isCurrently("metalic")); + } + + public void testFailsOnIncorrectState() { + final States statMach = context.states("statMach").startsAs("metalic"); + + try { + assertThat(statMach, isCurrently("wood")); + fail("should have thrown AssertionError"); + } + catch (AssertionError e) { + String errString = e.toString(); + AssertThat.stringIncludes("should describe statMach state", + "statMach is metalic", errString); + AssertThat.stringIncludes("should describe expected state", + "statMach to be wood", errString); + } + } +} Index: /home/marcos/workspaces/test/jmock2/test/org/jmock/test/acceptance/IsNotCurrentlyAcceptanceTests.java =================================================================== --- /home/marcos/workspaces/test/jmock2/test/org/jmock/test/acceptance/IsNotCurrentlyAcceptanceTests.java (revision 0) +++ /home/marcos/workspaces/test/jmock2/test/org/jmock/test/acceptance/IsNotCurrentlyAcceptanceTests.java (revision 0) @@ -0,0 +1,38 @@ +package org.jmock.test.acceptance; + +import static org.jmock.Assert.isNotCurrently; + +import static org.junit.Assert.assertThat; + +import junit.framework.TestCase; + +import org.jmock.Mockery; +import org.jmock.States; +import org.jmock.test.unit.support.AssertThat; + + +public class IsNotCurrentlyAcceptanceTests extends TestCase { + Mockery context = new Mockery(); + + public void testPassesOnCorrectState() { + final States theState = context.states("theState").startsAs("pass"); + + assertThat(theState, isNotCurrently("fail")); + } + + public void testFailsOnIncorrectState() { + final States machStat = context.states("machStat").startsAs("metalic"); + + try { + assertThat(machStat, isNotCurrently("metalic")); + fail("should have thrown AssertionError"); + } + catch (AssertionError e) { + String errString = e.toString(); + AssertThat.stringIncludes("should describe machStat state", + "machStat is metalic", errString); + AssertThat.stringIncludes("should describe expected state", + "machStat to not be metalic", errString); + } + } +}