]> git.proxmox.com Git - extjs.git/blame - extjs/packages/core/test/specs/Widget.js
add extjs 6.0.1 sources
[extjs.git] / extjs / packages / core / test / specs / Widget.js
CommitLineData
6527f429
DM
1describe("Ext.Widget", function() {\r
2 var widget;\r
3\r
4 function defineWidget(first, config) {\r
5 Ext.define('spec.Widget', Ext.apply({\r
6 extend: 'Ext.Widget'\r
7 }, config));\r
8\r
9 if (!first) {\r
10 // The spec wants to run in "not first" mode - this means we need to create\r
11 // an instance and throw it away, so that the spec operates on the second\r
12 // instance of the Widget ever created.\r
13 var first = new spec.Widget();\r
14 first.destroy();\r
15 }\r
16 }\r
17\r
18 afterEach(function() {\r
19 if (widget) {\r
20 widget.destroy();\r
21 }\r
22 Ext.undefine('spec.Widget');\r
23 });\r
24\r
25 function makeSuite(first) {\r
26 // most specs defined here need to run twice - once as the first instance of a\r
27 // Widget that gets created, and once as the second instance. This is needed because\r
28 // the first and second instances of a Ext.Widget go down significantly different\r
29 // code paths. The first instance creates the Element and caches it as a template\r
30 // element that is cloned by successive instances.\r
31 describe(first ? "first instance" : "second instance", function() {\r
32 it("should have an element when 'element' reference is defined on the main element", function() {\r
33 defineWidget(first);\r
34 widget = new spec.Widget();\r
35 expect(widget.element instanceof Ext.dom.Element).toBe(true);\r
36 expect(widget.el).toBe(widget.element);\r
37 });\r
38\r
39 if (first) {\r
40 // error thrown on first instance - no need to run these spec for the second instance\r
41 it("should throw an error when no 'element' reference is defined", function() {\r
42 defineWidget(first, {\r
43 element: {}\r
44 });\r
45\r
46 function makeWidget() {\r
47 new spec.Widget();\r
48 }\r
49\r
50 expect(makeWidget).toThrow("No 'element' reference found in 'spec.Widget' template.");\r
51 });\r
52\r
53 it("should throw an error if multiple 'element' references are defined", function() {\r
54 defineWidget(first, {\r
55 element: {\r
56 reference: 'element',\r
57 children: [{\r
58 reference: 'element'\r
59 }]\r
60 }\r
61 });\r
62\r
63 function makeWidget() {\r
64 new spec.Widget();\r
65 }\r
66\r
67 expect(makeWidget).toThrow("Duplicate 'element' reference detected in 'spec.Widget' template.");\r
68 });\r
69 }\r
70\r
71 it("should allow the 'element' reference to be a descendant of the main template element", function() {\r
72 defineWidget(first, {\r
73 element: {\r
74 children: [{\r
75 cls: 'foo',\r
76 reference: 'element'\r
77 }]\r
78 }\r
79 });\r
80\r
81 widget = new spec.Widget();\r
82\r
83 expect(widget.element.dom.className).toBe('foo');\r
84 });\r
85\r
86 it("should resolve element references, and remove the 'reference' attributes from the dom", function() {\r
87 defineWidget(first, {\r
88 element: {\r
89 reference: 'element',\r
90 children: [{\r
91 cls: 'foo',\r
92 reference: 'foo',\r
93 children: [{\r
94 cls: 'baz',\r
95 reference: 'baz'\r
96 }]\r
97 }, {\r
98 cls: 'bar',\r
99 reference: 'bar'\r
100 }]\r
101 }\r
102 });\r
103\r
104 widget = new spec.Widget();\r
105\r
106 expect(widget.foo instanceof Ext.dom.Element).toBe(true);\r
107 expect(widget.foo.dom.className).toBe('foo');\r
108 expect(widget.foo.dom.getAttribute('reference')).toBeNull();\r
109\r
110 expect(widget.bar instanceof Ext.dom.Element).toBe(true);\r
111 expect(widget.bar.dom.className).toBe('bar');\r
112 expect(widget.bar.dom.getAttribute('reference')).toBeNull();\r
113\r
114 expect(widget.baz instanceof Ext.dom.Element).toBe(true);\r
115 expect(widget.baz.dom.className).toBe('baz');\r
116 expect(widget.baz.dom.getAttribute('reference')).toBeNull();\r
117\r
118 expect(widget.element.dom.getAttribute('reference')).toBeNull();\r
119 });\r
120\r
121 it("should set skipGarbageCollection on element references", function() {\r
122 defineWidget(first, {\r
123 element: {\r
124 reference: 'element',\r
125 children: [{\r
126 reference: 'foo'\r
127 }]\r
128 }\r
129 });\r
130\r
131 widget = new spec.Widget();\r
132\r
133 expect(widget.element.skipGarbageCollection).toBe(true);\r
134 expect(widget.foo.skipGarbageCollection).toBe(true);\r
135 });\r
136\r
137 it("should generate an id if not configured", function() {\r
138 defineWidget(first);\r
139 widget = new spec.Widget();\r
140\r
141 expect(widget.id).toBeDefined();\r
142 expect(widget.element.id).toBe(widget.id);\r
143 });\r
144\r
145 it("should use configured id", function() {\r
146 var id = 'my-widget';\r
147\r
148 defineWidget(first);\r
149 widget = new spec.Widget({\r
150 id: id\r
151 });\r
152\r
153 expect(widget.id).toBe(id);\r
154 expect(widget.element.id).toBe(id);\r
155 });\r
156\r
157 it("should add a listener to the main element", function() {\r
158 var onClick = jasmine.createSpy();\r
159\r
160 defineWidget(first, {\r
161 element: {\r
162 reference: 'element',\r
163 listeners: {\r
164 click: 'onClick'\r
165 }\r
166 },\r
167 onClick: onClick\r
168 });\r
169\r
170 widget = new spec.Widget();\r
171 // must be in the document to receive events\r
172 Ext.getBody().appendChild(widget.element);\r
173\r
174 jasmine.fireMouseEvent(widget.element, 'click');\r
175\r
176 expect(onClick).toHaveBeenCalled();\r
177 expect(onClick.mostRecentCall.object).toBe(widget);\r
178\r
179 widget.destroy();\r
180 });\r
181\r
182 it("should add listeners to child elements", function() {\r
183 var fooScope, barScope, bazScope, jazzScope,\r
184 fooClick = jasmine.createSpy(),\r
185 barClick = jasmine.createSpy(),\r
186 bazClick = jasmine.createSpy(),\r
187 jazzClick = jasmine.createSpy();\r
188\r
189 defineWidget(first, {\r
190 element: {\r
191 reference: 'element',\r
192 children: [{\r
193 reference: 'foo',\r
194 listeners: {\r
195 click: 'fooClick'\r
196 }\r
197 }, {\r
198 cls: 'bar',\r
199 reference: 'bar',\r
200 listeners: {\r
201 // Make sure scope is set correctly for object form\r
202 click: {\r
203 fn: 'barClick'\r
204 }\r
205 },\r
206 children: [{\r
207 reference: 'baz',\r
208 listeners: {\r
209 click: 'bazClick'\r
210 },\r
211 scope: {} // make sure this scope is ignored\r
212 }, {\r
213 reference: 'jazz',\r
214 listeners: {\r
215 click: {\r
216 fn: 'jazzClick',\r
217 scope: {} // ignored - scope is always "this"\r
218 }\r
219 }\r
220 }]\r
221 }]\r
222 },\r
223\r
224 fooClick: fooClick,\r
225\r
226 barClick: barClick,\r
227\r
228 bazClick: bazClick,\r
229\r
230 jazzClick: jazzClick\r
231 });\r
232\r
233 widget = new spec.Widget();\r
234 // must be in the document to receive events\r
235 Ext.getBody().appendChild(widget.element);\r
236\r
237 jasmine.fireMouseEvent(widget.foo, 'click');\r
238 expect(fooClick).toHaveBeenCalled();\r
239 expect(fooClick.mostRecentCall.object).toBe(widget);\r
240\r
241 jasmine.fireMouseEvent(widget.bar, 'click');\r
242 expect(barClick).toHaveBeenCalled();\r
243 expect(barClick.mostRecentCall.object).toBe(widget);\r
244\r
245 jasmine.fireMouseEvent(widget.baz, 'click');\r
246 expect(bazClick).toHaveBeenCalled();\r
247 expect(bazClick.mostRecentCall.object).toBe(widget);\r
248\r
249 jasmine.fireMouseEvent(widget.jazz, 'click');\r
250 expect(jazzClick).toHaveBeenCalled();\r
251 expect(jazzClick.mostRecentCall.object).toBe(widget);\r
252\r
253 widget.destroy();\r
254 });\r
255 });\r
256 }\r
257\r
258 makeSuite(true);\r
259 makeSuite(false);\r
260\r
261 describe("element listener merging", function() {\r
262 var SuperWidget, SubWidget, superWidget, subWidget;\r
263\r
264 it("should not allow listeners declared in a subclass to pollute the superclass cache (no listeners on superclass)", function() {\r
265 // https://sencha.jira.com/browse/EXTJS-16984\r
266 SuperWidget = Ext.define(null, {\r
267 extend: Ext.Widget\r
268 });\r
269\r
270 SubWidget = Ext.define(null, {\r
271 extend: SuperWidget,\r
272 element: {\r
273 reference: 'element',\r
274 listeners: {\r
275 click: 'onClick'\r
276 }\r
277 },\r
278 onClick: Ext.emptyFn\r
279 });\r
280\r
281 // create an instance of SuperWidget first so that its listener cache gets created\r
282 superWidget = new SuperWidget();\r
283\r
284 // SubWidget should create its own listener cache\r
285 subWidget = new SubWidget();\r
286\r
287 // SubWidget's listeners should not invade SuperWidget's cache\r
288 expect(SuperWidget.prototype._elementListeners).toEqual({});\r
289 // SubWidget should have its own cache\r
290 expect(SubWidget.prototype.hasOwnProperty('_elementListeners')).toBe(true);\r
291 \r
292 Ext.destroy(subWidget, superWidget);\r
293 });\r
294\r
295 it("should not allow listeners declared in a subclass to pollute the superclass cache (with listeners on superclass)", function() {\r
296 // https://sencha.jira.com/browse/EXTJS-16984\r
297 SuperWidget = Ext.define(null, {\r
298 extend: Ext.Widget,\r
299 element: {\r
300 reference: 'element',\r
301 listeners: {\r
302 mousedown: 'onMouseDown'\r
303 }\r
304 },\r
305 onMouseDown: Ext.emptyFn\r
306 });\r
307\r
308 SubWidget = Ext.define(null, {\r
309 extend: SuperWidget,\r
310 element: {\r
311 reference: 'element',\r
312 listeners: {\r
313 click: 'onClick'\r
314 }\r
315 },\r
316 onClick: Ext.emptyFn\r
317 });\r
318\r
319 // create an instance of SuperWidget first so that its listener cache gets created\r
320 superWidget = new SuperWidget();\r
321\r
322 // SubWidget should create its own listener cache\r
323 subWidget = new SubWidget();\r
324\r
325 // SubWidget's listeners should not invade SuperWidget's cache\r
326 expect(SuperWidget.prototype._elementListeners).toEqual({\r
327 element: {\r
328 mousedown: 'onMouseDown'\r
329 }\r
330 });\r
331 // SubWidget should have its own cache\r
332 expect(SubWidget.prototype.hasOwnProperty('_elementListeners')).toBe(true);\r
333 \r
334 Ext.destroy(subWidget, superWidget);\r
335 });\r
336\r
337 describe("when first instance of superclass has already been created", function() {\r
338 var superMouseDownSpy, superMouseUpSpy, superClickSpy,\r
339 subMouseDownSpy, subMouseUpSpy, subClickSpy;\r
340\r
341 beforeEach(function() {\r
342 superMouseDownSpy = jasmine.createSpy();\r
343 superMouseUpSpy = jasmine.createSpy();\r
344 superClickSpy = jasmine.createSpy();\r
345\r
346 subMouseDownSpy = jasmine.createSpy();\r
347 subMouseUpSpy = jasmine.createSpy();\r
348 subClickSpy = jasmine.createSpy();\r
349 });\r
350\r
351 afterEach(function() {\r
352 if (superWidget) {\r
353 superWidget.destroy();\r
354 }\r
355 if (subWidget) {\r
356 subWidget.destroy();\r
357 }\r
358 });\r
359\r
360 it("should merge subclass element listeners with superclass element listeners", function() {\r
361 SuperWidget = Ext.define(null, {\r
362 extend: Ext.Widget,\r
363 element: {\r
364 reference: 'element',\r
365 listeners: {\r
366 click: 'superOnClick',\r
367 mousedown: 'superOnMouseDown'\r
368 }\r
369 },\r
370 superOnClick: superClickSpy,\r
371 superOnMouseDown: superMouseDownSpy\r
372 });\r
373\r
374 SubWidget = Ext.define(null, {\r
375 extend: SuperWidget,\r
376 element: {\r
377 reference: 'element',\r
378 listeners: {\r
379 // inherits mousedown, overrides click, and adds mouseup\r
380 click: 'subOnClick',\r
381 mouseup: 'subOnMouseUp'\r
382 }\r
383 },\r
384 subOnClick: subClickSpy,\r
385 subOnMouseUp: subMouseUpSpy\r
386 });\r
387\r
388 // create an instance of SuperWidget first so that its listener cache gets created\r
389 superWidget = new SuperWidget();\r
390\r
391 subWidget = new SubWidget();\r
392\r
393 Ext.getBody().appendChild(subWidget.element);\r
394\r
395 jasmine.fireMouseEvent(subWidget.element, 'click');\r
396\r
397 expect(superMouseDownSpy.callCount).toBe(1);\r
398 expect(superClickSpy).not.toHaveBeenCalled();\r
399 expect(subClickSpy.callCount).toBe(1);\r
400 expect(subMouseUpSpy.callCount).toBe(1);\r
401 });\r
402\r
403 it("should inherit element listeners from superclass", function() {\r
404 SuperWidget = Ext.define(null, {\r
405 extend: Ext.Widget,\r
406 element: {\r
407 reference: 'element',\r
408 listeners: {\r
409 click: 'superOnClick'\r
410 }\r
411 },\r
412 superOnClick: superClickSpy\r
413 });\r
414\r
415 SubWidget = Ext.define(null, {\r
416 extend: SuperWidget\r
417 });\r
418\r
419 // create an instance of SuperWidget first so that its listener cache gets created\r
420 superWidget = new SuperWidget();\r
421\r
422 subWidget = new SubWidget();\r
423\r
424 Ext.getBody().appendChild(subWidget.element);\r
425\r
426 jasmine.fireMouseEvent(subWidget.element, 'click');\r
427\r
428 expect(superClickSpy.callCount).toBe(1);\r
429 });\r
430\r
431 it("should merge subclass child element listeners with superclass child element listeners", function() {\r
432 SuperWidget = Ext.define(null, {\r
433 extend: Ext.Widget,\r
434 element: {\r
435 reference: 'element',\r
436 children: [{\r
437 reference: 'foo',\r
438 listeners: {\r
439 click: 'superOnClick',\r
440 mousedown: 'superOnMouseDown'\r
441 }\r
442 }]\r
443 },\r
444 superOnClick: superClickSpy,\r
445 superOnMouseDown: superMouseDownSpy\r
446 });\r
447\r
448 SubWidget = Ext.define(null, {\r
449 extend: SuperWidget,\r
450 element: {\r
451 reference: 'element',\r
452 children: [{\r
453 reference: 'foo',\r
454 listeners: {\r
455 // inherits mousedown, overrides click, and adds mouseup\r
456 click: 'subOnClick',\r
457 mouseup: 'subOnMouseUp'\r
458 }\r
459 }]\r
460 },\r
461 subOnClick: subClickSpy,\r
462 subOnMouseUp: subMouseUpSpy\r
463 });\r
464\r
465 // create an instance of SuperWidget first so that its listener cache gets created\r
466 superWidget = new SuperWidget();\r
467\r
468 subWidget = new SubWidget();\r
469\r
470 Ext.getBody().appendChild(subWidget.element);\r
471\r
472 jasmine.fireMouseEvent(subWidget.foo, 'click');\r
473\r
474 expect(superMouseDownSpy.callCount).toBe(1);\r
475 expect(superClickSpy).not.toHaveBeenCalled();\r
476 expect(subClickSpy.callCount).toBe(1);\r
477 expect(subMouseUpSpy.callCount).toBe(1);\r
478 });\r
479\r
480 it("should inherit child element listeners from superclass", function() {\r
481 SuperWidget = Ext.define(null, {\r
482 extend: Ext.Widget,\r
483 element: {\r
484 reference: 'element',\r
485 children: [{\r
486 reference: 'foo',\r
487 listeners: {\r
488 click: 'superOnClick'\r
489 }\r
490 }]\r
491 },\r
492 superOnClick: superClickSpy\r
493 });\r
494\r
495 SubWidget = Ext.define(null, {\r
496 extend: SuperWidget\r
497 });\r
498\r
499 // create an instance of SuperWidget first so that its listener cache gets created\r
500 superWidget = new SuperWidget();\r
501\r
502 subWidget = new SubWidget();\r
503\r
504 Ext.getBody().appendChild(subWidget.element);\r
505\r
506 jasmine.fireMouseEvent(subWidget.foo, 'click');\r
507\r
508 expect(superClickSpy.callCount).toBe(1);\r
509 });\r
510\r
511 it("should add listeners to subclass child elements that do not have a corresponding reference in the superclass template", function() {\r
512 SuperWidget = Ext.define(null, {\r
513 extend: Ext.Widget,\r
514 element: {\r
515 reference: 'element',\r
516 children: [{\r
517 reference: 'foo',\r
518 listeners: {\r
519 click: 'superOnClick'\r
520 }\r
521 }]\r
522 },\r
523 superOnClick: superClickSpy\r
524 });\r
525\r
526 SubWidget = Ext.define(null, {\r
527 extend: SuperWidget,\r
528 element: {\r
529 reference: 'element',\r
530 children: [{\r
531 reference: 'bar',\r
532 listeners: {\r
533 click: 'subOnClick'\r
534 }\r
535 }]\r
536 },\r
537 subOnClick: subClickSpy\r
538 });\r
539\r
540 // create an instance of SuperWidget first so that its listener cache gets created\r
541 superWidget = new SuperWidget();\r
542\r
543 subWidget = new SubWidget();\r
544\r
545 Ext.getBody().appendChild(subWidget.element);\r
546\r
547 jasmine.fireMouseEvent(subWidget.bar, 'click');\r
548\r
549 expect(superClickSpy.callCount).toBe(0);\r
550 expect(subClickSpy.callCount).toBe(1);\r
551 });\r
552\r
553 it("should merge subclass element listeners with superclass element listeners (multiple levels of inheritance)", function() {\r
554 var mouseUpSpy = jasmine.createSpy(),\r
555 Widget;\r
556\r
557 SuperWidget = Ext.define(null, {\r
558 extend: Ext.Widget,\r
559 element: {\r
560 reference: 'element',\r
561 listeners: {\r
562 click: 'superOnClick',\r
563 mousedown: 'superOnMouseDown'\r
564 }\r
565 },\r
566 superOnClick: superClickSpy,\r
567 superOnMouseDown: superMouseDownSpy\r
568 });\r
569\r
570 SubWidget = Ext.define(null, {\r
571 extend: SuperWidget,\r
572 element: {\r
573 reference: 'element',\r
574 listeners: {\r
575 // inherits mousedown, overrides click, and adds mouseup\r
576 click: 'subOnClick',\r
577 mouseup: 'subOnMouseUp'\r
578 }\r
579 },\r
580 subOnClick: subClickSpy,\r
581 subOnMouseUp: subMouseUpSpy\r
582 });\r
583\r
584 Widget = Ext.define(null, {\r
585 extend: SubWidget,\r
586 element: {\r
587 reference: 'element',\r
588 listeners: {\r
589 // overrides mouseup, inherits click/mousedown\r
590 mouseup: 'onMouseUp'\r
591 }\r
592 },\r
593 onMouseUp: mouseUpSpy\r
594 });\r
595\r
596 // create an instance of SuperWidget/SubWidget first so that their listener caches get created\r
597 superWidget = new SuperWidget();\r
598 subWidget = new SubWidget();\r
599 widget = new Widget();\r
600\r
601 Ext.getBody().appendChild(widget.element);\r
602\r
603 jasmine.fireMouseEvent(widget.element, 'click');\r
604\r
605 expect(superMouseDownSpy.callCount).toBe(1);\r
606 expect(superClickSpy).not.toHaveBeenCalled();\r
607 expect(subClickSpy.callCount).toBe(1);\r
608 expect(subMouseUpSpy).not.toHaveBeenCalled();\r
609 expect(mouseUpSpy.callCount).toBe(1);\r
610 });\r
611\r
612 it("should inherit child element listeners from superclass over multiple inheritance levels", function() {\r
613 var Widget;\r
614\r
615 SuperWidget = Ext.define(null, {\r
616 extend: Ext.Widget,\r
617 element: {\r
618 reference: 'element',\r
619 children: [{\r
620 reference: 'foo',\r
621 listeners: {\r
622 click: 'superOnClick'\r
623 }\r
624 }]\r
625 },\r
626 superOnClick: superClickSpy\r
627 });\r
628\r
629 SubWidget = Ext.define(null, {\r
630 extend: SuperWidget\r
631 });\r
632\r
633 Widget = Ext.define(null, {\r
634 extend: SubWidget\r
635 });\r
636\r
637 // create an instance of SuperWidget/SubWidget first so that their listener caches get created\r
638 superWidget = new SuperWidget();\r
639 subWidget = new SubWidget();\r
640\r
641 widget = new Widget();\r
642\r
643 Ext.getBody().appendChild(widget.element);\r
644\r
645 jasmine.fireMouseEvent(widget.foo, 'click');\r
646\r
647 expect(superClickSpy.callCount).toBe(1);\r
648 });\r
649 });\r
650\r
651 describe("when first instance of superclass has not yet been created", function() {\r
652 var superMouseDownSpy, superMouseUpSpy, superClickSpy,\r
653 subMouseDownSpy, subMouseUpSpy, subClickSpy;\r
654\r
655 beforeEach(function() {\r
656 superMouseDownSpy = jasmine.createSpy();\r
657 superMouseUpSpy = jasmine.createSpy();\r
658 superClickSpy = jasmine.createSpy();\r
659\r
660 subMouseDownSpy = jasmine.createSpy();\r
661 subMouseUpSpy = jasmine.createSpy();\r
662 subClickSpy = jasmine.createSpy();\r
663 });\r
664\r
665 afterEach(function() {\r
666 if (superWidget) {\r
667 superWidget.destroy();\r
668 }\r
669 if (subWidget) {\r
670 subWidget.destroy();\r
671 }\r
672 });\r
673\r
674 it("should merge subclass element listeners with superclass element listeners", function() {\r
675 SuperWidget = Ext.define(null, {\r
676 extend: Ext.Widget,\r
677 element: {\r
678 reference: 'element',\r
679 listeners: {\r
680 click: 'superOnClick',\r
681 mousedown: 'superOnMouseDown'\r
682 }\r
683 },\r
684 superOnClick: superClickSpy,\r
685 superOnMouseDown: superMouseDownSpy\r
686 });\r
687\r
688 SubWidget = Ext.define(null, {\r
689 extend: SuperWidget,\r
690 element: {\r
691 reference: 'element',\r
692 listeners: {\r
693 // inherits mousedown, overrides click, and adds mouseup\r
694 click: 'subOnClick',\r
695 mouseup: 'subOnMouseUp'\r
696 }\r
697 },\r
698 subOnClick: subClickSpy,\r
699 subOnMouseUp: subMouseUpSpy\r
700 });\r
701\r
702 subWidget = new SubWidget();\r
703\r
704 Ext.getBody().appendChild(subWidget.element);\r
705\r
706 jasmine.fireMouseEvent(subWidget.element, 'click');\r
707\r
708 expect(superMouseDownSpy.callCount).toBe(1);\r
709 expect(superClickSpy).not.toHaveBeenCalled();\r
710 expect(subClickSpy.callCount).toBe(1);\r
711 expect(subMouseUpSpy.callCount).toBe(1);\r
712 });\r
713\r
714 it("should inherit element listeners from superclass", function() {\r
715 SuperWidget = Ext.define(null, {\r
716 extend: Ext.Widget,\r
717 element: {\r
718 reference: 'element',\r
719 listeners: {\r
720 click: 'superOnClick'\r
721 }\r
722 },\r
723 superOnClick: superClickSpy\r
724 });\r
725\r
726 SubWidget = Ext.define(null, {\r
727 extend: SuperWidget\r
728 });\r
729\r
730 subWidget = new SubWidget();\r
731\r
732 Ext.getBody().appendChild(subWidget.element);\r
733\r
734 jasmine.fireMouseEvent(subWidget.element, 'click');\r
735\r
736 expect(superClickSpy.callCount).toBe(1);\r
737 });\r
738\r
739 it("should merge subclass child element listeners with superclass child element listeners", function() {\r
740 SuperWidget = Ext.define(null, {\r
741 extend: Ext.Widget,\r
742 element: {\r
743 reference: 'element',\r
744 children: [{\r
745 reference: 'foo',\r
746 listeners: {\r
747 click: 'superOnClick',\r
748 mousedown: 'superOnMouseDown'\r
749 }\r
750 }]\r
751 },\r
752 superOnClick: superClickSpy,\r
753 superOnMouseDown: superMouseDownSpy\r
754 });\r
755\r
756 SubWidget = Ext.define(null, {\r
757 extend: SuperWidget,\r
758 element: {\r
759 reference: 'element',\r
760 children: [{\r
761 reference: 'foo',\r
762 listeners: {\r
763 // inherits mousedown, overrides click, and adds mouseup\r
764 click: 'subOnClick',\r
765 mouseup: 'subOnMouseUp'\r
766 }\r
767 }]\r
768 },\r
769 subOnClick: subClickSpy,\r
770 subOnMouseUp: subMouseUpSpy\r
771 });\r
772\r
773 subWidget = new SubWidget();\r
774\r
775 Ext.getBody().appendChild(subWidget.element);\r
776\r
777 jasmine.fireMouseEvent(subWidget.foo, 'click');\r
778\r
779 expect(superMouseDownSpy.callCount).toBe(1);\r
780 expect(superClickSpy).not.toHaveBeenCalled();\r
781 expect(subClickSpy.callCount).toBe(1);\r
782 expect(subMouseUpSpy.callCount).toBe(1);\r
783 });\r
784\r
785 it("should inherit child element listeners from superclass", function() {\r
786 SuperWidget = Ext.define(null, {\r
787 extend: Ext.Widget,\r
788 element: {\r
789 reference: 'element',\r
790 children: [{\r
791 reference: 'foo',\r
792 listeners: {\r
793 click: 'superOnClick'\r
794 }\r
795 }]\r
796 },\r
797 superOnClick: superClickSpy\r
798 });\r
799\r
800 SubWidget = Ext.define(null, {\r
801 extend: SuperWidget\r
802 });\r
803\r
804 subWidget = new SubWidget();\r
805\r
806 Ext.getBody().appendChild(subWidget.element);\r
807\r
808 jasmine.fireMouseEvent(subWidget.foo, 'click');\r
809\r
810 expect(superClickSpy.callCount).toBe(1);\r
811 });\r
812\r
813 it("should add listeners to subclass child elements that do not have a corresponding reference in the superclass template", function() {\r
814 SuperWidget = Ext.define(null, {\r
815 extend: Ext.Widget,\r
816 element: {\r
817 reference: 'element',\r
818 children: [{\r
819 reference: 'foo',\r
820 listeners: {\r
821 click: 'superOnClick'\r
822 }\r
823 }]\r
824 },\r
825 superOnClick: superClickSpy\r
826 });\r
827\r
828 SubWidget = Ext.define(null, {\r
829 extend: SuperWidget,\r
830 element: {\r
831 reference: 'element',\r
832 children: [{\r
833 reference: 'bar',\r
834 listeners: {\r
835 click: 'subOnClick'\r
836 }\r
837 }]\r
838 },\r
839 subOnClick: subClickSpy\r
840 });\r
841\r
842 subWidget = new SubWidget();\r
843\r
844 Ext.getBody().appendChild(subWidget.element);\r
845\r
846 jasmine.fireMouseEvent(subWidget.bar, 'click');\r
847\r
848 expect(superClickSpy.callCount).toBe(0);\r
849 expect(subClickSpy.callCount).toBe(1);\r
850 });\r
851\r
852 it("should merge subclass element listeners with superclass element listeners (multiple levels of inheritance)", function() {\r
853 var mouseUpSpy = jasmine.createSpy(),\r
854 Widget;\r
855\r
856 SuperWidget = Ext.define(null, {\r
857 extend: Ext.Widget,\r
858 element: {\r
859 reference: 'element',\r
860 listeners: {\r
861 click: 'superOnClick',\r
862 mousedown: 'superOnMouseDown'\r
863 }\r
864 },\r
865 superOnClick: superClickSpy,\r
866 superOnMouseDown: superMouseDownSpy\r
867 });\r
868\r
869 SubWidget = Ext.define(null, {\r
870 extend: SuperWidget,\r
871 element: {\r
872 reference: 'element',\r
873 listeners: {\r
874 // inherits mousedown, overrides click, and adds mouseup\r
875 click: 'subOnClick',\r
876 mouseup: 'subOnMouseUp'\r
877 }\r
878 },\r
879 subOnClick: subClickSpy,\r
880 subOnMouseUp: subMouseUpSpy\r
881 });\r
882\r
883 Widget = Ext.define(null, {\r
884 extend: SubWidget,\r
885 element: {\r
886 reference: 'element',\r
887 listeners: {\r
888 // overrides mouseup, inherits click/mousedown\r
889 mouseup: 'onMouseUp'\r
890 }\r
891 },\r
892 onMouseUp: mouseUpSpy\r
893 });\r
894\r
895 widget = new Widget();\r
896\r
897 Ext.getBody().appendChild(widget.element);\r
898\r
899 jasmine.fireMouseEvent(widget.element, 'click');\r
900\r
901 expect(superMouseDownSpy.callCount).toBe(1);\r
902 expect(superClickSpy).not.toHaveBeenCalled();\r
903 expect(subClickSpy.callCount).toBe(1);\r
904 expect(subMouseUpSpy).not.toHaveBeenCalled();\r
905 expect(mouseUpSpy.callCount).toBe(1);\r
906 });\r
907\r
908 it("should inherit child element listeners from superclass over multiple inheritance levels", function() {\r
909 var Widget;\r
910\r
911 SuperWidget = Ext.define(null, {\r
912 extend: Ext.Widget,\r
913 element: {\r
914 reference: 'element',\r
915 children: [{\r
916 reference: 'foo',\r
917 listeners: {\r
918 click: 'superOnClick'\r
919 }\r
920 }]\r
921 },\r
922 superOnClick: superClickSpy\r
923 });\r
924\r
925 SubWidget = Ext.define(null, {\r
926 extend: SuperWidget\r
927 });\r
928\r
929 Widget = Ext.define(null, {\r
930 extend: SubWidget\r
931 });\r
932\r
933 widget = new Widget();\r
934\r
935 Ext.getBody().appendChild(widget.element);\r
936\r
937 jasmine.fireMouseEvent(widget.foo, 'click');\r
938\r
939 expect(superClickSpy.callCount).toBe(1);\r
940 });\r
941 });\r
942 });\r
943\r
944 describe("listener scope resolution", function() {\r
945 var spies, scopes, Widget, widget, Parent, parent, Grandparent, grandparent,\r
946 Controller, ParentController, GrandparentController;\r
947\r
948 function defineParent(cfg) {\r
949 Parent = Ext.define(null, Ext.apply({\r
950 extend: 'Ext.Container',\r
951 onFoo: spies.parent\r
952 }, cfg));\r
953 }\r
954\r
955 function defineGrandparent(cfg) {\r
956 Grandparent = Ext.define(null, Ext.apply({\r
957 extend: 'Ext.Container',\r
958 onFoo: spies.grandparent\r
959 }, cfg));\r
960 }\r
961\r
962 function expectScope(scope) {\r
963 var scopes = {\r
964 widget: widget,\r
965 controller: widget.getController(),\r
966 parent: parent,\r
967 parentController: parent && parent.getController(),\r
968 grandparent: grandparent,\r
969 grandparentController: grandparent && grandparent.getController()\r
970 },\r
971 name, spy;\r
972\r
973 for (name in spies) {\r
974 spy = spies[name];\r
975\r
976 if (name === scope) {\r
977 expect(spy).toHaveBeenCalled();\r
978 expect(spy.mostRecentCall.object).toBe(scopes[name]);\r
979 } else {\r
980 expect(spy).not.toHaveBeenCalled();\r
981 }\r
982 }\r
983 }\r
984\r
985 beforeEach(function() {\r
986 spies = {\r
987 widget: jasmine.createSpy(),\r
988 controller: jasmine.createSpy(),\r
989 parent: jasmine.createSpy(),\r
990 parentController: jasmine.createSpy(),\r
991 grandparent: jasmine.createSpy(),\r
992 grandparentController: jasmine.createSpy()\r
993 };\r
994\r
995 Controller = Ext.define(null, {\r
996 extend: 'Ext.app.ViewController',\r
997 onFoo: spies.controller\r
998 });\r
999\r
1000 ParentController = Ext.define(null, {\r
1001 extend: 'Ext.app.ViewController',\r
1002 onFoo: spies.parentController\r
1003 });\r
1004\r
1005 GrandparentController = Ext.define(null, {\r
1006 extend: 'Ext.app.ViewController',\r
1007 onFoo: spies.grandparentController\r
1008 });\r
1009 });\r
1010\r
1011 afterEach(function() {\r
1012 if (widget) {\r
1013 widget.destroy();\r
1014 }\r
1015 if (parent) {\r
1016 parent.destroy();\r
1017 }\r
1018 if (grandparent) {\r
1019 grandparent.destroy();\r
1020 }\r
1021 });\r
1022\r
1023 describe("listener declared on class body", function() {\r
1024 function defineWidget(cfg) {\r
1025 Widget = Ext.define(null, Ext.merge({\r
1026 extend: 'Ext.Widget',\r
1027 listeners: {\r
1028 foo: 'onFoo'\r
1029 },\r
1030 onFoo: spies.widget\r
1031 }, cfg));\r
1032 }\r
1033\r
1034 it("should resolve to the widget with unspecified scope", function() {\r
1035 defineWidget();\r
1036 widget = new Widget();\r
1037 widget.fireEvent('foo');\r
1038 expectScope('widget');\r
1039 });\r
1040\r
1041 it("should fail with scope:'controller'", function() {\r
1042 defineWidget({\r
1043 listeners: {\r
1044 scope: 'controller'\r
1045 }\r
1046 });\r
1047 widget = new Widget();\r
1048 expect(function() {\r
1049 widget.fireEvent('foo');\r
1050 }).toThrow();\r
1051 });\r
1052\r
1053 it("should resolve to the widget with scope:'this'", function() {\r
1054 defineWidget({\r
1055 listeners: {\r
1056 scope: 'this'\r
1057 }\r
1058 });\r
1059 widget = new Widget();\r
1060 widget.fireEvent('foo');\r
1061 expectScope('widget');\r
1062 });\r
1063\r
1064 describe("with view controller", function() {\r
1065 it("should resolve to the view controller with unspecified scope", function() {\r
1066 defineWidget({\r
1067 controller: new Controller()\r
1068 });\r
1069 widget = new Widget();\r
1070 widget.fireEvent('foo');\r
1071 expectScope('controller');\r
1072 });\r
1073\r
1074 it("should resolve to the view controller with scope:'controller'", function() {\r
1075 defineWidget({\r
1076 controller: new Controller(),\r
1077 listeners: {\r
1078 scope: 'controller'\r
1079 }\r
1080 });\r
1081 widget = new Widget();\r
1082 widget.fireEvent('foo');\r
1083 expectScope('controller');\r
1084 });\r
1085\r
1086 it("should resolve to the widget with scope:'this'", function() {\r
1087 defineWidget({\r
1088 controller: new Controller(),\r
1089 listeners: {\r
1090 scope: 'this'\r
1091 }\r
1092 });\r
1093 widget = new Widget();\r
1094 widget.fireEvent('foo');\r
1095 expectScope('widget');\r
1096 });\r
1097 });\r
1098\r
1099 describe("with defaultListenerScope", function() {\r
1100 it("should resolve to the widget with unspecified scope", function() {\r
1101 defineWidget({\r
1102 defaultListenerScope: true\r
1103 });\r
1104 widget = new Widget();\r
1105 widget.fireEvent('foo');\r
1106 expectScope('widget');\r
1107 });\r
1108\r
1109 it("should fail with scope:'controller'", function() {\r
1110 defineWidget({\r
1111 defaultListenerScope: true,\r
1112 listeners: {\r
1113 scope: 'controller'\r
1114 }\r
1115 });\r
1116 widget = new Widget();\r
1117 expect(function() {\r
1118 widget.fireEvent('foo');\r
1119 }).toThrow();\r
1120 });\r
1121\r
1122 it("should resolve to the widget with scope:'this'", function() {\r
1123 defineWidget({\r
1124 defaultListenerScope: true,\r
1125 listeners: {\r
1126 scope: 'this'\r
1127 }\r
1128 });\r
1129 widget = new Widget();\r
1130 widget.fireEvent('foo');\r
1131 expectScope('widget');\r
1132 });\r
1133 });\r
1134\r
1135 describe("with view controller and defaultListenerScope", function() {\r
1136 it("should resolve to the widget with unspecified scope", function() {\r
1137 defineWidget({\r
1138 controller: new Controller(),\r
1139 defaultListenerScope: true\r
1140 });\r
1141 widget = new Widget();\r
1142 widget.fireEvent('foo');\r
1143 expectScope('widget');\r
1144 });\r
1145\r
1146 it("should resolve to the view controller with scope:'controller'", function() {\r
1147 defineWidget({\r
1148 controller: new Controller(),\r
1149 defaultListenerScope: true,\r
1150 listeners: {\r
1151 scope: 'controller'\r
1152 }\r
1153 });\r
1154 widget = new Widget();\r
1155 widget.fireEvent('foo');\r
1156 expectScope('controller');\r
1157 });\r
1158\r
1159 it("should resolve to the widget with scope:'this'", function() {\r
1160 defineWidget({\r
1161 controller: new Controller(),\r
1162 defaultListenerScope: true,\r
1163 listeners: {\r
1164 scope: 'this'\r
1165 }\r
1166 });\r
1167 widget = new Widget();\r
1168 widget.fireEvent('foo');\r
1169 expectScope('widget');\r
1170 });\r
1171 });\r
1172\r
1173 describe("with defaultListenerScope on parent", function() {\r
1174 beforeEach(function() {\r
1175 defineParent({\r
1176 defaultListenerScope: true\r
1177 });\r
1178 });\r
1179\r
1180 it("should resolve to the parent with unspecified scope", function() {\r
1181 defineWidget();\r
1182 widget = new Widget();\r
1183 parent = new Parent({\r
1184 items: widget\r
1185 });\r
1186 widget.fireEvent('foo');\r
1187 expectScope('parent');\r
1188 });\r
1189\r
1190 it("should fail with scope:'controller'", function() {\r
1191 defineWidget({\r
1192 listeners: {\r
1193 scope: 'controller'\r
1194 }\r
1195 });\r
1196 widget = new Widget();\r
1197 parent = new Parent({\r
1198 items: widget\r
1199 });\r
1200 expect(function() {\r
1201 widget.fireEvent('foo');\r
1202 }).toThrow();\r
1203 });\r
1204\r
1205 it("should resolve to the widget with scope:'this'", function() {\r
1206 defineWidget({\r
1207 listeners: {\r
1208 scope: 'this'\r
1209 }\r
1210 });\r
1211 widget = new Widget();\r
1212 parent = new Parent({\r
1213 items: widget\r
1214 });\r
1215 widget.fireEvent('foo');\r
1216 expectScope('widget');\r
1217 });\r
1218 });\r
1219\r
1220 describe("with view controller on parent", function() {\r
1221 beforeEach(function() {\r
1222 defineParent({\r
1223 controller: new ParentController()\r
1224 });\r
1225 });\r
1226\r
1227 it("should resolve to the parent view controller with unspecified scope", function() {\r
1228 defineWidget();\r
1229 widget = new Widget();\r
1230 parent = new Parent({\r
1231 items: widget\r
1232 });\r
1233 widget.fireEvent('foo');\r
1234 expectScope('parentController');\r
1235 });\r
1236\r
1237 it("should resolve to the parent view controller with scope:'controller'", function() {\r
1238 defineWidget({\r
1239 listeners: {\r
1240 scope: 'controller'\r
1241 }\r
1242 });\r
1243 widget = new Widget();\r
1244 parent = new Parent({\r
1245 items: widget\r
1246 });\r
1247 widget.fireEvent('foo');\r
1248 expectScope('parentController');\r
1249 });\r
1250\r
1251 it("should resolve to the widget with scope:'this'", function() {\r
1252 defineWidget({\r
1253 listeners: {\r
1254 scope: 'this'\r
1255 }\r
1256 });\r
1257 widget = new Widget();\r
1258 parent = new Parent({\r
1259 items: widget\r
1260 });\r
1261 widget.fireEvent('foo');\r
1262 expectScope('widget');\r
1263 });\r
1264 });\r
1265\r
1266 describe("with view controller and defaultListenerScope on parent", function() {\r
1267 beforeEach(function() {\r
1268 defineParent({\r
1269 controller: new ParentController(),\r
1270 defaultListenerScope: true\r
1271 })\r
1272 });\r
1273\r
1274 it("should resolve to the parent with unspecified scope", function() {\r
1275 defineWidget();\r
1276 widget = new Widget();\r
1277 parent = new Parent({\r
1278 items: widget\r
1279 });\r
1280 widget.fireEvent('foo');\r
1281 expectScope('parent');\r
1282 });\r
1283\r
1284 it("should resolve to the parent view controller with scope:'controller'", function() {\r
1285 defineWidget({\r
1286 listeners: {\r
1287 scope: 'controller'\r
1288 }\r
1289 });\r
1290 widget = new Widget();\r
1291 parent = new Parent({\r
1292 items: widget\r
1293 });\r
1294 widget.fireEvent('foo');\r
1295 expectScope('parentController');\r
1296 });\r
1297\r
1298 it("should resolve to the widget with scope:'this'", function() {\r
1299 defineWidget({\r
1300 listeners: {\r
1301 scope: 'this'\r
1302 }\r
1303 });\r
1304 widget = new Widget();\r
1305 parent = new Parent({\r
1306 items: widget\r
1307 });\r
1308 widget.fireEvent('foo');\r
1309 expectScope('widget');\r
1310 });\r
1311 });\r
1312\r
1313 describe("with defaultListenerScope on grandparent", function() {\r
1314 beforeEach(function() {\r
1315 defineGrandparent({\r
1316 defaultListenerScope: true\r
1317 });\r
1318 });\r
1319\r
1320 it("should resolve to the grandparent with unspecified scope", function() {\r
1321 defineWidget();\r
1322 widget = new Widget();\r
1323 grandparent = new Grandparent({\r
1324 items: {\r
1325 items: widget\r
1326 }\r
1327 });\r
1328 widget.fireEvent('foo');\r
1329 expectScope('grandparent');\r
1330 });\r
1331\r
1332 it("should fail with scope:'controller'", function() {\r
1333 defineWidget({\r
1334 listeners: {\r
1335 scope: 'controller'\r
1336 }\r
1337 });\r
1338 widget = new Widget();\r
1339 grandparent = new Grandparent({\r
1340 items: {\r
1341 items: widget\r
1342 }\r
1343 });\r
1344 expect(function() {\r
1345 widget.fireEvent('foo');\r
1346 }).toThrow();\r
1347 });\r
1348\r
1349 it("should resolve to the widget with scope:'this'", function() {\r
1350 defineWidget({\r
1351 listeners: {\r
1352 scope: 'this'\r
1353 }\r
1354 });\r
1355 widget = new Widget();\r
1356 grandparent = new Grandparent({\r
1357 items: {\r
1358 items: widget\r
1359 }\r
1360 });\r
1361 widget.fireEvent('foo');\r
1362 expectScope('widget');\r
1363 });\r
1364 });\r
1365\r
1366 describe("with view controller on grandparent", function() {\r
1367 beforeEach(function() {\r
1368 defineGrandparent({\r
1369 controller: new GrandparentController()\r
1370 });\r
1371 });\r
1372\r
1373 it("should resolve to the grandparent view controller with unspecified scope", function() {\r
1374 defineWidget();\r
1375 widget = new Widget();\r
1376 grandparent = new Grandparent({\r
1377 items: {\r
1378 items: widget\r
1379 }\r
1380 });\r
1381 widget.fireEvent('foo');\r
1382 expectScope('grandparentController');\r
1383 });\r
1384\r
1385 it("should resolve to the grandparent view controller with scope:'controller'", function() {\r
1386 defineWidget({\r
1387 listeners: {\r
1388 scope: 'controller'\r
1389 }\r
1390 });\r
1391 widget = new Widget();\r
1392 grandparent = new Grandparent({\r
1393 items: {\r
1394 items: widget\r
1395 }\r
1396 });\r
1397 widget.fireEvent('foo');\r
1398 expectScope('grandparentController');\r
1399 });\r
1400\r
1401 it("should resolve to the widget with scope:'this'", function() {\r
1402 defineWidget({\r
1403 listeners: {\r
1404 scope: 'this'\r
1405 }\r
1406 });\r
1407 widget = new Widget();\r
1408 grandparent = new Grandparent({\r
1409 items: {\r
1410 items: widget\r
1411 }\r
1412 });\r
1413 widget.fireEvent('foo');\r
1414 expectScope('widget');\r
1415 });\r
1416 });\r
1417\r
1418 describe("with view controller and defaultListenerScope on grandparent", function() {\r
1419 beforeEach(function() {\r
1420 defineGrandparent({\r
1421 controller: new GrandparentController(),\r
1422 defaultListenerScope: true\r
1423 });\r
1424 });\r
1425\r
1426 it("should resolve to the grandparent with unspecified scope", function() {\r
1427 defineWidget();\r
1428 widget = new Widget();\r
1429 grandparent = new Grandparent({\r
1430 items: {\r
1431 items: widget\r
1432 }\r
1433 });\r
1434 widget.fireEvent('foo');\r
1435 expectScope('grandparent');\r
1436 });\r
1437\r
1438 it("should resolve to the grandparent view controller with scope:'controller'", function() {\r
1439 defineWidget({\r
1440 listeners: {\r
1441 scope: 'controller'\r
1442 }\r
1443 });\r
1444 widget = new Widget();\r
1445 grandparent = new Grandparent({\r
1446 items: {\r
1447 items: widget\r
1448 }\r
1449 });\r
1450 widget.fireEvent('foo');\r
1451 expectScope('grandparentController');\r
1452 });\r
1453\r
1454 it("should resolve to the widget with scope:'this'", function() {\r
1455 defineWidget({\r
1456 listeners: {\r
1457 scope: 'this'\r
1458 }\r
1459 });\r
1460 widget = new Widget();\r
1461 grandparent = new Grandparent({\r
1462 items: {\r
1463 items: widget\r
1464 }\r
1465 });\r
1466 widget.fireEvent('foo');\r
1467 expectScope('widget');\r
1468 });\r
1469 });\r
1470\r
1471 describe("with view controller on child and view controller on parent", function() {\r
1472 beforeEach(function() {\r
1473 defineParent({\r
1474 controller: new ParentController()\r
1475 });\r
1476 });\r
1477\r
1478 it("should resolve to the child view controller with unspecified scope", function() {\r
1479 defineWidget({\r
1480 controller: new Controller()\r
1481 });\r
1482 widget = new Widget();\r
1483 parent = new Parent({\r
1484 items: widget\r
1485 });\r
1486 widget.fireEvent('foo');\r
1487 expectScope('controller');\r
1488 });\r
1489\r
1490 it("should resolve to the child view controller with scope:'controller'", function() {\r
1491 defineWidget({\r
1492 controller: new Controller(),\r
1493 listeners: {\r
1494 scope: 'controller'\r
1495 }\r
1496 });\r
1497 widget = new Widget();\r
1498 parent = new Parent({\r
1499 items: widget\r
1500 });\r
1501 widget.fireEvent('foo');\r
1502 expectScope('controller');\r
1503 });\r
1504\r
1505 it("should resolve to the widget with scope:'this'", function() {\r
1506 defineWidget({\r
1507 controller: new Controller(),\r
1508 listeners: {\r
1509 scope: 'this'\r
1510 }\r
1511 });\r
1512 widget = new Widget();\r
1513 parent = new Parent({\r
1514 items: widget\r
1515 });\r
1516 widget.fireEvent('foo');\r
1517 expectScope('widget');\r
1518 });\r
1519 });\r
1520\r
1521 describe("with view controller on child and view controller on grandparent", function() {\r
1522 beforeEach(function() {\r
1523 defineGrandparent({\r
1524 controller: new GrandparentController()\r
1525 });\r
1526 });\r
1527\r
1528 it("should resolve to the child view controller with unspecified scope", function() {\r
1529 defineWidget({\r
1530 controller: new Controller()\r
1531 });\r
1532 widget = new Widget();\r
1533 grandparent = new Grandparent({\r
1534 items: {\r
1535 items: widget\r
1536 }\r
1537 });\r
1538 widget.fireEvent('foo');\r
1539 expectScope('controller');\r
1540 });\r
1541\r
1542 it("should resolve to the child view controller with scope:'controller'", function() {\r
1543 defineWidget({\r
1544 controller: new Controller(),\r
1545 listeners: {\r
1546 scope: 'controller'\r
1547 }\r
1548 });\r
1549 widget = new Widget();\r
1550 grandparent = new Grandparent({\r
1551 items: {\r
1552 items: widget\r
1553 }\r
1554 });\r
1555 widget.fireEvent('foo');\r
1556 expectScope('controller');\r
1557 });\r
1558\r
1559 it("should resolve to the widget with scope:'this'", function() {\r
1560 defineWidget({\r
1561 controller: new Controller(),\r
1562 listeners: {\r
1563 scope: 'this'\r
1564 }\r
1565 });\r
1566 widget = new Widget();\r
1567 grandparent = new Grandparent({\r
1568 items: {\r
1569 items: widget\r
1570 }\r
1571 });\r
1572 widget.fireEvent('foo');\r
1573 expectScope('widget');\r
1574 });\r
1575 });\r
1576\r
1577 describe("with view controller on child and defaultListenerScope on parent", function() {\r
1578 beforeEach(function() {\r
1579 defineParent({\r
1580 defaultListenerScope: true\r
1581 });\r
1582 });\r
1583\r
1584 it("should resolve to the child view controller with unspecified scope", function() {\r
1585 defineWidget({\r
1586 controller: new Controller()\r
1587 });\r
1588 widget = new Widget();\r
1589 parent = new Parent({\r
1590 items: widget\r
1591 });\r
1592 widget.fireEvent('foo');\r
1593 expectScope('controller');\r
1594 });\r
1595\r
1596 it("should resolve to the child view controller with scope:'controller'", function() {\r
1597 defineWidget({\r
1598 controller: new Controller(),\r
1599 listeners: {\r
1600 scope: 'controller'\r
1601 }\r
1602 });\r
1603 widget = new Widget();\r
1604 parent = new Parent({\r
1605 items: widget\r
1606 });\r
1607 widget.fireEvent('foo');\r
1608 expectScope('controller');\r
1609 });\r
1610\r
1611 it("should resolve to the widget with scope:'this'", function() {\r
1612 defineWidget({\r
1613 controller: new Controller(),\r
1614 listeners: {\r
1615 scope: 'this'\r
1616 }\r
1617 });\r
1618 widget = new Widget();\r
1619 parent = new Parent({\r
1620 items: widget\r
1621 });\r
1622 widget.fireEvent('foo');\r
1623 expectScope('widget');\r
1624 });\r
1625 });\r
1626\r
1627 describe("with view controller on parent and defaultListenerScope on child", function() {\r
1628 beforeEach(function() {\r
1629 defineParent({\r
1630 controller: new ParentController()\r
1631 });\r
1632 });\r
1633\r
1634 it("should resolve to the widget with unspecified scope", function() {\r
1635 defineWidget({\r
1636 defaultListenerScope: true\r
1637 });\r
1638 widget = new Widget();\r
1639 parent = new Parent({\r
1640 items: widget\r
1641 });\r
1642 widget.fireEvent('foo');\r
1643 expectScope('widget');\r
1644 });\r
1645\r
1646 it("should resolve to the parent view controller with scope:'controller'", function() {\r
1647 defineWidget({\r
1648 defaultListenerScope: true,\r
1649 listeners: {\r
1650 scope: 'controller'\r
1651 }\r
1652 });\r
1653 widget = new Widget();\r
1654 parent = new Parent({\r
1655 items: widget\r
1656 });\r
1657 widget.fireEvent('foo');\r
1658 expectScope('parentController');\r
1659 });\r
1660\r
1661 it("should resolve to the widget with scope:'this'", function() {\r
1662 defineWidget({\r
1663 defaultListenerScope: true,\r
1664 listeners: {\r
1665 scope: 'this'\r
1666 }\r
1667 });\r
1668 widget = new Widget();\r
1669 parent = new Parent({\r
1670 items: widget\r
1671 });\r
1672 widget.fireEvent('foo');\r
1673 expectScope('widget');\r
1674 });\r
1675 });\r
1676\r
1677 describe("with view controller on child and defaultListenerScope on grandparent", function() {\r
1678 beforeEach(function() {\r
1679 defineGrandparent({\r
1680 defaultListenerScope: true\r
1681 });\r
1682 });\r
1683\r
1684 it("should resolve to the child view controller with unspecified scope", function() {\r
1685 defineWidget({\r
1686 controller: new Controller()\r
1687 });\r
1688 widget = new Widget();\r
1689 grandparent = new Grandparent({\r
1690 items: {\r
1691 items: widget\r
1692 }\r
1693 });\r
1694 widget.fireEvent('foo');\r
1695 expectScope('controller');\r
1696 });\r
1697\r
1698 it("should resolve to the child view controller with scope:'controller'", function() {\r
1699 defineWidget({\r
1700 controller: new Controller(),\r
1701 listeners: {\r
1702 scope: 'controller'\r
1703 }\r
1704 });\r
1705 widget = new Widget();\r
1706 grandparent = new Grandparent({\r
1707 items: {\r
1708 items: widget\r
1709 }\r
1710 });\r
1711 widget.fireEvent('foo');\r
1712 expectScope('controller');\r
1713 });\r
1714\r
1715 it("should resolve to the widget with scope:'this'", function() {\r
1716 defineWidget({\r
1717 controller: new Controller(),\r
1718 listeners: {\r
1719 scope: 'this'\r
1720 }\r
1721 });\r
1722 widget = new Widget();\r
1723 grandparent = new Grandparent({\r
1724 items: {\r
1725 items: widget\r
1726 }\r
1727 });\r
1728 widget.fireEvent('foo');\r
1729 expectScope('widget');\r
1730 });\r
1731 });\r
1732\r
1733 describe("with view controller on grandparent and defaultListenerScope on child", function() {\r
1734 beforeEach(function() {\r
1735 defineGrandparent({\r
1736 controller: new GrandparentController()\r
1737 });\r
1738 });\r
1739\r
1740 it("should resolve to the widget with unspecified scope", function() {\r
1741 defineWidget({\r
1742 defaultListenerScope: true\r
1743 });\r
1744 widget = new Widget();\r
1745 grandparent = new Grandparent({\r
1746 items: {\r
1747 items: widget\r
1748 }\r
1749 });\r
1750 widget.fireEvent('foo');\r
1751 expectScope('widget');\r
1752 });\r
1753\r
1754 it("should resolve to the grandparent view controller with scope:'controller'", function() {\r
1755 defineWidget({\r
1756 defaultListenerScope: true,\r
1757 listeners: {\r
1758 scope: 'controller'\r
1759 }\r
1760 });\r
1761 widget = new Widget();\r
1762 grandparent = new Grandparent({\r
1763 items: {\r
1764 items: widget\r
1765 }\r
1766 });\r
1767 widget.fireEvent('foo');\r
1768 expectScope('grandparentController');\r
1769 });\r
1770\r
1771 it("should resolve to the widget with scope:'this'", function() {\r
1772 defineWidget({\r
1773 defaultListenerScope: true,\r
1774 listeners: {\r
1775 scope: 'this'\r
1776 }\r
1777 });\r
1778 widget = new Widget();\r
1779 grandparent = new Grandparent({\r
1780 items: {\r
1781 items: widget\r
1782 }\r
1783 });\r
1784 widget.fireEvent('foo');\r
1785 expectScope('widget');\r
1786 });\r
1787 });\r
1788\r
1789 describe("with scope declared on inner object", function() {\r
1790 it("should resolve to controller with unspecified outer scope", function() {\r
1791 defineWidget({\r
1792 defaultListenerScope: true,\r
1793 controller: new Controller(),\r
1794 listeners: {\r
1795 foo: {\r
1796 fn: 'onFoo',\r
1797 scope: 'controller'\r
1798 }\r
1799 }\r
1800 });\r
1801 widget = new Widget();\r
1802 widget.fireEvent('foo');\r
1803 expectScope('controller');\r
1804 });\r
1805\r
1806 it("should resolve to controller with outer scope of controller", function() {\r
1807 defineWidget({\r
1808 defaultListenerScope: true,\r
1809 controller: new Controller(),\r
1810 listeners: {\r
1811 scope: 'controller',\r
1812 foo: {\r
1813 fn: 'onFoo',\r
1814 scope: 'controller'\r
1815 }\r
1816 }\r
1817 });\r
1818 widget = new Widget();\r
1819 widget.fireEvent('foo');\r
1820 expectScope('controller');\r
1821 });\r
1822 });\r
1823\r
1824 describe("with handler declared as a function reference", function() {\r
1825 var handler, scope;\r
1826\r
1827 function defineWidget(cfg) {\r
1828 Widget = Ext.define(null, Ext.merge({\r
1829 extend: 'Ext.Widget',\r
1830 listeners: {\r
1831 foo: handler\r
1832 }\r
1833 }, cfg))\r
1834 }\r
1835\r
1836 beforeEach(function() {\r
1837 handler = jasmine.createSpy();\r
1838 handler.andCallFake(function() {\r
1839 scope = this;\r
1840 });\r
1841 });\r
1842\r
1843 afterEach(function() {\r
1844 scope = null;\r
1845 });\r
1846\r
1847 it("should use the widget as the default scope", function() {\r
1848 defineWidget();\r
1849 widget = new Widget();\r
1850 widget.fireEvent('foo');\r
1851 expect(handler).toHaveBeenCalled();\r
1852 expect(handler.mostRecentCall.object).toBe(widget);\r
1853 });\r
1854\r
1855 it("should use an arbitrary object as the scope", function() {\r
1856 var obj = {};\r
1857\r
1858 defineWidget({\r
1859 listeners: {\r
1860 scope: obj\r
1861 }\r
1862 });\r
1863 widget = new Widget();\r
1864 widget.fireEvent('foo');\r
1865 expect(scope).toBe(scope);\r
1866 });\r
1867\r
1868 it("should use the widget with scope:'this'", function() {\r
1869 defineWidget({\r
1870 listeners: {\r
1871 scope: 'this'\r
1872 }\r
1873 });\r
1874 widget = new Widget();\r
1875 widget.fireEvent('foo');\r
1876 expect(scope).toBe(widget);\r
1877 });\r
1878\r
1879 it("should fail with scope:'controller'", function() {\r
1880 defineWidget({\r
1881 listeners: {\r
1882 scope: 'controller'\r
1883 }\r
1884 });\r
1885 widget = new Widget();\r
1886 expect(function() {\r
1887 widget.fireEvent('foo');\r
1888 }).toThrow();\r
1889 });\r
1890\r
1891 it("should use the widget with scope:'this' specified on an inner object", function() {\r
1892 defineWidget({\r
1893 listeners: {\r
1894 foo: {\r
1895 fn: handler,\r
1896 scope: 'this'\r
1897 }\r
1898 }\r
1899 });\r
1900 widget = new Widget();\r
1901 widget.fireEvent('foo');\r
1902 expect(scope).toBe(widget);\r
1903 });\r
1904\r
1905 it("should fail with scope:'controller' specified on an inner object", function() {\r
1906 defineWidget({\r
1907 listeners: {\r
1908 foo: {\r
1909 fn: handler,\r
1910 scope: 'controller'\r
1911 }\r
1912 }\r
1913 });\r
1914 widget = new Widget();\r
1915 expect(function() {\r
1916 widget.fireEvent('foo');\r
1917 }).toThrow();\r
1918 });\r
1919\r
1920 describe("with view controller", function() {\r
1921 it("should resolve to the widget with unspecified scope", function() {\r
1922 defineWidget({\r
1923 controller: new Controller()\r
1924 });\r
1925 widget = new Widget();\r
1926 widget.fireEvent('foo');\r
1927 expect(scope).toBe(widget);\r
1928 });\r
1929\r
1930 it("should resolve to the view controller with scope:'controller'", function() {\r
1931 defineWidget({\r
1932 controller: new Controller(),\r
1933 listeners: {\r
1934 scope: 'controller'\r
1935 }\r
1936 });\r
1937 widget = new Widget();\r
1938 widget.fireEvent('foo');\r
1939 expect(scope).toBe(widget.getController());\r
1940 });\r
1941\r
1942 it("should resolve to the widget with scope:'this'", function() {\r
1943 defineWidget({\r
1944 controller: new Controller(),\r
1945 listeners: {\r
1946 scope: 'this'\r
1947 }\r
1948 });\r
1949 widget = new Widget();\r
1950 widget.fireEvent('foo');\r
1951 expect(scope).toBe(widget);\r
1952 });\r
1953 });\r
1954\r
1955 describe("with defaultListenerScope", function() {\r
1956 it("should resolve to the widget with unspecified scope", function() {\r
1957 defineWidget({\r
1958 defaultListenerScope: true\r
1959 });\r
1960 widget = new Widget();\r
1961 widget.fireEvent('foo');\r
1962 expect(scope).toBe(widget);\r
1963 });\r
1964\r
1965 it("should fail with scope:'controller'", function() {\r
1966 defineWidget({\r
1967 defaultListenerScope: true,\r
1968 listeners: {\r
1969 scope: 'controller'\r
1970 }\r
1971 });\r
1972 widget = new Widget();\r
1973 expect(function() {\r
1974 widget.fireEvent('foo');\r
1975 }).toThrow();\r
1976 });\r
1977\r
1978 it("should resolve to the widget with scope:'this'", function() {\r
1979 defineWidget({\r
1980 defaultListenerScope: true,\r
1981 listeners: {\r
1982 scope: 'this'\r
1983 }\r
1984 });\r
1985 widget = new Widget();\r
1986 widget.fireEvent('foo');\r
1987 expect(scope).toBe(widget);\r
1988 });\r
1989 });\r
1990\r
1991 describe("with view controller and defaultListenerScope", function() {\r
1992 it("should resolve to the widget with unspecified scope", function() {\r
1993 defineWidget({\r
1994 controller: new Controller(),\r
1995 defaultListenerScope: true\r
1996 });\r
1997 widget = new Widget();\r
1998 widget.fireEvent('foo');\r
1999 expect(scope).toBe(widget);\r
2000 });\r
2001\r
2002 it("should resolve to the view controller with scope:'controller'", function() {\r
2003 defineWidget({\r
2004 controller: new Controller(),\r
2005 defaultListenerScope: true,\r
2006 listeners: {\r
2007 scope: 'controller'\r
2008 }\r
2009 });\r
2010 widget = new Widget();\r
2011 widget.fireEvent('foo');\r
2012 expect(scope).toBe(widget.getController());\r
2013 });\r
2014\r
2015 it("should resolve to the widget with scope:'this'", function() {\r
2016 defineWidget({\r
2017 controller: new Controller(),\r
2018 defaultListenerScope: true,\r
2019 listeners: {\r
2020 scope: 'this'\r
2021 }\r
2022 });\r
2023 widget = new Widget();\r
2024 widget.fireEvent('foo');\r
2025 expect(scope).toBe(widget);\r
2026 });\r
2027 });\r
2028\r
2029 describe("with defaultListenerScope on parent", function() {\r
2030 beforeEach(function() {\r
2031 defineParent({\r
2032 defaultListenerScope: true\r
2033 });\r
2034 });\r
2035\r
2036 it("should resolve to the widget with unspecified scope", function() {\r
2037 defineWidget();\r
2038 widget = new Widget();\r
2039 parent = new Parent({\r
2040 items: widget\r
2041 });\r
2042 widget.fireEvent('foo');\r
2043 expect(scope).toBe(widget);\r
2044 });\r
2045\r
2046 it("should fail with scope:'controller'", function() {\r
2047 defineWidget({\r
2048 listeners: {\r
2049 scope: 'controller'\r
2050 }\r
2051 });\r
2052 widget = new Widget();\r
2053 parent = new Parent({\r
2054 items: widget\r
2055 });\r
2056 expect(function() {\r
2057 widget.fireEvent('foo');\r
2058 }).toThrow();\r
2059 });\r
2060\r
2061 it("should resolve to the widget with scope:'this'", function() {\r
2062 defineWidget({\r
2063 listeners: {\r
2064 scope: 'this'\r
2065 }\r
2066 });\r
2067 widget = new Widget();\r
2068 parent = new Parent({\r
2069 items: widget\r
2070 });\r
2071 widget.fireEvent('foo');\r
2072 expect(scope).toBe(widget);\r
2073 });\r
2074 });\r
2075\r
2076 describe("with view controller on parent", function() {\r
2077 beforeEach(function() {\r
2078 defineParent({\r
2079 controller: new ParentController()\r
2080 });\r
2081 });\r
2082\r
2083 it("should resolve to the widget with unspecified scope", function() {\r
2084 defineWidget();\r
2085 widget = new Widget();\r
2086 parent = new Parent({\r
2087 items: widget\r
2088 });\r
2089 widget.fireEvent('foo');\r
2090 expect(scope).toBe(widget);\r
2091 });\r
2092\r
2093 it("should resolve to the parent view controller with scope:'controller'", function() {\r
2094 defineWidget({\r
2095 listeners: {\r
2096 scope: 'controller'\r
2097 }\r
2098 });\r
2099 widget = new Widget();\r
2100 parent = new Parent({\r
2101 items: widget\r
2102 });\r
2103 widget.fireEvent('foo');\r
2104 expect(scope).toBe(parent.getController());\r
2105 });\r
2106\r
2107 it("should resolve to the widget with scope:'this'", function() {\r
2108 defineWidget({\r
2109 listeners: {\r
2110 scope: 'this'\r
2111 }\r
2112 });\r
2113 widget = new Widget();\r
2114 parent = new Parent({\r
2115 items: widget\r
2116 });\r
2117 widget.fireEvent('foo');\r
2118 expect(scope).toBe(widget);\r
2119 });\r
2120 });\r
2121 });\r
2122 });\r
2123\r
2124 describe("listener declared on instance config", function() {\r
2125 function defineWidget(cfg) {\r
2126 Widget = Ext.define(null, Ext.merge({\r
2127 extend: 'Ext.Widget',\r
2128 onFoo: spies.widget\r
2129 }, cfg));\r
2130 }\r
2131\r
2132 it("should resolve to the widget with unspecified scope", function() {\r
2133 defineWidget();\r
2134 widget = new Widget({\r
2135 listeners: {\r
2136 foo: 'onFoo'\r
2137 }\r
2138 });\r
2139 widget.fireEvent('foo');\r
2140 expectScope('widget');\r
2141 });\r
2142\r
2143 it("should fail with scope:'controller'", function() {\r
2144 defineWidget();\r
2145 widget = new Widget({\r
2146 listeners: {\r
2147 foo: 'onFoo',\r
2148 scope: 'controller'\r
2149 }\r
2150 });\r
2151 expect(function() {\r
2152 widget.fireEvent('foo');\r
2153 }).toThrow();\r
2154 });\r
2155\r
2156 it("should resolve to the widget with scope:'this'", function() {\r
2157 defineWidget();\r
2158 widget = new Widget({\r
2159 listeners: {\r
2160 foo: 'onFoo',\r
2161 scope: 'this'\r
2162 }\r
2163 });\r
2164 widget.fireEvent('foo');\r
2165 expectScope('widget');\r
2166 });\r
2167\r
2168 describe("with view controller", function() {\r
2169 beforeEach(function() {\r
2170 defineWidget({\r
2171 controller: new Controller()\r
2172 });\r
2173 });\r
2174\r
2175 it("should resolve to the widget with unspecified scope", function() {\r
2176 widget = new Widget({\r
2177 listeners: {\r
2178 foo: 'onFoo'\r
2179 }\r
2180 });\r
2181 widget.fireEvent('foo');\r
2182 expectScope('widget');\r
2183 });\r
2184\r
2185 it("should fail with scope:'controller'", function() {\r
2186 widget = new Widget({\r
2187 listeners: {\r
2188 foo: 'onFoo',\r
2189 scope: 'controller'\r
2190 }\r
2191 });\r
2192 expect(function() {\r
2193 widget.fireEvent('foo');\r
2194 }).toThrow();\r
2195 });\r
2196\r
2197 it("should resolve to the widget with scope:'this'", function() {\r
2198 widget = new Widget({\r
2199 listeners: {\r
2200 foo: 'onFoo',\r
2201 scope: 'this'\r
2202 }\r
2203 });\r
2204 widget.fireEvent('foo');\r
2205 expectScope('widget');\r
2206 });\r
2207 });\r
2208\r
2209 describe("with defaultListenerScope", function() {\r
2210 beforeEach(function() {\r
2211 defineWidget({\r
2212 defaultListenerScope: true\r
2213 });\r
2214 });\r
2215\r
2216 it("should resolve to the widget with unspecified scope", function() {\r
2217 widget = new Widget({\r
2218 listeners: {\r
2219 foo: 'onFoo'\r
2220 }\r
2221 });\r
2222 widget.fireEvent('foo');\r
2223 expectScope('widget');\r
2224 });\r
2225\r
2226 it("should fail with scope:'controller'", function() {\r
2227 widget = new Widget({\r
2228 listeners: {\r
2229 foo: 'onFoo',\r
2230 scope: 'controller'\r
2231 }\r
2232 });\r
2233 expect(function() {\r
2234 widget.fireEvent('foo');\r
2235 }).toThrow();\r
2236 });\r
2237\r
2238 it("should resolve to the widget with scope:'this'", function() {\r
2239 widget = new Widget({\r
2240 listeners: {\r
2241 foo: 'onFoo',\r
2242 scope: 'this'\r
2243 }\r
2244 });\r
2245 widget.fireEvent('foo');\r
2246 expectScope('widget');\r
2247 });\r
2248 });\r
2249\r
2250 describe("with view controller and defaultListenerScope", function() {\r
2251 beforeEach(function() {\r
2252 defineWidget({\r
2253 controller: new Controller(),\r
2254 defaultListenerScope: true\r
2255 });\r
2256 });\r
2257\r
2258 it("should resolve to the widget with unspecified scope", function() {\r
2259 widget = new Widget({\r
2260 listeners: {\r
2261 foo: 'onFoo'\r
2262 }\r
2263 });\r
2264 widget.fireEvent('foo');\r
2265 expectScope('widget');\r
2266 });\r
2267\r
2268 it("should fail with scope:'controller'", function() {\r
2269 widget = new Widget({\r
2270 listeners: {\r
2271 foo: 'onFoo',\r
2272 scope: 'controller'\r
2273 }\r
2274 });\r
2275 expect(function() {\r
2276 widget.fireEvent('foo');\r
2277 }).toThrow();\r
2278 });\r
2279\r
2280 it("should resolve to the widget with scope:'this'", function() {\r
2281 widget = new Widget({\r
2282 listeners: {\r
2283 foo: 'onFoo',\r
2284 scope: 'this'\r
2285 }\r
2286 });\r
2287 widget.fireEvent('foo');\r
2288 expectScope('widget');\r
2289 });\r
2290 });\r
2291\r
2292 describe("with defaultListenerScope on parent", function() {\r
2293 beforeEach(function() {\r
2294 defineParent({\r
2295 defaultListenerScope: true\r
2296 });\r
2297 defineWidget();\r
2298 });\r
2299\r
2300 it("should resolve to the parent with unspecified scope", function() {\r
2301 widget = new Widget({\r
2302 listeners: {\r
2303 foo: 'onFoo'\r
2304 }\r
2305 });\r
2306 parent = new Parent({\r
2307 items: widget\r
2308 });\r
2309 widget.fireEvent('foo');\r
2310 expectScope('parent');\r
2311 });\r
2312\r
2313 it("should fail with scope:'controller'", function() {\r
2314 widget = new Widget({\r
2315 listeners: {\r
2316 foo: 'onFoo',\r
2317 scope: 'controller'\r
2318 }\r
2319 });\r
2320 parent = new Parent({\r
2321 items: widget\r
2322 });\r
2323 expect(function() {\r
2324 widget.fireEvent('foo');\r
2325 }).toThrow();\r
2326 });\r
2327\r
2328 it("should resolve to the widget with scope:'this'", function() {\r
2329 widget = new Widget({\r
2330 listeners: {\r
2331 foo: 'onFoo',\r
2332 scope: 'this'\r
2333 }\r
2334 });\r
2335 parent = new Parent({\r
2336 items: widget\r
2337 });\r
2338 widget.fireEvent('foo');\r
2339 expectScope('widget');\r
2340 });\r
2341 });\r
2342\r
2343 describe("with view controller on parent", function() {\r
2344 beforeEach(function() {\r
2345 defineParent({\r
2346 controller: new ParentController()\r
2347 });\r
2348 defineWidget();\r
2349 });\r
2350\r
2351 it("should resolve to the parent view controller with unspecified scope", function() {\r
2352 widget = new Widget({\r
2353 listeners: {\r
2354 foo: 'onFoo'\r
2355 }\r
2356 });\r
2357 parent = new Parent({\r
2358 items: widget\r
2359 });\r
2360 widget.fireEvent('foo');\r
2361 expectScope('parentController');\r
2362 });\r
2363\r
2364 it("should resolve to the parent view controller with scope:'controller'", function() {\r
2365 widget = new Widget({\r
2366 listeners: {\r
2367 foo: 'onFoo',\r
2368 scope: 'controller'\r
2369 }\r
2370 });\r
2371 parent = new Parent({\r
2372 items: widget\r
2373 });\r
2374 widget.fireEvent('foo');\r
2375 expectScope('parentController');\r
2376 });\r
2377\r
2378 it("should resolve to the widget with scope:'this'", function() {\r
2379 widget = new Widget({\r
2380 listeners: {\r
2381 foo: 'onFoo',\r
2382 scope: 'this'\r
2383 }\r
2384 });\r
2385 parent = new Parent({\r
2386 items: widget\r
2387 });\r
2388 widget.fireEvent('foo');\r
2389 expectScope('widget');\r
2390 });\r
2391 });\r
2392\r
2393 describe("with view controller and defaultListenerScope on parent", function() {\r
2394 beforeEach(function() {\r
2395 defineParent({\r
2396 controller: new ParentController(),\r
2397 defaultListenerScope: true\r
2398 });\r
2399 defineWidget();\r
2400 });\r
2401\r
2402 it("should resolve to the parent with unspecified scope", function() {\r
2403 widget = new Widget({\r
2404 listeners: {\r
2405 foo: 'onFoo'\r
2406 }\r
2407 });\r
2408 parent = new Parent({\r
2409 items: widget\r
2410 });\r
2411 widget.fireEvent('foo');\r
2412 expectScope('parent');\r
2413 });\r
2414\r
2415 it("should resolve to the parent view controller with scope:'controller'", function() {\r
2416 widget = new Widget({\r
2417 listeners: {\r
2418 foo: 'onFoo',\r
2419 scope: 'controller'\r
2420 }\r
2421 });\r
2422 parent = new Parent({\r
2423 items: widget\r
2424 });\r
2425 widget.fireEvent('foo');\r
2426 expectScope('parentController');\r
2427 });\r
2428\r
2429 it("should resolve to the widget with scope:'this'", function() {\r
2430 widget = new Widget({\r
2431 listeners: {\r
2432 foo: 'onFoo',\r
2433 scope: 'this'\r
2434 }\r
2435 });\r
2436 parent = new Parent({\r
2437 items: widget\r
2438 });\r
2439 widget.fireEvent('foo');\r
2440 expectScope('widget');\r
2441 });\r
2442 });\r
2443\r
2444 describe("with defaultListenerScope on grandparent", function() {\r
2445 beforeEach(function() {\r
2446 defineGrandparent({\r
2447 defaultListenerScope: true\r
2448 });\r
2449 defineWidget();\r
2450 });\r
2451\r
2452 it("should resolve to the grandparent with unspecified scope", function() {\r
2453 widget = new Widget({\r
2454 listeners: {\r
2455 foo: 'onFoo'\r
2456 }\r
2457 });\r
2458 grandparent = new Grandparent({\r
2459 items: {\r
2460 items: widget\r
2461 }\r
2462 });\r
2463 widget.fireEvent('foo');\r
2464 expectScope('grandparent');\r
2465 });\r
2466\r
2467 it("should fail with scope:'controller'", function() {\r
2468 widget = new Widget({\r
2469 listeners: {\r
2470 foo: 'onFoo',\r
2471 scope: 'controller'\r
2472 }\r
2473 });\r
2474 grandparent = new Grandparent({\r
2475 items: {\r
2476 items: widget\r
2477 }\r
2478 });\r
2479 expect(function() {\r
2480 widget.fireEvent('foo');\r
2481 }).toThrow();\r
2482 });\r
2483\r
2484 it("should resolve to the widget with scope:'this'", function() {\r
2485 widget = new Widget({\r
2486 listeners: {\r
2487 foo: 'onFoo',\r
2488 scope: 'this'\r
2489 }\r
2490 });\r
2491 grandparent = new Grandparent({\r
2492 items: {\r
2493 items: widget\r
2494 }\r
2495 });\r
2496 widget.fireEvent('foo');\r
2497 expectScope('widget');\r
2498 });\r
2499 });\r
2500\r
2501 describe("with view controller on grandparent", function() {\r
2502 beforeEach(function() {\r
2503 defineGrandparent({\r
2504 controller: new GrandparentController()\r
2505 });\r
2506 defineWidget();\r
2507 });\r
2508\r
2509 it("should resolve to the grandparent view controller with unspecified scope", function() {\r
2510 widget = new Widget({\r
2511 listeners: {\r
2512 foo: 'onFoo'\r
2513 }\r
2514 });\r
2515 grandparent = new Grandparent({\r
2516 items: {\r
2517 items: widget\r
2518 }\r
2519 });\r
2520 widget.fireEvent('foo');\r
2521 expectScope('grandparentController');\r
2522 });\r
2523\r
2524 it("should resolve to the grandparent view controller with scope:'controller'", function() {\r
2525 widget = new Widget({\r
2526 listeners: {\r
2527 foo: 'onFoo',\r
2528 scope: 'controller'\r
2529 }\r
2530 });\r
2531 grandparent = new Grandparent({\r
2532 items: {\r
2533 items: widget\r
2534 }\r
2535 });\r
2536 widget.fireEvent('foo');\r
2537 expectScope('grandparentController');\r
2538 });\r
2539\r
2540 it("should resolve to the widget with scope:'this'", function() {\r
2541 widget = new Widget({\r
2542 listeners: {\r
2543 foo: 'onFoo',\r
2544 scope: 'this'\r
2545 }\r
2546 });\r
2547 grandparent = new Grandparent({\r
2548 items: {\r
2549 items: widget\r
2550 }\r
2551 });\r
2552 widget.fireEvent('foo');\r
2553 expectScope('widget');\r
2554 });\r
2555 });\r
2556\r
2557 describe("with view controller and defaultListenerScope on grandparent", function() {\r
2558 beforeEach(function() {\r
2559 defineGrandparent({\r
2560 controller: new GrandparentController(),\r
2561 defaultListenerScope: true\r
2562 });\r
2563 defineWidget();\r
2564 });\r
2565\r
2566 it("should resolve to the grandparent with unspecified scope", function() {\r
2567 widget = new Widget({\r
2568 listeners: {\r
2569 foo: 'onFoo'\r
2570 }\r
2571 });\r
2572 grandparent = new Grandparent({\r
2573 items: {\r
2574 items: widget\r
2575 }\r
2576 });\r
2577 widget.fireEvent('foo');\r
2578 expectScope('grandparent');\r
2579 });\r
2580\r
2581 it("should resolve to the grandparent view controller with scope:'controller'", function() {\r
2582 widget = new Widget({\r
2583 listeners: {\r
2584 foo: 'onFoo',\r
2585 scope: 'controller'\r
2586 }\r
2587 });\r
2588 grandparent = new Grandparent({\r
2589 items: {\r
2590 items: widget\r
2591 }\r
2592 });\r
2593 widget.fireEvent('foo');\r
2594 expectScope('grandparentController');\r
2595 });\r
2596\r
2597 it("should resolve to the widget with scope:'this'", function() {\r
2598 widget = new Widget({\r
2599 listeners: {\r
2600 foo: 'onFoo',\r
2601 scope: 'this'\r
2602 }\r
2603 });\r
2604 grandparent = new Grandparent({\r
2605 items: {\r
2606 items: widget\r
2607 }\r
2608 });\r
2609 widget.fireEvent('foo');\r
2610 expectScope('widget');\r
2611 });\r
2612 });\r
2613\r
2614 describe("with view controller on child and view controller on parent", function() {\r
2615 beforeEach(function() {\r
2616 defineParent({\r
2617 controller: new ParentController()\r
2618 });\r
2619\r
2620 defineWidget({\r
2621 controller: new Controller()\r
2622 });\r
2623 });\r
2624\r
2625 it("should resolve to the parent view controller with unspecified scope", function() {\r
2626 widget = new Widget({\r
2627 listeners: {\r
2628 foo: 'onFoo'\r
2629 }\r
2630 });\r
2631 parent = new Parent({\r
2632 items: widget\r
2633 });\r
2634 widget.fireEvent('foo');\r
2635 expectScope('parentController');\r
2636 });\r
2637\r
2638 it("should resolve to the parent view controller with scope:'controller'", function() {\r
2639 widget = new Widget({\r
2640 listeners: {\r
2641 foo: 'onFoo',\r
2642 scope: 'controller'\r
2643 }\r
2644 });\r
2645 parent = new Parent({\r
2646 items: widget\r
2647 });\r
2648 widget.fireEvent('foo');\r
2649 expectScope('parentController');\r
2650 });\r
2651\r
2652 it("should resolve to the widget with scope:'this'", function() {\r
2653 widget = new Widget({\r
2654 listeners: {\r
2655 foo: 'onFoo',\r
2656 scope: 'this'\r
2657 }\r
2658 });\r
2659 parent = new Parent({\r
2660 items: widget\r
2661 });\r
2662 widget.fireEvent('foo');\r
2663 expectScope('widget');\r
2664 });\r
2665 });\r
2666\r
2667 describe("with view controller on child and view controller on grandparent", function() {\r
2668 beforeEach(function() {\r
2669 defineGrandparent({\r
2670 controller: new GrandparentController()\r
2671 });\r
2672\r
2673 defineWidget({\r
2674 controller: new Controller()\r
2675 });\r
2676 });\r
2677\r
2678 it("should resolve to the grandparent view controller with unspecified scope", function() {\r
2679 widget = new Widget({\r
2680 listeners: {\r
2681 foo: 'onFoo'\r
2682 }\r
2683 });\r
2684 grandparent = new Grandparent({\r
2685 items: {\r
2686 items: widget\r
2687 }\r
2688 });\r
2689 widget.fireEvent('foo');\r
2690 expectScope('grandparentController');\r
2691 });\r
2692\r
2693 it("should resolve to the grandparent view controller with scope:'controller'", function() {\r
2694 widget = new Widget({\r
2695 listeners: {\r
2696 foo: 'onFoo',\r
2697 scope: 'controller'\r
2698 }\r
2699 });\r
2700 grandparent = new Grandparent({\r
2701 items: {\r
2702 items: widget\r
2703 }\r
2704 });\r
2705 widget.fireEvent('foo');\r
2706 expectScope('grandparentController');\r
2707 });\r
2708\r
2709 it("should resolve to the widget with scope:'this'", function() {\r
2710 widget = new Widget({\r
2711 listeners: {\r
2712 foo: 'onFoo',\r
2713 scope: 'this'\r
2714 }\r
2715 });\r
2716 grandparent = new Grandparent({\r
2717 items: {\r
2718 items: widget\r
2719 }\r
2720 });\r
2721 widget.fireEvent('foo');\r
2722 expectScope('widget');\r
2723 });\r
2724 });\r
2725\r
2726 describe("with view controller on child and defaultListenerScope on parent", function() {\r
2727 beforeEach(function() {\r
2728 defineParent({\r
2729 defaultListenerScope: true\r
2730 });\r
2731\r
2732 defineWidget({\r
2733 controller: new Controller()\r
2734 });\r
2735 });\r
2736\r
2737 it("should resolve to the parent with unspecified scope", function() {\r
2738 widget = new Widget({\r
2739 listeners: {\r
2740 foo: 'onFoo'\r
2741 }\r
2742 });\r
2743 parent = new Parent({\r
2744 items: widget\r
2745 });\r
2746 widget.fireEvent('foo');\r
2747 expectScope('parent');\r
2748 });\r
2749\r
2750 it("should fail with scope:'controller'", function() {\r
2751 widget = new Widget({\r
2752 listeners: {\r
2753 foo: 'onFoo',\r
2754 scope: 'controller'\r
2755 }\r
2756 });\r
2757 parent = new Parent({\r
2758 items: widget\r
2759 });\r
2760 expect(function() {\r
2761 widget.fireEvent('foo');\r
2762 }).toThrow();\r
2763 });\r
2764\r
2765 it("should resolve to the widget with scope:'this'", function() {\r
2766 widget = new Widget({\r
2767 listeners: {\r
2768 foo: 'onFoo',\r
2769 scope: 'this'\r
2770 }\r
2771 });\r
2772 parent = new Parent({\r
2773 items: widget\r
2774 });\r
2775 widget.fireEvent('foo');\r
2776 expectScope('widget');\r
2777 });\r
2778 });\r
2779\r
2780 describe("with view controller on parent and defaultListenerScope on child", function() {\r
2781 beforeEach(function() {\r
2782 defineParent({\r
2783 controller: new ParentController()\r
2784 });\r
2785\r
2786 defineWidget({\r
2787 defaultListenerScope: true\r
2788 });\r
2789 });\r
2790\r
2791 it("should resolve to the parent view controller with unspecified scope", function() {\r
2792 widget = new Widget({\r
2793 listeners: {\r
2794 foo: 'onFoo'\r
2795 }\r
2796 });\r
2797 parent = new Parent({\r
2798 items: widget\r
2799 });\r
2800 widget.fireEvent('foo');\r
2801 expectScope('parentController');\r
2802 });\r
2803\r
2804 it("should resolve to the parent view controller with scope:'controller'", function() {\r
2805 widget = new Widget({\r
2806 listeners: {\r
2807 foo: 'onFoo',\r
2808 scope: 'controller'\r
2809 }\r
2810 });\r
2811 parent = new Parent({\r
2812 items: widget\r
2813 });\r
2814 widget.fireEvent('foo');\r
2815 expectScope('parentController');\r
2816 });\r
2817\r
2818 it("should resolve to the widget with scope:'this'", function() {\r
2819 widget = new Widget({\r
2820 listeners: {\r
2821 foo: 'onFoo',\r
2822 scope: 'this'\r
2823 }\r
2824 });\r
2825 parent = new Parent({\r
2826 items: widget\r
2827 });\r
2828 widget.fireEvent('foo');\r
2829 expectScope('widget');\r
2830 });\r
2831 });\r
2832\r
2833 describe("with view controller on child and defaultListenerScope on grandparent", function() {\r
2834 beforeEach(function() {\r
2835 defineGrandparent({\r
2836 defaultListenerScope: true\r
2837 });\r
2838\r
2839 defineWidget({\r
2840 controller: new Controller()\r
2841 });\r
2842 });\r
2843\r
2844 it("should resolve to the grandparent with unspecified scope", function() {\r
2845 widget = new Widget({\r
2846 listeners: {\r
2847 foo: 'onFoo'\r
2848 }\r
2849 });\r
2850 grandparent = new Grandparent({\r
2851 items: {\r
2852 items: widget\r
2853 }\r
2854 });\r
2855 widget.fireEvent('foo');\r
2856 expectScope('grandparent');\r
2857 });\r
2858\r
2859 it("should fail with scope:'controller'", function() {\r
2860 widget = new Widget({\r
2861 listeners: {\r
2862 foo: 'onFoo',\r
2863 scope: 'controller'\r
2864 }\r
2865 });\r
2866 grandparent = new Grandparent({\r
2867 items: {\r
2868 items: widget\r
2869 }\r
2870 });\r
2871 expect(function() {\r
2872 widget.fireEvent('foo');\r
2873 }).toThrow();\r
2874 });\r
2875\r
2876 it("should resolve to the widget with scope:'this'", function() {\r
2877 widget = new Widget({\r
2878 listeners: {\r
2879 foo: 'onFoo',\r
2880 scope: 'this'\r
2881 }\r
2882 });\r
2883 grandparent = new Grandparent({\r
2884 items: {\r
2885 items: widget\r
2886 }\r
2887 });\r
2888 widget.fireEvent('foo');\r
2889 expectScope('widget');\r
2890 });\r
2891 });\r
2892\r
2893 describe("with view controller on grandparent and defaultListenerScope on child", function() {\r
2894 beforeEach(function() {\r
2895 defineGrandparent({\r
2896 controller: new GrandparentController()\r
2897 });\r
2898\r
2899 defineWidget({\r
2900 defaultListenerScope: true\r
2901 });\r
2902 });\r
2903\r
2904 it("should resolve to the grandparent view controller with unspecified scope", function() {\r
2905 widget = new Widget({\r
2906 listeners: {\r
2907 foo: 'onFoo'\r
2908 }\r
2909 });\r
2910 grandparent = new Grandparent({\r
2911 items: {\r
2912 items: widget\r
2913 }\r
2914 });\r
2915 widget.fireEvent('foo');\r
2916 expectScope('grandparentController');\r
2917 });\r
2918\r
2919 it("should resolve to the grandparent view controller with scope:'controller'", function() {\r
2920 widget = new Widget({\r
2921 listeners: {\r
2922 foo: 'onFoo',\r
2923 scope: 'controller'\r
2924 }\r
2925 });\r
2926 grandparent = new Grandparent({\r
2927 items: {\r
2928 items: widget\r
2929 }\r
2930 });\r
2931 widget.fireEvent('foo');\r
2932 expectScope('grandparentController');\r
2933 });\r
2934\r
2935 it("should resolve to the widget with scope:'this'", function() {\r
2936 widget = new Widget({\r
2937 listeners: {\r
2938 foo: 'onFoo',\r
2939 scope: 'this'\r
2940 }\r
2941 });\r
2942 grandparent = new Grandparent({\r
2943 items: {\r
2944 items: widget\r
2945 }\r
2946 });\r
2947 widget.fireEvent('foo');\r
2948 expectScope('widget');\r
2949 });\r
2950 });\r
2951\r
2952 describe("with handler declared as a function reference", function() {\r
2953 var handler, scope;\r
2954\r
2955 function defineWidget(cfg) {\r
2956 Widget = Ext.define(null, Ext.merge({\r
2957 extend: 'Ext.Widget'\r
2958 }, cfg));\r
2959 }\r
2960\r
2961 beforeEach(function() {\r
2962 handler = jasmine.createSpy();\r
2963 handler.andCallFake(function() {\r
2964 scope = this;\r
2965 });\r
2966 });\r
2967\r
2968 afterEach(function() {\r
2969 scope = null;\r
2970 });\r
2971\r
2972 it("should use the widget as the default scope", function() {\r
2973 defineWidget();\r
2974 widget = new Widget({\r
2975 listeners: {\r
2976 foo: handler\r
2977 }\r
2978 });\r
2979 widget.fireEvent('foo');\r
2980 expect(scope).toBe(widget);\r
2981 });\r
2982\r
2983 it("should use an arbitrary object as the scope", function() {\r
2984 defineWidget();\r
2985 var scope = {};\r
2986\r
2987 widget = new Widget({\r
2988 listeners: {\r
2989 foo: handler,\r
2990 scope: scope\r
2991 }\r
2992 });\r
2993 widget.fireEvent('foo');\r
2994 expect(scope).toBe(scope);\r
2995 });\r
2996\r
2997 it("should use the widget with scope:'this'", function() {\r
2998 defineWidget();\r
2999 widget = new Widget({\r
3000 listeners: {\r
3001 foo: handler,\r
3002 scope: 'this'\r
3003 }\r
3004 });\r
3005 widget.fireEvent('foo');\r
3006 expect(scope).toBe(widget);\r
3007 });\r
3008\r
3009 it("should fail with scope:'controller'", function() {\r
3010 defineWidget();\r
3011 widget = new Widget({\r
3012 listeners: {\r
3013 foo: handler,\r
3014 scope: 'controller'\r
3015 }\r
3016 });\r
3017 expect(function() {\r
3018 widget.fireEvent('foo');\r
3019 }).toThrow();\r
3020 });\r
3021\r
3022 it("should use the widget with scope:'this' specified on an inner object", function() {\r
3023 defineWidget();\r
3024 widget = new Widget({\r
3025 listeners: {\r
3026 foo: {\r
3027 fn: handler,\r
3028 scope: 'this'\r
3029 }\r
3030 }\r
3031 });\r
3032 widget.fireEvent('foo');\r
3033 expect(scope).toBe(widget);\r
3034 });\r
3035\r
3036 it("should fail with scope:'controller' specified on an inner object", function() {\r
3037 defineWidget();\r
3038 widget = new Widget({\r
3039 listeners: {\r
3040 foo: {\r
3041 fn: handler,\r
3042 scope: 'controller'\r
3043 }\r
3044 }\r
3045 });\r
3046 expect(function() {\r
3047 widget.fireEvent('foo');\r
3048 }).toThrow();\r
3049 });\r
3050\r
3051 describe("with view controller", function() {\r
3052 beforeEach(function() {\r
3053 defineWidget({\r
3054 controller: new Controller()\r
3055 });\r
3056 });\r
3057\r
3058 it("should resolve to the widget with unspecified scope", function() {\r
3059 widget = new Widget({\r
3060 listeners: {\r
3061 foo: handler\r
3062 }\r
3063 });\r
3064 widget.fireEvent('foo');\r
3065 expect(scope).toBe(widget);\r
3066 });\r
3067\r
3068 it("should fail with scope:'controller'", function() {\r
3069 widget = new Widget({\r
3070 listeners: {\r
3071 foo: handler,\r
3072 scope: 'controller'\r
3073 }\r
3074 });\r
3075 expect(function() {\r
3076 widget.fireEvent('foo');\r
3077 }).toThrow();\r
3078 });\r
3079\r
3080 it("should resolve to the widget with scope:'this'", function() {\r
3081 widget = new Widget({\r
3082 listeners: {\r
3083 foo: handler,\r
3084 scope: 'this'\r
3085 }\r
3086 });\r
3087 widget.fireEvent('foo');\r
3088 expect(scope).toBe(widget);\r
3089 });\r
3090 });\r
3091\r
3092 describe("with defaultListenerScope", function() {\r
3093 beforeEach(function() {\r
3094 defineWidget({\r
3095 defaultListenerScope: true\r
3096 });\r
3097 });\r
3098\r
3099 it("should resolve to the widget with unspecified scope", function() {\r
3100 widget = new Widget({\r
3101 listeners: {\r
3102 foo: handler\r
3103 }\r
3104 });\r
3105 widget.fireEvent('foo');\r
3106 expect(scope).toBe(widget);\r
3107 });\r
3108\r
3109 it("should fail with scope:'controller'", function() {\r
3110 widget = new Widget({\r
3111 listeners: {\r
3112 foo: handler,\r
3113 scope: 'controller'\r
3114 }\r
3115 });\r
3116 expect(function() {\r
3117 widget.fireEvent('foo');\r
3118 }).toThrow();\r
3119 });\r
3120\r
3121 it("should resolve to the widget with scope:'this'", function() {\r
3122 widget = new Widget({\r
3123 listeners: {\r
3124 foo: handler,\r
3125 scope: 'this'\r
3126 }\r
3127 });\r
3128 widget.fireEvent('foo');\r
3129 expect(scope).toBe(widget);\r
3130 });\r
3131 });\r
3132\r
3133 describe("with defaultListenerScope on parent", function() {\r
3134 beforeEach(function() {\r
3135 defineParent({\r
3136 defaultListenerScope: true\r
3137 });\r
3138 defineWidget();\r
3139 });\r
3140\r
3141 it("should resolve to the widget with unspecified scope", function() {\r
3142 widget = new Widget({\r
3143 listeners: {\r
3144 foo: handler\r
3145 }\r
3146 });\r
3147 parent = new Parent({\r
3148 items: widget\r
3149 });\r
3150 widget.fireEvent('foo');\r
3151 expect(scope).toBe(widget);\r
3152 });\r
3153\r
3154 it("should fail with scope:'controller'", function() {\r
3155 widget = new Widget({\r
3156 listeners: {\r
3157 foo: handler,\r
3158 scope: 'controller'\r
3159 }\r
3160 });\r
3161 parent = new Parent({\r
3162 items: widget\r
3163 });\r
3164 expect(function() {\r
3165 widget.fireEvent('foo');\r
3166 }).toThrow();\r
3167 });\r
3168\r
3169 it("should resolve to the widget with scope:'this'", function() {\r
3170 widget = new Widget({\r
3171 listeners: {\r
3172 foo: handler,\r
3173 scope: 'this'\r
3174 }\r
3175 });\r
3176 parent = new Parent({\r
3177 items: widget\r
3178 });\r
3179 widget.fireEvent('foo');\r
3180 expect(scope).toBe(widget);\r
3181 });\r
3182 });\r
3183\r
3184 describe("with view controller on parent", function() {\r
3185 beforeEach(function() {\r
3186 defineParent({\r
3187 controller: new ParentController()\r
3188 });\r
3189 defineWidget();\r
3190 });\r
3191\r
3192 it("should resolve to the widget with unspecified scope", function() {\r
3193 widget = new Widget({\r
3194 listeners: {\r
3195 foo: handler\r
3196 }\r
3197 });\r
3198 parent = new Parent({\r
3199 items: widget\r
3200 });\r
3201 widget.fireEvent('foo');\r
3202 expect(scope).toBe(widget);\r
3203 });\r
3204\r
3205 it("should resolve to the parent view controller with scope:'controller'", function() {\r
3206 widget = new Widget({\r
3207 listeners: {\r
3208 foo: handler,\r
3209 scope: 'controller'\r
3210 }\r
3211 });\r
3212 parent = new Parent({\r
3213 items: widget\r
3214 });\r
3215 widget.fireEvent('foo');\r
3216 expect(scope).toBe(parent.getController());\r
3217 });\r
3218\r
3219 it("should resolve to the widget with scope:'this'", function() {\r
3220 widget = new Widget({\r
3221 listeners: {\r
3222 foo: handler,\r
3223 scope: 'this'\r
3224 }\r
3225 });\r
3226 parent = new Parent({\r
3227 items: widget\r
3228 });\r
3229 widget.fireEvent('foo');\r
3230 expect(scope).toBe(widget);\r
3231 });\r
3232 });\r
3233 });\r
3234 });\r
3235 });\r
3236});\r