Skip to content

Commit

Permalink
- Add readystatechange to xhr events regardless of the browser supp…
Browse files Browse the repository at this point in the history
…orting `onload`, for ajax implementations that still rely on readystatechange

- Move `evts` into function closure so multiple calls to `createPassthrough` don't result in duplicate entries in `evts`.
  • Loading branch information
adamjmcgrath committed Nov 18, 2015
1 parent c2c4d75 commit 512d696
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 14 deletions.
22 changes: 11 additions & 11 deletions pretender.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,23 +133,22 @@ function interceptor(pretender) {
}
};

// event types to handle on the xhr
var evts = ['error', 'timeout', 'abort'];

// event types to handle on the xhr.upload
var uploadEvents = ['progress'];
function createPassthrough(fakeXHR) {
// event types to handle on the xhr
var evts = ['error', 'timeout', 'abort', 'readystatechange'];

// properties to copy from the native xhr to fake xhr
var lifecycleProps = ['readyState', 'responseText', 'responseXML', 'status', 'statusText'];
// event types to handle on the xhr.upload
var uploadEvents = ['progress'];

// properties to copy from the native xhr to fake xhr
var lifecycleProps = ['readyState', 'responseText', 'responseXML', 'status', 'statusText'];

function createPassthrough(fakeXHR) {
var xhr = fakeXHR._passthroughRequest = new pretender._nativeXMLHttpRequest();

// Use onload instead of onreadystatechange if the browser supports it
// Use onload if the browser supports it
if ('onload' in xhr) {
evts.push('load');
} else {
evts.push('readystatechange');
}

// add progress event for async calls
Expand Down Expand Up @@ -183,6 +182,8 @@ function interceptor(pretender) {
};
}

xhr.open(fakeXHR.method, fakeXHR.url, fakeXHR.async, fakeXHR.username, fakeXHR.password);

// set the on- handler on the native xhr's `upload` property for
// the given eventType
function createUploadHandler(eventType) {
Expand All @@ -201,7 +202,6 @@ function interceptor(pretender) {
createUploadHandler(uploadEvents[i]);
}

xhr.open(fakeXHR.method, fakeXHR.url, fakeXHR.async, fakeXHR.username, fakeXHR.password);
if (fakeXHR.async) {
xhr.timeout = fakeXHR.timeout;
xhr.withCredentials = fakeXHR.withCredentials;
Expand Down
24 changes: 21 additions & 3 deletions test/passthrough_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,19 @@ asyncTest('synchronous request does not have timeout, withCredentials and onprog

test('asynchronous request fires events', function(assert) {
var done = assert.async();
assert.expect(4);
assert.expect(6);

pretender.post('/some/:route', pretender.passthrough);

var onEvents = {
load: false,
progress: false
progress: false,
readystatechange: false
};
var listenerEvents = {
load: false,
progress: false
progress: false,
readystatechange: false
};

var xhr = new window.XMLHttpRequest();
Expand All @@ -132,6 +134,20 @@ test('asynchronous request fires events', function(assert) {
finishNext();
};

xhr.addEventListener('readystatechange', function _load() {
if (xhr.readyState == 4) {
listenerEvents.readystatechange = true;
finishNext();
}
});

xhr.onreadystatechange = function _onload() {
if (xhr.readyState == 4) {
onEvents.readystatechange = true;
finishNext();
}
};

xhr.send();

// call `finish` in next tick to ensure both load event handlers
Expand All @@ -147,9 +163,11 @@ test('asynchronous request fires events', function(assert) {

assert.ok(onEvents.load, 'onload called');
assert.ok(onEvents.progress, 'onprogress called');
assert.ok(onEvents.readystatechange, 'onpreadystate called');

assert.ok(listenerEvents.load, 'load listener called');
assert.ok(listenerEvents.progress, 'progress listener called');
assert.ok(listenerEvents.readystatechange, 'readystate listener called');

done();
}
Expand Down

0 comments on commit 512d696

Please sign in to comment.