Skip to content

Commit

Permalink
change webidl.util.Type return to an enum value
Browse files Browse the repository at this point in the history
  • Loading branch information
KhafraDev committed Aug 28, 2024
1 parent c108287 commit 486eafc
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 32 deletions.
2 changes: 1 addition & 1 deletion lib/web/fetch/headers.js
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ Object.defineProperties(Headers.prototype, {
})

webidl.converters.HeadersInit = function (V, prefix, argument) {
if (webidl.util.Type(V) === 'Object') {
if (webidl.util.Type(V) === webidl.util.Types.OBJECT) {
const iterator = Reflect.get(V, Symbol.iterator)

// A work-around to ensure we send the properly-cased Headers when V is a Headers object.
Expand Down
69 changes: 51 additions & 18 deletions lib/web/fetch/webidl.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@
const { types, inspect } = require('node:util')
const { toUSVString } = require('../../core/util')

const UNDEFINED = 1
const BOOLEAN = 2
const STRING = 3
const SYMBOL = 4
const NUMBER = 5
const BIGINT = 6
const NULL = 7
const OBJECT = 8 // function and object

/** @type {import('../../../types/webidl').Webidl} */
const webidl = {}
webidl.converters = {}
Expand Down Expand Up @@ -69,23 +78,47 @@ webidl.illegalConstructor = function () {
// https://tc39.es/ecma262/#sec-ecmascript-data-types-and-values
webidl.util.Type = function (V) {
switch (typeof V) {
case 'undefined': return 'Undefined'
case 'boolean': return 'Boolean'
case 'string': return 'String'
case 'symbol': return 'Symbol'
case 'number': return 'Number'
case 'bigint': return 'BigInt'
case 'undefined': return UNDEFINED
case 'boolean': return BOOLEAN
case 'string': return STRING
case 'symbol': return SYMBOL
case 'number': return NUMBER
case 'bigint': return BIGINT
case 'function':
case 'object': {
if (V === null) {
return 'Null'
return NULL
}

return 'Object'
return OBJECT
}
}
}

webidl.util.Types = {
UNDEFINED,
BOOLEAN,
STRING,
SYMBOL,
NUMBER,
BIGINT,
NULL,
OBJECT
}

webidl.util.TypeValueToString = function (o) {
switch (webidl.util.Type(o)) {
case UNDEFINED: return 'Undefined'
case BOOLEAN: return 'Boolean'
case STRING: return 'String'
case SYMBOL: return 'Symbol'
case NUMBER: return 'Number'
case BIGINT: return 'BigInt'
case NULL: return 'Null'
case OBJECT: return 'Object'
}
}

// https://webidl.spec.whatwg.org/#abstract-opdef-converttoint
webidl.util.ConvertToInt = function (V, bitLength, signedness, opts) {
let upperBound
Expand Down Expand Up @@ -224,11 +257,11 @@ webidl.util.Stringify = function (V) {
const type = webidl.util.Type(V)

switch (type) {
case 'Symbol':
case SYMBOL:
return `Symbol(${V.description})`
case 'Object':
case OBJECT:
return inspect(V)
case 'String':
case STRING:
return `"${V}"`
default:
return `${V}`
Expand All @@ -239,7 +272,7 @@ webidl.util.Stringify = function (V) {
webidl.sequenceConverter = function (converter) {
return (V, prefix, argument, Iterable) => {
// 1. If Type(V) is not Object, throw a TypeError.
if (webidl.util.Type(V) !== 'Object') {
if (webidl.util.Type(V) !== OBJECT) {
throw webidl.errors.exception({
header: prefix,
message: `${argument} (${webidl.util.Stringify(V)}) is not iterable.`
Expand Down Expand Up @@ -282,10 +315,10 @@ webidl.sequenceConverter = function (converter) {
webidl.recordConverter = function (keyConverter, valueConverter) {
return (O, prefix, argument) => {
// 1. If Type(O) is not Object, throw a TypeError.
if (webidl.util.Type(O) !== 'Object') {
if (webidl.util.Type(O) !== OBJECT) {
throw webidl.errors.exception({
header: prefix,
message: `${argument} ("${webidl.util.Type(O)}") is not an Object.`
message: `${argument} ("${webidl.util.TypeValueToString(O)}") is not an Object.`
})
}

Expand Down Expand Up @@ -356,7 +389,7 @@ webidl.dictionaryConverter = function (converters) {
return (dictionary, prefix, argument) => {
const dict = {}

if (dictionary != null && webidl.util.Type(dictionary) !== 'Object') {
if (dictionary != null && webidl.util.Type(dictionary) !== OBJECT) {
throw webidl.errors.exception({
header: prefix,
message: `Expected ${dictionary} to be one of: Null, Undefined, Object.`
Expand Down Expand Up @@ -532,7 +565,7 @@ webidl.converters.ArrayBuffer = function (V, prefix, argument, opts) {
// see: https://tc39.es/ecma262/#sec-properties-of-the-arraybuffer-instances
// see: https://tc39.es/ecma262/#sec-properties-of-the-sharedarraybuffer-instances
if (
webidl.util.Type(V) !== 'Object' ||
webidl.util.Type(V) !== OBJECT ||
!types.isAnyArrayBuffer(V)
) {
throw webidl.errors.conversionFailed({
Expand Down Expand Up @@ -576,7 +609,7 @@ webidl.converters.TypedArray = function (V, T, prefix, name, opts) {
// [[TypedArrayName]] internal slot with a value
// equal to T’s name, then throw a TypeError.
if (
webidl.util.Type(V) !== 'Object' ||
webidl.util.Type(V) !== OBJECT ||
!types.isTypedArray(V) ||
V.constructor.name !== T.name
) {
Expand Down Expand Up @@ -617,7 +650,7 @@ webidl.converters.TypedArray = function (V, T, prefix, name, opts) {
webidl.converters.DataView = function (V, prefix, name, opts) {
// 1. If Type(V) is not Object, or V does not have a
// [[DataView]] internal slot, then throw a TypeError.
if (webidl.util.Type(V) !== 'Object' || !types.isDataView(V)) {
if (webidl.util.Type(V) !== OBJECT || !types.isDataView(V)) {
throw webidl.errors.exception({
header: prefix,
message: `${name} is not a DataView.`
Expand Down
6 changes: 3 additions & 3 deletions lib/web/websocket/websocket.js
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,7 @@ webidl.converters['sequence<DOMString>'] = webidl.sequenceConverter(
)

webidl.converters['DOMString or sequence<DOMString>'] = function (V, prefix, argument) {
if (webidl.util.Type(V) === 'Object' && Symbol.iterator in V) {
if (webidl.util.Type(V) === webidl.util.Types.OBJECT && Symbol.iterator in V) {
return webidl.converters['sequence<DOMString>'](V)
}

Expand All @@ -784,15 +784,15 @@ webidl.converters.WebSocketInit = webidl.dictionaryConverter([
])

webidl.converters['DOMString or sequence<DOMString> or WebSocketInit'] = function (V) {
if (webidl.util.Type(V) === 'Object' && !(Symbol.iterator in V)) {
if (webidl.util.Type(V) === webidl.util.Types.OBJECT && !(Symbol.iterator in V)) {
return webidl.converters.WebSocketInit(V)
}

return { protocols: webidl.converters['DOMString or sequence<DOMString>'](V) }
}

webidl.converters.WebSocketSendData = function (V) {
if (webidl.util.Type(V) === 'Object') {
if (webidl.util.Type(V) === webidl.util.Types.OBJECT) {
if (V instanceof Blob) {
return V
}
Expand Down
9 changes: 9 additions & 0 deletions test/webidl/converters.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,3 +238,12 @@ test('webidl.util.Stringify', (t) => {
assert.deepStrictEqual(webidl.util.Stringify(value), expected)
}
})

test('recordConverter', () => {
const anyConverter = webidl.recordConverter(webidl.converters.any, webidl.converters.any)

assert.throws(
() => anyConverter(null, 'prefix', 'argument'),
new TypeError('prefix: argument ("Null") is not an Object.')
)
})
20 changes: 11 additions & 9 deletions test/webidl/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ const { webidl } = require('../../lib/web/fetch/webidl')

test('Type(V)', () => {
const Type = webidl.util.Type

assert.equal(Type(undefined), 'Undefined')
assert.equal(Type(null), 'Null')
assert.equal(Type(true), 'Boolean')
assert.equal(Type('string'), 'String')
assert.equal(Type(Symbol('symbol')), 'Symbol')
assert.equal(Type(1.23), 'Number')
assert.equal(Type(1n), 'BigInt')
assert.equal(Type({ a: 'b' }), 'Object')
const Types = webidl.util.Types

assert.equal(Type(undefined), Types.UNDEFINED)
assert.equal(Type(null), Types.NULL)
assert.equal(Type(true), Types.BOOLEAN)
assert.equal(Type('string'), Types.STRING)
assert.equal(Type(Symbol('symbol')), Types.SYMBOL)
assert.equal(Type(1.23), Types.NUMBER)
assert.equal(Type(1n), Types.BIGINT)
assert.equal(Type({ a: 'b' }), Types.OBJECT)
assert.equal(Type(function () {}), Types.OBJECT)
})

test('ConvertToInt(V)', () => {
Expand Down
17 changes: 16 additions & 1 deletion types/webidl.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,24 @@ interface WebidlErrors {
}): TypeError
}

interface WebIDLTypes {
UNDEFINED: 1,
BOOLEAN: 2,
STRING: 3,
SYMBOL: 4,
NUMBER: 5,
BIGINT: 6,
NULL: 7
OBJECT: 8
}

interface WebidlUtil {
/**
* @see https://tc39.es/ecma262/#sec-ecmascript-data-types-and-values
*/
Type (object: unknown):
Type (object: unknown): WebIDLTypes

TypeValueToString (o: unknown):
| 'Undefined'
| 'Boolean'
| 'String'
Expand All @@ -48,6 +61,8 @@ interface WebidlUtil {
| 'Null'
| 'Object'

Types: WebIDLTypes

/**
* @see https://webidl.spec.whatwg.org/#abstract-opdef-converttoint
*/
Expand Down

0 comments on commit 486eafc

Please sign in to comment.