Skip to content

Commit

Permalink
Merge pull request #477 from rendrjs/pass-spec-to-lazy
Browse files Browse the repository at this point in the history
allow someone to pass the *entire* fetch spec.
  • Loading branch information
saponifi3d committed May 15, 2015
2 parents cde62bd + ce3cb27 commit 64e0790
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 38 deletions.
13 changes: 11 additions & 2 deletions shared/base/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ module.exports = BaseView = Backbone.View.extend({

if (this.options.fetch_params) {
if (!_.isObject(this.options.fetch_params)) {
throw new Error('fetch_params must be an object for lazy loaded views')
throw new Error('fetch_params must be an object for lazy loaded views');
}

params = this.options.fetch_params;
Expand All @@ -241,7 +241,7 @@ module.exports = BaseView = Backbone.View.extend({

if (this.options.fetch_options) {
if (!_.isObject(this.options.fetch_options)) {
throw new Error('fetch_options must be an object for lazy loaded views')
throw new Error('fetch_options must be an object for lazy loaded views');
}

fetchOptions = this.options.fetch_options;
Expand All @@ -267,6 +267,15 @@ module.exports = BaseView = Backbone.View.extend({
};
}

// Allow ability to just pass the full "spec" to a lazy loaded view
if (this.options.fetch_spec) {
if (!_.isObject(this.options.fetch_spec)) {
throw new Error('fetch_spec must be an object for lazy loaded views');
}

fetchSpec = this.options.fetch_spec;
}

this.setLoading(true);

this._preRender();
Expand Down
88 changes: 52 additions & 36 deletions test/shared/base/view.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,36 +239,61 @@ describe('BaseView', function() {
});

describe('fetchLazy', function () {
var fetchParams = { model: 'Foo' },
fetchOptions = { readFromCache: false },
modelName = 'MyModel',
MyView,
view,
fetchSpec;

beforeEach(function () {
fetchSpec = {
model: {
model: modelName,
params: fetchParams
}
this.app = {
fetch: sinon.spy(),
modelUtils: modelUtils
};

MyView = BaseView.extend({ name: 'A View Name' });
myView = new MyView({
'app': { fetch: sinon.stub() },
'model_name': modelName,
'fetch_params': fetchParams,
'fetch_options': fetchOptions
this.view = new this.MyTopView({ app: this.app });
sinon.stub(this.view, 'setLoading');
});

context('passed a fetch_spec', function () {
var fetchSpec;

beforeEach(function () {
fetchSpec = {
model: {
model: 'Test',
params: { id: 1 }
}
};

this.view.options.fetch_spec = fetchSpec;
});

myView.setLoading = sinon.stub();
myView._preRender = sinon.stub();
myView.fetchLazy();
it('overrides the fetchSpec and calls fetch with it.', function () {
this.view.fetchLazy();
expect(this.app.fetch).to.have.been.calledWith(fetchSpec);
});
});

it('passes the fetchSpec and fetch_options to the fetch call', function () {
expect(myView.app.fetch).to.have.been.calledWith(fetchSpec, fetchOptions, sinon.match.func);
context('passed fetch options', function () {
var fetchParams, fetchOptions;

beforeEach(function () {
fetchParams = { id: 1 };
fetchOptions = {
readFromCache: false,
writeToCache: true
};

this.view.options.model_name = 'MyModel';
this.view.options.fetch_params = fetchParams;
this.view.options.fetch_options = fetchOptions;
})

it('invokes app.fetch with the fetchOptions', function () {
this.view.fetchLazy();

expect(this.app.fetch).to.have.been.calledWith({
model: {
model: 'MyModel',
params: fetchParams
}
}, fetchOptions);
});
});
});

Expand Down Expand Up @@ -643,7 +668,7 @@ describe('BaseView', function() {
topView.childViews.push(bottomView);
childViews = topView.getChildViewsByName('my_bottom_view');
childViews.should.have.length(1);
bottomView.remove()
bottomView.remove();
childViews = topView.getChildViewsByName('my_bottom_view');
childViews.should.be.empty;
});
Expand All @@ -656,49 +681,40 @@ describe('BaseView', function() {
topView.$el = $('<div>');
topView.childViews = [];

expect(topView.remove.bind(topView)).to.not.throw(Error)
expect(topView.remove.bind(topView)).to.not.throw(Error);
});

});

describe('createChildView', function() {

var ViewClass, parentView, cb, attachNewChildView;

beforeEach(function() {

ViewClass = BaseView.extend({});
parentView = 'parentView';
cb = sinon.spy();
sinon.stub(BaseView, 'attachNewChildView').returns('view');

sinon.stub(BaseView, 'attachNewChildView').returns('view');
});

afterEach(function() {

BaseView.attachNewChildView.restore();
cb = null;

});

it('should call callback with null and view arguments if the view is not yet attached', function() {

var $el = $('<div>');

BaseView.createChildView(ViewClass, {app: this.app}, $el, parentView, cb);
cb.should.have.been.calledWithExactly(null, 'view');

});

it('should call callback with null and null arguments if the view is already attached', function() {

var $el = $('<div data-view-attached="true"></div>');

BaseView.createChildView(ViewClass, {app: this.app}, $el, parentView, cb);
cb.should.have.been.calledWithExactly(null, null);

});

});

describe('attachNewChildView', function() {
Expand All @@ -716,8 +732,8 @@ describe('BaseView', function() {
});

it('should create a new instance of ViewClass', function() {

var newChildView = BaseView.attachNewChildView(ViewClass, {app: this.app}, 'foo', 'bar');

expect(newChildView).to.be.an.instanceOf(ViewClass);
});
});
Expand Down

0 comments on commit 64e0790

Please sign in to comment.