PromucFlow_constructor/app/client/src/workers/evaluate.test.ts
Vinod 2bd324a5aa
feat: address few bug with linting and improve highlighting (#7287)
* show lint errors as warnings

* add initial code

* adjust editor positions

* update pr comments

* mark jshint errors

* reset changes

* remove unused prop

* fix test errors

* remove unused imports

* dont show warning in the error counter

* show yellow if warning

* remove active error functionality

* update linter to use async functionality

* update linter messages

* update binding positions

* fix evaluate tests

* dont show undefined errors in debugger

* move lint code to separate file

* update testes

* remove unused import

* update tests

* address pr comments

* add comment to explain why

* replace proper regex

* fix undefined message error

* Update styling for warnings

* address position issue in the linter

* Fix failing tests

* Merge 'release' on to  'Feature/linting-errors'

* add console as global object

* address lint issues

* fix requested linting erros for release

* fix breaking issue

* remove unwanted code

* revert unrelated changes

* remove unnecessary file

* add extra libraries to jshint data

* import lodash functions that are used

* update jshint settings

* Fix failing test

* don't show lint errors if there is a parsing issue

* update jshint to latest version
2021-09-17 16:01:45 +05:30

181 lines
4.6 KiB
TypeScript

import evaluate from "workers/evaluate";
import {
DataTree,
DataTreeWidget,
ENTITY_TYPE,
} from "entities/DataTree/dataTreeFactory";
import { RenderModes } from "constants/WidgetConstants";
describe("evaluate", () => {
const widget: DataTreeWidget = {
bottomRow: 0,
isLoading: false,
leftColumn: 0,
parentColumnSpace: 0,
parentRowSpace: 0,
renderMode: RenderModes.CANVAS,
rightColumn: 0,
topRow: 0,
type: "INPUT_WIDGET",
version: 0,
widgetId: "",
widgetName: "",
text: "value",
ENTITY_TYPE: ENTITY_TYPE.WIDGET,
bindingPaths: {},
triggerPaths: {},
validationPaths: {},
logBlackList: {},
};
const dataTree: DataTree = {
Input1: widget,
};
it("unescapes string before evaluation", () => {
const js = '\\"Hello!\\"';
const response = evaluate(js, {}, {});
expect(response.result).toBe("Hello!");
});
it("throws error for undefined js", () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
expect(() => evaluate(undefined, {})).toThrow(TypeError);
});
it("Returns for syntax errors", () => {
const response1 = evaluate("wrongJS", {}, {});
expect(response1).toStrictEqual({
result: undefined,
triggers: [],
errors: [
{
ch: 1,
code: "W117",
errorMessage: "'wrongJS' is not defined.",
errorSegment: " const result = wrongJS",
errorType: "LINT",
line: 0,
raw: `
function closedFunction () {
const result = wrongJS
return result;
}
closedFunction()
`,
severity: "error",
originalBinding: "wrongJS",
variables: ["wrongJS", undefined, undefined, undefined],
},
{
errorMessage: "ReferenceError: wrongJS is not defined",
errorType: "PARSE",
raw: `
function closedFunction () {
const result = wrongJS
return result;
}
closedFunction()
`,
severity: "error",
originalBinding: "wrongJS",
},
],
});
const response2 = evaluate("{}.map()", {}, {});
expect(response2).toStrictEqual({
result: undefined,
triggers: [],
errors: [
{
errorMessage: "TypeError: {}.map is not a function",
errorType: "PARSE",
raw: `
function closedFunction () {
const result = {}.map()
return result;
}
closedFunction()
`,
severity: "error",
originalBinding: "{}.map()",
},
],
});
});
it("evaluates value from data tree", () => {
const js = "Input1.text";
const response = evaluate(js, dataTree, {});
expect(response.result).toBe("value");
});
it("gets triggers from a function", () => {
const js = "showAlert('message', 'info')";
const response = evaluate(js, dataTree, {}, undefined, true);
//this will be changed again in new implemenation for promises
const data = {
action: {
payload: {
executor: [
{
payload: { message: "message", style: "info" },
type: "SHOW_ALERT",
},
],
then: [],
},
type: "PROMISE",
},
triggerReference: 0,
};
expect(response.result).toEqual(data);
expect(response.triggers).toStrictEqual([
{
type: "PROMISE",
payload: {
executor: [
{
type: "SHOW_ALERT",
payload: {
message: "message",
style: "info",
},
},
],
then: [],
},
},
]);
});
it("disallows unsafe function calls", () => {
const js = "setTimeout(() => {}, 100)";
const response = evaluate(js, dataTree, {});
expect(response).toStrictEqual({
result: undefined,
triggers: [],
errors: [
{
errorMessage: "TypeError: setTimeout is not a function",
errorType: "PARSE",
raw: `
function closedFunction () {
const result = setTimeout(() => {}, 100)
return result;
}
closedFunction()
`,
severity: "error",
originalBinding: "setTimeout(() => {}, 100)",
},
],
});
});
it("has access to extra library functions", () => {
const js = "_.add(1,2)";
const response = evaluate(js, dataTree, {});
expect(response.result).toBe(3);
});
it("evaluates functions with callback data", () => {
const js = "(arg1, arg2) => arg1.value + arg2";
const callbackData = [{ value: "test" }, "1"];
const response = evaluate(js, dataTree, {}, callbackData);
expect(response.result).toBe("test1");
});
});