Co-authored-by: Trisha Anand <trisha@appsmith.com> Co-authored-by: Piyush Mishra <piyush@codeitout.com> Co-authored-by: Nikhil Nandagopal <nikhil@appsmith.com> Co-authored-by: Akash N <akash@codemonk.in>
768 lines
21 KiB
TypeScript
768 lines
21 KiB
TypeScript
import { DataTreeEvaluator } from "./evaluation.worker";
|
|
import {
|
|
DataTreeAction,
|
|
DataTreeWidget,
|
|
ENTITY_TYPE,
|
|
} from "../entities/DataTree/dataTreeFactory";
|
|
import { WidgetTypeConfigMap } from "../utils/WidgetFactory";
|
|
import { RenderModes, WidgetTypes } from "../constants/WidgetConstants";
|
|
import { PluginType } from "../entities/Action";
|
|
|
|
const WIDGET_CONFIG_MAP: WidgetTypeConfigMap = {
|
|
CONTAINER_WIDGET: {
|
|
validations: {
|
|
isLoading: "BOOLEAN",
|
|
isVisible: "BOOLEAN",
|
|
isDisabled: "BOOLEAN",
|
|
},
|
|
defaultProperties: {},
|
|
derivedProperties: {},
|
|
triggerProperties: {},
|
|
metaProperties: {},
|
|
},
|
|
TEXT_WIDGET: {
|
|
validations: {
|
|
isLoading: "BOOLEAN",
|
|
isVisible: "BOOLEAN",
|
|
isDisabled: "BOOLEAN",
|
|
text: "TEXT",
|
|
textStyle: "TEXT",
|
|
shouldScroll: "BOOLEAN",
|
|
},
|
|
defaultProperties: {},
|
|
derivedProperties: {
|
|
value: "{{ this.text }}",
|
|
},
|
|
triggerProperties: {},
|
|
metaProperties: {},
|
|
},
|
|
BUTTON_WIDGET: {
|
|
validations: {
|
|
isLoading: "BOOLEAN",
|
|
isVisible: "BOOLEAN",
|
|
isDisabled: "BOOLEAN",
|
|
text: "TEXT",
|
|
buttonStyle: "TEXT",
|
|
},
|
|
defaultProperties: {},
|
|
derivedProperties: {},
|
|
triggerProperties: {
|
|
onClick: true,
|
|
},
|
|
metaProperties: {},
|
|
},
|
|
INPUT_WIDGET: {
|
|
validations: {
|
|
isLoading: "BOOLEAN",
|
|
isVisible: "BOOLEAN",
|
|
isDisabled: "BOOLEAN",
|
|
inputType: "TEXT",
|
|
defaultText: "TEXT",
|
|
text: "TEXT",
|
|
regex: "REGEX",
|
|
errorMessage: "TEXT",
|
|
placeholderText: "TEXT",
|
|
maxChars: "NUMBER",
|
|
minNum: "NUMBER",
|
|
maxNum: "NUMBER",
|
|
label: "TEXT",
|
|
inputValidators: "ARRAY",
|
|
focusIndex: "NUMBER",
|
|
isAutoFocusEnabled: "BOOLEAN",
|
|
isRequired: "BOOLEAN",
|
|
isValid: "BOOLEAN",
|
|
},
|
|
defaultProperties: {
|
|
text: "defaultText",
|
|
},
|
|
derivedProperties: {
|
|
isValid:
|
|
'{{\n function(){\n let parsedRegex = null;\n if (this.regex) {\n /*\n * break up the regexp pattern into 4 parts: given regex, regex prefix , regex pattern, regex flags\n * Example /test/i will be split into ["/test/gi", "/", "test", "gi"]\n */\n const regexParts = this.regex.match(/(\\/?)(.+)\\1([a-z]*)/i);\n if (!regexParts) {\n parsedRegex = new RegExp(this.regex);\n } else {\n /*\n * if we don\'t have a regex flags (gmisuy), convert provided string into regexp directly\n /*\n if (regexParts[3] && !/^(?!.*?(.).*?\\1)[gmisuy]+$/.test(regexParts[3])) {\n parsedRegex = RegExp(this.regex);\n }\n /*\n * if we have a regex flags, use it to form regexp\n */\n parsedRegex = new RegExp(regexParts[2], regexParts[3]);\n }\n }\n if (this.inputType === "EMAIL") {\n const emailRegex = new RegExp(/^\\w+([\\.-]?\\w+)*@\\w+([\\.-]?\\w+)*(\\.\\w{2,3})+$/);\n return emailRegex.test(this.text);\n }\n else if (this.inputType === "NUMBER") {\n return !isNaN(this.text)\n }\n else if (this.isRequired) {\n if(this.text && this.text.length) {\n if (parsedRegex) {\n return parsedRegex.test(this.text)\n } else {\n return true;\n }\n } else {\n return false;\n }\n } if (parsedRegex) {\n return parsedRegex.test(this.text)\n } else {\n return true;\n }\n }()\n }}',
|
|
value: "{{this.text}}",
|
|
},
|
|
triggerProperties: {
|
|
onTextChanged: true,
|
|
},
|
|
metaProperties: {
|
|
isFocused: false,
|
|
isDirty: false,
|
|
},
|
|
},
|
|
CHECKBOX_WIDGET: {
|
|
validations: {
|
|
isLoading: "BOOLEAN",
|
|
isVisible: "BOOLEAN",
|
|
isDisabled: "BOOLEAN",
|
|
label: "TEXT",
|
|
defaultCheckedState: "BOOLEAN",
|
|
},
|
|
defaultProperties: {
|
|
isChecked: "defaultCheckedState",
|
|
},
|
|
derivedProperties: {
|
|
value: "{{this.isChecked}}",
|
|
},
|
|
triggerProperties: {
|
|
onCheckChange: true,
|
|
},
|
|
metaProperties: {},
|
|
},
|
|
DROP_DOWN_WIDGET: {
|
|
validations: {
|
|
isLoading: "BOOLEAN",
|
|
isVisible: "BOOLEAN",
|
|
isDisabled: "BOOLEAN",
|
|
placeholderText: "TEXT",
|
|
label: "TEXT",
|
|
options: "OPTIONS_DATA",
|
|
selectionType: "TEXT",
|
|
isRequired: "BOOLEAN",
|
|
selectedOptionValues: "ARRAY",
|
|
defaultOptionValue: "DEFAULT_OPTION_VALUE",
|
|
},
|
|
defaultProperties: {
|
|
selectedOptionValue: "defaultOptionValue",
|
|
selectedOptionValueArr: "defaultOptionValue",
|
|
},
|
|
derivedProperties: {
|
|
isValid:
|
|
"{{this.isRequired ? this.selectionType === 'SINGLE_SELECT' ? !!this.selectedOption : !!this.selectedIndexArr && this.selectedIndexArr.length > 0 : true}}",
|
|
selectedOption:
|
|
"{{ this.selectionType === 'SINGLE_SELECT' ? _.find(this.options, { value: this.selectedOptionValue }) : undefined}}",
|
|
selectedOptionArr:
|
|
'{{this.selectionType === "MULTI_SELECT" ? this.options.filter(opt => _.includes(this.selectedOptionValueArr, opt.value)) : undefined}}',
|
|
selectedIndex:
|
|
"{{ _.findIndex(this.options, { value: this.selectedOption.value } ) }}",
|
|
selectedIndexArr:
|
|
"{{ this.selectedOptionValueArr.map(o => _.findIndex(this.options, { value: o })) }}",
|
|
value:
|
|
"{{ this.selectionType === 'SINGLE_SELECT' ? this.selectedOptionValue : this.selectedOptionValueArr }}",
|
|
selectedOptionValues: "{{ this.selectedOptionValueArr }}",
|
|
},
|
|
triggerProperties: {
|
|
onOptionChange: true,
|
|
},
|
|
metaProperties: {},
|
|
},
|
|
RADIO_GROUP_WIDGET: {
|
|
validations: {
|
|
isLoading: "BOOLEAN",
|
|
isVisible: "BOOLEAN",
|
|
isDisabled: "BOOLEAN",
|
|
label: "TEXT",
|
|
options: "OPTIONS_DATA",
|
|
selectedOptionValue: "TEXT",
|
|
defaultOptionValue: "TEXT",
|
|
isRequired: "BOOLEAN",
|
|
},
|
|
defaultProperties: {
|
|
selectedOptionValue: "defaultOptionValue",
|
|
},
|
|
derivedProperties: {
|
|
selectedOption:
|
|
"{{_.find(this.options, { value: this.selectedOptionValue })}}",
|
|
isValid: "{{ this.isRequired ? !!this.selectedOptionValue : true }}",
|
|
value: "{{this.selectedOptionValue}}",
|
|
},
|
|
triggerProperties: {
|
|
onSelectionChange: true,
|
|
},
|
|
metaProperties: {},
|
|
},
|
|
IMAGE_WIDGET: {
|
|
validations: {
|
|
isLoading: "BOOLEAN",
|
|
isVisible: "BOOLEAN",
|
|
isDisabled: "BOOLEAN",
|
|
image: "TEXT",
|
|
imageShape: "TEXT",
|
|
defaultImage: "TEXT",
|
|
maxZoomLevel: "NUMBER",
|
|
},
|
|
defaultProperties: {},
|
|
derivedProperties: {},
|
|
triggerProperties: {
|
|
onClick: true,
|
|
},
|
|
metaProperties: {},
|
|
},
|
|
TABLE_WIDGET: {
|
|
validations: {
|
|
isLoading: "BOOLEAN",
|
|
isVisible: "BOOLEAN",
|
|
isDisabled: "BOOLEAN",
|
|
tableData: "TABLE_DATA",
|
|
nextPageKey: "TEXT",
|
|
prevPageKey: "TEXT",
|
|
label: "TEXT",
|
|
searchText: "TEXT",
|
|
defaultSearchText: "TEXT",
|
|
defaultSelectedRow: "DEFAULT_SELECTED_ROW",
|
|
},
|
|
defaultProperties: {
|
|
searchText: "defaultSearchText",
|
|
selectedRowIndex: "defaultSelectedRow",
|
|
selectedRowIndices: "defaultSelectedRow",
|
|
},
|
|
derivedProperties: {
|
|
selectedRow: `{{ _.get(this.filteredTableData, this.selectedRowIndex, _.mapValues(this.filteredTableData[0], () => undefined)) }}`,
|
|
selectedRows: `{{ this.filteredTableData.filter((item, i) => selectedRowIndices.includes(i) }); }}`,
|
|
},
|
|
triggerProperties: {
|
|
onRowSelected: true,
|
|
onPageChange: true,
|
|
onSearchTextChanged: true,
|
|
columnActions: true,
|
|
},
|
|
metaProperties: {
|
|
pageNo: 1,
|
|
selectedRow: {},
|
|
selectedRows: [],
|
|
},
|
|
},
|
|
VIDEO_WIDGET: {
|
|
validations: {
|
|
isLoading: "BOOLEAN",
|
|
isVisible: "BOOLEAN",
|
|
isDisabled: "BOOLEAN",
|
|
url: "TEXT",
|
|
},
|
|
defaultProperties: {},
|
|
derivedProperties: {},
|
|
triggerProperties: {
|
|
onEnd: true,
|
|
onPlay: true,
|
|
onPause: true,
|
|
},
|
|
metaProperties: {
|
|
playState: "NOT_STARTED",
|
|
},
|
|
},
|
|
FILE_PICKER_WIDGET: {
|
|
validations: {
|
|
isLoading: "BOOLEAN",
|
|
isVisible: "BOOLEAN",
|
|
isDisabled: "BOOLEAN",
|
|
label: "TEXT",
|
|
maxNumFiles: "NUMBER",
|
|
allowedFileTypes: "ARRAY",
|
|
files: "ARRAY",
|
|
isRequired: "BOOLEAN",
|
|
},
|
|
defaultProperties: {},
|
|
derivedProperties: {
|
|
isValid: "{{ this.isRequired ? this.files.length > 0 : true }}",
|
|
value: "{{this.files}}",
|
|
},
|
|
triggerProperties: {
|
|
onFilesSelected: true,
|
|
},
|
|
metaProperties: {
|
|
files: [],
|
|
uploadedFileData: {},
|
|
},
|
|
},
|
|
DATE_PICKER_WIDGET: {
|
|
validations: {
|
|
isLoading: "BOOLEAN",
|
|
isVisible: "BOOLEAN",
|
|
isDisabled: "BOOLEAN",
|
|
defaultDate: "DATE",
|
|
timezone: "TEXT",
|
|
enableTimePicker: "BOOLEAN",
|
|
dateFormat: "TEXT",
|
|
label: "TEXT",
|
|
datePickerType: "TEXT",
|
|
maxDate: "DATE",
|
|
minDate: "DATE",
|
|
isRequired: "BOOLEAN",
|
|
},
|
|
defaultProperties: {
|
|
selectedDate: "defaultDate",
|
|
},
|
|
derivedProperties: {
|
|
isValid: "{{ this.isRequired ? !!this.selectedDate : true }}",
|
|
value: "{{ this.selectedDate }}",
|
|
},
|
|
triggerProperties: {
|
|
onDateSelected: true,
|
|
},
|
|
metaProperties: {},
|
|
},
|
|
TABS_WIDGET: {
|
|
validations: {
|
|
tabs: "TABS_DATA",
|
|
defaultTab: "SELECTED_TAB",
|
|
},
|
|
defaultProperties: {},
|
|
derivedProperties: {
|
|
selectedTab:
|
|
"{{_.find(this.tabs, { widgetId: this.selectedTabWidgetId }).label}}",
|
|
},
|
|
triggerProperties: {
|
|
onTabSelected: true,
|
|
},
|
|
metaProperties: {},
|
|
},
|
|
MODAL_WIDGET: {
|
|
validations: {
|
|
isLoading: "BOOLEAN",
|
|
isVisible: "BOOLEAN",
|
|
isDisabled: "BOOLEAN",
|
|
},
|
|
defaultProperties: {},
|
|
derivedProperties: {},
|
|
triggerProperties: {},
|
|
metaProperties: {},
|
|
},
|
|
RICH_TEXT_EDITOR_WIDGET: {
|
|
validations: {
|
|
text: "TEXT",
|
|
placeholder: "TEXT",
|
|
defaultValue: "TEXT",
|
|
isDisabled: "BOOLEAN",
|
|
isVisible: "BOOLEAN",
|
|
},
|
|
defaultProperties: {
|
|
text: "defaultText",
|
|
},
|
|
derivedProperties: {
|
|
value: "{{this.text}}",
|
|
},
|
|
triggerProperties: {
|
|
onTextChange: true,
|
|
},
|
|
metaProperties: {},
|
|
},
|
|
CHART_WIDGET: {
|
|
validations: {
|
|
xAxisName: "TEXT",
|
|
yAxisName: "TEXT",
|
|
chartName: "TEXT",
|
|
isVisible: "BOOLEAN",
|
|
chartData: "CHART_DATA",
|
|
},
|
|
defaultProperties: {},
|
|
derivedProperties: {},
|
|
triggerProperties: {},
|
|
metaProperties: {},
|
|
},
|
|
FORM_WIDGET: {
|
|
validations: {
|
|
isLoading: "BOOLEAN",
|
|
isVisible: "BOOLEAN",
|
|
isDisabled: "BOOLEAN",
|
|
},
|
|
defaultProperties: {},
|
|
derivedProperties: {},
|
|
triggerProperties: {},
|
|
metaProperties: {},
|
|
},
|
|
FORM_BUTTON_WIDGET: {
|
|
validations: {
|
|
isLoading: "BOOLEAN",
|
|
isVisible: "BOOLEAN",
|
|
isDisabled: "BOOLEAN",
|
|
text: "TEXT",
|
|
disabledWhenInvalid: "BOOLEAN",
|
|
buttonStyle: "TEXT",
|
|
buttonType: "TEXT",
|
|
},
|
|
defaultProperties: {},
|
|
derivedProperties: {},
|
|
triggerProperties: {
|
|
onClick: true,
|
|
},
|
|
metaProperties: {},
|
|
},
|
|
MAP_WIDGET: {
|
|
validations: {
|
|
defaultMarkers: "MARKERS",
|
|
isDisabled: "BOOLEAN",
|
|
isVisible: "BOOLEAN",
|
|
enableSearch: "BOOLEAN",
|
|
enablePickLocation: "BOOLEAN",
|
|
allowZoom: "BOOLEAN",
|
|
zoomLevel: "NUMBER",
|
|
mapCenter: "OBJECT",
|
|
},
|
|
defaultProperties: {
|
|
markers: "defaultMarkers",
|
|
center: "mapCenter",
|
|
},
|
|
derivedProperties: {},
|
|
triggerProperties: {
|
|
onMarkerClick: true,
|
|
onCreateMarker: true,
|
|
},
|
|
metaProperties: {},
|
|
},
|
|
CANVAS_WIDGET: {
|
|
validations: {
|
|
isLoading: "BOOLEAN",
|
|
isVisible: "BOOLEAN",
|
|
isDisabled: "BOOLEAN",
|
|
},
|
|
defaultProperties: {},
|
|
derivedProperties: {},
|
|
triggerProperties: {},
|
|
metaProperties: {},
|
|
},
|
|
ICON_WIDGET: {
|
|
validations: {
|
|
isLoading: "BOOLEAN",
|
|
isVisible: "BOOLEAN",
|
|
isDisabled: "BOOLEAN",
|
|
},
|
|
defaultProperties: {},
|
|
derivedProperties: {},
|
|
triggerProperties: {
|
|
onClick: true,
|
|
},
|
|
metaProperties: {},
|
|
},
|
|
SKELETON_WIDGET: {
|
|
validations: {
|
|
isLoading: "BOOLEAN",
|
|
isVisible: "BOOLEAN",
|
|
isDisabled: "BOOLEAN",
|
|
},
|
|
defaultProperties: {},
|
|
derivedProperties: {},
|
|
triggerProperties: {},
|
|
metaProperties: {},
|
|
},
|
|
};
|
|
|
|
const BASE_WIDGET: DataTreeWidget = {
|
|
widgetId: "randomID",
|
|
widgetName: "randomName",
|
|
bottomRow: 0,
|
|
isLoading: false,
|
|
leftColumn: 0,
|
|
parentColumnSpace: 0,
|
|
parentRowSpace: 0,
|
|
renderMode: RenderModes.CANVAS,
|
|
rightColumn: 0,
|
|
topRow: 0,
|
|
type: WidgetTypes.SKELETON_WIDGET,
|
|
parentId: "0",
|
|
ENTITY_TYPE: ENTITY_TYPE.WIDGET,
|
|
};
|
|
|
|
const BASE_ACTION: DataTreeAction = {
|
|
actionId: "randomId",
|
|
name: "randomName",
|
|
config: {
|
|
timeoutInMillisecond: 10,
|
|
},
|
|
dynamicBindingPathList: [],
|
|
isLoading: false,
|
|
pluginType: PluginType.API,
|
|
run: {},
|
|
data: {},
|
|
ENTITY_TYPE: ENTITY_TYPE.ACTION,
|
|
};
|
|
|
|
describe("DataTreeEvaluator", () => {
|
|
const unEvalTree = {
|
|
Text1: {
|
|
...BASE_WIDGET,
|
|
widgetName: "Text1",
|
|
text: "Label",
|
|
type: WidgetTypes.TEXT_WIDGET,
|
|
},
|
|
Text2: {
|
|
...BASE_WIDGET,
|
|
widgetName: "Text2",
|
|
text: "{{Text1.text}}",
|
|
dynamicBindingPathList: [{ key: "text" }],
|
|
type: WidgetTypes.TEXT_WIDGET,
|
|
},
|
|
Text3: {
|
|
...BASE_WIDGET,
|
|
widgetName: "Text3",
|
|
text: "{{Text1.text}}",
|
|
dynamicBindingPathList: [{ key: "text" }],
|
|
type: WidgetTypes.TEXT_WIDGET,
|
|
},
|
|
Dropdown1: {
|
|
...BASE_WIDGET,
|
|
options: [
|
|
{
|
|
label: "test",
|
|
value: "valueTest",
|
|
},
|
|
{
|
|
label: "test2",
|
|
value: "valueTest2",
|
|
},
|
|
],
|
|
type: WidgetTypes.DROP_DOWN_WIDGET,
|
|
},
|
|
Table1: {
|
|
...BASE_WIDGET,
|
|
tableData: "{{Api1.data.map(datum => ({ ...datum, raw: Text1.text }) )}}",
|
|
dynamicBindingPathList: [{ key: "tableData" }],
|
|
type: WidgetTypes.TABLE_WIDGET,
|
|
},
|
|
Text4: {
|
|
...BASE_WIDGET,
|
|
text: "{{Table1.selectedRow.test}}",
|
|
dynamicBindingPathList: [{ key: "text" }],
|
|
type: WidgetTypes.TEXT_WIDGET,
|
|
},
|
|
};
|
|
const evaluator = new DataTreeEvaluator(WIDGET_CONFIG_MAP);
|
|
evaluator.createFirstTree(unEvalTree);
|
|
it("Evaluates a binding in first run", () => {
|
|
const evaluation = evaluator.evalTree;
|
|
const dependencyMap = evaluator.dependencyMap;
|
|
|
|
expect(evaluation).toHaveProperty("Text2.text", "Label");
|
|
expect(evaluation).toHaveProperty("Text3.text", "Label");
|
|
expect(dependencyMap).toStrictEqual({
|
|
Text1: ["Text1.text"],
|
|
Text2: ["Text2.text"],
|
|
Text3: ["Text3.text"],
|
|
Text4: ["Text4.text"],
|
|
Table1: [
|
|
"Table1.tableData",
|
|
"Table1.searchText",
|
|
"Table1.selectedRowIndex",
|
|
"Table1.selectedRowIndices",
|
|
],
|
|
Dropdown1: [
|
|
"Dropdown1.selectedOptionValue",
|
|
"Dropdown1.selectedOptionValueArr",
|
|
],
|
|
"Text2.text": ["Text1.text"],
|
|
"Text3.text": ["Text1.text"],
|
|
"Dropdown1.selectedOptionValue": [],
|
|
"Dropdown1.selectedOptionValueArr": [],
|
|
"Table1.tableData": ["Text1.text"],
|
|
"Table1.searchText": [],
|
|
"Table1.selectedRowIndex": [],
|
|
"Table1.selectedRowIndices": [],
|
|
"Text4.text": [],
|
|
});
|
|
});
|
|
|
|
it("Evaluates a value change in update run", () => {
|
|
const updatedUnEvalTree = {
|
|
...unEvalTree,
|
|
Text1: {
|
|
...unEvalTree.Text1,
|
|
text: "Hey there",
|
|
},
|
|
};
|
|
const updatedEvalTree = evaluator.updateDataTree(updatedUnEvalTree);
|
|
expect(updatedEvalTree).toHaveProperty("Text2.text", "Hey there");
|
|
expect(updatedEvalTree).toHaveProperty("Text3.text", "Hey there");
|
|
});
|
|
|
|
it("Evaluates a dependency change in update run", () => {
|
|
const updatedUnEvalTree = {
|
|
...unEvalTree,
|
|
Text3: {
|
|
...unEvalTree.Text3,
|
|
text: "Label 3",
|
|
},
|
|
};
|
|
const updatedEvalTree = evaluator.updateDataTree(updatedUnEvalTree);
|
|
const updatedDependencyMap = evaluator.dependencyMap;
|
|
expect(updatedEvalTree).toHaveProperty("Text2.text", "Label");
|
|
expect(updatedEvalTree).toHaveProperty("Text3.text", "Label 3");
|
|
expect(updatedDependencyMap).toStrictEqual({
|
|
Text1: ["Text1.text"],
|
|
Text2: ["Text2.text"],
|
|
Text3: ["Text3.text"],
|
|
Text4: ["Text4.text"],
|
|
Table1: [
|
|
"Table1.tableData",
|
|
"Table1.searchText",
|
|
"Table1.selectedRowIndex",
|
|
"Table1.selectedRowIndices",
|
|
],
|
|
Dropdown1: [
|
|
"Dropdown1.selectedOptionValue",
|
|
"Dropdown1.selectedOptionValueArr",
|
|
],
|
|
"Text2.text": ["Text1.text"],
|
|
"Dropdown1.selectedOptionValue": [],
|
|
"Dropdown1.selectedOptionValueArr": [],
|
|
"Table1.tableData": ["Text1.text"],
|
|
"Table1.searchText": [],
|
|
"Table1.selectedRowIndex": [],
|
|
"Table1.selectedRowIndices": [],
|
|
"Text4.text": [],
|
|
});
|
|
});
|
|
|
|
it("Overrides with default value", () => {
|
|
const updatedUnEvalTree = {
|
|
...unEvalTree,
|
|
Input1: {
|
|
...BASE_WIDGET,
|
|
text: undefined,
|
|
defaultText: "Default value",
|
|
widgetName: "Input1",
|
|
type: WidgetTypes.INPUT_WIDGET,
|
|
},
|
|
};
|
|
|
|
const updatedEvalTree = evaluator.updateDataTree(updatedUnEvalTree);
|
|
expect(updatedEvalTree).toHaveProperty("Input1.text", "Default value");
|
|
});
|
|
|
|
it("Evaluates for value changes in nested diff paths", () => {
|
|
const updatedUnEvalTree = {
|
|
...unEvalTree,
|
|
Dropdown1: {
|
|
...BASE_WIDGET,
|
|
options: [
|
|
{
|
|
label: "newValue",
|
|
value: "valueTest",
|
|
},
|
|
{
|
|
label: "test2",
|
|
value: "valueTest2",
|
|
},
|
|
],
|
|
type: WidgetTypes.DROP_DOWN_WIDGET,
|
|
},
|
|
};
|
|
const updatedEvalTree = evaluator.updateDataTree(updatedUnEvalTree);
|
|
expect(updatedEvalTree).toHaveProperty(
|
|
"Dropdown1.options.0.label",
|
|
"newValue",
|
|
);
|
|
});
|
|
|
|
it("Adds an entity with a complicated binding", () => {
|
|
const updatedUnEvalTree = {
|
|
...unEvalTree,
|
|
Api1: {
|
|
...BASE_ACTION,
|
|
data: [
|
|
{
|
|
test: "Hey",
|
|
},
|
|
{
|
|
test: "Ho",
|
|
},
|
|
],
|
|
},
|
|
};
|
|
const updatedEvalTree = evaluator.updateDataTree(updatedUnEvalTree);
|
|
const updatedDependencyMap = evaluator.dependencyMap;
|
|
expect(updatedEvalTree).toHaveProperty("Table1.tableData", [
|
|
{
|
|
test: "Hey",
|
|
raw: "Label",
|
|
},
|
|
{
|
|
test: "Ho",
|
|
raw: "Label",
|
|
},
|
|
]);
|
|
expect(updatedDependencyMap).toStrictEqual({
|
|
Api1: ["Api1.data"],
|
|
Input1: ["Input1.text"],
|
|
Text1: ["Text1.text"],
|
|
Text2: ["Text2.text"],
|
|
Text3: ["Text3.text"],
|
|
Text4: ["Text4.text"],
|
|
Table1: [
|
|
"Table1.tableData",
|
|
"Table1.searchText",
|
|
"Table1.selectedRowIndex",
|
|
"Table1.selectedRowIndices",
|
|
],
|
|
Dropdown1: [
|
|
"Dropdown1.selectedOptionValue",
|
|
"Dropdown1.selectedOptionValueArr",
|
|
],
|
|
"Text2.text": ["Text1.text"],
|
|
"Text3.text": ["Text1.text"],
|
|
"Dropdown1.selectedOptionValue": [],
|
|
"Dropdown1.selectedOptionValueArr": [],
|
|
"Table1.tableData": ["Api1.data", "Text1.text"],
|
|
"Table1.searchText": [],
|
|
"Table1.selectedRowIndex": [],
|
|
"Table1.selectedRowIndices": [],
|
|
"Text4.text": [],
|
|
"Input1.text": [],
|
|
});
|
|
});
|
|
|
|
it("Selects a row", () => {
|
|
const updatedUnEvalTree = {
|
|
...unEvalTree,
|
|
Table1: {
|
|
...unEvalTree.Table1,
|
|
selectedRowIndex: 0,
|
|
selectedRow: {
|
|
test: "Hey",
|
|
raw: "Label",
|
|
},
|
|
},
|
|
Api1: {
|
|
...BASE_ACTION,
|
|
data: [
|
|
{
|
|
test: "Hey",
|
|
},
|
|
{
|
|
test: "Ho",
|
|
},
|
|
],
|
|
},
|
|
};
|
|
const updatedEvalTree = evaluator.updateDataTree(updatedUnEvalTree);
|
|
const updatedDependencyMap = evaluator.dependencyMap;
|
|
expect(updatedEvalTree).toHaveProperty("Table1.tableData", [
|
|
{
|
|
test: "Hey",
|
|
raw: "Label",
|
|
},
|
|
{
|
|
test: "Ho",
|
|
raw: "Label",
|
|
},
|
|
]);
|
|
expect(updatedEvalTree).toHaveProperty("Text4.text", "Hey");
|
|
expect(updatedDependencyMap).toStrictEqual({
|
|
Api1: ["Api1.data"],
|
|
Text1: ["Text1.text"],
|
|
Text2: ["Text2.text"],
|
|
Text3: ["Text3.text"],
|
|
Text4: ["Text4.text"],
|
|
Table1: [
|
|
"Table1.tableData",
|
|
"Table1.selectedRowIndex",
|
|
"Table1.searchText",
|
|
"Table1.selectedRowIndices",
|
|
"Table1.selectedRow",
|
|
],
|
|
"Table1.selectedRow": ["Table1.selectedRow.test"],
|
|
Dropdown1: [
|
|
"Dropdown1.selectedOptionValue",
|
|
"Dropdown1.selectedOptionValueArr",
|
|
],
|
|
Input1: ["Input1.text"],
|
|
"Text2.text": ["Text1.text"],
|
|
"Text3.text": ["Text1.text"],
|
|
"Dropdown1.selectedOptionValue": [],
|
|
"Dropdown1.selectedOptionValueArr": [],
|
|
"Table1.tableData": ["Api1.data", "Text1.text"],
|
|
"Table1.searchText": [],
|
|
"Table1.selectedRowIndex": [],
|
|
"Table1.selectedRowIndices": [],
|
|
"Text4.text": ["Table1.selectedRow.test"],
|
|
"Input1.text": [],
|
|
});
|
|
});
|
|
});
|