From f3cb815baa03f7775524d0dac083a884fbc42016 Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Wed, 4 Jun 2014 00:37:08 -0400 Subject: [PATCH] Sibling traits will each have __mixin called distinctly --- lib/Trait.js | 17 ++++++++++++++--- test/Trait/ParameterTest.js | 26 ++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/lib/Trait.js b/lib/Trait.js index 41ee82f..233feb8 100644 --- a/lib/Trait.js +++ b/lib/Trait.js @@ -617,6 +617,14 @@ function mixMethods( src, dest, vis, iname ) continue; } + // TODO: generalize + // __mixin is exclusive to the trait (private-ish, but can be + // invoked publically internally) + if ( f === '__mixin' ) + { + continue; + } + // TODO: this is a kluge; we'll use proper reflection eventually, // but for now, this is how we determine if this is an actual method // vs. something that just happens to be on the visibility object @@ -778,10 +786,13 @@ function tctor( tc, base, privsym ) // visibility object to gain access to its protected members...quite // the intimate relationship this[ f ] = C( base, this[ privsym ].vis )[ privsym ].vis; - } - // this has been previously validated to ensure that it is a function - this.__mixin && this.__mixin.apply( this, T.___$$mixinargs ); + // this has been previously validated to ensure that it is a + // function + this[ f ].__mixin && this[ f ].__mixin.apply( + this[ f ], T.___$$mixinargs + ); + } // if we are a subtype, be sure to initialize our parent's traits this.__super && this.__super( privsym ); diff --git a/test/Trait/ParameterTest.js b/test/Trait/ParameterTest.js index 4de7ce0..31730f5 100644 --- a/test/Trait/ParameterTest.js +++ b/test/Trait/ParameterTest.js @@ -259,5 +259,31 @@ require( 'common' ).testCase( this.assertEqual( n, 3 ); }, + + + /** + * Sibling traits are an interesting case---rather than stacking, they + * are mixed in alongside each other, meaning that there may be + * multiple traits that define __mixin. Ordinarily, this is a problem; + * however, __mixin shall be treated as if it were private and shall be + * invoked once per trait, giving each a chance to initialize. + * + * Furthermore, each should retain access to their own configuration. + */ + 'Invokes __mixin of each sibling mixin': function() + { + var args = [], + vals = [ {}, [] ], + c = function() { args.push( arguments ) }; + + var Ta = this.createParamTrait( c ), + Tb = this.createParamTrait( c ); + + this.Class( {} ).use( Ta( vals[0] ), Tb( vals[1] ) )(); + + this.assertEqual( args.length, 2 ); + this.assertStrictEqual( args[0][0], vals[0] ); + this.assertStrictEqual( args[1][0], vals[1] ); + } } );