Repository: gcanti/tcomb
Pull request #144 (2015-09-15 15:07:56)

added struct multiple inheritance #143


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b9c53fa..2de8b19 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,11 @@
 **Note**: Gaps between patch versions are faulty/broken releases.
 **Note**: A feature tagged as Experimental is in a high state of flux, you're at risk of it changing without notice.
 
+## v2.4.1
+
+- **New Feature**
+  - added struct multiple inheritance, fix #143
+
 ## v2.4.0
 
 - **New Feature**
diff --git a/index.js b/index.js
index 43fe396..66af09a 100644
--- a/index.js
+++ b/index.js
@@ -362,18 +362,22 @@ function struct(props, name) {
   };
 
   Struct.extend = function (structs, name) {
-    structs = [].concat(structs).map(function (x, i) {
-      if (isObject(x)) {
-        return x;
+    var props = {};
+    var prototype = {};
+    [Struct].concat(structs).forEach(function (struct, i) {
+      if (isObject(struct)) {
+        mixin(props, struct);
       }
-      if (process.env.NODE_ENV !== 'production') {
-        assert(isStruct(x), function () { return 'Invalid argument structs[' + i + '] ' + exports.stringify(structs[i]) + ' supplied to ' + displayName + '.extend(structs, name)'; });
+      else {
+        if (process.env.NODE_ENV !== 'production') {
+          assert(isStruct(struct), function () { return 'Invalid argument structs[' + i + '] ' + exports.stringify(struct) + ' supplied to ' + displayName + '.extend(structs, name)'; });
+        }
+        mixin(props, struct.meta.props);
+        mixin(prototype, struct.prototype);
       }
-      return x.meta.props;
     });
-    structs.unshift(props);
-    var ret = struct(structs.reduce(mixin, {}), name);
-    mixin(ret.prototype, Struct.prototype); // prototypal inheritance
+    var ret = struct(props, name);
+    mixin(ret.prototype, prototype);
     return ret;
   };
 
diff --git a/package.json b/package.json
index 887259a..fc21cd9 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "tcomb",
-  "version": "2.4.0",
+  "version": "2.4.1",
   "description": "Type checking and DDD for JavaScript",
   "main": "index.js",
   "scripts": {


Test patch:
diff --git a/test/struct.js b/test/struct.js
index 1fc4c2b..655beb8 100644
--- a/test/struct.js
+++ b/test/struct.js
@@ -83,10 +83,10 @@ describe('t.struct(props, [name])', function () {
         y: t.Number
       }, 'Point');
       var Point3D = Point.extend({z: t.Number}, 'Point3D');
-      assert.deepEqual(t.getTypeName(Point3D), 'Point3D');
-      assert.deepEqual(Point3D.meta.props.x, t.Number);
-      assert.deepEqual(Point3D.meta.props.y, t.Number);
-      assert.deepEqual(Point3D.meta.props.z, t.Number);
+      assert.deepEqual(Point3D.meta.name, 'Point3D', 'name');
+      assert.deepEqual(Point3D.meta.props.x, t.Number, 'x');
+      assert.deepEqual(Point3D.meta.props.y, t.Number, 'y');
+      assert.deepEqual(Point3D.meta.props.z, t.Number, 'z');
     });
 
     it('should handle an array as argument', function () {
@@ -138,6 +138,21 @@ describe('t.struct(props, [name])', function () {
       assert.deepEqual(c.volume(), 8);
     });
 
+    it('should support multiple prototypal inheritance', function () {
+      var A = t.struct({ a: t.Str }, 'A');
+      A.prototype.amethod = function () {};
+      var B = t.struct({ b: t.Str }, 'B');
+      B.prototype.bmethod = function () {};
+      var C = t.struct({ c: t.Str }, 'C');
+      C.prototype.cmethod = function () {};
+      var Z = C.extend([A, B], 'Z');
+      var z = new Z({ a: 'a', b: 'b', c: 'c' });
+      assert.strictEqual(Z.meta.name, 'Z');
+      assert.strictEqual(t.Function.is(z.cmethod), true);
+      assert.strictEqual(t.Function.is(z.bmethod), true);
+      assert.strictEqual(t.Function.is(z.amethod), true);
+    });
+
   });
 
 });