|
TestCase("SM", { |
|
"test SM API": function() { |
|
var sm = SM(); |
|
assertFunction(sm.event); |
|
}, |
|
|
|
"test SM transits between 2 states": function() { |
|
|
|
var open=function(){open.called=true;}, |
|
close=function(){close.called=true;}, |
|
sm = SM("closed", |
|
{ |
|
// When in closed state, if the event is "open!" then execute the open action and go to opened state. |
|
"closed":{"open!": [open, "opened"]}, |
|
// The opposite |
|
"opened":{ "close!": [close, "closed"]} |
|
}); |
|
|
|
assertUndefined(open.called); |
|
assertEquals("opened", sm.event("open!")); |
|
assertTrue(open.called); |
|
|
|
assertUndefined(close.called); |
|
assertEquals("closed", sm.event("close!")); |
|
assertTrue(close.called); |
|
|
|
}, |
|
|
|
"test SM doesn't crash if wrong event in given state": function() { |
|
var sm = SM("state", { |
|
"state": {"event": [function(){}, "nextState"]} |
|
}); |
|
assertUndefined(sm.event("crash!")); |
|
}, |
|
|
|
"test SM can pass arguments to the action": function () { |
|
var action = function(arg) {action.arg = arg; }, |
|
sm = SM("state", { |
|
"state": {"event": [action, "state2"]}, |
|
"state2": {"event": [action]} |
|
}), |
|
arg = {}, |
|
arg2 = {}; |
|
|
|
sm.event("event", arg); |
|
assertSame(arg, action.arg); |
|
sm.event("event", arg2); |
|
assertSame(arg2, action.arg); |
|
}, |
|
|
|
"test SM can run actions in given context": function () { |
|
var action = function() { action.ctx = this; }, |
|
ctx = {}, |
|
sm = SM("state", { |
|
"state": { "event": [[action, ctx], "nextState"]}}); |
|
|
|
sm.event("event"); |
|
assertSame(ctx, action.ctx); |
|
|
|
}, |
|
|
|
"test the whole diagram": function() { |
|
|
|
var alarm = function () { alarm.called = true; alarm.args = arguments; }, |
|
open = function () { open.called = true; open.args = arguments; }, |
|
thank = function () { thank.called = true; thank.args = arguments; }, |
|
close = function () { close.called = true; close.args = arguments; }, |
|
|
|
sm = SM("closed", { |
|
"closed": { |
|
"pass": [alarm], |
|
"coin": [open, "opened"] |
|
}, |
|
"opened": { |
|
"coin": [thank], |
|
"pass": [close, "closed"] |
|
} |
|
}); |
|
|
|
assertEquals("closed", sm.event("pass", "picture")); |
|
assertTrue(alarm.called); |
|
assertEquals("picture", alarm.args[0]); |
|
|
|
assertEquals("opened", sm.event("coin", "$2")); |
|
assertTrue(open.called); |
|
assertEquals("$2", open.args[0]); |
|
|
|
assertEquals("opened", sm.event("coin", "c50")); |
|
assertTrue(thank.called); |
|
assertEquals("c50", thank.args[0]); |
|
|
|
assertEquals("closed", sm.event("pass")); |
|
assertTrue(close.called); |
|
|
|
} |
|
|
|
}); |
this is awesome—thank you for sharing!