From 85be9be88715157fdecd9713ef2629ad0b7c6df1 Mon Sep 17 00:00:00 2001 From: Sheel Choksi Date: Sun, 1 Jun 2014 15:37:19 -0700 Subject: [PATCH] Fixes for IE 8 and IE 9 - Object.keys isn't available in IE 8, so using a local objectKeys helper method that accomplishes the same effect for spec - The DONE property isn't supported in IE 8, so falling back to the numerical 4 in spec when necessary - Extending from an XMLHttpRequest can't extend properties that are filled in asynchronously (status, responseText, etc.) on IE 8 and IE 9 so we now skip these properties when extending --- lib/mock-ajax.js | 19 +++++++++++--- .../javascripts/fake-xml-http-request-spec.js | 25 +++++++++++-------- spec/javascripts/mock-ajax-toplevel-spec.js | 2 +- spec/javascripts/webmock-style-spec.js | 4 +-- 4 files changed, 33 insertions(+), 17 deletions(-) diff --git a/lib/mock-ajax.js b/lib/mock-ajax.js index 97e04a0..d622aad 100644 --- a/lib/mock-ajax.js +++ b/lib/mock-ajax.js @@ -31,13 +31,25 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ (function() { - function extend(destination, source) { + function extend(destination, source, propertiesToSkip) { + propertiesToSkip = propertiesToSkip || []; for (var property in source) { - destination[property] = source[property]; + 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 MockAjax(global) { var requestTracker = new RequestTracker(), stubTracker = new StubTracker(), @@ -101,7 +113,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. this.requestHeaders = {}; } - extend(FakeXMLHttpRequest.prototype, new window.XMLHttpRequest()); + var iePropertiesThatCannotBeCopied = ['responseBody', 'responseText', 'responseXML', 'status', 'statusText', 'responseTimeout']; + extend(FakeXMLHttpRequest.prototype, new window.XMLHttpRequest(), iePropertiesThatCannotBeCopied); extend(FakeXMLHttpRequest.prototype, { open: function() { this.method = arguments[0]; diff --git a/spec/javascripts/fake-xml-http-request-spec.js b/spec/javascripts/fake-xml-http-request-spec.js index a964b32..8a6cdbe 100644 --- a/spec/javascripts/fake-xml-http-request-spec.js +++ b/spec/javascripts/fake-xml-http-request-spec.js @@ -11,6 +11,17 @@ describe("FakeXMLHttpRequest", function() { xhr2 = new fakeGlobal.XMLHttpRequest(); }); + function objectKeys(obj) { + keys = []; + for (key in obj) { + if (obj.hasOwnProperty(key)) { + keys.push(key); + } + } + + return keys; + } + it("should have an initial readyState of 0 (uninitialized)", function() { expect(xhr.readyState).toEqual(0); }); @@ -21,7 +32,7 @@ describe("FakeXMLHttpRequest", function() { }); it("should make the request headers available", function() { - expect(Object.keys(xhr.requestHeaders).length).toEqual(1); + expect(objectKeys(xhr.requestHeaders).length).toEqual(1); expect(xhr.requestHeaders['X-Header-1']).toEqual('one'); }); @@ -31,12 +42,12 @@ describe("FakeXMLHttpRequest", function() { }); it("should make the only its request headers available", function() { - expect(Object.keys(xhr2.requestHeaders).length).toEqual(1); + expect(objectKeys(xhr2.requestHeaders).length).toEqual(1); expect(xhr2.requestHeaders['X-Header-2']).toEqual('two'); }); it("should not modify any other xhr objects", function() { - expect(Object.keys(xhr.requestHeaders).length).toEqual(1); + expect(objectKeys(xhr.requestHeaders).length).toEqual(1); expect(xhr.requestHeaders['X-Header-1']).toEqual('one'); }); }); @@ -97,14 +108,6 @@ describe("FakeXMLHttpRequest", function() { }); }); - it("can be extended", function(){ - pending("why do we want to do this?"); - FakeXMLHttpRequest.prototype.foo = function(){ - return "foo"; - }; - expect(new FakeXMLHttpRequest().foo()).toEqual("foo"); - }); - describe("data", function() { beforeEach(function() { xhr.open("POST", "http://example.com?this=that"); diff --git a/spec/javascripts/mock-ajax-toplevel-spec.js b/spec/javascripts/mock-ajax-toplevel-spec.js index 7378f0a..4e49275 100644 --- a/spec/javascripts/mock-ajax-toplevel-spec.js +++ b/spec/javascripts/mock-ajax-toplevel-spec.js @@ -16,7 +16,7 @@ describe("Jasmine Mock Ajax (for toplevel)", function() { complete = jasmine.createSpy("onComplete"); onreadystatechange = function() { - if (this.readyState == this.DONE) { + if (this.readyState == (this.DONE || 4)) { // IE 8 doesn't support DONE if (this.status == 200) { if (this.responseHeaders['Content-type'] === 'application/json') { this.response = JSON.parse(this.responseText); diff --git a/spec/javascripts/webmock-style-spec.js b/spec/javascripts/webmock-style-spec.js index 120c9e2..425d72e 100644 --- a/spec/javascripts/webmock-style-spec.js +++ b/spec/javascripts/webmock-style-spec.js @@ -5,7 +5,7 @@ describe("Webmock style mocking", function() { url = url || "http://example.com/someApi" var xhr = new fakeGlobal.XMLHttpRequest(); xhr.onreadystatechange = function(arguments) { - if (this.readyState == this.DONE) { + if (this.readyState == (this.DONE || 4)) { // IE 8 doesn't support DONE response = this; successSpy(); } @@ -85,7 +85,7 @@ describe("Webmock style mocking", function() { var postRequest = function(data) { var xhr = new fakeGlobal.XMLHttpRequest(); xhr.onreadystatechange = function(arguments) { - if (this.readyState == this.DONE) { + if (this.readyState == (this.DONE || 4)) { // IE 8 doesn't support DONE response = this; successSpy(); }