getJasmineRequireObj().AjaxFakeRequest = function() { function extend(destination, source, propertiesToSkip) { propertiesToSkip = propertiesToSkip || []; for (var property in source) { if (!arrayContains(propertiesToSkip, property)) { destination[property] = source[property]; } } return destination; } function arrayContains(arr, item) { for (var i = 0; i < arr.length; i++) { if (arr[i] === item) { return true; } } return false; } function wrapProgressEvent(xhr, eventName) { return function() { if (xhr[eventName]) { xhr[eventName](); } }; } function initializeEvents(xhr) { return { 'loadstart': wrapProgressEvent(xhr, 'onloadstart'), 'load': wrapProgressEvent(xhr, 'onload'), 'loadend': wrapProgressEvent(xhr, 'onloadend'), 'progress': wrapProgressEvent(xhr, 'onprogress'), 'error': wrapProgressEvent(xhr, 'onerror'), 'abort': wrapProgressEvent(xhr, 'onabort'), 'timeout': wrapProgressEvent(xhr, 'ontimeout') }; } function fakeRequest(global, requestTracker, stubTracker, paramParser) { function FakeXMLHttpRequest() { requestTracker.track(this); this.events = initializeEvents(this); this.requestHeaders = {}; this.overriddenMimeType = null; } function findHeader(name, headers) { name = name.toLowerCase(); for (var header in headers) { if (header.toLowerCase() === name) { return headers[header]; } } } function normalizeHeaders(rawHeaders, contentType) { var headers = []; if (rawHeaders) { if (rawHeaders instanceof Array) { headers = rawHeaders; } else { for (var headerName in rawHeaders) { if (rawHeaders.hasOwnProperty(headerName)) { headers.push({ name: headerName, value: rawHeaders[headerName] }); } } } } else { headers.push({ name: "Content-Type", value: contentType || "application/json" }); } return headers; } function parseXml(xmlText, contentType) { if (global.DOMParser) { return (new global.DOMParser()).parseFromString(xmlText, 'text/xml'); } else { var xml = new global.ActiveXObject("Microsoft.XMLDOM"); xml.async = "false"; xml.loadXML(xmlText); return xml; } } var xmlParsables = ['text/xml', 'application/xml']; function getResponseXml(responseText, contentType) { if (arrayContains(xmlParsables, contentType.toLowerCase())) { return parseXml(responseText, contentType); } else if (contentType.match(/\+xml$/)) { return parseXml(responseText, 'text/xml'); } return null; } var iePropertiesThatCannotBeCopied = ['responseBody', 'responseText', 'responseXML', 'status', 'statusText', 'responseTimeout']; extend(FakeXMLHttpRequest.prototype, new global.XMLHttpRequest(), iePropertiesThatCannotBeCopied); extend(FakeXMLHttpRequest.prototype, { open: function() { this.method = arguments[0]; this.url = arguments[1]; this.username = arguments[3]; this.password = arguments[4]; this.readyState = 1; this.onreadystatechange(); }, setRequestHeader: function(header, value) { if(this.requestHeaders.hasOwnProperty(header)) { this.requestHeaders[header] = [this.requestHeaders[header], value].join(', '); } else { this.requestHeaders[header] = value; } }, overrideMimeType: function(mime) { this.overriddenMimeType = mime; }, abort: function() { this.readyState = 0; this.status = 0; this.statusText = "abort"; this.onreadystatechange(); this.events.progress(); this.events.abort(); this.events.loadend(); }, readyState: 0, onloadstart: null, onprogress: null, onabort: null, onerror: null, onload: null, ontimeout: null, onloadend: null, onreadystatechange: function(isTimeout) { }, addEventListener: function(event, callback) { var existingCallback = this.events[event], self = this; this.events[event] = function() { callback.apply(self); existingCallback(); }; }, status: null, send: function(data) { this.params = data; this.readyState = 2; this.events.loadstart(); this.onreadystatechange(); var stub = stubTracker.findStub(this.url, data, this.method); if (stub) { this.respondWith(stub); } }, contentType: function() { return findHeader('content-type', this.requestHeaders); }, data: function() { if (!this.params) { return {}; } return paramParser.findParser(this).parse(this.params); }, getResponseHeader: function(name) { name = name.toLowerCase(); var resultHeader; for(var i = 0; i < this.responseHeaders.length; i++) { var header = this.responseHeaders[i]; if (name === header.name.toLowerCase()) { if (resultHeader) { resultHeader = [resultHeader, header.value].join(', '); } else { resultHeader = header.value; } } } return resultHeader; }, getAllResponseHeaders: function() { var responseHeaders = []; for (var i = 0; i < this.responseHeaders.length; i++) { responseHeaders.push(this.responseHeaders[i].name + ': ' + this.responseHeaders[i].value); } return responseHeaders.join('\r\n'); }, responseText: null, response: function(response) { if (window.console && window.console.warn) { window.console.warn("jasmine-ajax's response method is deprecated because it conflicts with XmlHTTPRequest 2 sytax. It will be removed in a later version. Please use respondWith"); } this.respondWith(response); }, respondWith: function(response) { if (this.readyState === 4) { throw new Error("FakeXMLHttpRequest already completed"); } this.status = response.status; this.statusText = response.statusText || ""; this.responseText = response.responseText || ""; this.readyState = 4; this.responseHeaders = normalizeHeaders(response.responseHeaders, response.contentType); this.responseXML = getResponseXml(response.responseText, this.getResponseHeader('content-type') || ''); this.onreadystatechange(); this.events.progress(); this.events.load(); this.events.loadend(); }, responseTimeout: function() { if (this.readyState === 4) { throw new Error("FakeXMLHttpRequest already completed"); } this.readyState = 4; jasmine.clock().tick(30000); this.onreadystatechange('timeout'); this.events.progress(); this.events.timeout(); this.events.loadend(); }, responseError: function() { if (this.readyState === 4) { throw new Error("FakeXMLHttpRequest already completed"); } this.readyState = 4; this.onreadystatechange(); this.events.progress(); this.events.error(); this.events.loadend(); } }); return FakeXMLHttpRequest; } return fakeRequest; };