提交 a8695f95 编写于 作者: M Mislav Marohnić

Merge branch 'array-buffer'

...@@ -184,12 +184,24 @@ ...@@ -184,12 +184,24 @@
return fileReaderReady(reader) return fileReaderReady(reader)
} }
function bufferClone(buf) {
if (buf.slice) {
return buf.slice(0)
} else {
var view = new Uint8Array(buf.byteLength)
view.set(new Uint8Array(buf))
return view.buffer
}
}
function Body() { function Body() {
this.bodyUsed = false this.bodyUsed = false
this._initBody = function(body) { this._initBody = function(body) {
this._bodyInit = body this._bodyInit = body
if (typeof body === 'string') { if (!body) {
this._bodyText = ''
} else if (typeof body === 'string') {
this._bodyText = body this._bodyText = body
} else if (support.blob && Blob.prototype.isPrototypeOf(body)) { } else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
this._bodyBlob = body this._bodyBlob = body
...@@ -197,14 +209,12 @@ ...@@ -197,14 +209,12 @@
this._bodyFormData = body this._bodyFormData = body
} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) { } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
this._bodyText = body.toString() this._bodyText = body.toString()
} else if (!body) {
this._bodyText = ''
} else if (support.arrayBuffer && support.blob && isDataView(body)) { } else if (support.arrayBuffer && support.blob && isDataView(body)) {
this._bodyArrayBuffer = bufferClone(body.buffer)
// IE 10-11 can't handle a DataView body. // IE 10-11 can't handle a DataView body.
this._bodyInit = new Blob([body.buffer]) this._bodyInit = new Blob([this._bodyArrayBuffer])
} else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) { } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {
// Only support ArrayBuffers for POST method. this._bodyArrayBuffer = bufferClone(body)
// Receiving ArrayBuffers happens via Blobs, instead.
} else { } else {
throw new Error('unsupported BodyInit type') throw new Error('unsupported BodyInit type')
} }
...@@ -229,36 +239,43 @@ ...@@ -229,36 +239,43 @@
if (this._bodyBlob) { if (this._bodyBlob) {
return Promise.resolve(this._bodyBlob) return Promise.resolve(this._bodyBlob)
} else if (this._bodyArrayBuffer) {
return Promise.resolve(new Blob([this._bodyArrayBuffer]))
} else if (this._bodyFormData) { } else if (this._bodyFormData) {
throw new Error('could not read FormData body as blob') throw new Error('could not read FormData body as blob')
} else { } else {
return Promise.resolve(new Blob([this._bodyText])) return Promise.resolve(new Blob([this._bodyText]))
} }
} }
}
this.arrayBuffer = function() { this.text = function() {
return this.blob().then(readBlobAsArrayBuffer) var rejected = consumed(this)
if (rejected) {
return rejected
} }
this.text = function() { if (this._bodyBlob) {
var rejected = consumed(this) return readBlobAsText(this._bodyBlob)
if (rejected) { } else if (this._bodyArrayBuffer) {
return rejected var view = new Uint8Array(this._bodyArrayBuffer)
} var str = String.fromCharCode.apply(null, view)
return Promise.resolve(str)
} else if (this._bodyFormData) {
throw new Error('could not read FormData body as text')
} else {
return Promise.resolve(this._bodyText)
}
}
if (this._bodyBlob) { if (support.arrayBuffer) {
return readBlobAsText(this._bodyBlob) this.arrayBuffer = function() {
} else if (this._bodyFormData) { if (this._bodyArrayBuffer) {
throw new Error('could not read FormData body as text') return consumed(this) || Promise.resolve(this._bodyArrayBuffer)
} else { } else {
return Promise.resolve(this._bodyText) return this.blob().then(readBlobAsArrayBuffer)
} }
} }
} else {
this.text = function() {
var rejected = consumed(this)
return rejected ? rejected : Promise.resolve(this._bodyText)
}
} }
if (support.formData) { if (support.formData) {
......
...@@ -63,6 +63,10 @@ function arrayBufferFromText(text) { ...@@ -63,6 +63,10 @@ function arrayBufferFromText(text) {
return buf return buf
} }
function readArrayBufferAsText(buf) {
return String.fromCharCode.apply(null, new Uint8Array(buf))
}
var native = {} var native = {}
var keepGlobals = ['fetch', 'Headers', 'Request', 'Response'] var keepGlobals = ['fetch', 'Headers', 'Request', 'Response']
var exercise = ['polyfill'] var exercise = ['polyfill']
...@@ -97,6 +101,51 @@ exercise.forEach(function(exerciseMode) { ...@@ -97,6 +101,51 @@ exercise.forEach(function(exerciseMode) {
var nativeFirefox = /Firefox\//.test(navigator.userAgent) && exerciseMode === 'native' var nativeFirefox = /Firefox\//.test(navigator.userAgent) && exerciseMode === 'native'
var polyfillFirefox = /Firefox\//.test(navigator.userAgent) && exerciseMode === 'polyfill' var polyfillFirefox = /Firefox\//.test(navigator.userAgent) && exerciseMode === 'polyfill'
// https://fetch.spec.whatwg.org/#concept-bodyinit-extract
function testBodyExtract(factory) {
suite('body extract', function() {
var expected = 'Hello World!'
var inputs = [['type USVString', expected]]
if (support.blob) {
inputs.push(['type Blob', new Blob([expected])])
}
if (support.arrayBuffer) {
inputs = inputs.concat([
['type ArrayBuffer', arrayBufferFromText(expected)],
['type TypedArray', new Uint8Array(arrayBufferFromText(expected))],
['type DataView', new DataView(arrayBufferFromText(expected))],
])
}
inputs.forEach(function(input) {
var typeLabel = input[0], body = input[1]
suite(typeLabel, function() {
featureDependent(test, support.blob, 'consume as blob', function() {
var r = factory(body)
return r.blob().then(readBlobAsText).then(function(text) {
assert.equal(text, expected)
})
})
test('consume as text', function() {
var r = factory(body)
return r.text().then(function(text) {
assert.equal(text, expected)
})
})
featureDependent(test, support.arrayBuffer, 'consume as array buffer', function() {
var r = factory(body)
return r.arrayBuffer().then(readArrayBufferAsText).then(function(text) {
assert.equal(text, expected)
})
})
})
})
})
}
// https://fetch.spec.whatwg.org/#headers-class // https://fetch.spec.whatwg.org/#headers-class
suite('Headers', function() { suite('Headers', function() {
test('constructor copies headers', function() { test('constructor copies headers', function() {
...@@ -426,39 +475,8 @@ suite('Request', function() { ...@@ -426,39 +475,8 @@ suite('Request', function() {
}) })
}) })
// https://fetch.spec.whatwg.org/#concept-bodyinit-extract testBodyExtract(function(body) {
suite('BodyInit extract', function() { return new Request('', { method: 'POST', body: body })
featureDependent(suite, support.blob, 'type Blob', function() {
test('consume as blob', function() {
var request = new Request('', {method: 'POST', body: new Blob(['hello'])})
return request.blob().then(readBlobAsText).then(function(text) {
assert.equal(text, 'hello')
})
})
test('consume as text', function() {
var request = new Request('', {method: 'POST', body: new Blob(['hello'])})
return request.text().then(function(text) {
assert.equal(text, 'hello')
})
})
})
suite('type USVString', function() {
test('consume as text', function() {
var request = new Request('', {method: 'POST', body: 'hello'})
return request.text().then(function(text) {
assert.equal(text, 'hello')
})
})
featureDependent(test, support.blob, 'consume as blob', function() {
var request = new Request('', {method: 'POST', body: 'hello'})
return request.blob().then(readBlobAsText).then(function(text) {
assert.equal(text, 'hello')
})
})
})
}) })
}) })
...@@ -471,39 +489,8 @@ suite('Response', function() { ...@@ -471,39 +489,8 @@ suite('Response', function() {
assert.isTrue(res.ok) assert.isTrue(res.ok)
}) })
// https://fetch.spec.whatwg.org/#concept-bodyinit-extract testBodyExtract(function(body) {
suite('BodyInit extract', function() { return new Response(body)
featureDependent(suite, support.blob, 'type Blob', function() {
test('consume as blob', function() {
var response = new Response(new Blob(['hello']))
return response.blob().then(readBlobAsText).then(function(text) {
assert.equal(text, 'hello')
})
})
test('consume as text', function() {
var response = new Response(new Blob(['hello']))
return response.text().then(function(text) {
assert.equal(text, 'hello')
})
})
})
suite('type USVString', function() {
test('consume as text', function() {
var response = new Response('hello')
return response.text().then(function(text) {
assert.equal(text, 'hello')
})
})
featureDependent(test, support.blob, 'consume as blob', function() {
var response = new Response('hello')
return response.blob().then(readBlobAsText).then(function(text) {
assert.equal(text, 'hello')
})
})
})
}) })
test('creates Headers object from raw headers', function() { test('creates Headers object from raw headers', function() {
...@@ -943,19 +930,6 @@ suite('fetch method', function() { ...@@ -943,19 +930,6 @@ suite('fetch method', function() {
assert.equal(response.headers.get('Content-Type'), 'text/html; charset=utf-8') assert.equal(response.headers.get('Content-Type'), 'text/html; charset=utf-8')
}) })
}) })
featureDependent(test, support.blob, 'handles binary', function() {
return fetch('/binary').then(function(response) {
return response.arrayBuffer()
}).then(function(buf) {
assert(buf instanceof ArrayBuffer, 'buf is an ArrayBuffer instance')
assert.equal(buf.byteLength, 256, 'buf.byteLength is correct')
var view = new Uint8Array(buf)
for (var i = 0; i < 256; i++) {
assert.equal(view[i], i)
}
})
})
}) })
// https://fetch.spec.whatwg.org/#methods // https://fetch.spec.whatwg.org/#methods
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册