/** * Based on React Native's DOMException integration tests * https://github.com/facebook/react-native/blob/f5bd86c31105bb6a994acb03c8149bd7ee03dac6/packages/react-native/src/private/webapis/errors/__tests__/DOMException-itest.js */ describe('DOMException', () => { const errorCodes = [ ['INDEX_SIZE_ERR', 1], ['DOMSTRING_SIZE_ERR', 2], ['HIERARCHY_REQUEST_ERR', 3], ['WRONG_DOCUMENT_ERR', 4], ['INVALID_CHARACTER_ERR', 5], ['NO_DATA_ALLOWED_ERR', 6], ['NO_MODIFICATION_ALLOWED_ERR', 7], ['NOT_FOUND_ERR', 8], ['NOT_SUPPORTED_ERR', 9], ['INUSE_ATTRIBUTE_ERR', 10], ['INVALID_STATE_ERR', 11], ['SYNTAX_ERR', 12], ['INVALID_MODIFICATION_ERR', 13], ['NAMESPACE_ERR', 14], ['INVALID_ACCESS_ERR', 15], ['VALIDATION_ERR', 16], ['TYPE_MISMATCH_ERR', 17], ['SECURITY_ERR', 18], ['NETWORK_ERR', 19], ['ABORT_ERR', 20], ['URL_MISMATCH_ERR', 21], ['QUOTA_EXCEEDED_ERR', 22], ['TIMEOUT_ERR', 23], ['INVALID_NODE_TYPE_ERR', 24], ['DATA_CLONE_ERR', 25], ] as const; const errorNameCodes = [ ['SomethingElse', 0], ['IndexSizeError', DOMException.INDEX_SIZE_ERR], ['HierarchyRequestError', DOMException.HIERARCHY_REQUEST_ERR], ['WrongDocumentError', DOMException.WRONG_DOCUMENT_ERR], ['InvalidCharacterError', DOMException.INVALID_CHARACTER_ERR], ['NoModificationAllowedError', DOMException.NO_MODIFICATION_ALLOWED_ERR], ['NotFoundError', DOMException.NOT_FOUND_ERR], ['NotSupportedError', DOMException.NOT_SUPPORTED_ERR], ['InUseAttributeError', DOMException.INUSE_ATTRIBUTE_ERR], ['InvalidStateError', DOMException.INVALID_STATE_ERR], ['SyntaxError', DOMException.SYNTAX_ERR], ['InvalidModificationError', DOMException.INVALID_MODIFICATION_ERR], ['NamespaceError', DOMException.NAMESPACE_ERR], ['InvalidAccessError', DOMException.INVALID_ACCESS_ERR], ['TypeMismatchError', DOMException.TYPE_MISMATCH_ERR], ['SecurityError', DOMException.SECURITY_ERR], ['NetworkError', DOMException.NETWORK_ERR], ['AbortError', DOMException.ABORT_ERR], ['URLMismatchError', DOMException.URL_MISMATCH_ERR], ['QuotaExceededError', DOMException.QUOTA_EXCEEDED_ERR], ['TimeoutError', DOMException.TIMEOUT_ERR], ['InvalidNodeTypeError', DOMException.INVALID_NODE_TYPE_ERR], ['DataCloneError', DOMException.DATA_CLONE_ERR], ] as const; it('should use the Expo built-in API', () => { expect((DOMException as any)[Symbol.for('expo.builtin')]).toBe(true); }); it('should provide error codes as static fields and instance fields', () => { const exception = new DOMException(); for (const [name, code] of errorCodes) { expect(DOMException[name]).toBe(code); expect(exception[name]).toBe(code); } }); it('should create named exceptions with legacy codes', () => { const exception = new DOMException('signal timed out', 'TimeoutError'); expect(exception).toBeInstanceOf(Error); expect(exception.message).toBe('signal timed out'); expect(exception.name).toBe('TimeoutError'); expect(exception.code).toBe(DOMException.TIMEOUT_ERR); expect(exception.code).toBe(23); }); it('should default to Error with code 0', () => { const exception = new DOMException('failed'); expect(exception.name).toBe('Error'); expect(exception.code).toBe(0); }); it('should normalize names', () => { expect(new DOMException(undefined, undefined).name).toBe('Error'); expect(new DOMException(undefined, '').name).toBe(''); expect(new DOMException(undefined, null as unknown as string).name).toBe('null'); expect(new DOMException(undefined, {} as string).name).toBe('[object Object]'); }); it('should assign the right code for the given name', () => { for (const [name, code] of errorNameCodes) { expect(new DOMException(undefined, name).code).toBe(code); } }); });