Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Support mixin override of non-function properties

  • Loading branch information...
commit 638964b03e758632024c2f741faa2ab10475d582 1 parent a13d61d
Riley Martinez-Lynch authored September 21, 2012
10  Cocktail.js
@@ -28,12 +28,12 @@
28 28
         });
29 29
       });
30 30
 
31  
-      _(collisions).each(function(methods, methodName) {
32  
-        klass.prototype[methodName] = function() {
  31
+      _(collisions).each(function(propertyValues, propertyName) {
  32
+        klass.prototype[propertyName] = function() {
33 33
           var that = this, args = arguments, returnValue = undefined;
34 34
 
35  
-          _(methods).each(function(method) {
36  
-            var returnedValue = method.apply(that, args);
  35
+          _(propertyValues).each(function(value) {
  36
+            var returnedValue = _.isFunction(value) ? value.apply(that, args) : value;
37 37
             returnValue = (returnedValue === undefined ? returnValue : returnedValue);
38 38
           });
39 39
 
@@ -46,4 +46,4 @@
46 46
   }
47 47
 
48 48
   Backbone.Model.extend = Backbone.Collection.extend = Backbone.Router.extend = Backbone.View.extend = extend;
49  
-})();
  49
+})();
76  spec/spec/CocktailSpec.js
@@ -36,6 +36,7 @@ describe('Cocktail', function() {
36 36
         calls.push('fooBarA');
37 37
         return true;
38 38
       }
  39
+
39 40
     }
40 41
 
41 42
     B = {
@@ -66,6 +67,17 @@ describe('Cocktail', function() {
66 67
       }
67 68
     }
68 69
 
  70
+    C = {
  71
+      url: function() {
  72
+        return '/sprockets';
  73
+      }
  74
+    }
  75
+
  76
+    D = {
  77
+      urlRoot: '/thingamajigs',
  78
+      defaults: function() { return null; }
  79
+    }
  80
+
69 81
     ViewClass = Backbone.View.extend({
70 82
       mixins: [A, B],
71 83
       
@@ -74,26 +86,38 @@ describe('Cocktail', function() {
74 86
       },
75 87
       
76 88
       initialize: function() {
77  
-       this.$el.append('<div class="view"></div>');
78  
-     },
  89
+        this.$el.append('<div class="view"></div>');
  90
+      },
79 91
 
80  
-     clickView: function() {
81  
-      calls.push('clickView');
82  
-    },
  92
+      clickView: function() {
  93
+        calls.push('clickView');
  94
+      },
83 95
 
84  
-    render: function() {
85  
-      calls.push('renderView');
86  
-      return this;
87  
-    },
  96
+      render: function() {
  97
+        calls.push('renderView');
  98
+        return this;
  99
+      },
88 100
 
89  
-    beforeTearDown: function() {
90  
-      calls.push('beforeTearDownView');
91  
-    },
  101
+      beforeTearDown: function() {
  102
+        calls.push('beforeTearDownView');
  103
+      },
  104
+
  105
+      awesomeSauce: function() {
  106
+        calls.push('awesomeView')
  107
+      }
  108
+    }),
  109
+
  110
+    CollectionClass = Backbone.Collection.extend({
  111
+      mixins: [C],
  112
+      url: '/widgets'
  113
+    }),
  114
+
  115
+    ModelClass = Backbone.Model.extend({
  116
+      mixins: [D],
  117
+      urlRoot: function() { return '/gizmos'; },
  118
+      defaults: { foo : 'bar' }
  119
+    });
92 120
 
93  
-    awesomeSauce: function() {
94  
-      calls.push('awesomeView')
95  
-    }
96  
-  });
97 121
   });
98 122
 
99 123
 describe('mixing in mixins', function() {
@@ -145,6 +169,24 @@ describe('handling method collisions', function() {
145 169
   });
146 170
 });
147 171
 
  172
+describe('handling functional override of non-function property', function() {
  173
+  it('should return the last defined value in the collision chain with truthy return value', function() {
  174
+    var collection = new CollectionClass();
  175
+    expect(collection.url()).toEqual('/sprockets');
  176
+  });
  177
+  it('should return the last defined value in the collision chain with null return value', function() {
  178
+    var model = new ModelClass();
  179
+    expect(model.defaults()).toBeNull();
  180
+  });
  181
+});
  182
+
  183
+describe('handling non-functional override of non-events property', function() {
  184
+  it('should ignore the non-functional mixin property', function() {
  185
+    var model = new ModelClass();
  186
+    expect(model.url()).toEqual('/gizmos');
  187
+  });
  188
+});
  189
+
148 190
 describe('when mixins are applied in the context of super/subclasses', function() {
149 191
   var BaseClass, SubClass, SubClassWithMixin;
150 192
   beforeEach(function() {
@@ -203,4 +245,4 @@ describe('when mixins are applied in the context of super/subclasses', function(
203 245
     expect(calls).toEqual(['clickA', 'clickB', 'BaseClassFoo', 'fooBarA', 'SubClassWithMixinFoo', 'fooBarB']);
204 246
   });
205 247
 });
206  
-});
  248
+});

0 notes on commit 638964b

Please sign in to comment.
Something went wrong with that request. Please try again.