Odoo18-Base/addons/web/static/tests/core/domain.test.js
2025-01-06 10:57:38 +07:00

590 lines
28 KiB
JavaScript

import { describe, expect, test } from "@odoo/hoot";
import { patchWithCleanup } from "@web/../tests/web_test_helpers";
import { Domain } from "@web/core/domain";
import { PyDate } from "@web/core/py_js/py_date";
describe.current.tags("headless");
//-------------------------------------------------------------------------
// Basic properties
//-------------------------------------------------------------------------
describe("Basic Properties", () => {
test("empty", () => {
expect(new Domain([]).contains({})).toBe(true);
expect(new Domain([]).toString()).toBe("[]");
expect(new Domain([]).toList()).toEqual([]);
});
test("undefined domain", () => {
expect(new Domain(undefined).contains({})).toBe(true);
expect(new Domain(undefined).toString()).toBe("[]");
expect(new Domain(undefined).toList()).toEqual([]);
});
test("simple condition", () => {
expect(new Domain([["a", "=", 3]]).contains({ a: 3 })).toBe(true);
expect(new Domain([["a", "=", 3]]).contains({ a: 5 })).toBe(false);
expect(new Domain([["a", "=", 3]]).toString()).toBe(`[("a", "=", 3)]`);
expect(new Domain([["a", "=", 3]]).toList()).toEqual([["a", "=", 3]]);
});
test("can be created from domain", () => {
const domain = new Domain([["a", "=", 3]]);
expect(new Domain(domain).toString()).toBe(`[("a", "=", 3)]`);
});
test("basic", () => {
const record = {
a: 3,
group_method: "line",
select1: "day",
rrule_type: "monthly",
};
expect(new Domain([["a", "=", 3]]).contains(record)).toBe(true);
expect(new Domain([["a", "=", 5]]).contains(record)).toBe(false);
expect(new Domain([["group_method", "!=", "count"]]).contains(record)).toBe(true);
expect(
new Domain([
["select1", "=", "day"],
["rrule_type", "=", "monthly"],
]).contains(record)
).toBe(true);
});
test("support of '=?' operator", () => {
const record = { a: 3 };
expect(new Domain([["a", "=?", null]]).contains(record)).toBe(true);
expect(new Domain([["a", "=?", false]]).contains(record)).toBe(true);
expect(new Domain(["!", ["a", "=?", false]]).contains(record)).toBe(false);
expect(new Domain([["a", "=?", 1]]).contains(record)).toBe(false);
expect(new Domain([["a", "=?", 3]]).contains(record)).toBe(true);
expect(new Domain(["!", ["a", "=?", 3]]).contains(record)).toBe(false);
});
test("or", () => {
const currentDomain = [
"|",
["section_id", "=", 42],
"|",
["user_id", "=", 3],
["member_ids", "in", [3]],
];
const record = {
section_id: null,
user_id: null,
member_ids: null,
};
expect(new Domain(currentDomain).contains({ ...record, section_id: 42 })).toBe(true);
expect(new Domain(currentDomain).contains({ ...record, user_id: 3 })).toBe(true);
expect(new Domain(currentDomain).contains({ ...record, member_ids: 3 })).toBe(true);
});
test("and", () => {
const domain = new Domain(["&", "&", ["a", "=", 1], ["b", "=", 2], ["c", "=", 3]]);
expect(domain.contains({ a: 1, b: 2, c: 3 })).toBe(true);
expect(domain.contains({ a: -1, b: 2, c: 3 })).toBe(false);
expect(domain.contains({ a: 1, b: -1, c: 3 })).toBe(false);
expect(domain.contains({ a: 1, b: 2, c: -1 })).toBe(false);
});
test("not", () => {
const record = {
a: 5,
group_method: "line",
};
expect(new Domain(["!", ["a", "=", 3]]).contains(record)).toBe(true);
expect(new Domain(["!", ["group_method", "=", "count"]]).contains(record)).toBe(true);
});
test("like, =like, ilike, =ilike, not like and not ilike", () => {
expect.assertions(28);
expect(new Domain([["a", "like", "value"]]).contains({ a: "value" })).toBe(true);
expect(new Domain([["a", "like", "value"]]).contains({ a: "some value" })).toBe(true);
expect(new Domain([["a", "like", "value"]]).contains({ a: "Some Value" })).not.toBe(true);
expect(new Domain([["a", "like", "value"]]).contains({ a: false })).toBe(false);
expect(new Domain([["a", "=like", "%value"]]).contains({ a: "value" })).toBe(true);
expect(new Domain([["a", "=like", "%value"]]).contains({ a: "some value" })).toBe(true);
expect(new Domain([["a", "=like", "%value"]]).contains({ a: "Some Value" })).not.toBe(true);
expect(new Domain([["a", "=like", "%value"]]).contains({ a: false })).toBe(false);
expect(new Domain([["a", "ilike", "value"]]).contains({ a: "value" })).toBe(true);
expect(new Domain([["a", "ilike", "value"]]).contains({ a: "some value" })).toBe(true);
expect(new Domain([["a", "ilike", "value"]]).contains({ a: "Some Value" })).toBe(true);
expect(new Domain([["a", "ilike", "value"]]).contains({ a: false })).toBe(false);
expect(new Domain([["a", "=ilike", "%value"]]).contains({ a: "value" })).toBe(true);
expect(new Domain([["a", "=ilike", "%value"]]).contains({ a: "some value" })).toBe(true);
expect(new Domain([["a", "=ilike", "%value"]]).contains({ a: "Some Value" })).toBe(true);
expect(new Domain([["a", "=ilike", "%value"]]).contains({ a: false })).toBe(false);
expect(new Domain([["a", "not like", "value"]]).contains({ a: "value" })).not.toBe(true);
expect(new Domain([["a", "not like", "value"]]).contains({ a: "some value" })).not.toBe(
true
);
expect(new Domain([["a", "not like", "value"]]).contains({ a: "Some Value" })).toBe(true);
expect(new Domain([["a", "not like", "value"]]).contains({ a: "something" })).toBe(true);
expect(new Domain([["a", "not like", "value"]]).contains({ a: "Something" })).toBe(true);
expect(new Domain([["a", "not like", "value"]]).contains({ a: false })).toBe(false);
expect(new Domain([["a", "not ilike", "value"]]).contains({ a: "value" })).not.toBe(true);
expect(new Domain([["a", "not ilike", "value"]]).contains({ a: "some value" })).toBe(false);
expect(new Domain([["a", "not ilike", "value"]]).contains({ a: "Some Value" })).toBe(false);
expect(new Domain([["a", "not ilike", "value"]]).contains({ a: "something" })).toBe(true);
expect(new Domain([["a", "not ilike", "value"]]).contains({ a: "Something" })).toBe(true);
expect(new Domain([["a", "not ilike", "value"]]).contains({ a: false })).toBe(false);
});
test("complex domain", () => {
const domain = new Domain(["&", "!", ["a", "=", 1], "|", ["a", "=", 2], ["a", "=", 3]]);
expect(domain.contains({ a: 1 })).toBe(false);
expect(domain.contains({ a: 2 })).toBe(true);
expect(domain.contains({ a: 3 })).toBe(true);
expect(domain.contains({ a: 4 })).toBe(false);
});
test("toList", () => {
expect(new Domain([]).toList()).toEqual([]);
expect(new Domain([["a", "=", 3]]).toList()).toEqual([["a", "=", 3]]);
expect(
new Domain([
["a", "=", 3],
["b", "!=", "4"],
]).toList()
).toEqual(["&", ["a", "=", 3], ["b", "!=", "4"]]);
expect(new Domain(["!", ["a", "=", 3]]).toList()).toEqual(["!", ["a", "=", 3]]);
});
test("toString", () => {
expect(new Domain([]).toString()).toBe(`[]`);
expect(new Domain([["a", "=", 3]]).toString()).toBe(`[("a", "=", 3)]`);
expect(
new Domain([
["a", "=", 3],
["b", "!=", "4"],
]).toString()
).toBe(`["&", ("a", "=", 3), ("b", "!=", "4")]`);
expect(new Domain(["!", ["a", "=", 3]]).toString()).toBe(`["!", ("a", "=", 3)]`);
expect(new Domain([["name", "=", null]]).toString()).toBe('[("name", "=", None)]');
expect(new Domain([["name", "=", false]]).toString()).toBe('[("name", "=", False)]');
expect(new Domain([["name", "=", true]]).toString()).toBe('[("name", "=", True)]');
expect(new Domain([["name", "=", "null"]]).toString()).toBe('[("name", "=", "null")]');
expect(new Domain([["name", "=", "false"]]).toString()).toBe('[("name", "=", "false")]');
expect(new Domain([["name", "=", "true"]]).toString()).toBe('[("name", "=", "true")]');
expect(new Domain().toString()).toBe("[]");
expect(new Domain([["name", "in", [true, false]]]).toString()).toBe(
'[("name", "in", [True, False])]'
);
expect(new Domain([["name", "in", [null]]]).toString()).toBe('[("name", "in", [None])]');
expect(new Domain([["name", "in", ["foo", "bar"]]]).toString()).toBe(
'[("name", "in", ["foo", "bar"])]'
);
expect(new Domain([["name", "in", [1, 2]]]).toString()).toBe('[("name", "in", [1, 2])]');
expect(new Domain(["&", ["name", "=", "foo"], ["type", "=", "bar"]]).toString()).toBe(
'["&", ("name", "=", "foo"), ("type", "=", "bar")]'
);
expect(new Domain(["|", ["name", "=", "foo"], ["type", "=", "bar"]]).toString()).toBe(
'["|", ("name", "=", "foo"), ("type", "=", "bar")]'
);
expect(new Domain().toString()).toBe("[]");
// string domains are only reformatted
expect(new Domain('[("name","ilike","foo")]').toString()).toBe(
'[("name", "ilike", "foo")]'
);
});
test("toJson", () => {
expect(new Domain([]).toJson()).toEqual([]);
expect(new Domain("[]").toJson()).toEqual([]);
expect(new Domain([["a", "=", 3]]).toJson()).toEqual([["a", "=", 3]]);
expect(new Domain('[("a", "=", 3)]').toJson()).toEqual([["a", "=", 3]]);
expect(new Domain('[("user_id", "=", uid)]').toJson()).toBe('[("user_id", "=", uid)]');
expect(new Domain('[("date", "=", context_today())]').toJson()).toBe(
'[("date", "=", context_today())]'
);
});
test("implicit &", () => {
const domain = new Domain([
["a", "=", 3],
["b", "=", 4],
]);
expect(domain.contains({})).toBe(false);
expect(domain.contains({ a: 3, b: 4 })).toBe(true);
expect(domain.contains({ a: 3, b: 5 })).toBe(false);
});
test("comparison operators", () => {
expect(new Domain([["a", "=", 3]]).contains({ a: 3 })).toBe(true);
expect(new Domain([["a", "=", 3]]).contains({ a: 4 })).toBe(false);
expect(new Domain([["a", "=", 3]]).toString()).toBe(`[("a", "=", 3)]`);
expect(new Domain([["a", "==", 3]]).contains({ a: 3 })).toBe(true);
expect(new Domain([["a", "==", 3]]).contains({ a: 4 })).toBe(false);
expect(new Domain([["a", "==", 3]]).toString()).toBe(`[("a", "==", 3)]`);
expect(new Domain([["a", "!=", 3]]).contains({ a: 3 })).toBe(false);
expect(new Domain([["a", "!=", 3]]).contains({ a: 4 })).toBe(true);
expect(new Domain([["a", "!=", 3]]).toString()).toBe(`[("a", "!=", 3)]`);
expect(new Domain([["a", "<>", 3]]).contains({ a: 3 })).toBe(false);
expect(new Domain([["a", "<>", 3]]).contains({ a: 4 })).toBe(true);
expect(new Domain([["a", "<>", 3]]).toString()).toBe(`[("a", "<>", 3)]`);
expect(new Domain([["a", "<", 3]]).contains({ a: 5 })).toBe(false);
expect(new Domain([["a", "<", 3]]).contains({ a: 3 })).toBe(false);
expect(new Domain([["a", "<", 3]]).contains({ a: 2 })).toBe(true);
expect(new Domain([["a", "<", 3]]).toString()).toBe(`[("a", "<", 3)]`);
expect(new Domain([["a", "<=", 3]]).contains({ a: 5 })).toBe(false);
expect(new Domain([["a", "<=", 3]]).contains({ a: 3 })).toBe(true);
expect(new Domain([["a", "<=", 3]]).contains({ a: 2 })).toBe(true);
expect(new Domain([["a", "<=", 3]]).toString()).toBe(`[("a", "<=", 3)]`);
expect(new Domain([["a", ">", 3]]).contains({ a: 5 })).toBe(true);
expect(new Domain([["a", ">", 3]]).contains({ a: 3 })).toBe(false);
expect(new Domain([["a", ">", 3]]).contains({ a: 2 })).toBe(false);
expect(new Domain([["a", ">", 3]]).toString()).toBe(`[("a", ">", 3)]`);
expect(new Domain([["a", ">=", 3]]).contains({ a: 5 })).toBe(true);
expect(new Domain([["a", ">=", 3]]).contains({ a: 3 })).toBe(true);
expect(new Domain([["a", ">=", 3]]).contains({ a: 2 })).toBe(false);
expect(new Domain([["a", ">=", 3]]).toString()).toBe(`[("a", ">=", 3)]`);
});
test("other operators", () => {
expect(new Domain([["a", "in", 3]]).contains({ a: 3 })).toBe(true);
expect(new Domain([["a", "in", [1, 2, 3]]]).contains({ a: 3 })).toBe(true);
expect(new Domain([["a", "in", [1, 2, 3]]]).contains({ a: [3] })).toBe(true);
expect(new Domain([["a", "in", 3]]).contains({ a: 5 })).toBe(false);
expect(new Domain([["a", "in", [1, 2, 3]]]).contains({ a: 5 })).toBe(false);
expect(new Domain([["a", "in", [1, 2, 3]]]).contains({ a: [5] })).toBe(false);
expect(new Domain([["a", "not in", 3]]).contains({ a: 3 })).toBe(false);
expect(new Domain([["a", "not in", [1, 2, 3]]]).contains({ a: 3 })).toBe(false);
expect(new Domain([["a", "not in", [1, 2, 3]]]).contains({ a: [3] })).toBe(false);
expect(new Domain([["a", "not in", 3]]).contains({ a: 5 })).toBe(true);
expect(new Domain([["a", "not in", [1, 2, 3]]]).contains({ a: 5 })).toBe(true);
expect(new Domain([["a", "not in", [1, 2, 3]]]).contains({ a: [5] })).toBe(true);
expect(new Domain([["a", "like", "abc"]]).contains({ a: "abc" })).toBe(true);
expect(new Domain([["a", "like", "abc"]]).contains({ a: "def" })).toBe(false);
expect(new Domain([["a", "=like", "abc"]]).contains({ a: "abc" })).toBe(true);
expect(new Domain([["a", "=like", "abc"]]).contains({ a: "def" })).toBe(false);
expect(new Domain([["a", "ilike", "abc"]]).contains({ a: "abc" })).toBe(true);
expect(new Domain([["a", "ilike", "abc"]]).contains({ a: "def" })).toBe(false);
expect(new Domain([["a", "=ilike", "abc"]]).contains({ a: "abc" })).toBe(true);
expect(new Domain([["a", "=ilike", "abc"]]).contains({ a: "def" })).toBe(false);
});
test("creating a domain with a string expression", () => {
expect(new Domain(`[('a', '>=', 3)]`).toString()).toBe(`[("a", ">=", 3)]`);
expect(new Domain(`[('a', '>=', 3)]`).contains({ a: 5 })).toBe(true);
});
test("can evaluate a python expression", () => {
expect(new Domain(`[('date', '!=', False)]`).toList()).toEqual([["date", "!=", false]]);
expect(new Domain(`[('date', '!=', False)]`).toList()).toEqual([["date", "!=", false]]);
expect(new Domain(`[('date', '!=', 1 + 2)]`).toString()).toBe(`[("date", "!=", 1 + 2)]`);
expect(new Domain(`[('date', '!=', 1 + 2)]`).toList()).toEqual([["date", "!=", 3]]);
expect(new Domain(`[('a', '==', 1 + 2)]`).contains({ a: 3 })).toBe(true);
expect(new Domain(`[('a', '==', 1 + 2)]`).contains({ a: 2 })).toBe(false);
});
test("some expression with date stuff", () => {
patchWithCleanup(PyDate, {
today() {
return new PyDate(2013, 4, 24);
},
});
expect(
new Domain(
"[('date','>=', (context_today() - datetime.timedelta(days=30)).strftime('%Y-%m-%d'))]"
).toList()
).toEqual([["date", ">=", "2013-03-25"]]);
const domainList = new Domain(
"[('date', '>=', context_today() - relativedelta(days=30))]"
).toList(); // domain creation using `parseExpr` function since the parameter is a string.
expect(domainList[0][2]).toEqual(PyDate.create({ day: 25, month: 3, year: 2013 }), {
message: "The right item in the rule in the domain should be a PyDate object",
});
expect(JSON.stringify(domainList)).toBe('[["date",">=","2013-03-25"]]');
const domainList2 = new Domain(domainList).toList(); // domain creation using `toAST` function since the parameter is a list.
expect(domainList2[0][2]).toEqual(PyDate.create({ day: 25, month: 3, year: 2013 }), {
message: "The right item in the rule in the domain should be a PyDate object",
});
expect(JSON.stringify(domainList2)).toBe('[["date",">=","2013-03-25"]]');
});
test("Check that there is no dependency between two domains", () => {
// The purpose of this test is to verify that a domain created on the basis
// of another one does not share any dependency.
const domain1 = new Domain(`[('date', '!=', False)]`);
const domain2 = new Domain(domain1);
expect(domain1.toString()).toBe(domain2.toString());
domain2.ast.value.unshift({ type: 1, value: "!" });
expect(domain1.toString()).not.toBe(domain2.toString());
});
test("TRUE and FALSE Domain", () => {
expect(Domain.TRUE.contains({})).toBe(true);
expect(Domain.FALSE.contains({})).toBe(false);
expect(Domain.and([Domain.TRUE, new Domain([["a", "=", 3]])]).contains({ a: 3 })).toBe(
true
);
expect(Domain.and([Domain.FALSE, new Domain([["a", "=", 3]])]).contains({ a: 3 })).toBe(
false
);
});
test("invalid domains should not succeed", () => {
expect(() => new Domain(["|", ["hr_presence_state", "=", "absent"]])).toThrow(
/invalid domain .* \(missing 1 segment/
);
expect(
() =>
new Domain([
"|",
"|",
["hr_presence_state", "=", "absent"],
["attendance_state", "=", "checked_in"],
])
).toThrow(/invalid domain .* \(missing 1 segment/);
expect(() => new Domain(["|", "|", ["hr_presence_state", "=", "absent"]])).toThrow(
/invalid domain .* \(missing 2 segment\(s\)/
);
expect(() => new Domain(["&", ["composition_mode", "!=", "mass_post"]])).toThrow(
/invalid domain .* \(missing 1 segment/
);
expect(() => new Domain(["!"])).toThrow(/invalid domain .* \(missing 1 segment/);
expect(() => new Domain(`[(1, 2)]`)).toThrow(/Invalid domain AST/);
expect(() => new Domain(`[(1, 2, 3, 4)]`)).toThrow(/Invalid domain AST/);
expect(() => new Domain(`["a"]`)).toThrow(/Invalid domain AST/);
expect(() => new Domain(`[1]`)).toThrow(/Invalid domain AST/);
expect(() => new Domain(`[x]`)).toThrow(/Invalid domain AST/);
expect(() => new Domain(`[True]`)).toThrow(/Invalid domain AST/); // will possibly change with CHM work
expect(() => new Domain(`[(x.=, "=", 1)]`)).toThrow(/Invalid domain representation/);
expect(() => new Domain(`[(+, "=", 1)]`)).toThrow(/Invalid domain representation/);
expect(() => new Domain([{}])).toThrow(/Invalid domain representation/);
expect(() => new Domain([1])).toThrow(/Invalid domain representation/);
});
test("follow relations", () => {
expect(
new Domain([["partner.city", "ilike", "Bru"]]).contains({
name: "Lucas",
partner: {
city: "Bruxelles",
},
})
).toBe(true);
expect(
new Domain([["partner.city.name", "ilike", "Bru"]]).contains({
name: "Lucas",
partner: {
city: {
name: "Bruxelles",
},
},
})
).toBe(true);
});
test("Arrays comparison", () => {
const domain = new Domain(["&", ["a", "==", []], ["b", "!=", []]]);
expect(domain.contains({ a: [] })).toBe(true);
expect(domain.contains({ a: [], b: [4] })).toBe(true);
expect(domain.contains({ a: [1] })).toBe(false);
expect(domain.contains({ b: [] })).toBe(false);
});
});
// ---------------------------------------------------------------------------
// Normalization
// ---------------------------------------------------------------------------
describe("Normalization", () => {
test("return simple (normalized) domains", () => {
const domains = ["[]", `[("a", "=", 1)]`, `["!", ("a", "=", 1)]`];
for (const domain of domains) {
expect(new Domain(domain).toString()).toBe(domain);
}
});
test("properly add the & in a non normalized domain", () => {
expect(new Domain(`[("a", "=", 1), ("b", "=", 2)]`).toString()).toBe(
`["&", ("a", "=", 1), ("b", "=", 2)]`
);
});
test("normalize domain with ! operator", () => {
expect(new Domain(`["!", ("a", "=", 1), ("b", "=", 2)]`).toString()).toBe(
`["&", "!", ("a", "=", 1), ("b", "=", 2)]`
);
});
});
// ---------------------------------------------------------------------------
// Combining domains
// ---------------------------------------------------------------------------
describe("Combining domains", () => {
test("combining zero domain", () => {
expect(Domain.combine([], "AND").toString()).toBe("[]");
expect(Domain.combine([], "OR").toString()).toBe("[]");
expect(Domain.combine([], "AND").contains({ a: 1, b: 2 })).toBe(true);
});
test("combining one domain", () => {
expect(Domain.combine([`[("a", "=", 1)]`], "AND").toString()).toBe(`[("a", "=", 1)]`);
expect(Domain.combine([`[("user_id", "=", uid)]`], "AND").toString()).toBe(
`[("user_id", "=", uid)]`
);
expect(Domain.combine([[["a", "=", 1]]], "AND").toString()).toBe(`[("a", "=", 1)]`);
expect(Domain.combine(["[('a', '=', '1'), ('b', '!=', 2)]"], "AND").toString()).toBe(
`["&", ("a", "=", "1"), ("b", "!=", 2)]`
);
});
test("combining two domains", () => {
expect(Domain.combine([`[("a", "=", 1)]`, "[]"], "AND").toString()).toBe(`[("a", "=", 1)]`);
expect(Domain.combine([`[("a", "=", 1)]`, []], "AND").toString()).toBe(`[("a", "=", 1)]`);
expect(Domain.combine([new Domain(`[("a", "=", 1)]`), "[]"], "AND").toString()).toBe(
`[("a", "=", 1)]`
);
expect(Domain.combine([new Domain(`[("a", "=", 1)]`), "[]"], "OR").toString()).toBe(
`[("a", "=", 1)]`
);
expect(Domain.combine([[["a", "=", 1]], "[('uid', '<=', uid)]"], "AND").toString()).toBe(
`["&", ("a", "=", 1), ("uid", "<=", uid)]`
);
expect(Domain.combine([[["a", "=", 1]], "[('b', '<=', 3)]"], "OR").toString()).toBe(
`["|", ("a", "=", 1), ("b", "<=", 3)]`
);
expect(
Domain.combine(
["[('a', '=', '1'), ('c', 'in', [4, 5])]", "[('b', '<=', 3)]"],
"OR"
).toString()
).toBe(`["|", "&", ("a", "=", "1"), ("c", "in", [4, 5]), ("b", "<=", 3)]`);
expect(
Domain.combine(
[new Domain("[('a', '=', '1'), ('c', 'in', [4, 5])]"), "[('b', '<=', 3)]"],
"OR"
).toString()
).toBe(`["|", "&", ("a", "=", "1"), ("c", "in", [4, 5]), ("b", "<=", 3)]`);
});
test("combining three domains", () => {
expect(
Domain.combine(
[
new Domain("[('a', '=', '1'), ('c', 'in', [4, 5])]"),
[["b", "<=", 3]],
`['!', ('uid', '=', uid)]`,
],
"OR"
).toString()
).toBe(
`["|", "&", ("a", "=", "1"), ("c", "in", [4, 5]), "|", ("b", "<=", 3), "!", ("uid", "=", uid)]`
);
});
});
// ---------------------------------------------------------------------------
// OPERATOR AND / OR / NOT
// ---------------------------------------------------------------------------
describe("Operator and - or - not", () => {
test("combining two domains with and/or", () => {
expect(Domain.and([`[("a", "=", 1)]`, "[]"]).toString()).toBe(`[("a", "=", 1)]`);
expect(Domain.and([`[("a", "=", 1)]`, []]).toString()).toBe(`[("a", "=", 1)]`);
expect(Domain.and([new Domain(`[("a", "=", 1)]`), "[]"]).toString()).toBe(
`[("a", "=", 1)]`
);
expect(Domain.or([new Domain(`[("a", "=", 1)]`), "[]"]).toString()).toBe(`[("a", "=", 1)]`);
expect(Domain.and([[["a", "=", 1]], "[('uid', '<=', uid)]"]).toString()).toBe(
`["&", ("a", "=", 1), ("uid", "<=", uid)]`
);
expect(Domain.or([[["a", "=", 1]], "[('b', '<=', 3)]"]).toString()).toBe(
`["|", ("a", "=", 1), ("b", "<=", 3)]`
);
expect(
Domain.or(["[('a', '=', '1'), ('c', 'in', [4, 5])]", "[('b', '<=', 3)]"]).toString()
).toBe(`["|", "&", ("a", "=", "1"), ("c", "in", [4, 5]), ("b", "<=", 3)]`);
expect(
Domain.or([
new Domain("[('a', '=', '1'), ('c', 'in', [4, 5])]"),
"[('b', '<=', 3)]",
]).toString()
).toBe(`["|", "&", ("a", "=", "1"), ("c", "in", [4, 5]), ("b", "<=", 3)]`);
});
test("apply `NOT` on a Domain", () => {
expect(Domain.not("[('a', '=', 1)]").toString()).toBe(`["!", ("a", "=", 1)]`);
expect(Domain.not('[("uid", "<=", uid)]').toString()).toBe(`["!", ("uid", "<=", uid)]`);
expect(Domain.not(new Domain("[('a', '=', 1)]")).toString()).toBe(`["!", ("a", "=", 1)]`);
expect(Domain.not(new Domain([["a", "=", 1]])).toString()).toBe(`["!", ("a", "=", 1)]`);
});
test("tuple are supported", () => {
expect(
new Domain(`(("field", "like", "string"), ("field", "like", "strOng"))`).toList()
).toEqual(["&", ["field", "like", "string"], ["field", "like", "strOng"]]);
expect(new Domain(`("!",("field", "like", "string"))`).toList()).toEqual([
"!",
["field", "like", "string"],
]);
expect(() => new Domain(`(("field", "like", "string"))`)).toThrow(/Invalid domain AST/);
expect(() => new Domain(`("&", "&", "|")`)).toThrow(/Invalid domain AST/);
expect(() => new Domain(`("&", "&", 3)`)).toThrow(/Invalid domain AST/);
});
});
describe("Remove domain leaf", () => {
test("Remove leaf in domain.", () => {
let domain = [
["start_datetime", "!=", false],
["end_datetime", "!=", false],
["sale_line_id", "!=", false],
];
const keysToRemove = ["start_datetime", "end_datetime"];
let newDomain = Domain.removeDomainLeaves(domain, keysToRemove);
let expectedDomain = new Domain([
"&",
...Domain.TRUE.toList({}),
...Domain.TRUE.toList({}),
["sale_line_id", "!=", false],
]);
expect(newDomain.toList({})).toEqual(expectedDomain.toList({}));
domain = [
"|",
["role_id", "=", false],
"&",
["resource_id", "!=", false],
["start_datetime", "=", false],
["sale_line_id", "!=", false],
];
newDomain = Domain.removeDomainLeaves(domain, keysToRemove);
expectedDomain = new Domain([
"|",
["role_id", "=", false],
"&",
["resource_id", "!=", false],
...Domain.TRUE.toList({}),
["sale_line_id", "!=", false],
]);
expect(newDomain.toList({})).toEqual(expectedDomain.toList({}));
domain = [
"|",
["start_datetime", "=", false],
["end_datetime", "=", false],
["sale_line_id", "!=", false],
];
newDomain = Domain.removeDomainLeaves(domain, keysToRemove);
expectedDomain = new Domain([...Domain.TRUE.toList({}), ["sale_line_id", "!=", false]]);
expect(newDomain.toList({})).toEqual(expectedDomain.toList({}));
});
});