|
16 | 16 | */ |
17 | 17 |
|
18 | 18 | import {Checkbox} from '@material/mwc-checkbox'; |
| 19 | +import {html} from 'lit-html'; |
19 | 20 |
|
20 | | -import {Fake, rafPromise} from '../../../test/src/util/helpers'; |
| 21 | +import {Fake, fixture, rafPromise, TestFixture} from '../../../test/src/util/helpers'; |
21 | 22 |
|
22 | 23 | interface CheckboxInternals { |
23 | 24 | formElement: HTMLInputElement; |
24 | 25 | animationClass: string; |
25 | 26 | } |
26 | 27 |
|
| 28 | +interface CheckboxProps { |
| 29 | + checked: boolean; |
| 30 | + indeterminate: boolean; |
| 31 | + disabled: boolean; |
| 32 | + value: string; |
| 33 | + reduceTouchTarget: boolean; |
| 34 | +} |
| 35 | + |
| 36 | +const defaultCheckbox = html`<mwc-checkbox></mwc-checkbox>`; |
| 37 | + |
| 38 | +const checkbox = (propsInit: Partial<CheckboxProps>) => { |
| 39 | + return html` |
| 40 | + <mwc-checkbox |
| 41 | + ?checked=${propsInit.checked === true} |
| 42 | + ?indeterminate=${propsInit.indeterminate === true} |
| 43 | + ?disabled=${propsInit.disabled === true} |
| 44 | + value=${propsInit.value ?? ''} |
| 45 | + ?reduceTouchTarget=${propsInit.reduceTouchTarget === true}> |
| 46 | + </mwc-checkbox> |
| 47 | + `; |
| 48 | +}; |
| 49 | + |
27 | 50 | suite('mwc-checkbox', () => { |
| 51 | + let fixt: TestFixture; |
28 | 52 | let element: Checkbox; |
29 | 53 | let internals: CheckboxInternals; |
30 | 54 |
|
31 | | - setup(() => { |
32 | | - element = document.createElement('mwc-checkbox'); |
33 | | - internals = element as unknown as CheckboxInternals; |
34 | | - document.body.appendChild(element); |
35 | | - }); |
36 | | - |
37 | 55 | teardown(() => { |
38 | | - document.body.removeChild(element); |
| 56 | + fixt.remove(); |
39 | 57 | }); |
40 | 58 |
|
41 | | - test('initializes as an mwc-checkbox', () => { |
42 | | - assert.instanceOf(element, Checkbox); |
| 59 | + suite('basic', () => { |
| 60 | + setup(async () => { |
| 61 | + fixt = await fixture(defaultCheckbox); |
| 62 | + element = fixt.root.querySelector('mwc-checkbox')!; |
| 63 | + internals = element as unknown as CheckboxInternals; |
| 64 | + }); |
| 65 | + |
| 66 | + test('initializes as an mwc-checkbox', () => { |
| 67 | + assert.instanceOf(element, Checkbox); |
| 68 | + assert.equal(element.checked, false); |
| 69 | + assert.equal(element.indeterminate, false); |
| 70 | + assert.equal(element.disabled, false); |
| 71 | + assert.equal(element.value, ''); |
| 72 | + }); |
| 73 | + |
| 74 | + test( |
| 75 | + 'element.formElement returns the native checkbox element', async () => { |
| 76 | + await element.updateComplete; |
| 77 | + assert.instanceOf(internals.formElement, HTMLElement); |
| 78 | + assert.equal(internals.formElement.localName, 'input'); |
| 79 | + }); |
| 80 | + |
| 81 | + test('user input emits `change` event', async () => { |
| 82 | + const callback = new Fake<[], void>(); |
| 83 | + element.addEventListener('change', callback.handler); |
| 84 | + element.click(); |
| 85 | + assert.equal(callback.callCount, 1); |
| 86 | + }); |
| 87 | + |
| 88 | + test('user input updates checked state', async () => { |
| 89 | + element.click(); |
| 90 | + await element.updateComplete; |
| 91 | + assert.equal(element.checked, true); |
| 92 | + }); |
| 93 | + |
| 94 | + test('does not animate after being hidden', async () => { |
| 95 | + element.checked = true; |
| 96 | + const animatedElement = |
| 97 | + element.shadowRoot!.querySelector('.mdc-checkbox__background')!; |
| 98 | + await new Promise((resolve) => { |
| 99 | + animatedElement.addEventListener('animationend', resolve); |
| 100 | + }); |
| 101 | + await element.updateComplete; |
| 102 | + element.style.display = 'hidden'; |
| 103 | + await rafPromise(); |
| 104 | + element.style.display = ''; |
| 105 | + await rafPromise(); |
| 106 | + assert.equal(internals.animationClass, ''); |
| 107 | + }); |
43 | 108 | }); |
44 | 109 |
|
45 | | - |
46 | | - test('element.formElement returns the native checkbox element', async () => { |
47 | | - await element.updateComplete; |
48 | | - assert.instanceOf(internals.formElement, HTMLElement); |
49 | | - assert.equal(internals.formElement.localName, 'input'); |
| 110 | + suite('checked', () => { |
| 111 | + setup(async () => { |
| 112 | + fixt = await fixture(checkbox({checked: true})); |
| 113 | + element = fixt.root.querySelector('mwc-checkbox')!; |
| 114 | + internals = element as unknown as CheckboxInternals; |
| 115 | + await element.updateComplete; |
| 116 | + }); |
| 117 | + |
| 118 | + test( |
| 119 | + 'get/set updates the checked property on the native checkbox element', |
| 120 | + async () => { |
| 121 | + assert.equal(internals.formElement.checked, true); |
| 122 | + element.checked = false; |
| 123 | + await element.updateComplete; |
| 124 | + assert.equal(internals.formElement.checked, false); |
| 125 | + }); |
50 | 126 | }); |
51 | 127 |
|
52 | | - test( |
53 | | - 'get/set checked updates the checked property on the native checkbox element', |
54 | | - async () => { |
55 | | - element.checked = true; |
56 | | - await element.updateComplete; |
57 | | - assert.equal(internals.formElement.checked, true); |
58 | | - element.checked = false; |
59 | | - await element.updateComplete; |
60 | | - assert.equal(internals.formElement.checked, false); |
61 | | - }); |
62 | | - |
63 | | - test( |
64 | | - 'get/set indeterminate updates the indeterminate property on the native checkbox element', |
65 | | - async () => { |
66 | | - element.indeterminate = true; |
67 | | - await element.updateComplete; |
68 | | - assert.equal(internals.formElement.indeterminate, true); |
69 | | - element.indeterminate = false; |
70 | | - await element.updateComplete; |
71 | | - assert.equal(internals.formElement.indeterminate, false); |
72 | | - }); |
73 | | - |
74 | | - test( |
75 | | - 'get/set disabled updates the disabled property on the native checkbox element', |
76 | | - async () => { |
77 | | - element.disabled = true; |
78 | | - await element.updateComplete; |
79 | | - assert.equal(internals.formElement.disabled, true); |
80 | | - element.disabled = false; |
81 | | - await element.updateComplete; |
82 | | - assert.equal(internals.formElement.disabled, false); |
83 | | - }); |
84 | | - |
85 | | - test( |
86 | | - 'get/set value updates the value of the native checkbox element', |
87 | | - async () => { |
88 | | - let value = 'new value'; |
89 | | - element.value = value; |
90 | | - await element.updateComplete; |
91 | | - assert.equal(internals.formElement.value, value); |
92 | | - value = 'new value 2'; |
93 | | - element.value = value; |
94 | | - await element.updateComplete; |
95 | | - assert.equal(internals.formElement.value, value); |
96 | | - }); |
97 | | - |
98 | | - test('user input emits `change` event', async () => { |
99 | | - const callback = new Fake<[], void>(); |
100 | | - document.body.addEventListener('change', callback.handler); |
101 | | - element.checked = false; |
102 | | - await element.updateComplete; |
103 | | - element.click(); |
104 | | - assert.equal(callback.callCount, 1); |
| 128 | + suite('indeterminate', () => { |
| 129 | + setup(async () => { |
| 130 | + fixt = await fixture(checkbox({indeterminate: true})); |
| 131 | + element = fixt.root.querySelector('mwc-checkbox')!; |
| 132 | + internals = element as unknown as CheckboxInternals; |
| 133 | + await element.updateComplete; |
| 134 | + }); |
| 135 | + |
| 136 | + test( |
| 137 | + 'get/set updates the indeterminate property on the native checkbox element', |
| 138 | + async () => { |
| 139 | + assert.equal(internals.formElement.indeterminate, true); |
| 140 | + assert.equal( |
| 141 | + internals.formElement.getAttribute('aria-checked'), 'mixed'); |
| 142 | + element.indeterminate = false; |
| 143 | + await element.updateComplete; |
| 144 | + assert.equal(internals.formElement.indeterminate, false); |
| 145 | + }); |
105 | 146 | }); |
106 | 147 |
|
107 | | - test('user input updates checked state', async () => { |
108 | | - element.checked = false; |
109 | | - await element.updateComplete; |
110 | | - element.click(); |
111 | | - await element.updateComplete; |
112 | | - assert.equal(element.checked, true); |
| 148 | + suite('disabled', () => { |
| 149 | + setup(async () => { |
| 150 | + fixt = await fixture(checkbox({disabled: true})); |
| 151 | + element = fixt.root.querySelector('mwc-checkbox')!; |
| 152 | + internals = element as unknown as CheckboxInternals; |
| 153 | + await element.updateComplete; |
| 154 | + }); |
| 155 | + |
| 156 | + test( |
| 157 | + 'get/set updates the disabled property on the native checkbox element', |
| 158 | + async () => { |
| 159 | + assert.equal(internals.formElement.disabled, true); |
| 160 | + element.disabled = false; |
| 161 | + await element.updateComplete; |
| 162 | + assert.equal(internals.formElement.disabled, false); |
| 163 | + }); |
113 | 164 | }); |
114 | 165 |
|
115 | | - test('does not animate after being hidden', async () => { |
116 | | - element.checked = true; |
117 | | - await element.updateComplete; |
118 | | - element.style.display = 'hidden'; |
119 | | - await rafPromise(); |
120 | | - element.style.display = ''; |
121 | | - await rafPromise(); |
122 | | - assert.equal(internals.animationClass, ''); |
| 166 | + suite('value', () => { |
| 167 | + setup(async () => { |
| 168 | + fixt = await fixture(checkbox({value: 'new value'})); |
| 169 | + element = fixt.root.querySelector('mwc-checkbox')!; |
| 170 | + internals = element as unknown as CheckboxInternals; |
| 171 | + await element.updateComplete; |
| 172 | + }); |
| 173 | + |
| 174 | + test( |
| 175 | + 'get/set updates the value of the native checkbox element', |
| 176 | + async () => { |
| 177 | + assert.equal(internals.formElement.value, 'new value'); |
| 178 | + element.value = 'new value 2'; |
| 179 | + await element.updateComplete; |
| 180 | + assert.equal(internals.formElement.value, 'new value 2'); |
| 181 | + }); |
123 | 182 | }); |
124 | 183 | }); |
0 commit comments