2024-08-06 14:52:22 +00:00
|
|
|
import type { WidgetEntityConfig } from "ee/entities/DataTree/types";
|
|
|
|
|
import { DataTreeDiffEvent } from "ee/workers/Evaluation/evaluationUtils";
|
2024-06-18 09:45:24 +00:00
|
|
|
import { RenderModes } from "constants/WidgetConstants";
|
2024-12-26 05:07:41 +00:00
|
|
|
import { ENTITY_TYPE } from "ee/entities/DataTree/types";
|
2024-06-18 09:45:24 +00:00
|
|
|
import type { ConfigTree } from "entities/DataTree/dataTreeTypes";
|
|
|
|
|
import { generateDataTreeWidget } from "entities/DataTree/dataTreeWidget";
|
2025-02-06 05:50:08 +00:00
|
|
|
import { create } from "mutative";
|
2024-06-18 09:45:24 +00:00
|
|
|
import type { WidgetEntity } from "plugins/Linting/lib/entity/WidgetEntity";
|
|
|
|
|
import type { UpdateDataTreeMessageData } from "sagas/EvalWorkerActionSagas";
|
|
|
|
|
import DataTreeEvaluator from "workers/common/DataTreeEvaluator";
|
|
|
|
|
import * as evalTreeWithChanges from "./evalTreeWithChanges";
|
2024-10-15 15:35:39 +00:00
|
|
|
import { APP_MODE } from "entities/App";
|
2024-06-18 09:45:24 +00:00
|
|
|
export const BASE_WIDGET = {
|
|
|
|
|
widgetId: "randomID",
|
|
|
|
|
widgetName: "randomWidgetName",
|
|
|
|
|
bottomRow: 0,
|
|
|
|
|
isLoading: false,
|
|
|
|
|
leftColumn: 0,
|
|
|
|
|
parentColumnSpace: 0,
|
|
|
|
|
parentRowSpace: 0,
|
|
|
|
|
renderMode: RenderModes.CANVAS,
|
|
|
|
|
rightColumn: 0,
|
|
|
|
|
topRow: 0,
|
|
|
|
|
type: "SKELETON_WIDGET",
|
|
|
|
|
parentId: "0",
|
|
|
|
|
version: 1,
|
|
|
|
|
ENTITY_TYPE: ENTITY_TYPE.WIDGET,
|
|
|
|
|
meta: {},
|
|
|
|
|
} as unknown as WidgetEntity;
|
|
|
|
|
|
|
|
|
|
export const BASE_WIDGET_CONFIG = {
|
|
|
|
|
logBlackList: {},
|
|
|
|
|
widgetId: "randomID",
|
|
|
|
|
type: "SKELETON_WIDGET",
|
|
|
|
|
ENTITY_TYPE: ENTITY_TYPE.WIDGET,
|
|
|
|
|
} as unknown as WidgetEntityConfig;
|
|
|
|
|
|
|
|
|
|
const WIDGET_CONFIG_MAP = {
|
|
|
|
|
TEXT_WIDGET: {
|
|
|
|
|
defaultProperties: {},
|
|
|
|
|
derivedProperties: {
|
|
|
|
|
value: "{{ this.text }}",
|
|
|
|
|
},
|
|
|
|
|
metaProperties: {},
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const configTree: ConfigTree = {
|
|
|
|
|
Text1: generateDataTreeWidget(
|
|
|
|
|
{
|
|
|
|
|
...BASE_WIDGET_CONFIG,
|
|
|
|
|
...BASE_WIDGET,
|
|
|
|
|
widgetName: "Text1",
|
|
|
|
|
text: "Label",
|
|
|
|
|
type: "TEXT_WIDGET",
|
2024-07-31 15:41:28 +00:00
|
|
|
// TODO: Fix this the next time the file is edited
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2024-06-18 09:45:24 +00:00
|
|
|
} as any,
|
|
|
|
|
{},
|
|
|
|
|
new Set(),
|
|
|
|
|
).configEntity,
|
|
|
|
|
Text2: generateDataTreeWidget(
|
|
|
|
|
{
|
|
|
|
|
...BASE_WIDGET_CONFIG,
|
|
|
|
|
...BASE_WIDGET,
|
|
|
|
|
widgetName: "Text2",
|
|
|
|
|
text: "{{Text1.text}}",
|
|
|
|
|
dynamicBindingPathList: [{ key: "text" }],
|
|
|
|
|
type: "TEXT_WIDGET",
|
2024-07-31 15:41:28 +00:00
|
|
|
// TODO: Fix this the next time the file is edited
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2024-06-18 09:45:24 +00:00
|
|
|
} as any,
|
|
|
|
|
{},
|
|
|
|
|
new Set(),
|
|
|
|
|
).configEntity,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const unEvalTree = {
|
|
|
|
|
Text1: generateDataTreeWidget(
|
|
|
|
|
{
|
|
|
|
|
...BASE_WIDGET_CONFIG,
|
|
|
|
|
...BASE_WIDGET,
|
|
|
|
|
widgetName: "Text1",
|
|
|
|
|
text: "Label",
|
|
|
|
|
type: "TEXT_WIDGET",
|
2024-07-31 15:41:28 +00:00
|
|
|
// TODO: Fix this the next time the file is edited
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2024-06-18 09:45:24 +00:00
|
|
|
} as any,
|
|
|
|
|
{},
|
|
|
|
|
new Set(),
|
|
|
|
|
).unEvalEntity,
|
|
|
|
|
Text2: generateDataTreeWidget(
|
|
|
|
|
{
|
|
|
|
|
...BASE_WIDGET_CONFIG,
|
|
|
|
|
...BASE_WIDGET,
|
|
|
|
|
widgetName: "Text2",
|
|
|
|
|
text: "{{Text1.text}}",
|
|
|
|
|
dynamicBindingPathList: [{ key: "text" }],
|
|
|
|
|
type: "TEXT_WIDGET",
|
2024-07-31 15:41:28 +00:00
|
|
|
// TODO: Fix this the next time the file is edited
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2024-06-18 09:45:24 +00:00
|
|
|
} as any,
|
|
|
|
|
{},
|
|
|
|
|
new Set(),
|
|
|
|
|
).unEvalEntity,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
describe("evaluateAndPushResponse", () => {
|
2024-07-31 15:41:28 +00:00
|
|
|
// TODO: Fix this the next time the file is edited
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2024-06-18 09:45:24 +00:00
|
|
|
let pushResponseToMainThreadMock: any;
|
2024-09-18 16:35:28 +00:00
|
|
|
|
2024-06-18 09:45:24 +00:00
|
|
|
beforeAll(() => {
|
|
|
|
|
pushResponseToMainThreadMock = jest
|
|
|
|
|
.spyOn(evalTreeWithChanges, "pushResponseToMainThread")
|
|
|
|
|
.mockImplementation(() => {}); // spy on foo
|
|
|
|
|
});
|
|
|
|
|
beforeAll(() => {
|
|
|
|
|
jest.clearAllMocks();
|
|
|
|
|
});
|
|
|
|
|
test("should call pushResponseToMainThread when we evaluate and push updates", () => {
|
|
|
|
|
evalTreeWithChanges.evaluateAndPushResponse(
|
|
|
|
|
undefined,
|
|
|
|
|
{
|
|
|
|
|
unEvalUpdates: [],
|
|
|
|
|
evalOrder: [],
|
|
|
|
|
jsUpdates: {},
|
|
|
|
|
},
|
|
|
|
|
[],
|
|
|
|
|
[],
|
|
|
|
|
);
|
|
|
|
|
// check if push response has been called
|
|
|
|
|
expect(pushResponseToMainThreadMock).toHaveBeenCalled();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe("getAffectedNodesInTheDataTree", () => {
|
|
|
|
|
test("should merge paths from unEvalUpdates and evalOrder", () => {
|
|
|
|
|
const result = evalTreeWithChanges.getAffectedNodesInTheDataTree(
|
|
|
|
|
[
|
|
|
|
|
{
|
|
|
|
|
event: DataTreeDiffEvent.NOOP,
|
|
|
|
|
payload: {
|
|
|
|
|
propertyPath: "Text2.text",
|
|
|
|
|
value: "",
|
|
|
|
|
},
|
2024-07-31 15:41:28 +00:00
|
|
|
// TODO: Fix this the next time the file is edited
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2024-06-18 09:45:24 +00:00
|
|
|
} as any,
|
|
|
|
|
],
|
|
|
|
|
["Text1.text"],
|
|
|
|
|
);
|
2024-09-18 16:35:28 +00:00
|
|
|
|
2024-06-18 09:45:24 +00:00
|
|
|
expect(result).toEqual(["Text2.text", "Text1.text"]);
|
|
|
|
|
});
|
|
|
|
|
test("should extract unique paths from unEvalUpdates and evalOrder", () => {
|
|
|
|
|
const result = evalTreeWithChanges.getAffectedNodesInTheDataTree(
|
|
|
|
|
[
|
|
|
|
|
{
|
|
|
|
|
event: DataTreeDiffEvent.NOOP,
|
|
|
|
|
payload: {
|
|
|
|
|
propertyPath: "Text1.text",
|
|
|
|
|
value: "",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
["Text1.text"],
|
|
|
|
|
);
|
2024-09-18 16:35:28 +00:00
|
|
|
|
2024-06-18 09:45:24 +00:00
|
|
|
expect(result).toEqual(["Text1.text"]);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
describe("evaluateAndGenerateResponse", () => {
|
|
|
|
|
let evaluator: DataTreeEvaluator;
|
|
|
|
|
const UPDATED_LABEL = "updated Label";
|
|
|
|
|
|
|
|
|
|
const getParsedUpdatesFromWebWorkerResp = (
|
|
|
|
|
webworkerResponse: UpdateDataTreeMessageData,
|
|
|
|
|
) => {
|
|
|
|
|
const updates = JSON.parse(webworkerResponse.workerResponse.updates);
|
2024-09-18 16:35:28 +00:00
|
|
|
|
2024-06-18 09:45:24 +00:00
|
|
|
//scrub out all __evaluation__ patches
|
2024-07-31 15:41:28 +00:00
|
|
|
// TODO: Fix this the next time the file is edited
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2024-06-18 09:45:24 +00:00
|
|
|
return updates.filter((p: any) => !p.rhs.__evaluation__);
|
|
|
|
|
};
|
2024-09-18 16:35:28 +00:00
|
|
|
|
2024-10-15 15:35:39 +00:00
|
|
|
beforeEach(async () => {
|
2024-06-18 09:45:24 +00:00
|
|
|
evaluator = new DataTreeEvaluator(WIDGET_CONFIG_MAP);
|
2024-10-15 15:35:39 +00:00
|
|
|
await evaluator.setupFirstTree(
|
|
|
|
|
unEvalTree,
|
|
|
|
|
configTree,
|
|
|
|
|
{},
|
|
|
|
|
{
|
|
|
|
|
appId: "appId",
|
|
|
|
|
pageId: "pageId",
|
|
|
|
|
timestamp: "timestamp",
|
|
|
|
|
appMode: APP_MODE.PUBLISHED,
|
|
|
|
|
instanceId: "instanceId",
|
|
|
|
|
},
|
|
|
|
|
);
|
2024-06-18 09:45:24 +00:00
|
|
|
evaluator.evalAndValidateFirstTree();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("inital evaluation successful should be successful", () => {
|
|
|
|
|
expect(evaluator.evalTree).toHaveProperty("Text2.text", "Label");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("should respond with default values when dataTreeEvaluator is not provided", () => {
|
|
|
|
|
const webworkerResponse = evalTreeWithChanges.evaluateAndGenerateResponse(
|
|
|
|
|
undefined,
|
|
|
|
|
{
|
|
|
|
|
unEvalUpdates: [],
|
|
|
|
|
evalOrder: [],
|
|
|
|
|
jsUpdates: {},
|
|
|
|
|
},
|
|
|
|
|
[],
|
|
|
|
|
[],
|
|
|
|
|
);
|
|
|
|
|
const parsedUpdates = getParsedUpdatesFromWebWorkerResp(webworkerResponse);
|
|
|
|
|
|
|
|
|
|
expect(parsedUpdates).toEqual([]);
|
|
|
|
|
expect(webworkerResponse).toEqual({
|
|
|
|
|
workerResponse: {
|
|
|
|
|
dependencies: {},
|
|
|
|
|
errors: [],
|
|
|
|
|
evalMetaUpdates: [],
|
|
|
|
|
evaluationOrder: [],
|
|
|
|
|
isCreateFirstTree: false,
|
|
|
|
|
isNewWidgetAdded: false,
|
|
|
|
|
jsUpdates: {},
|
|
|
|
|
jsVarsCreatedEvent: [],
|
|
|
|
|
logs: [],
|
|
|
|
|
removedPaths: [],
|
|
|
|
|
staleMetaIds: [],
|
|
|
|
|
unEvalUpdates: [],
|
|
|
|
|
undefinedEvalValuesMap: {},
|
|
|
|
|
updates: "[]",
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
test("should generate no updates when the updateTreeResponse is empty", () => {
|
|
|
|
|
const webworkerResponse = evalTreeWithChanges.evaluateAndGenerateResponse(
|
|
|
|
|
evaluator,
|
|
|
|
|
{
|
|
|
|
|
unEvalUpdates: [],
|
|
|
|
|
evalOrder: [],
|
|
|
|
|
jsUpdates: {},
|
|
|
|
|
},
|
|
|
|
|
[],
|
|
|
|
|
[],
|
|
|
|
|
);
|
|
|
|
|
const parsedUpdates = getParsedUpdatesFromWebWorkerResp(webworkerResponse);
|
|
|
|
|
|
|
|
|
|
expect(parsedUpdates).toEqual([]);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe("updates", () => {
|
|
|
|
|
test("should generate updates based on the unEvalUpdates", () => {
|
2024-07-31 15:41:28 +00:00
|
|
|
// TODO: Fix this the next time the file is edited
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2025-02-06 05:50:08 +00:00
|
|
|
const updatedLabelUnevalTree = create(unEvalTree, (draft: any) => {
|
2024-06-18 09:45:24 +00:00
|
|
|
draft.Text1.text = UPDATED_LABEL;
|
|
|
|
|
draft.Text1.label = UPDATED_LABEL;
|
|
|
|
|
});
|
|
|
|
|
const updateTreeResponse = evaluator.setupUpdateTree(
|
|
|
|
|
updatedLabelUnevalTree,
|
|
|
|
|
configTree,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// ignore label Text1.label uneval update and just include Text1.text uneval update
|
|
|
|
|
updateTreeResponse.unEvalUpdates = [
|
|
|
|
|
{
|
|
|
|
|
event: DataTreeDiffEvent.NOOP,
|
|
|
|
|
payload: {
|
|
|
|
|
propertyPath: "Text1.text",
|
|
|
|
|
value: "",
|
|
|
|
|
},
|
|
|
|
|
},
|
2024-07-31 15:41:28 +00:00
|
|
|
// TODO: Fix this the next time the file is edited
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2024-06-18 09:45:24 +00:00
|
|
|
] as any;
|
|
|
|
|
// the eval tree should have the uneval update but the diff should not be generated because the unEvalUpdates has been altered
|
|
|
|
|
expect(evaluator.evalTree).toHaveProperty("Text1.text", UPDATED_LABEL);
|
|
|
|
|
|
|
|
|
|
const webworkerResponse = evalTreeWithChanges.evaluateAndGenerateResponse(
|
|
|
|
|
evaluator,
|
|
|
|
|
updateTreeResponse,
|
|
|
|
|
[],
|
|
|
|
|
[],
|
|
|
|
|
);
|
2024-10-10 11:36:11 +00:00
|
|
|
|
|
|
|
|
expect(webworkerResponse.workerResponse.dependencies).toEqual({
|
|
|
|
|
"Text1.text": ["Text2.text", "Text1"],
|
|
|
|
|
"Text2.text": ["Text2"],
|
|
|
|
|
});
|
2024-06-18 09:45:24 +00:00
|
|
|
const parsedUpdates =
|
|
|
|
|
getParsedUpdatesFromWebWorkerResp(webworkerResponse);
|
2024-09-18 16:35:28 +00:00
|
|
|
|
2024-06-18 09:45:24 +00:00
|
|
|
// Text1.label update should be ignored
|
|
|
|
|
expect(parsedUpdates).not.toEqual(
|
|
|
|
|
expect.arrayContaining([
|
|
|
|
|
{
|
|
|
|
|
kind: "N",
|
|
|
|
|
path: ["Text1", "label"],
|
|
|
|
|
rhs: UPDATED_LABEL,
|
|
|
|
|
},
|
|
|
|
|
]),
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
test("should generate updates based on the evalOrder", () => {
|
2024-07-31 15:41:28 +00:00
|
|
|
// TODO: Fix this the next time the file is edited
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2025-02-06 05:50:08 +00:00
|
|
|
const updatedLabelUnevalTree = create(unEvalTree, (draft: any) => {
|
2024-06-18 09:45:24 +00:00
|
|
|
draft.Text1.text = UPDATED_LABEL;
|
|
|
|
|
});
|
|
|
|
|
const updateTreeResponse = evaluator.setupUpdateTree(
|
|
|
|
|
updatedLabelUnevalTree,
|
|
|
|
|
configTree,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// ignore label Text1.label uneval update and just include Text1.text uneval update
|
|
|
|
|
// expect(updateTreeResponse.evalOrder).toEqual([]);
|
|
|
|
|
updateTreeResponse.evalOrder = [];
|
|
|
|
|
|
|
|
|
|
const webworkerResponse = evalTreeWithChanges.evaluateAndGenerateResponse(
|
|
|
|
|
evaluator,
|
|
|
|
|
updateTreeResponse,
|
|
|
|
|
[],
|
|
|
|
|
[],
|
|
|
|
|
);
|
|
|
|
|
const parsedUpdates =
|
|
|
|
|
getParsedUpdatesFromWebWorkerResp(webworkerResponse);
|
|
|
|
|
|
|
|
|
|
// Text1.label update should be ignored
|
|
|
|
|
expect(parsedUpdates).not.toEqual(
|
|
|
|
|
expect.arrayContaining([
|
|
|
|
|
{
|
|
|
|
|
kind: "N",
|
|
|
|
|
path: ["Text2", "text"],
|
|
|
|
|
rhs: "updated Label",
|
|
|
|
|
},
|
|
|
|
|
]),
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
test("should generate the correct updates to be sent to the main thread's state when the value tied to a binding changes ", () => {
|
2024-07-31 15:41:28 +00:00
|
|
|
// TODO: Fix this the next time the file is edited
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2025-02-06 05:50:08 +00:00
|
|
|
const updatedLabelUnevalTree = create(unEvalTree, (draft: any) => {
|
2024-06-18 09:45:24 +00:00
|
|
|
if (draft.Text1?.text) {
|
|
|
|
|
draft.Text1.text = UPDATED_LABEL;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
const updateTreeResponse = evaluator.setupUpdateTree(
|
|
|
|
|
updatedLabelUnevalTree,
|
|
|
|
|
configTree,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const webworkerResponse = evalTreeWithChanges.evaluateAndGenerateResponse(
|
|
|
|
|
evaluator,
|
|
|
|
|
updateTreeResponse,
|
|
|
|
|
[],
|
|
|
|
|
[],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const parsedUpdates =
|
|
|
|
|
getParsedUpdatesFromWebWorkerResp(webworkerResponse);
|
2024-09-18 16:35:28 +00:00
|
|
|
|
2024-06-18 09:45:24 +00:00
|
|
|
expect(parsedUpdates).toEqual(
|
|
|
|
|
expect.arrayContaining([
|
|
|
|
|
{
|
|
|
|
|
kind: "N",
|
|
|
|
|
path: ["Text1", "text"],
|
|
|
|
|
rhs: "updated Label",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
kind: "N",
|
|
|
|
|
path: ["Text2", "text"],
|
|
|
|
|
rhs: "updated Label",
|
|
|
|
|
},
|
|
|
|
|
]),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(evaluator.evalTree).toHaveProperty("Text2.text", UPDATED_LABEL);
|
|
|
|
|
});
|
|
|
|
|
test("should merge additional updates to the dataTree as well as push the updates back to the main thread's state when unEvalUpdates is ignored", () => {
|
2024-07-31 15:41:28 +00:00
|
|
|
// TODO: Fix this the next time the file is edited
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2025-02-06 05:50:08 +00:00
|
|
|
const updatedLabelUnevalTree = create(unEvalTree, (draft: any) => {
|
2024-06-18 09:45:24 +00:00
|
|
|
if (draft.Text1?.text) {
|
|
|
|
|
draft.Text1.text = UPDATED_LABEL;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
const updateTreeResponse = evaluator.setupUpdateTree(
|
|
|
|
|
updatedLabelUnevalTree,
|
|
|
|
|
configTree,
|
|
|
|
|
);
|
2024-09-18 16:35:28 +00:00
|
|
|
|
2024-06-18 09:45:24 +00:00
|
|
|
//set the unEvalUpdates is empty so that evaluation ignores diffing the node
|
|
|
|
|
updateTreeResponse.unEvalUpdates = [];
|
|
|
|
|
|
|
|
|
|
const webworkerResponse = evalTreeWithChanges.evaluateAndGenerateResponse(
|
|
|
|
|
evaluator,
|
|
|
|
|
updateTreeResponse,
|
|
|
|
|
[],
|
|
|
|
|
["Text1.text"],
|
|
|
|
|
);
|
|
|
|
|
const parsedUpdates =
|
|
|
|
|
getParsedUpdatesFromWebWorkerResp(webworkerResponse);
|
2024-09-18 16:35:28 +00:00
|
|
|
|
2024-06-18 09:45:24 +00:00
|
|
|
expect(parsedUpdates).toEqual(
|
|
|
|
|
expect.arrayContaining([
|
|
|
|
|
{
|
|
|
|
|
kind: "N",
|
|
|
|
|
path: ["Text1", "text"],
|
|
|
|
|
rhs: UPDATED_LABEL,
|
|
|
|
|
},
|
|
|
|
|
]),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(evaluator.evalTree).toHaveProperty("Text1.text", UPDATED_LABEL);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe("evalMetaUpdates", () => {
|
|
|
|
|
test("should add metaUpdates in the webworker's response", () => {
|
2024-07-31 15:41:28 +00:00
|
|
|
// TODO: Fix this the next time the file is edited
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2025-02-06 05:50:08 +00:00
|
|
|
const updatedLabelUnevalTree = create(unEvalTree, (draft: any) => {
|
2024-06-18 09:45:24 +00:00
|
|
|
if (draft.Text1?.text) {
|
|
|
|
|
draft.Text1.text = UPDATED_LABEL;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
const response = evaluator.setupUpdateTree(
|
|
|
|
|
updatedLabelUnevalTree,
|
|
|
|
|
configTree,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const metaUpdates = [
|
|
|
|
|
{
|
|
|
|
|
widgetId: unEvalTree.Text1.widgetId,
|
|
|
|
|
metaPropertyPath: ["someMetaValuePath"],
|
|
|
|
|
value: "someValue",
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
const { workerResponse } =
|
|
|
|
|
evalTreeWithChanges.evaluateAndGenerateResponse(
|
|
|
|
|
evaluator,
|
|
|
|
|
response,
|
|
|
|
|
metaUpdates,
|
|
|
|
|
[],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
expect(workerResponse.evalMetaUpdates).toEqual(metaUpdates);
|
|
|
|
|
});
|
|
|
|
|
test("should sanitise metaUpdates in the webworker's response and strip out non serialisable properties", () => {
|
2024-07-31 15:41:28 +00:00
|
|
|
// TODO: Fix this the next time the file is edited
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2025-02-06 05:50:08 +00:00
|
|
|
const updatedLabelUnevalTree = create(unEvalTree, (draft: any) => {
|
2024-06-18 09:45:24 +00:00
|
|
|
if (draft.Text1?.text) {
|
|
|
|
|
draft.Text1.text = UPDATED_LABEL;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
const response = evaluator.setupUpdateTree(
|
|
|
|
|
updatedLabelUnevalTree,
|
|
|
|
|
configTree,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const metaUpdates = [
|
|
|
|
|
{
|
|
|
|
|
widgetId: unEvalTree.Text1.widgetId,
|
|
|
|
|
metaPropertyPath: ["someMetaValuePath"],
|
|
|
|
|
value: function () {},
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
const { workerResponse } =
|
|
|
|
|
evalTreeWithChanges.evaluateAndGenerateResponse(
|
|
|
|
|
evaluator,
|
|
|
|
|
response,
|
|
|
|
|
metaUpdates,
|
|
|
|
|
[],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// the function properties should be stripped out
|
|
|
|
|
expect(workerResponse.evalMetaUpdates).toEqual([
|
|
|
|
|
{
|
|
|
|
|
widgetId: unEvalTree.Text1.widgetId,
|
|
|
|
|
metaPropertyPath: ["someMetaValuePath"],
|
|
|
|
|
},
|
|
|
|
|
]);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe("unEvalUpdates", () => {
|
|
|
|
|
test("should add unEvalUpdates to the web worker response", () => {
|
2024-07-31 15:41:28 +00:00
|
|
|
// TODO: Fix this the next time the file is edited
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2025-02-06 05:50:08 +00:00
|
|
|
const updatedLabelUnevalTree = create(unEvalTree, (draft: any) => {
|
2024-06-18 09:45:24 +00:00
|
|
|
if (draft.Text1?.text) {
|
|
|
|
|
draft.Text1.text = UPDATED_LABEL;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
const updateTreeResponse = evaluator.setupUpdateTree(
|
|
|
|
|
updatedLabelUnevalTree,
|
|
|
|
|
configTree,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const webworkerResponse = evalTreeWithChanges.evaluateAndGenerateResponse(
|
|
|
|
|
evaluator,
|
|
|
|
|
updateTreeResponse,
|
|
|
|
|
[],
|
|
|
|
|
[],
|
|
|
|
|
);
|
|
|
|
|
const parsedUpdates =
|
|
|
|
|
getParsedUpdatesFromWebWorkerResp(webworkerResponse);
|
2024-09-18 16:35:28 +00:00
|
|
|
|
2024-06-18 09:45:24 +00:00
|
|
|
expect(webworkerResponse.workerResponse.unEvalUpdates).toEqual([
|
|
|
|
|
{
|
|
|
|
|
event: DataTreeDiffEvent.NOOP,
|
|
|
|
|
payload: { propertyPath: "Text1.text", value: "" },
|
|
|
|
|
},
|
|
|
|
|
]);
|
|
|
|
|
expect(parsedUpdates).toEqual(
|
|
|
|
|
expect.arrayContaining([
|
|
|
|
|
{
|
|
|
|
|
kind: "N",
|
|
|
|
|
path: ["Text1", "text"],
|
|
|
|
|
rhs: UPDATED_LABEL,
|
|
|
|
|
},
|
|
|
|
|
]),
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
test("should ignore generating updates when unEvalUpdates is empty", () => {
|
2024-07-31 15:41:28 +00:00
|
|
|
// TODO: Fix this the next time the file is edited
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2025-02-06 05:50:08 +00:00
|
|
|
const updatedLabelUnevalTree = create(unEvalTree, (draft: any) => {
|
2024-06-18 09:45:24 +00:00
|
|
|
if (draft.Text1?.text) {
|
|
|
|
|
draft.Text1.text = UPDATED_LABEL;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
const updateTreeResponse = evaluator.setupUpdateTree(
|
|
|
|
|
updatedLabelUnevalTree,
|
|
|
|
|
configTree,
|
|
|
|
|
);
|
2024-09-18 16:35:28 +00:00
|
|
|
|
2024-06-18 09:45:24 +00:00
|
|
|
//set the evalOrder is empty so that evaluation ignores diffing the node
|
|
|
|
|
updateTreeResponse.unEvalUpdates = [];
|
|
|
|
|
|
|
|
|
|
const webworkerResponse = evalTreeWithChanges.evaluateAndGenerateResponse(
|
|
|
|
|
evaluator,
|
|
|
|
|
updateTreeResponse,
|
|
|
|
|
[],
|
|
|
|
|
[],
|
|
|
|
|
);
|
|
|
|
|
const parsedUpdates =
|
|
|
|
|
getParsedUpdatesFromWebWorkerResp(webworkerResponse);
|
|
|
|
|
|
|
|
|
|
expect(parsedUpdates).not.toEqual(
|
|
|
|
|
expect.arrayContaining([
|
|
|
|
|
{
|
|
|
|
|
kind: "N",
|
|
|
|
|
path: ["Text1", "text"],
|
|
|
|
|
rhs: UPDATED_LABEL,
|
|
|
|
|
},
|
|
|
|
|
]),
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|