From c90fb6eb81f1e8d7c6a87fa7ed9be8636aa5836d Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Sun, 10 May 2015 01:49:23 -0400 Subject: [PATCH] Trait.extend error on nonsense bases --- lib/Trait.js | 10 +++++++- test/Trait/ClassExtendTest.js | 47 +++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/lib/Trait.js b/lib/Trait.js index 260a9d2..cae1a31 100644 --- a/lib/Trait.js +++ b/lib/Trait.js @@ -20,6 +20,7 @@ */ var AbstractClass = require( './class_abstract' ), + Class = require( './class' ), ClassBuilder = require( './ClassBuilder' ), Interface = require( './interface' ); @@ -110,9 +111,11 @@ Trait.extend = function() throw Error( "Trait.extend expects no more than two arguments" ); } + var has_extend = ( an > 1 ); + // this verbose syntax ensures that `arguments' isn't passed around var dfn = ( ( an > 0 ) ? a[ an - 1 ] : 0 ) || {}, - extend = ( ( an > 1 ) ? a[ an - 2 ] : 0 ) || null; + extend = ( ( has_extend ) ? a[ an - 2 ] : 0 ) || null; // store any provided name, since we'll be clobbering it (the definition // object will be used to define the hidden abstract class) @@ -120,6 +123,11 @@ Trait.extend = function() type = _getTraitType( dfn ), isparam = ( type === 'param' ); + if ( has_extend && !Class.isClass( extend ) ) + { + throw TypeError( "Trait " + name + " cannot extend non-class" ); + } + // augment the parser to handle our own oddities dfn.___$$parser$$ = { each: _parseMember, diff --git a/test/Trait/ClassExtendTest.js b/test/Trait/ClassExtendTest.js index 58b8480..7c4e327 100644 --- a/test/Trait/ClassExtendTest.js +++ b/test/Trait/ClassExtendTest.js @@ -25,6 +25,18 @@ require( 'common' ).testCase( { this.Sut = this.require( 'Trait' ); this.Class = this.require( 'class' ); + + // nonsensical extend bases + this.nonsense = [ + '', + null, + undefined, + false, + NaN, + Infinity, + {}, + [], + ]; }, @@ -212,4 +224,39 @@ require( 'common' ).testCase( _self.Sut.extend( _self.Class( {} ), {}, {} ); } ); }, + + + /** + * Help out the programmer by letting her know when she provides an + * invalid base, which would surely not give her the result that she + * expects. + */ + '@each(nonsense) Traits cannot extend nonsense': function( base ) + { + var _self = this; + + this.assertThrows( function() + { + _self.Sut.extend( base, {} ); + } ); + }, + + + /** + * Eventually, traits will be able to extend other traits just as they + * can classes---by asserting and operating on the type. This is just a + * generalization that needs to be properly tested and allowed, and + * should not function any differently than a class. + * + * Don't worry; it'll happen in the future. + */ + 'Traits cannot yet extend other traits': function() + { + var _self = this; + + this.assertThrows( function() + { + _self.Sut.extend( _self.Sut( {} ), {} ); + }, TypeError ); + }, } );