Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added getter and setter inheritance + tests

  • Loading branch information...
commit 243f056d01a360fac7a5968e8ba1a1966575fb9d 1 parent 2fc196d
Robert Massa authored
Showing with 64 additions and 16 deletions.
  1. +33 −15 classy.js
  2. +15 −0 tests/core.js
  3. +16 −1 tests/data.js
48 classy.js
View
@@ -1,7 +1,7 @@
/**
* Classy - classy classes for JavaScript
*
- * :copyright: (c) 2010 by Armin Ronacher.
+ * :copyright: (c) 2010 by Armin Ronacher.
* :license: BSD.
*/
@@ -44,6 +44,26 @@
return rv;
}
+ /* wraps a function adding a $super variable */
+ function wrapForSuper(super_prototype, meth, name, type) {
+ return function() {
+ var old_super = getOwnProperty(this, '$super');
+ if (type === 'getter')
+ this.$super = super_prototype.__lookupGetter__(name);
+ else if (type === 'setter')
+ this.$super = super_prototype.__lookupSetter__(name);
+ else
+ this.$super = super_prototype[name];
+
+ try {
+ return meth.apply(this, arguments);
+ }
+ finally {
+ setOrUnset(this, '$super', old_super);
+ }
+ };
+ }
+
/* the base class we export */
var Class = function() {};
@@ -83,7 +103,7 @@
prototype[name] = mixin[name];
}
}
-
+
/* copy class vars from the superclass */
properties.__classvars__ = properties.__classvars__ || {};
if (prototype.__classvars__)
@@ -95,24 +115,22 @@
/* copy all properties over to the new prototype */
for (var name in properties) {
+ var getter = properties.__lookupGetter__(name),
+ setter = properties.__lookupSetter__(name);
+ if (getter || setter) {
+ if (getter)
+ prototype.__defineGetter__(name, usesSuper(getter) ? wrapForSuper(super_prototype, getter, name, 'getter') : getter);
+ if (setter)
+ prototype.__defineSetter__(name, usesSuper(setter) ? wrapForSuper(super_prototype, setter, name, 'setter') : setter);
+ continue;
+ }
+
var value = getOwnProperty(properties, name);
if (name === '__include__' ||
value === undefined)
continue;
- prototype[name] = typeof value === 'function' && usesSuper(value) ?
- (function(meth, name) {
- return function() {
- var old_super = getOwnProperty(this, '$super');
- this.$super = super_prototype[name];
- try {
- return meth.apply(this, arguments);
- }
- finally {
- setOrUnset(this, '$super', old_super);
- }
- };
- })(value, name) : value
+ prototype[name] = typeof value === 'function' && usesSuper(value) ? wrapForSuper(super_prototype, value, name) : value
}
/* dummy constructor */
15 tests/core.js
View
@@ -79,6 +79,21 @@ test('basic classical inheritence works', function() {
'base HouseCat is not affected by subclass mutations');
});
+test('inheritance of getters and setters works', function() {
+ cat = Cat();
+ parasite = Parasite();
+ lion = Lion();
+
+ equal(cat.furryness, 20,
+ 'getter was inherted from base')
+
+ equal(parasite.furryness, 0,
+ 'getters can override base')
+
+ equal(lion.furryness, 40,
+ 'getters can use $super to get base getter')
+});
+
test('instanceof works', function() {
var lion = Lion();
ok(lion instanceof Lion,
17 tests/data.js
View
@@ -7,6 +7,7 @@ var Animal = Class.$extend({
// required defaults
this.name = (typeof(options.name) == 'string' ? options.name : 'Animal');
this.health = (typeof(options.health) == 'integer' ? options.health : 100);
+ this._furryness = (typeof(options.furryness) == 'integer' ? options.furryness : 20);
},
die: function() {
@@ -19,6 +20,14 @@ var Animal = Class.$extend({
dead: function() {
return (this.health <= 0);
+ },
+
+ get furryness() {
+ return this._furryness;
+ },
+
+ set furryness(val) {
+ this._furryness = val;
}
});
@@ -26,6 +35,9 @@ var Parasite = Animal.$extend({
eat: function(animal) {
this.$super(animal);
animal.health -= 5;
+ },
+ get furryness() {
+ return 0;
}
});
@@ -43,5 +55,8 @@ var HouseCat = Cat.$extend({
var Lion = Cat.$extend({
'cute': false,
- 'scary': true
+ 'scary': true,
+ get furryness() {
+ return this.$super() * 2;
+ }
});
Please sign in to comment.
Something went wrong with that request. Please try again.