1<!DOCTYPE html> 2<meta charset="utf-8"> 3<script src="/resources/testharness.js"></script> 4<script src="/resources/testharnessreport.js"></script> 5<script src="resources/helpers.js"></script> 6<script> 7'use strict'; 8 9// Chrome used to special-case the reason for cancel() and abort() in order to 10// handle exceptions correctly. This is no longer necessary. These tests are 11// retained to avoid regressions. 12 13async function getTransferredReason(originalReason) { 14 let resolvePromise; 15 const rv = new Promise(resolve => { 16 resolvePromise = resolve; 17 }); 18 const rs = await createTransferredReadableStream({ 19 cancel(reason) { 20 resolvePromise(reason); 21 } 22 }); 23 await rs.cancel(originalReason); 24 return rv; 25} 26 27for (const value of ['hi', '\t\r\n', 7, 3.0, undefined, null, true, false, 28 NaN, Infinity]) { 29 promise_test(async () => { 30 const reason = await getTransferredReason(value); 31 assert_equals(reason, value, 'reason should match'); 32 }, `reason with a simple value of '${value}' should be preserved`); 33} 34 35for (const badType of [Symbol('hi'), _ => 'hi']) { 36 promise_test(async t => { 37 return promise_rejects_dom(t, 'DataCloneError', 38 getTransferredReason(badType), 39 'cancel() should reject'); 40 }, `reason with a type of '${typeof badType}' should be rejected and ` + 41 `error the stream`); 42} 43 44promise_test(async () => { 45 const reasonAsJson = 46 `{"foo":[1,"col"],"bar":{"hoge":0.2,"baz":{},"shan":null}}`; 47 const reason = await getTransferredReason(JSON.parse(reasonAsJson)); 48 assert_equals(JSON.stringify(reason), reasonAsJson, 49 'object should be preserved'); 50}, 'objects that can be completely expressed in JSON should be preserved'); 51 52promise_test(async () => { 53 const circularObject = {}; 54 circularObject.self = circularObject; 55 const reason = await getTransferredReason(circularObject); 56 assert_true(reason instanceof Object, 'an Object should be output'); 57 assert_equals(reason.self, reason, 58 'the object should have a circular reference'); 59}, 'objects that cannot be expressed in JSON should also be preserved'); 60 61promise_test(async () => { 62 const originalReason = new TypeError('hi'); 63 const reason = await getTransferredReason(originalReason); 64 assert_true(reason instanceof TypeError, 65 'type should be preserved'); 66 assert_equals(reason.message, originalReason.message, 67 'message should be preserved'); 68}, 'the type and message of a TypeError should be preserved'); 69 70promise_test(async () => { 71 const originalReason = new TypeError('hi'); 72 originalReason.foo = 'bar'; 73 const reason = await getTransferredReason(originalReason); 74 assert_false('foo' in reason, 75 'foo should not be preserved'); 76}, 'other attributes of a TypeError should not be preserved'); 77 78promise_test(async () => { 79 const originalReason = new TypeError(); 80 originalReason.message = [1, 2, 3]; 81 const reason = await getTransferredReason(originalReason); 82 assert_equals(reason.message, '1,2,3', 'message should be stringified'); 83}, 'a TypeError message should be converted to a string'); 84 85promise_test(async () => { 86 const originalReason = new TypeError(); 87 Object.defineProperty(originalReason, 'message', { 88 get() { return 'words'; } 89 }); 90 const reason = await getTransferredReason(originalReason); 91 assert_equals(reason.message, '', 'message should not be preserved'); 92}, 'a TypeError message should not be preserved if it is a getter'); 93 94promise_test(async () => { 95 const originalReason = new TypeError(); 96 delete originalReason.message; 97 TypeError.prototype.message = 'inherited message'; 98 const reason = await getTransferredReason(originalReason); 99 delete TypeError.prototype.message; 100 assert_equals(reason.message, '', 'message should not be preserved'); 101}, 'a TypeError message should not be preserved if it is inherited'); 102 103promise_test(async () => { 104 const originalReason = new DOMException('yes', 'AbortError'); 105 const reason = await getTransferredReason(originalReason); 106 assert_true(reason instanceof DOMException, 107 'reason should be a DOMException'); 108 assert_equals(reason.message, originalReason.message, 109 'the messages should match'); 110 assert_equals(reason.name, originalReason.name, 111 'the names should match'); 112}, 'DOMException errors should be preserved'); 113 114for (const errorConstructor of [EvalError, RangeError, 115 ReferenceError, SyntaxError, TypeError, 116 URIError]) { 117 promise_test(async () => { 118 const originalReason = new errorConstructor('nope'); 119 const reason = await getTransferredReason(originalReason); 120 assert_equals(typeof reason, 'object', 'reason should have type object'); 121 assert_true(reason instanceof errorConstructor, 122 `reason should inherit ${errorConstructor.name}`); 123 assert_true(reason instanceof Error, 'reason should inherit Error'); 124 assert_equals(reason.constructor, errorConstructor, 125 'reason should have the right constructor'); 126 assert_equals(reason.name, errorConstructor.name, 127 `name should match constructor name`); 128 assert_equals(reason.message, 'nope', 'message should match'); 129 }, `${errorConstructor.name} should be preserved`); 130} 131 132</script> 133