test_classes.js 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. //-----------------------------------------------------------------------------
  2. QUnit.module("classes");
  3. //-----------------------------------------------------------------------------
  4. test("prototype based state machine", function() {
  5. var myFSM = function() {
  6. this.counter = 42;
  7. this.startup();
  8. };
  9. myFSM.prototype = {
  10. onwarn: function() { this.counter++; }
  11. }
  12. StateMachine.create({
  13. target: myFSM.prototype,
  14. events: [
  15. { name: 'startup', from: 'none', to: 'green' },
  16. { name: 'warn', from: 'green', to: 'yellow' },
  17. { name: 'panic', from: 'yellow', to: 'red' },
  18. { name: 'clear', from: 'yellow', to: 'green' }
  19. ]
  20. });
  21. var a = new myFSM();
  22. var b = new myFSM();
  23. equal(a.current, 'green', 'start with correct state');
  24. equal(b.current, 'green', 'start with correct state');
  25. equal(a.counter, 42, 'start with correct counter');
  26. equal(b.counter, 42, 'start with correct counter');
  27. a.warn();
  28. equal(a.current, 'yellow', 'maintain independent current state');
  29. equal(b.current, 'green', 'maintain independent current state');
  30. equal(a.counter, 43, 'counter for (a) should have incremented');
  31. equal(b.counter, 42, 'counter for (b) should remain untouched');
  32. ok(a.hasOwnProperty('current'), "each instance should have its own current state");
  33. ok(b.hasOwnProperty('current'), "each instance should have its own current state");
  34. ok(!a.hasOwnProperty('warn'), "each instance should NOT have its own event methods");
  35. ok(!b.hasOwnProperty('warn'), "each instance should NOT have its own event methods");
  36. ok(a.warn === b.warn, "each instance should share event methods");
  37. ok(a.warn === a.__proto__.warn, "each instance event methods come from its shared prototype");
  38. ok(b.warn === b.__proto__.warn, "each instance event methods come from its shared prototype");
  39. });
  40. //-----------------------------------------------------------------------------
  41. test("github issue 19", function() {
  42. var Foo = function() {
  43. this.counter = 7;
  44. this.initFSM();
  45. };
  46. Foo.prototype.onenterready = function() { this.counter++; };
  47. Foo.prototype.onenterrunning = function() { this.counter++; };
  48. StateMachine.create({
  49. target : Foo.prototype,
  50. initial: { state: 'ready', event: 'initFSM', defer: true }, // unfortunately, trying to apply an IMMEDIATE initial state wont work on prototype based FSM, it MUST be deferred and called in the constructor for each instance
  51. events : [{name: 'execute', from: 'ready', to: 'running'},
  52. {name: 'abort', from: 'running', to: 'ready'}]
  53. });
  54. var foo = new Foo();
  55. var bar = new Foo();
  56. equal(foo.current, 'ready', 'start with correct state');
  57. equal(bar.current, 'ready', 'start with correct state');
  58. equal(foo.counter, 8, 'start with correct counter 7 (from constructor) + 1 (from onenterready)');
  59. equal(bar.counter, 8, 'start with correct counter 7 (from constructor) + 1 (from onenterready)');
  60. foo.execute(); // transition foo, but NOT bar
  61. equal(foo.current, 'running', 'changed state');
  62. equal(bar.current, 'ready', 'state remains the same');
  63. equal(foo.counter, 9, 'incremented counter during onenterrunning');
  64. equal(bar.counter, 8, 'counter remains the same');
  65. });