diff --git a/machine.js b/machine.js index 8b07a05b9..0a587c587 100644 --- a/machine.js +++ b/machine.js @@ -119,6 +119,10 @@ export function invoke(fn, ...transitions) { }); } +export let nested = (to, states) => invoke(createMachine(states, identity), + transition('done', to) +); + let machine = { get state() { return { @@ -172,6 +176,14 @@ function send(service, event) { } let service = { + matches(query) { + let states = query.split('.'), matched = false, service = this; + do { + matched = !!service && states.shift() === service.machine.current; + service = service.child; + } while(matched && states.length); + return matched; + }, send(event) { this.machine = send(this, event); diff --git a/test/test-invoke.js b/test/test-invoke.js index acac057b7..7cb4eec1c 100644 --- a/test/test-invoke.js +++ b/test/test-invoke.js @@ -1,4 +1,4 @@ -import { createMachine, immediate, interpret, invoke, reduce, state, state as final, transition } from '../machine.js'; +import { createMachine, immediate, interpret, invoke, nested, reduce, state, state as final, transition } from '../machine.js'; QUnit.module('Invoke', hooks => { QUnit.module('Promise'); @@ -275,4 +275,30 @@ QUnit.module('Invoke', hooks => { service.send('next'); }); + + QUnit.test('matches() matches the state', async assert => { + const machine = createMachine({ + one: state( + transition('next', 'two') + ), + two: nested('three', { + alpha: state( + transition('next', 'beta') + ), + beta: state() + }), + three: state() + }); + + let service = interpret(machine, () => {}); + assert.equal(service.matches('one'), true, 'is the first state'); + assert.equal(service.matches('two.alpha'), false, 'not in the child state'); + + service.send('next'); + assert.equal(service.matches('two'), true, 'is in the two state'); + assert.equal(service.matches('two.alpha'), true, 'in the alpha state'); + + service.child.send('next'); + assert.equal(service.matches('three'), true, 'In the last state'); + }); }); \ No newline at end of file