diff options
-rw-r--r-- | cli/tests/070_location.ts | 2 | ||||
-rw-r--r-- | cli/tests/unit/dom_exception_test.ts | 18 | ||||
-rw-r--r-- | cli/tests/unit/unit_tests.ts | 1 | ||||
-rw-r--r-- | cli/tests/wpt.jsonc | 16 | ||||
-rw-r--r-- | op_crates/web/00_dom_exception.js | 135 |
5 files changed, 125 insertions, 47 deletions
diff --git a/cli/tests/070_location.ts b/cli/tests/070_location.ts index 62fd34af2..4eace257e 100644 --- a/cli/tests/070_location.ts +++ b/cli/tests/070_location.ts @@ -6,5 +6,5 @@ console.log(location); try { location.hostname = "bar"; } catch (error) { - console.log(error); + console.log(error.toString()); } diff --git a/cli/tests/unit/dom_exception_test.ts b/cli/tests/unit/dom_exception_test.ts deleted file mode 100644 index f6c69c36d..000000000 --- a/cli/tests/unit/dom_exception_test.ts +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -import { assert, assertEquals, unitTest } from "./test_util.ts"; - -unitTest(function testDomError() { - const de = new DOMException("foo", "bar"); - assert(de); - assertEquals(de.message, "foo"); - assertEquals(de.name, "bar"); - assertEquals(de.code, 0); -}); - -unitTest(function testKnownDomException() { - const de = new DOMException("foo", "SyntaxError"); - assert(de); - assertEquals(de.message, "foo"); - assertEquals(de.name, "SyntaxError"); - assertEquals(de.code, 12); -}); diff --git a/cli/tests/unit/unit_tests.ts b/cli/tests/unit/unit_tests.ts index 7d00101d3..1e86650c3 100644 --- a/cli/tests/unit/unit_tests.ts +++ b/cli/tests/unit/unit_tests.ts @@ -17,7 +17,6 @@ import "./custom_event_test.ts"; import "./dir_test.ts"; import "./dispatch_minimal_test.ts"; import "./dispatch_json_test.ts"; -import "./dom_exception_test.ts"; import "./error_stack_test.ts"; import "./event_test.ts"; import "./event_target_test.ts"; diff --git a/cli/tests/wpt.jsonc b/cli/tests/wpt.jsonc index 29f3967ad..242338155 100644 --- a/cli/tests/wpt.jsonc +++ b/cli/tests/wpt.jsonc @@ -182,5 +182,21 @@ ], "WebCryptoApi": [ "getRandomValues" + ], + "WebIDL": [ + "ecmascript-binding/es-exceptions/DOMException-constants", + "ecmascript-binding/es-exceptions/DOMException-constructor-and-prototype", + "ecmascript-binding/es-exceptions/DOMException-constructor-behavior", + { + "name": "ecmascript-binding/es-exceptions/DOMException-custom-bindings", + "expectFail": [ + // TODO(kt3k): Enable this test. + // We can pass this test by using Object.setPrototypeOf(...) instead of + // class...extends, but that causes a problem in printing of uncaught + // DOMException. We might need to modify how to print uncaught error in + // `//core/error.rs`. + "does not inherit from Error: class-side" + ] + } ] } diff --git a/op_crates/web/00_dom_exception.js b/op_crates/web/00_dom_exception.js index 590a3c24f..8ea979f1f 100644 --- a/op_crates/web/00_dom_exception.js +++ b/op_crates/web/00_dom_exception.js @@ -1,42 +1,80 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. ((window) => { - const nameToCodeMapping = Object.create( - null, - { - IndexSizeError: { value: 1 }, - HierarchyRequestError: { value: 3 }, - WrongDocumentError: { value: 4 }, - InvalidCharacterError: { value: 5 }, - NoModificationAllowedError: { value: 7 }, - NotFoundError: { value: 8 }, - NotSupportedError: { value: 9 }, - InvalidStateError: { value: 11 }, - SyntaxError: { value: 12 }, - InvalidModificationError: { value: 13 }, - NamespaceError: { value: 14 }, - InvalidAccessError: { value: 15 }, - TypeMismatchError: { value: 17 }, - SecurityError: { value: 18 }, - NetworkError: { value: 19 }, - AbortError: { value: 20 }, - URLMismatchError: { value: 21 }, - QuotaExceededError: { value: 22 }, - TimeoutError: { value: 23 }, - InvalidNodeTypeError: { value: 24 }, - DataCloneError: { value: 25 }, - }, - ); + const { defineProperty } = Object; + // Defined in WebIDL 4.3. + // https://heycam.github.io/webidl/#idl-DOMException + const INDEX_SIZE_ERR = 1; + const DOMSTRING_SIZE_ERR = 2; + const HIERARCHY_REQUEST_ERR = 3; + const WRONG_DOCUMENT_ERR = 4; + const INVALID_CHARACTER_ERR = 5; + const NO_DATA_ALLOWED_ERR = 6; + const NO_MODIFICATION_ALLOWED_ERR = 7; + const NOT_FOUND_ERR = 8; + const NOT_SUPPORTED_ERR = 9; + const INUSE_ATTRIBUTE_ERR = 10; + const INVALID_STATE_ERR = 11; + const SYNTAX_ERR = 12; + const INVALID_MODIFICATION_ERR = 13; + const NAMESPACE_ERR = 14; + const INVALID_ACCESS_ERR = 15; + const VALIDATION_ERR = 16; + const TYPE_MISMATCH_ERR = 17; + const SECURITY_ERR = 18; + const NETWORK_ERR = 19; + const ABORT_ERR = 20; + const URL_MISMATCH_ERR = 21; + const QUOTA_EXCEEDED_ERR = 22; + const TIMEOUT_ERR = 23; + const INVALID_NODE_TYPE_ERR = 24; + const DATA_CLONE_ERR = 25; + + // Defined in WebIDL 2.8.1. + // https://heycam.github.io/webidl/#dfn-error-names-table + const nameToCodeMapping = { + IndexSizeError: INDEX_SIZE_ERR, + HierarchyRequestError: HIERARCHY_REQUEST_ERR, + WrongDocumentError: WRONG_DOCUMENT_ERR, + InvalidCharacterError: INVALID_CHARACTER_ERR, + NoModificationAllowedError: NO_MODIFICATION_ALLOWED_ERR, + NotFoundError: NOT_FOUND_ERR, + NotSupportedError: NOT_SUPPORTED_ERR, + InUseAttributeError: INUSE_ATTRIBUTE_ERR, + InvalidStateError: INVALID_STATE_ERR, + SyntaxError: SYNTAX_ERR, + InvalidModificationError: INVALID_MODIFICATION_ERR, + NamespaceError: NAMESPACE_ERR, + InvalidAccessError: INVALID_ACCESS_ERR, + TypeMismatchError: TYPE_MISMATCH_ERR, + SecurityError: SECURITY_ERR, + NetworkError: NETWORK_ERR, + AbortError: ABORT_ERR, + URLMismatchError: URL_MISMATCH_ERR, + QuotaExceededError: QUOTA_EXCEEDED_ERR, + TimeoutError: TIMEOUT_ERR, + InvalidNodeTypeError: INVALID_NODE_TYPE_ERR, + DataCloneError: DATA_CLONE_ERR, + }; + + // Defined in WebIDL 4.3. + // https://heycam.github.io/webidl/#idl-DOMException class DOMException extends Error { + #message = ""; #name = ""; #code = 0; constructor(message = "", name = "Error") { - super(message); + super(); + this.#message = String(message); this.#name = name; this.#code = nameToCodeMapping[name] ?? 0; } + get message() { + return this.#message; + } + get name() { return this.#name; } @@ -44,7 +82,50 @@ get code() { return this.#code; } + + get [Symbol.toStringTag]() { + return "DOMException"; + } + } + + defineProperty(DOMException.prototype, "message", { enumerable: true }); + defineProperty(DOMException.prototype, "name", { enumerable: true }); + defineProperty(DOMException.prototype, "code", { enumerable: true }); + + for ( + const [key, value] of Object.entries({ + 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, + }) + ) { + const desc = { value, enumerable: true }; + defineProperty(DOMException, key, desc); + defineProperty(DOMException.prototype, key, desc); } window.DOMException = DOMException; + defineProperty(window, "DOMException", { enumerable: false }); })(this); |