diff options
| author | Géry Debongnie <ged@odoo.com> | 2018-06-22 11:47:51 +0200 |
|---|---|---|
| committer | Adrien Dieudonne <adr@odoo.com> | 2018-07-06 14:09:09 +0200 |
| commit | 0194d85b67c38701befa7d8560a211358fcf79e9 (patch) | |
| tree | 04cdf311d6d592d3e58c64f2edba4ccfbd2dcc5a /addons/web/static | |
| parent | 3248498f4844bbeb06768c064b6fd3a1f400030e (diff) | |
[IMP] web: implement normalize domain utility function
In this commit, we implement a function which normalize a domain
represented as a py.js syntax tree.
Diffstat (limited to 'addons/web/static')
| -rw-r--r-- | addons/web/static/src/js/core/py_utils.js | 30 | ||||
| -rw-r--r-- | addons/web/static/tests/core/py_utils_tests.js | 39 |
2 files changed, 69 insertions, 0 deletions
diff --git a/addons/web/static/src/js/core/py_utils.js b/addons/web/static/src/js/core/py_utils.js index c077cfc2e7e..f275302279b 100644 --- a/addons/web/static/src/js/core/py_utils.js +++ b/addons/web/static/src/js/core/py_utils.js @@ -407,6 +407,35 @@ function formatAST(ast, lbp) { throw new Error("Unimplemented python construct"); } +/** + * Normalize a domain, at the level of the AST. + * + * Note: this function does not evaluate anything inside the domain. This is + * actually quite critical because this allows the manipulation of unevaluated + * (dynamic) domains. + * + * @param {PyJS AST} domain valid AST representing a domain + * @returns {PyJS AST} normalized domain AST + */ +function normalizeDomain(domain) { + var expected = 1; + for (var i = 0; i < domain.first.length; i++) { + var value = domain.first[i].value; + if (value === '&' || value === '|') { + expected++; + } else if (value !== '!') { + expected--; + } + } + var andOperator = py.tokenize("'&'")[0]; + + if (expected < 0) { + domain.first.unshift.apply(domain.first, _.times(Math.abs(expected), _.constant(andOperator))); + } + + return domain; +} + return { context: pycontext, ensure_evaluated: ensure_evaluated, @@ -414,6 +443,7 @@ return { eval_domains_and_contexts: eval_domains_and_contexts, py_eval: py_eval, formatAST: formatAST, + normalizeDomain: normalizeDomain, }; }); diff --git a/addons/web/static/tests/core/py_utils_tests.js b/addons/web/static/tests/core/py_utils_tests.js index 99fe3c60862..fafb3d8f6ca 100644 --- a/addons/web/static/tests/core/py_utils_tests.js +++ b/addons/web/static/tests/core/py_utils_tests.js @@ -1159,6 +1159,45 @@ QUnit.module('core', function () { assert.checkAST(expr); }); + QUnit.module('pyutils (normalizeDomain)'); + + QUnit.assert.checkNormalization = function (domainStr, normalizedDomain) { + normalizedDomain = normalizedDomain || domainStr; + var domainAST = py.parse(py.tokenize(domainStr)); + var normalizedDomainAST = pyUtils.normalizeDomain(domainAST); + var result = pyUtils.formatAST(normalizedDomainAST); + this.pushResult({ + result: result === normalizedDomain, + actual: result, + expected: normalizedDomain + }); + }; + + + QUnit.test("return simple (normalized) domains", function (assert) { + assert.expect(3); + + assert.checkNormalization("[]"); + assert.checkNormalization("[('a', '=', 1)]"); + assert.checkNormalization("['!', ('a', '=', 1)]"); + }); + + QUnit.test("properly add the & in a non normalized domain", function (assert) { + assert.expect(1); + assert.checkNormalization( + "[('a', '=', 1), ('b', '=', 2)]", + "['&', ('a', '=', 1), ('b', '=', 2)]" + ); + }); + + QUnit.test("normalize domain with ! operator", function (assert) { + assert.expect(1); + assert.checkNormalization( + "['!', ('a', '=', 1), ('b', '=', 2)]", + "['&', '!', ('a', '=', 1), ('b', '=', 2)]" + ); + }); + }); }); |
