Skip to content

Commit

Permalink
Merge pull request #3036 from statelyai/davidkpiano/xstate-test-1
Browse files Browse the repository at this point in the history
[@xstate/test] Next version low-level API
  • Loading branch information
Andarist authored May 30, 2022
2 parents fd3a4e9 + ae673e4 commit 8a101dc
Show file tree
Hide file tree
Showing 41 changed files with 4,065 additions and 11,161 deletions.
8 changes: 8 additions & 0 deletions .changeset/curly-windows-burn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@xstate/graph': major
---

pr: #3036
@author: @davidkpiano

Renamed `getAdjacencyMap` to `getValueAdjacencyMap`.
10 changes: 10 additions & 0 deletions .changeset/curly-windows-learn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@xstate/graph': major
---

pr: #3036
@author: @davidkpiano

Changed `getSimplePaths` to `getSimplePlans`, and `getShortestPaths` to `getShortestPlans`. Both of these functions can be passed a machine, and return `StatePlan[]`.

Added functions `traverseSimplePlans`, `traverseShortestPlans`,`traverseShortestPlansFromTo`, `traverseSimplePlansTo` and `traverseSimplePlansFromTo`, which can be passed a `Behavior` and return `StatePlan[]`.
12 changes: 12 additions & 0 deletions .changeset/great-lions-buy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
'@xstate/test': major
---

pr: #3036

@author: @mattpocock
@author: @davidkpiano

Substantially simplified how paths and plans work in `TestModel`. Changed `getShortestPlans` and `getSimplePlans` to `getShortestPaths` and `getSimplePaths`. These functions now return an array of paths, instead of an array of plans which contain paths.

Also added `getPaths`, which defaults to `getShortestPaths`. This can be passed a `pathGenerator` to customize how paths are generated.
37 changes: 37 additions & 0 deletions .changeset/lazy-turtles-brand.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
'@xstate/test': major
---

pr: #3036
@author: @mattpocock

Moved event cases out of `events`, and into their own attribute called `eventCases`:

```ts
const model = createTestModel(machine, {
eventCases: {
CHOOSE_CURRENCY: [
{
currency: 'GBP'
},
{
currency: 'USD'
}
]
}
});

model.getPaths().forEach((path) => {
it(path.description, async () => {
await path.test({
events: {
CHOOSE_CURRENCY: ({ event }) => {
console.log(event.currency);
}
}
});
});
});
```

`eventCases` will also now always produce a new path, instead of only creating a path for the first case which matches.
8 changes: 8 additions & 0 deletions .changeset/lazy-turtles-bread.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@xstate/test': major
---

pr: #3036
@author: @davidkpiano

Removed `.testCoverage()`, and instead made `getPlans`, `getShortestPlans` and `getSimplePlans` cover all states and transitions enabled by event cases by default.
10 changes: 10 additions & 0 deletions .changeset/lazy-turtles-grand.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@xstate/test': major
---

pr: #3036
@author: @davidkpiano

Added validation on `createTestModel` to ensure that you don't include invalid machine configuration in your test machine. Invalid machine configs include `invoke`, `after`, and any actions with a `delay`.

Added `createTestMachine`, which provides a slimmed-down API for creating machines which removes these types from the config type signature.
47 changes: 47 additions & 0 deletions .changeset/lazy-turtles-grate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
'@xstate/test': major
---

pr: #3036
@author: @davidkpiano

`getShortestPaths()` and `getPaths()` will now traverse all _transitions_ by default, not just all events.

Take this machine:

```ts
const machine = createTestMachine({
initial: 'toggledOn',
states: {
toggledOn: {
on: {
TOGGLE: 'toggledOff'
}
},
toggledOff: {
on: {
TOGGLE: 'toggledOn'
}
}
}
});
```

In `@xstate/test` version 0.x, this would run this path by default:

```txt
toggledOn -> TOGGLE -> toggledOff
```

This is because it satisfies two conditions:

1. Covers all states
2. Covers all events

But this a complete test - it doesn't test if going from `toggledOff` to `toggledOn` works.

Now, we seek to cover all transitions by default. So the path would be:

```txt
toggledOn -> TOGGLE -> toggledOff -> TOGGLE -> toggledOn
```
8 changes: 8 additions & 0 deletions .changeset/lazy-turtles-great.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@xstate/test': minor
---

pr: #3036
@author: @mattpocock @davidkpiano

Added `path.testSync(...)` to allow for testing paths in sync-only environments, such as Cypress.
28 changes: 28 additions & 0 deletions .changeset/lazy-turtles-mate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
'@xstate/test': major
---

pr: #3036
@author: @mattpocock @davidkpiano

Moved `events` from `createTestModel` to `path.test`.

Old:

```ts
const model = createTestModel(machine, {
events: {}
});
```

New:

```ts
const paths = model.getPaths().forEach((path) => {
path.test({
events: {}
});
});
```

This allows for easier usage of per-test mocks and per-test context.
21 changes: 21 additions & 0 deletions .changeset/lazy-turtles-trade.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
'@xstate/test': major
---

pr: #3036
@author: @mattpocock @davidkpiano

Added `states` to `path.test()`:

```ts
const paths = model.getPaths().forEach((path) => {
path.test({
states: {
myState: () => {},
'myState.deep': () => {}
}
});
});
```

This allows you to define your tests outside of your machine, keeping the machine itself easy to read.
2 changes: 1 addition & 1 deletion packages/core/src/interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1094,7 +1094,7 @@ export class Interpreter<
})
.start();

return actor as any;
return actor as ActorRef<TChildEvent, State<TChildContext, TChildEvent>>;
}
private spawnBehavior<TActorEvent extends EventObject, TEmitted>(
behavior: Behavior<TActorEvent, TEmitted>,
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1504,6 +1504,9 @@ export interface StateConfig<TContext, TEvent extends EventObject> {
*/
activities?: ActivityMap;
meta?: any;
/**
* @deprecated
*/
events?: TEvent[];
configuration: Array<StateNode<TContext, any, TEvent>>;
transitions: Array<TransitionDefinition<TContext, TEvent>>;
Expand Down
Loading

0 comments on commit 8a101dc

Please sign in to comment.