Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Added getter and setter inheritance + tests

  • Loading branch information...
commit 243f056d01a360fac7a5968e8ba1a1966575fb9d 1 parent 2fc196d
Robert Massa authored October 31, 2010
48  classy.js
... ...
@@ -1,7 +1,7 @@
1 1
 /**
2 2
  * Classy - classy classes for JavaScript
3 3
  *
4  
- * :copyright: (c) 2010 by Armin Ronacher. 
  4
+ * :copyright: (c) 2010 by Armin Ronacher.
5 5
  * :license: BSD.
6 6
  */
7 7
 
@@ -44,6 +44,26 @@
44 44
     return rv;
45 45
   }
46 46
 
  47
+  /* wraps a function adding a $super variable */
  48
+  function wrapForSuper(super_prototype, meth, name, type) {
  49
+    return function() {
  50
+      var old_super = getOwnProperty(this, '$super');
  51
+      if (type === 'getter')
  52
+        this.$super = super_prototype.__lookupGetter__(name);
  53
+      else if (type === 'setter')
  54
+        this.$super = super_prototype.__lookupSetter__(name);
  55
+      else
  56
+        this.$super = super_prototype[name];
  57
+
  58
+      try {
  59
+        return meth.apply(this, arguments);
  60
+      }
  61
+      finally {
  62
+        setOrUnset(this, '$super', old_super);
  63
+      }
  64
+    };
  65
+  }
  66
+
47 67
   /* the base class we export */
48 68
   var Class = function() {};
49 69
 
@@ -83,7 +103,7 @@
83 103
             prototype[name] = mixin[name];
84 104
         }
85 105
       }
86  
- 
  106
+
87 107
     /* copy class vars from the superclass */
88 108
     properties.__classvars__ = properties.__classvars__ || {};
89 109
     if (prototype.__classvars__)
@@ -95,24 +115,22 @@
95 115
 
96 116
     /* copy all properties over to the new prototype */
97 117
     for (var name in properties) {
  118
+      var getter = properties.__lookupGetter__(name),
  119
+          setter = properties.__lookupSetter__(name);
  120
+      if (getter || setter) {
  121
+        if (getter)
  122
+          prototype.__defineGetter__(name, usesSuper(getter) ? wrapForSuper(super_prototype, getter, name, 'getter') : getter);
  123
+        if (setter)
  124
+          prototype.__defineSetter__(name, usesSuper(setter) ? wrapForSuper(super_prototype, setter, name, 'setter') : setter);
  125
+        continue;
  126
+      }
  127
+
98 128
       var value = getOwnProperty(properties, name);
99 129
       if (name === '__include__' ||
100 130
           value === undefined)
101 131
         continue;
102 132
 
103  
-      prototype[name] = typeof value === 'function' && usesSuper(value) ?
104  
-        (function(meth, name) {
105  
-          return function() {
106  
-            var old_super = getOwnProperty(this, '$super');
107  
-            this.$super = super_prototype[name];
108  
-            try {
109  
-              return meth.apply(this, arguments);
110  
-            }
111  
-            finally {
112  
-              setOrUnset(this, '$super', old_super);
113  
-            }
114  
-          };
115  
-        })(value, name) : value
  133
+      prototype[name] = typeof value === 'function' && usesSuper(value) ? wrapForSuper(super_prototype, value, name) : value
116 134
     }
117 135
 
118 136
     /* dummy constructor */
15  tests/core.js
@@ -79,6 +79,21 @@ test('basic classical inheritence works', function() {
79 79
     'base HouseCat is not affected by subclass mutations');
80 80
 });
81 81
 
  82
+test('inheritance of getters and setters works', function() {
  83
+  cat = Cat();
  84
+  parasite = Parasite();
  85
+  lion = Lion();
  86
+
  87
+  equal(cat.furryness, 20,
  88
+    'getter was inherted from base')
  89
+
  90
+  equal(parasite.furryness, 0,
  91
+    'getters can override base')
  92
+
  93
+  equal(lion.furryness, 40,
  94
+    'getters can use $super to get base getter')
  95
+});
  96
+
82 97
 test('instanceof works', function() {
83 98
   var lion = Lion();
84 99
   ok(lion instanceof Lion,
17  tests/data.js
@@ -7,6 +7,7 @@ var Animal = Class.$extend({
7 7
     // required defaults
8 8
     this.name = (typeof(options.name) == 'string' ? options.name : 'Animal');
9 9
     this.health = (typeof(options.health) == 'integer' ? options.health : 100);
  10
+    this._furryness = (typeof(options.furryness) == 'integer' ? options.furryness : 20);
10 11
   },
11 12
 
12 13
   die: function() {
@@ -19,6 +20,14 @@ var Animal = Class.$extend({
19 20
 
20 21
   dead: function() {
21 22
     return (this.health <= 0);
  23
+  },
  24
+
  25
+  get furryness() {
  26
+    return this._furryness;
  27
+  },
  28
+
  29
+  set furryness(val) {
  30
+    this._furryness = val;
22 31
   }
23 32
 });
24 33
 
@@ -26,6 +35,9 @@ var Parasite = Animal.$extend({
26 35
   eat: function(animal) {
27 36
     this.$super(animal);
28 37
     animal.health -= 5;
  38
+  },
  39
+  get furryness() {
  40
+    return 0;
29 41
   }
30 42
 });
31 43
 
@@ -43,5 +55,8 @@ var HouseCat = Cat.$extend({
43 55
 
44 56
 var Lion = Cat.$extend({
45 57
   'cute': false,
46  
-  'scary': true
  58
+  'scary': true,
  59
+  get furryness() {
  60
+    return this.$super() * 2;
  61
+  }
47 62
 });

0 notes on commit 243f056

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