[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.
This commit is contained in:
Géry Debongnie
2018-07-06 14:09:09 +02:00
committed by Adrien Dieudonne
parent 3248498f48
commit 0194d85b67
2 changed files with 69 additions and 0 deletions
+30
View File
@@ -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,
};
});
@@ -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)]"
);
});
});
});