diff --git a/shared/app.js b/shared/app.js index 1cd6a1ef..7dd4cb77 100644 --- a/shared/app.js +++ b/shared/app.js @@ -7,10 +7,9 @@ var Backbone = require('backbone'), Fetcher = require('./fetcher'), ModelUtils = require('./modelUtils'), isServer = (typeof window === 'undefined'), - ClientRouter; + defaultRouterModule = 'app/router'; if (!isServer) { - ClientRouter = require('app/router'); Backbone.$ = window.$ || require('jquery'); } @@ -56,8 +55,12 @@ module.exports = Backbone.Model.extend({ * We can't use `this.get('templateAdapter')` here because `Backbone.Model`'s * constructor has not yet been called. */ - var templateAdapterModule = attributes.templateAdapter || this.defaults.templateAdapter; - this.templateAdapter = require(templateAdapterModule)({entryPath: entryPath}); + if (this.options.templateAdapterInstance) { + this.templateAdapter = options.templateAdapterInstance; + } else { + var templateAdapterModule = attributes.templateAdapter || this.defaults.templateAdapter; + this.templateAdapter = require(templateAdapterModule)({entryPath: entryPath}); + } /** * Instantiate the `Fetcher`, which is used on client and server. @@ -70,6 +73,8 @@ module.exports = Backbone.Model.extend({ * Initialize the `ClientRouter` on the client-side. */ if (!isServer) { + var ClientRouter = this.options.ClientRouter || require(defaultRouterModule); + new ClientRouter({ app: this, entryPath: entryPath, diff --git a/test/fixtures/app/template_adapter.js b/test/fixtures/app/template_adapter.js new file mode 100644 index 00000000..0b5e0a00 --- /dev/null +++ b/test/fixtures/app/template_adapter.js @@ -0,0 +1,6 @@ +module.exports = function (options) { + return { + name: 'Test template adapter', + suppliedOptions: options + }; +} diff --git a/test/shared/app.test.js b/test/shared/app.test.js index 4e973838..23527e63 100644 --- a/test/shared/app.test.js +++ b/test/shared/app.test.js @@ -26,4 +26,41 @@ describe('BaseApp', function() { new MyApp(); }); }); + + describe('constructor', function() { + context('with a custom templateAdapter module name', function() { + beforeEach(function () { + this.attributes = {templateAdapter: '../test/fixtures/app/template_adapter'}; + }); + + it('creates the templateAdapter we specify', function() { + var app = new App(this.attributes); + + expect(app.templateAdapter).to.have.property('name', 'Test template adapter'); + }); + + it('supplies the entryPath to the template adapter', function() { + var app = new App(this.attributes, {entryPath: 'myEntryPath'}); + + expect(app.templateAdapter).to.have.deep.property('suppliedOptions.entryPath', 'myEntryPath'); + }); + }); + + context('with a concrete templateAdapterInstance', function() { + it('uses the supplied templateAdapterInstance', function() { + var myTemplateAdapter = {}; + var app = new App(null, {templateAdapterInstance: myTemplateAdapter}); + + expect(app.templateAdapter).to.equal(myTemplateAdapter); + }); + + it('does not try to require a template adapter by name', function () { + new App({ + templateAdapter: 'non existent module name - should throw' + }, { + templateAdapterInstance: {} + }); + }); + }); + }); });