feat(eval): handle globals

This commit is contained in:
Ajai Shankar
2023-02-11 08:57:27 -06:00
parent 429ca4093c
commit 3d22f77226
2 changed files with 57 additions and 13 deletions

View File

@@ -44,32 +44,32 @@ describe("utils", () => {
it("should identify top level variables", () => {
const expr = "res.data.pets[0].toUpperCase()";
evaluateJsExpression(expr, context);
expect(cache.get(expr).toString()).toContain("const { res } = context;");
expect(cache.get(expr).toString()).toContain("let { res } = context;");
});
it("should not duplicate variables", () => {
const expr = "res.data.pets[0] + res.data.pets[1]";
evaluateJsExpression(expr, context);
expect(cache.get(expr).toString()).toContain("const { res } = context;");
expect(cache.get(expr).toString()).toContain("let { res } = context;");
});
it("should exclude js keywords like true false from vars", () => {
const expr = "res.data.pets.length > 0 ? true : false";
evaluateJsExpression(expr, context);
expect(cache.get(expr).toString()).toContain("const { res } = context;");
expect(cache.get(expr).toString()).toContain("let { res } = context;");
});
it("should exclude numbers from vars", () => {
const expr = "res.data.pets.length + 10";
evaluateJsExpression(expr, context);
expect(cache.get(expr).toString()).toContain("const { res } = context;");
expect(cache.get(expr).toString()).toContain("let { res } = context;");
});
it("should pick variables from complex expressions", () => {
const expr = "res.data.pets.map(pet => pet.length)";
const result = evaluateJsExpression(expr, context);
expect(result).toEqual([5, 3]);
expect(cache.get(expr).toString()).toContain("const { res, pet } = context;");
expect(cache.get(expr).toString()).toContain("let { res, pet } = context;");
});
it("should be ok picking extra vars from strings", () => {
@@ -77,7 +77,39 @@ describe("utils", () => {
const result = evaluateJsExpression(expr, context);
expect(result).toBe("hello bruno");
// extra var hello is harmless
expect(cache.get(expr).toString()).toContain("const { hello, res } = context;");
expect(cache.get(expr).toString()).toContain("let { hello, res } = context;");
});
it("should evaluate expressions referencing globals", () => {
const startTime = new Date("2022-02-01").getTime();
const currentTime = new Date("2022-02-02").getTime();
jest.useFakeTimers({ now: currentTime });
const expr = "Math.max(Date.now(), startTime)";
const result = evaluateJsExpression(expr, { startTime });
expect(result).toBe(currentTime);
expect(cache.get(expr).toString()).toContain("Math = Math ?? globalThis.Math;");
expect(cache.get(expr).toString()).toContain("Date = Date ?? globalThis.Date;");
});
it("should use global overridden in context", () => {
const startTime = new Date("2022-02-01").getTime();
const currentTime = new Date("2022-02-02").getTime();
jest.useFakeTimers({ now: currentTime });
const context = {
Date: { now: () => new Date("2022-01-31").getTime() },
startTime
};
const expr = "Math.max(Date.now(), startTime)";
const result = evaluateJsExpression(expr, context);
expect(result).toBe(startTime);
});
});
});