From c86bb6111af600a8326b842770a2cdd2b8d6f24d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Fri, 8 Oct 2021 15:13:51 +0200 Subject: [PATCH] wip --- src/qweb/base_directives.ts | 10 + src/qweb/qweb.ts | 2 +- tests/qweb/__snapshots__/qweb.test.ts.snap | 507 +++++++++--------- .../qweb_t_esc_t_raw.test.ts.snap | 122 +++++ tests/qweb/qweb.test.ts | 188 +++---- tests/qweb/qweb_t_esc_t_raw.test.ts | 67 +++ 6 files changed, 546 insertions(+), 350 deletions(-) create mode 100644 tests/qweb/__snapshots__/qweb_t_esc_t_raw.test.ts.snap create mode 100644 tests/qweb/qweb_t_esc_t_raw.test.ts diff --git a/src/qweb/base_directives.ts b/src/qweb/base_directives.ts index 0b01ee48..0684bd29 100644 --- a/src/qweb/base_directives.ts +++ b/src/qweb/base_directives.ts @@ -100,6 +100,16 @@ QWeb.addDirective({ }, }); +QWeb.addDirective({ + name: "out", + priority: 70, + atNodeEncounter({ node, qweb, ctx }): boolean { + let value = ctx.getValue(node.getAttribute("t-out")!); + compileValueNode(value, node, qweb, ctx.subContext("escaping", true)); + return true; + }, +}); + QWeb.addDirective({ name: "raw", priority: 80, diff --git a/src/qweb/qweb.ts b/src/qweb/qweb.ts index fbcc9a93..f01e2691 100644 --- a/src/qweb/qweb.ts +++ b/src/qweb/qweb.ts @@ -599,7 +599,7 @@ export class QWeb extends EventBus { if (!(dName in QWeb.DIRECTIVE_NAMES)) { throw new Error(`Unknown QWeb directive: '${attrName}'`); } - if (node.tagName !== "t" && (attrName === "t-esc" || attrName === "t-raw")) { + if (node.tagName !== "t" && (attrName === "t-esc" || attrName === "t-out" || attrName === "t-raw")) { const tNode = document.implementation.createDocument( "http://www.w3.org/1999/xhtml", "t", diff --git a/tests/qweb/__snapshots__/qweb.test.ts.snap b/tests/qweb/__snapshots__/qweb.test.ts.snap index 41de1d25..5ebaa6ce 100644 --- a/tests/qweb/__snapshots__/qweb.test.ts.snap +++ b/tests/qweb/__snapshots__/qweb.test.ts.snap @@ -1236,7 +1236,7 @@ exports[`static templates empty div 1`] = ` }" `; -exports[`static templates inline template string in t-esc 1`] = ` +exports[`static templates inline template string in t-out 1`] = ` "function anonymous(context, extra ) { // Template name: \\"test\\" @@ -1252,7 +1252,7 @@ exports[`static templates inline template string in t-esc 1`] = ` }" `; -exports[`static templates inline template string with content in t-esc 1`] = ` +exports[`static templates inline template string with content in t-out 1`] = ` "function anonymous(context, extra ) { // Template name: \\"test\\" @@ -2244,245 +2244,6 @@ exports[`t-call (template calling with used set body 1`] = ` }" `; -exports[`t-esc div with falsy values 1`] = ` -"function anonymous(context, extra -) { - // Template name: \\"test\\" - let scope = Object.create(context); - let h = this.h; - let c1 = [], p1 = {key:1}; - let vn1 = h('div', p1, c1); - let c2 = [], p2 = {key:2}; - let vn2 = h('p', p2, c2); - c1.push(vn2); - let _3 = scope['v1']; - if (_3 != null) { - c2.push({text: _3}); - } - let c4 = [], p4 = {key:4}; - let vn4 = h('p', p4, c4); - c1.push(vn4); - let _5 = scope['v2']; - if (_5 != null) { - c4.push({text: _5}); - } - let c6 = [], p6 = {key:6}; - let vn6 = h('p', p6, c6); - c1.push(vn6); - let _7 = scope['v3']; - if (_7 != null) { - c6.push({text: _7}); - } - let c8 = [], p8 = {key:8}; - let vn8 = h('p', p8, c8); - c1.push(vn8); - let _9 = scope['v4']; - if (_9 != null) { - c8.push({text: _9}); - } - let c10 = [], p10 = {key:10}; - let vn10 = h('p', p10, c10); - c1.push(vn10); - let _11 = scope['v5']; - if (_11 != null) { - c10.push({text: _11}); - } - return vn1; -}" -`; - -exports[`t-esc escaping 1`] = ` -"function anonymous(context, extra -) { - // Template name: \\"test\\" - let scope = Object.create(context); - let h = this.h; - let c1 = [], p1 = {key:1}; - let vn1 = h('span', p1, c1); - let _2 = scope['var']; - if (_2 != null) { - c1.push({text: _2}); - } - return vn1; -}" -`; - -exports[`t-esc escaping on a node 1`] = ` -"function anonymous(context, extra -) { - // Template name: \\"test\\" - let scope = Object.create(context); - let h = this.h; - let c1 = [], p1 = {key:1}; - let vn1 = h('span', p1, c1); - let _2 = 'ok'; - if (_2 != null) { - c1.push({text: _2}); - } - return vn1; -}" -`; - -exports[`t-esc escaping on a node with a body 1`] = ` -"function anonymous(context, extra -) { - // Template name: \\"test\\" - let scope = Object.create(context); - let h = this.h; - let c1 = [], p1 = {key:1}; - let vn1 = h('span', p1, c1); - let _2 = 'ok'; - if (_2 != null) { - c1.push({text: _2}); - } else { - c1.push({text: \`nope\`}); - } - return vn1; -}" -`; - -exports[`t-esc escaping on a node with a body, as a default 1`] = ` -"function anonymous(context, extra -) { - // Template name: \\"test\\" - let scope = Object.create(context); - let h = this.h; - let c1 = [], p1 = {key:1}; - let vn1 = h('span', p1, c1); - let _2 = scope['var']; - if (_2 != null) { - c1.push({text: _2}); - } else { - c1.push({text: \`nope\`}); - } - return vn1; -}" -`; - -exports[`t-esc literal 1`] = ` -"function anonymous(context, extra -) { - // Template name: \\"test\\" - let scope = Object.create(context); - let h = this.h; - let c1 = [], p1 = {key:1}; - let vn1 = h('span', p1, c1); - let _2 = 'ok'; - if (_2 != null) { - c1.push({text: _2}); - } - return vn1; -}" -`; - -exports[`t-esc t-esc inside t-call, with t-set outside 1`] = ` -"function anonymous(context, extra -) { - // Template name: \\"main\\" - let utils = this.constructor.utils; - let scope = Object.create(context); - let h = this.h; - let c1 = [], p1 = {key:1}; - let vn1 = h('div', p1, c1); - let c2 = new utils.VDomArray(); - c2.push({text: \`Hi\`}); - scope.v = c2 - let _origScope6 = scope; - scope = Object.create(scope); - scope.__access_mode__ = 'ro'; - this.constructor.subTemplates['1'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__7__'})); - scope = _origScope6; - return vn1; -}" -`; - -exports[`t-esc t-esc is escaped 1`] = ` -"function anonymous(context, extra -) { - // Template name: \\"test\\" - let utils = this.constructor.utils; - let scope = Object.create(context); - let h = this.h; - let c1 = [], p1 = {key:1}; - let vn1 = h('div', p1, c1); - let c2 = new utils.VDomArray(); - let c3 = [], p3 = {key:3}; - let vn3 = h('p', p3, c3); - c2.push(vn3); - c3.push({text: \`escaped\`}); - scope.var = c2 - if (scope.var != null) { - let _origScope4 = scope; - scope = Object.create(scope); - scope.__access_mode__ = 'ro'; - scope.var = scope.var instanceof utils.VDomArray ? utils.vDomToString(scope.var) : scope.var; - c1.push({text: scope.var}); - scope = _origScope4; - } - return vn1; -}" -`; - -exports[`t-esc t-esc work with spread operator 1`] = ` -"function anonymous(context, extra -) { - // Template name: \\"test\\" - let scope = Object.create(context); - let h = this.h; - let c1 = [], p1 = {key:1}; - let vn1 = h('span', p1, c1); - let _2 = [...scope['state'].list]; - if (_2 != null) { - c1.push({text: _2}); - } - return vn1; -}" -`; - -exports[`t-esc t-esc=0 is escaped 1`] = ` -"function anonymous(context, extra -) { - // Template name: \\"testCaller\\" - let utils = this.constructor.utils; - let scope = Object.create(context); - let h = this.h; - let c1 = [], p1 = {key:1}; - let vn1 = h('div', p1, c1); - let _origScope4 = scope; - scope = Object.create(scope); - scope.__access_mode__ = 'ro'; - { - { - let c__0 = []; - let c5 = [], p5 = {key:5}; - let vn5 = h('p', p5, c5); - c__0.push(vn5); - c5.push({text: \`escaped\`}); - scope[utils.zero] = c__0; - } - this.constructor.subTemplates['1'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__6__'})); - } - scope = _origScope4; - return vn1; -}" -`; - -exports[`t-esc variable 1`] = ` -"function anonymous(context, extra -) { - // Template name: \\"test\\" - let scope = Object.create(context); - let h = this.h; - let c1 = [], p1 = {key:1}; - let vn1 = h('span', p1, c1); - let _2 = scope['var']; - if (_2 != null) { - c1.push({text: _2}); - } - return vn1; -}" -`; - exports[`t-if boolean value condition elif 1`] = ` "function anonymous(context, extra ) { @@ -2640,7 +2401,7 @@ exports[`t-if can use some boolean operators in expressions 1`] = ` }" `; -exports[`t-if t-esc with t-elif 1`] = ` +exports[`t-if t-out with t-elif 1`] = ` "function anonymous(context, extra ) { // Template name: \\"test\\" @@ -2661,7 +2422,7 @@ exports[`t-if t-esc with t-elif 1`] = ` }" `; -exports[`t-if t-esc with t-if 1`] = ` +exports[`t-if t-out with t-if 1`] = ` "function anonymous(context, extra ) { // Template name: \\"test\\" @@ -2957,7 +2718,7 @@ exports[`t-on handler is bound to proper owner 1`] = ` }" `; -exports[`t-on t-on combined with t-esc 1`] = ` +exports[`t-on t-on combined with t-out 1`] = ` "function anonymous(context, extra ) { // Template name: \\"test\\" @@ -3283,41 +3044,39 @@ exports[`t-on t-on, with arguments and t-call 1`] = ` }" `; -exports[`t-raw literal 1`] = ` +exports[`t-out (formerly t-raw tests) literal 1`] = ` "function anonymous(context, extra ) { // Template name: \\"test\\" - let utils = this.constructor.utils; let scope = Object.create(context); let h = this.h; let c1 = [], p1 = {key:1}; let vn1 = h('span', p1, c1); let _2 = 'ok'; if (_2 != null) { - c1.push(...utils.htmlToVDOM(_2)); + c1.push({text: _2}); } return vn1; }" `; -exports[`t-raw not escaping 1`] = ` +exports[`t-out (formerly t-raw tests) not escaping 1`] = ` "function anonymous(context, extra ) { // Template name: \\"test\\" - let utils = this.constructor.utils; let scope = Object.create(context); let h = this.h; let c1 = [], p1 = {key:1}; let vn1 = h('div', p1, c1); let _2 = scope['var']; if (_2 != null) { - c1.push(...utils.htmlToVDOM(_2)); + c1.push({text: _2}); } return vn1; }" `; -exports[`t-raw t-raw and another sibling node 1`] = ` +exports[`t-out (formerly t-raw tests) t-raw and another sibling node 1`] = ` "function anonymous(context, extra ) { // Template name: \\"test\\" @@ -3338,7 +3097,7 @@ exports[`t-raw t-raw and another sibling node 1`] = ` }" `; -exports[`t-raw t-raw with comment 1`] = ` +exports[`t-out (formerly t-raw tests) t-raw with comment 1`] = ` "function anonymous(context, extra ) { // Template name: \\"test\\" @@ -3355,7 +3114,175 @@ exports[`t-raw t-raw with comment 1`] = ` }" `; -exports[`t-raw variable 1`] = ` +exports[`t-out (formerly t-raw tests) variable 1`] = ` +"function anonymous(context, extra +) { + // Template name: \\"test\\" + let scope = Object.create(context); + let h = this.h; + let c1 = [], p1 = {key:1}; + let vn1 = h('span', p1, c1); + let _2 = scope['var']; + if (_2 != null) { + c1.push({text: _2}); + } + return vn1; +}" +`; + +exports[`t-out div with falsy values 1`] = ` +"function anonymous(context, extra +) { + // Template name: \\"test\\" + let scope = Object.create(context); + let h = this.h; + let c1 = [], p1 = {key:1}; + let vn1 = h('div', p1, c1); + let c2 = [], p2 = {key:2}; + let vn2 = h('p', p2, c2); + c1.push(vn2); + let _3 = scope['v1']; + if (_3 != null) { + c2.push({text: _3}); + } + let c4 = [], p4 = {key:4}; + let vn4 = h('p', p4, c4); + c1.push(vn4); + let _5 = scope['v2']; + if (_5 != null) { + c4.push({text: _5}); + } + let c6 = [], p6 = {key:6}; + let vn6 = h('p', p6, c6); + c1.push(vn6); + let _7 = scope['v3']; + if (_7 != null) { + c6.push({text: _7}); + } + let c8 = [], p8 = {key:8}; + let vn8 = h('p', p8, c8); + c1.push(vn8); + let _9 = scope['v4']; + if (_9 != null) { + c8.push({text: _9}); + } + let c10 = [], p10 = {key:10}; + let vn10 = h('p', p10, c10); + c1.push(vn10); + let _11 = scope['v5']; + if (_11 != null) { + c10.push({text: _11}); + } + return vn1; +}" +`; + +exports[`t-out escaping 1`] = ` +"function anonymous(context, extra +) { + // Template name: \\"test\\" + let scope = Object.create(context); + let h = this.h; + let c1 = [], p1 = {key:1}; + let vn1 = h('span', p1, c1); + let _2 = scope['var']; + if (_2 != null) { + c1.push({text: _2}); + } + return vn1; +}" +`; + +exports[`t-out escaping on a node 1`] = ` +"function anonymous(context, extra +) { + // Template name: \\"test\\" + let scope = Object.create(context); + let h = this.h; + let c1 = [], p1 = {key:1}; + let vn1 = h('span', p1, c1); + let _2 = 'ok'; + if (_2 != null) { + c1.push({text: _2}); + } + return vn1; +}" +`; + +exports[`t-out escaping on a node with a body 1`] = ` +"function anonymous(context, extra +) { + // Template name: \\"test\\" + let scope = Object.create(context); + let h = this.h; + let c1 = [], p1 = {key:1}; + let vn1 = h('span', p1, c1); + let _2 = 'ok'; + if (_2 != null) { + c1.push({text: _2}); + } else { + c1.push({text: \`nope\`}); + } + return vn1; +}" +`; + +exports[`t-out escaping on a node with a body, as a default 1`] = ` +"function anonymous(context, extra +) { + // Template name: \\"test\\" + let scope = Object.create(context); + let h = this.h; + let c1 = [], p1 = {key:1}; + let vn1 = h('span', p1, c1); + let _2 = scope['var']; + if (_2 != null) { + c1.push({text: _2}); + } else { + c1.push({text: \`nope\`}); + } + return vn1; +}" +`; + +exports[`t-out literal 1`] = ` +"function anonymous(context, extra +) { + // Template name: \\"test\\" + let scope = Object.create(context); + let h = this.h; + let c1 = [], p1 = {key:1}; + let vn1 = h('span', p1, c1); + let _2 = 'ok'; + if (_2 != null) { + c1.push({text: _2}); + } + return vn1; +}" +`; + +exports[`t-out t-out inside t-call, with t-set outside 1`] = ` +"function anonymous(context, extra +) { + // Template name: \\"main\\" + let utils = this.constructor.utils; + let scope = Object.create(context); + let h = this.h; + let c1 = [], p1 = {key:1}; + let vn1 = h('div', p1, c1); + let c2 = new utils.VDomArray(); + c2.push({text: \`Hi\`}); + scope.v = c2 + let _origScope6 = scope; + scope = Object.create(scope); + scope.__access_mode__ = 'ro'; + this.constructor.subTemplates['1'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__7__'})); + scope = _origScope6; + return vn1; +}" +`; + +exports[`t-out t-out is escaped 1`] = ` "function anonymous(context, extra ) { // Template name: \\"test\\" @@ -3363,10 +3290,80 @@ exports[`t-raw variable 1`] = ` let scope = Object.create(context); let h = this.h; let c1 = [], p1 = {key:1}; + let vn1 = h('div', p1, c1); + let c2 = new utils.VDomArray(); + let c3 = [], p3 = {key:3}; + let vn3 = h('p', p3, c3); + c2.push(vn3); + c3.push({text: \`escaped\`}); + scope.var = c2 + if (scope.var != null) { + let _origScope4 = scope; + scope = Object.create(scope); + scope.__access_mode__ = 'ro'; + scope.var = scope.var instanceof utils.VDomArray ? utils.vDomToString(scope.var) : scope.var; + c1.push({text: scope.var}); + scope = _origScope4; + } + return vn1; +}" +`; + +exports[`t-out t-out work with spread operator 1`] = ` +"function anonymous(context, extra +) { + // Template name: \\"test\\" + let scope = Object.create(context); + let h = this.h; + let c1 = [], p1 = {key:1}; + let vn1 = h('span', p1, c1); + let _2 = [...scope['state'].list]; + if (_2 != null) { + c1.push({text: _2}); + } + return vn1; +}" +`; + +exports[`t-out t-out=0 is escaped 1`] = ` +"function anonymous(context, extra +) { + // Template name: \\"testCaller\\" + let utils = this.constructor.utils; + let scope = Object.create(context); + let h = this.h; + let c1 = [], p1 = {key:1}; + let vn1 = h('div', p1, c1); + let _origScope4 = scope; + scope = Object.create(scope); + scope.__access_mode__ = 'ro'; + { + { + let c__0 = []; + let c5 = [], p5 = {key:5}; + let vn5 = h('p', p5, c5); + c__0.push(vn5); + c5.push({text: \`escaped\`}); + scope[utils.zero] = c__0; + } + this.constructor.subTemplates['1'].call(this, scope, Object.assign({}, extra, {parentNode: c1, parent: utils.getComponent(context), key: '__6__'})); + } + scope = _origScope4; + return vn1; +}" +`; + +exports[`t-out variable 1`] = ` +"function anonymous(context, extra +) { + // Template name: \\"test\\" + let scope = Object.create(context); + let h = this.h; + let c1 = [], p1 = {key:1}; let vn1 = h('span', p1, c1); let _2 = scope['var']; if (_2 != null) { - c1.push(...utils.htmlToVDOM(_2)); + c1.push({text: _2}); } return vn1; }" @@ -3708,7 +3705,7 @@ exports[`t-set t-set should reuse variable if possible 1`] = ` }" `; -exports[`t-set t-set with content and sub t-esc 1`] = ` +exports[`t-set t-set with content and sub t-out 1`] = ` "function anonymous(context, extra ) { // Template name: \\"test\\" diff --git a/tests/qweb/__snapshots__/qweb_t_esc_t_raw.test.ts.snap b/tests/qweb/__snapshots__/qweb_t_esc_t_raw.test.ts.snap new file mode 100644 index 00000000..abd8b6be --- /dev/null +++ b/tests/qweb/__snapshots__/qweb_t_esc_t_raw.test.ts.snap @@ -0,0 +1,122 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`old t-esc directive escaping 1`] = ` +"function anonymous(context, extra +) { + // Template name: \\"test\\" + let scope = Object.create(context); + let h = this.h; + let c1 = [], p1 = {key:1}; + let vn1 = h('span', p1, c1); + let _2 = scope['var']; + if (_2 != null) { + c1.push({text: _2}); + } + return vn1; +}" +`; + +exports[`old t-esc directive simple dynamic value 1`] = ` +"function anonymous(context, extra +) { + // Template name: \\"test\\" + let scope = Object.create(context); + let result; + let h = this.h; + let _1 = scope['text']; + if (_1 != null) { + let vn2 = {text: _1}; + result = vn2 + } + return result; +}" +`; + +exports[`old t-raw directive literal 1`] = ` +"function anonymous(context, extra +) { + // Template name: \\"test\\" + let utils = this.constructor.utils; + let scope = Object.create(context); + let h = this.h; + let c1 = [], p1 = {key:1}; + let vn1 = h('span', p1, c1); + let _2 = 'ok'; + if (_2 != null) { + c1.push(...utils.htmlToVDOM(_2)); + } + return vn1; +}" +`; + +exports[`old t-raw directive not escaping 1`] = ` +"function anonymous(context, extra +) { + // Template name: \\"test\\" + let utils = this.constructor.utils; + let scope = Object.create(context); + let h = this.h; + let c1 = [], p1 = {key:1}; + let vn1 = h('div', p1, c1); + let _2 = scope['var']; + if (_2 != null) { + c1.push(...utils.htmlToVDOM(_2)); + } + return vn1; +}" +`; + +exports[`old t-raw directive t-raw and another sibling node 1`] = ` +"function anonymous(context, extra +) { + // Template name: \\"test\\" + let utils = this.constructor.utils; + let scope = Object.create(context); + let h = this.h; + let c1 = [], p1 = {key:1}; + let vn1 = h('span', p1, c1); + let c2 = [], p2 = {key:2}; + let vn2 = h('span', p2, c2); + c1.push(vn2); + c2.push({text: \`hello\`}); + let _3 = scope['var']; + if (_3 != null) { + c1.push(...utils.htmlToVDOM(_3)); + } + return vn1; +}" +`; + +exports[`old t-raw directive t-raw with comment 1`] = ` +"function anonymous(context, extra +) { + // Template name: \\"test\\" + let utils = this.constructor.utils; + let scope = Object.create(context); + let h = this.h; + let c1 = [], p1 = {key:1}; + let vn1 = h('span', p1, c1); + let _2 = scope['var']; + if (_2 != null) { + c1.push(...utils.htmlToVDOM(_2)); + } + return vn1; +}" +`; + +exports[`old t-raw directive variable 1`] = ` +"function anonymous(context, extra +) { + // Template name: \\"test\\" + let utils = this.constructor.utils; + let scope = Object.create(context); + let h = this.h; + let c1 = [], p1 = {key:1}; + let vn1 = h('span', p1, c1); + let _2 = scope['var']; + if (_2 != null) { + c1.push(...utils.htmlToVDOM(_2)); + } + return vn1; +}" +`; diff --git a/tests/qweb/qweb.test.ts b/tests/qweb/qweb.test.ts index 4aec9512..84a9e1a4 100644 --- a/tests/qweb/qweb.test.ts +++ b/tests/qweb/qweb.test.ts @@ -29,27 +29,27 @@ describe("static templates", () => { }); test("simple dynamic value", () => { - qweb.addTemplate("test", ''); + qweb.addTemplate("test", ''); expect(renderToString(qweb, "test", { text: "hello vdom" })).toBe("hello vdom"); }); - test("inline template string in t-esc", () => { - qweb.addTemplate("test", ''); + test("inline template string in t-out", () => { + qweb.addTemplate("test", ''); expect(renderToString(qweb, "test")).toBe("text"); }); - test("inline template string with content in t-esc", () => { - qweb.addTemplate("test", ''); + test("inline template string with content in t-out", () => { + qweb.addTemplate("test", ''); expect(renderToString(qweb, "test")).toBe("text1"); }); test("inline template string with variable in context", () => { - qweb.addTemplate("test", ''); + qweb.addTemplate("test", ''); expect(renderToString(qweb, "test", { v: "from context" })).toBe("text from context"); }); test("simple string, with some dynamic value", () => { - qweb.addTemplate("test", 'hello '); + qweb.addTemplate("test", 'hello '); expect(renderToString(qweb, "test", { text: "vdom" })).toBe("hello vdom"); }); @@ -149,47 +149,47 @@ describe("error handling", () => { }); }); -describe("t-esc", () => { +describe("t-out", () => { test("literal", () => { - qweb.addTemplate("test", ``); + qweb.addTemplate("test", ``); expect(renderToString(qweb, "test")).toBe("ok"); }); test("variable", () => { - qweb.addTemplate("test", ``); + qweb.addTemplate("test", ``); expect(renderToString(qweb, "test", { var: "ok" })).toBe("ok"); }); test("escaping", () => { - qweb.addTemplate("test", ``); + qweb.addTemplate("test", ``); expect(renderToString(qweb, "test", { var: "abc" })).toBe( "<ok>abc</ok>" ); }); test("escaping on a node", () => { - qweb.addTemplate("test", ``); + qweb.addTemplate("test", ``); expect(renderToString(qweb, "test")).toBe("ok"); }); test("escaping on a node with a body", () => { - qweb.addTemplate("test", `nope`); + qweb.addTemplate("test", `nope`); expect(renderToString(qweb, "test")).toBe("ok"); }); test("escaping on a node with a body, as a default", () => { - qweb.addTemplate("test", `nope`); + qweb.addTemplate("test", `nope`); expect(renderToString(qweb, "test")).toBe("nope"); }); - test("t-esc is escaped", () => { - qweb.addTemplate("test", `

escaped

`); + test("t-out is escaped", () => { + qweb.addTemplate("test", `

escaped

`); const domRendered = renderToDOM(qweb, "test"); expect(domRendered.textContent).toBe("

escaped

"); }); - test("t-esc=0 is escaped", () => { - qweb.addTemplate("test", ``); + test("t-out=0 is escaped", () => { + qweb.addTemplate("test", ``); qweb.addTemplate("testCaller", `

escaped

`); const domRendered = renderToDOM(qweb, "testCaller") as HTMLElement; expect(domRendered.querySelector("span")!.textContent).toBe("

escaped

"); @@ -200,11 +200,11 @@ describe("t-esc", () => { "test", `
-

-

-

-

-

+

+

+

+

+

` ); const vals = { @@ -219,33 +219,33 @@ describe("t-esc", () => { ); }); - test("t-esc work with spread operator", () => { - qweb.addTemplate("test", ``); + test("t-out work with spread operator", () => { + qweb.addTemplate("test", ``); const result = renderToString(qweb, "test", { state: { list: [1, 2] } }); expect(result).toBe("1,2"); }); - test("t-esc inside t-call, with t-set outside", () => { + test("t-out inside t-call, with t-set outside", () => { qweb.addTemplate("main", `
Hi
`); - qweb.addTemplate("sub", ``); + qweb.addTemplate("sub", ``); const result = renderToString(qweb, "main"); expect(result).toBe("
Hi
"); }); }); -describe("t-raw", () => { +describe("t-out (formerly t-raw tests)", () => { test("literal", () => { - qweb.addTemplate("test", ``); + qweb.addTemplate("test", ``); expect(renderToString(qweb, "test")).toBe("ok"); }); test("variable", () => { - qweb.addTemplate("test", ``); + qweb.addTemplate("test", ``); expect(renderToString(qweb, "test", { var: "ok" })).toBe("ok"); }); test("not escaping", () => { - qweb.addTemplate("test", `
`); + qweb.addTemplate("test", `
`); expect(renderToString(qweb, "test", { var: "" })).toBe("
"); }); @@ -266,7 +266,7 @@ describe("t-raw", () => { describe("t-set", () => { test("set from attribute literal", () => { - qweb.addTemplate("test", `
`); + qweb.addTemplate("test", `
`); expect(renderToString(qweb, "test")).toBe("
ok
"); }); @@ -282,12 +282,12 @@ describe("t-set", () => { }); test("set from body literal", () => { - qweb.addTemplate("test", `ok`); + qweb.addTemplate("test", `ok`); expect(renderToString(qweb, "test")).toBe("ok"); }); test("set from attribute lookup", () => { - qweb.addTemplate("test", `
`); + qweb.addTemplate("test", `
`); expect(renderToString(qweb, "test", { value: "ok" })).toBe("
ok
"); }); @@ -296,8 +296,8 @@ describe("t-set", () => { "test", `
- - + +
` ); expect(renderToString(qweb, "test", { value: "stella" })).toBe( @@ -308,23 +308,23 @@ describe("t-set", () => { test("set from body lookup", () => { qweb.addTemplate( "test", - `
` + `
` ); expect(renderToString(qweb, "test", { value: "ok" })).toBe("
ok
"); }); test("set from empty body", () => { - qweb.addTemplate("test", `
`); + qweb.addTemplate("test", `
`); expect(renderToString(qweb, "test")).toBe("
"); }); test("value priority", () => { - qweb.addTemplate("test", `
2
`); + qweb.addTemplate("test", `
2
`); expect(renderToString(qweb, "test")).toBe("
1
"); }); test("evaluate value expression", () => { - qweb.addTemplate("test", `
`); + qweb.addTemplate("test", `
`); expect(renderToString(qweb, "test")).toBe("
3
"); }); @@ -334,7 +334,7 @@ describe("t-set", () => { `
- v + v
` @@ -344,12 +344,12 @@ describe("t-set", () => { ); }); - test("t-set with content and sub t-esc", () => { + test("t-set with content and sub t-out", () => { qweb.addTemplate( "test", `
- boop - + boop +
` ); @@ -359,7 +359,7 @@ describe("t-set", () => { test("evaluate value expression, part 2", () => { qweb.addTemplate( "test", - `
` + `
` ); expect(renderToString(qweb, "test", { somevariable: 43 })).toBe("
45
"); }); @@ -370,7 +370,7 @@ describe("t-set", () => { `
1 - +
` ); expect(renderToString(qweb, "test", { flag: true })).toBe("
1
"); @@ -383,7 +383,7 @@ describe("t-set", () => { `
0 - +
` ); expect(renderToString(qweb, "test", { flag: true })).toBe("
1
"); @@ -396,7 +396,7 @@ describe("t-set", () => { `
- + @@ -413,7 +413,7 @@ describe("t-set", () => { - + @@ -431,7 +431,7 @@ describe("t-set", () => { - + @@ -522,13 +522,13 @@ describe("t-if", () => { expect(normalize(renderToString(qweb, "test", context))).toBe("
andormgtnlt
"); }); - test("t-esc with t-if", () => { - qweb.addTemplate("test", `
`); + test("t-out with t-if", () => { + qweb.addTemplate("test", `
`); expect(renderToString(qweb, "test")).toBe("
x
"); }); - test("t-esc with t-elif", () => { - qweb.addTemplate("test", `
abc
`); + test("t-out with t-elif", () => { + qweb.addTemplate("test", `
abc
`); expect(renderToString(qweb, "test")).toBe("
x
"); }); @@ -538,7 +538,7 @@ describe("t-if", () => { `
- +
` ); const result = renderToString(qweb, "test"); @@ -812,14 +812,14 @@ describe("t-call (template calling", () => { }); test("with used body", () => { - qweb.addTemplate("_callee-printsbody", '

'); + qweb.addTemplate("_callee-printsbody", '

'); qweb.addTemplate("caller", 'ok'); const expected = "

ok

"; expect(renderToString(qweb, "caller")).toBe(expected); }); test("with used set body", () => { - qweb.addTemplate("_callee-uses-foo", ''); + qweb.addTemplate("_callee-uses-foo", ''); qweb.addTemplate( "caller", ` @@ -830,7 +830,7 @@ describe("t-call (template calling", () => { }); test("inherit context", () => { - qweb.addTemplate("_callee-uses-foo", ''); + qweb.addTemplate("_callee-uses-foo", ''); qweb.addTemplate( "caller", ` @@ -849,7 +849,7 @@ describe("t-call (template calling", () => { - +
` ); @@ -937,7 +937,7 @@ describe("t-call (template calling", () => {
-

+

@@ -966,7 +966,7 @@ describe("t-call (template calling", () => {
-

+

@@ -996,7 +996,7 @@ describe("t-call (template calling", () => {
-

+

@@ -1027,7 +1027,7 @@ describe("t-call (template calling", () => { test("t-call, conditional and t-set in t-call body", () => { QWeb.registerTemplate("callee1", "
callee1
"); - QWeb.registerTemplate("callee2", '
callee2
'); + QWeb.registerTemplate("callee2", '
callee2
'); QWeb.registerTemplate( "caller", `
@@ -1054,7 +1054,7 @@ describe("t-call (template calling", () => {
- + `); @@ -1075,8 +1075,8 @@ describe("t-call (template calling", () => {
- - + +

@@ -1099,7 +1099,7 @@ describe("t-call (template calling", () => { }); test("t-call with t-set inside and body text content", () => { - qweb.addTemplate("sub", `

`); + qweb.addTemplate("sub", `

`); qweb.addTemplate( "main", ` @@ -1121,8 +1121,8 @@ describe("t-call (template calling", () => { }); test("dynamic t-call", () => { - qweb.addTemplate("foo", ``); - qweb.addTemplate("bar", ``); + qweb.addTemplate("foo", ``); + qweb.addTemplate("bar", ``); qweb.addTemplate("main", `
`); const expected = "
foo
"; expect(renderToString(qweb, "main", { template: "foo", val: "foo" })).toBe(expected); @@ -1141,7 +1141,7 @@ describe("foreach", () => { `
- [: ] + [: ]
` ); @@ -1155,7 +1155,7 @@ describe("foreach", () => { "test", `
- +
` ); const result = trim(renderToString(qweb, "test")); @@ -1169,7 +1169,7 @@ describe("foreach", () => { `
- - first last () + - first last ()
` ); @@ -1184,7 +1184,7 @@ describe("foreach", () => { `
- [: ] + [: ]
` ); @@ -1197,7 +1197,7 @@ describe("foreach", () => { qweb.addTemplate( "test", `
- +
` ); const context = { __owl__: {} }; @@ -1211,7 +1211,7 @@ describe("foreach", () => { `
- [] + []
` @@ -1227,9 +1227,9 @@ describe("foreach", () => { "test_called", ` - [] - [] - [] + [] + [] + [] ` ); qweb.addTemplate( @@ -1239,9 +1239,9 @@ describe("foreach", () => { - + - [][][] + [][][] ` ); const context = { numbers: [1, 2, 3], letters: ["a", "b"] }; @@ -1254,9 +1254,9 @@ describe("foreach", () => { qweb.addTemplate( "test_called", ` - [] - [] - [] + [] + [] + [] ` ); qweb.addTemplate( @@ -1268,9 +1268,9 @@ describe("foreach", () => { - + - [][][] + [][][] ` ); const context = { numbers: [1, 2, 3], letters: ["a", "b"] }; @@ -1296,7 +1296,7 @@ describe("foreach", () => { `
- +
` ); @@ -1312,14 +1312,14 @@ describe("foreach", () => { describe("misc", () => { test("global", () => { qweb.addTemplate("_callee-asc", ``); - qweb.addTemplate("_callee-uses-foo", `foo default`); + qweb.addTemplate("_callee-uses-foo", `foo default`); qweb.addTemplate("_callee-asc-toto", `
toto default
`); qweb.addTemplate( "caller", `
- + @@ -1719,7 +1719,7 @@ describe("t-on", () => { `` @@ -1767,9 +1767,9 @@ describe("t-on", () => { button.click(); }); - test("t-on combined with t-esc", async () => { + test("t-on combined with t-out", async () => { expect.assertions(3); - qweb.addTemplate("test", `
`); + qweb.addTemplate("test", `
`); const steps: string[] = []; const owner = { text: "Click here", @@ -1852,7 +1852,7 @@ describe("t-ref", () => { `
-
+
` ); @@ -2038,7 +2038,7 @@ describe("whitespace handling", () => { describe("t-key", () => { test("can use t-key directive on a node", () => { - qweb.addTemplate("test", `
`); + qweb.addTemplate("test", `
`); expect(renderToString(qweb, "test", { beer: { id: 12, name: "Chimay Rouge" } })).toBe( "
Chimay Rouge
" ); @@ -2048,7 +2048,7 @@ describe("t-key", () => { qweb.addTemplate( "test", `
    -
  • +
` ); expect( diff --git a/tests/qweb/qweb_t_esc_t_raw.test.ts b/tests/qweb/qweb_t_esc_t_raw.test.ts new file mode 100644 index 00000000..b770511c --- /dev/null +++ b/tests/qweb/qweb_t_esc_t_raw.test.ts @@ -0,0 +1,67 @@ +import { QWeb } from "../../src/qweb/index"; +import { renderToString } from "../helpers"; + +//------------------------------------------------------------------------------ +// Setup and helpers +//------------------------------------------------------------------------------ + +// We create before each test: +// - qweb: a new QWeb instance + +let qweb: QWeb; + +beforeEach(() => { + QWeb.TEMPLATES = {}; + QWeb.nextId = 1; + qweb = new QWeb(); +}); + +//------------------------------------------------------------------------------ +// Tests +//------------------------------------------------------------------------------ + +describe("old t-esc directive", () => { + test("simple dynamic value", () => { + qweb.addTemplate("test", ''); + expect(renderToString(qweb, "test", { text: "hello vdom" })).toBe("hello vdom"); + }); + + test("escaping", () => { + qweb.addTemplate("test", ``); + expect(renderToString(qweb, "test", { var: "abc" })).toBe( + "<ok>abc</ok>" + ); + }); + +}); + +describe("old t-raw directive", () => { + test("literal", () => { + qweb.addTemplate("test", ``); + expect(renderToString(qweb, "test")).toBe("ok"); + }); + + test("variable", () => { + qweb.addTemplate("test", ``); + expect(renderToString(qweb, "test", { var: "ok" })).toBe("ok"); + }); + + test("not escaping", () => { + qweb.addTemplate("test", `
`); + expect(renderToString(qweb, "test", { var: "" })).toBe("
"); + }); + + test("t-raw and another sibling node", () => { + qweb.addTemplate("test", `hello`); + expect(renderToString(qweb, "test", { var: "world" })).toBe( + "helloworld" + ); + }); + + test("t-raw with comment", () => { + qweb.addTemplate("test", ``); + expect(renderToString(qweb, "test", { var: "

text

" })).toBe( + "

text

" + ); + }); + }); \ No newline at end of file