Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change Headers multiple value handling for spec compatibility #429

Merged
merged 2 commits into from Nov 14, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 10 additions & 18 deletions fetch.js
Expand Up @@ -73,41 +73,33 @@
Headers.prototype.append = function(name, value) {
name = normalizeName(name)
value = normalizeValue(value)
var list = this.map[name]
if (!list) {
list = []
this.map[name] = list
}
list.push(value)
var oldValue = this.map[name]
this.map[name] = oldValue ? oldValue+','+value : value
}

Headers.prototype['delete'] = function(name) {
delete this.map[normalizeName(name)]
}

Headers.prototype.get = function(name) {
var values = this.map[normalizeName(name)]
return values ? values[0] : null
}

Headers.prototype.getAll = function(name) {
return this.map[normalizeName(name)] || []
name = normalizeName(name)
return this.has(name) ? this.map[name] : null
}

Headers.prototype.has = function(name) {
return this.map.hasOwnProperty(normalizeName(name))
}

Headers.prototype.set = function(name, value) {
this.map[normalizeName(name)] = [normalizeValue(value)]
this.map[normalizeName(name)] = normalizeValue(value)
}

Headers.prototype.forEach = function(callback, thisArg) {
Object.getOwnPropertyNames(this.map).forEach(function(name) {
this.map[name].forEach(function(value) {
callback.call(thisArg, value, name, this)
}, this)
}, this)
for (var name in this.map) {
if (this.map.hasOwnProperty(name)) {
callback.call(thisArg, this.map[name], name, this)
}
}
}

Headers.prototype.keys = function() {
Expand Down
43 changes: 13 additions & 30 deletions test/test.js
Expand Up @@ -84,7 +84,6 @@ exercise.forEach(function(exerciseMode) {
}

var nativeChrome = /Chrome\//.test(navigator.userAgent) && exerciseMode === 'native'
var nativeFirefox = /Firefox\//.test(navigator.userAgent) && exerciseMode === 'native'
var polyfillFirefox = /Firefox\//.test(navigator.userAgent) && exerciseMode === 'polyfill'

test('resolves promise on 500 error', function() {
Expand Down Expand Up @@ -122,8 +121,8 @@ suite('Headers', function() {
original.append('Content-Type', 'text/html')

var headers = new Headers(original)
assert.deepEqual(['application/json', 'text/plain'], headers.getAll('Accept'))
assert.deepEqual(['text/html'], headers.getAll('Content-Type'))
assert.equal(headers.get('Accept'), 'application/json,text/plain')
assert.equal(headers.get('Content-type'), 'text/html')
})
test('headers are case insensitive', function() {
var headers = new Headers({'Accept': 'application/json'})
Expand All @@ -141,9 +140,7 @@ suite('Headers', function() {
test('appends values to existing header name', function() {
var headers = new Headers({'Accept': 'application/json'})
headers.append('Accept', 'text/plain')
assert.equal(headers.getAll('Accept').length, 2)
assert.equal(headers.getAll('Accept')[0], 'application/json')
assert.equal(headers.getAll('Accept')[1], 'text/plain')
assert.equal(headers.get('Accept'), 'application/json,text/plain')
})
test('sets header name and value', function() {
var headers = new Headers()
Expand All @@ -167,20 +164,10 @@ suite('Headers', function() {
assert.isFalse(headers.has('Content-Type'))
assert.isNull(headers.get('Content-Type'))
})
test('returns list on getAll when header found', function() {
var headers = new Headers({'Content-Type': 'application/json'})
assert.isArray(headers.getAll('Content-Type'))
assert.equal(headers.getAll('Content-Type').length, 1)
assert.equal(headers.getAll('Content-Type')[0], 'application/json')
})
test('returns empty list on getAll when no header found', function() {
var headers = new Headers()
assert.isArray(headers.getAll('Content-Type'))
assert.equal(headers.getAll('Content-Type').length, 0)
})
test('converts field name to string on set and get', function() {
var headers = new Headers()
headers.set(1, 'application/json')
assert.isTrue(headers.has('1'))
assert.equal(headers.get(1), 'application/json')
})
test('converts field value to string on set and get', function() {
Expand All @@ -191,14 +178,14 @@ suite('Headers', function() {
assert.equal(headers.get('X-CSRF-Token'), 'undefined')
})
test('throws TypeError on invalid character in field name', function() {
assert.throws(function() { new Headers({'<Accept>': ['application/json']}) }, TypeError)
assert.throws(function() { new Headers({'Accept:': ['application/json']}) }, TypeError)
assert.throws(function() { new Headers({'<Accept>': 'application/json'}) }, TypeError)
assert.throws(function() { new Headers({'Accept:': 'application/json'}) }, TypeError)
assert.throws(function() {
var headers = new Headers()
headers.set({field: 'value'}, 'application/json')
}, TypeError)
})
featureDependent(test, !nativeFirefox, 'is iterable with forEach', function() {
test('is iterable with forEach', function() {
var headers = new Headers()
headers.append('Accept', 'application/json')
headers.append('Accept', 'text/plain')
Expand All @@ -209,12 +196,11 @@ suite('Headers', function() {
results.push({value: value, key: key, object: object})
})

assert.equal(results.length, 3)
assert.deepEqual({key: 'accept', value: 'application/json', object: headers}, results[0])
assert.deepEqual({key: 'accept', value: 'text/plain', object: headers}, results[1])
assert.deepEqual({key: 'content-type', value: 'text/html', object: headers}, results[2])
assert.equal(results.length, 2)
assert.deepEqual({key: 'accept', value: 'application/json,text/plain', object: headers}, results[0])
assert.deepEqual({key: 'content-type', value: 'text/html', object: headers}, results[1])
})
featureDependent(test, !nativeFirefox, 'forEach accepts second thisArg argument', function() {
test('forEach accepts second thisArg argument', function() {
var headers = new Headers({'Accept': 'application/json'})
var thisArg = 42
headers.forEach(function() {
Expand All @@ -229,7 +215,6 @@ suite('Headers', function() {

var iterator = headers.keys()
assert.deepEqual({done: false, value: 'accept'}, iterator.next())
assert.deepEqual({done: false, value: 'accept'}, iterator.next())
assert.deepEqual({done: false, value: 'content-type'}, iterator.next())
assert.deepEqual({done: true, value: undefined}, iterator.next())
})
Expand All @@ -240,8 +225,7 @@ suite('Headers', function() {
headers.append('Content-Type', 'text/html')

var iterator = headers.values()
assert.deepEqual({done: false, value: 'application/json'}, iterator.next())
assert.deepEqual({done: false, value: 'text/plain'}, iterator.next())
assert.deepEqual({done: false, value: 'application/json,text/plain'}, iterator.next())
assert.deepEqual({done: false, value: 'text/html'}, iterator.next())
assert.deepEqual({done: true, value: undefined}, iterator.next())
})
Expand All @@ -252,8 +236,7 @@ suite('Headers', function() {
headers.append('Content-Type', 'text/html')

var iterator = headers.entries()
assert.deepEqual({done: false, value: ['accept', 'application/json']}, iterator.next())
assert.deepEqual({done: false, value: ['accept', 'text/plain']}, iterator.next())
assert.deepEqual({done: false, value: ['accept', 'application/json,text/plain']}, iterator.next())
assert.deepEqual({done: false, value: ['content-type', 'text/html']}, iterator.next())
assert.deepEqual({done: true, value: undefined}, iterator.next())
})
Expand Down