diff options
Diffstat (limited to 'test/js/deno/fetch')
| -rw-r--r-- | test/js/deno/fetch/blob.test.ts | 118 | ||||
| -rw-r--r-- | test/js/deno/fetch/body.test.ts | 1 | ||||
| -rw-r--r-- | test/js/deno/fetch/file.test.ts | 124 | ||||
| -rw-r--r-- | test/js/deno/fetch/headers.test.ts | 459 | ||||
| -rw-r--r-- | test/js/deno/fetch/request.test.ts | 59 | ||||
| -rw-r--r-- | test/js/deno/fetch/response.test.ts | 105 |
6 files changed, 865 insertions, 1 deletions
diff --git a/test/js/deno/fetch/blob.test.ts b/test/js/deno/fetch/blob.test.ts new file mode 100644 index 000000000..8c9c7318c --- /dev/null +++ b/test/js/deno/fetch/blob.test.ts @@ -0,0 +1,118 @@ +// Copyright 2018+ the Deno authors. All rights reserved. MIT license. +// https://raw.githubusercontent.com/denoland/deno/main/cli/tests/unit/blob_test.ts +import { assert, assertEquals, assertStringIncludes } from "deno:harness"; +import { concat } from "deno:harness"; +Deno.test(function blobString() { + const b1 = new Blob([ + "Hello World" + ]); + const str = "Test"; + const b2 = new Blob([ + b1, + str + ]); + assertEquals(b2.size, b1.size + str.length); +}); +Deno.test(function blobBuffer() { + const buffer = new ArrayBuffer(12); + const u8 = new Uint8Array(buffer); + const f1 = new Float32Array(buffer); + const b1 = new Blob([ + buffer, + u8 + ]); + assertEquals(b1.size, 2 * u8.length); + const b2 = new Blob([ + b1, + f1 + ]); + assertEquals(b2.size, 3 * u8.length); +}); +Deno.test(function blobSlice() { + const blob = new Blob([ + "Deno", + "Foo" + ]); + const b1 = blob.slice(0, 3, "Text/HTML"); + assert(b1 instanceof Blob); + assertEquals(b1.size, 3); + assertEquals(b1.type, "text/html"); + const b2 = blob.slice(-1, 3); + assertEquals(b2.size, 0); + const b3 = blob.slice(100, 3); + assertEquals(b3.size, 0); + const b4 = blob.slice(0, 10); + assertEquals(b4.size, blob.size); +}); +Deno.test(function blobInvalidType() { + const blob = new Blob([ + "foo" + ], { + type: "\u0521" + }); + assertEquals(blob.type, ""); +}); +Deno.test(function blobShouldNotThrowError() { + let hasThrown = false; + try { + const options1: any = { + ending: "utf8", + hasOwnProperty: "hasOwnProperty" + }; + const options2 = Object.create(null); + new Blob([ + "Hello World" + ], options1); + new Blob([ + "Hello World" + ], options2); + } catch { + hasThrown = true; + } + assertEquals(hasThrown, false); +}); +Deno.test(async function blobText() { + const blob = new Blob([ + "Hello World" + ]); + assertEquals(await blob.text(), "Hello World"); +}); +Deno.test(async function blobStream() { + const blob = new Blob([ + "Hello World" + ]); + const stream = blob.stream(); + assert(stream instanceof ReadableStream); + const reader = stream.getReader(); + let bytes = new Uint8Array(); + const read = async (): Promise<void> =>{ + const { done , value } = await reader.read(); + if (!done && value) { + bytes = concat(bytes, value); + return read(); + } + }; + await read(); + const decoder = new TextDecoder(); + assertEquals(decoder.decode(bytes), "Hello World"); +}); +Deno.test(async function blobArrayBuffer() { + const uint = new Uint8Array([ + 102, + 111, + 111 + ]); + const blob = new Blob([ + uint + ]); + assertEquals(await blob.arrayBuffer(), uint.buffer); +}); +Deno.test(function blobConstructorNameIsBlob() { + const blob = new Blob(); + assertEquals(blob.constructor.name, "Blob"); +}); +Deno.test.ignore(function blobCustomInspectFunction() { + const blob = new Blob(); + assertEquals(Deno.inspect(blob), `Blob { size: 0, type: "" }`); + assertStringIncludes(Deno.inspect(Blob.prototype), "Blob"); +}); diff --git a/test/js/deno/fetch/body.test.ts b/test/js/deno/fetch/body.test.ts index 92ad70c0a..87966bc48 100644 --- a/test/js/deno/fetch/body.test.ts +++ b/test/js/deno/fetch/body.test.ts @@ -1,6 +1,5 @@ // Copyright 2018+ the Deno authors. All rights reserved. MIT license. // https://raw.githubusercontent.com/denoland/deno/main/cli/tests/unit/body_test.ts - import { assert, assertEquals } from "deno:harness"; function buildBody(body: any, headers?: Headers): Body { const stub = new Request("http://foo/", { diff --git a/test/js/deno/fetch/file.test.ts b/test/js/deno/fetch/file.test.ts new file mode 100644 index 000000000..a74cabc64 --- /dev/null +++ b/test/js/deno/fetch/file.test.ts @@ -0,0 +1,124 @@ +// Copyright 2018+ the Deno authors. All rights reserved. MIT license. +// https://raw.githubusercontent.com/denoland/deno/main/cli/tests/unit/file_test.ts +import { assert, assertEquals } from "deno:harness"; +function testFirstArgument(arg1: any[], expectedSize: number) { + const file = new File(arg1, "name"); + assert(file instanceof File); + assertEquals(file.name, "name"); + assertEquals(file.size, expectedSize); + assertEquals(file.type, ""); +} +Deno.test(function fileEmptyFileBits() { + testFirstArgument([], 0); +}); +Deno.test(function fileStringFileBits() { + testFirstArgument([ + "bits" + ], 4); +}); +Deno.test(function fileUnicodeStringFileBits() { + testFirstArgument([ + "𝓽𝓮𝔁𝓽" + ], 16); +}); +Deno.test(function fileStringObjectFileBits() { + testFirstArgument([ + new String("string object") + ], 13); +}); +Deno.test(function fileEmptyBlobFileBits() { + testFirstArgument([ + new Blob() + ], 0); +}); +Deno.test(function fileBlobFileBits() { + testFirstArgument([ + new Blob([ + "bits" + ]) + ], 4); +}); +Deno.test(function fileEmptyFileFileBits() { + testFirstArgument([ + new File([], "world.txt") + ], 0); +}); +Deno.test(function fileFileFileBits() { + testFirstArgument([ + new File([ + "bits" + ], "world.txt") + ], 4); +}); +Deno.test(function fileArrayBufferFileBits() { + testFirstArgument([ + new ArrayBuffer(8) + ], 8); +}); +Deno.test(function fileTypedArrayFileBits() { + testFirstArgument([ + new Uint8Array([ + 0x50, + 0x41, + 0x53, + 0x53 + ]) + ], 4); +}); +Deno.test(function fileVariousFileBits() { + testFirstArgument([ + "bits", + new Blob([ + "bits" + ]), + new Blob(), + new Uint8Array([ + 0x50, + 0x41 + ]), + new Uint16Array([ + 0x5353 + ]), + new Uint32Array([ + 0x53534150 + ]) + ], 16); +}); +Deno.test(function fileNumberInFileBits() { + testFirstArgument([ + 12 + ], 2); +}); +Deno.test(function fileArrayInFileBits() { + testFirstArgument([ + [ + 1, + 2, + 3 + ] + ], 5); +}); +Deno.test(function fileObjectInFileBits() { + testFirstArgument([ + {} + ], 15); +}); +function testSecondArgument(arg2: any, expectedFileName: string) { + const file = new File([ + "bits" + ], arg2); + assert(file instanceof File); + assertEquals(file.name, expectedFileName); +} +Deno.test(function fileUsingFileName() { + testSecondArgument("dummy", "dummy"); +}); +Deno.test(function fileUsingNullFileName() { + testSecondArgument(null, "null"); +}); +Deno.test(function fileUsingNumberFileName() { + testSecondArgument(1, "1"); +}); +Deno.test(function fileUsingEmptyStringFileName() { + testSecondArgument("", ""); +}); diff --git a/test/js/deno/fetch/headers.test.ts b/test/js/deno/fetch/headers.test.ts new file mode 100644 index 000000000..1bac1b93c --- /dev/null +++ b/test/js/deno/fetch/headers.test.ts @@ -0,0 +1,459 @@ +// Copyright 2018+ the Deno authors. All rights reserved. MIT license. +// https://raw.githubusercontent.com/denoland/deno/main/cli/tests/unit/headers_test.ts +import { assert, assertEquals, assertThrows } from "deno:harness"; +const { inspectArgs } = Deno[Deno.internal]; +Deno.test(function headersHasCorrectNameProp() { + assertEquals(Headers.name, "Headers"); +}); +Deno.test(function newHeaderTest() { + new Headers(); + new Headers(undefined); + new Headers({}); + try { + new Headers(null as any); + } catch (e) { + assert(e instanceof TypeError); + } +}); +const headerDict: Record<string, string> = { + name1: "value1", + name2: "value2", + name3: "value3", + name4: undefined as any, + "Content-Type": "value4" +}; +const headerSeq: any[] = []; +for (const [name, value] of Object.entries(headerDict)){ + headerSeq.push([ + name, + value + ]); +} +Deno.test(function newHeaderWithSequence() { + const headers = new Headers(headerSeq); + for (const [name, value] of Object.entries(headerDict)){ + assertEquals(headers.get(name), String(value)); + } + assertEquals(headers.get("length"), null); +}); +Deno.test(function newHeaderWithRecord() { + const headers = new Headers(headerDict); + for (const [name, value] of Object.entries(headerDict)){ + assertEquals(headers.get(name), String(value)); + } +}); +Deno.test(function newHeaderWithHeadersInstance() { + const headers = new Headers(headerDict); + const headers2 = new Headers(headers); + for (const [name, value] of Object.entries(headerDict)){ + assertEquals(headers2.get(name), String(value)); + } +}); +Deno.test(function headerAppendSuccess() { + const headers = new Headers(); + for (const [name, value] of Object.entries(headerDict)){ + headers.append(name, value); + assertEquals(headers.get(name), String(value)); + } +}); +Deno.test(function headerSetSuccess() { + const headers = new Headers(); + for (const [name, value] of Object.entries(headerDict)){ + headers.set(name, value); + assertEquals(headers.get(name), String(value)); + } +}); +Deno.test(function headerHasSuccess() { + const headers = new Headers(headerDict); + for (const name of Object.keys(headerDict)){ + assert(headers.has(name), "headers has name " + name); + assert(!headers.has("nameNotInHeaders"), "headers do not have header: nameNotInHeaders"); + } +}); +Deno.test(function headerDeleteSuccess() { + const headers = new Headers(headerDict); + for (const name of Object.keys(headerDict)){ + assert(headers.has(name), "headers have a header: " + name); + headers.delete(name); + assert(!headers.has(name), "headers do not have anymore a header: " + name); + } +}); +Deno.test(function headerGetSuccess() { + const headers = new Headers(headerDict); + for (const [name, value] of Object.entries(headerDict)){ + assertEquals(headers.get(name), String(value)); + assertEquals(headers.get("nameNotInHeaders"), null); + } +}); +Deno.test(function headerEntriesSuccess() { + const headers = new Headers(headerDict); + const iterators = headers.entries(); + for (const it of iterators){ + const key = it[0]; + const value = it[1]; + assert(headers.has(key)); + assertEquals(value, headers.get(key)); + } +}); +Deno.test(function headerKeysSuccess() { + const headers = new Headers(headerDict); + const iterators = headers.keys(); + for (const it of iterators){ + assert(headers.has(it)); + } +}); +Deno.test(function headerValuesSuccess() { + const headers = new Headers(headerDict); + const iterators = headers.values(); + const entries = headers.entries(); + const values = []; + for (const pair of entries){ + values.push(pair[1]); + } + for (const it of iterators){ + assert(values.includes(it)); + } +}); +const headerEntriesDict: Record<string, string> = { + name1: "value1", + Name2: "value2", + name: "value3", + "content-Type": "value4", + "Content-Typ": "value5", + "Content-Types": "value6" +}; +Deno.test(function headerForEachSuccess() { + const headers = new Headers(headerEntriesDict); + const keys = Object.keys(headerEntriesDict); + keys.forEach((key)=>{ + const value = headerEntriesDict[key]; + const newkey = key.toLowerCase(); + headerEntriesDict[newkey] = value; + }); + let callNum = 0; + headers.forEach((value, key, container)=>{ + assertEquals(headers, container); + assertEquals(value, headerEntriesDict[key]); + callNum++; + }); + assertEquals(callNum, keys.length); +}); +Deno.test(function headerSymbolIteratorSuccess() { + assert(Symbol.iterator in Headers.prototype); + const headers = new Headers(headerEntriesDict); + for (const header of headers){ + const key = header[0]; + const value = header[1]; + assert(headers.has(key)); + assertEquals(value, headers.get(key)); + } +}); +Deno.test(function headerTypesAvailable() { + function newHeaders(): Headers { + return new Headers(); + } + const headers = newHeaders(); + assert(headers instanceof Headers); +}); +Deno.test(function headerIllegalReject() { + let errorCount = 0; + try { + new Headers({ + "He y": "ok" + }); + } catch (_e) { + errorCount++; + } + try { + new Headers({ + "Hé-y": "ok" + }); + } catch (_e) { + errorCount++; + } + try { + new Headers({ + "He-y": "ăk" + }); + } catch (_e) { + errorCount++; + } + const headers = new Headers(); + try { + headers.append("Hé-y", "ok"); + } catch (_e) { + errorCount++; + } + try { + headers.delete("Hé-y"); + } catch (_e) { + errorCount++; + } + try { + headers.get("Hé-y"); + } catch (_e) { + errorCount++; + } + try { + headers.has("Hé-y"); + } catch (_e) { + errorCount++; + } + try { + headers.set("Hé-y", "ok"); + } catch (_e) { + errorCount++; + } + try { + headers.set("", "ok"); + } catch (_e) { + errorCount++; + } + assertEquals(errorCount, 9); + new Headers({ + "He-y": "o k" + }); +}); +Deno.test(function headerParamsShouldThrowTypeError() { + let hasThrown = 0; + try { + new Headers(([ + [ + "1" + ] + ] as unknown) as Array<[string, string]>); + hasThrown = 1; + } catch (err) { + if (err instanceof TypeError) { + hasThrown = 2; + } else { + hasThrown = 3; + } + } + assertEquals(hasThrown, 2); +}); +Deno.test(function headerParamsArgumentsCheck() { + const methodRequireOneParam = [ + "delete", + "get", + "has", + "forEach" + ] as const; + const methodRequireTwoParams = [ + "append", + "set" + ] as const; + methodRequireOneParam.forEach((method)=>{ + const headers = new Headers(); + let hasThrown = 0; + try { + (headers as any)[method](); + hasThrown = 1; + } catch (err) { + if (err instanceof TypeError) { + hasThrown = 2; + } else { + hasThrown = 3; + } + } + assertEquals(hasThrown, 2); + }); + methodRequireTwoParams.forEach((method)=>{ + const headers = new Headers(); + let hasThrown = 0; + try { + (headers as any)[method](); + hasThrown = 1; + } catch (err) { + if (err instanceof TypeError) { + hasThrown = 2; + } else { + hasThrown = 3; + } + } + assertEquals(hasThrown, 2); + hasThrown = 0; + try { + (headers as any)[method]("foo"); + hasThrown = 1; + } catch (err) { + if (err instanceof TypeError) { + hasThrown = 2; + } else { + hasThrown = 3; + } + } + assertEquals(hasThrown, 2); + }); +}); +Deno.test(function headersInitMultiple() { + const headers = new Headers([ + [ + "Set-Cookie", + "foo=bar" + ], + [ + "Set-Cookie", + "bar=baz" + ], + [ + "X-Deno", + "foo" + ], + [ + "X-Deno", + "bar" + ] + ]); + const actual = [ + ...headers + ]; + assertEquals(actual, [ + [ + "set-cookie", + "foo=bar" + ], + [ + "set-cookie", + "bar=baz" + ], + [ + "x-deno", + "foo, bar" + ] + ]); +}); +Deno.test(function headerInitWithPrototypePollution() { + const originalExec = RegExp.prototype.exec; + try { + RegExp.prototype.exec = ()=>{ + throw Error(); + }; + new Headers([ + [ + "X-Deno", + "foo" + ], + [ + "X-Deno", + "bar" + ] + ]); + } finally{ + RegExp.prototype.exec = originalExec; + } +}); +Deno.test(function headersAppendMultiple() { + const headers = new Headers([ + [ + "Set-Cookie", + "foo=bar" + ], + [ + "X-Deno", + "foo" + ] + ]); + headers.append("set-Cookie", "bar=baz"); + headers.append("x-Deno", "bar"); + const actual = [ + ...headers + ]; + assertEquals(actual, [ + [ + "set-cookie", + "foo=bar" + ], + [ + "set-cookie", + "bar=baz" + ], + [ + "x-deno", + "foo, bar" + ] + ]); +}); +Deno.test(function headersAppendDuplicateSetCookieKey() { + const headers = new Headers([ + [ + "Set-Cookie", + "foo=bar" + ] + ]); + headers.append("set-Cookie", "foo=baz"); + headers.append("Set-cookie", "baz=bar"); + const actual = [ + ...headers + ]; + assertEquals(actual, [ + [ + "set-cookie", + "foo=bar" + ], + [ + "set-cookie", + "foo=baz" + ], + [ + "set-cookie", + "baz=bar" + ] + ]); +}); +Deno.test(function headersGetSetCookie() { + const headers = new Headers([ + [ + "Set-Cookie", + "foo=bar" + ], + [ + "set-Cookie", + "bar=qat" + ] + ]); + assertEquals(headers.get("SET-COOKIE"), "foo=bar, bar=qat"); +}); +Deno.test(function toStringShouldBeWebCompatibility() { + const headers = new Headers(); + assertEquals(headers.toString(), "[object Headers]"); +}); +function stringify(...args: unknown[]): string { + return inspectArgs(args).replace(/\n$/, ""); +} +Deno.test.ignore(function customInspectReturnsCorrectHeadersFormat() { + const blankHeaders = new Headers(); + assertEquals(stringify(blankHeaders), "Headers {}"); + const singleHeader = new Headers([ + [ + "Content-Type", + "application/json" + ] + ]); + assertEquals(stringify(singleHeader), `Headers { "content-type": "application/json" }`); + const multiParamHeader = new Headers([ + [ + "Content-Type", + "application/json" + ], + [ + "Content-Length", + "1337" + ] + ]); + assertEquals(stringify(multiParamHeader), `Headers { "content-length": "1337", "content-type": "application/json" }`); +}); +Deno.test(function invalidHeadersFlaky() { + assertThrows(()=>new Headers([ + [ + "x", + "\u0000x" + ] + ]), TypeError, "Header value is not valid."); + assertThrows(()=>new Headers([ + [ + "x", + "\u0000x" + ] + ]), TypeError, "Header value is not valid."); +}); diff --git a/test/js/deno/fetch/request.test.ts b/test/js/deno/fetch/request.test.ts new file mode 100644 index 000000000..d1a444196 --- /dev/null +++ b/test/js/deno/fetch/request.test.ts @@ -0,0 +1,59 @@ +// Copyright 2018+ the Deno authors. All rights reserved. MIT license. +// https://raw.githubusercontent.com/denoland/deno/main/cli/tests/unit/request_test.ts +import { assertEquals, assertStringIncludes } from "deno:harness"; +Deno.test(async function fromInit() { + const req = new Request("http://foo/", { + body: "ahoyhoy", + method: "POST", + headers: { + "test-header": "value" + } + }); + assertEquals("ahoyhoy", await req.text()); + assertEquals(req.url, "http://foo/"); + assertEquals(req.headers.get("test-header"), "value"); +}); +Deno.test(function requestNonString() { + const nonString = { + toString () { + return "http://foo/"; + } + }; + assertEquals(new Request(nonString).url, "http://foo/"); +}); +Deno.test(function methodNonString() { + assertEquals(new Request("http://foo/", { + method: undefined + }).method, "GET"); +}); +Deno.test.ignore(function requestRelativeUrl() { + assertEquals(new Request("relative-url").url, "http://js-unit-tests/foo/relative-url"); +}); +Deno.test(async function cloneRequestBodyStream() { + const stream = new Request("http://foo/", { + body: "a test body", + method: "POST" + }).body; + const r1 = new Request("http://foo/", { + body: stream, + method: "POST" + }); + const r2 = r1.clone(); + const b1 = await r1.text(); + const b2 = await r2.text(); + assertEquals(b1, b2); +}); +Deno.test.ignore(function customInspectFunction() { + const request = new Request("https://example.com"); + assertEquals(Deno.inspect(request), `Request { + bodyUsed: false, + headers: Headers {}, + method: "GET", + redirect: "follow", + url: "https://example.com/" +}`); + assertStringIncludes(Deno.inspect(Request.prototype), "Request"); +}); +Deno.test(function requestConstructorTakeURLObjectAsParameter() { + assertEquals(new Request(new URL("http://foo/")).url, "http://foo/"); +}); diff --git a/test/js/deno/fetch/response.test.ts b/test/js/deno/fetch/response.test.ts new file mode 100644 index 000000000..2e83ed0d8 --- /dev/null +++ b/test/js/deno/fetch/response.test.ts @@ -0,0 +1,105 @@ +// Copyright 2018+ the Deno authors. All rights reserved. MIT license. +// https://raw.githubusercontent.com/denoland/deno/main/cli/tests/unit/response_test.ts +import { assert, assertEquals, assertStringIncludes, assertThrows } from "deno:harness"; +Deno.test(async function responseText() { + const response = new Response("hello world"); + const textPromise = response.text(); + assert(textPromise instanceof Promise); + const text = await textPromise; + assert(typeof text === "string"); + assertEquals(text, "hello world"); +}); +Deno.test(async function responseArrayBuffer() { + const response = new Response(new Uint8Array([ + 1, + 2, + 3 + ])); + const arrayBufferPromise = response.arrayBuffer(); + assert(arrayBufferPromise instanceof Promise); + const arrayBuffer = await arrayBufferPromise; + assert(arrayBuffer instanceof ArrayBuffer); + assertEquals(new Uint8Array(arrayBuffer), new Uint8Array([ + 1, + 2, + 3 + ])); +}); +Deno.test(async function responseJson() { + const response = new Response('{"hello": "world"}'); + const jsonPromise = response.json(); + assert(jsonPromise instanceof Promise); + const json = await jsonPromise; + assert(json instanceof Object); + assertEquals(json, { + hello: "world" + }); +}); +Deno.test(async function responseBlob() { + const response = new Response(new Uint8Array([ + 1, + 2, + 3 + ])); + const blobPromise = response.blob(); + assert(blobPromise instanceof Promise); + const blob = await blobPromise; + assert(blob instanceof Blob); + assertEquals(blob.size, 3); + assertEquals(await blob.arrayBuffer(), new Uint8Array([ + 1, + 2, + 3 + ]).buffer); +}); +Deno.test(async function responseFormData() { + const input = new FormData(); + input.append("hello", "world"); + const response = new Response(input); + const contentType = response.headers.get("content-type")!; + assert(contentType.startsWith("multipart/form-data")); + const formDataPromise = response.formData(); + assert(formDataPromise instanceof Promise); + const formData = await formDataPromise; + assert(formData instanceof FormData); + assertEquals([ + ...formData + ], [ + ...input + ]); +}); +Deno.test(function responseInvalidInit() { + assertThrows(()=>new Response("", 0)); + assertThrows(()=>new Response("", { + status: 0 + })); + assertThrows(()=>new Response("", { + status: null + })); +}); +Deno.test(function responseNullInit() { + const response = new Response("", null); + assertEquals(response.status, 200); +}); +Deno.test.ignore(function customInspectFunction() { + const response = new Response(); + assertEquals(Deno.inspect(response), `Response { + body: null, + bodyUsed: false, + headers: Headers {}, + ok: true, + redirected: false, + status: 200, + statusText: "", + url: "" +}`); + assertStringIncludes(Deno.inspect(Response.prototype), "Response"); +}); +Deno.test(async function responseBodyUsed() { + const response = new Response("body"); + assert(!response.bodyUsed); + await response.text(); + assert(response.bodyUsed); + response.body; + assert(response.bodyUsed); +}); |
