diff --git a/fetch.js b/fetch.js index 292b8b74..9c3ead5c 100644 --- a/fetch.js +++ b/fetch.js @@ -74,7 +74,7 @@ } this.formData = function() { - throw new Error('Not implemented yet') + return Promise.resolve(decode(this.body)) } this.json = function() { @@ -115,6 +115,19 @@ }).join('&').replace(/%20/g, '+') } + function decode(body) { + var form = new FormData() + body.trim().split('&').forEach(function(bytes) { + if (bytes) { + var split = bytes.split('=') + var name = split.shift().replace(/\+/g, ' ') + var value = split.join('=').replace(/\+/g, ' ') + form.append(decodeURIComponent(name), decodeURIComponent(value)) + } + }) + return form + } + function isObject(value) { try { return Object.getPrototypeOf(value) === Object.prototype diff --git a/test/test.js b/test/test.js index bac16ac5..75d173d2 100644 --- a/test/test.js +++ b/test/test.js @@ -8,6 +8,9 @@ MockXHR.responses = { '/error': function(xhr) { xhr.error() }, + '/form': function(xhr) { + xhr.respond(200, 'number=1&space=one+two&empty=&encoded=a%2Bb&') + }, '/json': function(xhr) { xhr.respond(200, JSON.stringify({name: 'Hubot', login: 'hubot'})) }, @@ -80,6 +83,15 @@ asyncTest('resolves text promise', 1, function() { }) }) +asyncTest('parses form encoded response', 1, function() { + fetch('/form').then(function(response) { + return response.formData() + }).then(function(form) { + ok(form instanceof FormData, 'Parsed a FormData object') + start() + }) +}) + asyncTest('parses json response', 2, function() { fetch('/json').then(function(response) { return response.json()