From 731799aceaeb611fdec7e7e9150a483e8a3f7da9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Mon, 23 Oct 2023 16:47:36 +0200 Subject: [PATCH] Do not resolve `output` of final states directly nested in parallel states (#4386) * Do not resolve `output` of final states directly nested in parallel states * simplify the while loop through parallel ancestry chain * rewrite test to fix the CI --- packages/core/src/stateUtils.ts | 32 +++++++++++--------------------- packages/core/test/final.test.ts | 29 +++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/packages/core/src/stateUtils.ts b/packages/core/src/stateUtils.ts index 72b84630ae..f1f2265b02 100644 --- a/packages/core/src/stateUtils.ts +++ b/packages/core/src/stateUtils.ts @@ -1157,16 +1157,11 @@ function enterStates( if (stateNodeToEnter.type === 'final') { const parent = stateNodeToEnter.parent; - if (completedNodes.has(parent)) { - continue; - } - completedNodes.add(parent); - let ancestorMarker = parent?.type === 'parallel' ? parent : parent?.parent; let rootCompletionNode = ancestorMarker || stateNodeToEnter; - if (ancestorMarker) { + if (parent?.type === 'compound') { internalQueue.push( createDoneStateEvent( parent!.id, @@ -1180,21 +1175,16 @@ function enterStates( : undefined ) ); - while ( - ancestorMarker?.type === 'parallel' && - isInFinalState(mutConfiguration, ancestorMarker) - ) { - const completedNode: typeof ancestorMarker = ancestorMarker; - - ancestorMarker = completedNode.parent; - rootCompletionNode = completedNode; - - if (completedNodes.has(completedNode)) { - break; - } - completedNodes.add(completedNode); - internalQueue.push(createDoneStateEvent(completedNode.id)); - } + } + while ( + ancestorMarker?.type === 'parallel' && + !completedNodes.has(ancestorMarker) && + isInFinalState(mutConfiguration, ancestorMarker) + ) { + completedNodes.add(ancestorMarker); + internalQueue.push(createDoneStateEvent(ancestorMarker.id)); + rootCompletionNode = ancestorMarker; + ancestorMarker = ancestorMarker.parent; } if (ancestorMarker) { continue; diff --git a/packages/core/test/final.test.ts b/packages/core/test/final.test.ts index 1dd7d2401e..9bbba070a9 100644 --- a/packages/core/test/final.test.ts +++ b/packages/core/test/final.test.ts @@ -1080,4 +1080,33 @@ describe('final states', () => { expect(actorRef.getSnapshot().status).toBe('active'); }); + + it('should not resolve output of a final state if its parent is a parallel state', () => { + const spy = jest.fn(); + + const machine = createMachine({ + initial: 'A', + states: { + A: { + type: 'parallel', + states: { + B: { + type: 'final', + output: spy + }, + C: { + initial: 'C1', + states: { + C1: {} + } + } + } + } + } + }); + + createActor(machine).start(); + + expect(spy).not.toHaveBeenCalled(); + }); });