Add tests for tree reset propagation #60

Merged
thepaperpilot merged 4 commits from thepaperpilot/Profectus:feat/reset-tests into main 2024-02-21 04:15:49 +00:00
2 changed files with 112 additions and 1 deletions

View file

@ -224,7 +224,7 @@ export interface BaseTree {
id: string; id: string;
/** The link objects for each of the branches of the tree. */ /** The link objects for each of the branches of the tree. */
links: Ref<Link[]>; links: Ref<Link[]>;
/** Cause a reset on this node and propagate it through the tree according to {@link resetPropagation}. */ /** Cause a reset on this node and propagate it through the tree according to {@link TreeOptions.resetPropagation}. */
reset: (node: GenericTreeNode) => void; reset: (node: GenericTreeNode) => void;
/** A flag that is true while the reset is still propagating through the tree. */ /** A flag that is true while the reset is still propagating through the tree. */
isResetting: Ref<boolean>; isResetting: Ref<boolean>;

111
tests/features/tree.test.ts Normal file
View file

@ -0,0 +1,111 @@
import { beforeAll, beforeEach, describe, expect, test, vi } from "vitest";
import { Ref, ref } from "vue";
import "../utils";
import {
createTree,
createTreeNode,
defaultResetPropagation,
invertedResetPropagation,
branchedResetPropagation
} from "features/trees/tree";
import { createReset, GenericReset } from "features/reset";
describe("Reset propagation", () => {
let shouldReset: Ref<boolean>, shouldNotReset: Ref<boolean>;
let goodReset: GenericReset, badReset: GenericReset;
beforeAll(() => {
shouldReset = ref(false);
shouldNotReset = ref(false);
goodReset = createReset(() => ({
thingsToReset: [],
onReset() {
shouldReset.value = true;
}
}));
badReset = createReset(() => ({
thingsToReset: [],
onReset() {
shouldNotReset.value = true;
}
}));
});
beforeEach(() => {
shouldReset.value = false;
shouldNotReset.value = false;
});
test("No resets", () => {
expect(() => {
const a = createTreeNode(() => ({}));
const b = createTreeNode(() => ({}));
const c = createTreeNode(() => ({}));
const tree = createTree(() => ({
nodes: [[a], [b], [c]]
}));
tree.reset(a);
}).not.toThrowError();
});
test("Do not propagate resets", () => {
const a = createTreeNode(() => ({ reset: badReset }));
const b = createTreeNode(() => ({ reset: badReset }));
const c = createTreeNode(() => ({ reset: badReset }));
const tree = createTree(() => ({
nodes: [[a], [b], [c]]
}));
tree.reset(b);
expect(shouldNotReset.value).toBe(false);
});
escapee marked this conversation as resolved
Review

This one isn't feeling right - isn't tree.reset(node) supposed to trigger that node's reset too, or is tree.reset(node) supposed to just start a reset that propagates from that node, but doesn't include it?

This one isn't feeling right - isn't `tree.reset(node)` supposed to trigger that node's `reset` too, or is `tree.reset(node)` supposed to just start a reset that propagates from that node, but doesn't include it?
Review

I based this off the behavior based on the createResetButton util which calls reset on the node itself and then propagates the rest. The idea being that you're resetting for currency on that layer, not resetting that layer. This has been a point of contention previously though so I'm open to changing it in order to be more clear and intuitive, but that'll be a breaking change that's out of scope for this PR.

I based this off the behavior based on the `createResetButton` util which calls reset on the node itself and then propagates the rest. The idea being that you're resetting for currency on that layer, not resetting that layer. This has been a point of contention previously though so I'm open to changing it in order to be more clear and intuitive, but that'll be a breaking change that's out of scope for this PR.
Review

Fair enough - should be fine to just talk about that in the features' docs, nothing that needs to change here then.

Fair enough - should be fine to just talk about that in the features' docs, nothing that needs to change here then.
test("Default propagation", () => {
const a = createTreeNode(() => ({ reset: goodReset }));
const b = createTreeNode(() => ({}));
const c = createTreeNode(() => ({ reset: badReset }));
const tree = createTree(() => ({
nodes: [[a], [b], [c]],
resetPropagation: defaultResetPropagation
}));
tree.reset(b);
expect(shouldReset.value).toBe(true);
expect(shouldNotReset.value).toBe(false);
});
test("Inverted propagation", () => {
const a = createTreeNode(() => ({ reset: badReset }));
const b = createTreeNode(() => ({}));
const c = createTreeNode(() => ({ reset: goodReset }));
const tree = createTree(() => ({
nodes: [[a], [b], [c]],
resetPropagation: invertedResetPropagation
}));
tree.reset(b);
expect(shouldReset.value).toBe(true);
expect(shouldNotReset.value).toBe(false);
});
test("Branched propagation", () => {
const a = createTreeNode(() => ({ reset: badReset }));
const b = createTreeNode(() => ({}));
const c = createTreeNode(() => ({ reset: goodReset }));
const tree = createTree(() => ({
nodes: [[a, b, c]],
resetPropagation: branchedResetPropagation,
branches: [{ startNode: b, endNode: c }]
}));
tree.reset(b);
expect(shouldReset.value).toBe(true);
expect(shouldNotReset.value).toBe(false);
});
test("Branched propagation not bi-directional", () => {
const a = createTreeNode(() => ({ reset: badReset }));
const b = createTreeNode(() => ({}));
const c = createTreeNode(() => ({ reset: badReset }));
const tree = createTree(() => ({
nodes: [[a, b, c]],
resetPropagation: branchedResetPropagation,
branches: [{ startNode: c, endNode: b }]
}));
tree.reset(b);
expect(shouldNotReset.value).toBe(false);
});
});