Chromium Code Reviews| Index: third_party/WebKit/LayoutTests/custom-elements/spec/upgrade-element.html |
| diff --git a/third_party/WebKit/LayoutTests/custom-elements/spec/upgrade-element.html b/third_party/WebKit/LayoutTests/custom-elements/spec/upgrade-element.html |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..383ff6ce2a2eecbec1cecad08d524c8573597cad |
| --- /dev/null |
| +++ b/third_party/WebKit/LayoutTests/custom-elements/spec/upgrade-element.html |
| @@ -0,0 +1,103 @@ |
| +<!DOCTYPE html> |
| +<title>Custom Elements: upgrade element</title> |
| +<link rel="help" href="https://html.spec.whatwg.org/multipage/scripting.html#concept-upgrade-an-element"> |
| +<script src="../../resources/testharness.js"></script> |
| +<script src="../../resources/testharnessreport.js"></script> |
| +<script src="resources/custom-elements-helpers.js"></script> |
| +<body> |
| +<script> |
| + |
| +'use strict' |
| +// 6. "attributeChangedCallback" and "connectedCallback" should execute after C and |
| +// the rest of the upgrade process finishes. |
| +test_with_window((w) => { |
| + let invocations = []; |
| + let changedCallbackArgs; |
| + let a = w.document.createElement('a-a'); |
| + w.document.body.appendChild(a); |
| + a.setAttribute('x', '1'); |
| + class X extends w.HTMLElement { |
| + constructor() { |
| + super(); |
| + invocations.push(['constructor', this]); |
| + } |
| + connectedCallback() { invocations.push(['connected', this]); } |
| + static get observedAttributes() { return ['x']; } |
| + attributeChangedCallback() { |
| + invocations.push(['attributeChanged', this]); |
| + changedCallbackArgs = arguments; |
| + } |
| + } |
| + w.customElements.define('a-a', X); |
| + assert_array_equals(invocations[0], ['constructor', a], 'constructor should execute first'); |
| + assert_array_equals(invocations[1], ['attributeChanged', a], 'attributeChangedCallback should execute after the constructor'); |
| + assert_array_equals(changedCallbackArgs, ['x', null, '1', '']); |
| + assert_array_equals(invocations[2], ['connected', a], 'connectedCallback should execute after the constructor'); |
|
dominicc (has gone to gerrit)
2016/07/13 07:06:17
This is great. Maybe add something that checks the
|
| +}, '"connectedCallback", "attributeChangedCallback" reactions should execute after the constructor'); |
| + |
| +// 6. If C non-conformantly uses an API decorated with the [CEReactions] extended attribute, |
| +// then the reactions enqueued at the beginning of upgrade will execute during this step, |
| +// before C finishes and control returns to this algorithm. |
| +test_with_window((w) => { |
| + let invocations = []; |
| + let changedCallbackArgs; |
| + let a = w.document.createElement('a-a'); |
| + w.document.body.appendChild(a); |
| + class X extends w.HTMLElement { |
| + constructor() { |
| + super(); |
| + this.setAttribute('x', '1'); |
| + invocations.push(['constructor', this]); |
| + } |
| + connectedCallback() { invocations.push(['connected', this]); } |
| + static get observedAttributes() { return ['x']; } |
| + attributeChangedCallback() { |
| + invocations.push(['attributeChanged', this]); |
| + changedCallbackArgs = arguments; |
| + } |
| + } |
| + w.customElements.define('a-a', X); |
| + assert_array_equals(invocations[0], ['connected', a], 'connectedCallback executes before the constructor'); |
| + assert_array_equals(invocations[1], ['attributeChanged', a], 'attributeChangedCallback executes before the constructor'); |
| + assert_array_equals(changedCallbackArgs, ['x', null, '1', '']); |
| + assert_array_equals(invocations[2], ['constructor', a], 'constructor executes last'); |
| +}, 'The constructor non-conformatly uses API decorated with the [CEReactions]'); |
| + |
| +// 8. If constructResult is an abrupt completion, then return constructResult |
| +// (i.e., rethrow the exception). |
| +test_with_window((w) => { |
| + let error_log = []; |
| + let a = w.document.createElement('a-a'); |
|
dominicc (has gone to gerrit)
2016/07/13 07:06:17
If you don't need a, maybe simplify this and the a
|
| + w.document.body.appendChild(a); |
| + w.onerror = function (msg, url, lineNo, columnNo, error) { |
| + error_log.push(error); |
| + return true; |
| + }; |
| + class X extends w.HTMLElement { |
| + constructor() { throw 'constructor throws'; } |
| + } |
| + w.customElements.define('a-a', X); |
| + assert_array_equals(error_log, ['constructor throws'], 'rethrow any exception thrown from constructor'); |
| +}, 'Upgrading an element with a throwing constructor should rethrow that exception'); |
| + |
| +// TODO(davaajav): add a failure expectation to this file |
| +// 9. If SameValue(constructResult.[[value]], element) is false, then throw an |
| +// "InvalidStateError" DOMException and terminate these steps. |
| +test_with_window((w) => { |
| + let a = w.document.createElement('a-a'); |
| + w.document.body.appendChild(a); |
| + class X extends w.HTMLElement { |
| + constructor() { |
| + super(); |
| + return ['aaaa']; |
| + } |
| + } |
| + assert_throws('InvalidStateError', () => { |
| + w.customElements.define('a-a', X); |
| + }, 'Using JavaScript return-override should throw "InvalidStateError"DOMException'); |
|
dominicc (has gone to gerrit)
2016/07/13 07:06:17
space after "
|
| +}, 'Upgrading an element with invalid constructor'); |
| + |
| +// 10. Set element's custom element state to "custom". |
|
dominicc (has gone to gerrit)
2016/07/13 07:06:17
Could you file that bug and delete this FIXME? Sen
|
| +// TODO(davaajav): file spec bug. Step 10 is redundant. |
| +</script> |
| +</body> |