1
0
Fork 0

Provide useful error on attempt to mix in non-trait

Before this change, mixin attempts would fail at the time of mixin when
easejs attempts to invoke the `__mixin` method on the object.  This is both
cryptic and void of any useful information on the stack.
master
Mike Gerwitz 2015-10-25 22:15:34 -04:00
parent d9b86c1544
commit 47d51fd5da
No known key found for this signature in database
GPG Key ID: F22BB8158EE30EAB
2 changed files with 54 additions and 0 deletions

View File

@ -486,9 +486,13 @@ function createImplement( base, ifaces, cname )
* with implicit extend) * with implicit extend)
* *
* @return {Function} staging object for mixin * @return {Function} staging object for mixin
*
* @throws {TypeError} when object is not a trait
*/ */
function createUse( basef, traits, nonbase ) function createUse( basef, traits, nonbase )
{ {
_validateTraits( traits );
// invoking the partially applied class will immediately complete its // invoking the partially applied class will immediately complete its
// definition and instantiate it with the provided constructor arguments // definition and instantiate it with the provided constructor arguments
var partial = function() var partial = function()
@ -575,6 +579,30 @@ function createUse( basef, traits, nonbase )
} }
/**
* Verify that each object in TRAITS will be able to be mixed in
*
* TODO: Use Trait.isTrait; we have circular dependency issues at the moment
* preventing that; refactoring is needed.
*
* @param {Array} traits objects to validate
*
* @return {undefined}
*
* @throws {TypeError} when object is not a trait
*/
function _validateTraits( traits )
{
for ( var t in traits )
{
if ( typeof traits[ t ].__mixin !== 'function' )
{
throw TypeError( "Cannot mix in non-trait " + t );
}
}
}
function createMixedClass( base, traits ) function createMixedClass( base, traits )
{ {
// generated definition for our [abstract] class that will mix in each // generated definition for our [abstract] class that will mix in each

View File

@ -475,4 +475,30 @@ require( 'common' ).testCase(
this.Class.isClass( this.Class( {} ).use( T ) ) this.Class.isClass( this.Class( {} ).use( T ) )
); );
}, },
/**
* Attempts to mix in non-traits should immediately trigger an error
* during the declaration. It is important not to defer this until the
* time of actual mix in---which is lazy---since the stack will not
* provide useful information on how to correct it.
*/
'Throws error when object to mix in is not a trait': function()
{
var _self = this;
// one of one
this.assertThrows( function()
{
// this should error immediately; it should not wait until
// the actual mix in (which is lazy)
_self.Class( {} ).use( {} );
}, TypeError );
// one of many
this.assertThrows( function()
{
_self.Class( {} ).use( _self.Trait( {} ), {} );
}, TypeError );
},
} ); } );