diff options
Diffstat (limited to 'testing/web-platform/tests/webidl/ecmascript-binding/es-exceptions')
5 files changed, 421 insertions, 0 deletions
diff --git a/testing/web-platform/tests/webidl/ecmascript-binding/es-exceptions/DOMException-constants.any.js b/testing/web-platform/tests/webidl/ecmascript-binding/es-exceptions/DOMException-constants.any.js new file mode 100644 index 0000000000..bb846a494e --- /dev/null +++ b/testing/web-platform/tests/webidl/ecmascript-binding/es-exceptions/DOMException-constants.any.js @@ -0,0 +1,51 @@ +'use strict'; + +test(function() { + // https://www.w3.org/Bugs/Public/show_bug.cgi?id=27732 + var constants = [ + "INDEX_SIZE_ERR", + "DOMSTRING_SIZE_ERR", + "HIERARCHY_REQUEST_ERR", + "WRONG_DOCUMENT_ERR", + "INVALID_CHARACTER_ERR", + "NO_DATA_ALLOWED_ERR", + "NO_MODIFICATION_ALLOWED_ERR", + "NOT_FOUND_ERR", + "NOT_SUPPORTED_ERR", + "INUSE_ATTRIBUTE_ERR", + "INVALID_STATE_ERR", + "SYNTAX_ERR", + "INVALID_MODIFICATION_ERR", + "NAMESPACE_ERR", + "INVALID_ACCESS_ERR", + "VALIDATION_ERR", + "TYPE_MISMATCH_ERR", + "SECURITY_ERR", + "NETWORK_ERR", + "ABORT_ERR", + "URL_MISMATCH_ERR", + "QUOTA_EXCEEDED_ERR", + "TIMEOUT_ERR", + "INVALID_NODE_TYPE_ERR", + "DATA_CLONE_ERR" + ] + var objects = [ + [DOMException, "DOMException constructor object"], + [DOMException.prototype, "DOMException prototype object"] + ] + constants.forEach(function(name, i) { + objects.forEach(function(o) { + var object = o[0], description = o[1]; + test(function() { + assert_equals(object[name], i + 1, name) + assert_own_property(object, name) + var pd = Object.getOwnPropertyDescriptor(object, name) + assert_false("get" in pd, "get") + assert_false("set" in pd, "set") + assert_false(pd.writable, "writable") + assert_true(pd.enumerable, "enumerable") + assert_false(pd.configurable, "configurable") + }, "Constant " + name + " on " + description) + }) + }) +}) diff --git a/testing/web-platform/tests/webidl/ecmascript-binding/es-exceptions/DOMException-constructor-and-prototype.any.js b/testing/web-platform/tests/webidl/ecmascript-binding/es-exceptions/DOMException-constructor-and-prototype.any.js new file mode 100644 index 0000000000..a015470cad --- /dev/null +++ b/testing/web-platform/tests/webidl/ecmascript-binding/es-exceptions/DOMException-constructor-and-prototype.any.js @@ -0,0 +1,32 @@ +test(function() { + assert_own_property(self, "DOMException", "property of global"); + + var desc = Object.getOwnPropertyDescriptor(self, "DOMException"); + assert_false("get" in desc, "get"); + assert_false("set" in desc, "set"); + assert_true(desc.writable, "writable"); + assert_false(desc.enumerable, "enumerable"); + assert_true(desc.configurable, "configurable"); +}, "existence and property descriptor of DOMException"); + +test(function() { + assert_own_property(self.DOMException, "prototype", "prototype property"); + + var desc = Object.getOwnPropertyDescriptor(self.DOMException, "prototype"); + assert_false("get" in desc, "get"); + assert_false("set" in desc, "set"); + assert_false(desc.writable, "writable"); + assert_false(desc.enumerable, "enumerable"); + assert_false(desc.configurable, "configurable"); +}, "existence and property descriptor of DOMException.prototype"); + +test(function() { + assert_own_property(self.DOMException.prototype, "constructor", "property of prototype"); + var desc = Object.getOwnPropertyDescriptor(self.DOMException.prototype, "constructor"); + assert_false("get" in desc, "get"); + assert_false("set" in desc, "set"); + assert_true(desc.writable, "writable"); + assert_false(desc.enumerable, "enumerable"); + assert_true(desc.configurable, "configurable"); + assert_equals(self.DOMException.prototype.constructor, self.DOMException, "equality with actual constructor"); +}, "existence and property descriptor of DOMException.prototype.constructor"); diff --git a/testing/web-platform/tests/webidl/ecmascript-binding/es-exceptions/DOMException-constructor-behavior.any.js b/testing/web-platform/tests/webidl/ecmascript-binding/es-exceptions/DOMException-constructor-behavior.any.js new file mode 100644 index 0000000000..e9917af228 --- /dev/null +++ b/testing/web-platform/tests/webidl/ecmascript-binding/es-exceptions/DOMException-constructor-behavior.any.js @@ -0,0 +1,140 @@ +'use strict'; + +test(function() { + var ex = new DOMException(); + assert_equals(ex.name, "Error", + "Not passing a name should end up with 'Error' as the name"); + assert_equals(ex.message, "", + "Not passing a message should end up with empty string as the message"); +}, 'new DOMException()'); + +test(function() { + var ex = new DOMException(); + assert_false(ex.hasOwnProperty("name"), + "The name property should be inherited"); + assert_false(ex.hasOwnProperty("message"), + "The message property should be inherited"); +}, 'new DOMException(): inherited-ness'); + +test(function() { + var ex = new DOMException(null); + assert_equals(ex.name, "Error", + "Not passing a name should end up with 'Error' as the name"); + assert_equals(ex.message, "null", + "Passing null as message should end up with stringified 'null' as the message"); +}, 'new DOMException(null)'); + +test(function() { + var ex = new DOMException(undefined); + assert_equals(ex.name, "Error", + "Not passing a name should end up with 'Error' as the name"); + assert_equals(ex.message, "", + "Not passing a message should end up with empty string as the message"); +}, 'new DOMException(undefined)'); + +test(function() { + var ex = new DOMException(undefined); + assert_false(ex.hasOwnProperty("name"), + "The name property should be inherited"); + assert_false(ex.hasOwnProperty("message"), + "The message property should be inherited"); +}, 'new DOMException(undefined): inherited-ness'); + +test(function() { + var ex = new DOMException("foo"); + assert_equals(ex.name, "Error", + "Not passing a name should still end up with 'Error' as the name"); + assert_equals(ex.message, "foo", "Should be using passed-in message"); +}, 'new DOMException("foo")'); + +test(function() { + var ex = new DOMException("foo"); + assert_false(ex.hasOwnProperty("name"), + "The name property should be inherited"); + assert_false(ex.hasOwnProperty("message"), + "The message property should be inherited"); +}, 'new DOMException("foo"): inherited-ness'); + +test(function() { + var ex = new DOMException("bar", undefined); + assert_equals(ex.name, "Error", + "Passing undefined for name should end up with 'Error' as the name"); + assert_equals(ex.message, "bar", "Should still be using passed-in message"); +}, 'new DOMException("bar", undefined)'); + +test(function() { + var ex = new DOMException("bar", "NotSupportedError"); + assert_equals(ex.name, "NotSupportedError", "Should be using the passed-in name"); + assert_equals(ex.message, "bar", "Should still be using passed-in message"); + assert_equals(ex.code, DOMException.NOT_SUPPORTED_ERR, + "Should have the right exception code"); +}, 'new DOMException("bar", "NotSupportedError")'); + +test(function() { + var ex = new DOMException("bar", "NotSupportedError"); + assert_false(ex.hasOwnProperty("name"), + "The name property should be inherited"); + assert_false(ex.hasOwnProperty("message"), + "The message property should be inherited"); +}, 'new DOMException("bar", "NotSupportedError"): inherited-ness'); + +test(function() { + var ex = new DOMException("bar", "foo"); + assert_equals(ex.name, "foo", "Should be using the passed-in name"); + assert_equals(ex.message, "bar", "Should still be using passed-in message"); + assert_equals(ex.code, 0, + "Should have 0 for code for a name not in the exception names table"); +}, 'new DOMException("bar", "foo")'); + +[ + {name: "IndexSizeError", code: 1}, + {name: "HierarchyRequestError", code: 3}, + {name: "WrongDocumentError", code: 4}, + {name: "InvalidCharacterError", code: 5}, + {name: "NoModificationAllowedError", code: 7}, + {name: "NotFoundError", code: 8}, + {name: "NotSupportedError", code: 9}, + {name: "InUseAttributeError", code: 10}, + {name: "InvalidStateError", code: 11}, + {name: "SyntaxError", code: 12}, + {name: "InvalidModificationError", code: 13}, + {name: "NamespaceError", code: 14}, + {name: "InvalidAccessError", code: 15}, + {name: "TypeMismatchError", code: 17}, + {name: "SecurityError", code: 18}, + {name: "NetworkError", code: 19}, + {name: "AbortError", code: 20}, + {name: "URLMismatchError", code: 21}, + {name: "QuotaExceededError", code: 22}, + {name: "TimeoutError", code: 23}, + {name: "InvalidNodeTypeError", code: 24}, + {name: "DataCloneError", code: 25}, + + // These were removed from the error names table. + // See https://github.com/heycam/webidl/pull/946. + {name: "DOMStringSizeError", code: 0}, + {name: "NoDataAllowedError", code: 0}, + {name: "ValidationError", code: 0}, + + // The error names which don't have legacy code values. + {name: "EncodingError", code: 0}, + {name: "NotReadableError", code: 0}, + {name: "UnknownError", code: 0}, + {name: "ConstraintError", code: 0}, + {name: "DataError", code: 0}, + {name: "TransactionInactiveError", code: 0}, + {name: "ReadOnlyError", code: 0}, + {name: "VersionError", code: 0}, + {name: "OperationError", code: 0}, + {name: "NotAllowedError", code: 0} +].forEach(function(test_case) { + test(function() { + var ex = new DOMException("msg", test_case.name); + assert_equals(ex.name, test_case.name, + "Should be using the passed-in name"); + assert_equals(ex.message, "msg", + "Should be using the passed-in message"); + assert_equals(ex.code, test_case.code, + "Should have matching legacy code from error names table"); + },'new DOMexception("msg", "' + test_case.name + '")'); +}); diff --git a/testing/web-platform/tests/webidl/ecmascript-binding/es-exceptions/DOMException-custom-bindings.any.js b/testing/web-platform/tests/webidl/ecmascript-binding/es-exceptions/DOMException-custom-bindings.any.js new file mode 100644 index 0000000000..cd4e5b6341 --- /dev/null +++ b/testing/web-platform/tests/webidl/ecmascript-binding/es-exceptions/DOMException-custom-bindings.any.js @@ -0,0 +1,120 @@ +"use strict"; + +test(() => { + assert_throws_js(TypeError, () => DOMException()); +}, "Cannot construct without new"); + +test(() => { + assert_equals(Object.getPrototypeOf(DOMException.prototype), Error.prototype); +}, "inherits from Error: prototype-side"); + +test(() => { + assert_equals(Object.getPrototypeOf(DOMException), Function.prototype); +}, "does not inherit from Error: class-side"); + +test(() => { + const e = new DOMException("message", "name"); + assert_false(e.hasOwnProperty("message"), "property is not own"); + + const propDesc = Object.getOwnPropertyDescriptor(DOMException.prototype, "message"); + assert_equals(typeof propDesc.get, "function", "property descriptor is a getter"); + assert_equals(propDesc.set, undefined, "property descriptor is not a setter"); + assert_true(propDesc.enumerable, "property descriptor enumerable"); + assert_true(propDesc.configurable, "property descriptor configurable"); +}, "message property descriptor"); + +test(() => { + const getter = Object.getOwnPropertyDescriptor(DOMException.prototype, "message").get; + + assert_throws_js(TypeError, () => getter.apply({})); +}, "message getter performs brand checks (i.e. is not [LegacyLenientThis])"); + +test(() => { + const e = new DOMException("message", "name"); + assert_false(e.hasOwnProperty("name"), "property is not own"); + + const propDesc = Object.getOwnPropertyDescriptor(DOMException.prototype, "name"); + assert_equals(typeof propDesc.get, "function", "property descriptor is a getter"); + assert_equals(propDesc.set, undefined, "property descriptor is not a setter"); + assert_true(propDesc.enumerable, "property descriptor enumerable"); + assert_true(propDesc.configurable, "property descriptor configurable"); +}, "name property descriptor"); + +test(() => { + const getter = Object.getOwnPropertyDescriptor(DOMException.prototype, "name").get; + + assert_throws_js(TypeError, () => getter.apply({})); +}, "name getter performs brand checks (i.e. is not [LegacyLenientThis])"); + +test(() => { + const e = new DOMException("message", "name"); + assert_false(e.hasOwnProperty("code"), "property is not own"); + + const propDesc = Object.getOwnPropertyDescriptor(DOMException.prototype, "code"); + assert_equals(typeof propDesc.get, "function", "property descriptor is a getter"); + assert_equals(propDesc.set, undefined, "property descriptor is not a setter"); + assert_true(propDesc.enumerable, "property descriptor enumerable"); + assert_true(propDesc.configurable, "property descriptor configurable"); +}, "code property descriptor"); + +test(() => { + const getter = Object.getOwnPropertyDescriptor(DOMException.prototype, "code").get; + + assert_throws_js(TypeError, () => getter.apply({})); +}, "code getter performs brand checks (i.e. is not [LegacyLenientThis])"); + +test(() => { + const e = new DOMException("message", "InvalidCharacterError"); + assert_equals(e.code, 5, "Initially the code is set to 5"); + + Object.defineProperty(e, "name", { + value: "WrongDocumentError" + }); + + assert_equals(e.code, 5, "The code is still set to 5"); +}, "code property is not affected by shadowing the name property"); + +test(() => { + const e = new DOMException("message", "name"); + assert_equals(Object.prototype.toString.call(e), "[object DOMException]"); +}, "Object.prototype.toString behavior is like other interfaces"); + +test(() => { + const e = new DOMException("message", "name"); + assert_false(e.hasOwnProperty("toString"), "toString must not exist on the instance"); + assert_false(DOMException.prototype.hasOwnProperty("toString"), "toString must not exist on DOMException.prototype"); + assert_equals(typeof e.toString, "function", "toString must still exist (via Error.prototype)"); +}, "Inherits its toString() from Error.prototype"); + +test(() => { + const e = new DOMException("message", "name"); + assert_equals(e.toString(), "name: message", + "The default Error.prototype.toString() behavior must work on supplied name and message"); + + Object.defineProperty(e, "name", { value: "new name" }); + Object.defineProperty(e, "message", { value: "new message" }); + assert_equals(e.toString(), "new name: new message", + "The default Error.prototype.toString() behavior must work on shadowed names and messages"); +}, "toString() behavior from Error.prototype applies as expected"); + +test(() => { + assert_throws_js(TypeError, () => DOMException.prototype.toString()); +}, "DOMException.prototype.toString() applied to DOMException.prototype throws because of name/message brand checks"); + +test(() => { + let stackOnNormalErrors; + try { + throw new Error("normal error"); + } catch (e) { + stackOnNormalErrors = e.stack; + } + + let stackOnDOMException; + try { + throw new DOMException("message", "name"); + } catch (e) { + stackOnDOMException = e.stack; + } + + assert_equals(typeof stackOnDOMException, typeof stackOnNormalErrors, "The typeof values must match"); +}, "If the implementation has a stack property on normal errors, it also does on DOMExceptions"); diff --git a/testing/web-platform/tests/webidl/ecmascript-binding/es-exceptions/exceptions.html b/testing/web-platform/tests/webidl/ecmascript-binding/es-exceptions/exceptions.html new file mode 100644 index 0000000000..d26c662669 --- /dev/null +++ b/testing/web-platform/tests/webidl/ecmascript-binding/es-exceptions/exceptions.html @@ -0,0 +1,78 @@ +<!doctype html> +<meta charset=utf-8> +<title>DOMException-throwing tests</title> +<link rel=author title="Aryeh Gregor" href=ayg@aryeh.name> +<div id=log></div> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script> +/** + * This file just picks one case where browsers are supposed to throw an + * exception, and tests the heck out of whether it meets the spec. In the + * future, all these checks should be in assert_throws_dom(), but we don't want + * every browser failing every assert_throws_dom() check until they fix every + * single bug in their exception-throwing. + * + * We don't go out of our way to test everything that's already tested by + * interfaces.html, like whether all constants are present on the object, but + * some things are duplicated. + */ +setup({explicit_done: true}); + +function testException(exception, global, desc) { + test(function() { + assert_equals(global.Object.getPrototypeOf(exception), + global.DOMException.prototype); + }, desc + "Object.getPrototypeOf(exception) === DOMException.prototype"); + + + test(function() { + assert_false(exception.hasOwnProperty("name")); + }, desc + "exception.hasOwnProperty(\"name\")"); + test(function() { + assert_false(exception.hasOwnProperty("message")); + }, desc + "exception.hasOwnProperty(\"message\")"); + + test(function() { + assert_equals(exception.name, "HierarchyRequestError"); + }, desc + "exception.name === \"HierarchyRequestError\""); + + test(function() { + assert_equals(exception.code, global.DOMException.HIERARCHY_REQUEST_ERR); + }, desc + "exception.code === DOMException.HIERARCHY_REQUEST_ERR"); + + test(function() { + assert_equals(global.Object.prototype.toString.call(exception), + "[object DOMException]"); + }, desc + "Object.prototype.toString.call(exception) === \"[object DOMException]\""); +} + + +// Test in current window +var exception = null; +try { + // This should throw a HierarchyRequestError in every browser since the + // Stone Age, so we're really only testing exception-throwing details. + document.documentElement.appendChild(document); +} catch(e) { + exception = e; +} +testException(exception, window, ""); + +// Test in iframe +var iframe = document.createElement("iframe"); +iframe.src = "about:blank"; +iframe.onload = function() { + var exception = null; + try { + iframe.contentDocument.documentElement.appendChild(iframe.contentDocument); + } catch(e) { + exception = e; + } + testException(exception, iframe.contentWindow, "In iframe: "); + + document.body.removeChild(iframe); + done(); +}; +document.body.appendChild(iframe); +</script> |