From 2bf55339ecdb6d17a9327405af2aec8dda7cbba2 Mon Sep 17 00:00:00 2001 From: kbparagua Date: Thu, 24 Mar 2016 22:26:06 +0800 Subject: [PATCH 1/5] Rename ControllerBuilder to ControllerClassFactory --- .../{controller_builder.js => controller_class_factory.js} | 6 +++--- vendor/assets/javascripts/paloma/index.js | 2 +- vendor/assets/javascripts/paloma/paloma.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) rename vendor/assets/javascripts/paloma/{controller_builder.js => controller_class_factory.js} (91%) diff --git a/vendor/assets/javascripts/paloma/controller_builder.js b/vendor/assets/javascripts/paloma/controller_class_factory.js similarity index 91% rename from vendor/assets/javascripts/paloma/controller_builder.js rename to vendor/assets/javascripts/paloma/controller_class_factory.js index 51a0dc4..53417cc 100644 --- a/vendor/assets/javascripts/paloma/controller_builder.js +++ b/vendor/assets/javascripts/paloma/controller_class_factory.js @@ -1,11 +1,11 @@ -Paloma.ControllerBuilder = function(){ +Paloma.ControllerClassFactory = function(){ this._controllers = {}; this._inheritanceSymbol = '<'; }; -Paloma.ControllerBuilder.prototype = { +Paloma.ControllerClassFactory.prototype = { - build: function(controllerAndParent, prototype){ + make: function(controllerAndParent, prototype){ var parts = this._extractParts(controllerAndParent), controller = this._getOrCreate( parts.controller ); diff --git a/vendor/assets/javascripts/paloma/index.js b/vendor/assets/javascripts/paloma/index.js index c080857..c801ce9 100644 --- a/vendor/assets/javascripts/paloma/index.js +++ b/vendor/assets/javascripts/paloma/index.js @@ -1,6 +1,6 @@ //= require ./init.js //= require ./base_controller.js -//= require ./controller_builder.js +//= require ./controller_class_factory.js //= require ./before_callback_performer.js //= require ./engine.js //= require ./paloma.js diff --git a/vendor/assets/javascripts/paloma/paloma.js b/vendor/assets/javascripts/paloma/paloma.js index 6e12dc0..08cef0b 100644 --- a/vendor/assets/javascripts/paloma/paloma.js +++ b/vendor/assets/javascripts/paloma/paloma.js @@ -1,10 +1,10 @@ (function(Paloma){ - Paloma._controllerBuilder = new Paloma.ControllerBuilder(); + Paloma._controllerClassFactory = new Paloma.ControllerClassFactory(); Paloma.engine = new Paloma.Engine({builder: Paloma._controllerBuilder}); Paloma.controller = function(name, prototype){ - return Paloma._controllerBuilder.build(name, prototype); + return Paloma._controllerClassFactory.make(name, prototype); }; Paloma._executeHook = function(){ From 13f07269a175cb8a7802dc07dbb9e720bfb06b27 Mon Sep 17 00:00:00 2001 From: kbparagua Date: Thu, 24 Mar 2016 22:57:07 +0800 Subject: [PATCH 2/5] adjust Paloma.Engine to use new ControllerBuilder --- .../javascripts/paloma/controller_builder.js | 34 +++++++++++++++++ vendor/assets/javascripts/paloma/engine.js | 37 +++++++++++-------- vendor/assets/javascripts/paloma/index.js | 1 + vendor/assets/javascripts/paloma/paloma.js | 17 ++++++--- 4 files changed, 67 insertions(+), 22 deletions(-) create mode 100644 vendor/assets/javascripts/paloma/controller_builder.js diff --git a/vendor/assets/javascripts/paloma/controller_builder.js b/vendor/assets/javascripts/paloma/controller_builder.js new file mode 100644 index 0000000..0e3802e --- /dev/null +++ b/vendor/assets/javascripts/paloma/controller_builder.js @@ -0,0 +1,34 @@ +Paloma.ControllerBuilder = function(classFactory){ + this.classFactory = classFactory; + this.options = {}; +}; + +Paloma.ControllerBuilder.prototype = { + + build: function(options){ + this.options = options; + + var ControllerClass = this._controllerClass(), + if ( !ControllerClass ) return null; + + return new ControllerClass( this._buildParams() ); + }, + + _controllerClass: function(){ + return this.classFactory.get( this.options.controller ); + }, + + _buildParams: function(){ + var params = { + _controller: this.options.controller, + _action: this.options.action + }; + + for (var k in this.options.params) + if (this.options.hasOwnProperty(k)) + params[k] = this.options.params[k]; + + return params; + } + +}; diff --git a/vendor/assets/javascripts/paloma/engine.js b/vendor/assets/javascripts/paloma/engine.js index 34c55f5..16e1559 100644 --- a/vendor/assets/javascripts/paloma/engine.js +++ b/vendor/assets/javascripts/paloma/engine.js @@ -1,5 +1,5 @@ -Paloma.Engine = function(config){ - this.builder = config.builder; +Paloma.Engine = function(controllerBuilder){ + this.controllerBuilder = controllerBuilder; this._clearRequest(); }; @@ -29,27 +29,31 @@ Paloma.Engine.prototype = { this._logRequest(); this._lastRequest = this._request; - var controllerClass = this.builder.get( this._request.controller ); - - if (controllerClass){ - var controller = new controllerClass( this._request.params ); - this._executeActionOf(controller); - } - + this._executeControllerAction(); this._clearRequest(); }, - _executeActionOf: function(controller){ + _executeControllerAction: function(){ + var controller = this._buildController(); + if (!controller) return; + var action = controller[ this._request.action ]; + if (!action) return; - if (action){ - var callbackPerformer = new Paloma.BeforeCallbackPerformer(controller); - callbackPerformer.perform( this._request.action ); + var callbackPerformer = new Paloma.BeforeCallbackPerformer(controller); + callbackPerformer.perform( this._request.action ); - action.call(controller); + action.call(controller); - this._lastRequest.executed = true; - } + this._lastRequest.executed = true; + }, + + _buildController: function(){ + return this.controllerBuilder.build({ + controller: this._request.controller, + action: this._request.action, + params: this._request.params + }); }, _shouldStop: function(){ @@ -71,4 +75,5 @@ Paloma.Engine.prototype = { _clearRequest: function(){ this._request = null; } + }; diff --git a/vendor/assets/javascripts/paloma/index.js b/vendor/assets/javascripts/paloma/index.js index c801ce9..1b348ec 100644 --- a/vendor/assets/javascripts/paloma/index.js +++ b/vendor/assets/javascripts/paloma/index.js @@ -2,5 +2,6 @@ //= require ./base_controller.js //= require ./controller_class_factory.js //= require ./before_callback_performer.js +//= require ./controller_builder.js //= require ./engine.js //= require ./paloma.js diff --git a/vendor/assets/javascripts/paloma/paloma.js b/vendor/assets/javascripts/paloma/paloma.js index 08cef0b..9fc381a 100644 --- a/vendor/assets/javascripts/paloma/paloma.js +++ b/vendor/assets/javascripts/paloma/paloma.js @@ -1,10 +1,15 @@ (function(Paloma){ - Paloma._controllerClassFactory = new Paloma.ControllerClassFactory(); - Paloma.engine = new Paloma.Engine({builder: Paloma._controllerBuilder}); + var classFactory = new Paloma.ControllerClassFactory(), + controllerBuilder = new Paloma.ControllerBuilder(classFactory), + engine = new Paloma.Engine(controllerBuilder) + + Paloma._controllerClassFactory = classFactory; + Paloma._controllerBuilder = controllerBuilder + Paloma.engine = engine; Paloma.controller = function(name, prototype){ - return Paloma._controllerClassFactory.make(name, prototype); + return classFactory.make(name, prototype); }; Paloma._executeHook = function(){ @@ -13,12 +18,12 @@ }; Paloma.start = function(){ - if ( !this.engine.hasRequest() ) this._executeHook(); - if ( this.engine.hasRequest() ) this.engine.start(); + if ( !engine.hasRequest() ) this._executeHook(); + if ( engine.hasRequest() ) engine.start(); }; Paloma.isExecuted = function(){ - return this.engine.lastRequest().executed; + return engine.lastRequest().executed; }; })(window.Paloma); From 853ba9c61482ce993a3ffd698c1930798909c739 Mon Sep 17 00:00:00 2001 From: kbparagua Date: Thu, 24 Mar 2016 23:22:46 +0800 Subject: [PATCH 3/5] Fix tests for Paloma.ControllerClassFactory --- ...ec.js => controller_class_factory_spec.js} | 48 +++++++++---------- .../javascripts/paloma/controller_builder.js | 2 +- 2 files changed, 25 insertions(+), 25 deletions(-) rename test_app/spec/javascripts/{controller_builder_spec.js => controller_class_factory_spec.js} (61%) diff --git a/test_app/spec/javascripts/controller_builder_spec.js b/test_app/spec/javascripts/controller_class_factory_spec.js similarity index 61% rename from test_app/spec/javascripts/controller_builder_spec.js rename to test_app/spec/javascripts/controller_class_factory_spec.js index 7b3bfbb..5c3dd56 100644 --- a/test_app/spec/javascripts/controller_builder_spec.js +++ b/test_app/spec/javascripts/controller_class_factory_spec.js @@ -1,19 +1,19 @@ -describe('Paloma.ControllerBuilder', function(){ +describe('Paloma.ControllerClassFactory', function(){ - var _builder = null; - function builder(){ return _builder; } + var _factory = null; + function factory(){ return _factory; } - function newBuilder(){ - _builder = new Paloma.ControllerBuilder(); - return _builder; + function newFactory(){ + _factory = new Paloma.ControllerClassFactory(); + return _factory; } - describe('#build(controllerAndParent, prototype)', function(){ + describe('#make(controllerAndParent, prototype)', function(){ describe('when controller is not yet existing', function(){ it('creates a new controller', function(){ - var controller = newBuilder().build('MyController'), + var controller = newFactory().make('MyController'), instance = new controller(); expect(instance instanceof Paloma.BaseController).toBeTruthy(); @@ -21,7 +21,7 @@ describe('Paloma.ControllerBuilder', function(){ describe('when prototype is present', function(){ it('adds the prototype to the controller', function(){ - var controller = newBuilder().build('MyController', {a: 100}); + var controller = newFactory().make('MyController', {a: 100}); expect(controller.prototype.a).toEqual(100); }); @@ -29,8 +29,8 @@ describe('Paloma.ControllerBuilder', function(){ describe('when parent is present', function(){ it('creates a subclass of that parent', function(){ - var parent = newBuilder().build('Parent'), - child = builder().build('Child < Parent'); + var parent = newFactory().make('Parent'), + child = factory().make('Child < Parent'); var controller = new child(); expect(controller instanceof parent).toBeTruthy(); @@ -40,13 +40,13 @@ describe('Paloma.ControllerBuilder', function(){ describe('when controller is already existing', function(){ it('returns the existing controller', function(){ - var controller = newBuilder().build('test2'); - expect( builder().build('test2') ).toEqual(controller); + var controller = newFactory().make('test2'); + expect( factory().make('test2') ).toEqual(controller); }); describe('when prototype is present', function(){ - var controller = newBuilder().build('Test', {number: 9}); - builder().build('Test', {number: 10}); + var controller = newFactory().make('Test', {number: 9}); + factory().make('Test', {number: 10}); it('updates the current prototype', function(){ expect(controller.prototype.number).toEqual(10); @@ -54,12 +54,12 @@ describe('Paloma.ControllerBuilder', function(){ }); describe('when parent is present', function(){ - var oldParent = newBuilder().build('OldParent'), - newParent = builder().build('NewParent'); + var oldParent = newFactory().make('OldParent'), + newParent = factory().make('NewParent'); describe('when no previous parent', function(){ - var child = builder().build('ChildA'); - builder().build('ChildA < NewParent'); + var child = factory().make('ChildA'); + factory().make('ChildA < NewParent'); var instance = new child(); @@ -69,8 +69,8 @@ describe('Paloma.ControllerBuilder', function(){ }); describe('when has previous parent', function(){ - var child = builder().build('ChildB < OldParent'); - builder().build('ChildB < NewParent'); + var child = factory().make('ChildB < OldParent'); + factory().make('ChildB < NewParent'); var instance = new child(); @@ -89,14 +89,14 @@ describe('Paloma.ControllerBuilder', function(){ describe('#get(name)', function(){ describe('when name has no match', function(){ it('returns null', function(){ - expect( newBuilder().get('unknown') ).toBeNull(); + expect( newFactory().get('unknown') ).toBeNull(); }); }); describe('when name has match', function(){ it('returns the matched controller', function(){ - var controller = newBuilder().build('myController'); - expect( builder().get('myController') ).toEqual(controller); + var controller = newFactory().make('myController'); + expect( factory().get('myController') ).toEqual(controller); }); }); }); diff --git a/vendor/assets/javascripts/paloma/controller_builder.js b/vendor/assets/javascripts/paloma/controller_builder.js index 0e3802e..346d00b 100644 --- a/vendor/assets/javascripts/paloma/controller_builder.js +++ b/vendor/assets/javascripts/paloma/controller_builder.js @@ -8,7 +8,7 @@ Paloma.ControllerBuilder.prototype = { build: function(options){ this.options = options; - var ControllerClass = this._controllerClass(), + var ControllerClass = this._controllerClass(); if ( !ControllerClass ) return null; return new ControllerClass( this._buildParams() ); From 9cf086df2289783c54dbe3fe32d245d925688f05 Mon Sep 17 00:00:00 2001 From: kbparagua Date: Thu, 24 Mar 2016 23:39:41 +0800 Subject: [PATCH 4/5] Create test for Paloma.ControllerBuilder --- .../javascripts/controller_builder_spec.js | 49 +++++++++++++++++++ .../javascripts/paloma/controller_builder.js | 2 +- 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 test_app/spec/javascripts/controller_builder_spec.js diff --git a/test_app/spec/javascripts/controller_builder_spec.js b/test_app/spec/javascripts/controller_builder_spec.js new file mode 100644 index 0000000..2505e8a --- /dev/null +++ b/test_app/spec/javascripts/controller_builder_spec.js @@ -0,0 +1,49 @@ +describe('Paloma.ControllerBuilder', function(){ + + var TestController = Paloma.controller('Test'); + + + describe('#build(options)', function(){ + + describe('when options.controller has no match', function(){ + var factory = {get: function(controller){ return null; }}, + builder = new Paloma.ControllerBuilder(factory); + + it('returns null', function(){ + var options = {controller: 'Test', action: 'show'}; + expect( builder.build(options) ).toBeNull(); + }); + }); + + describe('when options.controller has a match', function(){ + var factory = {get: function(controller){ return TestController; }}, + builder = new Paloma.ControllerBuilder(factory); + + var options = { + controller: 'Test', + action: 'show', + params: {a: 1, b: 2} + }; + + var controller = builder.build(options); + + it('returns a new instance of the controller class', function(){ + expect(controller instanceof TestController).toBeTruthy(); + }); + + it("initializes controller instance's params", function(){ + var expectedParams = {_controller: 'Test', _action: 'show', a: 1, b: 2}; + var correct = true; + + for (var k in expectedParams){ + if (controller.params[k] != expectedParams[k]) + correct = false; + } + + expect(correct).toBeTruthy(); + }); + }); + + }); + +}); diff --git a/vendor/assets/javascripts/paloma/controller_builder.js b/vendor/assets/javascripts/paloma/controller_builder.js index 346d00b..f46ca93 100644 --- a/vendor/assets/javascripts/paloma/controller_builder.js +++ b/vendor/assets/javascripts/paloma/controller_builder.js @@ -25,7 +25,7 @@ Paloma.ControllerBuilder.prototype = { }; for (var k in this.options.params) - if (this.options.hasOwnProperty(k)) + if (this.options.params.hasOwnProperty(k)) params[k] = this.options.params[k]; return params; From 728e0a621e805f689af0ba765376369b7d89e7be Mon Sep 17 00:00:00 2001 From: kbparagua Date: Thu, 24 Mar 2016 23:49:54 +0800 Subject: [PATCH 5/5] Execute before callbacks even if action method does not exists --- vendor/assets/javascripts/paloma/engine.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/vendor/assets/javascripts/paloma/engine.js b/vendor/assets/javascripts/paloma/engine.js index 16e1559..84f32e3 100644 --- a/vendor/assets/javascripts/paloma/engine.js +++ b/vendor/assets/javascripts/paloma/engine.js @@ -37,13 +37,11 @@ Paloma.Engine.prototype = { var controller = this._buildController(); if (!controller) return; - var action = controller[ this._request.action ]; - if (!action) return; - var callbackPerformer = new Paloma.BeforeCallbackPerformer(controller); callbackPerformer.perform( this._request.action ); - action.call(controller); + var method = controller[ this._request.action ]; + if (method) method.call(controller); this._lastRequest.executed = true; },