diff --git a/lib/sinon/util/core/index.js b/lib/sinon/util/core/index.js index 6589c3d55..1662a5540 100644 --- a/lib/sinon/util/core/index.js +++ b/lib/sinon/util/core/index.js @@ -2,7 +2,6 @@ module.exports = { calledInOrder: require("./called-in-order"), - configureLogError: require("./log_error"), defaultConfig: require("./default-config"), deepEqual: require("./deep-equal"), every: require("./every"), diff --git a/lib/sinon/util/core/log_error.js b/lib/sinon/util/core/log_error.js deleted file mode 100644 index 01f83f228..000000000 --- a/lib/sinon/util/core/log_error.js +++ /dev/null @@ -1,47 +0,0 @@ -"use strict"; - -// cache a reference to setTimeout, so that our reference won't be stubbed out -// when using fake timers and errors will still get logged -// https://github.com/cjohansen/Sinon.JS/issues/381 -var realSetTimeout = setTimeout; - -function configure(config) { - config = config || {}; - // Function which prints errors. - if (!config.hasOwnProperty("logger")) { - config.logger = function () { }; - } - // When set to true, any errors logged will be thrown immediately; - // If set to false, the errors will be thrown in separate execution frame. - if (!config.hasOwnProperty("useImmediateExceptions")) { - config.useImmediateExceptions = true; - } - // wrap realSetTimeout with something we can stub in tests - if (!config.hasOwnProperty("setTimeout")) { - config.setTimeout = realSetTimeout; - } - - return function logError(label, e) { - var msg = label + " threw exception: "; - var err = { name: e.name || label, message: e.message || e.toString(), stack: e.stack }; - - function throwLoggedError() { - err.message = msg + err.message; - throw err; - } - - config.logger(msg + "[" + err.name + "] " + err.message); - - if (err.stack) { - config.logger(err.stack); - } - - if (config.useImmediateExceptions) { - throwLoggedError(); - } else { - config.setTimeout(throwLoggedError, 0); - } - }; -} - -module.exports = configure; diff --git a/lib/sinon/util/event.js b/lib/sinon/util/event.js deleted file mode 100644 index 8b91192e1..000000000 --- a/lib/sinon/util/event.js +++ /dev/null @@ -1,84 +0,0 @@ -"use strict"; - -var push = [].push; - -function Event(type, bubbles, cancelable, target) { - this.initEvent(type, bubbles, cancelable, target); -} - -Event.prototype = { - initEvent: function (type, bubbles, cancelable, target) { - this.type = type; - this.bubbles = bubbles; - this.cancelable = cancelable; - this.target = target; - }, - - stopPropagation: function () {}, - - preventDefault: function () { - this.defaultPrevented = true; - } -}; - -function ProgressEvent(type, progressEventRaw, target) { - this.initEvent(type, false, false, target); - this.loaded = typeof progressEventRaw.loaded === "number" ? progressEventRaw.loaded : null; - this.total = typeof progressEventRaw.total === "number" ? progressEventRaw.total : null; - this.lengthComputable = !!progressEventRaw.total; -} - -ProgressEvent.prototype = new Event(); - -ProgressEvent.prototype.constructor = ProgressEvent; - -function CustomEvent(type, customData, target) { - this.initEvent(type, false, false, target); - this.detail = customData.detail || null; -} - -CustomEvent.prototype = new Event(); - -CustomEvent.prototype.constructor = CustomEvent; - -var EventTarget = { - addEventListener: function addEventListener(event, listener) { - this.eventListeners = this.eventListeners || {}; - this.eventListeners[event] = this.eventListeners[event] || []; - push.call(this.eventListeners[event], listener); - }, - - removeEventListener: function removeEventListener(event, listener) { - var listeners = this.eventListeners && this.eventListeners[event] || []; - var index = listeners.indexOf(listener); - - if (index === -1) { - return; - } - - listeners.splice(index, 1); - }, - - dispatchEvent: function dispatchEvent(event) { - var self = this; - var type = event.type; - var listeners = self.eventListeners && self.eventListeners[type] || []; - - listeners.forEach(function (listener) { - if (typeof listener === "function") { - listener.call(self, event); - } else { - listener.handleEvent(event); - } - }); - - return !!event.defaultPrevented; - } -}; - -module.exports = { - Event: Event, - ProgressEvent: ProgressEvent, - CustomEvent: CustomEvent, - EventTarget: EventTarget -}; diff --git a/lib/sinon/util/fake_server.js b/lib/sinon/util/fake_server.js deleted file mode 100644 index 100f0ab39..000000000 --- a/lib/sinon/util/fake_server.js +++ /dev/null @@ -1,286 +0,0 @@ -"use strict"; - -var fakeXhr = require("./fake_xml_http_request"); -var push = [].push; -var format = require("./core/format"); -var configureLogError = require("./core/log_error"); -var pathToRegexp = require("path-to-regexp"); - -function responseArray(handler) { - var response = handler; - - if (Object.prototype.toString.call(handler) !== "[object Array]") { - response = [200, {}, handler]; - } - - if (typeof response[2] !== "string") { - throw new TypeError("Fake server response body should be string, but was " + - typeof response[2]); - } - - return response; -} - -function getDefaultWindowLocation() { - return { "host": "localhost", "protocol": "http" }; -} - -function getWindowLocation() { - if (typeof window === "undefined") { - // Fallback - return getDefaultWindowLocation(); - } - - if (typeof window.location !== "undefined") { - // Browsers place location on window - return window.location; - } - - if ((typeof window.window !== "undefined") && (typeof window.window.location !== "undefined")) { - // React Native on Android places location on window.window - return window.window.location; - } - - return getDefaultWindowLocation(); -} - -var wloc = getWindowLocation(); - -var rCurrLoc = new RegExp("^" + wloc.protocol + "//" + wloc.host); - -function matchOne(response, reqMethod, reqUrl) { - var rmeth = response.method; - var matchMethod = !rmeth || rmeth.toLowerCase() === reqMethod.toLowerCase(); - var url = response.url; - var matchUrl = !url || url === reqUrl || (typeof url.test === "function" && url.test(reqUrl)); - - return matchMethod && matchUrl; -} - -function match(response, request) { - var requestUrl = request.url; - - if (!/^https?:\/\//.test(requestUrl) || rCurrLoc.test(requestUrl)) { - requestUrl = requestUrl.replace(rCurrLoc, ""); - } - - if (matchOne(response, this.getHTTPMethod(request), requestUrl)) { - if (typeof response.response === "function") { - var ru = response.url; - var args = [request].concat(ru && typeof ru.exec === "function" ? ru.exec(requestUrl).slice(1) : []); - return response.response.apply(response, args); - } - - return true; - } - - return false; -} - -function incrementRequestCount() { - var count = ++this.requestCount; - - this.requested = true; - - this.requestedOnce = count === 1; - this.requestedTwice = count === 2; - this.requestedThrice = count === 3; - - this.firstRequest = this.getRequest(0); - this.secondRequest = this.getRequest(1); - this.thirdRequest = this.getRequest(2); - - this.lastRequest = this.getRequest(count - 1); -} - -var fakeServer = { - create: function (config) { - var server = Object.create(this); - server.configure(config); - this.xhr = fakeXhr.useFakeXMLHttpRequest(); - server.requests = []; - server.requestCount = 0; - server.queue = []; - server.responses = []; - - - this.xhr.onCreate = function (xhrObj) { - xhrObj.unsafeHeadersEnabled = function () { - return !(server.unsafeHeadersEnabled === false); - }; - server.addRequest(xhrObj); - }; - - return server; - }, - - configure: function (config) { - var self = this; - var whitelist = { - "autoRespond": true, - "autoRespondAfter": true, - "respondImmediately": true, - "fakeHTTPMethods": true, - "logger": true, - "unsafeHeadersEnabled": true - }; - - config = config || {}; - - Object.keys(config).forEach(function (setting) { - if (setting in whitelist) { - self[setting] = config[setting]; - } - }); - - self.logError = configureLogError(config); - }, - - addRequest: function addRequest(xhrObj) { - var server = this; - push.call(this.requests, xhrObj); - - incrementRequestCount.call(this); - - xhrObj.onSend = function () { - server.handleRequest(this); - - if (server.respondImmediately) { - server.respond(); - } else if (server.autoRespond && !server.responding) { - setTimeout(function () { - server.responding = false; - server.respond(); - }, server.autoRespondAfter || 10); - - server.responding = true; - } - }; - }, - - getHTTPMethod: function getHTTPMethod(request) { - if (this.fakeHTTPMethods && /post/i.test(request.method)) { - var matches = (request.requestBody || "").match(/_method=([^\b;]+)/); - return matches ? matches[1] : request.method; - } - - return request.method; - }, - - handleRequest: function handleRequest(xhr) { - if (xhr.async) { - push.call(this.queue, xhr); - } else { - this.processRequest(xhr); - } - }, - - logger: function () { - // no-op; override via configure() - }, - - logError: configureLogError({}), - - log: function log(response, request) { - var str; - - str = "Request:\n" + format(request) + "\n\n"; - str += "Response:\n" + format(response) + "\n\n"; - - if (typeof this.logger === "function") { - this.logger(str); - } - }, - - respondWith: function respondWith(method, url, body) { - if (arguments.length === 1 && typeof method !== "function") { - this.response = responseArray(method); - return; - } - - if (arguments.length === 1) { - body = method; - url = method = null; - } - - if (arguments.length === 2) { - body = url; - url = method; - method = null; - } - - push.call(this.responses, { - method: method, - url: typeof url === "string" && url !== "" ? pathToRegexp(url) : url, - response: typeof body === "function" ? body : responseArray(body) - }); - }, - - respond: function respond() { - if (arguments.length > 0) { - this.respondWith.apply(this, arguments); - } - - var queue = this.queue || []; - var requests = queue.splice(0, queue.length); - var self = this; - - requests.forEach(function (request) { - self.processRequest(request); - }); - }, - - processRequest: function processRequest(request) { - try { - if (request.aborted) { - return; - } - - var response = this.response || [404, {}, ""]; - - if (this.responses) { - for (var l = this.responses.length, i = l - 1; i >= 0; i--) { - if (match.call(this, this.responses[i], request)) { - response = this.responses[i].response; - break; - } - } - } - - if (request.readyState !== 4) { - this.log(response, request); - - request.respond(response[0], response[1], response[2]); - } - } catch (e) { - this.logError("Fake server request processing", e); - } - }, - - restore: function restore() { - return this.xhr.restore && this.xhr.restore.apply(this.xhr, arguments); - }, - - getRequest: function getRequest(index) { - return this.requests[index] || null; - }, - - reset: function reset() { - this.resetBehavior(); - this.resetHistory(); - }, - - resetBehavior: function resetBehavior() { - this.responses.length = this.queue.length = 0; - }, - - resetHistory: function resetHistory() { - this.requests.length = this.requestCount = 0; - - this.requestedOnce = this.requestedTwice = this.requestedThrice = this.requested = false; - - this.firstRequest = this.secondRequest = this.thirdRequest = this.lastRequest = null; - } -}; - -module.exports = fakeServer; diff --git a/lib/sinon/util/fake_server_with_clock.js b/lib/sinon/util/fake_server_with_clock.js deleted file mode 100644 index d97ce0722..000000000 --- a/lib/sinon/util/fake_server_with_clock.js +++ /dev/null @@ -1,66 +0,0 @@ -"use strict"; - -var fakeServer = require("./fake_server"); -var fakeTimers = require("./fake_timers"); - -function Server() {} -Server.prototype = fakeServer; - -var fakeServerWithClock = new Server(); - -fakeServerWithClock.addRequest = function addRequest(xhr) { - if (xhr.async) { - if (typeof setTimeout.clock === "object") { - this.clock = setTimeout.clock; - } else { - this.clock = fakeTimers.useFakeTimers(); - this.resetClock = true; - } - - if (!this.longestTimeout) { - var clockSetTimeout = this.clock.setTimeout; - var clockSetInterval = this.clock.setInterval; - var server = this; - - this.clock.setTimeout = function (fn, timeout) { - server.longestTimeout = Math.max(timeout, server.longestTimeout || 0); - - return clockSetTimeout.apply(this, arguments); - }; - - this.clock.setInterval = function (fn, timeout) { - server.longestTimeout = Math.max(timeout, server.longestTimeout || 0); - - return clockSetInterval.apply(this, arguments); - }; - } - } - - return fakeServer.addRequest.call(this, xhr); -}; - -fakeServerWithClock.respond = function respond() { - var returnVal = fakeServer.respond.apply(this, arguments); - - if (this.clock) { - this.clock.tick(this.longestTimeout || 0); - this.longestTimeout = 0; - - if (this.resetClock) { - this.clock.restore(); - this.resetClock = false; - } - } - - return returnVal; -}; - -fakeServerWithClock.restore = function restore() { - if (this.clock) { - this.clock.restore(); - } - - return fakeServer.restore.apply(this, arguments); -}; - -module.exports = fakeServerWithClock; diff --git a/lib/sinon/util/fake_xml_http_request.js b/lib/sinon/util/fake_xml_http_request.js deleted file mode 100644 index 7d0a91a4c..000000000 --- a/lib/sinon/util/fake_xml_http_request.js +++ /dev/null @@ -1,645 +0,0 @@ -"use strict"; - -var TextEncoder = require("text-encoding").TextEncoder; - -var configureLogError = require("./core/log_error"); -var sinonEvent = require("./event"); -var extend = require("./core/extend"); - -function getWorkingXHR(globalScope) { - var supportsXHR = typeof globalScope.XMLHttpRequest !== "undefined"; - if (supportsXHR) { - return globalScope.XMLHttpRequest; - } - - var supportsActiveX = typeof globalScope.ActiveXObject !== "undefined"; - if (supportsActiveX) { - return function () { - return new globalScope.ActiveXObject("MSXML2.XMLHTTP.3.0"); - }; - } - - return false; -} - -var supportsProgress = typeof ProgressEvent !== "undefined"; -var supportsCustomEvent = typeof CustomEvent !== "undefined"; -var supportsFormData = typeof FormData !== "undefined"; -var supportsArrayBuffer = typeof ArrayBuffer !== "undefined"; -var supportsBlob = require("../blob").isSupported; -var isReactNative = global.navigator && global.navigator.product === "ReactNative"; -var sinonXhr = { XMLHttpRequest: global.XMLHttpRequest }; -sinonXhr.GlobalXMLHttpRequest = global.XMLHttpRequest; -sinonXhr.GlobalActiveXObject = global.ActiveXObject; -sinonXhr.supportsActiveX = typeof sinonXhr.GlobalActiveXObject !== "undefined"; -sinonXhr.supportsXHR = typeof sinonXhr.GlobalXMLHttpRequest !== "undefined"; -sinonXhr.workingXHR = getWorkingXHR(global); -sinonXhr.supportsCORS = isReactNative || - (sinonXhr.supportsXHR && "withCredentials" in (new sinonXhr.GlobalXMLHttpRequest())); - -var unsafeHeaders = { - "Accept-Charset": true, - "Accept-Encoding": true, - "Connection": true, - "Content-Length": true, - "Cookie": true, - "Cookie2": true, - "Content-Transfer-Encoding": true, - "Date": true, - "Expect": true, - "Host": true, - "Keep-Alive": true, - "Referer": true, - "TE": true, - "Trailer": true, - "Transfer-Encoding": true, - "Upgrade": true, - "User-Agent": true, - "Via": true -}; - - -function EventTargetHandler() { - var self = this; - var events = ["loadstart", "progress", "abort", "error", "load", "timeout", "loadend"]; - - function addEventListener(eventName) { - self.addEventListener(eventName, function (event) { - var listener = self["on" + eventName]; - - if (listener && typeof listener === "function") { - listener.call(this, event); - } - }); - } - - events.forEach(addEventListener); -} - -EventTargetHandler.prototype = sinonEvent.EventTarget; - -// Note that for FakeXMLHttpRequest to work pre ES5 -// we lose some of the alignment with the spec. -// To ensure as close a match as possible, -// set responseType before calling open, send or respond; -function FakeXMLHttpRequest(config) { - EventTargetHandler.call(this); - this.readyState = FakeXMLHttpRequest.UNSENT; - this.requestHeaders = {}; - this.requestBody = null; - this.status = 0; - this.statusText = ""; - this.upload = new EventTargetHandler(); - this.responseType = ""; - this.response = ""; - this.logError = configureLogError(config); - if (sinonXhr.supportsCORS) { - this.withCredentials = false; - } - - if (typeof FakeXMLHttpRequest.onCreate === "function") { - FakeXMLHttpRequest.onCreate(this); - } -} - -function verifyState(xhr) { - if (xhr.readyState !== FakeXMLHttpRequest.OPENED) { - throw new Error("INVALID_STATE_ERR"); - } - - if (xhr.sendFlag) { - throw new Error("INVALID_STATE_ERR"); - } -} - -function getHeader(headers, header) { - var foundHeader = Object.keys(headers).filter(function (h) { - return h.toLowerCase() === header.toLowerCase(); - }); - - return foundHeader[0] || null; -} - -function excludeSetCookie2Header(header) { - return !/^Set-Cookie2?$/i.test(header); -} - -// largest arity in XHR is 5 - XHR#open -var apply = function (obj, method, args) { - switch (args.length) { - case 0: return obj[method](); - case 1: return obj[method](args[0]); - case 2: return obj[method](args[0], args[1]); - case 3: return obj[method](args[0], args[1], args[2]); - case 4: return obj[method](args[0], args[1], args[2], args[3]); - case 5: return obj[method](args[0], args[1], args[2], args[3], args[4]); - default: throw new Error("Unhandled case"); - } -}; - -FakeXMLHttpRequest.filters = []; -FakeXMLHttpRequest.addFilter = function addFilter(fn) { - this.filters.push(fn); -}; -FakeXMLHttpRequest.defake = function defake(fakeXhr, xhrArgs) { - var xhr = new sinonXhr.workingXHR(); // eslint-disable-line new-cap - - [ - "open", - "setRequestHeader", - "send", - "abort", - "getResponseHeader", - "getAllResponseHeaders", - "addEventListener", - "overrideMimeType", - "removeEventListener" - ].forEach(function (method) { - fakeXhr[method] = function () { - return apply(xhr, method, arguments); - }; - }); - - var copyAttrs = function (args) { - args.forEach(function (attr) { - fakeXhr[attr] = xhr[attr]; - }); - }; - - var stateChange = function stateChange() { - fakeXhr.readyState = xhr.readyState; - if (xhr.readyState >= FakeXMLHttpRequest.HEADERS_RECEIVED) { - copyAttrs(["status", "statusText"]); - } - if (xhr.readyState >= FakeXMLHttpRequest.LOADING) { - copyAttrs(["responseText", "response"]); - } - if (xhr.readyState === FakeXMLHttpRequest.DONE) { - copyAttrs(["responseXML"]); - } - if (fakeXhr.onreadystatechange) { - fakeXhr.onreadystatechange.call(fakeXhr, { target: fakeXhr }); - } - }; - - if (xhr.addEventListener) { - Object.keys(fakeXhr.eventListeners).forEach(function (event) { - /*eslint-disable no-loop-func*/ - fakeXhr.eventListeners[event].forEach(function (handler) { - xhr.addEventListener(event, handler); - }); - /*eslint-enable no-loop-func*/ - }); - - xhr.addEventListener("readystatechange", stateChange); - } else { - xhr.onreadystatechange = stateChange; - } - apply(xhr, "open", xhrArgs); -}; -FakeXMLHttpRequest.useFilters = false; - -function verifyRequestOpened(xhr) { - if (xhr.readyState !== FakeXMLHttpRequest.OPENED) { - throw new Error("INVALID_STATE_ERR - " + xhr.readyState); - } -} - -function verifyRequestSent(xhr) { - if (xhr.readyState === FakeXMLHttpRequest.DONE) { - throw new Error("Request done"); - } -} - -function verifyHeadersReceived(xhr) { - if (xhr.async && xhr.readyState !== FakeXMLHttpRequest.HEADERS_RECEIVED) { - throw new Error("No headers received"); - } -} - -function verifyResponseBodyType(body) { - if (typeof body !== "string") { - var error = new Error("Attempted to respond to fake XMLHttpRequest with " + - body + ", which is not a string."); - error.name = "InvalidBodyException"; - throw error; - } -} - -function convertToArrayBuffer(body, encoding) { - return new TextEncoder(encoding || "utf-8").encode(body).buffer; -} - -function isXmlContentType(contentType) { - return !contentType || /(text\/xml)|(application\/xml)|(\+xml)/.test(contentType); -} - -function convertResponseBody(responseType, contentType, body) { - if (responseType === "" || responseType === "text") { - return body; - } else if (supportsArrayBuffer && responseType === "arraybuffer") { - return convertToArrayBuffer(body); - } else if (responseType === "json") { - try { - return JSON.parse(body); - } catch (e) { - // Return parsing failure as null - return null; - } - } else if (supportsBlob && responseType === "blob") { - var blobOptions = {}; - if (contentType) { - blobOptions.type = contentType; - } - return new Blob([convertToArrayBuffer(body)], blobOptions); - } else if (responseType === "document") { - if (isXmlContentType(contentType)) { - return FakeXMLHttpRequest.parseXML(body); - } - return null; - } - throw new Error("Invalid responseType " + responseType); -} - -function clearResponse(xhr) { - if (xhr.responseType === "" || xhr.responseType === "text") { - xhr.response = xhr.responseText = ""; - } else { - xhr.response = xhr.responseText = null; - } - xhr.responseXML = null; -} - -FakeXMLHttpRequest.parseXML = function parseXML(text) { - // Treat empty string as parsing failure - if (text !== "") { - try { - if (typeof DOMParser !== "undefined") { - var parser = new DOMParser(); - return parser.parseFromString(text, "text/xml"); - } - var xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM"); - xmlDoc.async = "false"; - xmlDoc.loadXML(text); - return xmlDoc; - } catch (e) { - // Unable to parse XML - no biggie - } - } - - return null; -}; - -FakeXMLHttpRequest.statusCodes = { - 100: "Continue", - 101: "Switching Protocols", - 200: "OK", - 201: "Created", - 202: "Accepted", - 203: "Non-Authoritative Information", - 204: "No Content", - 205: "Reset Content", - 206: "Partial Content", - 207: "Multi-Status", - 300: "Multiple Choice", - 301: "Moved Permanently", - 302: "Found", - 303: "See Other", - 304: "Not Modified", - 305: "Use Proxy", - 307: "Temporary Redirect", - 400: "Bad Request", - 401: "Unauthorized", - 402: "Payment Required", - 403: "Forbidden", - 404: "Not Found", - 405: "Method Not Allowed", - 406: "Not Acceptable", - 407: "Proxy Authentication Required", - 408: "Request Timeout", - 409: "Conflict", - 410: "Gone", - 411: "Length Required", - 412: "Precondition Failed", - 413: "Request Entity Too Large", - 414: "Request-URI Too Long", - 415: "Unsupported Media Type", - 416: "Requested Range Not Satisfiable", - 417: "Expectation Failed", - 422: "Unprocessable Entity", - 500: "Internal Server Error", - 501: "Not Implemented", - 502: "Bad Gateway", - 503: "Service Unavailable", - 504: "Gateway Timeout", - 505: "HTTP Version Not Supported" -}; - -extend(FakeXMLHttpRequest.prototype, sinonEvent.EventTarget, { - async: true, - - open: function open(method, url, async, username, password) { - this.method = method; - this.url = url; - this.async = typeof async === "boolean" ? async : true; - this.username = username; - this.password = password; - clearResponse(this); - this.requestHeaders = {}; - this.sendFlag = false; - - if (FakeXMLHttpRequest.useFilters === true) { - var xhrArgs = arguments; - var defake = FakeXMLHttpRequest.filters.some(function (filter) { - return filter.apply(this, xhrArgs); - }); - if (defake) { - FakeXMLHttpRequest.defake(this, arguments); - return; - } - } - this.readyStateChange(FakeXMLHttpRequest.OPENED); - }, - - readyStateChange: function readyStateChange(state) { - this.readyState = state; - - var readyStateChangeEvent = new sinonEvent.Event("readystatechange", false, false, this); - var event, progress; - - if (typeof this.onreadystatechange === "function") { - try { - this.onreadystatechange(readyStateChangeEvent); - } catch (e) { - this.logError("Fake XHR onreadystatechange handler", e); - } - } - - if (this.readyState === FakeXMLHttpRequest.DONE) { - if (this.aborted || this.status === 0) { - progress = {loaded: 0, total: 0}; - event = this.aborted ? "abort" : "error"; - } else { - progress = {loaded: 100, total: 100}; - event = "load"; - } - - if (supportsProgress) { - this.upload.dispatchEvent(new sinonEvent.ProgressEvent("progress", progress, this)); - this.upload.dispatchEvent(new sinonEvent.ProgressEvent(event, progress, this)); - this.upload.dispatchEvent(new sinonEvent.ProgressEvent("loadend", progress, this)); - } - - this.dispatchEvent(new sinonEvent.ProgressEvent("progress", progress, this)); - this.dispatchEvent(new sinonEvent.ProgressEvent(event, progress, this)); - this.dispatchEvent(new sinonEvent.ProgressEvent("loadend", progress, this)); - } - - this.dispatchEvent(readyStateChangeEvent); - }, - - setRequestHeader: function setRequestHeader(header, value) { - verifyState(this); - - var checkUnsafeHeaders = true; - if (typeof this.unsafeHeadersEnabled === "function") { - checkUnsafeHeaders = this.unsafeHeadersEnabled(); - } - - if (checkUnsafeHeaders && (unsafeHeaders[header] || /^(Sec-|Proxy-)/.test(header))) { - throw new Error("Refused to set unsafe header \"" + header + "\""); - } - - if (this.requestHeaders[header]) { - this.requestHeaders[header] += "," + value; - } else { - this.requestHeaders[header] = value; - } - }, - - setStatus: function setStatus(status) { - var sanitizedStatus = typeof status === "number" ? status : 200; - - verifyRequestOpened(this); - this.status = sanitizedStatus; - this.statusText = FakeXMLHttpRequest.statusCodes[sanitizedStatus]; - }, - - // Helps testing - setResponseHeaders: function setResponseHeaders(headers) { - verifyRequestOpened(this); - - var responseHeaders = this.responseHeaders = {}; - - Object.keys(headers).forEach(function (header) { - responseHeaders[header] = headers[header]; - }); - - if (this.async) { - this.readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED); - } else { - this.readyState = FakeXMLHttpRequest.HEADERS_RECEIVED; - } - }, - - // Currently treats ALL data as a DOMString (i.e. no Document) - send: function send(data) { - verifyState(this); - - if (!/^(head)$/i.test(this.method)) { - var contentType = getHeader(this.requestHeaders, "Content-Type"); - if (this.requestHeaders[contentType]) { - var value = this.requestHeaders[contentType].split(";"); - this.requestHeaders[contentType] = value[0] + ";charset=utf-8"; - } else if (supportsFormData && !(data instanceof FormData)) { - this.requestHeaders["Content-Type"] = "text/plain;charset=utf-8"; - } - - this.requestBody = data; - } - - this.errorFlag = false; - this.sendFlag = this.async; - clearResponse(this); - this.readyStateChange(FakeXMLHttpRequest.OPENED); - - if (typeof this.onSend === "function") { - this.onSend(this); - } - - this.dispatchEvent(new sinonEvent.Event("loadstart", false, false, this)); - }, - - abort: function abort() { - this.aborted = true; - clearResponse(this); - this.errorFlag = true; - this.requestHeaders = {}; - this.responseHeaders = {}; - - if (this.readyState !== FakeXMLHttpRequest.UNSENT && this.sendFlag - && this.readyState !== FakeXMLHttpRequest.DONE) { - this.readyStateChange(FakeXMLHttpRequest.DONE); - this.sendFlag = false; - } - - this.readyState = FakeXMLHttpRequest.UNSENT; - }, - - error: function () { - clearResponse(this); - this.errorFlag = true; - this.requestHeaders = {}; - this.responseHeaders = {}; - - this.readyStateChange(FakeXMLHttpRequest.DONE); - }, - - getResponseHeader: function getResponseHeader(header) { - if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) { - return null; - } - - if (/^Set-Cookie2?$/i.test(header)) { - return null; - } - - header = getHeader(this.responseHeaders, header); - - return this.responseHeaders[header] || null; - }, - - getAllResponseHeaders: function getAllResponseHeaders() { - if (this.readyState < FakeXMLHttpRequest.HEADERS_RECEIVED) { - return ""; - } - - var responseHeaders = this.responseHeaders; - var headers = Object.keys(responseHeaders) - .filter(excludeSetCookie2Header) - .reduce(function (prev, header) { - var value = responseHeaders[header]; - - return prev + (header + ": " + value + "\r\n"); - }, ""); - - return headers; - }, - - setResponseBody: function setResponseBody(body) { - verifyRequestSent(this); - verifyHeadersReceived(this); - verifyResponseBodyType(body); - var contentType = this.overriddenMimeType || this.getResponseHeader("Content-Type"); - - var isTextResponse = this.responseType === "" || this.responseType === "text"; - clearResponse(this); - if (this.async) { - var chunkSize = this.chunkSize || 10; - var index = 0; - - do { - this.readyStateChange(FakeXMLHttpRequest.LOADING); - - if (isTextResponse) { - this.responseText = this.response += body.substring(index, index + chunkSize); - } - index += chunkSize; - } while (index < body.length); - } - - this.response = convertResponseBody(this.responseType, contentType, body); - if (isTextResponse) { - this.responseText = this.response; - } - - if (this.responseType === "document") { - this.responseXML = this.response; - } else if (this.responseType === "" && isXmlContentType(contentType)) { - this.responseXML = FakeXMLHttpRequest.parseXML(this.responseText); - } - this.readyStateChange(FakeXMLHttpRequest.DONE); - }, - - respond: function respond(status, headers, body) { - this.setStatus(status); - this.setResponseHeaders(headers || {}); - this.setResponseBody(body || ""); - }, - - uploadProgress: function uploadProgress(progressEventRaw) { - if (supportsProgress) { - this.upload.dispatchEvent(new sinonEvent.ProgressEvent("progress", progressEventRaw)); - } - }, - - downloadProgress: function downloadProgress(progressEventRaw) { - if (supportsProgress) { - this.dispatchEvent(new sinonEvent.ProgressEvent("progress", progressEventRaw)); - } - }, - - uploadError: function uploadError(error) { - if (supportsCustomEvent) { - this.upload.dispatchEvent(new sinonEvent.CustomEvent("error", {detail: error})); - } - }, - - overrideMimeType: function overrideMimeType(type) { - if (this.readyState >= FakeXMLHttpRequest.LOADING) { - throw new Error("INVALID_STATE_ERR"); - } - this.overriddenMimeType = type; - } -}); - -var states = { - UNSENT: 0, - OPENED: 1, - HEADERS_RECEIVED: 2, - LOADING: 3, - DONE: 4 -}; - -extend(FakeXMLHttpRequest, states); -extend(FakeXMLHttpRequest.prototype, states); - -function useFakeXMLHttpRequest() { - FakeXMLHttpRequest.restore = function restore(keepOnCreate) { - if (sinonXhr.supportsXHR) { - global.XMLHttpRequest = sinonXhr.GlobalXMLHttpRequest; - } - - if (sinonXhr.supportsActiveX) { - global.ActiveXObject = sinonXhr.GlobalActiveXObject; - } - - delete FakeXMLHttpRequest.restore; - - if (keepOnCreate !== true) { - delete FakeXMLHttpRequest.onCreate; - } - }; - if (sinonXhr.supportsXHR) { - global.XMLHttpRequest = FakeXMLHttpRequest; - } - - if (sinonXhr.supportsActiveX) { - global.ActiveXObject = function ActiveXObject(objId) { - if (objId === "Microsoft.XMLHTTP" || /^Msxml2\.XMLHTTP/i.test(objId)) { - - return new FakeXMLHttpRequest(); - } - - return new sinonXhr.GlobalActiveXObject(objId); - }; - } - - return FakeXMLHttpRequest; -} - -module.exports = { - xhr: sinonXhr, - FakeXMLHttpRequest: FakeXMLHttpRequest, - useFakeXMLHttpRequest: useFakeXMLHttpRequest -}; diff --git a/test/issues/issues-test.js b/test/issues/issues-test.js index 99461e547..b9264b257 100644 --- a/test/issues/issues-test.js +++ b/test/issues/issues-test.js @@ -2,12 +2,9 @@ var referee = require("referee"); var sinon = require("../../lib/sinon"); -var sinonSandbox = require("../../lib/sinon/sandbox"); -var configureLogError = require("../../lib/sinon/util/core/log_error.js"); var assert = referee.assert; var refute = referee.refute; - describe("issues", function () { beforeEach(function () { this.sandbox = sinon.sandbox.create(); @@ -73,33 +70,6 @@ describe("issues", function () { }); }); - describe("#835", function () { - it("logError() throws an exception if the passed err is read-only", function () { - var logError = configureLogError({useImmediateExceptions: true}); - - // passes - var err = { name: "TestError", message: "this is a proper exception" }; - assert.exception( - function () { - logError("#835 test", err); - }, - { - name: err.name - } - ); - - // fails until this issue is fixed - assert.exception( - function () { - logError("#835 test", "this literal string is not a proper exception"); - }, - { - name: "#835 test" - } - ); - }); - }); - describe("#852 - createStubInstance on intherited constructors", function () { it("must not throw error", function () { var A = function () {}; @@ -256,7 +226,7 @@ describe("issues", function () { var sandbox; beforeEach(function () { - sandbox = sinonSandbox.create(); + sandbox = sinon.sandbox.create(); }); afterEach(function () { diff --git a/test/util/core/log-error-test.js b/test/util/core/log-error-test.js deleted file mode 100644 index 98fe8a65c..000000000 --- a/test/util/core/log-error-test.js +++ /dev/null @@ -1,124 +0,0 @@ -"use strict"; - -var referee = require("referee"); -var configureLogError = require("../../../lib/sinon/util/core/log_error"); -var sandbox = require("../../../lib/sinon/sandbox"); -var assert = referee.assert; -var refute = referee.refute; - -describe("util/core/configureLogError", function () { - beforeEach(function () { - this.sandbox = sandbox.create(); - this.timeOutStub = sandbox.stub(); - }); - - afterEach(function () { - this.sandbox.restore(); - }); - - it("is a function", function () { - var instance = configureLogError(); - assert.isFunction(instance); - }); - - it("calls config.logger function with a String", function () { - var spy = this.sandbox.spy(); - var logError = configureLogError({ - logger: spy, - setTimeout: this.timeOutStub, - useImmediateExceptions: false - }); - var name = "Quisque consequat, elit id suscipit."; - var message = "Pellentesque gravida orci in tellus tristique, ac commodo nibh congue."; - var error = new Error(); - - error.name = name; - error.message = message; - - logError("a label", error); - - assert(spy.called); - assert(spy.calledWithMatch(name)); - assert(spy.calledWithMatch(message)); - }); - - it("calls config.logger function with a stack", function () { - var spy = this.sandbox.spy(); - var logError = configureLogError({ - logger: spy, - setTimeout: this.timeOutStub, - useImmediateExceptions: false - }); - var stack = "Integer rutrum dictum elit, posuere accumsan nisi pretium vel. Phasellus adipiscing."; - var error = new Error(); - - error.stack = stack; - - logError("another label", error); - - assert(spy.called); - assert(spy.calledWithMatch(stack)); - }); - - it("should call config.setTimeout", function () { - var logError = configureLogError({ - setTimeout: this.timeOutStub, - useImmediateExceptions: false - }); - var error = new Error(); - - logError("some wonky label", error); - - assert(this.timeOutStub.calledOnce); - }); - - it("should pass a throwing function to config.setTimeout", function () { - var logError = configureLogError({ - setTimeout: this.timeOutStub, - useImmediateExceptions: false - }); - var error = new Error(); - - logError("async error", error); - - var func = this.timeOutStub.args[0][0]; - assert.exception(func); - }); - - describe("config.useImmediateExceptions", function () { - beforeEach(function () { - this.sandbox = sandbox.create(); - this.timeOutStub = this.sandbox.stub(); - }); - - afterEach(function () { - this.sandbox.restore(); - }); - - it("throws the logged error immediately, does not call logError.setTimeout when flag is true", function () { - var error = new Error(); - var logError = configureLogError({ - setTimeout: this.timeOutStub, - useImmediateExceptions: true - }); - - assert.exception(function () { - logError("an error", error); - }); - assert(this.timeOutStub.notCalled); - }); - - it("does not throw logged error immediately and calls logError.setTimeout when flag is false", function () { - var error = new Error(); - var logError = configureLogError({ - setTimeout: this.timeOutStub, - useImmediateExceptions: false - }); - - refute.exception(function () { - logError("an error", error); - }); - assert(this.timeOutStub.called); - }); - }); -}); diff --git a/test/util/event-test.js b/test/util/event-test.js deleted file mode 100644 index ba39dcab5..000000000 --- a/test/util/event-test.js +++ /dev/null @@ -1,131 +0,0 @@ -"use strict"; - -var referee = require("referee"); -var assert = referee.assert; - -var sinonEvent = require("../../lib/sinon/util/event"); -var sinonExtend = require("../../lib/sinon/util/core/extend"); -var sinonSpy = require("../../lib/sinon/spy"); - -describe("sinon.EventTarget", function () { - beforeEach(function () { - this.target = sinonExtend({}, sinonEvent.EventTarget); - }); - - it("notifies event listener", function () { - var listener = sinonSpy(); - this.target.addEventListener("dummy", listener); - - var event = new sinonEvent.Event("dummy"); - this.target.dispatchEvent(event); - - assert(listener.calledOnce); - assert(listener.calledWith(event)); - }); - - it("notifies event listener with target as this", function () { - var listener = sinonSpy(); - this.target.addEventListener("dummy", listener); - - var event = new sinonEvent.Event("dummy"); - this.target.dispatchEvent(event); - - assert(listener.calledOn(this.target)); - }); - - it("notifies all event listeners", function () { - var listeners = [sinonSpy(), sinonSpy()]; - this.target.addEventListener("dummy", listeners[0]); - this.target.addEventListener("dummy", listeners[1]); - - var event = new sinonEvent.Event("dummy"); - this.target.dispatchEvent(event); - - assert(listeners[0].calledOnce); - assert(listeners[0].calledOnce); - }); - - it("notifies event listener of type listener", function () { - var listener = { handleEvent: sinonSpy() }; - this.target.addEventListener("dummy", listener); - - this.target.dispatchEvent(new sinonEvent.Event("dummy")); - - assert(listener.handleEvent.calledOnce); - }); - - it("does not notify listeners of other events", function () { - var listeners = [sinonSpy(), sinonSpy()]; - this.target.addEventListener("dummy", listeners[0]); - this.target.addEventListener("other", listeners[1]); - - this.target.dispatchEvent(new sinonEvent.Event("dummy")); - - assert.isFalse(listeners[1].called); - }); - - it("does not notify unregistered listeners", function () { - var listener = sinonSpy(); - this.target.addEventListener("dummy", listener); - this.target.removeEventListener("dummy", listener); - - this.target.dispatchEvent(new sinonEvent.Event("dummy")); - - assert.isFalse(listener.called); - }); - - it("notifies existing listeners after removing one", function () { - var listeners = [sinonSpy(), sinonSpy(), sinonSpy()]; - this.target.addEventListener("dummy", listeners[0]); - this.target.addEventListener("dummy", listeners[1]); - this.target.addEventListener("dummy", listeners[2]); - this.target.removeEventListener("dummy", listeners[1]); - - this.target.dispatchEvent(new sinonEvent.Event("dummy")); - - assert(listeners[0].calledOnce); - assert(listeners[2].calledOnce); - }); - - it("returns false when event.preventDefault is not called", function () { - this.target.addEventListener("dummy", sinonSpy()); - - var event = new sinonEvent.Event("dummy"); - var result = this.target.dispatchEvent(event); - - assert.isFalse(result); - }); - - it("returns true when event.preventDefault is called", function () { - this.target.addEventListener("dummy", function (e) { - e.preventDefault(); - }); - - var result = this.target.dispatchEvent(new sinonEvent.Event("dummy")); - - assert.isTrue(result); - }); - - it("notifies ProgressEvent listener with progress data ", function () { - var listener = sinonSpy(); - this.target.addEventListener("dummyProgress", listener); - - var progressEvent = new sinonEvent.ProgressEvent("dummyProgress", {loaded: 50, total: 120}); - this.target.dispatchEvent(progressEvent); - - assert.isTrue(progressEvent.lengthComputable); - assert(listener.calledOnce); - assert(listener.calledWith(progressEvent)); - }); - - it("notifies CustomEvent listener with custom data", function () { - var listener = sinonSpy(); - this.target.addEventListener("dummyCustom", listener); - - var customEvent = new sinonEvent.CustomEvent("dummyCustom", {detail: "hola"}); - this.target.dispatchEvent(customEvent); - - assert(listener.calledOnce); - assert(listener.calledWith(customEvent)); - }); -}); diff --git a/test/util/fake-server-test.js b/test/util/fake-server-test.js deleted file mode 100644 index 14bb4b6e6..000000000 --- a/test/util/fake-server-test.js +++ /dev/null @@ -1,1145 +0,0 @@ -"use strict"; - -var referee = require("referee"); -var sinon = require("../../lib/sinon"); -var sinonFakeServer = require("../../lib/sinon/util/fake_server"); -var fakeXhr = require("../../lib/sinon/util/fake_xml_http_request"); -var sinonStub = require("../../lib/sinon/stub"); -var sinonSpy = require("../../lib/sinon/spy"); -var sinonSandbox = require("../../lib/sinon/sandbox"); -var fakeTimers = require("../../lib/sinon/util/fake_timers"); -var FakeXMLHttpRequest = fakeXhr.FakeXMLHttpRequest; - -var assert = referee.assert; -var refute = referee.refute; - -if (typeof window !== "undefined") { - describe("sinonFakeServer", function () { - - afterEach(function () { - if (this.server) { - this.server.restore(); - } - }); - - it("provides restore method", function () { - this.server = sinonFakeServer.create(); - - assert.isFunction(this.server.restore); - }); - - describe(".create", function () { - it("allows the 'autoRespond' setting", function () { - var server = sinonFakeServer.create({ - autoRespond: true - }); - assert( - server.autoRespond, - "fakeServer.create should accept 'autoRespond' setting" - ); - }); - it("allows the 'autoRespondAfter' setting", function () { - var server = sinonFakeServer.create({ - autoRespondAfter: 500 - }); - assert.equals( - server.autoRespondAfter, - 500, - "fakeServer.create should accept 'autoRespondAfter' setting" - ); - }); - it("allows the 'respondImmediately' setting", function () { - var server = sinonFakeServer.create({ - respondImmediately: true - }); - assert( - server.respondImmediately, - "fakeServer.create should accept 'respondImmediately' setting" - ); - }); - it("allows the 'fakeHTTPMethods' setting", function () { - var server = sinonFakeServer.create({ - fakeHTTPMethods: true - }); - assert( - server.fakeHTTPMethods, - "fakeServer.create should accept 'fakeHTTPMethods' setting" - ); - }); - it("allows the 'unsafeHeadersEnabled' setting", function () { - var server = sinon.fakeServer.create({ - unsafeHeadersEnabled: false - }); - assert.defined( - server.unsafeHeadersEnabled, - "'unsafeHeadersEnabled' expected to be defined at server level"); - assert( - !server.unsafeHeadersEnabled, - "fakeServer.create should accept 'unsafeHeadersEnabled' setting" - ); - }); - it("does not assign a non-whitelisted setting", function () { - var server = sinonFakeServer.create({ - foo: true - }); - refute( - server.foo, - "fakeServer.create should not accept 'foo' settings" - ); - }); - }); - - it("fakes XMLHttpRequest", function () { - var sandbox = sinonSandbox.create(); - sandbox.stub(fakeXhr, "useFakeXMLHttpRequest").returns({ - restore: sinonStub() - }); - - this.server = sinonFakeServer.create(); - - assert(fakeXhr.useFakeXMLHttpRequest.called); - sandbox.restore(); - }); - - it("mirrors FakeXMLHttpRequest restore method", function () { - var sandbox = sinonSandbox.create(); - this.server = sinonFakeServer.create(); - var restore = sandbox.stub(FakeXMLHttpRequest, "restore"); - this.server.restore(); - - assert(restore.called); - sandbox.restore(); - }); - - describe(".requests", function () { - beforeEach(function () { - this.server = sinonFakeServer.create(); - }); - - afterEach(function () { - this.server.restore(); - }); - - it("collects objects created with fake XHR", function () { - var xhrs = [new FakeXMLHttpRequest(), new FakeXMLHttpRequest()]; - - assert.equals(this.server.requests, xhrs); - }); - - it("collects xhr objects through addRequest", function () { - this.server.addRequest = sinonSpy(); - var xhr = new FakeXMLHttpRequest(); - - assert(this.server.addRequest.calledWith(xhr)); - }); - - it("observes onSend on requests", function () { - var xhrs = [new FakeXMLHttpRequest(), new FakeXMLHttpRequest()]; - - assert.isFunction(xhrs[0].onSend); - assert.isFunction(xhrs[1].onSend); - }); - - it("onSend should call handleRequest with request object", function () { - var xhr = new FakeXMLHttpRequest(); - xhr.open("GET", "/"); - sinonSpy(this.server, "handleRequest"); - - xhr.send(); - - assert(this.server.handleRequest.called); - assert(this.server.handleRequest.calledWith(xhr)); - }); - }); - - describe(".handleRequest", function () { - beforeEach(function () { - this.server = sinonFakeServer.create(); - }); - - afterEach(function () { - this.server.restore(); - }); - - it("responds to synchronous requests", function () { - var xhr = new FakeXMLHttpRequest(); - xhr.open("GET", "/", false); - sinonSpy(xhr, "respond"); - - xhr.send(); - - assert(xhr.respond.called); - }); - - it("does not respond to async requests", function () { - var xhr = new FakeXMLHttpRequest(); - xhr.open("GET", "/", true); - sinonSpy(xhr, "respond"); - - xhr.send(); - - assert.isFalse(xhr.respond.called); - }); - }); - - describe(".respondWith", function () { - beforeEach(function () { - this.sandbox = sinonSandbox.create(); - - this.server = sinonFakeServer.create({ - setTimeout: this.sandbox.spy(), - useImmediateExceptions: false - }); - - this.getRootAsync = new FakeXMLHttpRequest(); - this.getRootAsync.open("GET", "/", true); - this.getRootAsync.send(); - sinonSpy(this.getRootAsync, "respond"); - - this.postRootAsync = new FakeXMLHttpRequest(); - this.postRootAsync.open("POST", "/", true); - this.postRootAsync.send(); - sinonSpy(this.postRootAsync, "respond"); - - this.getRootSync = new FakeXMLHttpRequest(); - this.getRootSync.open("GET", "/", false); - - this.getPathAsync = new FakeXMLHttpRequest(); - this.getPathAsync.open("GET", "/path", true); - this.getPathAsync.send(); - sinonSpy(this.getPathAsync, "respond"); - - this.postPathAsync = new FakeXMLHttpRequest(); - this.postPathAsync.open("POST", "/path", true); - this.postPathAsync.send(); - sinonSpy(this.postPathAsync, "respond"); - }); - - afterEach(function () { - this.server.restore(); - this.sandbox.restore(); - }); - - it("responds to queued async requests", function () { - this.server.respondWith("Oh yeah! Duffman!"); - - this.server.respond(); - - assert(this.getRootAsync.respond.called); - assert.equals(this.getRootAsync.respond.args[0], [200, {}, "Oh yeah! Duffman!"]); - }); - - it("responds to all queued async requests", function () { - this.server.respondWith("Oh yeah! Duffman!"); - - this.server.respond(); - - assert(this.getRootAsync.respond.called); - assert(this.getPathAsync.respond.called); - }); - - it("does not respond to requests queued after respond() (eg from callbacks)", function () { - var xhr; - this.getRootAsync.addEventListener("load", function () { - xhr = new FakeXMLHttpRequest(); - xhr.open("GET", "/", true); - xhr.send(); - sinonSpy(xhr, "respond"); - }); - - this.server.respondWith("Oh yeah! Duffman!"); - - this.server.respond(); - - assert(this.getRootAsync.respond.called); - assert(this.getPathAsync.respond.called); - assert(!xhr.respond.called); - - this.server.respond(); - - assert(xhr.respond.called); - }); - - it("responds with status, headers, and body", function () { - var headers = { "Content-Type": "X-test" }; - this.server.respondWith([201, headers, "Oh yeah!"]); - - this.server.respond(); - - assert.equals(this.getRootAsync.respond.args[0], [201, headers, "Oh yeah!"]); - }); - - it("handles responding with empty queue", function () { - delete this.server.queue; - var server = this.server; - - refute.exception(function () { - server.respond(); - }); - }); - - it("responds to sync request with canned answers", function () { - this.server.respondWith([210, { "X-Ops": "Yeah" }, "Body, man"]); - - this.getRootSync.send(); - - assert.equals(this.getRootSync.status, 210); - assert.equals(this.getRootSync.getAllResponseHeaders(), "X-Ops: Yeah\r\n"); - assert.equals(this.getRootSync.responseText, "Body, man"); - }); - - it("responds to sync request with 404 if no response is set", function () { - this.getRootSync.send(); - - assert.equals(this.getRootSync.status, 404); - assert.equals(this.getRootSync.getAllResponseHeaders(), ""); - assert.equals(this.getRootSync.responseText, ""); - }); - - it("responds to async request with 404 if no response is set", function () { - this.server.respond(); - - assert.equals(this.getRootAsync.respond.args[0], [404, {}, ""]); - }); - - it("responds to specific URL", function () { - this.server.respondWith("/path", "Duffman likes Duff beer"); - - this.server.respond(); - - assert.equals(this.getRootAsync.respond.args[0], [404, {}, ""]); - assert.equals(this.getPathAsync.respond.args[0], [200, {}, "Duffman likes Duff beer"]); - }); - - it("responds to URL matched by regexp", function () { - this.server.respondWith(/^\/p.*/, "Regexp"); - - this.server.respond(); - - assert.equals(this.getPathAsync.respond.args[0], [200, {}, "Regexp"]); - }); - - it("does not respond to URL not matched by regexp", function () { - this.server.respondWith(/^\/p.*/, "No regexp match"); - - this.server.respond(); - - assert.equals(this.getRootAsync.respond.args[0], [404, {}, ""]); - }); - - it("responds to all URLs matched by regexp", function () { - this.server.respondWith(/^\/.*/, "Match all URLs"); - - this.server.respond(); - - assert.equals(this.getRootAsync.respond.args[0], [200, {}, "Match all URLs"]); - assert.equals(this.getPathAsync.respond.args[0], [200, {}, "Match all URLs"]); - }); - - it("responds to all requests when match URL is falsy", function () { - this.server.respondWith("", "Falsy URL"); - - this.server.respond(); - - assert.equals(this.getRootAsync.respond.args[0], [200, {}, "Falsy URL"]); - assert.equals(this.getPathAsync.respond.args[0], [200, {}, "Falsy URL"]); - }); - - it("responds to all GET requests", function () { - this.server.respondWith("GET", "", "All GETs"); - - this.server.respond(); - - assert.equals(this.getRootAsync.respond.args[0], [200, {}, "All GETs"]); - assert.equals(this.getPathAsync.respond.args[0], [200, {}, "All GETs"]); - assert.equals(this.postRootAsync.respond.args[0], [404, {}, ""]); - assert.equals(this.postPathAsync.respond.args[0], [404, {}, ""]); - }); - - it("responds to all 'get' requests (case-insensitivity)", function () { - this.server.respondWith("get", "", "All GETs"); - - this.server.respond(); - - assert.equals(this.getRootAsync.respond.args[0], [200, {}, "All GETs"]); - assert.equals(this.getPathAsync.respond.args[0], [200, {}, "All GETs"]); - assert.equals(this.postRootAsync.respond.args[0], [404, {}, ""]); - assert.equals(this.postPathAsync.respond.args[0], [404, {}, ""]); - }); - - it("responds to all PUT requests", function () { - this.server.respondWith("PUT", "", "All PUTs"); - - this.server.respond(); - - assert.equals(this.getRootAsync.respond.args[0], [404, {}, ""]); - assert.equals(this.getPathAsync.respond.args[0], [404, {}, ""]); - assert.equals(this.postRootAsync.respond.args[0], [404, {}, ""]); - assert.equals(this.postPathAsync.respond.args[0], [404, {}, ""]); - }); - - it("responds to all POST requests", function () { - this.server.respondWith("POST", "", "All POSTs"); - - this.server.respond(); - - assert.equals(this.getRootAsync.respond.args[0], [404, {}, ""]); - assert.equals(this.getPathAsync.respond.args[0], [404, {}, ""]); - assert.equals(this.postRootAsync.respond.args[0], [200, {}, "All POSTs"]); - assert.equals(this.postPathAsync.respond.args[0], [200, {}, "All POSTs"]); - }); - - it("responds to all POST requests to /path", function () { - this.server.respondWith("POST", "/path", "All POSTs"); - - this.server.respond(); - - assert.equals(this.getRootAsync.respond.args[0], [404, {}, ""]); - assert.equals(this.getPathAsync.respond.args[0], [404, {}, ""]); - assert.equals(this.postRootAsync.respond.args[0], [404, {}, ""]); - assert.equals(this.postPathAsync.respond.args[0], [200, {}, "All POSTs"]); - }); - - it("responds to all POST requests matching regexp", function () { - this.server.respondWith("POST", /^\/path(\?.*)?/, "All POSTs"); - - this.server.respond(); - - assert.equals(this.getRootAsync.respond.args[0], [404, {}, ""]); - assert.equals(this.getPathAsync.respond.args[0], [404, {}, ""]); - assert.equals(this.postRootAsync.respond.args[0], [404, {}, ""]); - assert.equals(this.postPathAsync.respond.args[0], [200, {}, "All POSTs"]); - }); - - it("does not respond to aborted requests", function () { - this.server.respondWith("/", "That's my homepage!"); - this.getRootAsync.aborted = true; - - this.server.respond(); - - assert.isFalse(this.getRootAsync.respond.called); - }); - - it("resets requests", function () { - this.server.respondWith("/", "That's my homepage!"); - - this.server.respond(); - - assert.equals(this.server.queue, []); - }); - - it("notifies all requests when some throw", function () { - this.getRootAsync.respond = function () { - throw new Error("Oops!"); - }; - - this.server.respondWith(""); - this.server.respond(); - - assert.equals(this.getPathAsync.respond.args[0], [200, {}, ""]); - assert.equals(this.postRootAsync.respond.args[0], [200, {}, ""]); - assert.equals(this.postPathAsync.respond.args[0], [200, {}, ""]); - }); - - it("recognizes request with hostname", function () { - this.server.respondWith("/", [200, {}, "Yep"]); - var xhr = new FakeXMLHttpRequest(); - var loc = window.location; - xhr.open("GET", loc.protocol + "//" + loc.host + "/", true); - xhr.send(); - sinonSpy(xhr, "respond"); - - this.server.respond(); - - assert.equals(xhr.respond.args[0], [200, {}, "Yep"]); - }); - - it("accepts URLS which are common route DSLs", function () { - this.server.respondWith("/foo/*", [200, {}, "Yep"]); - - var xhr = new FakeXMLHttpRequest(); - xhr.respond = sinonSpy(); - xhr.open("GET", "/foo/bla/boo", true); - xhr.send(); - - this.server.respond(); - - assert.equals(xhr.respond.args[0], [200, {}, "Yep"]); - }); - - it("yields URL capture groups to response handler when using DSLs", function () { - var handler = sinonSpy(); - this.server.respondWith("GET", "/thing/:id", handler); - - var xhr = new FakeXMLHttpRequest(); - xhr.respond = sinonSpy(); - xhr.open("GET", "/thing/1337", true); - xhr.send(); - - this.server.respond(); - - assert(handler.called); - assert.equals(handler.args[0], [xhr, "1337"]); - }); - - it("throws understandable error if response is not a string", function () { - var server = this.server; - - assert.exception( - function () { - server.respondWith("/", {}); - }, - { - message: "Fake server response body should be string, but was object" - } - ); - }); - - it("throws understandable error if response in array is not a string", function () { - var server = this.server; - - assert.exception( - function () { - server.respondWith("/", [200, {}]); - }, - { - message: "Fake server response body should be string, but was undefined" - } - ); - }); - - it("is able to pass the same args to respond directly", function () { - this.server.respond("Oh yeah! Duffman!"); - - assert.equals(this.getRootAsync.respond.args[0], [200, {}, "Oh yeah! Duffman!"]); - assert.equals(this.getPathAsync.respond.args[0], [200, {}, "Oh yeah! Duffman!"]); - assert.equals(this.postRootAsync.respond.args[0], [200, {}, "Oh yeah! Duffman!"]); - assert.equals(this.postPathAsync.respond.args[0], [200, {}, "Oh yeah! Duffman!"]); - }); - - it("responds to most recently defined match", function () { - this.server.respondWith("POST", "", "All POSTs"); - this.server.respondWith("POST", "/path", "Particular POST"); - - this.server.respond(); - - assert.equals(this.postRootAsync.respond.args[0], [200, {}, "All POSTs"]); - assert.equals(this.postPathAsync.respond.args[0], [200, {}, "Particular POST"]); - }); - }); - - describe(".respondWith (FunctionHandler)", function () { - beforeEach(function () { - this.server = sinonFakeServer.create(); - }); - - afterEach(function () { - this.server.restore(); - }); - - it("yields response to request function handler", function () { - var handler = sinonSpy(); - this.server.respondWith("/hello", handler); - var xhr = new FakeXMLHttpRequest(); - xhr.open("GET", "/hello"); - xhr.send(); - - this.server.respond(); - - assert(handler.calledOnce); - assert(handler.calledWith(xhr)); - }); - - it("responds to request from function handler", function () { - this.server.respondWith("/hello", function (xhr) { - xhr.respond(200, { "Content-Type": "application/json" }, "{\"id\":42}"); - }); - - var request = new FakeXMLHttpRequest(); - request.open("GET", "/hello"); - request.send(); - - this.server.respond(); - - assert.equals(request.status, 200); - assert.equals(request.responseHeaders, { "Content-Type": "application/json" }); - assert.equals(request.responseText, "{\"id\":42}"); - }); - - it("yields response to request function handler when method matches", function () { - var handler = sinonSpy(); - this.server.respondWith("GET", "/hello", handler); - var xhr = new FakeXMLHttpRequest(); - xhr.open("GET", "/hello"); - xhr.send(); - - this.server.respond(); - - assert(handler.calledOnce); - }); - - it("yields response to request function handler when url contains RegExp characters", function () { - var handler = sinonSpy(); - this.server.respondWith("GET", "/hello?world", handler); - var xhr = new FakeXMLHttpRequest(); - xhr.open("GET", "/hello?world"); - xhr.send(); - - this.server.respond(); - - assert(handler.calledOnce); - }); - - it("does not yield response to request function handler when method does not match", function () { - var handler = sinonSpy(); - this.server.respondWith("GET", "/hello", handler); - var xhr = new FakeXMLHttpRequest(); - xhr.open("POST", "/hello"); - xhr.send(); - - this.server.respond(); - - assert(!handler.called); - }); - - it("yields response to request function handler when regexp url matches", function () { - var handler = sinonSpy(); - this.server.respondWith("GET", /\/.*/, handler); - var xhr = new FakeXMLHttpRequest(); - xhr.open("GET", "/hello"); - xhr.send(); - - this.server.respond(); - - assert(handler.calledOnce); - }); - - it("does not yield response to request function handler when regexp url does not match", function () { - var handler = sinonSpy(); - this.server.respondWith("GET", /\/a.*/, handler); - var xhr = new FakeXMLHttpRequest(); - xhr.open("GET", "/hello"); - xhr.send(); - - this.server.respond(); - - assert(!handler.called); - }); - - it("adds function handler without method or url filter", function () { - this.server.respondWith(function (xhr) { - xhr.respond(200, { "Content-Type": "application/json" }, "{\"id\":42}"); - }); - - var request = new FakeXMLHttpRequest(); - request.open("GET", "/whatever"); - request.send(); - - this.server.respond(); - - assert.equals(request.status, 200); - assert.equals(request.responseHeaders, { "Content-Type": "application/json" }); - assert.equals(request.responseText, "{\"id\":42}"); - }); - - it("does not process request further if processed by function", function () { - var handler = sinonSpy(); - this.server.respondWith("GET", "/aloha", [200, {}, "Oh hi"]); - this.server.respondWith("GET", /\/a.*/, handler); - var xhr = new FakeXMLHttpRequest(); - xhr.respond = sinonSpy(); - xhr.open("GET", "/aloha"); - xhr.send(); - - this.server.respond(); - - assert(handler.called); - assert(xhr.respond.calledOnce); - }); - - it("yields URL capture groups to response handler", function () { - var handler = sinonSpy(); - this.server.respondWith("GET", /\/people\/(\d+)/, handler); - var xhr = new FakeXMLHttpRequest(); - xhr.respond = sinonSpy(); - xhr.open("GET", "/people/3"); - xhr.send(); - - this.server.respond(); - - assert(handler.called); - assert.equals(handler.args[0], [xhr, "3"]); - }); - }); - - describe("respond with fake HTTP Verb", function () { - beforeEach(function () { - this.server = sinonFakeServer.create(); - - this.request = new FakeXMLHttpRequest(); - this.request.open("post", "/path", true); - this.request.send("_method=delete"); - sinonSpy(this.request, "respond"); - }); - - afterEach(function () { - this.server.restore(); - }); - - it("does not respond to DELETE request with _method parameter", function () { - this.server.respondWith("DELETE", "", ""); - - this.server.respond(); - - assert.equals(this.request.respond.args[0], [404, {}, ""]); - }); - - it("responds to 'fake' DELETE request", function () { - this.server.fakeHTTPMethods = true; - this.server.respondWith("DELETE", "", "OK"); - - this.server.respond(); - - assert.equals(this.request.respond.args[0], [200, {}, "OK"]); - }); - - it("does not respond to POST when faking DELETE", function () { - this.server.fakeHTTPMethods = true; - this.server.respondWith("POST", "", "OK"); - - this.server.respond(); - - assert.equals(this.request.respond.args[0], [404, {}, ""]); - }); - - it("does not fake method when not POSTing", function () { - this.server.fakeHTTPMethods = true; - this.server.respondWith("DELETE", "", "OK"); - - var request = new FakeXMLHttpRequest(); - request.open("GET", "/"); - request.send(); - request.respond = sinonSpy(); - this.server.respond(); - - assert.equals(request.respond.args[0], [404, {}, ""]); - }); - - it("customizes HTTP method extraction", function () { - this.server.getHTTPMethod = function () { - return "PUT"; - }; - - this.server.respondWith("PUT", "", "OK"); - - this.server.respond(); - - assert.equals(this.request.respond.args[0], [200, {}, "OK"]); - }); - - it("does not fail when getting the HTTP method from a request with no body", function () { - var server = this.server; - server.fakeHTTPMethods = true; - - assert.equals(server.getHTTPMethod({ method: "POST" }), "POST"); - }); - }); - - describe(".autoResponse", function () { - beforeEach(function () { - this.get = function get(url) { - var request = new FakeXMLHttpRequest(); - sinonSpy(request, "respond"); - request.open("get", url, true); - request.send(); - return request; - }; - - this.server = sinonFakeServer.create(); - this.clock = fakeTimers.useFakeTimers(); - }); - - afterEach(function () { - this.server.restore(); - this.clock.restore(); - }); - - it("responds async automatically after 10ms", function () { - this.server.autoRespond = true; - var request = this.get("/path"); - - this.clock.tick(10); - - assert.isTrue(request.respond.calledOnce); - }); - - it("normal server does not respond automatically", function () { - var request = this.get("/path"); - - this.clock.tick(100); - - assert.isTrue(!request.respond.called); - }); - - it("auto-responds only once", function () { - this.server.autoRespond = true; - var requests = [this.get("/path")]; - this.clock.tick(5); - requests.push(this.get("/other")); - this.clock.tick(5); - - assert.isTrue(requests[0].respond.calledOnce); - assert.isTrue(requests[1].respond.calledOnce); - }); - - it("auto-responds after having already responded", function () { - this.server.autoRespond = true; - var requests = [this.get("/path")]; - this.clock.tick(10); - requests.push(this.get("/other")); - this.clock.tick(10); - - assert.isTrue(requests[0].respond.calledOnce); - assert.isTrue(requests[1].respond.calledOnce); - }); - - it("sets auto-respond timeout to 50ms", function () { - this.server.autoRespond = true; - this.server.autoRespondAfter = 50; - - var request = this.get("/path"); - this.clock.tick(49); - assert.isFalse(request.respond.called); - - this.clock.tick(1); - assert.isTrue(request.respond.calledOnce); - }); - - it("auto-responds if two successive requests are made with a single XHR", function () { - this.server.autoRespond = true; - - var request = this.get("/path"); - - this.clock.tick(10); - - assert.isTrue(request.respond.calledOnce); - - request.open("get", "/other", true); - request.send(); - - this.clock.tick(10); - - assert.isTrue(request.respond.calledTwice); - }); - - it("auto-responds if timeout elapses between creating XHR object and sending request with it", function () { - this.server.autoRespond = true; - - var request = new FakeXMLHttpRequest(); - sinonSpy(request, "respond"); - - this.clock.tick(100); - - request.open("get", "/path", true); - request.send(); - - this.clock.tick(10); - - assert.isTrue(request.respond.calledOnce); - }); - }); - - describe(".respondImmediately", function () { - beforeEach(function () { - this.get = function get(url) { - var request = new FakeXMLHttpRequest(); - sinonSpy(request, "respond"); - request.open("get", url, true); - request.send(); - return request; - }; - - this.server = sinonFakeServer.create(); - this.server.respondImmediately = true; - }); - - afterEach(function () { - this.server.restore(); - }); - - it("responds synchronously", function () { - var request = this.get("/path"); - assert.isTrue(request.respond.calledOnce); - }); - - it("doesn't rely on a clock", function () { - this.clock = fakeTimers.useFakeTimers(); - - var request = this.get("/path"); - assert.isTrue(request.respond.calledOnce); - - this.clock.restore(); - }); - }); - - describe(".log", function () { - beforeEach(function () { - this.server = sinonFakeServer.create(); - }); - - afterEach(function () { - this.server.restore(); - }); - - it("logs response and request", function () { - sinonSpy(this.server, "log"); - var xhr = new FakeXMLHttpRequest(); - xhr.open("GET", "/hello"); - xhr.send(); - var response = [200, {}, "Hello!"]; - this.server.respond("GET", /.*/, response); - assert(this.server.log.calledOnce); - assert(this.server.log.calledWithExactly(response, xhr)); - }); - - it("can be overridden", function () { - this.server.log = sinonSpy(); - var xhr = new FakeXMLHttpRequest(); - xhr.open("GET", "/hello"); - xhr.send(); - var response = [200, {}, "Hello!"]; - this.server.respond("GET", /.*/, response); - assert(this.server.log.calledOnce); - assert(this.server.log.calledWithExactly(response, xhr)); - }); - }); - - describe(".reset", function () { - beforeEach(function () { - this.server = sinonFakeServer.create(); - - this.resetBehaviorStub = sinonStub(this.server, "resetBehavior"); - this.resetHistoryStub = sinonStub(this.server, "resetHistory"); - }); - - afterEach(function () { - this.server.restore(); - this.resetBehaviorStub.restore(); - this.resetHistoryStub.restore(); - }); - - it("should call resetBehavior and resetHistory", function () { - assert(this.resetBehaviorStub.notCalled); - assert(this.resetHistoryStub.notCalled); - - this.server.reset(); - - assert(this.resetBehaviorStub.calledOnce); - assert(this.resetBehaviorStub.calledWithExactly()); - - assert(this.resetHistoryStub.calledOnce); - assert(this.resetHistoryStub.calledWithExactly()); - - assert(this.resetBehaviorStub.calledBefore(this.resetHistoryStub)); - }); - }); - - describe(".resetBehavior", function () { - before(function () { - // capture default response - var self = this; - - sinonFakeServer.processRequest.call( - {log: function (response) { self.defaultResponse = response; }}, - {respond: function () {}} - ); - }); - - function makeRequest(context) { - context.request = new FakeXMLHttpRequest(); - context.request.open("get", "url", true); - context.request.send(null); - - sinonSpy(context.request, "respond"); - } - - beforeEach(function () { - this.server = sinonFakeServer.create(); - - this.testResponse = [200, {}, "OK"]; - - this.server.respondWith("GET", "url", this.testResponse); - - makeRequest(this); - }); - - it("should reset behavior", function () { - this.server.resetBehavior(); - - assert.equals(this.server.queue.length, 0); - assert.equals(this.server.responses.length, 0); - }); - - it("should work as expected", function () { - this.server.respond(); - - assert.equals(this.request.respond.args[0], this.testResponse); - - this.server.resetBehavior(); - - makeRequest(this); - - this.server.respond(); - - assert.equals(this.request.respond.args[0], this.defaultResponse); - }); - - it("should be idempotent", function () { - this.server.respond(); - - assert.equals(this.request.respond.args[0], this.testResponse); - - // calling N times should have the same effect as calling once - this.server.resetBehavior(); - this.server.resetBehavior(); - this.server.resetBehavior(); - - makeRequest(this); - - this.server.respond(); - - assert.equals(this.request.respond.args[0], this.defaultResponse); - }); - }); - - describe("history", function () { - function assertDefaultServerState(server) { - refute(server.requestedOnce); - refute(server.requestedTwice); - refute(server.requestedThrice); - refute(server.requested); - - refute(server.firstRequest); - refute(server.secondRequest); - refute(server.thirdRequest); - refute(server.lastRequest); - } - - function makeRequest() { - var request = new FakeXMLHttpRequest(); - request.open("get", "url", true); - request.send(null); - } - - beforeEach(function () { - this.server = sinonFakeServer.create(); - }); - - describe(".getRequest", function () { - it("should handle invalid indexes", function () { - assert.isNull(this.server.getRequest(1e3)); - assert.isNull(this.server.getRequest(0)); - assert.isNull(this.server.getRequest(-2)); - assert.isNull(this.server.getRequest("catpants")); - }); - - it("should return expected requests", function () { - makeRequest(); - - assert.equals(this.server.getRequest(0), this.server.requests[0]); - assert.isNull(this.server.getRequest(1)); - - makeRequest(); - - assert.equals(this.server.getRequest(1), this.server.requests[1]); - }); - }); - - describe(".resetHistory", function () { - it("should reset history", function () { - makeRequest(); - makeRequest(); - - assert.isTrue(this.server.requested); - assert.isTrue(this.server.requestedTwice); - - this.server.resetHistory(); - - assertDefaultServerState(this.server); - }); - - it("should be idempotent", function () { - makeRequest(); - makeRequest(); - - assert.isTrue(this.server.requested); - assert.isTrue(this.server.requestedTwice); - - this.server.resetHistory(); - this.server.resetHistory(); - this.server.resetHistory(); - - assertDefaultServerState(this.server); - }); - }); - - it("should start in a known default state", function () { - assertDefaultServerState(this.server); - }); - - it("should record requests", function () { - makeRequest(); - - assert.isTrue(this.server.requested); - assert.isTrue(this.server.requestedOnce); - assert.isFalse(this.server.requestedTwice); - assert.isFalse(this.server.requestedThrice); - assert.equals(this.server.requestCount, 1); - - assert.equals(this.server.firstRequest, this.server.requests[0]); - assert.equals(this.server.lastRequest, this.server.requests[0]); - - // #2 - makeRequest(); - - assert.isTrue(this.server.requested); - assert.isFalse(this.server.requestedOnce); - assert.isTrue(this.server.requestedTwice); - assert.isFalse(this.server.requestedThrice); - assert.equals(this.server.requestCount, 2); - - assert.equals(this.server.firstRequest, this.server.requests[0]); - assert.equals(this.server.secondRequest, this.server.requests[1]); - assert.equals(this.server.lastRequest, this.server.requests[1]); - - // #3 - makeRequest(); - - assert.isTrue(this.server.requested); - assert.isFalse(this.server.requestedOnce); - assert.isFalse(this.server.requestedTwice); - assert.isTrue(this.server.requestedThrice); - assert.equals(this.server.requestCount, 3); - - assert.equals(this.server.firstRequest, this.server.requests[0]); - assert.equals(this.server.secondRequest, this.server.requests[1]); - assert.equals(this.server.thirdRequest, this.server.requests[2]); - assert.equals(this.server.lastRequest, this.server.requests[2]); - - // #4 - makeRequest(); - - assert.isTrue(this.server.requested); - assert.isFalse(this.server.requestedOnce); - assert.isFalse(this.server.requestedTwice); - assert.isFalse(this.server.requestedThrice); - assert.equals(this.server.requestCount, 4); - - assert.equals(this.server.firstRequest, this.server.requests[0]); - assert.equals(this.server.secondRequest, this.server.requests[1]); - assert.equals(this.server.thirdRequest, this.server.requests[2]); - assert.equals(this.server.lastRequest, this.server.requests[3]); - }); - }); - }); -} diff --git a/test/util/fake-server-with-clock-test.js b/test/util/fake-server-with-clock-test.js deleted file mode 100644 index 1acf07621..000000000 --- a/test/util/fake-server-with-clock-test.js +++ /dev/null @@ -1,236 +0,0 @@ -"use strict"; - -var referee = require("referee"); -var sinonFakeServerWithClock = require("../../lib/sinon/util/fake_server_with_clock"); -var sinonFakeServer = require("../../lib/sinon/util/fake_server"); -var sinonSandbox = require("../../lib/sinon/sandbox"); -var fakeTimers = require("../../lib/sinon/util/fake_timers"); -var sinonSpy = require("../../lib/sinon/spy"); -var FakeXMLHttpRequest = require("../../lib/sinon/util/fake_xml_http_request").FakeXMLHttpRequest; -var assert = referee.assert; -var refute = referee.refute; - -if (typeof window !== "undefined") { - describe("sinonFakeServerWithClock", function () { - - describe("without pre-existing fake clock", function () { - beforeEach(function () { - this.server = sinonFakeServerWithClock.create(); - }); - - afterEach(function () { - this.server.restore(); - if (this.clock) { - this.clock.restore(); - } - }); - - it("calls 'super' when adding requests", function () { - var sandbox = sinonSandbox.create(); - var addRequest = sandbox.stub(sinonFakeServer, "addRequest"); - var xhr = {}; - this.server.addRequest(xhr); - - assert(addRequest.calledWith(xhr)); - assert(addRequest.calledOn(this.server)); - sandbox.restore(); - }); - - it("sets reference to clock when adding async request", function () { - this.server.addRequest({ async: true }); - - assert.isObject(this.server.clock); - assert.isFunction(this.server.clock.tick); - }); - - it("sets longest timeout from setTimeout", function () { - this.server.addRequest({ async: true }); - - setTimeout(function () {}, 12); - setTimeout(function () {}, 29); - setInterval(function () {}, 12); - setTimeout(function () {}, 27); - - assert.equals(this.server.longestTimeout, 29); - }); - - it("sets longest timeout from setInterval", function () { - this.server.addRequest({ async: true }); - - setTimeout(function () {}, 12); - setTimeout(function () {}, 29); - setInterval(function () {}, 132); - setTimeout(function () {}, 27); - - assert.equals(this.server.longestTimeout, 132); - }); - - it("resets clock", function () { - this.server.addRequest({ async: true }); - - this.server.respond(""); - assert.same(setTimeout, fakeTimers.timers.setTimeout); - }); - - it("does not reset clock second time", function () { - this.server.addRequest({ async: true }); - this.server.respond(""); - this.clock = fakeTimers.useFakeTimers(); - this.server.addRequest({ async: true }); - this.server.respond(""); - - refute.same(setTimeout, fakeTimers.timers.setTimeout); - }); - }); - - describe("existing clock", function () { - beforeEach(function () { - this.clock = fakeTimers.useFakeTimers(); - this.server = sinonFakeServerWithClock.create(); - }); - - afterEach(function () { - this.clock.restore(); - this.server.restore(); - }); - - it("uses existing clock", function () { - this.server.addRequest({ async: true }); - - assert.same(this.server.clock, this.clock); - }); - - it("records longest timeout using setTimeout and existing clock", function () { - this.server.addRequest({ async: true }); - - setInterval(function () {}, 42); - setTimeout(function () {}, 23); - setTimeout(function () {}, 53); - setInterval(function () {}, 12); - - assert.same(this.server.longestTimeout, 53); - }); - - it("records longest timeout using setInterval and existing clock", function () { - this.server.addRequest({ async: true }); - - setInterval(function () {}, 92); - setTimeout(function () {}, 73); - setTimeout(function () {}, 53); - setInterval(function () {}, 12); - - assert.same(this.server.longestTimeout, 92); - }); - - it("does not reset clock", function () { - this.server.respond(""); - - assert.same(setTimeout.clock, this.clock); - }); - }); - - describe(".respond", function () { - var sandbox; - - beforeEach(function () { - this.server = sinonFakeServerWithClock.create(); - this.server.addRequest({ async: true }); - }); - - afterEach(function () { - this.server.restore(); - if (sandbox) { - sandbox.restore(); - sandbox = null; - } - }); - - it("ticks the clock to fire the longest timeout", function () { - this.server.longestTimeout = 96; - - this.server.respond(); - - assert.equals(this.server.clock.now, 96); - }); - - it("ticks the clock to fire the longest timeout when multiple responds", function () { - setInterval(function () {}, 13); - this.server.respond(); - var xhr = new FakeXMLHttpRequest(); - // please the linter, we can't have unused variables - // even when we're instantiating FakeXMLHttpRequest for its side effects - assert(xhr); - setInterval(function () {}, 17); - this.server.respond(); - - assert.equals(this.server.clock.now, 17); - }); - - it("resets longest timeout", function () { - this.server.longestTimeout = 96; - - this.server.respond(); - - assert.equals(this.server.longestTimeout, 0); - }); - - it("calls original respond", function () { - sandbox = sinonSandbox.create(); - var obj = {}; - var respond = sandbox.stub(sinonFakeServer, "respond").returns(obj); - - var result = this.server.respond("GET", "/", ""); - - assert.equals(result, obj); - assert(respond.calledWith("GET", "/", "")); - assert(respond.calledOn(this.server)); - }); - }); - - describe("jQuery compat mode", function () { - beforeEach(function () { - this.server = sinonFakeServerWithClock.create(); - - this.request = new FakeXMLHttpRequest(); - this.request.open("get", "/", true); - this.request.send(); - sinonSpy(this.request, "respond"); - }); - - afterEach(function () { - this.server.restore(); - }); - - it("handles clock automatically", function () { - this.server.respondWith("OK"); - var spy = sinonSpy(); - - setTimeout(spy, 13); - this.server.respond(); - this.server.restore(); - - assert(spy.called); - assert.same(setTimeout, fakeTimers.timers.setTimeout); - }); - - it("finishes xhr from setInterval like jQuery 1.3.x does", function () { - this.server.respondWith("Hello World"); - var xhr = new FakeXMLHttpRequest(); - xhr.open("GET", "/"); - xhr.send(); - - var spy = sinonSpy(); - - setInterval(function () { - spy(xhr.responseText, xhr.statusText, xhr); - }, 13); - - this.server.respond(); - - assert.equals(spy.args[0][0], "Hello World"); - assert.equals(spy.args[0][1], "OK"); - assert.equals(spy.args[0][2].status, 200); - }); - }); - }); -} diff --git a/test/util/fake-xml-http-request-test.js b/test/util/fake-xml-http-request-test.js deleted file mode 100644 index 31a44f165..000000000 --- a/test/util/fake-xml-http-request-test.js +++ /dev/null @@ -1,2322 +0,0 @@ -"use strict"; - -var referee = require("referee"); -var sinonStub = require("../../lib/sinon/stub"); -var sinonSpy = require("../../lib/sinon/spy"); -var sinonExtend = require("../../lib/sinon/util/core/extend"); -var sinonSandbox = require("../../lib/sinon/sandbox"); -var sinonFakeXhr = require("../../lib/sinon/util/fake_xml_http_request"); -var sinon = require("../../lib/sinon"); - -var TextDecoder = global.TextDecoder || require("text-encoding").TextDecoder; -var FakeXMLHttpRequest = sinonFakeXhr.FakeXMLHttpRequest; -var assert = referee.assert; -var refute = referee.refute; - -var globalXMLHttpRequest = global.XMLHttpRequest; -var globalActiveXObject = global.ActiveXObject; - -var supportsProgressEvents = typeof ProgressEvent !== "undefined"; -var supportsFormData = typeof FormData !== "undefined"; -var supportsArrayBuffer = typeof ArrayBuffer !== "undefined"; -var supportsBlob = require("../../lib/sinon/blob").isSupported; - -var fakeXhrSetUp = function () { - this.fakeXhr = sinonFakeXhr.useFakeXMLHttpRequest(); -}; - -var fakeXhrTearDown = function () { - if (typeof this.fakeXhr.restore === "function") { - this.fakeXhr.restore(); - } -}; - -var runWithWorkingXHROveride = function (workingXHR, test) { - try { // eslint-disable-line no-restricted-syntax - var original = sinonFakeXhr.xhr.workingXHR; - sinonFakeXhr.xhr.workingXHR = workingXHR; - test(); - } finally { - sinonFakeXhr.xhr.workingXHR = original; - } -}; - -var assertArrayBufferMatches = function (actual, expected, encoding) { - assert(actual instanceof ArrayBuffer, "${0} expected to be an ArrayBuffer"); - var actualString = new TextDecoder(encoding || "utf-8").decode(actual); - assert.same(actualString, expected, "ArrayBuffer [${0}] expected to match ArrayBuffer [${1}]"); -}; - -var assertBlobMatches = function (actual, expected, done) { - var actualReader = new FileReader(); - actualReader.onloadend = function () { - assert.same(actualReader.result, expected); - done(); - }; - actualReader.readAsText(actual); -}; - -var assertProgressEvent = function (event, progress) { - assert.equals(event.loaded, progress); - assert.equals(event.total, progress); - assert.equals(event.lengthComputable, !!progress); -}; - -var assertEventOrdering = function (event, progress, callback) { - it("should follow request sequence for " + event, function (done) { - var expectedOrder = [ - "upload:progress", - "upload:" + event, - "upload:loadend", - "xhr:progress", - "xhr:on" + event, - "xhr:" + event - ]; - var eventOrder = []; - - function observe(name) { - return function (e) { - assertProgressEvent(e, progress); - eventOrder.push(name); - }; - } - - this.xhr.open("GET", "/"); - this.xhr.send(); - - this.xhr.upload.addEventListener("progress", observe("upload:progress")); - this.xhr.upload.addEventListener("loadend", observe("upload:loadend")); - this.xhr.addEventListener("progress", observe("xhr:progress")); - this.xhr.addEventListener("loadend", function (e) { - assertProgressEvent(e, progress); - - // finish next tick to allow any events that might fire - // after loadend to trigger - setTimeout(function () { - assert.equals(eventOrder, expectedOrder); - - done(); - }, 1); - }); - - // listen for abort, error, and load events to make sure only - // the expected events fire - ["abort", "error", "load"].forEach( - function (name) { - this.xhr.upload.addEventListener(name, observe("upload:" + name)); - this.xhr.addEventListener(name, observe("xhr:" + name)); - this.xhr["on" + name] = observe("xhr:on" + name); - }, - this - ); - - callback(this.xhr); - }); -}; - -if (typeof window !== "undefined") { - describe("FakeXMLHttpRequest", function () { - - afterEach(function () { - delete FakeXMLHttpRequest.onCreate; - }); - - it("is constructor", function () { - assert.isFunction(FakeXMLHttpRequest); - assert.same(FakeXMLHttpRequest.prototype.constructor, FakeXMLHttpRequest); - }); - - it("class implements readyState constants", function () { - assert.same(FakeXMLHttpRequest.OPENED, 1); - assert.same(FakeXMLHttpRequest.HEADERS_RECEIVED, 2); - assert.same(FakeXMLHttpRequest.LOADING, 3); - assert.same(FakeXMLHttpRequest.DONE, 4); - }); - - it("instance implements readyState constants", function () { - var xhr = new FakeXMLHttpRequest(); - - assert.same(xhr.OPENED, 1); - assert.same(xhr.HEADERS_RECEIVED, 2); - assert.same(xhr.LOADING, 3); - assert.same(xhr.DONE, 4); - }); - - it("calls onCreate if listener is set", function () { - var onCreate = sinonSpy(); - FakeXMLHttpRequest.onCreate = onCreate; - - // instantiating FakeXMLHttpRequest for its onCreate side effect - var xhr = new FakeXMLHttpRequest(); // eslint-disable-line no-unused-vars - - assert(onCreate.called); - }); - - it("passes new object to onCreate if set", function () { - var onCreate = sinonSpy(); - FakeXMLHttpRequest.onCreate = onCreate; - - var xhr = new FakeXMLHttpRequest(); - - assert.same(onCreate.getCall(0).args[0], xhr); - }); - - describe(".withCredentials", function () { - beforeEach(function () { - this.xhr = new FakeXMLHttpRequest(); - }); - - it("property is set if we support standards CORS", function () { - assert.equals(sinonFakeXhr.xhr.supportsCORS, "withCredentials" in this.xhr); - }); - - }); - - describe(".open", function () { - beforeEach(function () { - this.xhr = new FakeXMLHttpRequest(); - }); - - it("is method", function () { - assert.isFunction(this.xhr.open); - }); - - it("sets properties on object", function () { - this.xhr.open("GET", "/my/url", true, "cjno", "pass"); - - assert.equals(this.xhr.method, "GET"); - assert.equals(this.xhr.url, "/my/url"); - assert.isTrue(this.xhr.async); - assert.equals(this.xhr.username, "cjno"); - assert.equals(this.xhr.password, "pass"); - }); - - it("is async by default", function () { - this.xhr.open("GET", "/my/url"); - - assert.isTrue(this.xhr.async); - }); - - it("sets async to false", function () { - this.xhr.open("GET", "/my/url", false); - - assert.isFalse(this.xhr.async); - }); - - it("sets response to empty string", function () { - this.xhr.open("GET", "/my/url"); - - assert.same(this.xhr.response, ""); - }); - - it("sets responseText to empty string", function () { - this.xhr.open("GET", "/my/url"); - - assert.same(this.xhr.responseText, ""); - }); - - it("sets responseXML to null", function () { - this.xhr.open("GET", "/my/url"); - - assert.isNull(this.xhr.responseXML); - }); - - it("sets requestHeaders to blank object", function () { - this.xhr.open("GET", "/my/url"); - - assert.isObject(this.xhr.requestHeaders); - assert.equals(this.xhr.requestHeaders, {}); - }); - - it("sets readyState to OPENED", function () { - this.xhr.open("GET", "/my/url"); - - assert.same(this.xhr.readyState, FakeXMLHttpRequest.OPENED); - }); - - it("sets send flag to false", function () { - this.xhr.open("GET", "/my/url"); - - assert.isFalse(this.xhr.sendFlag); - }); - - it("dispatches onreadystatechange with reset state", function () { - var state = {}; - - this.xhr.onreadystatechange = function () { - sinonExtend(state, this); - }; - - this.xhr.open("GET", "/my/url"); - - assert.equals(state.method, "GET"); - assert.equals(state.url, "/my/url"); - assert.isTrue(state.async); - refute.defined(state.username); - refute.defined(state.password); - assert.same(state.response, ""); - assert.same(state.responseText, ""); - assert.isNull(state.responseXML); - refute.defined(state.responseHeaders); - assert.equals(state.readyState, FakeXMLHttpRequest.OPENED); - assert.isFalse(state.sendFlag); - }); - }); - - describe(".setRequestHeader", function () { - beforeEach(function () { - this.xhr = new FakeXMLHttpRequest(); - this.xhr.open("GET", "/"); - }); - - it("throws exception if readyState is not OPENED", function () { - var xhr = new FakeXMLHttpRequest(); - - assert.exception(function () { - xhr.setRequestHeader("X-EY", "No-no"); - }); - }); - - it("throws exception if send flag is true", function () { - var xhr = this.xhr; - xhr.sendFlag = true; - - assert.exception(function () { - xhr.setRequestHeader("X-EY", "No-no"); - }); - }); - - it("disallows unsafe headers by default", function () { - var xhr = this.xhr; - - assert.exception(function () { - xhr.setRequestHeader("Accept-Charset", ""); - }); - - assert.exception(function () { - xhr.setRequestHeader("Accept-Encoding", ""); - }); - - assert.exception(function () { - xhr.setRequestHeader("Connection", ""); - }); - - assert.exception(function () { - xhr.setRequestHeader("Content-Length", ""); - }); - - assert.exception(function () { - xhr.setRequestHeader("Cookie", ""); - }); - - assert.exception(function () { - xhr.setRequestHeader("Cookie2", ""); - }); - - assert.exception(function () { - xhr.setRequestHeader("Content-Transfer-Encoding", ""); - }); - - assert.exception(function () { - xhr.setRequestHeader("Date", ""); - }); - - assert.exception(function () { - xhr.setRequestHeader("Expect", ""); - }); - - assert.exception(function () { - xhr.setRequestHeader("Host", ""); - }); - - assert.exception(function () { - xhr.setRequestHeader("Keep-Alive", ""); - }); - - assert.exception(function () { - xhr.setRequestHeader("Referer", ""); - }); - - assert.exception(function () { - xhr.setRequestHeader("TE", ""); - }); - - assert.exception(function () { - xhr.setRequestHeader("Trailer", ""); - }); - - assert.exception(function () { - xhr.setRequestHeader("Transfer-Encoding", ""); - }); - - assert.exception(function () { - xhr.setRequestHeader("Upgrade", ""); - }); - - assert.exception(function () { - xhr.setRequestHeader("User-Agent", ""); - }); - - assert.exception(function () { - xhr.setRequestHeader("Via", ""); - }); - - assert.exception(function () { - xhr.setRequestHeader("Proxy-Oops", ""); - }); - - assert.exception(function () { - xhr.setRequestHeader("Sec-Oops", ""); - }); - }); - - it("allows unsafe headers when fake server unsafeHeadersEnabled option is turned off", function () { - var server = sinon.fakeServer.create({ - unsafeHeadersEnabled: false - }); - - var xhr = new sinon.FakeXMLHttpRequest(); - xhr.open("GET", "/"); - - refute.exception(function () { - xhr.setRequestHeader("Accept-Charset", ""); - }); - - refute.exception(function () { - xhr.setRequestHeader("Accept-Encoding", ""); - }); - - refute.exception(function () { - xhr.setRequestHeader("Connection", ""); - }); - - refute.exception(function () { - xhr.setRequestHeader("Content-Length", ""); - }); - - refute.exception(function () { - xhr.setRequestHeader("Cookie", ""); - }); - - refute.exception(function () { - xhr.setRequestHeader("Cookie2", ""); - }); - - refute.exception(function () { - xhr.setRequestHeader("Content-Transfer-Encoding", ""); - }); - - refute.exception(function () { - xhr.setRequestHeader("Date", ""); - }); - - refute.exception(function () { - xhr.setRequestHeader("Expect", ""); - }); - - refute.exception(function () { - xhr.setRequestHeader("Host", ""); - }); - - refute.exception(function () { - xhr.setRequestHeader("Keep-Alive", ""); - }); - - refute.exception(function () { - xhr.setRequestHeader("Referer", ""); - }); - - refute.exception(function () { - xhr.setRequestHeader("TE", ""); - }); - - refute.exception(function () { - xhr.setRequestHeader("Trailer", ""); - }); - - refute.exception(function () { - xhr.setRequestHeader("Transfer-Encoding", ""); - }); - - refute.exception(function () { - xhr.setRequestHeader("Upgrade", ""); - }); - - refute.exception(function () { - xhr.setRequestHeader("User-Agent", ""); - }); - - refute.exception(function () { - xhr.setRequestHeader("Via", ""); - }); - - refute.exception(function () { - xhr.setRequestHeader("Proxy-Oops", ""); - }); - - refute.exception(function () { - xhr.setRequestHeader("Sec-Oops", ""); - }); - - server.restore(); - }); - - it("sets header and value", function () { - this.xhr.setRequestHeader("X-Fake", "Yeah!"); - - assert.equals(this.xhr.requestHeaders, { "X-Fake": "Yeah!" }); - }); - - it("appends same-named header values", function () { - this.xhr.setRequestHeader("X-Fake", "Oh"); - this.xhr.setRequestHeader("X-Fake", "yeah!"); - - assert.equals(this.xhr.requestHeaders, { "X-Fake": "Oh,yeah!" }); - }); - }); - - describe(".send", function () { - beforeEach(function () { - this.xhr = new FakeXMLHttpRequest(); - }); - - it("throws if request is not open", function () { - var xhr = new FakeXMLHttpRequest(); - - assert.exception(function () { - xhr.send(); - }); - }); - - it("throws if send flag is true", function () { - var xhr = this.xhr; - xhr.open("GET", "/"); - xhr.sendFlag = true; - - assert.exception(function () { - xhr.send(); - }); - }); - - it("sets HEAD body to null", function () { - this.xhr.open("HEAD", "/"); - this.xhr.send("Data"); - - assert.isNull(this.xhr.requestBody); - }); - - if (supportsFormData) { - describe("sets mime to text/plain", function () { - it("test", function () { - this.xhr.open("POST", "/"); - this.xhr.send("Data"); - - assert.equals(this.xhr.requestHeaders["Content-Type"], "text/plain;charset=utf-8"); - }); - }); - } - - it("does not override mime", function () { - this.xhr.open("POST", "/"); - this.xhr.setRequestHeader("Content-Type", "text/html"); - this.xhr.send("Data"); - - assert.equals(this.xhr.requestHeaders["Content-Type"], "text/html;charset=utf-8"); - }); - - it("does not add new 'Content-Type' header if 'content-type' already exists", function () { - this.xhr.open("POST", "/"); - this.xhr.setRequestHeader("content-type", "application/json"); - this.xhr.send("Data"); - - assert.equals(this.xhr.requestHeaders["Content-Type"], undefined); - assert.equals(this.xhr.requestHeaders["content-type"], "application/json;charset=utf-8"); - }); - - if (supportsFormData) { - describe("does not add 'Content-Type' header if data is FormData", function () { - it("test", function () { - this.xhr.open("POST", "/"); - var formData = new FormData(); - formData.append("username", "biz"); - this.xhr.send("Data"); - - assert.equals(this.xhr.requestHeaders["content-type"], undefined); - }); - }); - } - - it("sets request body to string data for GET", function () { - this.xhr.open("GET", "/"); - this.xhr.send("Data"); - - assert.equals(this.xhr.requestBody, "Data"); - }); - - it("sets request body to string data for POST", function () { - this.xhr.open("POST", "/"); - this.xhr.send("Data"); - - assert.equals(this.xhr.requestBody, "Data"); - }); - - it("sets error flag to false", function () { - this.xhr.open("POST", "/"); - this.xhr.send("Data"); - - assert.isFalse(this.xhr.errorFlag); - }); - - it("sets send flag to true", function () { - this.xhr.open("POST", "/"); - this.xhr.send("Data"); - - assert.isTrue(this.xhr.sendFlag); - }); - - it("does not set send flag to true if sync", function () { - this.xhr.open("POST", "/", false); - this.xhr.send("Data"); - - assert.isFalse(this.xhr.sendFlag); - }); - - it("dispatches onreadystatechange", function () { - var event, state; - this.xhr.open("POST", "/", false); - - this.xhr.onreadystatechange = function (e) { - event = e; - state = this.readyState; - }; - - this.xhr.send("Data"); - - assert.equals(state, FakeXMLHttpRequest.OPENED); - assert.equals(event.type, "readystatechange"); - assert.defined(event.target); - }); - - it("dispatches event using DOM Event interface", function () { - var listener = sinonSpy(); - this.xhr.open("POST", "/", false); - this.xhr.addEventListener("readystatechange", listener); - - this.xhr.send("Data"); - - assert(listener.calledOnce); - assert.equals(listener.args[0][0].type, "readystatechange"); - assert.defined(listener.args[0][0].target); - }); - - it("dispatches onSend callback if set", function () { - this.xhr.open("POST", "/", true); - var callback = sinonSpy(); - this.xhr.onSend = callback; - - this.xhr.send("Data"); - - assert(callback.called); - }); - - it("dispatches onSend with request as argument", function () { - this.xhr.open("POST", "/", true); - var callback = sinonSpy(); - this.xhr.onSend = callback; - - this.xhr.send("Data"); - - assert(callback.calledWith(this.xhr)); - }); - - it("dispatches onSend when async", function () { - this.xhr.open("POST", "/", false); - var callback = sinonSpy(); - this.xhr.onSend = callback; - - this.xhr.send("Data"); - - assert(callback.calledWith(this.xhr)); - }); - }); - - describe(".setResponseHeaders", function () { - beforeEach(function () { - this.xhr = new FakeXMLHttpRequest(); - }); - - it("sets request headers", function () { - var object = { id: 42 }; - this.xhr.open("GET", "/"); - this.xhr.send(); - this.xhr.setResponseHeaders(object); - - assert.equals(this.xhr.responseHeaders, object); - }); - - it("calls readyStateChange with HEADERS_RECEIVED", function () { - var object = { id: 42 }; - this.xhr.open("GET", "/"); - this.xhr.send(); - var spy = this.xhr.readyStateChange = sinonSpy(); - - this.xhr.setResponseHeaders(object); - - assert(spy.calledWith(FakeXMLHttpRequest.HEADERS_RECEIVED)); - }); - - it("does not call readyStateChange if sync", function () { - var object = { id: 42 }; - this.xhr.open("GET", "/", false); - this.xhr.send(); - var spy = this.xhr.readyStateChange = sinonSpy(); - - this.xhr.setResponseHeaders(object); - - assert.isFalse(spy.called); - }); - - it("changes readyState to HEADERS_RECEIVED if sync", function () { - var object = { id: 42 }; - this.xhr.open("GET", "/", false); - this.xhr.send(); - - this.xhr.setResponseHeaders(object); - - assert.equals(this.xhr.readyState, FakeXMLHttpRequest.HEADERS_RECEIVED); - }); - - it("throws if headers were already set", function () { - var xhr = this.xhr; - - xhr.open("GET", "/", false); - xhr.send(); - xhr.setResponseHeaders({}); - - assert.exception(function () { - xhr.setResponseHeaders({}); - }); - }); - }); - - describe(".setStatus", function () { - beforeEach(function () { - this.xhr = new FakeXMLHttpRequest(); - }); - - it("cannot be set on closed request", function () { - assert.exception(function () { - this.xhr.setStatus(); - }); - }); - - it("cannot be set on unsent request", function () { - this.xhr.open("GET", "/"); - - assert.exception(function () { - this.xhr.setStatus(); - }); - }); - - it("by default sets status to 200", function () { - this.xhr.open("GET", "/"); - this.xhr.send(); - this.xhr.setStatus(); - - assert.equals(this.xhr.status, 200); - assert.equals(this.xhr.statusText, "OK"); - }); - - it("sets status", function () { - var expectedStatus = 206; - var xhr = this.xhr; - - xhr.open("GET", "/"); - xhr.send(); - xhr.setStatus(expectedStatus); - - assert.equals(xhr.status, expectedStatus); - }); - - it("sets status text to the value from FakeXMLHttpRequest.statusCodes", function () { - var status = 206; - var expectedStatusText = FakeXMLHttpRequest.statusCodes[status]; - var xhr = this.xhr; - - xhr.open("GET", "/"); - xhr.send(); - xhr.setStatus(status); - - assert.equals(xhr.statusText, expectedStatusText); - }); - }); - - describe(".setResponseBodyAsync", function () { - beforeEach(function () { - this.xhr = new FakeXMLHttpRequest(); - this.xhr.open("GET", "/"); - this.xhr.send(); - this.xhr.setResponseHeaders({}); - }); - - it("invokes onreadystatechange handler with LOADING state", function () { - var spy = sinonSpy(); - this.xhr.readyStateChange = spy; - - this.xhr.setResponseBody("Some text goes in here ok?"); - - assert(spy.calledWith(FakeXMLHttpRequest.LOADING)); - }); - - it("invokes onreadystatechange handler for each 10 byte chunk", function () { - var spy = sinonSpy(); - this.xhr.readyStateChange = spy; - this.xhr.chunkSize = 10; - - this.xhr.setResponseBody("Some text goes in here ok?"); - - assert.equals(spy.callCount, 4); - }); - - it("invokes onreadystatechange handler for each x byte chunk", function () { - var spy = sinonSpy(); - this.xhr.readyStateChange = spy; - this.xhr.chunkSize = 20; - - this.xhr.setResponseBody("Some text goes in here ok?"); - - assert.equals(spy.callCount, 3); - }); - - it("invokes onreadystatechange handler with partial data", function () { - var pieces = []; - var mismatch = false; - - this.xhr.readyStateChange = function () { - if (this.response !== this.responseText) { - mismatch = true; - } - pieces.push(this.responseText); - }; - this.xhr.chunkSize = 9; - - this.xhr.setResponseBody("Some text goes in here ok?"); - - assert.isFalse(mismatch); - assert.equals(pieces[1], "Some text"); - }); - - it("calls onreadystatechange with DONE state", function () { - var spy = sinonSpy(); - this.xhr.readyStateChange = spy; - - this.xhr.setResponseBody("Some text goes in here ok?"); - - assert(spy.calledWith(FakeXMLHttpRequest.DONE)); - }); - - it("throws if not open", function () { - var xhr = new FakeXMLHttpRequest(); - - assert.exception(function () { - xhr.setResponseBody(""); - }); - }); - - it("throws if no headers received", function () { - var xhr = new FakeXMLHttpRequest(); - xhr.open("GET", "/"); - xhr.send(); - - assert.exception(function () { - xhr.setResponseBody(""); - }); - }); - - it("throws if body was already sent", function () { - var xhr = new FakeXMLHttpRequest(); - xhr.open("GET", "/"); - xhr.send(); - xhr.setResponseHeaders({}); - xhr.setResponseBody(""); - - assert.exception(function () { - xhr.setResponseBody(""); - }); - }); - - it("throws if body is not a string", function () { - var xhr = new FakeXMLHttpRequest(); - xhr.open("GET", "/"); - xhr.send(); - xhr.setResponseHeaders({}); - - assert.exception(function () { - xhr.setResponseBody({}); - }, "InvalidBodyException"); - }); - - if (supportsArrayBuffer) { - describe("with ArrayBuffer support", function () { - it("invokes onreadystatechange for each chunk when responseType='arraybuffer'", function () { - var spy = sinonSpy(); - this.xhr.readyStateChange = spy; - this.xhr.chunkSize = 10; - - this.xhr.responseType = "arraybuffer"; - - this.xhr.setResponseBody("Some text goes in here ok?"); - - assert.equals(spy.callCount, 4); - }); - }); - } - - if (supportsBlob) { - describe("with Blob support", function () { - it("invokes onreadystatechange handler for each 10 byte chunk when responseType='blob'", - function () { - var spy = sinonSpy(); - this.xhr.readyStateChange = spy; - this.xhr.chunkSize = 10; - - this.xhr.responseType = "blob"; - - this.xhr.setResponseBody("Some text goes in here ok?"); - - assert.equals(spy.callCount, 4); - }); - }); - } - }); - - describe(".setResponseBodySync", function () { - beforeEach(function () { - this.xhr = new FakeXMLHttpRequest(); - this.xhr.open("GET", "/", false); - this.xhr.send(); - this.xhr.setResponseHeaders({}); - }); - - it("does not throw", function () { - var xhr = this.xhr; - - refute.exception(function () { - xhr.setResponseBody(""); - }); - }); - - it("sets readyState to DONE", function () { - this.xhr.setResponseBody(""); - - assert.equals(this.xhr.readyState, FakeXMLHttpRequest.DONE); - }); - - it("throws if responding to request twice", function () { - var xhr = this.xhr; - this.xhr.setResponseBody(""); - - assert.exception(function () { - xhr.setResponseBody(""); - }); - }); - - it("calls onreadystatechange for sync request with DONE state", function () { - var spy = sinonSpy(); - this.xhr.readyStateChange = spy; - - this.xhr.setResponseBody("Some text goes in here ok?"); - - assert(spy.calledWith(FakeXMLHttpRequest.DONE)); - }); - - it("simulates synchronous request", function () { - var xhr = new FakeXMLHttpRequest(); - - xhr.onSend = function () { - this.setResponseHeaders({}); - this.setResponseBody("Oh yeah"); - }; - - xhr.open("GET", "/", false); - xhr.send(); - - assert.equals(xhr.responseText, "Oh yeah"); - }); - }); - - describe(".respond", function () { - beforeEach(function () { - this.sandbox = sinonSandbox.create(); - this.xhr = new FakeXMLHttpRequest({ - setTimeout: this.sandbox.spy(), - useImmediateExceptions: false - }); - this.xhr.open("GET", "/"); - var spy = this.spy = sinonSpy(); - - this.xhr.onreadystatechange = function () { - if (this.readyState === 4) { - spy.call(this); - } - }; - - this.xhr.send(); - }); - - afterEach(function () { - this.sandbox.restore(); - }); - - it("fire onload event", function () { - this.onload = this.spy; - this.xhr.respond(200, {}, ""); - assert.equals(this.spy.callCount, 1); - }); - - it("fire onload event with this set to the XHR object", function (done) { - var xhr = new FakeXMLHttpRequest(); - xhr.open("GET", "/"); - - xhr.onload = function () { - assert.same(this, xhr); - - done(); - }; - - xhr.send(); - xhr.respond(200, {}, ""); - }); - - it("calls readystate handler with readyState DONE once", function () { - this.xhr.respond(200, {}, ""); - - assert.equals(this.spy.callCount, 1); - }); - - it("defaults to status 200, no headers, and blank body", function () { - this.xhr.respond(); - - assert.equals(this.xhr.status, 200); - assert.equals(this.xhr.getAllResponseHeaders(), ""); - assert.equals(this.xhr.responseText, ""); - }); - - it("sets status", function () { - this.xhr.respond(201); - - assert.equals(this.xhr.status, 201); - }); - - it("sets status text", function () { - this.xhr.respond(201); - - assert.equals(this.xhr.statusText, "Created"); - }); - - it("sets headers", function () { - sinonSpy(this.xhr, "setResponseHeaders"); - var responseHeaders = { some: "header", value: "over here" }; - this.xhr.respond(200, responseHeaders); - - assert.equals(this.xhr.setResponseHeaders.args[0][0], responseHeaders); - }); - - it("sets response text", function () { - this.xhr.respond(200, {}, "'tis some body text"); - - assert.equals(this.xhr.responseText, "'tis some body text"); - }); - - it("completes request when onreadystatechange fails", function () { - this.xhr.onreadystatechange = sinonStub().throws(); - this.xhr.respond(200, {}, "'tis some body text"); - - assert.equals(this.xhr.onreadystatechange.callCount, 4); - }); - - it("sets status before transitioning to readyState HEADERS_RECEIVED", function () { - var status, statusText; - this.xhr.onreadystatechange = function () { - if (this.readyState === 2) { - status = this.status; - statusText = this.statusText; - } - }; - this.xhr.respond(204); - - assert.equals(status, 204); - assert.equals(statusText, "No Content"); - }); - }); - - describe(".getResponseHeader", function () { - beforeEach(function () { - this.xhr = new FakeXMLHttpRequest(); - }); - - it("returns null if request is not finished", function () { - this.xhr.open("GET", "/"); - assert.isNull(this.xhr.getResponseHeader("Content-Type")); - }); - - it("returns null if header is Set-Cookie", function () { - this.xhr.open("GET", "/"); - this.xhr.send(); - - assert.isNull(this.xhr.getResponseHeader("Set-Cookie")); - }); - - it("returns null if header is Set-Cookie2", function () { - this.xhr.open("GET", "/"); - this.xhr.send(); - - assert.isNull(this.xhr.getResponseHeader("Set-Cookie2")); - }); - - it("returns header value", function () { - this.xhr.open("GET", "/"); - this.xhr.send(); - this.xhr.setResponseHeaders({ "Content-Type": "text/html" }); - - assert.equals(this.xhr.getResponseHeader("Content-Type"), "text/html"); - }); - - it("returns header value if sync", function () { - this.xhr.open("GET", "/", false); - this.xhr.send(); - this.xhr.setResponseHeaders({ "Content-Type": "text/html" }); - - assert.equals(this.xhr.getResponseHeader("Content-Type"), "text/html"); - }); - - it("returns null if header is not set", function () { - this.xhr.open("GET", "/"); - this.xhr.send(); - - assert.isNull(this.xhr.getResponseHeader("Content-Type")); - }); - - it("returns headers case insensitive", function () { - this.xhr.open("GET", "/"); - this.xhr.send(); - this.xhr.setResponseHeaders({ "Content-Type": "text/html" }); - - assert.equals(this.xhr.getResponseHeader("content-type"), "text/html"); - }); - }); - - describe(".getAllResponseHeaders", function () { - beforeEach(function () { - this.xhr = new FakeXMLHttpRequest(); - }); - - it("returns empty string if request is not finished", function () { - this.xhr.open("GET", "/"); - assert.equals(this.xhr.getAllResponseHeaders(), ""); - }); - - it("does not return Set-Cookie and Set-Cookie2 headers", function () { - this.xhr.open("GET", "/"); - this.xhr.send(); - this.xhr.setResponseHeaders({ - "Set-Cookie": "Hey", - "Set-Cookie2": "There" - }); - - assert.equals(this.xhr.getAllResponseHeaders(), ""); - }); - - it("returns headers", function () { - this.xhr.open("GET", "/"); - this.xhr.send(); - this.xhr.setResponseHeaders({ - "Content-Type": "text/html", - "Set-Cookie2": "There", - "Content-Length": "32" - }); - - assert.equals(this.xhr.getAllResponseHeaders(), "Content-Type: text/html\r\nContent-Length: 32\r\n"); - }); - - it("returns headers if sync", function () { - this.xhr.open("GET", "/", false); - this.xhr.send(); - this.xhr.setResponseHeaders({ - "Content-Type": "text/html", - "Set-Cookie2": "There", - "Content-Length": "32" - }); - - assert.equals(this.xhr.getAllResponseHeaders(), "Content-Type: text/html\r\nContent-Length: 32\r\n"); - }); - }); - - describe(".abort", function () { - beforeEach(function () { - this.xhr = new FakeXMLHttpRequest(); - }); - - it("sets aborted flag to true", function () { - this.xhr.abort(); - - assert.isTrue(this.xhr.aborted); - }); - - it("sets response to empty string", function () { - this.xhr.response = "Partial data"; - - this.xhr.abort(); - - assert.same(this.xhr.response, ""); - }); - - it("sets responseText to empty string", function () { - this.xhr.responseText = "Partial data"; - - this.xhr.abort(); - - assert.same(this.xhr.responseText, ""); - }); - - it("sets errorFlag to true", function () { - this.xhr.abort(); - - assert.isTrue(this.xhr.errorFlag); - }); - - it("nulls request headers", function () { - this.xhr.open("GET", "/"); - this.xhr.setRequestHeader("X-Test", "Sumptn"); - - this.xhr.abort(); - - assert.equals(this.xhr.requestHeaders, {}); - }); - - it("does not have undefined response headers", function () { - this.xhr.open("GET", "/"); - - this.xhr.abort(); - - assert.defined(this.xhr.responseHeaders); - }); - - it("nulls response headers", function () { - this.xhr.open("GET", "/"); - - this.xhr.abort(); - - assert.equals(this.xhr.responseHeaders, {}); - }); - - it("keeps readyState unsent if called in unsent state", function () { - this.xhr.abort(); - - assert.equals(this.xhr.readyState, FakeXMLHttpRequest.UNSENT); - }); - - it("resets readyState to unsent if it was opened", function () { - this.xhr.open("GET", "/"); - - this.xhr.abort(); - - assert.equals(this.xhr.readyState, FakeXMLHttpRequest.UNSENT); - }); - - it("resets readyState to unsent if it was opened with send() flag sent", function () { - this.xhr.open("GET", "/"); - this.xhr.send(); - - this.xhr.abort(); - - assert.equals(this.xhr.readyState, FakeXMLHttpRequest.UNSENT); - }); - - it("resets readyState to unsent if it headers were received", function () { - this.xhr.open("GET", "/"); - this.xhr.send(); - this.xhr.setResponseHeaders({}); - - this.xhr.abort(); - - assert.equals(this.xhr.readyState, FakeXMLHttpRequest.UNSENT); - }); - - it("resets readyState to unsent if it was done", function () { - this.xhr.open("GET", "/"); - this.xhr.send(); - this.xhr.respond(); - - this.xhr.abort(); - - assert.equals(this.xhr.readyState, FakeXMLHttpRequest.UNSENT); - }); - - it("signals onreadystatechange with state set to DONE if sent before", function () { - var readyState; - this.xhr.open("GET", "/"); - this.xhr.send(); - - this.xhr.onreadystatechange = function () { - readyState = this.readyState; - }; - - this.xhr.abort(); - - assert.equals(readyState, FakeXMLHttpRequest.DONE); - }); - - it("sets send flag to false if sent before", function () { - this.xhr.open("GET", "/"); - this.xhr.send(); - - this.xhr.abort(); - - assert.isFalse(this.xhr.sendFlag); - }); - - it("dispatches readystatechange event if sent before", function () { - this.xhr.open("GET", "/"); - this.xhr.send(); - this.xhr.onreadystatechange = sinonStub(); - - this.xhr.abort(); - - assert(this.xhr.onreadystatechange.called); - }); - - it("sets readyState to unsent if sent before", function () { - this.xhr.open("GET", "/"); - this.xhr.send(); - - this.xhr.abort(); - - assert.equals(this.xhr.readyState, FakeXMLHttpRequest.UNSENT); - }); - - it("does not dispatch readystatechange event if readyState is unsent", function () { - this.xhr.onreadystatechange = sinonStub(); - - this.xhr.abort(); - - assert.isFalse(this.xhr.onreadystatechange.called); - }); - - it("does not dispatch readystatechange event if readyState is opened but not sent", function () { - this.xhr.open("GET", "/"); - this.xhr.onreadystatechange = sinonStub(); - - this.xhr.abort(); - - assert.isFalse(this.xhr.onreadystatechange.called); - }); - - it("does not dispatch readystatechange event if readyState is done", function () { - this.xhr.open("GET", "/"); - this.xhr.send(); - this.xhr.respond(); - - this.xhr.onreadystatechange = sinonStub(); - this.xhr.abort(); - - assert.isFalse(this.xhr.onreadystatechange.called); - }); - - assertEventOrdering("abort", 0, function (xhr) { - xhr.abort(); - }); - }); - - describe(".error", function () { - beforeEach(function () { - this.xhr = new FakeXMLHttpRequest(); - }); - - it("sets response to empty string", function () { - this.xhr.response = "Partial data"; - - this.xhr.error(); - - assert.same(this.xhr.response, ""); - }); - - it("sets responseText to empty string", function () { - this.xhr.responseText = "Partial data"; - - this.xhr.error(); - - assert.same(this.xhr.responseText, ""); - }); - - it("sets errorFlag to true", function () { - this.xhr.errorFlag = false; - this.xhr.error(); - - assert.isTrue(this.xhr.errorFlag); - }); - - it("nulls request headers", function () { - this.xhr.open("GET", "/"); - this.xhr.setRequestHeader("X-Test", "Sumptn"); - - this.xhr.error(); - - assert.equals(this.xhr.requestHeaders, {}); - }); - - it("nulls response headers", function () { - this.xhr.open("GET", "/"); - - this.xhr.error(); - - assert.equals(this.xhr.responseHeaders, {}); - }); - - it("dispatches readystatechange event if sent before", function () { - this.xhr.open("GET", "/"); - this.xhr.send(); - this.xhr.onreadystatechange = sinonStub(); - - this.xhr.error(); - - assert(this.xhr.onreadystatechange.called); - }); - - it("sets readyState to DONE", function () { - this.xhr.open("GET", "/"); - - this.xhr.error(); - - assert.equals(this.xhr.readyState, FakeXMLHttpRequest.DONE); - }); - - assertEventOrdering("error", 0, function (xhr) { - xhr.error(); - }); - }); - - describe(".response", function () { - beforeEach(function () { - this.xhr = new FakeXMLHttpRequest(); - }); - - it("is initially the empty string if responseType === ''", function () { - this.xhr.responseType = ""; - this.xhr.open("GET", "/"); - assert.same(this.xhr.response, ""); - }); - - it("is initially the empty string if responseType === 'text'", function () { - this.xhr.responseType = "text"; - this.xhr.open("GET", "/"); - assert.same(this.xhr.response, ""); - }); - - it("is initially null if responseType === 'json'", function () { - this.xhr.responseType = "json"; - this.xhr.open("GET", "/"); - assert.isNull(this.xhr.response); - }); - - it("is initially null if responseType === 'document'", function () { - this.xhr.responseType = "document"; - this.xhr.open("GET", "/"); - assert.isNull(this.xhr.response); - }); - - it("is the empty string when the response body is empty", function () { - this.xhr.open("GET", "/"); - this.xhr.send(); - - this.xhr.respond(200, {}, ""); - - assert.same(this.xhr.response, ""); - }); - - it("parses JSON for responseType='json'", function () { - this.xhr.responseType = "json"; - this.xhr.open("GET", "/"); - this.xhr.send(); - - this.xhr.respond(200, { "Content-Type": "application/json" }, - JSON.stringify({foo: true})); - - var response = this.xhr.response; - assert.isObject(response); - assert.isTrue(response.foo); - }); - - it("does not parse JSON if responseType!='json'", function () { - this.xhr.open("GET", "/"); - this.xhr.send(); - - var responseText = JSON.stringify({foo: true}); - - this.xhr.respond(200, { "Content-Type": "application/json" }, - responseText); - - var response = this.xhr.response; - assert.isString(response); - assert.equals(response, responseText); - }); - - if (supportsArrayBuffer) { - describe("with ArrayBuffer support", function () { - it("is initially null if responseType === 'arraybuffer'", function () { - this.xhr.responseType = "arraybuffer"; - this.xhr.open("GET", "/"); - assert.isNull(this.xhr.response); - }); - - it("defaults to empty ArrayBuffer response", function () { - this.xhr.responseType = "arraybuffer"; - this.xhr.open("GET", "/"); - this.xhr.send(); - - this.xhr.respond(); - assertArrayBufferMatches(this.xhr.response, ""); - }); - - it("returns ArrayBuffer when responseType='arraybuffer'", function () { - this.xhr.responseType = "arraybuffer"; - this.xhr.open("GET", "/"); - this.xhr.send(); - - this.xhr.respond(200, { "Content-Type": "application/octet-stream" }, "a test buffer"); - - assertArrayBufferMatches(this.xhr.response, "a test buffer"); - }); - - it("returns binary data correctly when responseType='arraybuffer'", function () { - this.xhr.responseType = "arraybuffer"; - this.xhr.open("GET", "/"); - this.xhr.send(); - - this.xhr.respond(200, { "Content-Type": "application/octet-stream" }, "\xFF"); - - assertArrayBufferMatches(this.xhr.response, "\xFF"); - }); - }); - } - - if (supportsBlob) { - describe("with Blob support", function () { - it("is initially null if responseType === 'blob'", function () { - this.xhr.responseType = "blob"; - this.xhr.open("GET", "/"); - assert.isNull(this.xhr.response); - }); - - it("defaults to empty Blob response", function (done) { - this.xhr.responseType = "blob"; - this.xhr.open("GET", "/"); - this.xhr.send(); - - this.xhr.respond(); - - assertBlobMatches(this.xhr.response, "", done); - }); - - it("returns blob with correct data", function (done) { - this.xhr.responseType = "blob"; - this.xhr.open("GET", "/"); - this.xhr.send(); - - this.xhr.respond(200, { "Content-Type": "application/octet-stream" }, "a test blob"); - - assertBlobMatches(this.xhr.response, "a test blob", done); - }); - - it("returns blob with correct binary data", function (done) { - this.xhr.responseType = "blob"; - this.xhr.open("GET", "/"); - this.xhr.send(); - - this.xhr.respond(200, { "Content-Type": "application/octet-stream" }, "\xFF"); - - assertBlobMatches(this.xhr.response, "\xFF", done); - }); - - it("does parse utf-8 content outside ASCII range properly", function (done) { - this.xhr.responseType = "blob"; - this.xhr.open("GET", "/"); - this.xhr.send(); - - var responseText = JSON.stringify({foo: "♥"}); - - this.xhr.respond(200, { "Content-Type": "application/octet-stream" }, - responseText); - - assertBlobMatches(this.xhr.response, responseText, done); - }); - }); - } - }); - - describe(".responseXML", function () { - beforeEach(function () { - this.xhr = new FakeXMLHttpRequest(); - }); - - it("is initially null", function () { - this.xhr.open("GET", "/"); - assert.isNull(this.xhr.responseXML); - }); - - it("is null when the response body is empty", function () { - this.xhr.open("GET", "/"); - this.xhr.send(); - - this.xhr.respond(200, {}, ""); - - assert.isNull(this.xhr.responseXML); - }); - - it("parses XML for application/xml", function () { - this.xhr.open("GET", "/"); - this.xhr.send(); - - this.xhr.respond(200, { "Content-Type": "application/xml" }, - "