| 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 |