Skip to content

Commit

Permalink
Attempt at allowing for asynchronous responses
Browse files Browse the repository at this point in the history
This solve the issues presented in both #93 and #134 without changing existing behavior.

The usage would include just adding a second paramater to your response function callback. When present, mockjax would wait for it to be called before finishing the request.

See the new test for an example.
  • Loading branch information
dcneiner committed Aug 12, 2014
1 parent 040886b commit 2a9135d
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 35 deletions.
81 changes: 47 additions & 34 deletions jquery.mockjax.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,52 +140,65 @@
var process = (function(that) {
return function() {
return (function() {
var onReady;

// The request has returned
this.status = mockHandler.status;
this.statusText = mockHandler.statusText;
this.readyState = 4;

var finishRequest = function () {
var onReady;
// Copy over our mock to our xhr object before passing control back to
// jQuery's onreadystatechange callback
if ( requestSettings.dataType == 'json' && ( typeof mockHandler.responseText == 'object' ) ) {
this.responseText = JSON.stringify(mockHandler.responseText);
} else if ( requestSettings.dataType == 'xml' ) {
if ( typeof mockHandler.responseXML == 'string' ) {
this.responseXML = parseXML(mockHandler.responseXML);
//in jQuery 1.9.1+, responseXML is processed differently and relies on responseText
this.responseText = mockHandler.responseXML;
} else {
this.responseXML = mockHandler.responseXML;
}
} else {
this.responseText = mockHandler.responseText;
}
if( typeof mockHandler.status == 'number' || typeof mockHandler.status == 'string' ) {
this.status = mockHandler.status;
}
if( typeof mockHandler.statusText === "string") {
this.statusText = mockHandler.statusText;
}
// jQuery 2.0 renamed onreadystatechange to onload
onReady = this.onreadystatechange || this.onload;

// jQuery < 1.4 doesn't have onreadystate change for xhr
if ( $.isFunction( onReady ) ) {
if( mockHandler.isTimeout) {
this.status = -1;
}
onReady.call( this, mockHandler.isTimeout ? 'timeout' : undefined );
} else if ( mockHandler.isTimeout ) {
// Fix for 1.3.2 timeout to keep success from firing.
this.status = -1;
}
};

// We have an executable function, call it to give
// the mock handler a chance to update it's data
if ( $.isFunction(mockHandler.response) ) {
mockHandler.response(origSettings);
}
// Copy over our mock to our xhr object before passing control back to
// jQuery's onreadystatechange callback
if ( requestSettings.dataType == 'json' && ( typeof mockHandler.responseText == 'object' ) ) {
this.responseText = JSON.stringify(mockHandler.responseText);
} else if ( requestSettings.dataType == 'xml' ) {
if ( typeof mockHandler.responseXML == 'string' ) {
this.responseXML = parseXML(mockHandler.responseXML);
//in jQuery 1.9.1+, responseXML is processed differently and relies on responseText
this.responseText = mockHandler.responseXML;
// Wait for it to finish
console.log( mockHandler.response.length );
if ( mockHandler.response.length === 2 ) {
mockHandler.response(origSettings, function () {
finishRequest.call(that);
});
return;
} else {
this.responseXML = mockHandler.responseXML;
mockHandler.response(origSettings);
}
} else {
this.responseText = mockHandler.responseText;
}
if( typeof mockHandler.status == 'number' || typeof mockHandler.status == 'string' ) {
this.status = mockHandler.status;
}
if( typeof mockHandler.statusText === "string") {
this.statusText = mockHandler.statusText;
}
// jQuery 2.0 renamed onreadystatechange to onload
onReady = this.onreadystatechange || this.onload;

// jQuery < 1.4 doesn't have onreadystate change for xhr
if ( $.isFunction( onReady ) ) {
if( mockHandler.isTimeout) {
this.status = -1;
}
onReady.call( this, mockHandler.isTimeout ? 'timeout' : undefined );
} else if ( mockHandler.isTimeout ) {
// Fix for 1.3.2 timeout to keep success from firing.
this.status = -1;
}
finishRequest.call(that);
}).apply(that);
};
})(this);
Expand Down
29 changes: 28 additions & 1 deletion test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,33 @@ asyncTest('Dynamic response callback', function() {
});
});

asyncTest('Dynamic asynchronous response callback', function() {
$.mockjax({
url: '/response-callback',
responseText: 'original response',
response: function(settings, done) {
var that = this;
setTimeout(function() {
that.responseText = settings.data.response + ' 3';
done();
}, 30);
}
});

$.ajax({
url: '/response-callback',
dataType: 'text',
data: {
response: 'Hello world'
},
error: noErrorCallbackExpected,
complete: function(xhr) {
equal(xhr.responseText, 'Hello world 3', 'Response Text matches');
start();
}
});
});

if ($().jquery >= "1.4") {
// The $.ajax() API changed in version 1.4 to include the third argument: xhr
asyncTest('Success callback should have access to xhr object', function() {
Expand Down Expand Up @@ -265,7 +292,7 @@ asyncTest('Get mocked ajax calls - GET', function() {
$.mockjax({
url: '/api/example/*'
});

// GET
$.ajax({
async: false,
Expand Down

0 comments on commit 2a9135d

Please sign in to comment.