diff --git a/mod_test.ts b/mod_test.ts index b7abe1f..0022885 100644 --- a/mod_test.ts +++ b/mod_test.ts @@ -1,9 +1,16 @@ import { assertEquals } from "https://deno.land/std/testing/asserts.ts"; import { motor, MotorSpec } from "./mod.ts"; -type Gears = "stopped" | "paused" | "playing" | "loading"; +type Gears = "stopped" | "paused" | "playing" | "playing.skipping" | "loading"; -type Events = "SELECT" | "LOAD" | "PLAY" | "PAUSE" | "STOP"; +type Events = + | "SELECT" + | "LOAD" + | "PLAY" + | "PAUSE" + | "STOP" + | "SKIP_START" + | "SKIP_END"; const musicPlayerMotor: MotorSpec = { gear: "stopped", @@ -18,7 +25,10 @@ const musicPlayerMotor: MotorSpec = { on: { PLAY: "playing", STOP: "stopped" }, }, playing: { - on: { PAUSE: "paused", STOP: "stopped" }, + on: { PAUSE: "paused", STOP: "stopped", SKIP_START: "playing.skipping" }, + }, + "playing.skipping": { + on: { SKIP_END: "playing" }, }, }, }; @@ -67,3 +77,21 @@ Deno.test("Calls hooked functions to changes in gear", () => { assertEquals(counter, 3); }); + +Deno.test("Should support heirarchical state nodes", () => { + const { fire, gear, matches } = motor(musicPlayerMotor); + + fire("LOAD"); + + assertEquals(gear(), "loading"); + + fire("PLAY"); + + assertEquals(gear(), "playing"); + + fire("SKIP_START"); + + assertEquals(matches("playing"), true); + assertEquals(matches("playing.skipping"), true); + assertEquals(matches("loading"), false); +}); diff --git a/src/index.ts b/src/index.ts index e2c7a82..22da8a9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,6 +10,7 @@ export const motor = ( transmission.push(e); }, gear: () => _gear, + matches: (gear: G) => _gear.includes(gear), fire: (event: E) => { if (event) { const toGear = machine.transmission[_gear].on[event] ?? "";