Created
November 21, 2014 16:36
-
-
Save RuslanSushko/900d748801d0fb48e30f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
* MockJax - jQuery Plugin to Mock Ajax requests | |
* | |
* Version: 1.4.0 | |
* Released: 2011-02-04 | |
* Source: http://github.com/appendto/jquery-mockjax | |
* Docs: http://enterprisejquery.com/2010/07/mock-your-ajax-requests-with-mockjax-for-rapid-development | |
* Plugin: mockjax | |
* Author: Jonathan Sharp (http://jdsharp.com) | |
* License: MIT,GPL | |
* | |
* Copyright (c) 2010 appendTo LLC. | |
* Dual licensed under the MIT or GPL licenses. | |
* http://appendto.com/open-source-licenses | |
*/ | |
(function($) { | |
var _ajax = $.ajax, | |
mockHandlers = []; | |
function parseXML(xml) { | |
if ( window['DOMParser'] == undefined && window.ActiveXObject ) { | |
DOMParser = function() { }; | |
DOMParser.prototype.parseFromString = function( xmlString ) { | |
var doc = new ActiveXObject('Microsoft.XMLDOM'); | |
doc.async = 'false'; | |
doc.loadXML( xmlString ); | |
return doc; | |
}; | |
} | |
try { | |
var xmlDoc = ( new DOMParser() ).parseFromString( xml, 'text/xml' ); | |
if ( $.isXMLDoc( xmlDoc ) ) { | |
var err = $('parsererror', xmlDoc); | |
if ( err.length == 1 ) { | |
throw('Error: ' + $(xmlDoc).text() ); | |
} | |
} else { | |
throw('Unable to parse XML'); | |
} | |
} catch( e ) { | |
var msg = ( e.name == undefined ? e : e.name + ': ' + e.message ); | |
$(document).trigger('xmlParseError', [ msg ]); | |
return undefined; | |
} | |
return xmlDoc; | |
} | |
$.extend({ | |
ajax: function (origSettings) { | |
//jsonp do request like json | |
if (origSettings.dataType == "jsonp") | |
{ | |
origSettings.dataType = "json" | |
} | |
var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings), | |
mock = false; | |
// Iterate over our mock handlers (in registration order) until we find | |
// one that is willing to intercept the request | |
$.each(mockHandlers, function(k, v) { | |
if ( !mockHandlers[k] ) { | |
return; | |
} | |
var m = null; | |
// If the mock was registered with a function, let the function decide if we | |
// want to mock this request | |
if ( $.isFunction(mockHandlers[k]) ) { | |
m = mockHandlers[k](s); | |
} else { | |
m = mockHandlers[k]; | |
// Inspect the URL of the request and check if the mock handler's url | |
// matches the url for this ajax request | |
if ( $.isFunction(m.url.test) ) { | |
// The user provided a regex for the url, test it | |
if ( !m.url.test( s.url ) ) { | |
m = null; | |
} | |
} else { | |
// Look for a simple wildcard '*' or a direct URL match | |
var star = m.url.indexOf('*'); | |
if ( ( m.url != '*' && m.url != s.url && star == -1 ) || | |
( star > -1 && m.url.substr(0, star) != s.url.substr(0, star) ) ) { | |
// The url we tested did not match the wildcard * | |
m = null; | |
} | |
} | |
if ( m ) { | |
// Inspect the data submitted in the request (either POST body or GET query string) | |
if ( m.data && s.data ) { | |
var identical = false; | |
// Deep inspect the identity of the objects | |
(function ident(mock, live) { | |
// Test for situations where the data is a querystring (not an object) | |
if (typeof live === 'string') { | |
// Querystring may be a regex | |
identical = $.isFunction( mock.test ) ? mock.test(live) : mock == live; | |
return identical; | |
} | |
$.each(mock, function(k, v) { | |
if ( live[k] === undefined ) { | |
identical = false; | |
return false; | |
} else { | |
identical = true; | |
if ( typeof live[k] == 'object' ) { | |
return ident(mock[k], live[k]); | |
} else { | |
if ( $.isFunction( mock[k].test ) ) { | |
identical = mock[k].test(live[k]); | |
} else { | |
identical = ( mock[k] == live[k] ); | |
} | |
return identical; | |
} | |
} | |
}); | |
})(m.data, s.data); | |
// They're not identical, do not mock this request | |
if ( identical == false ) { | |
m = null; | |
} | |
} | |
// Inspect the request type | |
if ( m && m.type && m.type != s.type ) { | |
// The request type doesn't match (GET vs. POST) | |
m = null; | |
} | |
} | |
} | |
if ( m ) { | |
mock = true; | |
// Handle console logging | |
var c = $.extend({}, $.mockjaxSettings, m); | |
if ( c.log && $.isFunction(c.log) ) { | |
c.log('MOCK ' + s.type.toUpperCase() + ': ' + s.url, $.extend({}, s)); | |
} | |
var jsre = /=\?(&|$)/, jsc = (new Date()).getTime(); | |
//// Handle JSONP Parameter Callbacks, we need to replicate some of the jQuery core here | |
//// because there isn't an easy hook for the cross domain script tag of jsonp | |
//if ( s.dataType === "jsonp" ) { | |
// if ( s.type.toUpperCase() === "GET" ) { | |
// if ( !jsre.test( s.url ) ) { | |
// s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?"; | |
// } | |
// } else if ( !s.data || !jsre.test(s.data) ) { | |
// s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?"; | |
// } | |
// s.dataType = "json"; | |
//} | |
//// Build temporary JSONP function | |
//if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) { | |
// jsonp = s.jsonpCallback || ("jsonp" + jsc++); | |
// // Replace the =? sequence both in the query string and the data | |
// if ( s.data ) { | |
// s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1"); | |
// } | |
// s.url = s.url.replace(jsre, "=" + jsonp + "$1"); | |
// // We need to make sure | |
// // that a JSONP style response is executed properly | |
// s.dataType = "script"; | |
// // Handle JSONP-style loading | |
// window[ jsonp ] = window[ jsonp ] || function( tmp ) { | |
// data = tmp; | |
// success(); | |
// complete(); | |
// // Garbage collect | |
// window[ jsonp ] = undefined; | |
// try { | |
// delete window[ jsonp ]; | |
// } catch(e) {} | |
// if ( head ) { | |
// head.removeChild( script ); | |
// } | |
// }; | |
//} | |
var rurl = /^(\w+:)?\/\/([^\/?#]+)/, | |
parts = rurl.exec( s.url ), | |
remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host); | |
// Test if we are going to create a script tag (if so, intercept & mock) | |
if ( s.dataType === "script" && s.type.toUpperCase() === "GET" && remote ) { | |
// Synthesize the mock request for adding a script tag | |
var callbackContext = origSettings && origSettings.context || s; | |
function success() { | |
// If a local callback was specified, fire it and pass it the data | |
if ( s.success ) { | |
s.success.call( callbackContext, ( m.response ? m.response.toString() : m.responseText || ''), status, {} ); | |
} | |
// Fire the global callback | |
if ( s.global ) { | |
trigger( "ajaxSuccess", [{}, s] ); | |
} | |
} | |
function complete() { | |
// Process result | |
if ( s.complete ) { | |
s.complete.call( callbackContext, {} , status ); | |
} | |
// The request was completed | |
if ( s.global ) { | |
trigger( "ajaxComplete", [{}, s] ); | |
} | |
// Handle the global AJAX counter | |
if ( s.global && ! --jQuery.active ) { | |
jQuery.event.trigger( "ajaxStop" ); | |
} | |
} | |
function trigger(type, args) { | |
(s.context ? jQuery(s.context) : jQuery.event).trigger(type, args); | |
} | |
if ( m.response && $.isFunction(m.response) ) { | |
m.response(origSettings); | |
} else { | |
$.globalEval(m.responseText); | |
} | |
success(); | |
complete(); | |
return false; | |
} | |
mock = _ajax.call($, $.extend(true, {}, origSettings, { | |
// Mock the XHR object | |
xhr: function() { | |
// Extend with our default mockjax settings | |
m = $.extend({}, $.mockjaxSettings, m); | |
if ( m.contentType ) { | |
m.headers['content-type'] = m.contentType; | |
} | |
// Return our mock xhr object | |
return { | |
status: m.status, | |
readyState: 1, | |
open: function() { }, | |
send: function() { | |
// This is a substitute for < 1.4 which lacks $.proxy | |
var process = (function(that) { | |
return function() { | |
return (function() { | |
// The request has returned | |
this.status = m.status; | |
this.readyState = 4; | |
// We have an executable function, call it to give | |
// the mock handler a chance to update it's data | |
if ( $.isFunction(m.response) ) { | |
m.response(origSettings); | |
} | |
// Copy over our mock to our xhr object before passing control back to | |
// jQuery's onreadystatechange callback | |
if ( s.dataType == 'json' && ( typeof m.responseText == 'object' ) ) { | |
this.responseText = JSON.stringify(m.responseText); | |
} else if ( s.dataType == 'xml' ) { | |
if ( typeof m.responseXML == 'string' ) { | |
this.responseXML = parseXML(m.responseXML); | |
} else { | |
this.responseXML = m.responseXML; | |
} | |
} else { | |
this.responseText = m.responseText; | |
} | |
// jQuery < 1.4 doesn't have onreadystate change for xhr | |
if ( $.isFunction(this.onreadystatechange) ) { | |
this.onreadystatechange( m.isTimeout ? 'timeout' : undefined ); | |
} | |
}).apply(that); | |
}; | |
})(this); | |
if ( m.proxy ) { | |
// We're proxying this request and loading in an external file instead | |
_ajax({ | |
global: false, | |
url: m.proxy, | |
type: m.proxyType, | |
data: m.data, | |
dataType: s.dataType, | |
complete: function(xhr, txt) { | |
m.responseXML = xhr.responseXML; | |
m.responseText = xhr.responseText; | |
this.responseTimer = setTimeout(process, m.responseTime || 0); | |
} | |
}); | |
} else { | |
// type == 'POST' || 'GET' || 'DELETE' | |
if ( s.async === false ) { | |
// TODO: Blocking delay | |
process(); | |
} else { | |
this.responseTimer = setTimeout(process, m.responseTime || 50); | |
} | |
} | |
}, | |
abort: function() { | |
clearTimeout(this.responseTimer); | |
}, | |
setRequestHeader: function() { }, | |
getResponseHeader: function(header) { | |
// 'Last-modified', 'Etag', 'content-type' are all checked by jQuery | |
if ( m.headers && m.headers[header] ) { | |
// Return arbitrary headers | |
return m.headers[header]; | |
} else if ( header.toLowerCase() == 'last-modified' ) { | |
return m.lastModified || (new Date()).toString(); | |
} else if ( header.toLowerCase() == 'etag' ) { | |
return m.etag || ''; | |
} else if ( header.toLowerCase() == 'content-type' ) { | |
return m.contentType || 'text/plain'; | |
} | |
}, | |
getAllResponseHeaders: function() { | |
var headers = ''; | |
$.each(m.headers, function(k, v) { | |
headers += k + ': ' + v + "\n"; | |
}); | |
return headers; | |
} | |
}; | |
} | |
})); | |
return false; | |
} | |
}); | |
// We don't have a mock request, trigger a normal request | |
if ( !mock ) { | |
return _ajax.apply($, arguments); | |
} else { | |
return mock; | |
} | |
} | |
}); | |
$.mockjaxSettings = { | |
//url: null, | |
//type: 'GET', | |
log: function(msg) { | |
window['console'] && window.console.log && window.console.log(msg); | |
}, | |
status: 200, | |
responseTime: 500, | |
isTimeout: false, | |
contentType: 'text/plain', | |
response: '', | |
responseText: '', | |
responseXML: '', | |
proxy: '', | |
proxyType: 'GET', | |
lastModified: null, | |
etag: '', | |
headers: { | |
etag: 'IJF@H#@923uf8023hFO@I#H#', | |
'content-type' : 'text/plain' | |
} | |
}; | |
$.mockjax = function(settings) { | |
var i = mockHandlers.length; | |
mockHandlers[i] = settings; | |
return i; | |
}; | |
$.mockjaxClear = function(i) { | |
if ( arguments.length == 1 ) { | |
mockHandlers[i] = null; | |
} else { | |
mockHandlers = []; | |
} | |
}; | |
})(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment