diff options
Diffstat (limited to 'testing/web-platform/tests/streams/transferable/reason.html')
-rw-r--r-- | testing/web-platform/tests/streams/transferable/reason.html | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/testing/web-platform/tests/streams/transferable/reason.html b/testing/web-platform/tests/streams/transferable/reason.html new file mode 100644 index 0000000000..4251aa85b8 --- /dev/null +++ b/testing/web-platform/tests/streams/transferable/reason.html @@ -0,0 +1,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> |