Skip to content

Commit

Permalink
Allow any event to be raised (#952)
Browse files Browse the repository at this point in the history
* Allow any event to be raised. Fixes #949

* Add changeset

* Simplify tests
  • Loading branch information
davidkpiano authored and Andarist committed Jan 18, 2020
1 parent 16c21d2 commit 2a3fea1
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 92 deletions.
5 changes: 5 additions & 0 deletions .changeset/neat-files-switch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'xstate': patch
---

The typings for the raise() action have been fixed to allow any event to be raised. This typed behavior will be refined in version 5, to limit raised events to those that the machine accepts.
2 changes: 1 addition & 1 deletion packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export type Action<TContext, TEvent extends EventObject> =
| ActionFunction<TContext, TEvent>
| AssignAction<Required<TContext>, TEvent>
| SendAction<TContext, TEvent>
| RaiseAction<TEvent>;
| RaiseAction<AnyEventObject>;

export type Actions<TContext, TEvent extends EventObject> = SingleOrArray<
Action<TContext, TEvent>
Expand Down
152 changes: 61 additions & 91 deletions packages/core/test/types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,103 +202,73 @@ describe('Nested parallel stateSchema', () => {
});

describe('Raise events', () => {
interface GreetingStateSchema {
states: {
pending: {};
morning: {};
lunchTime: {};
afternoon: {};
evening: {};
night: {};
};
}
it('should work with all the ways to raise events', () => {
interface GreetingStateSchema {
states: {
pending: {};
morning: {};
lunchTime: {};
afternoon: {};
evening: {};
night: {};
};
}

type GreetingEvent =
| { type: 'DECIDE' }
| { type: 'MORNING' }
| { type: 'LUNCH_TIME' }
| { type: 'AFTERNOON' }
| { type: 'EVENING' }
| { type: 'NIGHT' };
type GreetingEvent =
| { type: 'DECIDE' }
| { type: 'MORNING' }
| { type: 'LUNCH_TIME' }
| { type: 'AFTERNOON' }
| { type: 'EVENING' }
| { type: 'NIGHT' };

interface GreetingContext {
hour: number;
}
interface GreetingContext {
hour: number;
}

const greetingContext: GreetingContext = { hour: 10 };
const greetingContext: GreetingContext = { hour: 10 };

const raiseGreetingMachine = Machine<
GreetingContext,
GreetingStateSchema,
GreetingEvent
>({
key: 'greeting',
context: greetingContext,
initial: 'pending',
states: {
pending: {
on: {
DECIDE: [
{
// This one does not work
actions: raise<GreetingContext, { type: 'MORNING' }>({
type: 'MORNING'
}),
cond: ctx => ctx.hour < 12
},
{
// This one does work which makes me wonder what the second type
// argument of type should be. I thought the event type that is
// raised should be passed ('LUNCH_TIME') or is it like the
// assign() API where we want the event that caused the action to
// be executed?
actions: raise<
GreetingContext,
{ type: 'DECIDE' } | { type: 'LUNCH_TIME' }
>({
type: 'LUNCH_TIME'
}),
cond: ctx => ctx.hour === 12
},
{
// Does not work
actions: raise<GreetingContext, { type: 'AFTERNOON' }>(
'AFTERNOON'
),
cond: ctx => ctx.hour < 18
},
{
// Does not work
actions: raise({ type: 'EVENING' }),
cond: ctx => ctx.hour < 22
},
{
// Works and fixes the type errors for the others too.
// Uncomment next line to see them pass :o
// actions: raise('NIGHT'),
cond: ctx => ctx.hour < 24
}
]
}
const raiseGreetingMachine = Machine<
GreetingContext,
GreetingStateSchema,
GreetingEvent
>({
key: 'greeting',
context: greetingContext,
initial: 'pending',
states: {
pending: {
on: {
DECIDE: [
{
actions: raise<GreetingContext, { type: 'MORNING' }>({
type: 'MORNING'
}),
cond: ctx => ctx.hour < 12
},
{
actions: raise({ type: 'EVENING' }),
cond: ctx => ctx.hour < 22
}
]
}
},
morning: {},
lunchTime: {},
afternoon: {},
evening: {},
night: {}
},
morning: {},
lunchTime: {},
afternoon: {},
evening: {},
night: {}
},
on: {
MORNING: '.morning',
LUNCH_TIME: '.lunchTime',
AFTERNOON: '.afternoon',
EVENING: '.evening',
NIGHT: '.night'
}
});

noop(raiseGreetingMachine);
on: {
MORNING: '.morning',
LUNCH_TIME: '.lunchTime',
AFTERNOON: '.afternoon',
EVENING: '.evening',
NIGHT: '.night'
}
});

it('should work with all the ways to raise events', () => {
noop(raiseGreetingMachine);
expect(true).toBeTruthy();
});
});

0 comments on commit 2a3fea1

Please sign in to comment.