diff --git a/packages/vest/src/core/Runtime.ts b/packages/vest/src/core/Runtime.ts
index caadb302d..4d389cbaf 100644
--- a/packages/vest/src/core/Runtime.ts
+++ b/packages/vest/src/core/Runtime.ts
@@ -118,6 +118,6 @@ export function useResetSuite() {
}
export function useLoadSuite(rootNode: TIsolateSuite): void {
- VestRuntime.useLoadRootNode(rootNode);
+ VestRuntime.useSetHistoryRoot(rootNode);
useExpireSuiteResultCache();
}
diff --git a/packages/vest/src/core/test/test.memo.ts b/packages/vest/src/core/test/test.memo.ts
index 2df21ef30..a6808f00a 100644
--- a/packages/vest/src/core/test/test.memo.ts
+++ b/packages/vest/src/core/test/test.memo.ts
@@ -66,7 +66,11 @@ function useGetTestFromCache(
return cache(dependencies, cacheAction);
}
- VestRuntime.addNodeToHistory(cachedValue);
+ // FIXME(@ealush 2024-08-12): This is some kind of a hack. Instead organically letting Vest set the next
+ // child of the isolate, we're forcing it from the outside.
+ // Instead, an ideal solution would probably be to have test.memo be its own isolate
+ // that just injects a historic output from a previous test run.
+ VestRuntime.useSetNextIsolateChild(cachedValue);
return cachedValue;
}
diff --git a/packages/vest/src/hooks/__tests__/mode.test.ts b/packages/vest/src/hooks/__tests__/mode.test.ts
index e36d3a053..ea680b379 100644
--- a/packages/vest/src/hooks/__tests__/mode.test.ts
+++ b/packages/vest/src/hooks/__tests__/mode.test.ts
@@ -184,12 +184,12 @@ describe('mode', () => {
it('Should follow the same behavior as if it was not nested', () => {
const suite = create(() => {
group('group_1', () => {
- dummyTest.failing('field_1', 'first-of-field_1');
- dummyTest.failing('field_1', 'second-of-field_1');
- dummyTest.failing('field_2', 'first-of-field_2');
- dummyTest.failing('field_2', 'second-of-field_2');
- dummyTest.failing('field_3', 'first-of-field_3');
- dummyTest.failing('field_3', 'second-of-field_3');
+ Vest.test('field_1', 'first-of-field_1', () => false);
+ Vest.test('field_1', 'second-of-field_1', () => false);
+ Vest.test('field_2', 'first-of-field_2', () => false);
+ Vest.test('field_2', 'second-of-field_2', () => false);
+ Vest.test('field_3', 'first-of-field_3', () => false);
+ Vest.test('field_3', 'second-of-field_3', () => false);
});
});
expect(suite.get().testCount).toBe(0); // sanity
diff --git a/packages/vestjs-runtime/src/Isolate/Isolate.ts b/packages/vestjs-runtime/src/Isolate/Isolate.ts
index 2ec4874d8..245d182f3 100644
--- a/packages/vestjs-runtime/src/Isolate/Isolate.ts
+++ b/packages/vestjs-runtime/src/Isolate/Isolate.ts
@@ -29,6 +29,7 @@ type UsedFeaturesOnly
= Pick<
>;
export class Isolate {
+ // eslint-disable-next-line max-statements
static create(
type: string,
callback: CB,
@@ -48,7 +49,11 @@ export class Isolate {
const shouldRunNew = Object.is(nextIsolateChild, newCreatedNode);
- VestRuntime.addNodeToHistory(nextIsolateChild);
+ if (parent) {
+ // We are within an isolate context. This means that
+ // we need to set the new node to be the child of this parent node.
+ VestRuntime.useSetNextIsolateChild(nextIsolateChild);
+ }
const output = shouldRunNew
? useRunAsNew(localHistoryNode, newCreatedNode, callback)
@@ -56,6 +61,13 @@ export class Isolate {
IsolateMutator.saveOutput(nextIsolateChild, output);
+ if (!parent) {
+ // We're exiting the node, and there is no parent. This means
+ // that we're at the top level and this node should be set
+ // as the new root of the history tree.
+ VestRuntime.useSetHistoryRoot(nextIsolateChild);
+ }
+
return nextIsolateChild as TIsolate;
}
diff --git a/packages/vestjs-runtime/src/Isolate/__tests__/reconciliation.test.ts b/packages/vestjs-runtime/src/Isolate/__tests__/reconciliation.test.ts
new file mode 100644
index 000000000..0c1adc8fc
--- /dev/null
+++ b/packages/vestjs-runtime/src/Isolate/__tests__/reconciliation.test.ts
@@ -0,0 +1,48 @@
+import { CB } from 'vest-utils';
+import { describe, it, expect, beforeEach, vi } from 'vitest';
+
+import { TIsolate, Isolate } from 'Isolate';
+import { StateRefType, useAvailableRoot } from 'VestRuntime';
+import { IRecociler, IsolateMutator, VestRuntime } from 'vestjs-runtime';
+
+describe('Reconciliation', () => {
+ let stateRef: StateRefType;
+
+ beforeEach(() => {
+ stateRef = VestRuntime.createRef(testReconciler, () => null);
+ });
+
+ it('Should return the current node if there is no history node', () => {
+ let rootIsolate;
+ const output = VestRuntime.Run(stateRef, () => {
+ rootIsolate = Isolate.create(IsolateType.RunOne, () => {});
+ });
+
+ const [historyRoot] = stateRef.historyRoot();
+
+ expect(historyRoot).toBe(rootIsolate);
+ });
+
+ it("should return the result of the reconciler's function when runs the second time", () => {
+ const isolate1 = VestRuntime.Run(stateRef, () => {
+ return Isolate.create(IsolateType.RunOne, () => ({ foo: 'bar' }));
+ });
+ const isolate2 = VestRuntime.Run(stateRef, () => {
+ return Isolate.create(IsolateType.RunTwo, () => ({ foo: 'baz' }));
+ });
+
+ const [historyRoot] = stateRef.historyRoot();
+
+ expect(historyRoot).toBe(isolate2);
+ });
+});
+
+enum IsolateType {
+ RunOne = 'RunOne',
+ RunTwo = 'RunTwo',
+}
+
+const testReconciler: IRecociler = (
+ currentNode: TIsolate,
+ historyNode: TIsolate,
+): TIsolate => currentNode;
diff --git a/packages/vestjs-runtime/src/VestRuntime.ts b/packages/vestjs-runtime/src/VestRuntime.ts
index 402816a46..bab120672 100644
--- a/packages/vestjs-runtime/src/VestRuntime.ts
+++ b/packages/vestjs-runtime/src/VestRuntime.ts
@@ -59,14 +59,14 @@ export const Run = PersistedContext.run;
export const RuntimeApi = {
Run,
- addNodeToHistory,
createRef,
persist,
reset,
useAvailableRoot,
useCurrentCursor,
useHistoryRoot,
- useLoadRootNode,
+ useSetHistoryRoot,
+ useSetNextIsolateChild,
useXAppData,
};
@@ -131,18 +131,7 @@ export function useHistoryIsolateAtCurrentPosition() {
return historyNode;
}
-export function addNodeToHistory(node: TIsolate): void {
- const parent = useIsolate();
- if (parent) {
- useSetNextIsolateChild(node);
- } else {
- useSetHistory(node);
- }
-
- IsolateMutator.setParent(node, parent);
-}
-
-export function useSetHistory(history: TIsolate) {
+export function useSetHistoryRoot(history: TIsolate) {
const [, setHistoryRoot] = useHistoryRoot();
setHistoryRoot(history);
}
@@ -172,6 +161,7 @@ export function useSetNextIsolateChild(child: TIsolate): void {
invariant(currentIsolate, ErrorStrings.NO_ACTIVE_ISOLATE);
IsolateMutator.addChild(currentIsolate, child);
+ IsolateMutator.setParent(child, currentIsolate);
}
export function useSetIsolateKey(key: Nullable, node: TIsolate): void {
if (!key) {
@@ -207,7 +197,3 @@ export function reset() {
resetHistoryRoot();
}
-
-export function useLoadRootNode(root: TIsolate): void {
- useSetHistory(root);
-}