Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Support mixin override of non-function properties

  • Loading branch information...
commit 638964b03e758632024c2f741faa2ab10475d582 1 parent a13d61d
@teleological teleological authored
Showing with 64 additions and 22 deletions.
  1. +5 −5 Cocktail.js
  2. +59 −17 spec/spec/CocktailSpec.js
View
10 Cocktail.js
@@ -28,12 +28,12 @@
});
});
- _(collisions).each(function(methods, methodName) {
- klass.prototype[methodName] = function() {
+ _(collisions).each(function(propertyValues, propertyName) {
+ klass.prototype[propertyName] = function() {
var that = this, args = arguments, returnValue = undefined;
- _(methods).each(function(method) {
- var returnedValue = method.apply(that, args);
+ _(propertyValues).each(function(value) {
+ var returnedValue = _.isFunction(value) ? value.apply(that, args) : value;
returnValue = (returnedValue === undefined ? returnValue : returnedValue);
});
@@ -46,4 +46,4 @@
}
Backbone.Model.extend = Backbone.Collection.extend = Backbone.Router.extend = Backbone.View.extend = extend;
-})();
+})();
View
76 spec/spec/CocktailSpec.js
@@ -36,6 +36,7 @@ describe('Cocktail', function() {
calls.push('fooBarA');
return true;
}
+
}
B = {
@@ -66,6 +67,17 @@ describe('Cocktail', function() {
}
}
+ C = {
+ url: function() {
+ return '/sprockets';
+ }
+ }
+
+ D = {
+ urlRoot: '/thingamajigs',
+ defaults: function() { return null; }
+ }
+
ViewClass = Backbone.View.extend({
mixins: [A, B],
@@ -74,26 +86,38 @@ describe('Cocktail', function() {
},
initialize: function() {
- this.$el.append('<div class="view"></div>');
- },
+ this.$el.append('<div class="view"></div>');
+ },
- clickView: function() {
- calls.push('clickView');
- },
+ clickView: function() {
+ calls.push('clickView');
+ },
- render: function() {
- calls.push('renderView');
- return this;
- },
+ render: function() {
+ calls.push('renderView');
+ return this;
+ },
- beforeTearDown: function() {
- calls.push('beforeTearDownView');
- },
+ beforeTearDown: function() {
+ calls.push('beforeTearDownView');
+ },
+
+ awesomeSauce: function() {
+ calls.push('awesomeView')
+ }
+ }),
+
+ CollectionClass = Backbone.Collection.extend({
+ mixins: [C],
+ url: '/widgets'
+ }),
+
+ ModelClass = Backbone.Model.extend({
+ mixins: [D],
+ urlRoot: function() { return '/gizmos'; },
+ defaults: { foo : 'bar' }
+ });
- awesomeSauce: function() {
- calls.push('awesomeView')
- }
- });
});
describe('mixing in mixins', function() {
@@ -145,6 +169,24 @@ describe('handling method collisions', function() {
});
});
+describe('handling functional override of non-function property', function() {
+ it('should return the last defined value in the collision chain with truthy return value', function() {
+ var collection = new CollectionClass();
+ expect(collection.url()).toEqual('/sprockets');
+ });
+ it('should return the last defined value in the collision chain with null return value', function() {
+ var model = new ModelClass();
+ expect(model.defaults()).toBeNull();
+ });
+});
+
+describe('handling non-functional override of non-events property', function() {
+ it('should ignore the non-functional mixin property', function() {
+ var model = new ModelClass();
+ expect(model.url()).toEqual('/gizmos');
+ });
+});
+
describe('when mixins are applied in the context of super/subclasses', function() {
var BaseClass, SubClass, SubClassWithMixin;
beforeEach(function() {
@@ -203,4 +245,4 @@ describe('when mixins are applied in the context of super/subclasses', function(
expect(calls).toEqual(['clickA', 'clickB', 'BaseClassFoo', 'fooBarA', 'SubClassWithMixinFoo', 'fooBarB']);
});
});
-});
+});
Please sign in to comment.
Something went wrong with that request. Please try again.