summaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
authorztplz <mysticzt@gmail.com>2018-10-20 00:12:36 +0800
committerRyan Dahl <ry@tinyclouds.org>2018-10-19 12:12:36 -0400
commit7210e7b33b84382d4f418ab1be37fea85c2e1422 (patch)
treef7dcb6d486d3b451fc12c3357ff2e48e4dde3ab0 /js
parent198fa31ec150b069dca39b94b2049d3ff65213e9 (diff)
Make fetch header compliant with the current spec (#1019)
Diffstat (limited to 'js')
-rw-r--r--js/dom_types.ts17
-rw-r--r--js/fetch.ts22
-rw-r--r--js/fetch_test.ts46
-rw-r--r--js/unit_tests.ts1
-rw-r--r--js/util.ts19
-rw-r--r--js/util_test.ts26
6 files changed, 130 insertions, 1 deletions
diff --git a/js/dom_types.ts b/js/dom_types.ts
index 47af2b17c..71881773d 100644
--- a/js/dom_types.ts
+++ b/js/dom_types.ts
@@ -296,6 +296,11 @@ export interface Headers {
append(name: string, value: string): void;
/** Deletes a header from a `Headers` object. */
delete(name: string): void;
+ /** Returns an iterator allowing to go through all key/value pairs
+ * contained in this Headers object. The both the key and value of each pairs
+ * are ByteString objects.
+ */
+ entries(): IterableIterator<[string, string]>;
/** Returns a `ByteString` sequence of all the values of a header within a
* `Headers` object with a given name.
*/
@@ -304,15 +309,27 @@ export interface Headers {
* header.
*/
has(name: string): boolean;
+ /** Returns an iterator allowing to go through all keys contained in
+ * this Headers object. The keys are ByteString objects.
+ */
+ keys(): IterableIterator<string>;
/** Sets a new value for an existing header inside a Headers object, or adds
* the header if it does not already exist.
*/
set(name: string, value: string): void;
+ /** Returns an iterator allowing to go through all values contained in
+ * this Headers object. The values are ByteString objects.
+ */
+ values(): IterableIterator<string>;
forEach(
callbackfn: (value: string, key: string, parent: Headers) => void,
// tslint:disable-next-line:no-any
thisArg?: any
): void;
+ /** The Symbol.iterator well-known symbol specifies the default
+ * iterator for this Headers object
+ */
+ [Symbol.iterator](): IterableIterator<[string, string]>;
}
type RequestCache =
diff --git a/js/fetch.ts b/js/fetch.ts
index ae62c576d..eef149e4d 100644
--- a/js/fetch.ts
+++ b/js/fetch.ts
@@ -5,7 +5,8 @@ import {
createResolvable,
Resolvable,
typedArrayToArrayBuffer,
- notImplemented
+ notImplemented,
+ CreateIterableIterator
} from "./util";
import * as flatbuffers from "./flatbuffers";
import { sendAsync } from "./dispatch";
@@ -70,6 +71,11 @@ export class DenoHeaders implements domTypes.Headers {
this.headerMap.delete(newname);
}
+ entries(): IterableIterator<[string, string]> {
+ const iterators = this.headerMap.entries();
+ return new CreateIterableIterator(iterators);
+ }
+
get(name: string): string | null {
const [newname] = this.normalizeParams(name);
const value = this.headerMap.get(newname);
@@ -81,11 +87,21 @@ export class DenoHeaders implements domTypes.Headers {
return this.headerMap.has(newname);
}
+ keys(): IterableIterator<string> {
+ const iterators = this.headerMap.keys();
+ return new CreateIterableIterator(iterators);
+ }
+
set(name: string, value: string): void {
const [newname, newvalue] = this.normalizeParams(name, value);
this.headerMap.set(newname, newvalue);
}
+ values(): IterableIterator<string> {
+ const iterators = this.headerMap.values();
+ return new CreateIterableIterator(iterators);
+ }
+
forEach(
callbackfn: (value: string, key: string, parent: domTypes.Headers) => void,
// tslint:disable-next-line:no-any
@@ -95,6 +111,10 @@ export class DenoHeaders implements domTypes.Headers {
callbackfn(value, name, this);
});
}
+
+ [Symbol.iterator](): IterableIterator<[string, string]> {
+ return this.entries();
+ }
}
class FetchResponse implements domTypes.Response {
diff --git a/js/fetch_test.ts b/js/fetch_test.ts
index 7e2177350..2ef58f273 100644
--- a/js/fetch_test.ts
+++ b/js/fetch_test.ts
@@ -147,6 +147,41 @@ test(function headerGetSuccess() {
}
});
+test(function headerEntriesSuccess() {
+ const headers = new Headers(headerDict);
+ const iterators = headers.entries();
+ assertEqual(Object.prototype.toString.call(iterators), "[object Iterator]");
+ for (const it of iterators) {
+ const key = it[0];
+ const value = it[1];
+ assert(headers.has(key));
+ assertEqual(value, headers.get(key));
+ }
+});
+
+test(function headerKeysSuccess() {
+ const headers = new Headers(headerDict);
+ const iterators = headers.keys();
+ assertEqual(Object.prototype.toString.call(iterators), "[object Iterator]");
+ for (const it of iterators) {
+ assert(headers.has(it));
+ }
+});
+
+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]);
+ }
+ assertEqual(Object.prototype.toString.call(iterators), "[object Iterator]");
+ for (const it of iterators) {
+ assert(values.includes(it));
+ }
+});
+
const headerEntriesDict = {
name1: "value1",
Name2: "value2",
@@ -172,3 +207,14 @@ test(function headerForEachSuccess() {
});
assertEqual(callNum, keys.length);
});
+
+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));
+ assertEqual(value, headers.get(key));
+ }
+});
diff --git a/js/unit_tests.ts b/js/unit_tests.ts
index e09d0aba0..9af603dfc 100644
--- a/js/unit_tests.ts
+++ b/js/unit_tests.ts
@@ -27,3 +27,4 @@ import "./truncate_test.ts";
import "./v8_source_maps_test.ts";
import "../website/app_test.js";
import "./metrics_test.ts";
+import "./util_test.ts";
diff --git a/js/util.ts b/js/util.ts
index 0c50acebb..0d2049842 100644
--- a/js/util.ts
+++ b/js/util.ts
@@ -125,3 +125,22 @@ export function deferred(): Deferred {
reject: reject!
};
}
+
+/** Create a IterableIterator. */
+// @internal
+export class CreateIterableIterator<T> implements IterableIterator<T> {
+ private readonly _iterators: IterableIterator<T>;
+ readonly [Symbol.toStringTag] = "Iterator";
+
+ constructor(iterators: IterableIterator<T>) {
+ this._iterators = iterators;
+ }
+
+ [Symbol.iterator](): IterableIterator<T> {
+ return this;
+ }
+
+ next(): IteratorResult<T> {
+ return this._iterators.next();
+ }
+}
diff --git a/js/util_test.ts b/js/util_test.ts
new file mode 100644
index 000000000..b7111fd0d
--- /dev/null
+++ b/js/util_test.ts
@@ -0,0 +1,26 @@
+// Copyright 2018 the Deno authors. All rights reserved. MIT license.
+import { test, assert, assertEqual } from "./test_util.ts";
+import { CreateIterableIterator } from "./util";
+
+test(function CreateIterableIteratorSuccess() {
+ const list = [1, 2, 3, 4, 5];
+ const listIterators = new CreateIterableIterator(list.values());
+ let idx = 0;
+ for (const it of listIterators) {
+ assertEqual(it, list[idx++]);
+ }
+ const obj = {
+ a: "foo",
+ b: "bar",
+ c: "baz"
+ };
+ const list1 = [];
+ const keys = Object.keys(obj);
+ keys.forEach(key => list1.push([key, obj[key]]));
+ const objectIterators = new CreateIterableIterator(list1.values());
+ for (const it of objectIterators) {
+ const [key, value] = it;
+ assert(key in obj);
+ assertEqual(value, obj[key]);
+ }
+}); \ No newline at end of file