From 0a09153609a40f75ff32c3a361637083ad188357 Mon Sep 17 00:00:00 2001 From: rogersillito Date: Tue, 16 Jun 2015 11:26:28 +0100 Subject: [PATCH 1/3] missing spec runner and empty test subject file for deferred koans. Added missing alive/dead parameters for dispatchEvent in observable game-of-life spec --- koans/deferred/SpecRunner.html | 32 +++++++++++++++++++++++++++ koans/deferred/src/deferred.js | 0 koans/observable/spec/game-of-life.js | 10 ++++----- 3 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 koans/deferred/SpecRunner.html create mode 100644 koans/deferred/src/deferred.js diff --git a/koans/deferred/SpecRunner.html b/koans/deferred/SpecRunner.html new file mode 100644 index 0000000..89f5a4d --- /dev/null +++ b/koans/deferred/SpecRunner.html @@ -0,0 +1,32 @@ + + + + Deferred Koans + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/koans/deferred/src/deferred.js b/koans/deferred/src/deferred.js new file mode 100644 index 0000000..e69de29 diff --git a/koans/observable/spec/game-of-life.js b/koans/observable/spec/game-of-life.js index faa7703..7ca9b59 100644 --- a/koans/observable/spec/game-of-life.js +++ b/koans/observable/spec/game-of-life.js @@ -38,14 +38,14 @@ describe('Game of Life Widget', function () { expect(gameOfLife.tick).toHaveBeenCalled(); }); it('should add class alive when cell becomes alive', function () { - gameOfLife.dispatchEvent('cellStateChanged', 3, 4); + gameOfLife.dispatchEvent('cellStateChanged', 3, 4, true); expect(widget.find('.grid tr:nth-child(4) td:nth-child(5)').hasClass('alive')).toBe(true); }); it('should remove class alive when cell dies', function () { - gameOfLife.dispatchEvent('cellStateChanged', 3, 4); + gameOfLife.dispatchEvent('cellStateChanged', 3, 4, true); - gameOfLife.dispatchEvent('cellStateChanged', 3, 4); + gameOfLife.dispatchEvent('cellStateChanged', 3, 4, false); expect(widget.find('.grid tr:nth-child(4) td:nth-child(5)').hasClass('alive')).toBe(false); }); @@ -53,7 +53,7 @@ describe('Game of Life Widget', function () { gameOfLife = SAMURAIPRINCIPLE.eventDispatcher(jasmine.createSpyObj('gameOfLife', ['tick', 'toggleCellState'])); widget = jQuery('#gameOfLifeWidget').clone().appendTo('body').gameOfLifeWidget(gameOfLife, 10, 10, 250); - gameOfLife.dispatchEvent('cellStateChanged', 3, 4); + gameOfLife.dispatchEvent('cellStateChanged', 3, 4, true); expect(widget.find('.grid tr:nth-child(4) td:nth-child(5)').hasClass('alive')).toBe(false); setTimeout(function () { @@ -75,7 +75,7 @@ describe('Game of Life Widget', function () { gameOfLife = SAMURAIPRINCIPLE.eventDispatcher(jasmine.createSpyObj('gameOfLife', ['tick', 'toggleCellState'])); widget = jQuery('#gameOfLifeWidget').clone().appendTo('body').gameOfLifeWidget(gameOfLife, 10, 10, 250); - gameOfLife.dispatchEvent('cellStateChanged', 3, 4); + gameOfLife.dispatchEvent('cellStateChanged', 3, 4, true); clock.tick(200); expect(widget.find('.grid tr:nth-child(4) td:nth-child(5)').hasClass('alive')).toBe(false); From e8f639cc063617cc1319435aae2f9b72b17ff088 Mon Sep 17 00:00:00 2001 From: rogersillito Date: Tue, 28 Jul 2015 17:58:52 +0100 Subject: [PATCH 2/3] added missing links to spec runners on index page --- index.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index 5285a30..b76271b 100644 --- a/index.html +++ b/index.html @@ -7,5 +7,7 @@ Functions part 2
OOP
Observable
+ Functions part 3
+ Deferred
- \ No newline at end of file + From 6de700ea0d405247ea1a0486f2d348b50490d67f Mon Sep 17 00:00:00 2001 From: rogersillito Date: Fri, 31 Jul 2015 15:57:23 +0100 Subject: [PATCH 3/3] reworked deferred implementation: now works correctly with regard to pending deferreds passed as parameters. Also allows isRejected/Resolved values to stay hidden --- koans/deferred/SpecRunner.html | 2 + koans/deferred/spec/DeferredTest16.js | 6 +-- koans/deferred/spec/DeferredTest18.js | 14 ++++++ koans/deferred/spec/DeferredTest19.js | 15 ++++++ koans/deferred/src/deferred.js | 68 +++++++++++++++++++++++++++ 5 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 koans/deferred/spec/DeferredTest18.js create mode 100644 koans/deferred/spec/DeferredTest19.js diff --git a/koans/deferred/SpecRunner.html b/koans/deferred/SpecRunner.html index 89f5a4d..3f9d72f 100644 --- a/koans/deferred/SpecRunner.html +++ b/koans/deferred/SpecRunner.html @@ -28,5 +28,7 @@ + + diff --git a/koans/deferred/spec/DeferredTest16.js b/koans/deferred/spec/DeferredTest16.js index aadd7d8..a2c67f9 100644 --- a/koans/deferred/spec/DeferredTest16.js +++ b/koans/deferred/spec/DeferredTest16.js @@ -3,9 +3,9 @@ describe('Deferred.when', function () { var doneCallback = jasmine.createSpy(), failedCallback = jasmine.createSpy(); SAMURAIPRINCIPLE.Deferred.when( - (new SAMURAIPRINCIPLE.Deferred()).resolve(), - (new SAMURAIPRINCIPLE.Deferred()).resolve(), - (new SAMURAIPRINCIPLE.Deferred()).resolve() + (new SAMURAIPRINCIPLE.Deferred()).resolve(1), + (new SAMURAIPRINCIPLE.Deferred()).resolve(2), + (new SAMURAIPRINCIPLE.Deferred()).resolve(3) ).then(doneCallback, failedCallback); expect(doneCallback).toHaveBeenCalled(); expect(failedCallback).not.toHaveBeenCalled(); diff --git a/koans/deferred/spec/DeferredTest18.js b/koans/deferred/spec/DeferredTest18.js new file mode 100644 index 0000000..e17ab98 --- /dev/null +++ b/koans/deferred/spec/DeferredTest18.js @@ -0,0 +1,14 @@ +describe('Deferred.when', function () { + it('should return Deferred that is pending until all of the Deferreds have resolved', function () { + var doneCallback = jasmine.createSpy(), + failedCallback = jasmine.createSpy(); + SAMURAIPRINCIPLE.Deferred.when( + (new SAMURAIPRINCIPLE.Deferred()).resolve(), + (new SAMURAIPRINCIPLE.Deferred()).resolve(), + new SAMURAIPRINCIPLE.Deferred(), + (new SAMURAIPRINCIPLE.Deferred()).resolve() + ).then(doneCallback, failedCallback); + expect(doneCallback).not.toHaveBeenCalled(); + expect(failedCallback).not.toHaveBeenCalled(); + }); +}); diff --git a/koans/deferred/spec/DeferredTest19.js b/koans/deferred/spec/DeferredTest19.js new file mode 100644 index 0000000..a013d8a --- /dev/null +++ b/koans/deferred/spec/DeferredTest19.js @@ -0,0 +1,15 @@ +describe('Deferred.when', function () { + it('should return Deferred that is rejected where one Deferreds is rejected and the rest are pending', function () { + var doneCallback = jasmine.createSpy(), + failedCallback = jasmine.createSpy(); + SAMURAIPRINCIPLE.Deferred.when( + new SAMURAIPRINCIPLE.Deferred(), + new SAMURAIPRINCIPLE.Deferred(), + (new SAMURAIPRINCIPLE.Deferred()).reject(), + new SAMURAIPRINCIPLE.Deferred(), + new SAMURAIPRINCIPLE.Deferred() + ).then(doneCallback, failedCallback); + expect(doneCallback).not.toHaveBeenCalled(); + expect(failedCallback).toHaveBeenCalled(); + }); +}); diff --git a/koans/deferred/src/deferred.js b/koans/deferred/src/deferred.js index e69de29..252af01 100644 --- a/koans/deferred/src/deferred.js +++ b/koans/deferred/src/deferred.js @@ -0,0 +1,68 @@ +var log = console.log.bind(console); +var SAMURAIPRINCIPLE = {}; + +SAMURAIPRINCIPLE.Deferred = function() { + + var resolveCallbacks = [], + rejectCallbacks = [], + deferredValues, + self = this, + isRejected = false, + isResolved = false; + + this.done = function(resolvedHandler) { + resolveCallbacks.push(resolvedHandler); + if (isResolved) { + self.resolve.apply(self, deferredValues); + } + return self; + }; + + this.resolve = function() { + deferredValues = arguments; + for (var i = 0; i < resolveCallbacks.length; i++) { + resolveCallbacks[i].apply(null, deferredValues); + } + isResolved = true; + return self; + }; + + this.failed = function(rejectHandler) { + rejectCallbacks.push(rejectHandler); + if (isRejected) { + self.reject.apply(self, deferredValues); + } + return self; + }; + + this.reject = function() { + deferredValues = arguments; + for (var i = 0; i < rejectCallbacks.length; i++) { + rejectCallbacks[i].apply(null, deferredValues); + } + isRejected = true; + return self; + }; + + this.then = function(resolvedHandler, rejectHandler) { + self.done(resolvedHandler); + self.failed(rejectHandler); + return self; + }; +}; + +SAMURAIPRINCIPLE.Deferred.when = function() { + var result = new SAMURAIPRINCIPLE.Deferred(); + var resolveCount = 0; + var deferredCount = arguments.length; + + for (var i = 0; i < deferredCount; i++) { + arguments[i].then(function() { + if (++resolveCount === deferredCount) + result.resolve(); + }, function() { + result.reject(); + }); + } + return result; +}