OLD | NEW |
1 | 1 |
2 let testNumber = 1; | 2 let testNumber = 1; |
3 | 3 |
| 4 function defineNewCustomElement(observedAttributes) { |
| 5 let log = []; |
| 6 let name = 'custom-element-' + testNumber++; |
| 7 |
| 8 class CustomElement extends HTMLElement { |
| 9 constructor() { |
| 10 super(); |
| 11 log.push({type: 'constructed', element: this}); |
| 12 } |
| 13 attributeChangedCallback(name, oldValue, newValue, namespace) { |
| 14 log.push({type: 'attributeChanged', element: this, name: name, oldVa
lue: oldValue, newValue: newValue, namespace: namespace}); |
| 15 } |
| 16 connectedCallback() { log.push({type: 'connected', element: this}); } |
| 17 disconnectedCallback() { log.push({type: 'disconnected', element: this})
; } |
| 18 adoptedCallback(oldDocument, newDocument) { log.push({type: 'adopted', e
lement: this, oldDocument: oldDocument, newDocument: newDocument}); } |
| 19 } |
| 20 CustomElement.observedAttributes = observedAttributes || ['id', 'title']; |
| 21 |
| 22 customElements.define(name, CustomElement); |
| 23 |
| 24 return { |
| 25 name: name, |
| 26 log: function () { |
| 27 let currentLog = log; log = []; |
| 28 return { |
| 29 types: () => currentLog.map((entry) => entry.type), |
| 30 log: (i) => currentLog[i == undefined ? currentLog.length - 1 :
i], |
| 31 } |
| 32 } |
| 33 }; |
| 34 } |
| 35 |
4 function testNodeConnector(testFunction, name) { | 36 function testNodeConnector(testFunction, name) { |
5 let container = document.createElement('div'); | 37 let container = document.createElement('div'); |
6 container.appendChild(document.createElement('div')); | 38 container.appendChild(document.createElement('div')); |
7 document.body.appendChild(container); | 39 document.body.appendChild(container); |
8 | 40 |
9 test(function () { | 41 test(function () { |
10 var element = define_new_custom_element(); | 42 var element = defineNewCustomElement(); |
11 var instance = document.createElement(element.name); | 43 var instance = document.createElement(element.name); |
12 assert_array_equals(element.takeLog().types(), ['constructed']); | 44 assert_array_equals(element.log().types(), ['constructed']); |
13 testFunction(container, instance); | 45 testFunction(container, instance); |
14 assert_array_equals(element.takeLog().types(), ['connected']); | 46 assert_array_equals(element.log().types(), ['connected']); |
15 }, name + ' must enqueue a connected reaction'); | 47 }, name + ' must enqueue a connected reaction'); |
16 | 48 |
17 test(function () { | 49 test(function () { |
18 var element = define_new_custom_element(); | 50 var element = defineNewCustomElement(); |
19 var instance = document.createElement(element.name); | 51 var instance = document.createElement(element.name); |
20 assert_array_equals(element.takeLog().types(), ['constructed']); | 52 assert_array_equals(element.log().types(), ['constructed']); |
21 var newDoc = document.implementation.createHTMLDocument(); | 53 var newDoc = document.implementation.createHTMLDocument(); |
22 testFunction(container, instance); | 54 testFunction(container, instance); |
23 assert_array_equals(element.takeLog().types(), ['connected']); | 55 assert_array_equals(element.log().types(), ['connected']); |
24 testFunction(newDoc.documentElement, instance); | 56 testFunction(newDoc.documentElement, instance); |
25 assert_array_equals(element.takeLog().types(), ['disconnected', 'adopted
', 'connected']); | 57 assert_array_equals(element.log().types(), ['disconnected', 'adopted', '
connected']); |
26 }, name + ' must enqueue a disconnected reaction, an adopted reaction, and a
connected reaction when the custom element was in another document'); | 58 }, name + ' must enqueue a disconnected reaction, an adopted reaction, and a
connected reaction when the custom element was in another document'); |
27 | 59 |
28 container.parentNode.removeChild(container); | 60 container.parentNode.removeChild(container); |
29 } | 61 } |
30 | 62 |
31 function testNodeDisconnector(testFunction, name) { | 63 function testNodeDisconnector(testFunction, name) { |
32 let container = document.createElement('div'); | 64 let container = document.createElement('div'); |
33 container.appendChild(document.createElement('div')); | 65 container.appendChild(document.createElement('div')); |
34 document.body.appendChild(container); | 66 document.body.appendChild(container); |
35 | 67 |
36 test(function () { | 68 test(function () { |
37 var element = define_new_custom_element(); | 69 var element = defineNewCustomElement(); |
38 var instance = document.createElement(element.name); | 70 var instance = document.createElement(element.name); |
39 assert_array_equals(element.takeLog().types(), ['constructed']); | 71 assert_array_equals(element.log().types(), ['constructed']); |
40 container.appendChild(instance); | 72 container.appendChild(instance); |
41 assert_array_equals(element.takeLog().types(), ['connected']); | 73 assert_array_equals(element.log().types(), ['connected']); |
42 testFunction(instance); | 74 testFunction(instance); |
43 assert_array_equals(element.takeLog().types(), ['disconnected']); | 75 assert_array_equals(element.log().types(), ['disconnected']); |
44 }, name + ' must enqueue a disconnected reaction'); | 76 }, name + ' must enqueue a disconnected reaction'); |
45 | 77 |
46 container.parentNode.removeChild(container); | 78 container.parentNode.removeChild(container); |
47 } | 79 } |
48 | 80 |
49 function testCloner(testFunction, name) { | 81 function testReflectAttribute(jsAttributeName, contentAttributeName, validValue1
, validValue2, name) { |
50 let container = document.createElement('div'); | 82 test(function () { |
51 container.appendChild(document.createElement('div')); | 83 var element = defineNewCustomElement([contentAttributeName]); |
52 document.body.appendChild(container); | 84 var instance = document.createElement(element.name); |
| 85 assert_array_equals(element.log().types(), ['constructed']); |
| 86 instance[jsAttributeName] = validValue1; |
| 87 var logEntries = element.log(); |
| 88 assert_array_equals(logEntries.types(), ['attributeChanged']); |
| 89 assert_equals(logEntries.log().name, contentAttributeName); |
| 90 assert_equals(logEntries.log().oldValue, null); |
| 91 assert_equals(logEntries.log().newValue, validValue1); |
| 92 assert_equals(logEntries.log().namespace, null); |
| 93 }, name + ' must enqueue a attributeChanged reaction when adding ' + content
AttributeName + ' content attribute'); |
53 | 94 |
54 test(function () { | 95 test(function () { |
55 var element = define_new_custom_element(['id']); | 96 var element = defineNewCustomElement([contentAttributeName]); |
56 var instance = document.createElement(element.name); | |
57 container.appendChild(instance); | |
58 | |
59 instance.setAttribute('id', 'foo'); | |
60 assert_array_equals(element.takeLog().types(), ['constructed', 'connecte
d', 'attributeChanged']); | |
61 var newInstance = testFunction(instance); | |
62 var logEntries = element.takeLog(); | |
63 assert_array_equals(logEntries.types(), ['constructed', 'attributeChange
d']); | |
64 assert_attribute_log_entry(logEntries.last(), {name: 'id', oldValue: nul
l, newValue: 'foo', namespace: null}); | |
65 }, name + ' must enqueue an attributeChanged reaction when cloning an elemen
t with an observed attribute'); | |
66 | |
67 test(function () { | |
68 var element = define_new_custom_element(['id']); | |
69 var instance = document.createElement(element.name); | |
70 container.appendChild(instance); | |
71 | |
72 instance.setAttribute('lang', 'en'); | |
73 assert_array_equals(element.takeLog().types(), ['constructed', 'connecte
d']); | |
74 var newInstance = testFunction(instance); | |
75 assert_array_equals(element.takeLog().types(), ['constructed']); | |
76 }, name + ' must not enqueue an attributeChanged reaction when cloning an el
ement with an unobserved attribute'); | |
77 | |
78 test(function () { | |
79 var element = define_new_custom_element(['title', 'class']); | |
80 var instance = document.createElement(element.name); | |
81 container.appendChild(instance); | |
82 | |
83 instance.setAttribute('lang', 'en'); | |
84 instance.className = 'foo'; | |
85 instance.setAttribute('title', 'hello world'); | |
86 assert_array_equals(element.takeLog().types(), ['constructed', 'connecte
d', 'attributeChanged', 'attributeChanged']); | |
87 var newInstance = testFunction(instance); | |
88 var logEntries = element.takeLog(); | |
89 assert_array_equals(logEntries.types(), ['constructed', 'attributeChange
d', 'attributeChanged']); | |
90 assert_attribute_log_entry(logEntries[1], {name: 'class', oldValue: null
, newValue: 'foo', namespace: null}); | |
91 assert_attribute_log_entry(logEntries[2], {name: 'title', oldValue: null
, newValue: 'hello world', namespace: null}); | |
92 }, name + ' must enqueue an attributeChanged reaction when cloning an elemen
t only for observed attributes'); | |
93 } | |
94 | |
95 function testReflectAttribute(jsAttributeName, contentAttributeName, validValue1
, validValue2, name) { | |
96 test(function () { | |
97 var element = define_new_custom_element([contentAttributeName]); | |
98 var instance = document.createElement(element.name); | |
99 assert_array_equals(element.takeLog().types(), ['constructed']); | |
100 instance[jsAttributeName] = validValue1; | |
101 var logEntries = element.takeLog(); | |
102 assert_array_equals(logEntries.types(), ['attributeChanged']); | |
103 assert_attribute_log_entry(logEntries.last(), {name: contentAttributeNam
e, oldValue: null, newValue: validValue1, namespace: null}); | |
104 }, name + ' must enqueue an attributeChanged reaction when adding ' + conten
tAttributeName + ' content attribute'); | |
105 | |
106 test(function () { | |
107 var element = define_new_custom_element([contentAttributeName]); | |
108 var instance = document.createElement(element.name); | 97 var instance = document.createElement(element.name); |
109 instance[jsAttributeName] = validValue1; | 98 instance[jsAttributeName] = validValue1; |
110 assert_array_equals(element.takeLog().types(), ['constructed', 'attribut
eChanged']); | 99 assert_array_equals(element.log().types(), ['constructed', 'attributeCha
nged']); |
111 instance[jsAttributeName] = validValue2; | 100 instance[jsAttributeName] = validValue2; |
112 var logEntries = element.takeLog(); | 101 var logEntries = element.log(); |
113 assert_array_equals(logEntries.types(), ['attributeChanged']); | 102 assert_array_equals(logEntries.types(), ['attributeChanged']); |
114 assert_attribute_log_entry(logEntries.last(), {name: contentAttributeNam
e, oldValue: validValue1, newValue: validValue2, namespace: null}); | 103 assert_equals(logEntries.log().name, contentAttributeName); |
115 }, name + ' must enqueue an attributeChanged reaction when replacing an exis
ting attribute'); | 104 assert_equals(logEntries.log().oldValue, validValue1); |
| 105 assert_equals(logEntries.log().newValue, validValue2); |
| 106 assert_equals(logEntries.log().namespace, null); |
| 107 }, name + ' must enqueue a attributeChanged reaction when replacing an exist
ing attribute'); |
116 } | 108 } |
117 | 109 |
118 function testAttributeAdder(testFunction, name) { | 110 function testAttributeAdder(testFunction, name) { |
119 test(function () { | 111 test(function () { |
120 var element = define_new_custom_element(['id']); | 112 var element = defineNewCustomElement(); |
121 var instance = document.createElement(element.name); | 113 var instance = document.createElement(element.name); |
122 assert_array_equals(element.takeLog().types(), ['constructed']); | 114 assert_array_equals(element.log().types(), ['constructed']); |
123 testFunction(instance, 'id', 'foo'); | 115 testFunction(instance, 'id', 'foo'); |
124 var logEntries = element.takeLog(); | 116 var logEntries = element.log(); |
125 assert_array_equals(logEntries.types(), ['attributeChanged']); | 117 assert_array_equals(logEntries.types(), ['attributeChanged']); |
126 assert_attribute_log_entry(logEntries.last(), {name: 'id', oldValue: nul
l, newValue: 'foo', namespace: null}); | 118 assert_equals(logEntries.log().name, 'id'); |
127 }, name + ' must enqueue an attributeChanged reaction when adding an attribu
te'); | 119 assert_equals(logEntries.log().oldValue, null); |
| 120 assert_equals(logEntries.log().newValue, 'foo'); |
| 121 assert_equals(logEntries.log().namespace, null); |
| 122 }, name + ' must enqueue a attributeChanged reaction when adding an attribut
e'); |
128 | 123 |
129 test(function () { | 124 test(function () { |
130 var element = define_new_custom_element(['class']); | 125 var element = defineNewCustomElement(); |
131 var instance = document.createElement(element.name); | 126 var instance = document.createElement(element.name); |
132 assert_array_equals(element.takeLog().types(), ['constructed']); | 127 assert_array_equals(element.log().types(), ['constructed']); |
133 testFunction(instance, 'data-lang', 'en'); | 128 testFunction(instance, 'data-lang', 'en'); |
134 assert_array_equals(element.takeLog().types(), []); | 129 assert_array_equals(element.log().types(), []); |
135 }, name + ' must not enqueue an attributeChanged reaction when adding an uno
bserved attribute'); | 130 }, name + ' must not enqueue a attributeChanged reaction when adding an unob
served attribute'); |
136 | 131 |
137 test(function () { | 132 test(function () { |
138 var element = define_new_custom_element(['title']); | 133 var element = defineNewCustomElement(); |
139 var instance = document.createElement(element.name); | 134 var instance = document.createElement(element.name); |
140 instance.setAttribute('title', 'hello'); | 135 instance.setAttribute('title', 'hello'); |
141 assert_array_equals(element.takeLog().types(), ['constructed', 'attribut
eChanged']); | 136 assert_array_equals(element.log().types(), ['constructed', 'attributeCha
nged']); |
142 testFunction(instance, 'title', 'world'); | 137 testFunction(instance, 'title', 'world'); |
143 var logEntries = element.takeLog(); | 138 var logEntries = element.log(); |
144 assert_array_equals(logEntries.types(), ['attributeChanged']); | 139 assert_array_equals(logEntries.types(), ['attributeChanged']); |
145 assert_attribute_log_entry(logEntries.last(), {name: 'title', oldValue:
'hello', newValue: 'world', namespace: null}); | 140 assert_equals(logEntries.log().name, 'title'); |
146 }, name + ' must enqueue an attributeChanged reaction when replacing an exis
ting attribute'); | 141 assert_equals(logEntries.log().oldValue, 'hello'); |
| 142 assert_equals(logEntries.log().newValue, 'world'); |
| 143 assert_equals(logEntries.log().namespace, null); |
| 144 }, name + ' must enqueue a attributeChanged reaction when replacing an exist
ing attribute'); |
147 | 145 |
148 test(function () { | 146 test(function () { |
149 var element = define_new_custom_element([]); | 147 var element = defineNewCustomElement(); |
150 var instance = document.createElement(element.name); | 148 var instance = document.createElement(element.name); |
151 instance.setAttribute('data-lang', 'zh'); | 149 instance.setAttribute('data-lang', 'zh'); |
152 assert_array_equals(element.takeLog().types(), ['constructed']); | 150 assert_array_equals(element.log().types(), ['constructed']); |
153 testFunction(instance, 'data-lang', 'en'); | 151 testFunction(instance, 'data-lang', 'en'); |
154 assert_array_equals(element.takeLog().types(), []); | 152 assert_array_equals(element.log().types(), []); |
155 }, name + ' must enqueue an attributeChanged reaction when replacing an exis
ting unobserved attribute'); | 153 }, name + ' must enqueue a attributeChanged reaction when replacing an exist
ing unobserved attribute'); |
156 } | 154 } |
157 | 155 |
158 function testAttributeMutator(testFunction, name) { | 156 function testAttributeMutator(testFunction, name) { |
159 test(function () { | 157 test(function () { |
160 var element = define_new_custom_element(['title']); | 158 var element = defineNewCustomElement(); |
161 var instance = document.createElement(element.name); | 159 var instance = document.createElement(element.name); |
162 instance.setAttribute('title', 'hello'); | 160 instance.setAttribute('title', 'hello'); |
163 assert_array_equals(element.takeLog().types(), ['constructed', 'attribut
eChanged']); | 161 assert_array_equals(element.log().types(), ['constructed', 'attributeCha
nged']); |
164 testFunction(instance, 'title', 'world'); | 162 testFunction(instance, 'title', 'world'); |
165 var logEntries = element.takeLog(); | 163 var logEntries = element.log(); |
166 assert_array_equals(logEntries.types(), ['attributeChanged']); | 164 assert_array_equals(logEntries.types(), ['attributeChanged']); |
167 assert_attribute_log_entry(logEntries.last(), {name: 'title', oldValue:
'hello', newValue: 'world', namespace: null}); | 165 assert_equals(logEntries.log().name, 'title'); |
168 }, name + ' must enqueue an attributeChanged reaction when replacing an exis
ting attribute'); | 166 assert_equals(logEntries.log().oldValue, 'hello'); |
| 167 assert_equals(logEntries.log().newValue, 'world'); |
| 168 assert_equals(logEntries.log().namespace, null); |
| 169 }, name + ' must enqueue a attributeChanged reaction when replacing an exist
ing attribute'); |
169 | 170 |
170 test(function () { | 171 test(function () { |
171 var element = define_new_custom_element(['class']); | 172 var element = defineNewCustomElement(); |
172 var instance = document.createElement(element.name); | 173 var instance = document.createElement(element.name); |
173 instance.setAttribute('data-lang', 'zh'); | 174 instance.setAttribute('data-lang', 'zh'); |
174 assert_array_equals(element.takeLog().types(), ['constructed']); | 175 assert_array_equals(element.log().types(), ['constructed']); |
175 testFunction(instance, 'data-lang', 'en'); | 176 testFunction(instance, 'data-lang', 'en'); |
176 assert_array_equals(element.takeLog().types(), []); | 177 assert_array_equals(element.log().types(), []); |
177 }, name + ' must not enqueue an attributeChanged reaction when replacing an
existing unobserved attribute'); | 178 }, name + ' must enqueue a attributeChanged reaction when replacing an exist
ing unobserved attribute'); |
178 } | 179 } |
179 | 180 |
180 function testAttributeRemover(testFunction, name) { | 181 function testAttributeRemover(testFunction, name) { |
181 test(function () { | 182 test(function () { |
182 var element = define_new_custom_element(['title']); | 183 var element = defineNewCustomElement(); |
183 var instance = document.createElement(element.name); | 184 var instance = document.createElement(element.name); |
184 assert_array_equals(element.takeLog().types(), ['constructed']); | 185 assert_array_equals(element.log().types(), ['constructed']); |
185 testFunction(instance, 'title'); | 186 testFunction(instance, 'title'); |
186 assert_array_equals(element.takeLog().types(), []); | 187 assert_array_equals(element.log().types(), []); |
187 }, name + ' must not enqueue an attributeChanged reaction when removing an a
ttribute that does not exist'); | 188 }, name + ' must not enqueue a attributeChanged reaction when removing an at
tribute that does not exist'); |
188 | 189 |
189 test(function () { | 190 test(function () { |
190 var element = define_new_custom_element([]); | 191 var element = defineNewCustomElement(); |
191 var instance = document.createElement(element.name); | 192 var instance = document.createElement(element.name); |
192 instance.setAttribute('data-lang', 'hello'); | 193 instance.setAttribute('data-lang', 'hello'); |
193 assert_array_equals(element.takeLog().types(), ['constructed']); | 194 assert_array_equals(element.log().types(), ['constructed']); |
194 testFunction(instance, 'data-lang'); | 195 testFunction(instance, 'data-lang'); |
195 assert_array_equals(element.takeLog().types(), []); | 196 assert_array_equals(element.log().types(), []); |
196 }, name + ' must not enqueue an attributeChanged reaction when removing an u
nobserved attribute'); | 197 }, name + ' must not enqueue a attributeChanged reaction when removing an un
observed attribute that does not exist'); |
197 | 198 |
198 test(function () { | 199 test(function () { |
199 var element = define_new_custom_element(['title']); | 200 var element = defineNewCustomElement(); |
200 var instance = document.createElement(element.name); | 201 var instance = document.createElement(element.name); |
201 instance.setAttribute('title', 'hello'); | 202 instance.setAttribute('title', 'hello'); |
202 assert_array_equals(element.takeLog().types(), ['constructed', 'attribut
eChanged']); | 203 assert_array_equals(element.log().types(), ['constructed', 'attributeCha
nged']); |
203 testFunction(instance, 'title'); | 204 testFunction(instance, 'title'); |
204 var logEntries = element.takeLog(); | 205 var logEntries = element.log(); |
205 assert_array_equals(logEntries.types(), ['attributeChanged']); | 206 assert_array_equals(logEntries.types(), ['attributeChanged']); |
206 assert_attribute_log_entry(logEntries.last(), {name: 'title', oldValue:
'hello', newValue: null, namespace: null}); | 207 assert_equals(logEntries.log().name, 'title'); |
207 }, name + ' must enqueue an attributeChanged reaction when removing an exist
ing attribute'); | 208 assert_equals(logEntries.log().oldValue, 'hello'); |
| 209 assert_equals(logEntries.log().newValue, null); |
| 210 assert_equals(logEntries.log().namespace, null); |
| 211 }, name + ' must enqueue a attributeChanged reaction when removing an existi
ng attribute'); |
208 | 212 |
209 test(function () { | 213 test(function () { |
210 var element = define_new_custom_element([]); | 214 var element = defineNewCustomElement(); |
211 var instance = document.createElement(element.name); | 215 var instance = document.createElement(element.name); |
212 instance.setAttribute('data-lang', 'ja'); | 216 instance.setAttribute('data-lang', 'ja'); |
213 assert_array_equals(element.takeLog().types(), ['constructed']); | 217 assert_array_equals(element.log().types(), ['constructed']); |
214 testFunction(instance, 'data-lang'); | 218 testFunction(instance, 'data-lang'); |
215 assert_array_equals(element.takeLog().types(), []); | 219 assert_array_equals(element.log().types(), []); |
216 }, name + ' must not enqueue an attributeChanged reaction when removing an e
xisting unobserved attribute'); | 220 }, name + ' must not enqueue a attributeChanged reaction when removing an ex
isting unobserved attribute'); |
217 } | 221 } |
OLD | NEW |