summaryrefslogtreecommitdiffstats
path: root/test/fetch/iterators.js
diff options
context:
space:
mode:
Diffstat (limited to 'test/fetch/iterators.js')
-rw-r--r--test/fetch/iterators.js140
1 files changed, 140 insertions, 0 deletions
diff --git a/test/fetch/iterators.js b/test/fetch/iterators.js
new file mode 100644
index 0000000..6c6761d
--- /dev/null
+++ b/test/fetch/iterators.js
@@ -0,0 +1,140 @@
+'use strict'
+
+const { test } = require('tap')
+const { Headers, FormData } = require('../..')
+
+test('Implements " Iterator" properly', (t) => {
+ t.test('all Headers iterators implement Headers Iterator', (t) => {
+ const headers = new Headers([['a', 'b'], ['c', 'd']])
+
+ for (const iterable of ['keys', 'values', 'entries', Symbol.iterator]) {
+ const gen = headers[iterable]()
+ // https://tc39.es/ecma262/#sec-%25iteratorprototype%25-object
+ const IteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))
+ const iteratorProto = Object.getPrototypeOf(gen)
+
+ t.ok(gen.constructor === Object)
+ t.ok(gen.prototype === undefined)
+ // eslint-disable-next-line no-proto
+ t.equal(gen.__proto__[Symbol.toStringTag], 'Headers Iterator')
+ // https://github.com/node-fetch/node-fetch/issues/1119#issuecomment-100222049
+ t.notOk(Headers.prototype[iterable] instanceof function * () {}.constructor)
+ // eslint-disable-next-line no-proto
+ t.ok(gen.__proto__.next.__proto__ === Function.prototype)
+ // https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object
+ // "The [[Prototype]] internal slot of an iterator prototype object must be %IteratorPrototype%."
+ t.equal(gen[Symbol.iterator], IteratorPrototype[Symbol.iterator])
+ t.equal(Object.getPrototypeOf(iteratorProto), IteratorPrototype)
+ }
+
+ t.end()
+ })
+
+ t.test('all FormData iterators implement FormData Iterator', (t) => {
+ const fd = new FormData()
+
+ for (const iterable of ['keys', 'values', 'entries', Symbol.iterator]) {
+ const gen = fd[iterable]()
+ // https://tc39.es/ecma262/#sec-%25iteratorprototype%25-object
+ const IteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))
+ const iteratorProto = Object.getPrototypeOf(gen)
+
+ t.ok(gen.constructor === Object)
+ t.ok(gen.prototype === undefined)
+ // eslint-disable-next-line no-proto
+ t.equal(gen.__proto__[Symbol.toStringTag], 'FormData Iterator')
+ // https://github.com/node-fetch/node-fetch/issues/1119#issuecomment-100222049
+ t.notOk(Headers.prototype[iterable] instanceof function * () {}.constructor)
+ // eslint-disable-next-line no-proto
+ t.ok(gen.__proto__.next.__proto__ === Function.prototype)
+ // https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object
+ // "The [[Prototype]] internal slot of an iterator prototype object must be %IteratorPrototype%."
+ t.equal(gen[Symbol.iterator], IteratorPrototype[Symbol.iterator])
+ t.equal(Object.getPrototypeOf(iteratorProto), IteratorPrototype)
+ }
+
+ t.end()
+ })
+
+ t.test('Iterator symbols are properly set', (t) => {
+ t.test('Headers', (t) => {
+ const headers = new Headers([['a', 'b'], ['c', 'd']])
+ const gen = headers.entries()
+
+ t.equal(typeof gen[Symbol.toStringTag], 'string')
+ t.equal(typeof gen[Symbol.iterator], 'function')
+ t.end()
+ })
+
+ t.test('FormData', (t) => {
+ const fd = new FormData()
+ const gen = fd.entries()
+
+ t.equal(typeof gen[Symbol.toStringTag], 'string')
+ t.equal(typeof gen[Symbol.iterator], 'function')
+ t.end()
+ })
+
+ t.end()
+ })
+
+ t.test('Iterator does not inherit Generator prototype methods', (t) => {
+ t.test('Headers', (t) => {
+ const headers = new Headers([['a', 'b'], ['c', 'd']])
+ const gen = headers.entries()
+
+ t.equal(gen.return, undefined)
+ t.equal(gen.throw, undefined)
+ t.equal(typeof gen.next, 'function')
+
+ t.end()
+ })
+
+ t.test('FormData', (t) => {
+ const fd = new FormData()
+ const gen = fd.entries()
+
+ t.equal(gen.return, undefined)
+ t.equal(gen.throw, undefined)
+ t.equal(typeof gen.next, 'function')
+
+ t.end()
+ })
+
+ t.end()
+ })
+
+ t.test('Symbol.iterator', (t) => {
+ // Headers
+ const headerValues = new Headers([['a', 'b']]).entries()[Symbol.iterator]()
+ t.same(Array.from(headerValues), [['a', 'b']])
+
+ // FormData
+ const formdata = new FormData()
+ formdata.set('a', 'b')
+ const formdataValues = formdata.entries()[Symbol.iterator]()
+ t.same(Array.from(formdataValues), [['a', 'b']])
+
+ t.end()
+ })
+
+ t.test('brand check', (t) => {
+ // Headers
+ t.throws(() => {
+ const gen = new Headers().entries()
+ // eslint-disable-next-line no-proto
+ gen.__proto__.next()
+ }, TypeError)
+
+ // FormData
+ t.throws(() => {
+ const gen = new FormData().entries()
+ // eslint-disable-next-line no-proto
+ gen.__proto__.next()
+ }, TypeError)
+
+ t.end()
+ })
+
+ t.end()
+})