<!DOCTYPE html>
<title>Custom Elements: report the exception</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="resources/custom-elements-helpers.js"></script>
<body>
<!--
The spec has two places where it says to [report the exception]:

1. In [create an element for a token], step 6.1
   This can occur when [create an element] is invoked from
   [create an element for a token] with the synchronous custom elements flag
   set, or from createElement.
2. In [invoke custom element reactions], step 2.1.

There are different code paths when:
1. Author script throws an exception that is rethrown.
2. The user agent throws an exception.

This test contains tests for the combination of the above 2x2.

[create an element]: https://dom.spec.whatwg.org/#concept-create-element
[create an element for a token]: https://html.spec.whatwg.org/multipage/syntax.html#create-an-element-for-the-token
[invoke custom element reactions]: https://html.spec.whatwg.org/multipage/scripting.html#invoke-custom-element-reactions
[report the exception]: https://html.spec.whatwg.org/multipage/webappapis.html#report-the-exception
-->
<template id="constructor-throws">
  <script>
'use strict';
window.errors = [];
// https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-attributes:handler-onerror
window.onerror = function (event, source, lineno, colno, error) {
  errors.push({
    event: event,
    source: source,
    lineno: lineno,
    colno: colno,
    error: error
  });
  return true; // Cancel the error event.
};

const rethrowErrorName = 'rethrown';
const rethrowErrorMessage = 'check this is rethrown';

customElements.define('a-a', class extends HTMLElement {
  constructor() {
    const error = new Error(rethrowErrorMessage);
    error.name = rethrowErrorName;
    throw error;
  }
});
  </script>
</template>
<template id="instantiate">
  <a-a></a-a>
</template>
<template id="createElement">
  <script>
    window.e = document.createElement('a-a');
  </script>
</template>
<script>
'use strict';
const rethrowErrorName = 'rethrown';
const rethrowErrorMessage = 'check this is rethrown';

function assert_not_muted_error_event(error) {
  assert_not_equals(error, undefined, 'should fire error event');
  // Report an error, 6. If script has muted errors, ...
  // https://html.spec.whatwg.org/multipage/webappapis.html#report-the-error
  assert_false(error.event === 'Script error.'
      && error.source === '' && error.lineno === 0 && error.colno === 0
      && error.error === null,
      'the error should not be muted.');
  assert_false(!error.event, 'event (1st arg) should not be null');
  assert_false(!error.source, 'source (2nd arg) should not be null');
  // The spec doesn't define valid values for lineno/colno.
  assert_false(!error.error, 'error (5th arg) should not be null');
}

function assert_reported_error_event(error) {
  assert_not_muted_error_event(error);
  assert_equals(error.error.name, rethrowErrorName);
  assert_equals(error.error.message, rethrowErrorMessage);
}

const constructor_throws =
    document.getElementById('constructor-throws').innerHTML;
const instantiate = document.getElementById('instantiate').innerHTML;
const create_element = document.getElementById('createElement').innerHTML;

test_with_window((w) => {
  assert_reported_error_event(w.errors[0]);
}, 'Document parser invokes the constructor that throws',
  constructor_throws + instantiate);

test_with_window((w) => {
  w.document.body.innerHTML = instantiate;
  assert_reported_error_event(w.errors[0]);
}, 'Upgrade reaction invokes the constructor that throws',
  constructor_throws);

test_with_window((w) => {
  assert_reported_error_event(w.errors[0]);
  assert_true(
      w.e instanceof w.HTMLUnknownElement,
      'the created element should be HTMLUnknownElement');
}, 'createElement invokes the constructor that throws',
  constructor_throws + create_element);
</script>

<!--
Test when JavaScript returns without throwing errors, but the result is invalid
and thus UA should [report the exception].
-->
<template id="constructor-returns-bad-object">
  <script>
'use strict';
window.errors = [];
// https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-attributes:handler-onerror
window.onerror = function (event, source, lineno, colno, error) {
  errors.push({
    event: event,
    source: source,
    lineno: lineno,
    colno: colno,
    error: error
  });
  return true; // Cancel the error event.
};

customElements.define('a-a', class extends HTMLElement {
  constructor() {
    super();
    return []; // returning objects other than "this" is invalid.
  }
});
  </script>
</template>
<script>
const constructor_returns_bad_object =
  document.getElementById('constructor-returns-bad-object').innerHTML;

function assert_type_error_event(error) {
  assert_not_muted_error_event(error);
  assert_equals(error.error.name, 'TypeError');
}

test_with_window((w) => {
  // "create an element" 6.1.3, throw a TypeError.
  // https://dom.spec.whatwg.org/#concept-create-element
  assert_type_error_event(w.errors[0]);
}, 'Document parser invokes the constructor that returns a bad object',
  constructor_returns_bad_object + instantiate);

test_with_window((w) => {
  // "upgrade an element" 10, throw a TypeError.
  // https://html.spec.whatwg.org/multipage/scripting.html#upgrades
  w.document.body.innerHTML = instantiate;
  assert_type_error_event(w.errors[0]);
}, 'Upgrade reaction invokes the constructor that returns a bad object',
  constructor_returns_bad_object);
</script>
</body>
