diff --git a/client/router.js b/client/router.js index de0fb647..d8ae9a27 100644 --- a/client/router.js +++ b/client/router.js @@ -122,17 +122,6 @@ ClientRouter.prototype.getHandler = function(action, pattern, route) { } else { if (!action) { throw new Error("Missing action \"" + route.action + "\" for controller \"" + route.controller + "\""); - } else if (typeof action == 'string') { - // in AMD environment action is the string containing path to the controller - // which will be loaded async (might be preloaded) - // Only used in AMD environment - requireAMD([action], function(controller) { - // check we have everything we need - if (typeof controller[route.action] != 'function') { - throw new Error("Missing action \"" + route.action + "\" for controller \"" + route.controller + "\""); - } - actionCall(controller[route.action], params); - }); } else { actionCall(action, params); } diff --git a/shared/base/router.js b/shared/base/router.js index 78c4607a..3b3bdcb4 100644 --- a/shared/base/router.js +++ b/shared/base/router.js @@ -8,6 +8,7 @@ if (!isServer) { Backbone.$ = window.$ || require('jquery'); } + function stringRouteDefinitionToObject(element) { var parts = element.split('#'); return { @@ -150,7 +151,7 @@ _.extend(BaseRouter.prototype, Backbone.Events, { * Adds a single route definition. */ route: function(pattern, controller, options) { - var realAction, action, handler, route, routeObj; + var realAction, action, handler, route, routeObj, self = this; route = parseRouteDefinitions([controller, options]); realAction = this.getAction(route); @@ -166,7 +167,21 @@ _.extend(BaseRouter.prototype, Backbone.Events, { callback.apply(this, arguments); } } - realAction.call(this, params, next); + // in AMD environment realAction is the string containing path to the controller + // which will be loaded async (might be preloaded) + // Only used in AMD environment + if (typeof realAction === 'string') { + self._requireAMD([realAction], function(controller) { + // check we have everything we need + if (typeof controller[route.action] != 'function') { + throw new Error("Missing action \"" + route.action + "\" for controller \"" + route.controller + "\""); + } + controller[route.action].call(this, params, next); + }); + } + else { + realAction.call(this, params, next); + } } } @@ -183,6 +198,11 @@ _.extend(BaseRouter.prototype, Backbone.Events, { return routeObj; }, + /** + * exposing for mocking in test + */ + _requireAMD: require, + /** * Support omitting view path; default it to ":controller/:action". */ diff --git a/test/shared/base/router.test.js b/test/shared/base/router.test.js index 32955fc7..e6efa556 100644 --- a/test/shared/base/router.test.js +++ b/test/shared/base/router.test.js @@ -1,7 +1,11 @@ var BaseRouter = require('../../../shared/base/router'), sinon = require('sinon'), chai = require('chai'), - should = chai.should(); + should = chai.should(), + clientTestHelper = require('../../helpers/client_test'), + basePath = __dirname.split('/'); + + basePath = basePath.splice(0, basePath.length - 3).join('/'); chai.use(require('sinon-chai')); @@ -162,4 +166,71 @@ describe('BaseRouter', function () { }); }); }); + + describe('route client instance', function() { + var router; + + beforeEach(function() { + clientTestHelper.before.call(this); + + // Make sure we are not getting a cached version because it might not hvae the window object + delete require.cache[basePath + '/shared/base/router.js']; + + var BaseRouter = require('../../../shared/base/router'); + router = new BaseRouter({entryPath: 'MyAppRootPath/'}); + }); + + after(clientTestHelper.after); + + describe('route', function() { + var getHandler, handler, getAction, controllerPath; + + beforeEach(function() { + controllerPath = 'controllers/home'; + handler = sinon.spy(); + getHandler = sinon.stub(router, 'getHandler').returns(handler); + + sinon.stub(router, 'getAction').returns(controllerPath); + + }); + + after(function() { + router._requireAMD.restore(); + }); + + it('for AMD version: should trigger an event, pass the correct route object and load the right controller', function() { + BaseRouter.setAMDEnvironment(true); + + var trigger = sinon.stub(router, 'trigger'); + + var callback = sinon.spy(); + + var requireSpy = sinon.spy(); + + var requireAMD = sinon.stub(router, '_requireAMD').returns(requireSpy); + + router.route('/home', 'home#index'); + + var getHandlerCall = getHandler.getCall(0); + + // call action function + getHandlerCall.callArgWith(0, {}, callback); + + // controller file path + requireAMD.getCall(0).args[0][0].should.be.equal('controllers/home'); + + trigger.should.have.been.calledOnce; + trigger.should.have.been.calledWithExactly('route:add', [ + '/home', + { controller: 'home', action: 'index' }, + handler + ]); + + BaseRouter.setAMDEnvironment(false); + }); + + }); + + }); + });