[FIX] qwebjs: add tests to test suite
This commit is contained in:
@@ -57,7 +57,7 @@
|
||||
</result>
|
||||
|
||||
<t t-name="basic-caller">
|
||||
<t t-call="{{True and '_basic-callee' or 'other'}}"/>
|
||||
<t t-call="{{1 and '_basic-callee' or 'other'}}"/>
|
||||
</t>
|
||||
<result id="basic-caller">ok</result>
|
||||
</templates>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
</t>
|
||||
</t>
|
||||
<t t-call="_callee-asc-toto"/>
|
||||
<t t-set="toto"><t t-set="truc" t-value="'bbb'"/><i t-att-notruc="not truc" t-att-truc="bool(truc)">i</i></t>
|
||||
<t t-set="toto"><t t-set="truc" t-value="'bbb'"/><i t-att-notruc="not truc" t-att-truc="truc and 'ok'">i</i></t>
|
||||
<t t-call="_callee-asc-toto"/>
|
||||
</t>
|
||||
|
||||
@@ -49,6 +49,6 @@
|
||||
|
||||
<div>toto default</div>
|
||||
|
||||
<div><i truc="True">i</i></div>
|
||||
<div><i truc="ok">i</i></div>
|
||||
]]></result>
|
||||
</templates>
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="/web/static/lib/jquery/jquery.js"></script>
|
||||
<link rel="stylesheet" href="/web/static/lib/qunit/qunit.css" type="text/css" media="screen"/>
|
||||
<script type="text/javascript" src="/web/static/lib/qunit/qunit.js"></script>
|
||||
|
||||
<script type="text/javascript" src="qweb2.js"></script>
|
||||
|
||||
<script>
|
||||
QWeb = new QWeb2.Engine();
|
||||
function trim(s) {
|
||||
return s.replace(/(^\s+|\s+$)/g, '');
|
||||
}
|
||||
function render(template, context) {
|
||||
return trim(QWeb.render(template, context)).toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the template file, and executes all the test template in a
|
||||
* qunit module $title
|
||||
*/
|
||||
function test(title, template) {
|
||||
QUnit.module(title, {
|
||||
setup: function () {
|
||||
var self = this;
|
||||
this.qweb = new QWeb2.Engine();
|
||||
QUnit.stop();
|
||||
this.qweb.add_template(template, function (_, doc) {
|
||||
self.doc = doc;
|
||||
QUnit.start();
|
||||
})
|
||||
}
|
||||
});
|
||||
QUnit.test('autotest', function (assert) {
|
||||
var templates = this.qweb.templates;
|
||||
for (var template in templates) {
|
||||
if (!templates.hasOwnProperty(template)) { continue; }
|
||||
// ignore templates whose name starts with _, they're
|
||||
// helpers/internal
|
||||
if (/^_/.test(template)) { continue; }
|
||||
|
||||
var params = this.doc.querySelector('params#' + template);
|
||||
var args = params ? JSON.parse(params.textContent) : {};
|
||||
|
||||
var results = this.doc.querySelector('result#' + template);
|
||||
assert.equal(
|
||||
trim(this.qweb.render(template, args)),
|
||||
trim(results.textContent),
|
||||
template);
|
||||
}
|
||||
});
|
||||
}
|
||||
$(document).ready(function() {
|
||||
test("Output", 'qweb-test-output.xml');
|
||||
test("Context-setting", 'qweb-test-set.xml');
|
||||
test("Conditionals", 'qweb-test-conditionals.xml');
|
||||
test("Attributes manipulation", 'qweb-test-attributes.xml');
|
||||
test("Template calling (to the faraway pages)",
|
||||
'qweb-test-call.xml');
|
||||
test("Foreach", 'qweb-test-foreach.xml');
|
||||
test("Global", 'qweb-test-global.xml');
|
||||
|
||||
test('Template inheritance', 'qweb-test-extend.xml');
|
||||
});
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="qunit"></div>
|
||||
<div id="qunit-fixture"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -28,8 +28,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
var QWeb2 = {
|
||||
expressions_cache: { },
|
||||
RESERVED_WORDS: 'true,false,NaN,null,undefined,debugger,console,window,in,instanceof,new,function,return,this,typeof,eval,void,Math,RegExp,Array,Object,Date'.split(','),
|
||||
ACTIONS_PRECEDENCE: 'foreach,if,elif,else,call,set,esc,raw,js,debug,log'.split(','),
|
||||
ACTIONS_PRECEDENCE: 'foreach,if,elif,else,call,set,js,debug,log'.split(','),
|
||||
WORD_REPLACEMENT: {
|
||||
// FUCKING CHM FOR FUCK'S SAKE
|
||||
'not': '!',
|
||||
'and': '&&',
|
||||
'or': '||',
|
||||
'gt': '>',
|
||||
@@ -76,9 +78,9 @@ var QWeb2 = {
|
||||
return s;
|
||||
},
|
||||
gen_attribute: function(o) {
|
||||
if (o !== null && o !== undefined) {
|
||||
if (o) {
|
||||
if (o.constructor === Array) {
|
||||
if (o[1] !== null && o[1] !== undefined) {
|
||||
if (o[1]) {
|
||||
return this.format_attribute(o[0], o[1]);
|
||||
}
|
||||
} else if (typeof o === 'object') {
|
||||
@@ -718,36 +720,52 @@ QWeb2.Element = (function() {
|
||||
},
|
||||
compile_element : function() {
|
||||
for (var i = 0, ilen = this.engine.actions_precedence.length; i < ilen; i++) {
|
||||
var a = this.engine.actions_precedence[i];
|
||||
if (a in this.actions) {
|
||||
var value = this.actions[a];
|
||||
var key = 'compile_action_' + a;
|
||||
var compiled_action = this.engine.actions_precedence[i];
|
||||
if (compiled_action in this.actions) {
|
||||
var value = this.actions[compiled_action];
|
||||
var key = 'compile_action_' + compiled_action;
|
||||
if (this[key]) {
|
||||
this[key](value);
|
||||
} else if (this.engine[key]) {
|
||||
this.engine[key].call(this, value);
|
||||
} else {
|
||||
this.engine.tools.exception("No handler method for action '" + a + "'");
|
||||
this.engine.tools.exception("No handler method for action '" + compiled_action + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
function print_contents(self) {
|
||||
var expr, esc, raw;
|
||||
if (esc = self.actions['esc']) {
|
||||
expr = "context.engine.tools.html_escape(" + self.format_str(esc) + ");";
|
||||
} else if(raw = self.actions['raw']) {
|
||||
expr = self.format_str(raw);
|
||||
}
|
||||
// print non-empty result of t-esc or t-raw, otherwise
|
||||
// print/process body
|
||||
if (expr) {
|
||||
self.top('var expr_result = ' + expr + ';');
|
||||
self.top('if (expr_result) {');
|
||||
self.top(' r.push(expr_result);');
|
||||
self.top('} else {');
|
||||
self.bottom('}');
|
||||
}
|
||||
}
|
||||
if (this.tag.toLowerCase() !== this.engine.prefix) {
|
||||
var tag = "<" + this.tag;
|
||||
for (var a in this.attributes) {
|
||||
tag += this.engine.tools.gen_attribute([a, this.attributes[a]]);
|
||||
for (var att in this.attributes) {
|
||||
tag += this.engine.tools.gen_attribute([att, this.attributes[att]]);
|
||||
}
|
||||
this.top_string(tag);
|
||||
if (this.actions.att) {
|
||||
this.top("r.push(context.engine.tools.gen_attribute(" + (this.format_expression(this.actions.att)) + "));");
|
||||
|
||||
}
|
||||
for (var a in this.actions) {
|
||||
var v = this.actions[a];
|
||||
var m = a.match(/att-(.+)/);
|
||||
if (m) {
|
||||
var m, v = this.actions[a];
|
||||
if (a === 'att') {
|
||||
this.top("r.push(context.engine.tools.gen_attribute(" + (this.format_expression(v)) + "));");
|
||||
} else if (m = a.match(/att-(.+)/)) {
|
||||
this.top("r.push(context.engine.tools.gen_attribute(['" + m[1] + "', (" + (this.format_expression(v)) + ")]));");
|
||||
}
|
||||
var m = a.match(/attf-(.+)/);
|
||||
if (m) {
|
||||
} else if (m = a.match(/attf-(.+)/)) {
|
||||
this.top("r.push(context.engine.tools.gen_attribute(['" + m[1] + "', (" + (this.string_interpolation(v)) + ")]));");
|
||||
}
|
||||
}
|
||||
@@ -755,11 +773,13 @@ QWeb2.Element = (function() {
|
||||
// We do not enforce empty content on void elements
|
||||
// because QWeb rendering is not necessarily html.
|
||||
this.top_string("/>");
|
||||
return; // ensure we skip processing content
|
||||
} else {
|
||||
this.top_string(">");
|
||||
this.bottom_string("</" + this.tag + ">");
|
||||
}
|
||||
}
|
||||
print_contents(this);
|
||||
},
|
||||
compile_action_if : function(value) {
|
||||
this.top("if (" + (this.format_expression(value)) + ") {");
|
||||
@@ -817,14 +837,6 @@ QWeb2.Element = (function() {
|
||||
}
|
||||
}
|
||||
},
|
||||
compile_action_esc : function(value) {
|
||||
this.top("r.push(context.engine.tools.html_escape("
|
||||
+ this.format_expression(value)
|
||||
+ "));");
|
||||
},
|
||||
compile_action_raw : function(value) {
|
||||
this.top("r.push(" + (this.format_str(value)) + ");");
|
||||
},
|
||||
compile_action_js : function(value) {
|
||||
this.top("(function(" + value + ") {");
|
||||
this.bottom("})(dict);");
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
odoo.define('qweb.tests', function () {
|
||||
'use strict';
|
||||
|
||||
function trim(s) {
|
||||
return s.replace(/(^\s+|\s+$)/g, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a QUnit.module hook object loading the specified test file
|
||||
* (from /web/static/lib/qweb) and setting ``this.qweb`` (the qweb
|
||||
* instance for this module) and ``this.doc`` (the loaded XML file).
|
||||
*
|
||||
* Note that test files mix template elements <t t-name>, params elements
|
||||
* <params> and result elements <result>. A result and an optional params
|
||||
* object are linked to the corresponding template via the ``id``
|
||||
* attribute (result and params have the template name as id).
|
||||
*/
|
||||
function hooks(testfile) {
|
||||
var template = '/web/static/lib/qweb/' + testfile;
|
||||
return {
|
||||
before: function () {
|
||||
var self = this;
|
||||
this.qweb = new QWeb2.Engine();
|
||||
var p = $.Deferred();
|
||||
this.qweb.add_template(template, function (_, doc) {
|
||||
self.doc = doc;
|
||||
p.resolve(doc);
|
||||
});
|
||||
return p.promise();
|
||||
}
|
||||
}
|
||||
}
|
||||
// can't get generative QUnit.test (e.g. QUnit.test in a for(;;)
|
||||
// or Array#forEach() loop) to work, so each test file has a single test,
|
||||
// that seems to work
|
||||
function runtest() {
|
||||
QUnit.test('', function (assert) {
|
||||
var templates = this.qweb.templates;
|
||||
assert.expect(_.reduce(templates, function (acc, _, k) {
|
||||
return acc + (/^_/.test(k) ? 0 : 1);
|
||||
}, 0));
|
||||
for (var template in templates) {
|
||||
if (!templates.hasOwnProperty(template)) { continue; }
|
||||
// ignore templates whose name starts with _, they're
|
||||
// helpers/internal
|
||||
if (/^_/.test(template)) { continue; }
|
||||
|
||||
var params = this.doc.querySelector('params#' + template);
|
||||
var args = params ? JSON.parse(params.textContent) : {};
|
||||
|
||||
var results = this.doc.querySelector('result#' + template);
|
||||
assert.equal(
|
||||
trim(this.qweb.render(template, args)),
|
||||
trim(results.textContent),
|
||||
template);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var TEMPLATES = [
|
||||
["Output", 'qweb-test-output.xml'],
|
||||
["Context-setting", 'qweb-test-set.xml'],
|
||||
["Conditionals", 'qweb-test-conditionals.xml'],
|
||||
["Attributes manipulation", 'qweb-test-attributes.xml'],
|
||||
["Template calling (to the faraway pages)", 'qweb-test-call.xml'],
|
||||
["Foreach", 'qweb-test-foreach.xml'],
|
||||
["Global", 'qweb-test-global.xml'],
|
||||
['Template inheritance', 'qweb-test-extend.xml']
|
||||
];
|
||||
|
||||
QUnit.module('qweb', {}, function () {
|
||||
TEMPLATES.forEach(function (it) {
|
||||
QUnit.module(it[0], hooks(it[1]), runtest);
|
||||
})
|
||||
});
|
||||
|
||||
});
|
||||
@@ -448,6 +448,9 @@
|
||||
display: inherit;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript" src="/web/static/lib/qweb/tests.js"></script>
|
||||
|
||||
<script type="text/javascript" src="/web/static/tests/helpers/test_utils.js"></script>
|
||||
<script type="text/javascript" src="/web/static/tests/helpers/mock_server.js"></script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user