diff options
| -rw-r--r-- | src/Browser.js | 26 | ||||
| -rw-r--r-- | test/BrowserSpecs.js | 90 | 
2 files changed, 93 insertions, 23 deletions
| diff --git a/src/Browser.js b/src/Browser.js index 815b6b24..a53687d5 100644 --- a/src/Browser.js +++ b/src/Browser.js @@ -100,12 +100,19 @@ function Browser(window, document, body, XHR, $log) {      outstandingRequestCount ++;      if (lowercase(method) == 'json') {        var callbackId = ("angular_" + Math.random() + '_' + (idCounter++)).replace(/\d\./, ''); -      var script = self.addJs(url.replace('JSON_CALLBACK', callbackId)); -      window[callbackId] = function(data){ +      window[callbackId] = function(data) { +        window[callbackId].data = data; +      }; + +      var script = self.addJs(url.replace('JSON_CALLBACK', callbackId), null, function() { +        if (window[callbackId].data) { +          completeOutstandingRequest(callback, 200, window[callbackId].data); +        } else { +          completeOutstandingRequest(callback); +        }          delete window[callbackId];          body[0].removeChild(script); -        completeOutstandingRequest(callback, 200, data); -      }; +      });      } else {        var xhr = new XHR();        xhr.open(method, url, true); @@ -452,7 +459,7 @@ function Browser(window, document, body, XHR, $log) {     * @description     * Adds a script tag to the head.     */ -  self.addJs = function(url, domId) { +  self.addJs = function(url, domId, done) {      // we can't use jQuery/jqLite here because jQuery does crazy shit with script elements, e.g.:      // - fetches local scripts via XHR and evals them      // - adds and immediately removes script elements from the document @@ -465,6 +472,15 @@ function Browser(window, document, body, XHR, $log) {      script.type = 'text/javascript';      script.src = url;      if (domId) script.id = domId; + +    if (msie) { +      script.onreadystatechange = function() { +        /loaded|complete/.test(script.readyState) && done && done(); +      } +    } else { +      if (done) script.onload = script.onerror = done; +    } +      body[0].appendChild(script);      return script; diff --git a/test/BrowserSpecs.js b/test/BrowserSpecs.js index ebaf0651..92e4e501 100644 --- a/test/BrowserSpecs.js +++ b/test/BrowserSpecs.js @@ -87,27 +87,81 @@ describe('browser', function(){    describe('xhr', function(){      describe('JSON', function(){ -      it('should add script tag for request', function() { -        var callback = jasmine.createSpy('callback'); -        var log = ""; -        browser.xhr('JSON', 'http://example.org/path?cb=JSON_CALLBACK', null, function(code, data){ -          log += code + ':' + data + ';'; -        }); -        browser.notifyWhenNoOutstandingRequests(callback); -        expect(callback).not.toHaveBeenCalled(); -        expect(scripts.length).toEqual(1); -        var script = scripts[0]; -        var url = script.src.split('?cb='); -        expect(url[0]).toEqual('http://example.org/path'); -        expect(typeof fakeWindow[url[1]]).toEqual($function); -        fakeWindow[url[1]]('data'); -        expect(callback).toHaveBeenCalled(); -        expect(log).toEqual('200:data;'); -        expect(scripts).toEqual(removedScripts); -        expect(fakeWindow[url[1]]).toBeUndefined(); +      var log; + +      function callback(code, data) { +        log += code + ':' + data + ';'; +      } + +      beforeEach(function() { +        log = "";        }); + + +      // We don't have unit tests for IE because script.readyState is readOnly. +      // Instead we run e2e tests on all browsers - see e2e for $xhr. +      if (!msie) { + +        it('should add script tag for JSONP request', function() { +          var notify = jasmine.createSpy('notify'); +          browser.xhr('JSON', 'http://example.org/path?cb=JSON_CALLBACK', null, callback); +          browser.notifyWhenNoOutstandingRequests(notify); +          expect(notify).not.toHaveBeenCalled(); +          expect(scripts.length).toEqual(1); +          var script = scripts[0]; +          var url = script.src.split('?cb='); +          expect(url[0]).toEqual('http://example.org/path'); +          expect(typeof fakeWindow[url[1]]).toEqual($function); +          fakeWindow[url[1]]('data'); +          script.onload(); + +          expect(notify).toHaveBeenCalled(); +          expect(log).toEqual('200:data;'); +          expect(scripts).toEqual(removedScripts); +          expect(fakeWindow[url[1]]).toBeUndefined(); +        }); + + +        it('should call callback when script fails to load', function() { +          browser.xhr('JSON', 'http://example.org/path?cb=JSON_CALLBACK', null, callback); +          var script = scripts[0]; +          expect(typeof script.onload).toBe($function); +          expect(typeof script.onerror).toBe($function); +          script.onerror(); + +          expect(log).toEqual('undefined:undefined;'); +        }); + + +        it('should update the outstandingRequests counter for successful requests', function() { +          var notify = jasmine.createSpy('notify'); +          browser.xhr('JSON', 'http://example.org/path?cb=JSON_CALLBACK', null, callback); +          browser.notifyWhenNoOutstandingRequests(notify); +          expect(notify).not.toHaveBeenCalled(); + +          var script = scripts[0]; +          var url = script.src.split('?cb='); +          fakeWindow[url[1]]('data'); +          script.onload(); + +          expect(notify).toHaveBeenCalled(); +        }); + + +        it('should update the outstandingRequests counter for failed requests', function() { +          var notify = jasmine.createSpy('notify'); +          browser.xhr('JSON', 'http://example.org/path?cb=JSON_CALLBACK', null, callback); +          browser.notifyWhenNoOutstandingRequests(notify); +          expect(notify).not.toHaveBeenCalled(); + +          scripts[0].onerror(); + +          expect(notify).toHaveBeenCalled(); +        }); +      }      }); +      it('should normalize IE\'s 1223 status code into 204', function() {        var callback = jasmine.createSpy('XHR'); | 
