[REF] web: use pseudo constructors to create (condition) trees
We define some helpers to easily create condition trees and use them where it is possible. closes odoo/odoo#139377 Signed-off-by: Michaël Mattiello (mcm) <mcm@odoo.com>
This commit is contained in:
@@ -4,7 +4,12 @@ import { extractPathsFromDomain, useGetDefaultCondition } from "@web/core/domain
|
||||
import { Component, onWillStart, onWillUpdateProps } from "@odoo/owl";
|
||||
import { Domain } from "@web/core/domain";
|
||||
import { TreeEditor } from "@web/core/tree_editor/tree_editor";
|
||||
import { domainFromTree, treeFromDomain, formatValue } from "@web/core/tree_editor/condition_tree";
|
||||
import {
|
||||
domainFromTree,
|
||||
treeFromDomain,
|
||||
formatValue,
|
||||
condition,
|
||||
} from "@web/core/tree_editor/condition_tree";
|
||||
import { useLoadFieldInfo } from "@web/core/model_field_selector/utils";
|
||||
import { CheckBox } from "@web/core/checkbox/checkbox";
|
||||
import { deepEqual } from "@web/core/utils/objects";
|
||||
@@ -13,13 +18,7 @@ import { getOperatorEditorInfo } from "@web/core/tree_editor/tree_editor_operato
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
import { ModelFieldSelector } from "@web/core/model_field_selector/model_field_selector";
|
||||
|
||||
const ARCHIVED_CONDITION = {
|
||||
type: "condition",
|
||||
value: [true, false],
|
||||
negate: false,
|
||||
path: "active",
|
||||
operator: "in",
|
||||
};
|
||||
const ARCHIVED_CONDITION = condition("active", "in", [true, false]);
|
||||
const ARCHIVED_DOMAIN = `[("active", "in", [True, False])]`;
|
||||
|
||||
export class DomainSelector extends Component {
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
normalizeValue,
|
||||
formatValue as toString,
|
||||
createVirtualOperators,
|
||||
condition,
|
||||
} from "@web/core/tree_editor/condition_tree";
|
||||
import { useLoadFieldInfo, useLoadPathDescription } from "@web/core/model_field_selector/utils";
|
||||
import {
|
||||
@@ -41,13 +42,7 @@ function getDefaultCondition(fieldDefs) {
|
||||
const fieldDef = fieldDefs[defaultPath];
|
||||
const operator = getDomainDisplayedOperators(fieldDef)[0];
|
||||
const value = getDefaultValue(fieldDef, operator);
|
||||
return {
|
||||
type: "condition",
|
||||
negate: false,
|
||||
path: fieldDef.name,
|
||||
operator,
|
||||
value,
|
||||
};
|
||||
return condition(fieldDef.name, operator, value);
|
||||
}
|
||||
|
||||
function getDefaultDomain(fieldDefs) {
|
||||
@@ -111,13 +106,7 @@ function simplifyTree(tree) {
|
||||
value.push(...child.value);
|
||||
}
|
||||
}
|
||||
children.push({
|
||||
type: "condition",
|
||||
negate: false,
|
||||
operator: "in",
|
||||
path: path,
|
||||
value: normalizeValue(value),
|
||||
});
|
||||
children.push(condition(path, "in", normalizeValue(value)));
|
||||
}
|
||||
if (children.length === 1) {
|
||||
return { ...children[0] };
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
|
||||
import { Component, onWillStart, onWillUpdateProps } from "@odoo/owl";
|
||||
import { getExpressionDisplayedOperators } from "@web/core/expression_editor/expression_editor_operator_editor";
|
||||
import { expressionFromTree, treeFromExpression } from "@web/core/tree_editor/condition_tree";
|
||||
import {
|
||||
condition,
|
||||
expressionFromTree,
|
||||
treeFromExpression,
|
||||
} from "@web/core/tree_editor/condition_tree";
|
||||
import { TreeEditor } from "@web/core/tree_editor/tree_editor";
|
||||
import { getOperatorEditorInfo } from "@web/core/tree_editor/tree_editor_operator_editor";
|
||||
import { getDefaultValue } from "@web/core/tree_editor/tree_editor_value_editors";
|
||||
@@ -13,13 +17,7 @@ function getDefaultCondition(fieldDefs) {
|
||||
const fieldDef = fieldDefs[defaultPath];
|
||||
const operator = getExpressionDisplayedOperators(fieldDef)[0];
|
||||
const value = getDefaultValue(fieldDef, operator);
|
||||
return {
|
||||
type: "condition",
|
||||
negate: false,
|
||||
path: fieldDef.name,
|
||||
operator,
|
||||
value,
|
||||
};
|
||||
return condition(fieldDef.name, operator, value);
|
||||
}
|
||||
|
||||
class ExpressionEditorFieldSelector extends Component {
|
||||
|
||||
@@ -31,27 +31,15 @@ import { toPyValue } from "@web/core/py_js/py_utils";
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} AND
|
||||
* @typedef {Object} Connector
|
||||
* @property {"connector"} type
|
||||
* @property {boolean} negate
|
||||
* @property {"&"} value
|
||||
* @property {(Connector|OR)[]} children
|
||||
* @property {"|"|"&"} value
|
||||
* @property {Tree[]} children
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} OR
|
||||
* @property {"connector"} type
|
||||
* @property {boolean} negate
|
||||
* @property {"|"} value
|
||||
* @property {(Connector|AND)[]} children
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {AND|OR|Condition} SimpleTree
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {AND|OR|Condition|ComplexCondition} Tree
|
||||
* @typedef {Connector|Condition|ComplexCondition} Tree
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -112,6 +100,70 @@ export class Expression {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} expr
|
||||
* @returns {Expression}
|
||||
*/
|
||||
export function expression(expr) {
|
||||
return new Expression(expr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {"|"|"&"} value
|
||||
* @param {Tree[]} [children=[]]
|
||||
* @param {boolean} [negate=false]
|
||||
* @returns {Connector}
|
||||
*/
|
||||
export function connector(value, children = [], negate = false) {
|
||||
return { type: "connector", value, children, negate };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Value} path
|
||||
* @param {Value} operator
|
||||
* @param {Value} value
|
||||
* @param {boolean} [negate=false]
|
||||
* @returns {Condition}
|
||||
*/
|
||||
export function condition(path, operator, value, negate = false) {
|
||||
return { type: "condition", path, operator, value, negate };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @returns {ComplexCondition}
|
||||
*/
|
||||
export function complexCondition(value) {
|
||||
parseExpr(value);
|
||||
return { type: "complex_condition", value };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Value} value
|
||||
* @returns {Value}
|
||||
*/
|
||||
function cloneValue(value) {
|
||||
if (value instanceof Expression) {
|
||||
return new Expression(value.toAST());
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(cloneValue);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Tree} tree
|
||||
* @returns {Tree}
|
||||
*/
|
||||
export function cloneTree(tree) {
|
||||
const clone = {};
|
||||
for (const key in tree) {
|
||||
clone[key] = cloneValue(tree[key]);
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
export function formatValue(value) {
|
||||
return formatAST(toAST(value));
|
||||
}
|
||||
@@ -239,7 +291,7 @@ function _construcTree(ASTs, distributeNot, negate = false) {
|
||||
*/
|
||||
function construcTree(initialASTs, options) {
|
||||
if (!initialASTs.length) {
|
||||
return { type: "connector", value: "&", negate: false, children: [] };
|
||||
return connector("&");
|
||||
}
|
||||
const { tree } = _construcTree(initialASTs, options.distributeNot);
|
||||
return tree;
|
||||
@@ -342,8 +394,6 @@ function _getConditionFromComparator(ast, options) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const tree = { type: "condition", negate: false };
|
||||
|
||||
let operator = ast.op;
|
||||
if (operator === "==") {
|
||||
operator = "=";
|
||||
@@ -364,18 +414,15 @@ function _getConditionFromComparator(ast, options) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
tree.path = left.value;
|
||||
tree.operator = operator;
|
||||
tree.value = toValue(right);
|
||||
|
||||
return tree;
|
||||
return condition(left.value, operator, toValue(right));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {AST} ast
|
||||
* @param {Options} options
|
||||
* @param {boolean} [negate=false]
|
||||
* @returns {import("@web/core/tree_editor/condition_tree").Condition|ComplexCondition}
|
||||
* @returns {Condition|ComplexCondition}
|
||||
*/
|
||||
function _leafFromAST(ast, options, negate = false) {
|
||||
if (isNot(ast)) {
|
||||
@@ -383,24 +430,12 @@ function _leafFromAST(ast, options, negate = false) {
|
||||
}
|
||||
|
||||
if (ast.type === 5 /** name */ && isValidPath(ast, options)) {
|
||||
return {
|
||||
type: "condition",
|
||||
negate: false,
|
||||
path: ast.value,
|
||||
operator: negate ? "=" : "!=",
|
||||
value: false,
|
||||
};
|
||||
return condition(ast.value, negate ? "=" : "!=", false);
|
||||
}
|
||||
|
||||
const astValue = toValue(ast);
|
||||
if (["boolean", "number", "string"].includes(typeof astValue)) {
|
||||
return {
|
||||
negate: false,
|
||||
type: "condition",
|
||||
path: astValue ? 1 : 0,
|
||||
operator: "=",
|
||||
value: 1,
|
||||
};
|
||||
return condition(astValue ? 1 : 0, "=", 1);
|
||||
}
|
||||
|
||||
if (ast.type === 7 && COMPARATORS.includes(ast.op)) {
|
||||
@@ -414,10 +449,7 @@ function _leafFromAST(ast, options, negate = false) {
|
||||
}
|
||||
|
||||
// no conclusive way to transform ast in a condition
|
||||
return {
|
||||
type: "complex_condition",
|
||||
value: formatAST(negate ? not(ast) : ast),
|
||||
};
|
||||
return complexCondition(formatAST(negate ? not(ast) : ast));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -432,14 +464,11 @@ function _treeFromAST(ast, options, negate = false) {
|
||||
}
|
||||
|
||||
if (ast.type === 14) {
|
||||
const tree = {
|
||||
type: "connector",
|
||||
value: ast.op === "and" ? "&" : "|", // and/or are the only ops that are given type 14 (for now)
|
||||
children: [],
|
||||
};
|
||||
const tree = connector(
|
||||
ast.op === "and" ? "&" : "|" // and/or are the only ops that are given type 14 (for now)
|
||||
);
|
||||
if (options.distributeNot && negate) {
|
||||
tree.value = tree.value === "&" ? "|" : "&";
|
||||
tree.negate = false;
|
||||
} else {
|
||||
tree.negate = negate;
|
||||
}
|
||||
@@ -574,13 +603,9 @@ function createBetweenOperators(tree) {
|
||||
child1.operator === ">=" &&
|
||||
child2.operator === "<="
|
||||
) {
|
||||
children.push({
|
||||
type: "condition",
|
||||
negate: false,
|
||||
path: child1.path,
|
||||
operator: "between",
|
||||
value: normalizeValue([child1.value, child2.value]),
|
||||
});
|
||||
children.push(
|
||||
condition(child1.path, "between", normalizeValue([child1.value, child2.value]))
|
||||
);
|
||||
i += 1;
|
||||
} else {
|
||||
children.push(child1);
|
||||
@@ -605,27 +630,11 @@ export function removeBetweenOperators(tree) {
|
||||
return tree;
|
||||
}
|
||||
const { negate, path, value } = tree;
|
||||
return {
|
||||
type: "connector",
|
||||
negate,
|
||||
value: "&",
|
||||
children: [
|
||||
{
|
||||
type: "condition",
|
||||
negate: false,
|
||||
path,
|
||||
operator: ">=",
|
||||
value: value[0],
|
||||
},
|
||||
{
|
||||
type: "condition",
|
||||
negate: false,
|
||||
path,
|
||||
operator: "<=",
|
||||
value: value[1],
|
||||
},
|
||||
],
|
||||
};
|
||||
return connector(
|
||||
"&",
|
||||
[condition(path, ">=", value[0]), condition(path, "<=", value[1])],
|
||||
negate
|
||||
);
|
||||
}
|
||||
const processedChildren = tree.children.map(removeBetweenOperators);
|
||||
if (tree.value === "|") {
|
||||
@@ -701,15 +710,12 @@ function createComplexConditions(tree) {
|
||||
if (tree.path instanceof Expression && tree.operator === "=" && tree.value === 1) {
|
||||
// not sure about this one -> we should maybe evaluate the condition and check
|
||||
// if it does not become something e.g. the name of a integer field?
|
||||
return {
|
||||
type: "complex_condition",
|
||||
value: String(tree.path),
|
||||
};
|
||||
return complexCondition(String(tree.path));
|
||||
}
|
||||
return { ...tree };
|
||||
return cloneTree(tree);
|
||||
}
|
||||
if (tree.type === "complex_condition") {
|
||||
return { ...tree };
|
||||
return cloneTree(tree);
|
||||
}
|
||||
return {
|
||||
...tree,
|
||||
@@ -723,16 +729,11 @@ function createComplexConditions(tree) {
|
||||
*/
|
||||
function removeComplexConditions(tree) {
|
||||
if (tree.type === "condition") {
|
||||
return { ...tree };
|
||||
return cloneTree(tree);
|
||||
}
|
||||
if (tree.type === "complex_condition") {
|
||||
const ast = parseExpr(tree.value);
|
||||
return {
|
||||
type: "condition",
|
||||
path: new Expression(bool(ast)),
|
||||
operator: "=",
|
||||
value: 1,
|
||||
};
|
||||
return condition(new Expression(bool(ast)), "=", 1);
|
||||
}
|
||||
return {
|
||||
...tree,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import {
|
||||
cloneTree,
|
||||
leafToString,
|
||||
useLoadDisplayNames,
|
||||
extractIdsFromTree,
|
||||
@@ -11,7 +10,13 @@ import {
|
||||
import { Component, onWillStart, onWillUpdateProps } from "@odoo/owl";
|
||||
import { Dropdown } from "@web/core/dropdown/dropdown";
|
||||
import { DropdownItem } from "@web/core/dropdown/dropdown_item";
|
||||
import { formatValue, removeVirtualOperators } from "@web/core/tree_editor/condition_tree";
|
||||
import {
|
||||
condition,
|
||||
cloneTree,
|
||||
formatValue,
|
||||
removeVirtualOperators,
|
||||
connector,
|
||||
} from "@web/core/tree_editor/condition_tree";
|
||||
import {
|
||||
getDefaultValue,
|
||||
getValueEditorInfo,
|
||||
@@ -20,21 +25,9 @@ import { ModelFieldSelector } from "@web/core/model_field_selector/model_field_s
|
||||
import { useLoadFieldInfo } from "@web/core/model_field_selector/utils";
|
||||
import { deepEqual, shallowEqual } from "@web/core/utils/objects";
|
||||
|
||||
const TRUE_TREE = {
|
||||
type: "condition",
|
||||
value: 1,
|
||||
negate: false,
|
||||
path: 1,
|
||||
operator: "=",
|
||||
};
|
||||
const TRUE_TREE = condition(1, "=", 1);
|
||||
|
||||
const DEFAULT_CONDITION = {
|
||||
type: "condition",
|
||||
path: "id",
|
||||
negate: false,
|
||||
operator: "=",
|
||||
value: 1,
|
||||
};
|
||||
const DEFAULT_CONDITION = condition("id", "=", 1);
|
||||
|
||||
function collectDifferences(tree, otherTree) {
|
||||
// some differences shadow the other differences "below":
|
||||
@@ -132,19 +125,9 @@ export class TreeEditor extends Component {
|
||||
async onPropsUpdated(props) {
|
||||
this.tree = cloneTree(props.tree);
|
||||
if (shallowEqual(this.tree, TRUE_TREE)) {
|
||||
this.tree = {
|
||||
type: "connector",
|
||||
negate: false,
|
||||
value: props.defaultConnector,
|
||||
children: [],
|
||||
};
|
||||
this.tree = connector(props.defaultConnector);
|
||||
} else if (this.tree.type !== "connector") {
|
||||
this.tree = {
|
||||
type: "connector",
|
||||
negate: false,
|
||||
value: props.defaultConnector,
|
||||
children: [this.tree],
|
||||
};
|
||||
this.tree = connector(props.defaultConnector, [this.tree]);
|
||||
}
|
||||
|
||||
if (this.previousTree) {
|
||||
@@ -213,13 +196,8 @@ export class TreeEditor extends Component {
|
||||
return cloneTree(this.props.defaultCondition);
|
||||
}
|
||||
|
||||
createNewBranch(connector) {
|
||||
return {
|
||||
type: "connector",
|
||||
value: connector,
|
||||
negate: false,
|
||||
children: [this.createNewLeaf(), this.createNewLeaf()],
|
||||
};
|
||||
createNewBranch(value) {
|
||||
return connector(value, [this.createNewLeaf(), this.createNewLeaf()]);
|
||||
}
|
||||
|
||||
insertRootLeaf(parent) {
|
||||
|
||||
@@ -6,32 +6,6 @@ import { Expression } from "@web/core/tree_editor/condition_tree";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
|
||||
/**
|
||||
* @param {import("@web/core/tree_editor/condition_tree").Value} value
|
||||
* @returns {import("@web/core/tree_editor/condition_tree").Value}
|
||||
*/
|
||||
function cloneValue(value) {
|
||||
if (value instanceof Expression) {
|
||||
return new Expression(value.toAST());
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(cloneValue);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import("@web/core/tree_editor/condition_tree").Tree} tree
|
||||
* @returns {import("@web/core/tree_editor/condition_tree").Tree}
|
||||
*/
|
||||
export function cloneTree(tree) {
|
||||
const clone = {};
|
||||
for (const key in tree) {
|
||||
clone[key] = cloneValue(tree[key]);
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import("@web/core/tree_editor/condition_tree").Value} val
|
||||
* @param {boolean} disambiguate
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import {
|
||||
complexCondition,
|
||||
condition,
|
||||
connector,
|
||||
domainFromExpression,
|
||||
domainFromTree,
|
||||
expression,
|
||||
Expression,
|
||||
expressionFromDomain,
|
||||
expressionFromTree,
|
||||
@@ -15,39 +19,27 @@ QUnit.module("condition tree", {});
|
||||
QUnit.test("domainFromTree", function (assert) {
|
||||
const toTest = [
|
||||
{
|
||||
tree: { type: "condition", negate: false, path: "foo", operator: "=", value: false },
|
||||
tree: condition("foo", "=", false),
|
||||
result: `[("foo", "=", False)]`,
|
||||
},
|
||||
{
|
||||
tree: { type: "condition", negate: true, path: "foo", operator: "=", value: false },
|
||||
tree: condition("foo", "=", false, true),
|
||||
result: `["!", ("foo", "=", False)]`,
|
||||
},
|
||||
{
|
||||
tree: { type: "condition", negate: false, path: "foo", operator: "=?", value: false },
|
||||
tree: condition("foo", "=?", false),
|
||||
result: `[("foo", "=?", False)]`,
|
||||
},
|
||||
{
|
||||
tree: { type: "condition", negate: true, path: "foo", operator: "=?", value: false },
|
||||
tree: condition("foo", "=?", false, true),
|
||||
result: `["!", ("foo", "=?", False)]`,
|
||||
},
|
||||
{
|
||||
tree: {
|
||||
type: "condition",
|
||||
negate: false,
|
||||
path: "foo",
|
||||
operator: "between",
|
||||
value: [1, 3],
|
||||
},
|
||||
tree: condition("foo", "between", [1, 3]),
|
||||
result: `["&", ("foo", ">=", 1), ("foo", "<=", 3)]`,
|
||||
},
|
||||
{
|
||||
tree: {
|
||||
type: "condition",
|
||||
negate: true,
|
||||
path: "foo",
|
||||
operator: "between",
|
||||
value: [1, new Expression({ type: 5, value: "uid" })],
|
||||
},
|
||||
tree: condition("foo", "between", [1, expression("uid")], true),
|
||||
result: `["!", "&", ("foo", ">=", 1), ("foo", "<=", uid)]`,
|
||||
},
|
||||
];
|
||||
@@ -255,80 +247,35 @@ QUnit.test("expressionFromTree", function (assert) {
|
||||
};
|
||||
const toTest = [
|
||||
{
|
||||
expressionTree: {
|
||||
type: "condition",
|
||||
path: "x",
|
||||
negate: false,
|
||||
operator: "=",
|
||||
value: false,
|
||||
},
|
||||
expressionTree: condition("x", "=", false),
|
||||
result: `not x`,
|
||||
},
|
||||
{
|
||||
expressionTree: {
|
||||
type: "condition",
|
||||
path: "x",
|
||||
negate: true,
|
||||
operator: "=",
|
||||
value: false,
|
||||
},
|
||||
expressionTree: condition("x", "=", false, true),
|
||||
result: `x`,
|
||||
},
|
||||
{
|
||||
expressionTree: {
|
||||
type: "condition",
|
||||
path: "x",
|
||||
negate: false,
|
||||
operator: "!=",
|
||||
value: false,
|
||||
},
|
||||
expressionTree: condition("x", "!=", false),
|
||||
result: `x`,
|
||||
},
|
||||
{
|
||||
expressionTree: {
|
||||
type: "condition",
|
||||
path: "x",
|
||||
negate: true,
|
||||
operator: "!=",
|
||||
value: false,
|
||||
},
|
||||
expressionTree: condition("x", "!=", false, true),
|
||||
result: `not x`,
|
||||
},
|
||||
{
|
||||
expressionTree: {
|
||||
type: "condition",
|
||||
path: "y",
|
||||
negate: false,
|
||||
operator: "=",
|
||||
value: false,
|
||||
},
|
||||
expressionTree: condition("y", "=", false),
|
||||
result: `not "y"`,
|
||||
},
|
||||
{
|
||||
expressionTree: {
|
||||
type: "condition",
|
||||
path: "x",
|
||||
negate: false,
|
||||
operator: "between",
|
||||
value: [1, 3],
|
||||
},
|
||||
expressionTree: condition("x", "between", [1, 3]),
|
||||
result: `x >= 1 and x <= 3`,
|
||||
},
|
||||
{
|
||||
expressionTree: {
|
||||
type: "condition",
|
||||
path: "x",
|
||||
negate: true,
|
||||
operator: "between",
|
||||
value: [1, new Expression("uid")],
|
||||
},
|
||||
expressionTree: condition("x", "between", [1, expression("uid")], true),
|
||||
result: `not ( x >= 1 and x <= uid )`,
|
||||
},
|
||||
{
|
||||
expressionTree: {
|
||||
type: "complex_condition",
|
||||
value: "uid",
|
||||
},
|
||||
expressionTree: complexCondition("uid"),
|
||||
result: `uid`,
|
||||
},
|
||||
];
|
||||
@@ -353,202 +300,70 @@ QUnit.test("treeFromExpression", function (assert) {
|
||||
const toTest = [
|
||||
{
|
||||
expression: `not foo`,
|
||||
result: {
|
||||
type: "condition",
|
||||
path: "foo",
|
||||
negate: false,
|
||||
operator: "not_set",
|
||||
value: false,
|
||||
},
|
||||
result: condition("foo", "not_set", false),
|
||||
},
|
||||
{
|
||||
expression: `foo == False`,
|
||||
result: {
|
||||
type: "condition",
|
||||
path: "foo",
|
||||
operator: "not_set",
|
||||
negate: false,
|
||||
value: false,
|
||||
},
|
||||
result: condition("foo", "not_set", false),
|
||||
},
|
||||
{
|
||||
expression: `foo`,
|
||||
result: {
|
||||
type: "condition",
|
||||
path: "foo",
|
||||
negate: false,
|
||||
operator: "set",
|
||||
value: false,
|
||||
},
|
||||
result: condition("foo", "set", false),
|
||||
},
|
||||
{
|
||||
expression: `foo == True`,
|
||||
result: {
|
||||
type: "condition",
|
||||
path: "foo",
|
||||
negate: false,
|
||||
operator: "=",
|
||||
value: true,
|
||||
},
|
||||
result: condition("foo", "=", true),
|
||||
},
|
||||
{
|
||||
expression: `foo is True`,
|
||||
result: {
|
||||
type: "complex_condition",
|
||||
value: `foo is True`,
|
||||
},
|
||||
result: complexCondition(`foo is True`),
|
||||
},
|
||||
{
|
||||
expression: `not (foo == False)`,
|
||||
result: {
|
||||
type: "condition",
|
||||
path: "foo",
|
||||
negate: false,
|
||||
operator: "set",
|
||||
value: false,
|
||||
},
|
||||
result: condition("foo", "set", false),
|
||||
},
|
||||
{
|
||||
expression: `not (not foo)`,
|
||||
result: {
|
||||
type: "condition",
|
||||
path: "foo",
|
||||
negate: false,
|
||||
operator: "set",
|
||||
value: false,
|
||||
},
|
||||
result: condition("foo", "set", false),
|
||||
},
|
||||
{
|
||||
expression: `foo >= 1 and foo <= 3`,
|
||||
result: {
|
||||
type: "condition",
|
||||
negate: false,
|
||||
operator: "between",
|
||||
path: "foo",
|
||||
value: [1, 3],
|
||||
},
|
||||
result: condition("foo", "between", [1, 3]),
|
||||
},
|
||||
{
|
||||
expression: `foo >= 1 and foo <= uid`,
|
||||
result: {
|
||||
type: "condition",
|
||||
path: "foo",
|
||||
negate: false,
|
||||
operator: "between",
|
||||
value: [1, new Expression("uid")],
|
||||
},
|
||||
result: condition("foo", "between", [1, expression("uid")]),
|
||||
},
|
||||
{
|
||||
expression: `foo >= 1 if bar else foo <= uid`,
|
||||
result: {
|
||||
type: "connector",
|
||||
negate: false,
|
||||
value: "|",
|
||||
children: [
|
||||
{
|
||||
type: "connector",
|
||||
negate: false,
|
||||
value: "&",
|
||||
children: [
|
||||
{
|
||||
type: "condition",
|
||||
path: "bar",
|
||||
negate: false,
|
||||
operator: "set",
|
||||
value: false,
|
||||
},
|
||||
{
|
||||
type: "condition",
|
||||
path: "foo",
|
||||
negate: false,
|
||||
operator: ">=",
|
||||
value: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "connector",
|
||||
negate: false,
|
||||
value: "&",
|
||||
children: [
|
||||
{
|
||||
type: "condition",
|
||||
path: "bar",
|
||||
negate: false,
|
||||
operator: "not_set",
|
||||
value: false,
|
||||
},
|
||||
{
|
||||
type: "condition",
|
||||
path: "foo",
|
||||
negate: false,
|
||||
operator: "<=",
|
||||
value: new Expression("uid"),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
result: connector("|", [
|
||||
connector("&", [condition("bar", "set", false), condition("foo", ">=", 1)]),
|
||||
connector("&", [
|
||||
condition("bar", "not_set", false),
|
||||
condition("foo", "<=", new Expression("uid")),
|
||||
]),
|
||||
]),
|
||||
},
|
||||
{
|
||||
expression: `context.get('toto')`,
|
||||
result: {
|
||||
type: "complex_condition",
|
||||
value: `context.get("toto")`,
|
||||
},
|
||||
result: complexCondition(`context.get("toto")`),
|
||||
},
|
||||
{
|
||||
expression: `not context.get('toto')`,
|
||||
result: {
|
||||
type: "complex_condition",
|
||||
value: `not context.get("toto")`,
|
||||
},
|
||||
result: complexCondition(`not context.get("toto")`),
|
||||
},
|
||||
{
|
||||
expression: `foo >= 1 if context.get('toto') else bar == 42`,
|
||||
result: {
|
||||
type: "connector",
|
||||
negate: false,
|
||||
value: "|",
|
||||
children: [
|
||||
{
|
||||
type: "connector",
|
||||
negate: false,
|
||||
value: "&",
|
||||
children: [
|
||||
{
|
||||
type: "complex_condition",
|
||||
value: `context.get("toto")`,
|
||||
},
|
||||
{
|
||||
type: "condition",
|
||||
path: "foo",
|
||||
negate: false,
|
||||
operator: ">=",
|
||||
value: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "connector",
|
||||
negate: false,
|
||||
value: "&",
|
||||
children: [
|
||||
{
|
||||
type: "complex_condition",
|
||||
value: `not context.get("toto")`,
|
||||
},
|
||||
{
|
||||
type: "condition",
|
||||
path: "bar",
|
||||
negate: false,
|
||||
operator: "=",
|
||||
value: 42,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
result: connector("|", [
|
||||
connector("&", [
|
||||
complexCondition(`context.get("toto")`),
|
||||
condition("foo", ">=", 1),
|
||||
]),
|
||||
connector("&", [
|
||||
complexCondition(`not context.get("toto")`),
|
||||
condition("bar", "=", 42),
|
||||
]),
|
||||
]),
|
||||
},
|
||||
];
|
||||
for (const { expression, result, extraOptions } of toTest) {
|
||||
|
||||
Reference in New Issue
Block a user