]> git.proxmox.com Git - extjs.git/blame - extjs/classic/classic/test/specs/form/field/Checkbox.js
add extjs 6.0.1 sources
[extjs.git] / extjs / classic / classic / test / specs / form / field / Checkbox.js
CommitLineData
6527f429
DM
1describe("Ext.form.field.Checkbox", function() {\r
2 var component, makeComponent;\r
3\r
4 function expectAria(attr, value) {\r
5 jasmine.expectAriaAttr(component.inputEl, attr, value);\r
6 }\r
7 \r
8 beforeEach(function() {\r
9 makeComponent = function(config) {\r
10 config = config || {};\r
11 Ext.applyIf(config, {\r
12 name: "test",\r
13 renderTo: Ext.getBody()\r
14 });\r
15 component = new Ext.form.field.Checkbox(config);\r
16 };\r
17 });\r
18\r
19 afterEach(function() {\r
20 if (component) {\r
21 component.destroy();\r
22 }\r
23 component = makeComponent = null;\r
24\r
25 });\r
26\r
27 it("should be registered with the 'checkboxfield' xtype", function() {\r
28 component = Ext.create("Ext.form.field.Checkbox", {name: 'test'});\r
29 expect(component instanceof Ext.form.field.Checkbox).toBe(true);\r
30 expect(Ext.getClass(component).xtype).toBe("checkboxfield");\r
31 });\r
32 \r
33 describe("configuring", function() {\r
34 it("should accept a value config", function() {\r
35 makeComponent({\r
36 value: true\r
37 }); \r
38 expect(component.checked).toBe(true);\r
39 }); \r
40 });\r
41\r
42 describe("rendering", function() {\r
43 // NOTE this doesn't test the main label, error icon, etc. just the parts specific to Checkbox.\r
44\r
45 describe("bodyEl", function() {\r
46 beforeEach(function() {\r
47 makeComponent({value: 'foo'});\r
48 });\r
49\r
50 it("should exist", function() {\r
51 expect(component.bodyEl).toBeDefined();\r
52 });\r
53\r
54 it("should have the class 'x-form-item-body'", function() {\r
55 expect(component.bodyEl.hasCls('x-form-item-body')).toBe(true);\r
56 });\r
57\r
58 it("should have the id '[id]-bodyEl'", function() {\r
59 expect(component.bodyEl.dom.id).toEqual(component.id + '-bodyEl');\r
60 });\r
61 });\r
62\r
63 describe("inputEl (checkbox element)", function() {\r
64 beforeEach(function() {\r
65 makeComponent({value: 'foo'});\r
66 });\r
67\r
68 it("should exist", function() {\r
69 expect(component.inputEl).toBeDefined();\r
70 });\r
71\r
72 it("should be a child of the div wrapper", function() {\r
73 expect(component.inputEl.dom.parentNode.tagName.toLowerCase()).toBe('div');\r
74 });\r
75\r
76 it("should be an ancestor of the bodyEl", function() {\r
77 expect(component.inputEl.dom.parentNode.parentNode).toBe(component.bodyEl.dom);\r
78 });\r
79\r
80 it("should be an input element", function() {\r
81 expect(component.inputEl.dom.tagName.toLowerCase()).toEqual('input');\r
82 });\r
83\r
84 it("should have type='checkbox'", function() {\r
85 expect(component.inputEl.dom.tagName.toLowerCase()).toEqual('input');\r
86 });\r
87\r
88 it("should have the component's inputId as its id", function() {\r
89 expect(component.inputEl.dom.id).toEqual(component.inputId);\r
90 });\r
91\r
92 it("should have the 'fieldCls' config as a class", function() {\r
93 expect(component.displayEl.hasCls(component.fieldCls)).toBe(true);\r
94 });\r
95 \r
96 describe("ARIA attributes", function() {\r
97 it("should have checkbox role", function() {\r
98 expectAria('role', 'checkbox');\r
99 });\r
100 \r
101 it("should have aria-hidden", function() {\r
102 expectAria('aria-hidden', 'false');\r
103 });\r
104 \r
105 it("should have aria-disabled", function() {\r
106 expectAria('aria-disabled', 'false');\r
107 });\r
108 \r
109 it("should have aria-invalid", function() {\r
110 expectAria('aria-invalid', 'false');\r
111 });\r
112 \r
113 it("should have aria-checked", function() {\r
114 expectAria('aria-checked', 'false');\r
115 });\r
116 \r
117 describe("aria-readonly", function() {\r
118 it("should false by default", function() {\r
119 expectAria('aria-readonly', 'false');\r
120 });\r
121 \r
122 it("should be true when readOnly", function() {\r
123 var cb2 = new Ext.form.field.Checkbox({\r
124 renderTo: Ext.getBody(),\r
125 name: 'cb2',\r
126 readOnly: true\r
127 });\r
128 \r
129 jasmine.expectAriaAttr(cb2.inputEl, 'aria-readonly', 'true');\r
130 \r
131 Ext.destroy(cb2);\r
132 });\r
133 });\r
134 });\r
135 });\r
136\r
137\r
138 describe("box label", function() {\r
139 it("should not be created by default", function() {\r
140 makeComponent({});\r
141 expect(component.bodyEl.child('label')).toBeNull();\r
142 });\r
143\r
144 it("should be created if the boxLabel config is defined", function() {\r
145 makeComponent({boxLabel: 'the box label'});\r
146 expect(component.bodyEl.down('label')).not.toBeNull();\r
147 });\r
148\r
149 it("should be stored as a 'boxLabelEl' reference", function() {\r
150 makeComponent({boxLabel: 'the box label'});\r
151 expect(component.bodyEl.down('label').dom).toBe(component.boxLabelEl.dom);\r
152 });\r
153\r
154 it("should have the class 'x-form-cb-label' by default", function() {\r
155 makeComponent({boxLabel: 'the box label'});\r
156 expect(component.boxLabelEl.hasCls('x-form-cb-label')).toBe(true);\r
157 });\r
158\r
159 it("should be given the configured boxLabelCls", function() {\r
160 makeComponent({boxLabel: 'the box label', boxLabelCls: 'my-custom-boxLabelCls'});\r
161 expect(component.boxLabelEl.hasCls('my-custom-boxLabelCls')).toBe(true);\r
162 });\r
163\r
164 it("should have a 'for' attribute set to the inputId", function() {\r
165 makeComponent({boxLabel: 'the box label'});\r
166 expect(component.boxLabelEl.getAttribute('for')).toEqual(component.inputId);\r
167 });\r
168\r
169 it("should contain the boxLabel as its inner text node", function() {\r
170 makeComponent({boxLabel: 'the box label'});\r
171 expect(component.boxLabelEl.dom).hasHTML('the box label');\r
172 });\r
173 \r
174 it("should be set to aria-labelledby", function() {\r
175 makeComponent({ boxLabel: 'foo' });\r
176 expectAria('aria-labelledby', component.boxLabelEl.id);\r
177 });\r
178\r
179 describe('boxLabelAlign', function() {\r
180 it("should render the label after the checkbox by default", function() {\r
181 makeComponent({boxLabel: 'the box label'});\r
182 expect(component.boxLabelEl.prev().prev().dom).toBe(component.inputEl.dom);\r
183 });\r
184 it("should render the label after the checkbox when boxLabelAlign='after'", function() {\r
185 makeComponent({boxLabel: 'the box label', boxLabelAlign: 'after'});\r
186 expect(component.boxLabelEl.prev().prev().dom).toBe(component.inputEl.dom);\r
187 });\r
188 it("should give the 'after' label a class of {boxLabelCls}-after", function() {\r
189 makeComponent({boxLabel: 'the box label', boxLabelAlign: 'after'});\r
190 expect(component.boxLabelEl.hasCls(component.boxLabelCls + '-after')).toBe(true);\r
191 });\r
192 it("should render the label before the checkbox when boxLabelAlign='before'", function() {\r
193 makeComponent({boxLabel: 'the box label', boxLabelAlign: 'before'});\r
194 expect(component.boxLabelEl.next().dom).toBe(component.inputEl.dom);\r
195 });\r
196 it("should give the 'before' label a class of {boxLabelCls}-before", function() {\r
197 makeComponent({boxLabel: 'the box label', boxLabelAlign: 'before'});\r
198 expect(component.boxLabelEl.hasCls(component.boxLabelCls + '-before')).toBe(true);\r
199 });\r
200 });\r
201 \r
202 describe("noBoxLabelCls", function() {\r
203 it("should add the class when there is no boxLabel", function() {\r
204 makeComponent();\r
205 expect(component.el.down('.' + component.noBoxLabelCls, true)).not.toBeNull();\r
206 });\r
207 \r
208 it("should not add the class when there is a boxLabel", function() {\r
209 makeComponent({\r
210 boxLabel: 'Foo'\r
211 });\r
212 expect(component.el.down('.' + component.noBoxLabelCls, true)).toBeNull();\r
213 });\r
214 });\r
215 });\r
216 });\r
217\r
218 describe("setting value", function() {\r
219\r
220 it("should accept the checked attribute", function(){\r
221 makeComponent({\r
222 checked: true\r
223 });\r
224 expect(component.getValue()).toBeTruthy();\r
225 component.destroy();\r
226\r
227 makeComponent();\r
228 expect(component.getValue()).toBeFalsy();\r
229\r
230 });\r
231\r
232 it("should allow the value to be set while not rendered", function(){\r
233 makeComponent({\r
234 renderTo: null\r
235 });\r
236 component.setValue(true);\r
237 component.render(Ext.getBody());\r
238 expect(component.getValue()).toBeTruthy();\r
239 });\r
240\r
241 it("should support different values for setValue", function(){\r
242 makeComponent();\r
243 component.setValue('true');\r
244 expect(component.getValue()).toBeTruthy();\r
245 component.destroy();\r
246\r
247 makeComponent();\r
248 component.setValue('1');\r
249 expect(component.getValue()).toBeTruthy();\r
250 component.destroy();\r
251\r
252 makeComponent();\r
253 component.setValue('on');\r
254 expect(component.getValue()).toBeTruthy();\r
255 component.destroy();\r
256\r
257 makeComponent({\r
258 inputValue: 'foo'\r
259 });\r
260 component.setValue('foo');\r
261 expect(component.getValue()).toBeTruthy();\r
262 component.setValue('bar');\r
263 expect(component.getValue()).toBeFalsy();\r
264 });\r
265\r
266 it("should fire the handler, with the correct scope", function(){\r
267 var o1 = {\r
268 fn: function(){}\r
269 }, o2 = {},\r
270 spy = spyOn(o1, 'fn');\r
271\r
272\r
273 makeComponent({\r
274 handler: o1.fn\r
275 });\r
276 component.setValue(true);\r
277 expect(o1.fn).toHaveBeenCalledWith(component, true);\r
278 expect(spy.calls[0].object).toBe(component);\r
279 component.destroy();\r
280\r
281 makeComponent({\r
282 handler: o1.fn,\r
283 scope: o1\r
284 });\r
285 component.setValue(true);\r
286 expect(o1.fn).toHaveBeenCalledWith(component, true);\r
287 expect(spy.calls[1].object).toBe(o1);\r
288 component.destroy();\r
289\r
290 makeComponent({\r
291 handler: o1.fn,\r
292 scope: o2\r
293 });\r
294 component.setValue(true);\r
295 expect(o1.fn).toHaveBeenCalledWith(component, true);\r
296 expect(spy.calls[2].object).toBe(o2);\r
297 });\r
298\r
299 it("should not fire the handler if the value doesn't change", function() {\r
300 makeComponent({\r
301 handler: function() {}\r
302 });\r
303 spyOn(component, 'handler');\r
304 component.setValue(false);\r
305 expect(component.handler).not.toHaveBeenCalled();\r
306 });\r
307\r
308 it("should allow the handler to route to a view controller", function() {\r
309 var ctrl = new Ext.app.ViewController();\r
310 ctrl.someMethod = function() {};\r
311 spyOn(ctrl, 'someMethod');\r
312\r
313 var ct = new Ext.container.Container({\r
314 controller: ctrl,\r
315 renderTo: Ext.getBody(),\r
316 items: {\r
317 xtype: 'checkbox',\r
318 handler: 'someMethod'\r
319 }\r
320 });\r
321\r
322 ct.items.first().setValue(true);\r
323 expect(ctrl.someMethod).toHaveBeenCalled();\r
324 ct.destroy();\r
325 });\r
326 \r
327 it("should update aria-checked", function() {\r
328 makeComponent();\r
329 component.setValue(true);\r
330 \r
331 expectAria('aria-checked', 'true');\r
332 });\r
333 });\r
334\r
335 describe('readOnly', function() {\r
336 it("should set the checkbox to disabled=true", function() {\r
337 makeComponent({\r
338 readOnly: true,\r
339 renderTo: Ext.getBody()\r
340 });\r
341 expect(component.inputEl.dom.disabled).toBe(true);\r
342 });\r
343\r
344 describe('setReadOnly method', function() {\r
345 it("should set disabled=true when the arg is true", function() {\r
346 makeComponent({\r
347 readOnly: false,\r
348 renderTo: Ext.getBody()\r
349 });\r
350 component.setReadOnly(true);\r
351 expect(component.inputEl.dom.disabled).toBe(true);\r
352 });\r
353 it("should set disabled=false when the arg is false", function() {\r
354 makeComponent({\r
355 readOnly: true,\r
356 renderTo: Ext.getBody()\r
357 });\r
358 component.setReadOnly(false);\r
359 expect(component.inputEl.dom.disabled).toBe(false);\r
360 });\r
361 it("should set disabled=true when the arg is false but the component is disabled", function() {\r
362 makeComponent({\r
363 readOnly: true,\r
364 disabled: true,\r
365 renderTo: Ext.getBody()\r
366 });\r
367 component.setReadOnly(false);\r
368 expect(component.inputEl.dom.disabled).toBe(true);\r
369 });\r
370 });\r
371 });\r
372\r
373 describe('submit value', function() {\r
374 it("should submit the inputValue when checked", function() {\r
375 makeComponent({\r
376 name: 'cb-name',\r
377 inputValue: 'the-input-value',\r
378 checked: true\r
379 });\r
380 expect(component.getSubmitData()).toEqual({'cb-name': 'the-input-value'});\r
381 });\r
382\r
383 it("should submit nothing when unchecked", function() {\r
384 makeComponent({\r
385 name: 'cb-name',\r
386 inputValue: 'the-input-value',\r
387 checked: false\r
388 });\r
389 expect(component.getSubmitData()).toBeNull();\r
390 });\r
391\r
392 it("should submit the uncheckedValue when unchecked, if defined", function() {\r
393 makeComponent({\r
394 name: 'cb-name',\r
395 inputValue: 'the-input-value',\r
396 uncheckedValue: 'the-unchecked-value',\r
397 checked: false\r
398 });\r
399 expect(component.getSubmitData()).toEqual({'cb-name': 'the-unchecked-value'});\r
400 });\r
401 });\r
402\r
403 describe('getModelData', function() {\r
404 it("should return true when checked", function() {\r
405 makeComponent({\r
406 name: 'cb-name',\r
407 inputValue: 'the-input-value',\r
408 checked: true\r
409 });\r
410 expect(component.getModelData()).toEqual({'cb-name': true});\r
411 });\r
412\r
413 it("should return false when unchecked", function() {\r
414 makeComponent({\r
415 name: 'cb-name',\r
416 inputValue: 'the-input-value',\r
417 uncheckedValue: 'the-unchecked-value',\r
418 checked: false\r
419 });\r
420 expect(component.getModelData()).toEqual({'cb-name': false});\r
421 });\r
422 });\r
423 \r
424 describe("setRawValue", function() {\r
425 it("should be able to fire the change event when checking after calling setRawValue", function() {\r
426 var val;\r
427 makeComponent();\r
428 component.setRawValue(true);\r
429 component.on('change', function(arg1, arg2) {\r
430 val = arg2;\r
431 }); \r
432 jasmine.fireMouseEvent(component.inputEl.dom, 'click');\r
433 expect(val).toBe(false);\r
434 }); \r
435 \r
436 it("should be dirty after calling setRawValue", function() {\r
437 makeComponent();\r
438 component.setRawValue(true);\r
439 expect(component.isDirty()).toBe(true);\r
440 });\r
441 });\r
442\r
443 describe("setBoxLabel", function() {\r
444\r
445 var boxOnlyWidth = 0,\r
446 withLabelWidth = 0,\r
447 label = '<div style="width: 100px;">a</div>';\r
448\r
449 beforeEach(function() {\r
450 var temp;\r
451\r
452 if (boxOnlyWidth === 0) {\r
453 temp = new Ext.form.field.Checkbox({\r
454 renderTo: Ext.getBody()\r
455 });\r
456 boxOnlyWidth = temp.getWidth();\r
457 temp.destroy();\r
458\r
459 temp = new Ext.form.field.Checkbox({\r
460 renderTo: Ext.getBody(),\r
461 boxLabel: label\r
462 });\r
463 withLabelWidth = temp.getWidth();\r
464 temp.destroy();\r
465 }\r
466 });\r
467\r
468 describe("before render", function() {\r
469 describe("with an existing label", function() {\r
470 it("should clear the label when passing an empty string", function() {\r
471 makeComponent({\r
472 boxLabel: 'Foo',\r
473 renderTo: null\r
474 });\r
475 component.setBoxLabel('');\r
476 component.render(Ext.getBody());\r
477 expect(component.getWidth()).toBe(boxOnlyWidth);\r
478 });\r
479\r
480 it("should change the label when passing an empty string", function() {\r
481 makeComponent({\r
482 boxLabel: 'Foo',\r
483 renderTo: null\r
484 });\r
485 component.setBoxLabel('');\r
486 component.render(Ext.getBody());\r
487 expect(component.getWidth()).toBe(boxOnlyWidth);\r
488 });\r
489 });\r
490\r
491 describe("with no label configured", function() {\r
492 it("should show the label", function() {\r
493 makeComponent({\r
494 renderTo: null\r
495 });\r
496 component.setBoxLabel(label);\r
497 component.render(Ext.getBody());\r
498 expect(component.getWidth()).toBe(withLabelWidth);\r
499 });\r
500 });\r
501 });\r
502\r
503 describe("after render", function() {\r
504 describe("with an existing label", function() {\r
505 it("should clear the label when passing an empty string", function() {\r
506 makeComponent({\r
507 boxLabel: 'Foo',\r
508 liquidLayout: false // Use false so layouts run\r
509 });\r
510 var count = component.componentLayoutCounter;\r
511 component.setBoxLabel('');\r
512 expect(component.getWidth()).toBe(boxOnlyWidth);\r
513 expect(component.componentLayoutCounter).toBe(count + 1);\r
514 });\r
515\r
516 it("should change the label when passing an empty string", function() {\r
517 makeComponent({\r
518 boxLabel: 'Foo',\r
519 liquidLayout: false // Use false so layouts run\r
520 });\r
521 var count = component.componentLayoutCounter;\r
522 component.setBoxLabel(label);\r
523 expect(component.getWidth()).toBe(withLabelWidth);\r
524 expect(component.componentLayoutCounter).toBe(count + 1);\r
525 });\r
526 });\r
527\r
528 describe("with no label configured", function() {\r
529 it("should show the label", function() {\r
530 makeComponent({\r
531 liquidLayout: false // Use false so layouts run\r
532 });\r
533 var count = component.componentLayoutCounter;\r
534 component.setBoxLabel(label);\r
535 expect(component.getWidth()).toBe(withLabelWidth);\r
536 expect(component.componentLayoutCounter).toBe(count + 1);\r
537 });\r
538 });\r
539 });\r
540 });\r
541\r
542});\r