diff --git a/request/request.js b/request/request.js index 91bc55cd..8c5d4017 100644 --- a/request/request.js +++ b/request/request.js @@ -25,14 +25,18 @@ module.exports = function($window, Promise) { return promise } } - - function request(args, extra) { - var finalize = finalizer() + function normalize(args, extra) { if (typeof args === "string") { var url = args args = extra || {} if (args.url == null) args.url = url } + return args + } + + function request(args, extra) { + var finalize = finalizer() + args = normalize(args, extra) var promise = new Promise(function(resolve, reject) { if (args.method == null) args.method = "GET" @@ -83,11 +87,13 @@ module.exports = function($window, Promise) { if (useBody && (args.data != null)) xhr.send(args.data) else xhr.send() }) - return args.redraw === false ? promise : finalize(promise) + return args.background === true ? promise : finalize(promise) } - function jsonp(args) { + function jsonp(args, extra) { var finalize = finalizer() + args = normalize(args, extra) + var promise = new Promise(function(resolve, reject) { var callbackName = args.callbackName || "_mithril_" + Math.round(Math.random() * 1e16) + "_" + callbackCount++ var script = $window.document.createElement("script") @@ -107,7 +113,7 @@ module.exports = function($window, Promise) { script.src = assemble(args.url, args.data) $window.document.documentElement.appendChild(script) }) - return args.redraw === false? promise : finalize(promise) + return args.background === true? promise : finalize(promise) } function interpolate(url, data) { diff --git a/request/tests/test-jsonp.js b/request/tests/test-jsonp.js index 5d2f261f..6dd0a619 100644 --- a/request/tests/test-jsonp.js +++ b/request/tests/test-jsonp.js @@ -7,10 +7,13 @@ var Promise = require("../../promise/promise") var parseQueryString = require("../../querystring/parse") o.spec("jsonp", function() { - var mock, jsonp, spy + var mock, jsonp, spy, complete o.beforeEach(function() { mock = xhrMock() - jsonp = new Request(mock, Promise).jsonp + var requestService = Request(mock, Promise) + jsonp = requestService.jsonp + complete = o.spy() + requestService.setCompletionCallback(complete) }) o("works", function(done) { @@ -24,6 +27,20 @@ o.spec("jsonp", function() { o(data).deepEquals({a: 1}) }).then(done) }) + o("first argument can be a string aliasing url property", function(done){ + var s = new Date + mock.$defineRoutes({ + "GET /item": function(request) { + var queryData = parseQueryString(request.query) + return {status: 200, responseText: queryData["callback"] + "(" + JSON.stringify({a: 1}) + ")"} + } + }) + jsonp("/item").then(function(data) { + o(data).deepEquals({a: 1}) + }).then(function() { + done() + }) + }) o("works w/ other querystring params", function(done) { mock.$defineRoutes({ "GET /item": function(request) { @@ -47,6 +64,64 @@ o.spec("jsonp", function() { o(data).deepEquals({a: 2}) }).then(done) }) + o("works w/ custom callbackKey", function(done) { + mock.$defineRoutes({ + "GET /item": function(request) { + var queryData = parseQueryString(request.query) + return {status: 200, responseText: queryData["cb"] + "(" + JSON.stringify({a: 2}) + ")"} + } + }) + jsonp({url: "/item", callbackKey: "cb"}).then(function(data) { + o(data).deepEquals({a: 2}) + }).then(done) + }) + o("requests don't block each other", function(done) { + mock.$defineRoutes({ + "GET /item": function(request) { + var queryData = parseQueryString(request.query) + return {status: 200, responseText: queryData["callback"] + "([])"} + } + }) + jsonp("/item").then(function() { + return jsonp("/item") + }) + jsonp("/item").then(function() { + return jsonp("/item") + }) + setTimeout(function() { + o(complete.callCount).equals(4) + done() + }, 20) + }) + o("requests trigger finally once with a chained then", function(done) { + mock.$defineRoutes({ + "GET /item": function(request) { + var queryData = parseQueryString(request.query) + return {status: 200, responseText: queryData["callback"] + "([])"} + } + }) + var promise = jsonp("/item") + promise.then(function() {}).then(function() {}) + promise.then(function() {}).then(function() {}) + setTimeout(function() { + o(complete.callCount).equals(1) + done() + }, 20) + }) + o("requests does not trigger finally when background: true", function(done) { + mock.$defineRoutes({ + "GET /item": function(request) { + var queryData = parseQueryString(request.query) + return {status: 200, responseText: queryData["callback"] + "([])"} + } + }) + var promise = jsonp("/item", {background: true}).then(function() {}) + + setTimeout(function() { + o(complete.callCount).equals(0) + done() + }, 20) + }) o("handles error", function(done) { jsonp({url: "/item", callbackKey: "cb"}).catch(function(e) { o(e.message).equals("JSONP request failed") diff --git a/request/tests/test-request.js b/request/tests/test-request.js index 7ddc4325..1de21861 100644 --- a/request/tests/test-request.js +++ b/request/tests/test-request.js @@ -329,6 +329,19 @@ o.spec("xhr", function() { done() }, 20) }) + o("requests does not trigger finally when background: true", function(done) { + mock.$defineRoutes({ + "GET /item": function(request) { + return {status: 200, responseText: "[]"} + } + }) + var promise = xhr("/item", {background: true}).then(function() {}) + + setTimeout(function() { + o(complete.callCount).equals(0) + done() + }, 20) + }) }) o.spec("failure", function() { o("rejects on server error", function(done) {