]> git.proxmox.com Git - extjs.git/blame - extjs/packages/core/test/specs/Template.js
add extjs 6.0.1 sources
[extjs.git] / extjs / packages / core / test / specs / Template.js
CommitLineData
6527f429
DM
1describe("Ext.Template", function() {\r
2\r
3 describe("instantiation", function() {\r
4 var tpl;\r
5\r
6 it("it should extend Ext.Base", function() {\r
7 tpl = new Ext.Template("");\r
8 expect(tpl.superclass).toEqual(Ext.Base.prototype);\r
9 });\r
10\r
11 describe("configuration options", function() {\r
12 it("should disableFormats by default", function() {\r
13 tpl = new Ext.Template("");\r
14 expect(tpl.disableFormats).toBe(false);\r
15 });\r
16 });\r
17\r
18 it("should alias apply with applyTemplate", function() {\r
19 tpl = new Ext.Template("");\r
20\r
21 spyOn(tpl, 'apply');\r
22\r
23 tpl.applyTemplate();\r
24\r
25 expect(tpl.apply).toHaveBeenCalled();\r
26 });\r
27\r
28 it("should be able to compile immediately", function() {\r
29 spyOn(Ext.Template.prototype, "compile").andCallThrough();\r
30\r
31 tpl = new Ext.Template('Hello {foo}', {\r
32 compiled: true\r
33 });\r
34 // must call the new tpl for it bother compiling it\r
35 var s = tpl.apply({ foo: 42 });\r
36\r
37 expect(s).toBe('Hello 42');\r
38 expect(Ext.Template.prototype.compile).toHaveBeenCalled();\r
39 });\r
40\r
41 describe("constructor arguments", function() {\r
42 describe("objects", function() {\r
43 it("should apply all object passed after first arguments to configuration", function() {\r
44 var o1 = {a: 1},\r
45 o2 = {a: 2},\r
46 o3 = {a: 3};\r
47\r
48 spyOn(Ext, "apply");\r
49\r
50 tpl = new Ext.Template("", o1, o2, o3);\r
51\r
52 expect(Ext.apply.calls[1].args).toEqual([tpl, o1]);\r
53 expect(Ext.apply.calls[3].args).toEqual([tpl, o2]);\r
54 expect(Ext.apply.calls[5].args).toEqual([tpl, o3]);\r
55 });\r
56 });\r
57\r
58 describe("strings", function() {\r
59 it("should concat all strings passed as arguments", function() {\r
60 var s1 = 'a',\r
61 s2 = 'b',\r
62 s3 = 'c';\r
63\r
64 tpl = new Ext.Template(s1, s2, s3);\r
65\r
66 expect(tpl.html).toEqual(s1 + s2 + s3);\r
67 });\r
68 });\r
69 \r
70 describe("array", function(){\r
71 it("should concat all array strings", function(){\r
72 var tpl = new Ext.Template(['foo', 'bar', 'baz']);\r
73 expect(tpl.html).toBe('foobarbaz'); \r
74 });\r
75 \r
76 it("should apply an objects after the first argument to the template", function(){\r
77 var o1 = {\r
78 a: function(){}\r
79 }, o2 = {\r
80 b: function(){}\r
81 };\r
82 \r
83 var tpl = new Ext.Template(['foo', 'bar', o1, o2]);\r
84 expect(tpl.html).toBe('foobar');\r
85 expect(tpl.a).toBe(o1.a);\r
86 expect(tpl.b).toBe(o2.b);\r
87 });\r
88 });\r
89 });\r
90 });\r
91\r
92 describe("methods", function() {\r
93 var appliedArr,\r
94 appliedObject,\r
95 simpleTpl,\r
96 complexTpl,\r
97 rootEl,\r
98 childEl,\r
99 simpleTplEl,\r
100 complexTplEl;\r
101\r
102 beforeEach(function() {\r
103 rootEl = Ext.fly(document.body).createChild({cls: "foo", children: [{cls: "bar"}]});\r
104 childEl = rootEl.first();\r
105\r
106 simpleTpl = new Ext.Template('<div class="template">Hello {0}.</div>');\r
107 appliedArr = ["world"];\r
108\r
109 complexTpl = new Ext.Template([\r
110 '<div name="{id}">',\r
111 '<span class="{cls}">{name} {value:ellipsis(10)}</span>',\r
112 '</div>'\r
113 ]);\r
114 appliedObject = {id: "myid", cls: "myclass", name: "foo", value: "bar"};\r
115 spyOn(Ext, "getDom").andCallThrough();\r
116 });\r
117\r
118 afterEach(function() {\r
119 rootEl.destroy();\r
120 childEl.destroy();\r
121 });\r
122\r
123 describe("append", function() {\r
124 describe("with a simple template", function() {\r
125 beforeEach(function() {\r
126 simpleTplEl = simpleTpl.append(rootEl, ["world"], true);\r
127 });\r
128\r
129 afterEach(function() {\r
130 simpleTplEl.destroy();\r
131 });\r
132\r
133 it("should append the new node to the end of the specified element", function() {\r
134 expect(simpleTplEl).toEqual(rootEl.last());\r
135 });\r
136\r
137 it("should apply the supplied value to the template", function() {\r
138 expect(simpleTplEl.dom).hasHTML('Hello world.');\r
139 });\r
140\r
141 it("should call Ext.getDom", function() {\r
142 expect(Ext.getDom).toHaveBeenCalledWith(rootEl);\r
143 });\r
144 });\r
145\r
146 describe("with a complex template", function() {\r
147 beforeEach(function() {\r
148 complexTplEl = complexTpl.append(rootEl, appliedObject, true);\r
149 });\r
150\r
151 afterEach(function() {\r
152 complexTplEl.destroy();\r
153 });\r
154\r
155 it("should append the new node to the end of the specified element", function() {\r
156 expect(complexTplEl).toEqual(rootEl.last());\r
157 });\r
158\r
159 it("should apply the supplied value to the template", function() {\r
160 expect(complexTplEl.dom).hasHTML('<span class="myclass">foo bar</span>');\r
161 });\r
162\r
163 it("should call Ext.getDom", function() {\r
164 expect(Ext.getDom).toHaveBeenCalledWith(rootEl);\r
165 });\r
166 });\r
167 });\r
168\r
169 describe("apply", function() {\r
170 describe("with a simple template", function() {\r
171 it("should apply the supplied value and return an HTML fragments", function() {\r
172 expect(simpleTpl.apply(appliedArr)).toEqual('<div class="template">Hello world.</div>');\r
173 });\r
174 });\r
175\r
176 describe("with a complex template", function() {\r
177 it("should apply the supplied value and return an HTML fragments", function() {\r
178 expect(complexTpl.apply(appliedObject)).toEqual('<div name="myid"><span class="myclass">foo bar</span></div>');\r
179 });\r
180 });\r
181\r
182 });\r
183\r
184 describe("insertAfter", function() {\r
185 describe("with a simple template", function() {\r
186 beforeEach(function() {\r
187 simpleTplEl = simpleTpl.insertAfter(childEl, ["world"], true);\r
188 });\r
189\r
190 afterEach(function() {\r
191 simpleTplEl.destroy();\r
192 });\r
193\r
194 it("should insert the new node after the specified element", function() {\r
195 expect(simpleTplEl).toEqual(childEl.next());\r
196 });\r
197\r
198 it("should apply the supplied value to the template", function() {\r
199 expect(simpleTplEl.dom).hasHTML('Hello world.');\r
200 });\r
201\r
202 it("should call Ext.getDom", function() {\r
203 expect(Ext.getDom).toHaveBeenCalledWith(childEl);\r
204 });\r
205 });\r
206\r
207 describe("with a complex template", function() {\r
208 beforeEach(function() {\r
209 complexTplEl = complexTpl.insertAfter(childEl, appliedObject, true);\r
210 });\r
211\r
212 afterEach(function() {\r
213 complexTplEl.destroy();\r
214 })\r
215\r
216 it("should insert the new node after the specified element", function() {\r
217 expect(complexTplEl).toEqual(childEl.next());\r
218 });\r
219\r
220 it("should apply the supplied value to the template", function() {\r
221 expect(complexTplEl.dom).hasHTML('<span class="myclass">foo bar</span>');\r
222 });\r
223\r
224 it("should call Ext.getDom", function() {\r
225 expect(Ext.getDom).toHaveBeenCalledWith(childEl);\r
226 });\r
227 });\r
228 });\r
229\r
230 describe("insertBefore", function() {\r
231 describe("with a simple template", function() {\r
232 beforeEach(function() {\r
233 simpleTplEl = simpleTpl.insertBefore(childEl, ["world"], true);\r
234 });\r
235\r
236 afterEach(function() {\r
237 simpleTplEl.destroy();\r
238 });\r
239\r
240 it("should insert the new node before the specified element", function() {\r
241 expect(simpleTplEl).toEqual(childEl.prev());\r
242 });\r
243\r
244 it("should apply the supplied value to the template", function() {\r
245 expect(simpleTplEl.dom).hasHTML('Hello world.');\r
246 });\r
247\r
248 it("should call Ext.getDom", function() {\r
249 expect(Ext.getDom).toHaveBeenCalledWith(childEl);\r
250 });\r
251 });\r
252\r
253 describe("with a complex template", function() {\r
254 beforeEach(function() {\r
255 complexTplEl = complexTpl.insertBefore(childEl, appliedObject, true);\r
256 });\r
257\r
258 afterEach(function() {\r
259 complexTplEl.destroy();\r
260 });\r
261\r
262 it("should insert the new node before the specified element", function() {\r
263 expect(complexTplEl).toEqual(childEl.prev());\r
264 });\r
265\r
266 it("should apply the supplied value to the template", function() {\r
267 expect(complexTplEl.dom).hasHTML('<span class="myclass">foo bar</span>');\r
268 });\r
269\r
270 it("should call Ext.getDom", function() {\r
271 expect(Ext.getDom).toHaveBeenCalledWith(childEl);\r
272 });\r
273 });\r
274 });\r
275\r
276 describe("insertFirst", function() {\r
277 describe("with a simple template", function() {\r
278 beforeEach(function() {\r
279 simpleTplEl = simpleTpl.insertFirst(rootEl, ["world"], true);\r
280 });\r
281\r
282 afterEach(function() {\r
283 simpleTplEl.destroy();\r
284 });\r
285\r
286 it("should insert the new node as first child of the specified element", function() {\r
287 expect(simpleTplEl).toEqual(rootEl.first());\r
288 });\r
289\r
290 it("should apply the supplied value to the template", function() {\r
291 expect(simpleTplEl.dom).hasHTML('Hello world.');\r
292 });\r
293\r
294 it("should call Ext.getDom", function() {\r
295 expect(Ext.getDom).toHaveBeenCalledWith(rootEl);\r
296 });\r
297 });\r
298\r
299 describe("with a complex template", function() {\r
300 beforeEach(function() {\r
301 complexTplEl = complexTpl.insertFirst(rootEl, appliedObject, true);\r
302 });\r
303\r
304 afterEach(function() {\r
305 complexTplEl.destroy();\r
306 });\r
307\r
308 it("should insert the new node as first child of the specified element", function() {\r
309 expect(complexTplEl).toEqual(rootEl.first());\r
310 });\r
311\r
312 it("should apply the supplied value to the template", function() {\r
313 expect(complexTplEl.dom).hasHTML('<span class="myclass">foo bar</span>');\r
314 });\r
315\r
316 it("should call Ext.getDom", function() {\r
317 expect(Ext.getDom).toHaveBeenCalledWith(rootEl);\r
318 });\r
319 });\r
320 });\r
321\r
322 describe("overwrite", function() {\r
323 describe("with a simple template", function() {\r
324 beforeEach(function() {\r
325 simpleTplEl = simpleTpl.overwrite(rootEl, ["world"], true);\r
326 });\r
327\r
328 afterEach(function() {\r
329 simpleTplEl.destroy();\r
330 });\r
331\r
332 it("should overrride the content of the specified element", function() {\r
333 expect(simpleTplEl).toEqual(rootEl.first());\r
334 expect(simpleTplEl).toEqual(rootEl.last());\r
335 });\r
336\r
337 it("should apply the supplied value to the template", function() {\r
338 expect(simpleTplEl.dom).hasHTML('Hello world.');\r
339 });\r
340\r
341 it("should call Ext.getDom", function() {\r
342 expect(Ext.getDom).toHaveBeenCalledWith(rootEl);\r
343 });\r
344 });\r
345\r
346 describe("with a complex template", function() {\r
347 beforeEach(function() {\r
348 complexTplEl = complexTpl.overwrite(rootEl, appliedObject, true);\r
349 });\r
350\r
351 afterEach(function() {\r
352 complexTplEl.destroy();\r
353 });\r
354\r
355 it("should overrride the content of the specified element", function() {\r
356 expect(complexTplEl).toEqual(rootEl.first());\r
357 expect(complexTplEl).toEqual(rootEl.last());\r
358 });\r
359\r
360 it("should apply the supplied value to the template", function() {\r
361 expect(complexTplEl.dom).hasHTML('<span class="myclass">foo bar</span>');\r
362 });\r
363\r
364 it("should call Ext.getDom", function() {\r
365 expect(Ext.getDom).toHaveBeenCalledWith(rootEl);\r
366 });\r
367 });\r
368 });\r
369\r
370 describe("overwrite a table element", function() {\r
371 var table;\r
372\r
373 beforeEach(function() {\r
374 table = Ext.fly(document.body).createChild({tag:'table'});\r
375 });\r
376\r
377 afterEach(function() {\r
378 table.destroy();\r
379 });\r
380\r
381 it("should insert table structure into a table", function() {\r
382 new Ext.Template('<tr><td>text</td></tr>').overwrite(table);\r
383\r
384 var innerHTML = table.dom.innerHTML;\r
385\r
386 if (Ext.isSafari4) {\r
387 // Old Safari doesn't inject the tbody but the table row is created successfully\r
388 expect(innerHTML).toEqual("<tr><td>text</td></tr>");\r
389 }\r
390 else {\r
391 expect(innerHTML.toLowerCase().replace(/\s/g, '')).toEqual("<tbody><tr><td>text</td></tr></tbody>");\r
392 }\r
393 });\r
394 });\r
395\r
396 describe("set", function() {\r
397 var tplString = '<div class="template">Good bye {0}.</div>';\r
398\r
399 it("should set the HTML used as the template", function() {\r
400 simpleTpl.set(tplString);\r
401\r
402 expect(simpleTpl.apply(["world"])).toEqual('<div class="template">Good bye world.</div>');\r
403 });\r
404\r
405 it("should be able to compile the template", function() {\r
406 simpleTpl.set(tplString, true);\r
407 var s = simpleTpl.apply([42]);\r
408\r
409 // must call the new tpl for it bother compiling it\r
410 expect(s).toBe('<div class="template">Good bye 42.</div>');\r
411 expect(typeof simpleTpl.fn === "function").toBe(true);\r
412 });\r
413 });\r
414\r
415 describe("compile", function() {\r
416 it("should call compiled function", function() {\r
417 complexTpl.compile();\r
418\r
419 spyOn(complexTpl, "fn").andCallThrough();\r
420\r
421 complexTpl.apply(appliedObject);\r
422\r
423 expect(complexTpl.fn).toHaveBeenCalledWith(appliedObject);\r
424 });\r
425\r
426 it("should return the same value as if it wasn't compiled with a complex template", function() {\r
427 var htmlWithNotCompiledTemplate,\r
428 htmlWithCompiledTemplate;\r
429 htmlWithNotCompiledTemplate = complexTpl.apply(appliedObject);\r
430 complexTpl.compile();\r
431 htmlWithCompiledTemplate = complexTpl.apply(appliedObject);\r
432\r
433 expect(htmlWithCompiledTemplate).toEqual(htmlWithNotCompiledTemplate);\r
434 });\r
435\r
436 it("should return the same value as if it wasn't compiled with a simple template", function() {\r
437 var htmlWithNotCompiledTemplate,\r
438 htmlWithCompiledTemplate;\r
439\r
440 htmlWithNotCompiledTemplate = simpleTpl.apply(appliedArr);\r
441 simpleTpl.compile();\r
442 htmlWithCompiledTemplate = simpleTpl.apply(appliedArr);\r
443\r
444 expect(htmlWithCompiledTemplate).toEqual(htmlWithNotCompiledTemplate);\r
445 });\r
446\r
447 it("should return the template itself", function() {\r
448 expect(simpleTpl.compile()).toEqual(simpleTpl);\r
449 });\r
450\r
451 });\r
452 });\r
453\r
454 describe("formats", function() {\r
455 var tpl,\r
456 ellipsisSpy,\r
457 htmlEncodeSpy,\r
458 appliedObject;\r
459\r
460 beforeEach(function() {\r
461 appliedObject = {a: "123", b: "456789"};\r
462\r
463 ellipsisSpy = spyOn(Ext.util.Format, "ellipsis");\r
464 htmlEncodeSpy = spyOn(Ext.util.Format, "htmlEncode");\r
465 });\r
466\r
467 describe("enabled", function() {\r
468 beforeEach(function() {\r
469 tpl = new Ext.Template(\r
470 '{a:ellipsis(2)}',\r
471 '{b:htmlEncode}'\r
472 );\r
473 });\r
474\r
475 it("should call Ext.util.Format.ellipsis with a non compiled template", function() {\r
476 tpl.apply(appliedObject);\r
477\r
478 expect(ellipsisSpy).toHaveBeenCalledWith(appliedObject.a, 2);\r
479 expect(htmlEncodeSpy).toHaveBeenCalledWith(appliedObject.b);\r
480 });\r
481\r
482 it("should call Ext.util.Format.ellipsis with compiled template", function() {\r
483 tpl.compile();\r
484 tpl.apply(appliedObject);\r
485\r
486 expect(ellipsisSpy).toHaveBeenCalledWith(appliedObject.a, 2);\r
487 expect(htmlEncodeSpy).toHaveBeenCalledWith(appliedObject.b);\r
488 });\r
489 });\r
490\r
491 describe("disabled", function() {\r
492 beforeEach(function() {\r
493 tpl = new Ext.Template(\r
494 '{a:ellipsis(2)}',\r
495 {disableFormats: true}\r
496 );\r
497 });\r
498\r
499 it("should not call Ext.util.Format.ellipsis with a non compiled template", function() {\r
500 tpl.apply(appliedObject);\r
501\r
502 expect(ellipsisSpy).not.toHaveBeenCalled();\r
503 });\r
504\r
505 it("should not call Ext.util.Format.ellipsis with compiled template", function() {\r
506 tpl.compile();\r
507 tpl.apply(appliedObject);\r
508\r
509 expect(ellipsisSpy).not.toHaveBeenCalled();\r
510 });\r
511 });\r
512 });\r
513\r
514 describe("members functions", function() {\r
515 var tpl,\r
516 memberFn,\r
517 appliedObject;\r
518\r
519 beforeEach(function() {\r
520 memberFn = jasmine.createSpy().andCallFake(function(a, inc) {\r
521 return a + inc;\r
522 });\r
523\r
524 var obj = {\r
525 referenceHolder: true,\r
526 controller: 'foo',\r
527\r
528 fmt: function () {\r
529 \r
530 },\r
531 promote: function () {\r
532 //\r
533 },\r
534\r
535 items: [{\r
536 items: [{\r
537 xtype: 'button',\r
538 reference: 'btn',\r
539 listeners: {\r
540 click: 'promote'\r
541 },\r
542 bind: {\r
543 text: 'Promote {user.name:this.fmt}'\r
544 }\r
545 }]\r
546 }]\r
547 }\r
548\r
549 tpl = new Ext.Template(\r
550 '{a:this.increment(7)}',\r
551 {increment: memberFn}\r
552 );\r
553\r
554 appliedObject = {a: 1};\r
555 });\r
556\r
557 it("should call members functions with a non compiled template", function() {\r
558 tpl.apply(appliedObject);\r
559 expect(memberFn).toHaveBeenCalledWith(1, 7);\r
560 });\r
561\r
562 it("should call members functions with a compiled template", function() {\r
563 tpl.compile();\r
564 tpl.apply(appliedObject);\r
565 expect(memberFn).toHaveBeenCalledWith(1, 7);\r
566 });\r
567\r
568 it("should add member function in initialConfig", function() {\r
569 expect(tpl.initialConfig).toEqual({increment: memberFn});\r
570 });\r
571 });\r
572\r
573 describe("Ext.Template.from", function() {\r
574 var elWithHtml, elWithValue;\r
575\r
576 beforeEach(function() {\r
577 elWithHtml = Ext.fly(document.body).createChild({tag: "div", html:"FOO {0}."});\r
578 elWithValue = Ext.fly(document.body).createChild({tag: "input"});\r
579 elWithValue.dom.value = "BAR {0}.";\r
580\r
581 });\r
582\r
583 afterEach(function() {\r
584 elWithHtml.remove();\r
585 elWithValue.remove();\r
586 });\r
587\r
588 it("should create a template with dom element innerHTML", function() {\r
589 var tpl = Ext.Template.from(elWithHtml);\r
590\r
591 expect(tpl.apply(['BAR'])).toEqual('FOO BAR.');\r
592 });\r
593\r
594 it("should create a template with dom element value", function() {\r
595 var tpl = Ext.Template.from(elWithValue);\r
596\r
597 expect(tpl.apply(['FOO'])).toEqual('BAR FOO.');\r
598 });\r
599 });\r
600\r
601 function testTemplate(compiled) {\r
602 describe('Using numeric tokens and a values array', function() {\r
603 it('should use Ext.util.Format formatting functions by default', function() {\r
604 expect(new Ext.Template('Value: {0:number("0.00")}', {compiled: compiled}).apply([3.257])).toBe("Value: 3.26");\r
605 });\r
606 it('should use member formatting functions when prepended with "this."', function() {\r
607 var tpl = [\r
608 'Warning: {0:this.bold}',\r
609 {\r
610 bold: function(v){\r
611 return '<b>' + v + '</b>';\r
612 },\r
613 compiled: compiled\r
614 }\r
615 ];\r
616 expect(new Ext.Template(tpl).apply(['Warning message'])).toBe("Warning: <b>Warning message</b>");\r
617 });\r
618 it('should not see "{margin:0} as a token', function() {\r
619 expect(new Ext.Template('p{margin:0}body{direction:{0}}', {compiled: compiled}).apply(['rtl'])).toBe('p{margin:0}body{direction:rtl}');\r
620 });\r
621 it('should not see "{1:someText} as a token', function() {\r
622 expect(new Ext.Template('{0}{1:sometext}{1}', {compiled: compiled}).apply(['foo', 'bar'])).toBe('foo{1:sometext}bar');\r
623 });\r
624 });\r
625\r
626 describe('Using alphanumeric tokens and a values object', function() {\r
627 it('should use Ext.util.Format formatting functions by default', function() {\r
628 expect(new Ext.Template('Value: {prop0:number("0.00")}', {compiled: compiled}).apply({prop0:3.257})).toBe("Value: 3.26");\r
629 });\r
630 it('should use member formatting functions when prepended with "this."', function() {\r
631 var tpl = [\r
632 'Warning: {prop0:this.bold}',\r
633 {\r
634 bold: function(v){\r
635 return '<b>' + v + '</b>';\r
636 },\r
637 compiled: compiled\r
638 }\r
639 ]\r
640 expect(new Ext.Template(tpl).apply({prop0:'Warning message'})).toBe("Warning: <b>Warning message</b>");\r
641 });\r
642 it('should not see "{margin:0} as a token', function() {\r
643 expect(new Ext.Template('p{margin:0}body{direction:{prop0}}', {compiled: compiled}).apply({prop0:'rtl'})).toBe('p{margin:0}body{direction:rtl}');\r
644 });\r
645 it('should not see "{1:someText} as a token', function() {\r
646 expect(new Ext.Template('{prop0}{1:sometext}{prop1}', {compiled: compiled}).apply({prop0:'foo', prop1:'bar'})).toBe('foo{1:sometext}bar');\r
647 });\r
648 });\r
649 }\r
650\r
651 describe('Non-compiled', function() {\r
652 testTemplate(false);\r
653 });\r
654\r
655 describe('Compiled', function() {\r
656 testTemplate(true);\r
657 });\r
658});\r