11cb0ef41Sopenharmony_ci<!DOCTYPE html>
21cb0ef41Sopenharmony_ci<meta charset="utf-8">
31cb0ef41Sopenharmony_ci<script src="/resources/testharness.js"></script>
41cb0ef41Sopenharmony_ci<script src="/resources/testharnessreport.js"></script>
51cb0ef41Sopenharmony_ci<script src="resources/helpers.js"></script>
61cb0ef41Sopenharmony_ci<script>
71cb0ef41Sopenharmony_ci'use strict';
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci// Chrome used to special-case the reason for cancel() and abort() in order to
101cb0ef41Sopenharmony_ci// handle exceptions correctly. This is no longer necessary. These tests are
111cb0ef41Sopenharmony_ci// retained to avoid regressions.
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ciasync function getTransferredReason(originalReason) {
141cb0ef41Sopenharmony_ci  let resolvePromise;
151cb0ef41Sopenharmony_ci  const rv = new Promise(resolve => {
161cb0ef41Sopenharmony_ci    resolvePromise = resolve;
171cb0ef41Sopenharmony_ci  });
181cb0ef41Sopenharmony_ci  const rs = await createTransferredReadableStream({
191cb0ef41Sopenharmony_ci    cancel(reason) {
201cb0ef41Sopenharmony_ci      resolvePromise(reason);
211cb0ef41Sopenharmony_ci    }
221cb0ef41Sopenharmony_ci  });
231cb0ef41Sopenharmony_ci  await rs.cancel(originalReason);
241cb0ef41Sopenharmony_ci  return rv;
251cb0ef41Sopenharmony_ci}
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_cifor (const value of ['hi', '\t\r\n', 7, 3.0, undefined, null, true, false,
281cb0ef41Sopenharmony_ci                    NaN, Infinity]) {
291cb0ef41Sopenharmony_ci  promise_test(async () => {
301cb0ef41Sopenharmony_ci    const reason = await getTransferredReason(value);
311cb0ef41Sopenharmony_ci    assert_equals(reason, value, 'reason should match');
321cb0ef41Sopenharmony_ci  }, `reason with a simple value of '${value}' should be preserved`);
331cb0ef41Sopenharmony_ci}
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_cifor (const badType of [Symbol('hi'), _ => 'hi']) {
361cb0ef41Sopenharmony_ci  promise_test(async t => {
371cb0ef41Sopenharmony_ci    return promise_rejects_dom(t, 'DataCloneError',
381cb0ef41Sopenharmony_ci                               getTransferredReason(badType),
391cb0ef41Sopenharmony_ci                               'cancel() should reject');
401cb0ef41Sopenharmony_ci  }, `reason with a type of '${typeof badType}' should be rejected and ` +
411cb0ef41Sopenharmony_ci     `error the stream`);
421cb0ef41Sopenharmony_ci}
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_cipromise_test(async () => {
451cb0ef41Sopenharmony_ci  const reasonAsJson =
461cb0ef41Sopenharmony_ci        `{"foo":[1,"col"],"bar":{"hoge":0.2,"baz":{},"shan":null}}`;
471cb0ef41Sopenharmony_ci  const reason = await getTransferredReason(JSON.parse(reasonAsJson));
481cb0ef41Sopenharmony_ci  assert_equals(JSON.stringify(reason), reasonAsJson,
491cb0ef41Sopenharmony_ci                'object should be preserved');
501cb0ef41Sopenharmony_ci}, 'objects that can be completely expressed in JSON should be preserved');
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_cipromise_test(async () => {
531cb0ef41Sopenharmony_ci  const circularObject = {};
541cb0ef41Sopenharmony_ci  circularObject.self = circularObject;
551cb0ef41Sopenharmony_ci  const reason = await getTransferredReason(circularObject);
561cb0ef41Sopenharmony_ci  assert_true(reason instanceof Object, 'an Object should be output');
571cb0ef41Sopenharmony_ci  assert_equals(reason.self, reason,
581cb0ef41Sopenharmony_ci                'the object should have a circular reference');
591cb0ef41Sopenharmony_ci}, 'objects that cannot be expressed in JSON should also be preserved');
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_cipromise_test(async () => {
621cb0ef41Sopenharmony_ci  const originalReason = new TypeError('hi');
631cb0ef41Sopenharmony_ci  const reason = await getTransferredReason(originalReason);
641cb0ef41Sopenharmony_ci  assert_true(reason instanceof TypeError,
651cb0ef41Sopenharmony_ci              'type should be preserved');
661cb0ef41Sopenharmony_ci  assert_equals(reason.message, originalReason.message,
671cb0ef41Sopenharmony_ci                'message should be preserved');
681cb0ef41Sopenharmony_ci}, 'the type and message of a TypeError should be preserved');
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_cipromise_test(async () => {
711cb0ef41Sopenharmony_ci  const originalReason = new TypeError('hi');
721cb0ef41Sopenharmony_ci  originalReason.foo = 'bar';
731cb0ef41Sopenharmony_ci  const reason = await getTransferredReason(originalReason);
741cb0ef41Sopenharmony_ci  assert_false('foo' in reason,
751cb0ef41Sopenharmony_ci               'foo should not be preserved');
761cb0ef41Sopenharmony_ci}, 'other attributes of a TypeError should not be preserved');
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_cipromise_test(async () => {
791cb0ef41Sopenharmony_ci  const originalReason = new TypeError();
801cb0ef41Sopenharmony_ci  originalReason.message = [1, 2, 3];
811cb0ef41Sopenharmony_ci  const reason = await getTransferredReason(originalReason);
821cb0ef41Sopenharmony_ci  assert_equals(reason.message, '1,2,3', 'message should be stringified');
831cb0ef41Sopenharmony_ci}, 'a TypeError message should be converted to a string');
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_cipromise_test(async () => {
861cb0ef41Sopenharmony_ci  const originalReason = new TypeError();
871cb0ef41Sopenharmony_ci  Object.defineProperty(originalReason, 'message', {
881cb0ef41Sopenharmony_ci    get() { return 'words'; }
891cb0ef41Sopenharmony_ci  });
901cb0ef41Sopenharmony_ci  const reason = await getTransferredReason(originalReason);
911cb0ef41Sopenharmony_ci  assert_equals(reason.message, '', 'message should not be preserved');
921cb0ef41Sopenharmony_ci}, 'a TypeError message should not be preserved if it is a getter');
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_cipromise_test(async () => {
951cb0ef41Sopenharmony_ci  const originalReason = new TypeError();
961cb0ef41Sopenharmony_ci  delete originalReason.message;
971cb0ef41Sopenharmony_ci  TypeError.prototype.message = 'inherited message';
981cb0ef41Sopenharmony_ci  const reason = await getTransferredReason(originalReason);
991cb0ef41Sopenharmony_ci  delete TypeError.prototype.message;
1001cb0ef41Sopenharmony_ci  assert_equals(reason.message, '', 'message should not be preserved');
1011cb0ef41Sopenharmony_ci}, 'a TypeError message should not be preserved if it is inherited');
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_cipromise_test(async () => {
1041cb0ef41Sopenharmony_ci  const originalReason = new DOMException('yes', 'AbortError');
1051cb0ef41Sopenharmony_ci  const reason = await getTransferredReason(originalReason);
1061cb0ef41Sopenharmony_ci  assert_true(reason instanceof DOMException,
1071cb0ef41Sopenharmony_ci              'reason should be a DOMException');
1081cb0ef41Sopenharmony_ci  assert_equals(reason.message, originalReason.message,
1091cb0ef41Sopenharmony_ci                'the messages should match');
1101cb0ef41Sopenharmony_ci  assert_equals(reason.name, originalReason.name,
1111cb0ef41Sopenharmony_ci                'the names should match');
1121cb0ef41Sopenharmony_ci}, 'DOMException errors should be preserved');
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_cifor (const errorConstructor of [EvalError, RangeError,
1151cb0ef41Sopenharmony_ci                                ReferenceError, SyntaxError, TypeError,
1161cb0ef41Sopenharmony_ci                                URIError]) {
1171cb0ef41Sopenharmony_ci  promise_test(async () => {
1181cb0ef41Sopenharmony_ci    const originalReason = new errorConstructor('nope');
1191cb0ef41Sopenharmony_ci    const reason = await getTransferredReason(originalReason);
1201cb0ef41Sopenharmony_ci    assert_equals(typeof reason, 'object', 'reason should have type object');
1211cb0ef41Sopenharmony_ci    assert_true(reason instanceof errorConstructor,
1221cb0ef41Sopenharmony_ci                `reason should inherit ${errorConstructor.name}`);
1231cb0ef41Sopenharmony_ci    assert_true(reason instanceof Error, 'reason should inherit Error');
1241cb0ef41Sopenharmony_ci    assert_equals(reason.constructor, errorConstructor,
1251cb0ef41Sopenharmony_ci                  'reason should have the right constructor');
1261cb0ef41Sopenharmony_ci    assert_equals(reason.name, errorConstructor.name,
1271cb0ef41Sopenharmony_ci                  `name should match constructor name`);
1281cb0ef41Sopenharmony_ci    assert_equals(reason.message, 'nope', 'message should match');
1291cb0ef41Sopenharmony_ci  }, `${errorConstructor.name} should be preserved`);
1301cb0ef41Sopenharmony_ci}
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ci</script>
133