2022-10-31 22:58:04 +01:00
|
|
|
// SPDX-FileCopyrightText: 2022 Johannes Loher
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
|
|
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
|
|
|
|
import { defaultEvaluator, Evaluator, mathEvaluator } from "../../src/expression-evaluation/evaluator";
|
|
|
|
|
|
|
|
describe("Evaluator", () => {
|
2023-07-10 22:23:13 +02:00
|
|
|
it("evaluates expressions that only use identifiers according to the given predicate", () => {
|
|
|
|
// given
|
|
|
|
const expression = "typeof 'foo' === 'string' ? 42 : null";
|
2022-10-31 22:58:04 +01:00
|
|
|
|
2023-07-10 22:23:13 +02:00
|
|
|
// when
|
|
|
|
const result = defaultEvaluator.evaluate(expression);
|
2022-10-31 22:58:04 +01:00
|
|
|
|
2023-07-10 22:23:13 +02:00
|
|
|
// then
|
|
|
|
expect(result).toEqual(42);
|
|
|
|
});
|
2022-10-31 22:58:04 +01:00
|
|
|
|
2023-07-10 22:23:13 +02:00
|
|
|
it("fails to evaluate expressions that contain identifiers that are not allowed by the predicate", () => {
|
|
|
|
// given
|
|
|
|
const expression = "typeof 'foo' === 'string' ? 42 : function (){}";
|
2022-10-31 22:58:04 +01:00
|
|
|
|
2023-07-10 22:23:13 +02:00
|
|
|
// when
|
|
|
|
const evaluate = () => defaultEvaluator.evaluate(expression);
|
2022-10-31 22:58:04 +01:00
|
|
|
|
2023-07-10 22:23:13 +02:00
|
|
|
// then
|
|
|
|
expect(evaluate).toThrowError("'function' is not an allowed identifier.");
|
|
|
|
});
|
2022-10-31 22:58:04 +01:00
|
|
|
|
2023-07-10 22:23:13 +02:00
|
|
|
it("fails to evaluate expressions that contain invalid tokens", () => {
|
|
|
|
// given
|
|
|
|
const expression = "1;";
|
2022-10-31 22:58:04 +01:00
|
|
|
|
2023-07-10 22:23:13 +02:00
|
|
|
// when
|
|
|
|
const evaluate = () => defaultEvaluator.evaluate(expression);
|
2022-10-31 22:58:04 +01:00
|
|
|
|
2023-07-10 22:23:13 +02:00
|
|
|
// then
|
|
|
|
expect(evaluate).toThrowError("Invalid or unexpected token (1)");
|
|
|
|
});
|
2022-10-31 22:58:04 +01:00
|
|
|
|
2023-07-10 22:23:13 +02:00
|
|
|
it("fails to evaluate expressions that contain arrow functions", () => {
|
|
|
|
// given
|
|
|
|
const expression = "(() => 1)()";
|
2022-10-31 22:58:04 +01:00
|
|
|
|
2023-07-10 22:23:13 +02:00
|
|
|
// when
|
|
|
|
const evaluate = () => defaultEvaluator.evaluate(expression);
|
2022-10-31 22:58:04 +01:00
|
|
|
|
2023-07-10 22:23:13 +02:00
|
|
|
// then
|
|
|
|
expect(evaluate).toThrowError("Invalid or unexpected token (4)");
|
|
|
|
});
|
2022-10-31 22:58:04 +01:00
|
|
|
|
2023-07-10 22:23:13 +02:00
|
|
|
it("makes the given context available", () => {
|
|
|
|
// given
|
|
|
|
const context = { floor: Math.floor };
|
|
|
|
const evaluator = new Evaluator({ context });
|
|
|
|
const expression = "floor(0.5)";
|
2022-10-31 22:58:04 +01:00
|
|
|
|
2023-07-10 22:23:13 +02:00
|
|
|
// when
|
|
|
|
const result = evaluator.evaluate(expression);
|
2022-10-31 22:58:04 +01:00
|
|
|
|
2023-07-10 22:23:13 +02:00
|
|
|
// then
|
|
|
|
expect(result).toEqual(0);
|
|
|
|
});
|
2022-10-31 22:58:04 +01:00
|
|
|
|
2023-07-10 22:23:13 +02:00
|
|
|
describe("mathEvaluator", () => {
|
|
|
|
it("makes the given context available", () => {
|
|
|
|
// given
|
|
|
|
const expression = "sqrt(sin(PI))";
|
2022-10-31 22:58:04 +01:00
|
|
|
|
2023-07-10 22:23:13 +02:00
|
|
|
// when
|
|
|
|
const result = mathEvaluator.evaluate(expression);
|
2022-10-31 22:58:04 +01:00
|
|
|
|
2023-07-10 22:23:13 +02:00
|
|
|
// then
|
|
|
|
expect(result).toEqual(Math.sqrt(Math.sin(Math.PI)));
|
|
|
|
});
|
2022-10-31 22:58:04 +01:00
|
|
|
|
2023-07-10 22:23:13 +02:00
|
|
|
it("does not give acces to the function constructor", () => {
|
|
|
|
// given
|
|
|
|
const expression = "sqrt.constructor";
|
2022-10-31 22:58:04 +01:00
|
|
|
|
2023-07-10 22:23:13 +02:00
|
|
|
// when
|
|
|
|
const evaluate = () => mathEvaluator.evaluate(expression);
|
2022-10-31 22:58:04 +01:00
|
|
|
|
2023-07-10 22:23:13 +02:00
|
|
|
// then
|
|
|
|
expect(evaluate).toThrowError("'constructor' is not an allowed identifier.");
|
2022-10-31 22:58:04 +01:00
|
|
|
});
|
2023-07-10 22:23:13 +02:00
|
|
|
});
|
2022-10-31 22:58:04 +01:00
|
|
|
});
|