summaryrefslogtreecommitdiff
path: root/packages/webapi/test
diff options
context:
space:
mode:
authorGravatar Nate Moore <natemoo-re@users.noreply.github.com> 2022-03-07 15:36:22 -0600
committerGravatar GitHub <noreply@github.com> 2022-03-07 15:36:22 -0600
commitf18ee36dc0abdc5c8ec87734de7962966d16fe65 (patch)
treec01a7034186cb0bbe5e1d042f4a5dd09bad21ed5 /packages/webapi/test
parent10a9c3412b4f6e8607687a74eafdb150d3222047 (diff)
downloadastro-f18ee36dc0abdc5c8ec87734de7962966d16fe65.tar.gz
astro-f18ee36dc0abdc5c8ec87734de7962966d16fe65.tar.zst
astro-f18ee36dc0abdc5c8ec87734de7962966d16fe65.zip
Add `@astrojs/webapi` package (#2729)@astrojs/webapi@0.11.0
* chore: add @astrojs/webapi * chore: update package.json * fix: update file case * fix: remove lowercase file * chore: update tests to use mocha * chore: update LICENSE
Diffstat (limited to 'packages/webapi/test')
-rw-r--r--packages/webapi/test/base64.js48
-rw-r--r--packages/webapi/test/basic.js156
-rw-r--r--packages/webapi/test/characterdata.js59
-rw-r--r--packages/webapi/test/elements.js87
-rw-r--r--packages/webapi/test/fetch.js140
-rw-r--r--packages/webapi/test/imagedata.js84
-rw-r--r--packages/webapi/test/internals.js29
-rw-r--r--packages/webapi/test/media.js31
-rw-r--r--packages/webapi/test/offscreencanvas.js57
-rw-r--r--packages/webapi/test/options.js53
-rw-r--r--packages/webapi/test/storage.js45
-rw-r--r--packages/webapi/test/structuredclone.js40
-rw-r--r--packages/webapi/test/urlpattern.js31
13 files changed, 860 insertions, 0 deletions
diff --git a/packages/webapi/test/base64.js b/packages/webapi/test/base64.js
new file mode 100644
index 000000000..d8ab66426
--- /dev/null
+++ b/packages/webapi/test/base64.js
@@ -0,0 +1,48 @@
+import { assert, test } from '../run/test.setup.js'
+import { polyfill } from '../mod.js'
+
+test(() => {
+ return [
+ {
+ name: 'Supports Base64 Methods',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ assert.equal('atob' in target, true)
+ assert.equal('btoa' in target, true)
+ assert.equal(typeof target['atob'], 'function')
+ assert.equal(typeof target['btoa'], 'function')
+ },
+ },
+ {
+ name: 'Supports atob(data)',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ const a = 'SGVsbG8sIHdvcmxk'
+ const b = target.atob(a)
+
+ assert.equal(a, 'SGVsbG8sIHdvcmxk')
+ assert.equal(b, 'Hello, world')
+ },
+ },
+ {
+ name: 'Supports btoa(data)',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ const b = 'Hello, world'
+ const a = target.btoa(b)
+
+ assert.equal(a, 'SGVsbG8sIHdvcmxk')
+ assert.equal(b, 'Hello, world')
+ },
+ },
+ ]
+})
diff --git a/packages/webapi/test/basic.js b/packages/webapi/test/basic.js
new file mode 100644
index 000000000..02284233c
--- /dev/null
+++ b/packages/webapi/test/basic.js
@@ -0,0 +1,156 @@
+import { assert, test } from '../run/test.setup.js'
+import { polyfill } from '../mod.js'
+
+test(() => {
+ polyfill(globalThis)
+
+ return [
+ {
+ name: 'Globals exist',
+ test() {
+ const webAPIs = [ 'AbortController', 'AbortSignal', 'Blob', 'ByteLengthQueuingStrategy', 'CSSStyleSheet', 'CountQueuingStrategy', 'CustomElementRegistry', 'CustomEvent', 'DOMException', 'Document', 'DocumentFragment', 'Element', 'Event', 'EventTarget', 'File', 'FormData', 'HTMLDocument', 'HTMLElement', 'HTMLDivElement', 'HTMLHeadElement', 'HTMLHtmlElement', 'HTMLImageElement', 'HTMLStyleElement', 'HTMLTemplateElement', 'HTMLUnknownElement', 'Headers', 'IntersectionObserver', 'Image', 'MediaQueryList', 'MutationObserver', 'Node', 'ReadableByteStreamController', 'ReadableStream', 'ReadableStreamBYOBReader', 'ReadableStreamBYOBRequest', 'ReadableStreamDefaultController', 'ReadableStreamDefaultReader', 'Request', 'Response', 'ShadowRoot', 'StyleSheet', 'TransformStream', 'WritableStream', 'WritableStreamDefaultController', 'WritableStreamDefaultWriter', 'Window', 'cancelAnimationFrame', 'cancelIdleCallback', 'clearTimeout', 'fetch', 'requestAnimationFrame', 'requestIdleCallback', 'setTimeout' ]
+
+ for (const name of webAPIs) {
+ assert.equal(typeof globalThis[name], 'function')
+ }
+ },
+ },
+ {
+ name: 'Constructs an Event',
+ test() {
+ const e = new Event('test')
+
+ assert.equal(e.type, 'test')
+ },
+ },
+ {
+ name: 'Constructs an EventTarget',
+ test() {
+ const t = new EventTarget()
+ },
+ },
+ {
+ name: 'Dispatches an Event on an EventTarget',
+ test() {
+ const t = new EventTarget()
+
+ let pass = false
+
+ t.addEventListener('test', (event) => {
+ pass = true
+ })
+
+ const e = new Event('test')
+
+ t.dispatchEvent(e)
+
+ assert.equal(pass, true)
+ },
+ },
+ {
+ name: 'Classes extend as expected',
+ test() {
+ assert.equal(HTMLElement.prototype instanceof Element, true)
+ assert.equal(Element.prototype instanceof Node, true)
+ assert.equal(Node.prototype instanceof EventTarget, true)
+ },
+ },
+ {
+ name: 'DOM Methods have no effect',
+ test() {
+ const element = document.createElement('div')
+
+ assert.equal(element.innerHTML, '')
+ element.innerHTML = 'frozen'
+ assert.equal(element.innerHTML, '')
+
+ assert.equal(element.textContent, '')
+ element.textContent = 'frozen'
+ assert.equal(element.textContent, '')
+ },
+ },
+ {
+ name: 'globalThis.window === globalThis',
+ test() {
+ assert.equal(globalThis.window, globalThis)
+ },
+ },
+ {
+ name: 'Relative Indexing Method (String#at)',
+ test() {
+ assert.equal(typeof String.prototype.at, 'function')
+ assert.equal(String.prototype.at.length, 1)
+
+ const example = 'The quick brown fox jumps over the lazy dog.'
+
+ assert.equal(example.at(2), 'e')
+ assert.equal(example.at(-2), 'g')
+ },
+ },
+ {
+ name: 'Relative Indexing Method (Array#at)',
+ test() {
+ assert.equal(typeof Array.prototype.at, 'function')
+ assert.equal(Array.prototype.at.length, 1)
+
+ const example = [1, 3, 5, 7, 9]
+
+ assert.equal(example.at(1), 3)
+ assert.equal(example.at(-1), 9)
+ },
+ },
+ {
+ name: 'Relative Indexing Method (TypedArray#at)',
+ test() {
+ assert.equal(typeof Int8Array.prototype.at, 'function')
+ assert.equal(Int8Array.prototype.at.length, 1)
+
+ const example = new Int8Array([1, 3, 5, 7, 9])
+
+ assert.equal(example.at(1), 3)
+ assert.equal(example.at(-1), 9)
+ },
+ },
+ {
+ name: 'Object.hasOwn',
+ test() {
+ assert.equal(typeof Object.hasOwn, 'function')
+ assert.equal(Object.hasOwn.length, 2)
+
+ const example = {}
+
+ assert.equal(Object.hasOwn(example, 'prop'), false)
+
+ example.prop = 'exists'
+
+ assert.equal(Object.hasOwn(example, 'prop'), true)
+ },
+ },
+ {
+ name: 'Promise.any',
+ test() {
+ assert.equal(typeof Promise.any, 'function')
+ assert.equal(Promise.any.length, 1)
+
+ Promise.any([Promise.resolve(42), Promise.reject(-1), Promise.reject(Infinity)]).then(
+ result => {
+ assert.equal(result, 42)
+ }
+ )
+ },
+ },
+ {
+ name: 'String#replaceAll',
+ test() {
+ assert.equal(typeof String.prototype.replaceAll, 'function')
+ assert.equal(String.prototype.replaceAll.length, 2)
+
+ const t1 = 'Of all the sorcerers in Harry Potter, Halo is my favorite sorcerer.'
+ const t2 = t1.replaceAll('sorcerer', 'philosopher')
+ const t3 = 'Of all the philosophers in Harry Potter, Halo is my favorite philosopher.'
+
+ assert.equal(t2, t3)
+ },
+ },
+ ]
+})
diff --git a/packages/webapi/test/characterdata.js b/packages/webapi/test/characterdata.js
new file mode 100644
index 000000000..a211586ea
--- /dev/null
+++ b/packages/webapi/test/characterdata.js
@@ -0,0 +1,59 @@
+import { assert, test } from '../run/test.setup.js'
+import { polyfill } from '../mod.js'
+
+test(() => {
+ return [
+ {
+ name: 'Includes CharacterData functionality',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ assert.equal(Reflect.has(target, 'CharacterData'), true)
+ assert.equal(Reflect.has(target, 'Text'), true)
+ assert.equal(Reflect.has(target, 'Comment'), true)
+ },
+ },
+ {
+ name: 'Throws new CharacterData',
+ test() {
+ const target = {}
+
+ polyfill(target)
+ },
+ },
+ {
+ name: 'Supports new Comment',
+ test() {
+ const target = polyfill({})
+
+ assert.doesNotThrow(() => {
+ new target.Comment()
+ })
+
+ assert.equal(new target.Comment().constructor.name, 'Comment')
+ assert.equal(Object.prototype.toString.call(new target.Comment()), '[object Comment]')
+
+ assert.equal(new target.Comment('hello').data, 'hello')
+ assert.equal(new target.Comment('hello').textContent, 'hello')
+ },
+ },
+ {
+ name: 'Supports new Text',
+ test() {
+ const target = polyfill({})
+
+ assert.doesNotThrow(() => {
+ new target.Text()
+ })
+
+ assert.equal(new target.Text().constructor.name, 'Text')
+ assert.equal(Object.prototype.toString.call(new target.Text()), '[object Text]')
+
+ assert.equal(new target.Text('hello').data, 'hello')
+ assert.equal(new target.Text('hello').textContent, 'hello')
+ },
+ },
+ ]
+})
diff --git a/packages/webapi/test/elements.js b/packages/webapi/test/elements.js
new file mode 100644
index 000000000..5d7501592
--- /dev/null
+++ b/packages/webapi/test/elements.js
@@ -0,0 +1,87 @@
+import { assert, test } from '../run/test.setup.js'
+import { polyfill } from '../mod.js'
+
+test(() => {
+ return [
+ {
+ name: 'Includes Custom Element functionality',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ assert.equal(Reflect.has(target, 'CustomElementRegistry'), true)
+ assert.equal(Reflect.has(target, 'customElements'), true)
+ assert.equal(Reflect.has(target, 'HTMLElement'), true)
+ },
+ },
+ {
+ name: 'Supports Custom Element creation',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ const CustomElement = class HTMLCustomElement extends target.HTMLElement {}
+
+ target.customElements.define('custom-element', CustomElement)
+
+ assert.equal(target.customElements.get('custom-element'), CustomElement)
+ assert.equal(target.customElements.getName(CustomElement), 'custom-element')
+ },
+ },
+ {
+ name: 'Supports Custom Elements created from Document',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ assert.equal(target.document.body.localName, 'body')
+ assert.equal(target.document.body.tagName, 'BODY')
+
+ assert.equal(target.document.createElement('custom-element').constructor.name, 'HTMLUnknownElement')
+
+ const CustomElement = class HTMLCustomElement extends target.HTMLElement {}
+
+ target.customElements.define('custom-element', CustomElement)
+
+ assert.equal(target.document.createElement('custom-element').constructor.name, 'HTMLCustomElement')
+ },
+ },
+ {
+ name: 'Supports Custom Elements with properties',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ const testSymbol = Symbol.for('webapi.test')
+
+ const CustomElement = class HTMLCustomElement extends target.HTMLElement {
+ otherMethod = () => testSymbol
+
+ method() {
+ return this.otherMethod()
+ }
+
+ static method() {
+ return this.otherMethod()
+ }
+
+ static otherMethod() {
+ return testSymbol
+ }
+ }
+
+ target.customElements.define('custom-element', CustomElement)
+
+ assert.equal(CustomElement.method(), testSymbol)
+
+ const customElement = new CustomElement()
+
+ assert.equal(customElement.method(), testSymbol)
+ },
+ },
+ ]
+})
diff --git a/packages/webapi/test/fetch.js b/packages/webapi/test/fetch.js
new file mode 100644
index 000000000..08d7c9297
--- /dev/null
+++ b/packages/webapi/test/fetch.js
@@ -0,0 +1,140 @@
+import { assert, test } from '../run/test.setup.js'
+import { polyfill } from '../mod.js'
+
+test(() => {
+ return [
+ {
+ name: 'Fetch functionality',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ assert.equal(Reflect.has(target, 'fetch'), true)
+ assert.equal(typeof target.fetch, 'function')
+ },
+ },
+ {
+ name: 'Fetch with https',
+ async test() {
+ const target = {}
+
+ polyfill(target)
+
+ const { fetch } = target
+
+ const response = await fetch('https://api.openbrewerydb.org/breweries')
+
+ assert.equal(response.constructor, target.Response)
+
+ const json = await response.json()
+
+ assert.equal(Array.isArray(json), true)
+ },
+ },
+ {
+ name: 'Fetch with file',
+ async test() {
+ const target = {}
+
+ polyfill(target)
+
+ const { fetch } = target
+
+ const url = new URL('../package.json', import.meta.url)
+
+ const response = await fetch(url)
+
+ assert.equal(response.constructor, target.Response)
+
+ assert.equal(response.status, 200)
+ assert.equal(response.statusText, '')
+ assert.equal(response.headers.has('date'), true)
+ assert.equal(response.headers.has('content-length'), true)
+ assert.equal(response.headers.has('last-modified'), true)
+
+ const json = await response.json()
+
+ assert.equal(json.name, '@astrojs/webapi')
+ },
+ },
+ {
+ name: 'Fetch with missing file',
+ async test() {
+ const target = {}
+
+ polyfill(target)
+
+ const { fetch } = target
+
+ const url = new URL('../missing.json', import.meta.url)
+
+ const response = await fetch(url)
+
+ assert.equal(response.constructor, target.Response)
+
+ assert.equal(response.status, 404)
+ assert.equal(response.statusText, '')
+ assert.equal(response.headers.has('date'), true)
+ assert.equal(response.headers.has('content-length'), false)
+ assert.equal(response.headers.has('last-modified'), false)
+ },
+ },
+ {
+ name: 'Fetch with (file) Request',
+ async test() {
+ const target = {}
+
+ polyfill(target)
+
+ const { Request, fetch } = target
+
+ const request = new Request(new URL('../package.json', import.meta.url))
+
+ const response = await fetch(request)
+
+ assert.equal(response.constructor, target.Response)
+
+ const json = await response.json()
+
+ assert.equal(json.name, '@astrojs/webapi')
+ },
+ },
+ {
+ name: 'Fetch with relative file',
+ async test() {
+ const target = {}
+
+ polyfill(target)
+
+ const { fetch } = target
+
+ const response = await fetch('package.json')
+
+ const json = await response.json()
+
+ assert.equal(json.name, '@astrojs/webapi')
+ },
+ },
+ {
+ name: 'Fetch with data',
+ async test() {
+ const target = {}
+
+ polyfill(target)
+
+ const { fetch } = target
+
+ const jsonURI = `data:application/json,${encodeURIComponent(JSON.stringify({
+ name: '@astrojs/webapi'
+ }))}`
+
+ const response = await fetch(jsonURI)
+
+ const json = await response.json()
+
+ assert.equal(json.name, '@astrojs/webapi')
+ },
+ },
+ ]
+})
diff --git a/packages/webapi/test/imagedata.js b/packages/webapi/test/imagedata.js
new file mode 100644
index 000000000..d4a542117
--- /dev/null
+++ b/packages/webapi/test/imagedata.js
@@ -0,0 +1,84 @@
+import { assert, test } from '../run/test.setup.js'
+import { polyfill } from '../mod.js'
+
+test(() => {
+ return [
+ {
+ name: 'Supports ImageData',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ assert.equal('ImageData' in target, true)
+ assert.equal(typeof target['ImageData'], 'function')
+ },
+ },
+ {
+ name: 'Supports new (data: Uint8ClampedArray, width: number, height: number): ImageData',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ const w = 640
+ const h = 480
+ const d = new Uint8ClampedArray(w * h * 4)
+
+ const id = new target.ImageData(d, w, h)
+
+ assert.equal(id.data, d)
+ assert.equal(id.width, w)
+ assert.equal(id.height, h)
+ },
+ },
+ {
+ name: 'Supports new (data: Uint8ClampedArray, width: number): ImageData',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ const w = 640
+ const h = 480
+ const d = new Uint8ClampedArray(w * h * 4)
+
+ const id = new target.ImageData(d, w)
+
+ assert.equal(id.data, d)
+ assert.equal(id.width, w)
+ assert.equal(id.height, h)
+ },
+ },
+ {
+ name: 'Supports new (width: number, height: number): ImageData',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ const w = 640
+ const h = 480
+
+ const id = new target.ImageData(w, h)
+
+ assert.equal(id.data.length, w * h * 4)
+ assert.equal(id.width, w)
+ assert.equal(id.height, h)
+ },
+ },
+ {
+ name: 'Supports Object.keys(new ImageData(640, 480))',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ const keys = Object.keys(new target.ImageData(640, 480))
+
+ assert.equal(keys.length, 1)
+ assert.equal(keys[0], 'data')
+ },
+ },
+ ]
+})
diff --git a/packages/webapi/test/internals.js b/packages/webapi/test/internals.js
new file mode 100644
index 000000000..84f918fb6
--- /dev/null
+++ b/packages/webapi/test/internals.js
@@ -0,0 +1,29 @@
+import { assert, test } from '../run/test.setup.js'
+import { polyfill } from '../mod.js'
+
+test(() => {
+ return [
+ {
+ name: 'Includes polyfill.internals functionality',
+ test() {
+ const target = {}
+
+ polyfill(target, { exclude: 'window document' })
+
+ const pseudo = { ...target }
+
+ assert.equal(Reflect.has(pseudo, 'document'), false)
+
+ const CustomElement = class extends pseudo.HTMLElement {}
+
+ pseudo.customElements.define('custom-element', CustomElement)
+
+ polyfill.internals(pseudo, 'Document')
+
+ assert.equal(Reflect.has(pseudo, 'document'), true)
+
+ assert.equal(CustomElement.prototype.isPrototypeOf(pseudo.document.createElement('custom-element')), true)
+ },
+ }
+ ]
+})
diff --git a/packages/webapi/test/media.js b/packages/webapi/test/media.js
new file mode 100644
index 000000000..74f6f42ce
--- /dev/null
+++ b/packages/webapi/test/media.js
@@ -0,0 +1,31 @@
+import { assert, test } from '../run/test.setup.js'
+import { polyfill } from '../mod.js'
+
+test(() => {
+ return [
+ {
+ name: 'Includes MediaQueryList functionality',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ assert.equal(Reflect.has(target, 'MediaQueryList'), true)
+ assert.equal(Reflect.has(target, 'matchMedia'), true)
+ },
+ },
+ {
+ name: 'Supports matchMedia creation',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ const mql = target.matchMedia('(min-width: 640px)')
+
+ assert.equal(mql.matches, false)
+ assert.equal(mql.media, '(min-width: 640px)')
+ },
+ },
+ ]
+})
diff --git a/packages/webapi/test/offscreencanvas.js b/packages/webapi/test/offscreencanvas.js
new file mode 100644
index 000000000..d4e863142
--- /dev/null
+++ b/packages/webapi/test/offscreencanvas.js
@@ -0,0 +1,57 @@
+import { assert, test } from '../run/test.setup.js'
+import { polyfill } from '../mod.js'
+
+test(() => {
+ return [
+ {
+ name: 'Supports OffscreenCanvas',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ assert.equal('OffscreenCanvas' in target, true)
+ assert.equal(typeof target['OffscreenCanvas'], 'function')
+ },
+ },
+ {
+ name: 'Supports new (width: number, height: number): OffscreenCanvas',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ const w = 640
+ const h = 480
+
+ const canvas = new target.OffscreenCanvas(w, h)
+
+ assert.equal(canvas.width, w)
+ assert.equal(canvas.height, h)
+ },
+ },
+ {
+ name: 'Supports OffscreenCanvas#getContext',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ const w = 640
+ const h = 480
+
+ const canvas = new target.OffscreenCanvas(w, h)
+
+ const context = canvas.getContext('2d')
+
+ assert.equal(context.canvas, canvas)
+
+ const imageData = context.createImageData(w, h)
+
+ assert.equal(imageData.width, w)
+ assert.equal(imageData.height, h)
+ assert.equal(imageData.data.length, w * h * 4)
+ },
+ },
+ ]
+})
diff --git a/packages/webapi/test/options.js b/packages/webapi/test/options.js
new file mode 100644
index 000000000..4b375fc82
--- /dev/null
+++ b/packages/webapi/test/options.js
@@ -0,0 +1,53 @@
+import { assert, test } from '../run/test.setup.js'
+import { polyfill } from '../mod.js'
+
+test(() => {
+ return [
+ {
+ name: 'Can exclude HTMLElement+',
+ test() {
+ const target = {}
+
+ polyfill(target, {
+ exclude: 'HTMLElement+'
+ })
+
+ assert.equal(Reflect.has(target, 'Event'), true)
+ assert.equal(Reflect.has(target, 'EventTarget'), true)
+ assert.equal(Reflect.has(target, 'Element'), true)
+ assert.equal(Reflect.has(target, 'HTMLElement'), false)
+ assert.equal(Reflect.has(target, 'HTMLDivElement'), false)
+ },
+ },
+ {
+ name: 'Can exclude Event+',
+ test() {
+ const target = {}
+
+ polyfill(target, {
+ exclude: 'Event+'
+ })
+
+ assert.equal(Reflect.has(target, 'Event'), false)
+ assert.equal(Reflect.has(target, 'EventTarget'), false)
+ assert.equal(Reflect.has(target, 'Element'), false)
+ assert.equal(Reflect.has(target, 'HTMLElement'), false)
+ assert.equal(Reflect.has(target, 'HTMLDivElement'), false)
+ },
+ },
+ {
+ name: 'Can exclude document',
+ test() {
+ const target = {}
+
+ polyfill(target, {
+ exclude: 'document'
+ })
+
+ assert.equal(Reflect.has(target, 'Document'), true)
+ assert.equal(Reflect.has(target, 'HTMLDocument'), true)
+ assert.equal(Reflect.has(target, 'document'), false)
+ },
+ },
+ ]
+})
diff --git a/packages/webapi/test/storage.js b/packages/webapi/test/storage.js
new file mode 100644
index 000000000..b8a6d2354
--- /dev/null
+++ b/packages/webapi/test/storage.js
@@ -0,0 +1,45 @@
+import { assert, test } from '../run/test.setup.js'
+import { polyfill } from '../mod.js'
+
+test(() => {
+ return [
+ {
+ name: 'Includes Storage functionality',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ assert.equal(Reflect.has(target, 'Storage'), true)
+ assert.equal(Reflect.has(target, 'localStorage'), true)
+ assert.equal(typeof target.Storage, 'function')
+ assert.equal(typeof target.localStorage, 'object')
+ },
+ },
+ {
+ name: 'Supports Storage methods',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ assert.equal(target.localStorage.setItem('hello', 'world'), undefined)
+ assert.equal(target.localStorage.getItem('hello'), 'world')
+ assert.equal(target.localStorage.key(0), 'hello')
+ assert.equal(target.localStorage.key(1), null)
+ assert.equal(target.localStorage.length, 1)
+ assert.equal(target.localStorage.setItem('world', 'hello'), undefined)
+ assert.equal(target.localStorage.key(1), 'world')
+ assert.equal(target.localStorage.key(2), null)
+ assert.equal(target.localStorage.length, 2)
+ assert.equal(target.localStorage.removeItem('hello'), undefined)
+ assert.equal(target.localStorage.key(0), 'world')
+ assert.equal(target.localStorage.key(1), null)
+ assert.equal(target.localStorage.length, 1)
+ assert.equal(target.localStorage.clear(), undefined)
+ assert.equal(target.localStorage.key(0), null)
+ assert.equal(target.localStorage.length, 0)
+ },
+ },
+ ]
+})
diff --git a/packages/webapi/test/structuredclone.js b/packages/webapi/test/structuredclone.js
new file mode 100644
index 000000000..6605f1f58
--- /dev/null
+++ b/packages/webapi/test/structuredclone.js
@@ -0,0 +1,40 @@
+import { assert, test } from '../run/test.setup.js'
+import { polyfill } from '../mod.js'
+
+test(() => {
+ return [
+ {
+ name: 'Includes structuredClone',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ assert.equal(Reflect.has(target, 'structuredClone'), true)
+ assert.equal(typeof target.structuredClone, 'function')
+ },
+ },
+ {
+ name: 'Supports structuredClone usage',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ const obj = {
+ foo: "bar",
+ baz: {
+ qux: "quux",
+ },
+ }
+
+ const clone = target.structuredClone(obj)
+
+ assert.notEqual(obj, clone)
+ assert.notEqual(obj.baz, clone.baz)
+
+ assert.equal(obj.baz.qux, clone.baz.qux)
+ },
+ },
+ ]
+})
diff --git a/packages/webapi/test/urlpattern.js b/packages/webapi/test/urlpattern.js
new file mode 100644
index 000000000..cc74d7738
--- /dev/null
+++ b/packages/webapi/test/urlpattern.js
@@ -0,0 +1,31 @@
+import { assert, test } from '../run/test.setup.js'
+import { polyfill } from '../mod.js'
+
+test(() => {
+ return [
+ {
+ name: 'Includes URLPattern',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ assert.equal(Reflect.has(target, 'URLPattern'), true)
+ assert.equal(typeof target.URLPattern, 'function')
+ },
+ },
+ {
+ name: 'Supports URLPattern usage',
+ test() {
+ const target = {}
+
+ polyfill(target)
+
+ const pattern = new target.URLPattern({ pathname: '/hello/:name' })
+ const match = pattern.exec('https://example.com/hello/Deno')
+
+ assert.deepEqual(match.pathname.groups, { name: 'Deno' })
+ },
+ },
+ ]
+})