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