From 4a48f9603fb4c09f2e81461010dd758a67c458a1 Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Tue, 3 Feb 2015 14:53:26 -0800 Subject: [PATCH] refactor(test): update to jasmine 2.0 and refactor tests --- package.json | 15 +- test/counting-zone.disabled.js | 106 +++++++++++++++ test/counting-zone.spec.js | 123 ----------------- test/long-stack-trace-zone.spec.js | 22 +-- test/patch/HTMLImports.spec.js | 90 ++++-------- test/patch/MutationObserver.spec.js | 57 ++------ test/patch/Promise.spec.js | 54 ++------ test/patch/XMLHttpRequest.spec.js | 58 +++----- test/patch/registerElement.spec.js | 166 +++++++++-------------- test/patch/requestAnimationFrame.spec.js | 129 ++---------------- test/patch/setInterval.spec.js | 16 +-- test/patch/setTimeout.spec.js | 14 +- test/zone.spec.js | 27 ++-- zone.js | 15 +- 14 files changed, 309 insertions(+), 583 deletions(-) create mode 100644 test/counting-zone.disabled.js delete mode 100644 test/counting-zone.spec.js diff --git a/package.json b/package.json index 8930cc3c3..2950692a9 100644 --- a/package.json +++ b/package.json @@ -20,12 +20,13 @@ "url": "https://github.com/angular/zone.js/issues" }, "devDependencies": { - "karma": "0.12.16", - "karma-sauce-launcher": "~0.2.0", - "karma-jasmine": "0.1.5", - "karma-chrome-launcher": "^0.1.4", - "karma-coverage": "~0.1.4", - "karma-firefox-launcher": "~0.1.3", - "karma-safari-launcher": "^0.1.1" + "jasmine-core": "^2.2.0", + "karma": "^0.12.31", + "karma-chrome-launcher": "^0.1.7", + "karma-firefox-launcher": "^0.1.4", + "karma-jasmine": "^0.3.5", + "karma-safari-launcher": "^0.1.1", + "karma-sauce-launcher": "^0.2.10", + "nodejs-websocket": "^1.2.0" } } diff --git a/test/counting-zone.disabled.js b/test/counting-zone.disabled.js new file mode 100644 index 000000000..f7844256c --- /dev/null +++ b/test/counting-zone.disabled.js @@ -0,0 +1,106 @@ +'use strict'; + +describe('Zone.countingZone', function () { + function makeCountingZone() { + return zone.fork(Zone.longStackTraceZone). + fork(Zone.countingZone); + } + + it('should flush at the end of a run', function (done) { + makeCountingZone().fork({ + onFlush: done + }).run(function () { }); + }); + + + it('should work with setTimeout', function (done) { + var countingZone = makeCountingZone(); + countingZone.run(function () { + setTimeout(function () { + expect(countingZone.counter()).toBe(0); + done(); + }, 0); + expect(countingZone.counter()).toBe(1); + }); + }); + + + it('should work with clearTimeout', function (done) { + var countingZone = makeCountingZone(); + + makeCountingZone().run(function () { + var id = setTimeout(function () {}, 0); + expect(countingZone.counter()).toBe(1); + clearTimeout(id); + expect(countingZone.counter()).toBe(0); + done(); + }); + }); + + + it('should work with setInterval', function (done) { + var latch = 0, + countingZone = makeCountingZone(), + id; + + countingZone.run(function () { + expect(countingZone.counter()).toBe(0); + + id = setInterval(function () { + latch += 1; + + // setInterval should run multiple times + if (latch === 2) { + finish(); + } + }, 0); + + expect(countingZone.counter()).toBe(1); + }); + + function finish() { + expect(countingZone.counter()).toBe(1); + clearInterval(id); + done(); + } + }); + + + it('should work with clearInterval', function (done) { + var id; + countingZone.run(function () { + id = setInterval(function () { + latch += 1; + }, 0); + expect(countingZone.counter()).toBe(1); + clearInterval(id); + expect(countingZone.counter()).toBe(0); + done(); + }); + }); + + + it('should work with addEventListener', function (done) { + var elt = document.createElement('button'); + expect(countingZone.counter()).toBe(0); + countingZone.run(main); + + function main () { + expect(countingZone.counter()).toBe(0); + elt.addEventListener('click', onClick); + expect(countingZone.counter()).toBe(1); + + elt.click(); + function onClick () { + expect(countingZone.counter()).toBe(1); + elt.removeEventListener('click', onClick); + expect(countingZone.counter()).toBe(0); + + done(); + clicked = true; + } + + expect(countingZone.counter()).toBe(0); + } + }); +}); diff --git a/test/counting-zone.spec.js b/test/counting-zone.spec.js deleted file mode 100644 index 98737211c..000000000 --- a/test/counting-zone.spec.js +++ /dev/null @@ -1,123 +0,0 @@ -'use strict'; - -describe('Zone.countingZone', function () { - var flushSpy, countingZone; - - beforeEach(function () { - flushSpy = jasmine.createSpy('flush'); - countingZone = zone.fork(Zone.longStackTraceZone). - fork(Zone.countingZone). - fork({ - onFlush: flushSpy - }); - }); - - it('should flush at the end of a run', function () { - countingZone.run(function () { - expect(countingZone.counter()).toBe(0); - }); - expect(countingZone.counter()).toBe(0); - expect(flushSpy.calls.length).toBe(1); - }); - - it('should work with setTimeout', function () { - var latch; - - runs(function () { - countingZone.run(function () { - setTimeout(function () { - latch = true; - }, 0); - expect(countingZone.counter()).toBe(1); - }); - }); - - waitsFor(function () { - return latch; - }); - - runs(function () { - expect(countingZone.counter()).toBe(0); - }) - }); - - it('should work with clearTimeout', function () { - var latch = false; - countingZone.run(function () { - var id = setTimeout(function () { - latch = true; - }, 0); - expect(countingZone.counter()).toBe(1); - clearTimeout(id); - expect(countingZone.counter()).toBe(0); - }); - }); - - it('should work with setInterval', function () { - var latch = 0, id; - - runs(function () { - countingZone.run(function () { - id = setInterval(function () { - latch += 1; - }, 0); - expect(countingZone.counter()).toBe(1); - }); - }); - - waitsFor(function () { - return latch === 2; - }, 100, 'latch to increment'); - - runs(function () { - expect(countingZone.counter()).toBe(1); - clearInterval(id); - }); - }); - - it('should work with clearInterval', function () { - var id; - countingZone.run(function () { - id = setInterval(function () { - latch += 1; - }, 0); - expect(countingZone.counter()).toBe(1); - clearInterval(id); - expect(countingZone.counter()).toBe(0); - }); - }); - - it('should work with addEventListener', function () { - var elt = document.createElement('button'); - var clicked = false; - - runs(function () { - countingZone.run(main); - }); - - function main () { - expect(countingZone.counter()).toBe(0); - elt.addEventListener('click', onClick); - expect(countingZone.counter()).toBe(1); - - elt.click(); - function onClick () { - expect(countingZone.counter()).toBe(1); - elt.removeEventListener('click', onClick); - expect(countingZone.counter()).toBe(0); - clicked = true; - } - - expect(countingZone.counter()).toBe(0); - } - - waitsFor(function () { - return clicked; - }, 10, 'the thing'); - - runs(function () { - expect(flushSpy.calls.length).toBe(1); - }); - - }); -}); diff --git a/test/long-stack-trace-zone.spec.js b/test/long-stack-trace-zone.spec.js index a797d10f2..5eb87b921 100644 --- a/test/long-stack-trace-zone.spec.js +++ b/test/long-stack-trace-zone.spec.js @@ -11,26 +11,25 @@ describe('longStackTraceZone', function () { beforeEach(function () { log = []; - jasmine.Clock.useMock(); }); - it('should produce long stack traces', function () { + it('should produce long stack traces', function (done) { lstz.run(function () { setTimeout(function () { setTimeout(function () { + setTimeout(function () { + expect(log[0]).toBe('Error: hello'); + expect(log[1].split('--- ').length).toBe(4); + done(); + }, 0); throw new Error('hello'); }, 0); }, 0); }); - - jasmine.Clock.tick(0); - - expect(log[0]).toBe('Error: hello'); - expect(log[1].split('--- ').length).toBe(4); }); - it('should filter based on stackFramesFilter', function () { + it('should filter based on stackFramesFilter', function (done) { lstz.fork({ stackFramesFilter: function (line) { return line.indexOf('jasmine.js') === -1; @@ -38,12 +37,13 @@ describe('longStackTraceZone', function () { }).run(function () { setTimeout(function () { setTimeout(function () { + setTimeout(function () { + expect(log[1]).not.toContain('jasmine.js'); + done(); + }, 0); throw new Error('hello'); }, 0); }, 0); }); - - jasmine.Clock.tick(0); - expect(log[1]).not.toContain('jasmine.js'); }); }); diff --git a/test/patch/HTMLImports.spec.js b/test/patch/HTMLImports.spec.js index 5a5319377..28d4dfcc1 100644 --- a/test/patch/HTMLImports.spec.js +++ b/test/patch/HTMLImports.spec.js @@ -2,79 +2,41 @@ describe('HTML Imports', ifEnvSupports(supportsImports, function () { - var flag, hasParent; - - beforeEach(function () { - flag = false; - hasParent = false; - }); - - it('should work with addEventListener', function () { - var link; - - runs(function () { - link = document.createElement('link'); - link.rel = 'import'; - link.href = 'someUrl'; - link.addEventListener('error', setFlag); - document.head.appendChild(link); - }); - - waitsFor(flagToBeTrue, 'template to resolve', 100); - - runs(function() { - expect(hasParent).toBe(true); + it('should work with addEventListener', function (done) { + var link = document.createElement('link'); + link.rel = 'import'; + link.href = 'someUrl'; + link.addEventListener('error', function () { + expect(window.zone.parent).toBeDefined(); document.head.removeChild(link); + done(); }); + document.head.appendChild(link); }); - it('should work with onerror', function () { - var link; - - runs(function () { - link = document.createElement('link'); - link.rel = 'import'; - link.href = 'anotherUrl'; - link.onerror = setFlag; - document.head.appendChild(link); - }); - - waitsFor(flagToBeTrue, 'template to resolve', 100); - - runs(function() { - expect(hasParent).toBe(true); + it('should work with onerror', function (done) { + var link = document.createElement('link'); + link.rel = 'import'; + link.href = 'anotherUrl'; + link.onerror = function () { + expect(window.zone.parent).toBeDefined(); document.head.removeChild(link); - }); + done(); + }; + document.head.appendChild(link); }); - it('should work with onload', function () { - var link; - - runs(function () { - link = document.createElement('link'); - link.rel = 'import'; - link.href = '/base/test/assets/import.html'; - link.onload = setFlag; - document.head.appendChild(link); - }); - - waitsFor(flagToBeTrue, 'template to resolve', 100); - - runs(function() { - expect(hasParent).toBe(true); + it('should work with onload', function (done) { + var link = document.createElement('link'); + link.rel = 'import'; + link.href = '/base/test/assets/import.html'; + link.onload = function () { + expect(window.zone.parent).toBeDefined(); document.head.removeChild(link); - }); + done(); + }; + document.head.appendChild(link); }); - - function setFlag() { - hasParent = !!window.zone.parent; - flag = true; - } - - function flagToBeTrue() { - return flag; - } - })); function supportsImports() { diff --git a/test/patch/MutationObserver.spec.js b/test/patch/MutationObserver.spec.js index 2cfadc3ec..0e4a24c1d 100644 --- a/test/patch/MutationObserver.spec.js +++ b/test/patch/MutationObserver.spec.js @@ -7,31 +7,17 @@ describe('MutationObserver', ifEnvSupports('MutationObserver', function () { elt = document.createElement('div'); }); - it('should work', function () { - var flag = false, - hasParent; - - runs(function () { - var ob = new MutationObserver(function () { - hasParent = !!window.zone.parent; - flag = true; - }); - - ob.observe(elt, { - childList: true - }); - - elt.innerHTML = '

hey

'; + it('should run observers within the zone', function (done) { + var ob = new MutationObserver(function () { + expect(window.zone.parent).toBeDefined(); + done(); }); - waitsFor(function() { - return flag; - }, 'mutation observer to fire', 100); - - runs(function() { - expect(hasParent).toBe(true); + ob.observe(elt, { + childList: true }); + elt.innerHTML = '

hey

'; }); it('should dequeue upon disconnect', function () { @@ -91,31 +77,18 @@ describe('MutationObserver', ifEnvSupports('MutationObserver', function () { })); describe('WebKitMutationObserver', ifEnvSupports('WebKitMutationObserver', function () { - it('should ensure observers run within the zone', function () { - var flag = false, - elt = document.createElement('div'), - hasParent; + it('should run observers within the zone', function (done) { + var elt = document.createElement('div'); - runs(function () { - var ob = new WebKitMutationObserver(function () { - hasParent = !!window.zone.parent; - flag = true; - }); - - ob.observe(elt, { - childList: true - }); - - elt.innerHTML = '

hey

'; + var ob = new WebKitMutationObserver(function () { + expect(window.zone.parent).toBeDefined(); + done(); }); - waitsFor(function() { - return flag; - }, 'mutation observer to fire', 100); - - runs(function() { - expect(hasParent).toBe(true); + ob.observe(elt, { + childList: true }); + elt.innerHTML = '

hey

'; }); })); diff --git a/test/patch/Promise.spec.js b/test/patch/Promise.spec.js index bc367523c..7c6b13a2f 100644 --- a/test/patch/Promise.spec.js +++ b/test/patch/Promise.spec.js @@ -1,61 +1,31 @@ 'use strict'; describe('Promise', function () { - var flag, hasParent; - beforeEach(function () { - jasmine.Clock.useMock(); - flag = false; - hasParent = false; - }); - - it('should work with .then', function () { + it('should work with .then', function (done) { if (!window.Promise) { console.log('WARNING: skipping Promise test (missing this API)'); return; } - runs(function () { - new Promise(function (resolve) { - setTimeout(resolve, 0); - }).then(function () { - hasParent = !!window.zone.parent; - flag = true; - }); - jasmine.Clock.tick(1); - }); - - - waitsFor(function() { - return flag; - }, 'promise to resolve', 100); - - runs(function() { - expect(hasParent).toBe(true); + new Promise(function (resolve) { + resolve(); + }).then(function () { + expect(window.zone.parent).toBeDefined(); + done(); }); }); - it('should work with .catch', function () { + it('should work with .catch', function (done) { if (!window.Promise) { return; } - runs(function() { - new Promise(function (resolve, reject) { - setTimeout(reject, 0); - }).catch(function () { - hasParent = !!window.zone.parent; - flag = true; - }); - jasmine.Clock.tick(1); - }); - - waitsFor(function() { - return flag; - }, 'promise to reject', 100); - - runs(function() { - expect(hasParent).toBe(true); + new Promise(function (resolve, reject) { + reject(); + }).catch(function () { + expect(window.zone.parent).toBeDefined(); + done(); }); }); diff --git a/test/patch/XMLHttpRequest.spec.js b/test/patch/XMLHttpRequest.spec.js index 6e5a01ff0..047bcfb1c 100644 --- a/test/patch/XMLHttpRequest.spec.js +++ b/test/patch/XMLHttpRequest.spec.js @@ -2,50 +2,24 @@ describe('XMLHttpRequest', function () { - it('should work with onreadystatechange', function () { - var flag = false, - hasParent; - - runs(function () { - var req = new XMLHttpRequest(); - req.onreadystatechange = function () { - hasParent = !!window.zone.parent; - flag = true; - }; - req.open('get', '/', true); - req.send(); - }); - - waitsFor(function() { - return flag; - }, 'HTTP request to resolve', 100); - - runs(function() { - expect(hasParent).toBe(true); - }); + it('should work with onreadystatechange', function (done) { + var req = new XMLHttpRequest(); + req.onreadystatechange = function () { + expect(window.zone.parent).toBeDefined(); + done(); + }; + req.open('get', '/', true); + req.send(); }); - it('should work with onprogress', function () { - var flag = false, - hasParent; - - runs(function () { - var req = new XMLHttpRequest(); - req.onprogress = function () { - hasParent = !!window.zone.parent; - flag = true; - }; - req.open('get', '/', true); - req.send(); - }); - - waitsFor(function() { - return flag; - }, 'HTTP request to resolve', 100); - - runs(function() { - expect(hasParent).toBe(true); - }); + it('should work with onprogress', function (done) { + var req = new XMLHttpRequest(); + req.onprogress = function () { + expect(window.zone.parent).toBeDefined(); + done(); + }; + req.open('get', '/', true); + req.send(); }); it('should preserve other setters', function () { diff --git a/test/patch/registerElement.spec.js b/test/patch/registerElement.spec.js index cc69139e6..2c52e4565 100644 --- a/test/patch/registerElement.spec.js +++ b/test/patch/registerElement.spec.js @@ -6,149 +6,107 @@ 'use strict'; describe('document.registerElement', ifEnvSupports(registerElement, function () { - var flag, hasParent; // register a custom element for each callback - var callbacks = [ + var callbackNames = [ 'created', 'attached', 'detached', 'attributeChanged' ]; - function flagAndCheckZone() { - flag = true; - hasParent = !!window.zone.parent; - } + var callbacks = {}; - var customElements = callbacks.map(function (callbackName) { + var customElements = callbackNames.map(function (callbackName) { var fullCallbackName = callbackName + 'Callback'; var proto = Object.create(HTMLElement.prototype); - proto[fullCallbackName] = flagAndCheckZone; + proto[fullCallbackName] = function (arg) { + callbacks[callbackName](arg); + }; return document.registerElement('x-' + callbackName.toLowerCase(), { prototype: proto }); }); - beforeEach(function () { - flag = false; - hasParent = false; + it('should work with createdCallback', function (done) { + callbacks.created = function () { + expect(window.zone.parent).toBeDefined(); + done(); + }; + var elt = document.createElement('x-created'); }); - it('should work with createdCallback', function () { - runs(function () { - var elt = document.createElement('x-created'); - }); - - waitsFor(function() { - return flag; - }, 'createdCallback to fire', 100); - - runs(function() { - expect(hasParent).toBe(true); - }); + it('should work with attachedCallback', function (done) { + callbacks.attached = function () { + expect(window.zone.parent).toBeDefined(); + done(); + }; + var elt = document.createElement('x-attached'); + document.body.appendChild(elt); + document.body.removeChild(elt); }); - it('should work with attachedCallback', function () { - runs(function () { - var elt = document.createElement('x-attached'); - document.body.appendChild(elt); - document.body.removeChild(elt); - }); - - waitsFor(function() { - return flag; - }, 'attachedCallback to fire', 100); - - runs(function() { - expect(hasParent).toBe(true); - }); + it('should work with detachedCallback', function (done) { + callbacks.detached = function () { + expect(window.zone.parent).toBeDefined(); + done(); + }; + var elt = document.createElement('x-detached'); + document.body.appendChild(elt); + document.body.removeChild(elt); }); - it('should work with detachedCallback', function () { - runs(function () { - var elt = document.createElement('x-detached'); - document.body.appendChild(elt); - document.body.removeChild(elt); - }); - - waitsFor(function() { - return flag; - }, 'detachedCallback to fire', 100); - - runs(function() { - expect(hasParent).toBe(true); - }); + it('should work with attributeChanged', function (done) { + callbacks.attributeChanged = function () { + expect(window.zone.parent).toBeDefined(); + done(); + }; + var elt = document.createElement('x-attributechanged'); + elt.id = 'bar'; }); - it('should work with attributeChanged', function () { - runs(function () { - var elt = document.createElement('x-attributechanged'); - elt.id = 'bar'; + it('should work with non-writable, non-configurable prototypes created with defineProperty', function (done) { + var proto = Object.create(HTMLElement.prototype); + Object.defineProperty(proto, 'createdCallback', { + writeable: false, + configurable: false, + value: checkZone }); - - waitsFor(function() { - return flag; - }, 'attributeChanged to fire', 100); - - runs(function() { - expect(hasParent).toBe(true); + document.registerElement('x-prop-desc', { + prototype: proto }); + var elt = document.createElement('x-prop-desc'); + + function checkZone() { + expect(window.zone.parent).toBeDefined(); + done(); + } }); - it('should work with prototypes that have non-writable, non-configurable descriptors', function () { - runs(function () { - var proto = Object.create(HTMLElement.prototype); - Object.defineProperty(proto, 'createdCallback', { + it('should work with non-writable, non-configurable prototypes created with defineProperties', function (done) { + var proto = Object.create(HTMLElement.prototype); + Object.defineProperties(proto, { + createdCallback: { writeable: false, configurable: false, - value: flagAndCheckZone - }); - document.registerElement('x-prop-desc', { - prototype: proto - }); - var elt = document.createElement('x-prop-desc'); - }); - - waitsFor(function() { - return flag; - }, 'createdCallback to fire', 100); - - runs(function() { - expect(hasParent).toBe(true); + value: checkZone + } }); - }); - - - it('should work with prototypes that have non-writable, non-configurable descriptors', function () { - runs(function () { - var proto = Object.create(HTMLElement.prototype); - Object.defineProperties(proto, { - createdCallback: { - writeable: false, - configurable: false, - value: flagAndCheckZone - } - }); - document.registerElement('x-props-desc', { - prototype: proto - }); - var elt = document.createElement('x-props-desc'); + document.registerElement('x-props-desc', { + prototype: proto }); + var elt = document.createElement('x-props-desc'); - waitsFor(function() { - return flag; - }, 'createdCallback to fire', 100); - - runs(function() { - expect(hasParent).toBe(true); - }); + function checkZone() { + expect(window.zone.parent).toBeDefined(); + done(); + } }); })); diff --git a/test/patch/requestAnimationFrame.spec.js b/test/patch/requestAnimationFrame.spec.js index 731008c86..2a375f202 100644 --- a/test/patch/requestAnimationFrame.spec.js +++ b/test/patch/requestAnimationFrame.spec.js @@ -1,154 +1,55 @@ 'use strict'; describe('requestAnimationFrame', function () { - var flag, hasParent, skip = false; - - it('should work', function (done) { - + it('should run the passed callback in a zone', function (done) { if (!window.requestAnimationFrame) { console.log('WARNING: skipping requestAnimationFrame test (missing this API)'); - return; + return done(); } // Some browsers (especially Safari) do not fire requestAnimationFrame // if they are offscreen. We can disable this test for those browsers and // assume the patch works if setTimeout works, since they are mechanically // the same - runs(function() { - flag = false; - window.requestAnimationFrame(function () { - flag = true; - }); - setTimeout(function () { - skip = true; - flag = true; - console.log('WARNING: skipping requestAnimationFrame test (not firing rAF)'); - }, 50); - }); - - waitsFor(function() { - return flag; - }, "requestAnimationFrame to run", 100); - - runs(function() { - flag = false; - hasParent = false; - - window.requestAnimationFrame(function () { - hasParent = !!window.zone.parent; - flag = true; - }); + window.requestAnimationFrame(function () { + expect(window.zone.parent).toBeDefined(); + done(); }); - - waitsFor(function() { - return flag || skip; - }, "requestAnimationFrame to run", 100); - - runs(function() { - expect(hasParent || skip).toBe(true); - }); - }); }); describe('mozRequestAnimationFrame', function () { - var flag, hasParent, skip = false; - - it('should work', function (done) { - + it('should run the passed callback in a zone', function (done) { if (!window.mozRequestAnimationFrame) { console.log('WARNING: skipping mozRequestAnimationFrame test (missing this API)'); - return; + return done(); } // Some browsers (especially Safari) do not fire mozRequestAnimationFrame // if they are offscreen. We can disable this test for those browsers and // assume the patch works if setTimeout works, since they are mechanically // the same - runs(function() { - flag = false; - window.mozRequestAnimationFrame(function () { - flag = true; - }); - setTimeout(function () { - skip = true; - flag = true; - console.log('WARNING: skipping mozRequestAnimationFrame test (not firing rAF)'); - }, 50); - }); - - waitsFor(function() { - return flag; - }, 'mozRequestAnimationFrame to run', 100); - - runs(function() { - flag = false; - hasParent = false; - - window.mozRequestAnimationFrame(function () { - hasParent = !!window.zone.parent; - flag = true; - }); - }); - - waitsFor(function() { - return flag || skip; - }, 'mozRequestAnimationFrame to run', 100); - - runs(function() { - expect(hasParent || skip).toBe(true); + window.mozRequestAnimationFrame(function () { + expect(window.zone.parent).toBeDefined(); + done(); }); - }); }); describe('webkitRequestAnimationFrame', function () { - var flag, hasParent, skip = false; - - it('should work', function (done) { - + it('should run the passed callback in a zone', function (done) { if (!window.webkitRequestAnimationFrame) { console.log('WARNING: skipping webkitRequestAnimationFrame test (missing this API)'); - return; + return done(); } // Some browsers (especially Safari) do not fire webkitRequestAnimationFrame // if they are offscreen. We can disable this test for those browsers and // assume the patch works if setTimeout works, since they are mechanically // the same - runs(function() { - flag = false; - window.webkitRequestAnimationFrame(function () { - flag = true; - }); - setTimeout(function () { - skip = true; - flag = true; - console.log('WARNING: skipping webkitRequestAnimationFrame test (not firing rAF)'); - }, 50); + window.webkitRequestAnimationFrame(function () { + expect(window.zone.parent).toBeDefined(); + done(); }); - - waitsFor(function() { - return flag; - }, 'webkitRequestAnimationFrame to run', 100); - - runs(function() { - flag = false; - hasParent = false; - - window.webkitRequestAnimationFrame(function () { - hasParent = !!window.zone.parent; - flag = true; - }); - }); - - waitsFor(function() { - return flag || skip; - }, 'webkitRequestAnimationFrame to run', 100); - - runs(function() { - expect(hasParent || skip).toBe(true); - }); - }); }); diff --git a/test/patch/setInterval.spec.js b/test/patch/setInterval.spec.js index a3c9dce7d..da86d53b6 100644 --- a/test/patch/setInterval.spec.js +++ b/test/patch/setInterval.spec.js @@ -4,10 +4,9 @@ describe('setInterval', function () { beforeEach(function () { zone.mark = 'root'; - jasmine.Clock.useMock(); }); - it('should work with setInterval', function () { + it('should work with setInterval', function (done) { var childZone = window.zone.fork({ mark: 'child' }); @@ -20,16 +19,15 @@ describe('setInterval', function () { var cancelId = window.setInterval(function() { // creates implied zone in all callbacks. - expect(zone).not.toEqual(childZone); - expect(zone.parent).toEqual(childZone); - expect(zone.mark).toEqual('child'); // proto inherited - }, 10); + expect(zone).not.toBe(childZone); + expect(zone.parent).toBe(childZone); + expect(zone.mark).toBe('child'); // proto inherited - jasmine.Clock.tick(11); + clearInterval(cancelId); + done(); + }, 10); expect(zone.mark).toEqual('child'); - - clearInterval(cancelId); }); expect(zone.mark).toEqual('root'); diff --git a/test/patch/setTimeout.spec.js b/test/patch/setTimeout.spec.js index e915c451f..945cf1771 100644 --- a/test/patch/setTimeout.spec.js +++ b/test/patch/setTimeout.spec.js @@ -4,10 +4,9 @@ describe('setTimeout', function () { beforeEach(function () { zone.mark = 'root'; - jasmine.Clock.useMock(); }); - it('should work with setTimeout', function () { + it('should work with setTimeout', function (done) { var childZone = window.zone.fork({ mark: 'child' @@ -24,6 +23,7 @@ describe('setTimeout', function () { expect(zone).not.toEqual(childZone); expect(zone.parent).toEqual(childZone); expect(zone.mark).toEqual('child'); // proto inherited + done(); }, 0); expect(zone.mark).toEqual('child'); @@ -32,14 +32,14 @@ describe('setTimeout', function () { expect(zone.mark).toEqual('root'); }); - it('should allow canceling of fns registered with setTimeout', function () { + it('should allow canceling of fns registered with setTimeout', function (done) { var spy = jasmine.createSpy(); var cancelId = window.setTimeout(spy, 0); window.clearTimeout(cancelId); - - jasmine.Clock.tick(1); - - expect(spy).not.toHaveBeenCalled(); + setTimeout(function () { + expect(spy).not.toHaveBeenCalled(); + done(); + }); }); }); diff --git a/test/zone.spec.js b/test/zone.spec.js index 7898a7952..790d89d3c 100644 --- a/test/zone.spec.js +++ b/test/zone.spec.js @@ -8,10 +8,6 @@ describe('Zone', function () { describe('hooks', function () { - beforeEach(function () { - jasmine.Clock.useMock(); - }); - it('should fire beforeTask before a zone runs a function', function () { var enterSpy = jasmine.createSpy(); var myZone = zone.fork({ @@ -25,6 +21,7 @@ describe('Zone', function () { }); }); + it('should fire afterTask after a zone runs a function', function () { var leaveSpy = jasmine.createSpy(); var myZone = zone.fork({ @@ -38,7 +35,8 @@ describe('Zone', function () { expect(leaveSpy).toHaveBeenCalled(); }); - it('should fire onZoneCreated when a zone is forked', function () { + + it('should fire onZoneCreated when a zone is forked', function (done) { var createdSpy = jasmine.createSpy(); var counter = 0; var myZone = zone.fork({ @@ -54,21 +52,15 @@ describe('Zone', function () { expect(counter).toBe(0); - setTimeout(function () { - expect(counter).toBe(2); - }, 0); + setTimeout(function () {}, 0); expect(counter).toBe(1); setTimeout(function () { + expect(counter).toBe(0); + setTimeout(done, 5); expect(counter).toBe(1); - setTimeout(function () {}, 0); - expect(counter).toBe(2); }, 0); expect(counter).toBe(2); - - jasmine.Clock.tick(1); - - expect(counter).toBe(0); }); }); @@ -79,6 +71,7 @@ describe('Zone', function () { }).toThrow(); }); + it('should fire onError if a function run by a zone throws', function () { var errorSpy = jasmine.createSpy(); var myZone = zone.fork({ @@ -94,15 +87,13 @@ describe('Zone', function () { expect(errorSpy).toHaveBeenCalled(); }); + it('should allow you to override alert', function () { var spy = jasmine.createSpy(); var myZone = zone.fork({ alert: spy }); - //alert('foo'); - //expect(spy).not.toHaveBeenCalled(); - myZone.run(function () { alert('foo'); }); @@ -111,6 +102,7 @@ describe('Zone', function () { }); }); + it('should allow zones to be run from within another zone', function () { var a = zone.fork({ mark: 'a' @@ -128,6 +120,7 @@ describe('Zone', function () { expect(zone.mark).toBe('root'); }); + describe('fork', function () { it('should fork deep copy', function () { var protoZone = { too: { deep: true } }, diff --git a/zone.js b/zone.js index dc5b5bde8..4c17a9484 100644 --- a/zone.js +++ b/zone.js @@ -357,6 +357,7 @@ Zone.patch = function patch () { } else { Zone.patchViaCapturingAllTheEvents(); Zone.patchClass('XMLHttpRequest'); + Zone.patchWebSocket(); } // patch promises @@ -413,6 +414,17 @@ Zone.patchViaCapturingAllTheEvents = function () { }); }; + +Zone.patchWebSocket = function() { + var WS = window.WebSocket; + window.WebSocket = function(a, b) { + var socket = arguments.length > 1 ? new WS(a, b) : new WS(a); + Zone.patchProperties(socket, ['onmessage']); + return socket; + }; +} + + // wrap some native API on `window` Zone.patchClass = function (className) { var OriginalClass = window[className]; @@ -458,6 +470,7 @@ Zone.patchClass = function (className) { }; }; + // wrap some native API on `window` Zone.patchMutationObserverClass = function (className) { var OriginalClass = window[className]; @@ -600,7 +613,7 @@ Zone.patchRegisterElement = function () { }; } -Zone.eventNames = 'copy cut paste abort blur focus canplay canplaythrough change click contextmenu dblclick drag dragend dragenter dragleave dragover dragstart drop durationchange emptied ended input invalid keydown keypress keyup load loadeddata loadedmetadata loadstart mousedown mouseenter mouseleave mousemove mouseout mouseover mouseup pause play playing progress ratechange reset scroll seeked seeking select show stalled submit suspend timeupdate volumechange waiting mozfullscreenchange mozfullscreenerror mozpointerlockchange mozpointerlockerror error webglcontextrestored webglcontextlost webglcontextcreationerror'.split(' '); +Zone.eventNames = 'copy cut paste abort blur focus canplay canplaythrough change click contextmenu dblclick drag dragend dragenter dragleave dragover dragstart drop durationchange emptied ended input invalid keydown keypress keyup load loadeddata loadedmetadata loadstart message mousedown mouseenter mouseleave mousemove mouseout mouseover mouseup pause play playing progress ratechange reset scroll seeked seeking select show stalled submit suspend timeupdate volumechange waiting mozfullscreenchange mozfullscreenerror mozpointerlockchange mozpointerlockerror error webglcontextrestored webglcontextlost webglcontextcreationerror'.split(' '); Zone.onEventNames = Zone.eventNames.map(function (property) { return 'on' + property; });