Skip to content

Commit

Permalink
Fixed an issue with incorrect ancestors being entered together with d…
Browse files Browse the repository at this point in the history
…efault history targets
  • Loading branch information
Andarist committed Dec 13, 2023
1 parent dd668c6 commit bd0c98c
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/happy-spiders-bathe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'xstate': patch
---

Fixed an issue with ancestors of the default history target that lie outside of the transition domain being incorrectly entered.
2 changes: 1 addition & 1 deletion packages/core/src/stateUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1294,7 +1294,7 @@ function addDescendantStatesToEnter<
for (const s of historyDefaultTransition.target) {
addProperAncestorStatesToEnter(
s,
stateNode,
stateNode.parent!,
statesToEnter,
historyValue,
statesForDefaultEntry
Expand Down
95 changes: 94 additions & 1 deletion packages/core/test/history.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { createActor, createMachine, fromCallback } from '../src/index';
import {
assign,
createActor,
createMachine,
fromCallback,
fromPromise
} from '../src/index';
import { trackEntries } from './utils';

describe('history states', () => {
it('should go to the most recently visited state (explicit shallow history type)', () => {
Expand Down Expand Up @@ -528,6 +535,92 @@ describe('history states', () => {

expect(spy).toHaveBeenCalledTimes(1);
});

it('should not enter ancestors of the entered history state that lie outside of the transition domain when entering the default history configuration', () => {
const machine = createMachine({
initial: 'closed',
states: {
closed: {
on: {
'BUTTON.CLICK': 'open.hist'
}
},
open: {
on: {
'BUTTON.CLICK': 'closed'
},
initial: 'first',
states: {
hist: { type: 'history' },
first: {},
second: {}
}
}
}
});

const flushTracked = trackEntries(machine);

const actorRef = createActor(machine).start();
flushTracked();

actorRef.send({ type: 'BUTTON.CLICK' });
expect(flushTracked()).toEqual([
'exit: closed',
'enter: open',
'enter: open.first'
]);
});

it('should not enter ancestors of the entered history state that lie outside of the transition domain when retoring the stored history configuration', () => {
const machine = createMachine({
initial: 'closed',
states: {
closed: {
id: 'closed',
on: {
'BUTTON.CLICK': 'open.hist'
}
},
open: {
on: {
'BUTTON.CLICK': 'closed'
},
initial: 'first',
states: {
hist: { type: 'history' },
first: {
on: {
NEXT: 'second'
}
},
second: {
on: {
CLOSE: '#closed'
}
}
}
}
}
});

const flushTracked = trackEntries(machine);

const actorRef = createActor(machine).start();

actorRef.send({ type: 'BUTTON.CLICK' });
actorRef.send({ type: 'NEXT' });
actorRef.send({ type: 'CLOSE' });

flushTracked();

actorRef.send({ type: 'BUTTON.CLICK' });
expect(flushTracked()).toEqual([
'exit: closed',
'enter: open',
'enter: open.second'
]);
});
});

describe('deep history states', () => {
Expand Down

0 comments on commit bd0c98c

Please sign in to comment.