diff options
Diffstat (limited to 'test/webidl')
-rw-r--r-- | test/webidl/converters.js | 202 | ||||
-rw-r--r-- | test/webidl/helpers.js | 75 | ||||
-rw-r--r-- | test/webidl/util.js | 106 |
3 files changed, 383 insertions, 0 deletions
diff --git a/test/webidl/converters.js b/test/webidl/converters.js new file mode 100644 index 0000000..95bea88 --- /dev/null +++ b/test/webidl/converters.js @@ -0,0 +1,202 @@ +'use strict' + +const { test } = require('tap') +const { webidl } = require('../../lib/fetch/webidl') + +test('sequence', (t) => { + const converter = webidl.sequenceConverter( + webidl.converters.DOMString + ) + + t.same(converter([1, 2, 3]), ['1', '2', '3']) + + t.throws(() => { + converter(3) + }, TypeError, 'disallows non-objects') + + t.throws(() => { + converter(null) + }, TypeError) + + t.throws(() => { + converter(undefined) + }, TypeError) + + t.throws(() => { + converter({}) + }, TypeError, 'no Symbol.iterator') + + t.throws(() => { + converter({ + [Symbol.iterator]: 42 + }) + }, TypeError, 'invalid Symbol.iterator') + + t.throws(() => { + converter(webidl.converters.sequence({ + [Symbol.iterator] () { + return { + next: 'never!' + } + } + })) + }, TypeError, 'invalid generator') + + t.end() +}) + +test('webidl.dictionaryConverter', (t) => { + t.test('arguments', (t) => { + const converter = webidl.dictionaryConverter([]) + + t.throws(() => { + converter(true) + }, TypeError) + + for (const value of [{}, undefined, null]) { + t.doesNotThrow(() => { + converter(value) + }) + } + + t.end() + }) + + t.test('required key', (t) => { + const converter = webidl.dictionaryConverter([ + { + converter: () => true, + key: 'Key', + required: true + } + ]) + + t.throws(() => { + converter({ wrongKey: 'key' }) + }, TypeError) + + t.doesNotThrow(() => { + converter({ Key: 'this key was required!' }) + }) + + t.end() + }) + + t.end() +}) + +test('ArrayBuffer', (t) => { + t.throws(() => { + webidl.converters.ArrayBuffer(true) + }, TypeError) + + t.throws(() => { + webidl.converters.ArrayBuffer({}) + }, TypeError) + + t.throws(() => { + const sab = new SharedArrayBuffer(1024) + webidl.converters.ArrayBuffer(sab, { allowShared: false }) + }, TypeError) + + t.doesNotThrow(() => { + const sab = new SharedArrayBuffer(1024) + webidl.converters.ArrayBuffer(sab) + }) + + t.doesNotThrow(() => { + const ab = new ArrayBuffer(8) + webidl.converters.ArrayBuffer(ab) + }) + + t.end() +}) + +test('TypedArray', (t) => { + t.throws(() => { + webidl.converters.TypedArray(3) + }, TypeError) + + t.throws(() => { + webidl.converters.TypedArray({}) + }, TypeError) + + t.throws(() => { + const uint8 = new Uint8Array([1, 2, 3]) + Object.defineProperty(uint8, 'buffer', { + get () { + return new SharedArrayBuffer(8) + } + }) + + webidl.converters.TypedArray(uint8, Uint8Array, { + allowShared: false + }) + }, TypeError) + + t.end() +}) + +test('DataView', (t) => { + t.throws(() => { + webidl.converters.DataView(3) + }, TypeError) + + t.throws(() => { + webidl.converters.DataView({}) + }, TypeError) + + t.throws(() => { + const buffer = new ArrayBuffer(16) + const view = new DataView(buffer, 0) + + Object.defineProperty(view, 'buffer', { + get () { + return new SharedArrayBuffer(8) + } + }) + + webidl.converters.DataView(view, { + allowShared: false + }) + }) + + const buffer = new ArrayBuffer(16) + const view = new DataView(buffer, 0) + + t.equal(webidl.converters.DataView(view), view) + + t.end() +}) + +test('BufferSource', (t) => { + t.doesNotThrow(() => { + const buffer = new ArrayBuffer(16) + const view = new DataView(buffer, 0) + + webidl.converters.BufferSource(view) + }) + + t.throws(() => { + webidl.converters.BufferSource(3) + }, TypeError) + + t.end() +}) + +test('ByteString', (t) => { + t.doesNotThrow(() => { + webidl.converters.ByteString('') + }) + + // https://github.com/nodejs/undici/issues/1590 + t.throws(() => { + const char = String.fromCharCode(256) + webidl.converters.ByteString(`invalid${char}char`) + }, { + message: 'Cannot convert argument to a ByteString because the character at ' + + 'index 7 has a value of 256 which is greater than 255.' + }) + + t.end() +}) diff --git a/test/webidl/helpers.js b/test/webidl/helpers.js new file mode 100644 index 0000000..f44d501 --- /dev/null +++ b/test/webidl/helpers.js @@ -0,0 +1,75 @@ +'use strict' + +const { test } = require('tap') +const { webidl } = require('../../lib/fetch/webidl') + +test('webidl.interfaceConverter', (t) => { + class A {} + class B {} + + const converter = webidl.interfaceConverter(A) + + t.throws(() => { + converter(new B()) + }, TypeError) + + t.doesNotThrow(() => { + converter(new A()) + }) + + t.end() +}) + +test('webidl.dictionaryConverter', (t) => { + t.test('extraneous keys are provided', (t) => { + const converter = webidl.dictionaryConverter([ + { + key: 'key', + converter: webidl.converters.USVString, + defaultValue: 420, + required: true + } + ]) + + t.same( + converter({ + a: 'b', + key: 'string', + c: 'd', + get value () { + return 6 + } + }), + { key: 'string' } + ) + + t.end() + }) + + t.test('defaultValue with key = null', (t) => { + const converter = webidl.dictionaryConverter([ + { + key: 'key', + converter: webidl.converters['unsigned short'], + defaultValue: 200 + } + ]) + + t.same(converter({ key: null }), { key: 0 }) + t.end() + }) + + t.test('no defaultValue and optional', (t) => { + const converter = webidl.dictionaryConverter([ + { + key: 'key', + converter: webidl.converters.ByteString + } + ]) + + t.same(converter({ a: 'b', c: 'd' }), {}) + t.end() + }) + + t.end() +}) diff --git a/test/webidl/util.js b/test/webidl/util.js new file mode 100644 index 0000000..c451590 --- /dev/null +++ b/test/webidl/util.js @@ -0,0 +1,106 @@ +'use strict' + +const { test } = require('tap') +const { webidl } = require('../../lib/fetch/webidl') + +test('Type(V)', (t) => { + const Type = webidl.util.Type + + t.equal(Type(undefined), 'Undefined') + t.equal(Type(null), 'Null') + t.equal(Type(true), 'Boolean') + t.equal(Type('string'), 'String') + t.equal(Type(Symbol('symbol')), 'Symbol') + t.equal(Type(1.23), 'Number') + t.equal(Type(1n), 'BigInt') + t.equal(Type({ a: 'b' }), 'Object') + + t.end() +}) + +test('ConvertToInt(V)', (t) => { + const ConvertToInt = webidl.util.ConvertToInt + + t.equal(ConvertToInt(63, 64, 'signed'), 63, 'odd int') + t.equal(ConvertToInt(64.49, 64, 'signed'), 64) + t.equal(ConvertToInt(64.51, 64, 'signed'), 64) + + const max = 2 ** 53 + t.equal(ConvertToInt(max + 1, 64, 'signed'), max, 'signed pos') + t.equal(ConvertToInt(-max - 1, 64, 'signed'), -max, 'signed neg') + + t.equal(ConvertToInt(max + 1, 64, 'unsigned'), max + 1, 'unsigned pos') + t.equal(ConvertToInt(-max - 1, 64, 'unsigned'), -max - 1, 'unsigned neg') + + for (const signedness of ['signed', 'unsigned']) { + t.equal(ConvertToInt(Infinity, 64, signedness), 0) + t.equal(ConvertToInt(-Infinity, 64, signedness), 0) + t.equal(ConvertToInt(NaN, 64, signedness), 0) + } + + for (const signedness of ['signed', 'unsigned']) { + t.throws(() => { + ConvertToInt(NaN, 64, signedness, { + enforceRange: true + }) + }, TypeError) + + t.throws(() => { + ConvertToInt(Infinity, 64, signedness, { + enforceRange: true + }) + }, TypeError) + + t.throws(() => { + ConvertToInt(-Infinity, 64, signedness, { + enforceRange: true + }) + }, TypeError) + + t.throws(() => { + ConvertToInt(2 ** 53 + 1, 32, 'signed', { + enforceRange: true + }) + }, TypeError) + + t.throws(() => { + ConvertToInt(-(2 ** 53 + 1), 32, 'unsigned', { + enforceRange: true + }) + }, TypeError) + + t.equal( + ConvertToInt(65.5, 64, signedness, { + enforceRange: true + }), + 65 + ) + } + + for (const signedness of ['signed', 'unsigned']) { + t.equal( + ConvertToInt(63.49, 64, signedness, { + clamp: true + }), + 64 + ) + + t.equal( + ConvertToInt(63.51, 64, signedness, { + clamp: true + }), + 64 + ) + + t.equal( + ConvertToInt(-0, 64, signedness, { + clamp: true + }), + 0 + ) + } + + t.equal(ConvertToInt(111, 2, 'signed'), -1) + + t.end() +}) |