-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add XMLHttpRequestUpload support #26
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/** | ||
* An EventTarget object | ||
* @constructor | ||
*/ | ||
function MockEventTarget() { | ||
this._eventListeners = []; | ||
} | ||
|
||
|
||
/** | ||
* Trigger an event | ||
* @param {String} event | ||
* @param {Object} eventDetails | ||
* @returns {MockEventTarget} | ||
*/ | ||
MockEventTarget.prototype.trigger = function(event, eventDetails) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. trigger seems clear enough |
||
for (var x = 0; x < this._eventListeners.length; x++) { | ||
var eventListener = this._eventListeners[x]; | ||
|
||
if (eventListener.event === event) { | ||
var eventListenerDetails = eventDetails || {}; | ||
eventListenerDetails.currentTarget = this; | ||
eventListenerDetails.type = event; | ||
eventListener.listener.call(this, eventListenerDetails); | ||
} | ||
} | ||
|
||
return this; | ||
}; | ||
|
||
MockEventTarget.prototype.addEventListener = function(event, listener) { | ||
this._eventListeners.push({ | ||
event: event, | ||
listener: listener | ||
}); | ||
}; | ||
|
||
MockEventTarget.prototype.removeEventListener = function(event, listener) { | ||
var currentIndex = 0; | ||
|
||
while (currentIndex < this._eventListeners.length) { | ||
var eventListener = this._eventListeners[currentIndex]; | ||
if (eventListener.event === event && eventListener.listener === listener) { | ||
this._eventListeners.splice(currentIndex, 1); | ||
} else { | ||
currentIndex++; | ||
} | ||
} | ||
}; | ||
|
||
module.exports = MockEventTarget; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
var MockRequest = require('./MockRequest'); | ||
var MockResponse = require('./MockResponse'); | ||
var MockEventTarget = require('./MockEventTarget'); | ||
|
||
var notImplementedError = new Error('This feature hasn\'t been implmented yet. Please submit an Issue or Pull Request on Github.'); | ||
|
||
|
@@ -72,14 +73,18 @@ MockXMLHttpRequest.handle = function(request) { | |
* @constructor | ||
*/ | ||
function MockXMLHttpRequest() { | ||
MockEventTarget.call(this); | ||
this.reset(); | ||
this._eventListeners = []; | ||
this.upload = new MockEventTarget(); | ||
this.timeout = 0; | ||
// some libraries (like Mixpanel) use the presence of this field to check if XHR is properly supported | ||
// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials | ||
this.withCredentials = false; | ||
} | ||
|
||
MockXMLHttpRequest.prototype = Object.create(MockEventTarget.prototype); | ||
MockXMLHttpRequest.prototype.constructor = MockXMLHttpRequest; | ||
|
||
/** | ||
* Reset the response values | ||
* @private | ||
|
@@ -115,18 +120,7 @@ MockXMLHttpRequest.prototype.trigger = function(event, eventDetails) { | |
this['on'+event](); | ||
} | ||
|
||
for (var x = 0; x < this._eventListeners.length; x++) { | ||
var eventListener = this._eventListeners[x]; | ||
|
||
if (eventListener.event === event) { | ||
var eventListenerDetails = eventDetails || {}; | ||
eventListenerDetails.currentTarget = this; | ||
eventListenerDetails.type = event; | ||
eventListener.listener.call(this, eventListenerDetails); | ||
} | ||
} | ||
|
||
return this; | ||
return MockEventTarget.prototype.trigger.apply(this, arguments); | ||
}; | ||
|
||
MockXMLHttpRequest.prototype.open = function(method, url, async, user, password) { | ||
|
@@ -171,6 +165,8 @@ MockXMLHttpRequest.prototype.send = function(data) { | |
}, typeof(timeout) === 'number' ? timeout : self.timeout+1); | ||
|
||
} else { | ||
//trigger a load event to indicate the data has been sent | ||
self.upload.trigger('load'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
we should probably dispatch the other events e.g. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. possibly so. I didn't need any of the other events to get my tests working, but having a full lifecycle would probably be useful. |
||
|
||
//map the response to the XHR object | ||
self.status = response.status(); | ||
|
@@ -203,6 +199,7 @@ MockXMLHttpRequest.prototype.abort = function() { | |
|
||
if (this.readyState > MockXMLHttpRequest.STATE_UNSENT && this.readyState < MockXMLHttpRequest.STATE_DONE) { | ||
this.readyState = MockXMLHttpRequest.STATE_UNSENT; | ||
this.upload.trigger('abort'); | ||
this.trigger('abort'); | ||
} | ||
|
||
|
@@ -233,24 +230,4 @@ MockXMLHttpRequest.prototype.getResponseHeader = function(name) { | |
return this._responseHeaders[name.toLowerCase()] || null; | ||
}; | ||
|
||
MockXMLHttpRequest.prototype.addEventListener = function(event, listener) { | ||
this._eventListeners.push({ | ||
event: event, | ||
listener: listener | ||
}); | ||
}; | ||
|
||
MockXMLHttpRequest.prototype.removeEventListener = function(event, listener) { | ||
var currentIndex = 0; | ||
|
||
while (currentIndex < this._eventListeners.length) { | ||
var eventListener = this._eventListeners[currentIndex]; | ||
if (eventListener.event === event && eventListener.listener === listener) { | ||
this._eventListeners.splice(currentIndex, 1); | ||
} else { | ||
currentIndex++; | ||
} | ||
} | ||
}; | ||
|
||
module.exports = MockXMLHttpRequest; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the fix here. do you think this should have been implemented on the response interface?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what do you think about
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good suggestion. I like the symmetry of having the upload related events on the request and the download related events on the response.