diff --git a/lib/class.js b/lib/class.js index 8c51910..ff740cf 100644 --- a/lib/class.js +++ b/lib/class.js @@ -326,7 +326,7 @@ function createStaging( cname ) // implement on empty base, providing the class name to be used once // extended return createImplement( - extend( {} ), + null, Array.prototype.slice.call( arguments ), cname ); @@ -343,7 +343,7 @@ function createStaging( cname ) * called, as it does not make sense to create a class without any * body/definition. * - * @param {Object} base base class to implement atop of + * @param {Object} base base class to implement atop of, or null * @param {Array} ifaces interfaces to implement * @param {string=} cname optional class name once extended * @@ -351,19 +351,27 @@ function createStaging( cname ) */ function createImplement( base, ifaces, cname ) { - ifaces.push( base ); - // Defer processing until after extend(). This also ensures that implement() // returns nothing usable. return { - extend: function( def ) + extend: function() { + var args = Array.prototype.slice.call( arguments ), + def = args.pop(), + ext_base = args.pop() + ; + // if a name was provided, use it if ( cname ) { def.__name = cname; } + // If a base was provided when createImplement() was called, use + // that. Otherwise, use the extend() base passed to this function. + // If neither of those are available, extend from an empty class. + ifaces.push( base || ext_base || extend( {} ) ); + return extend.apply( null, [ implement.apply( this, ifaces ), def diff --git a/test/test-class-name.js b/test/test-class-name.js index fbb40c3..a700c3a 100644 --- a/test/test-class-name.js +++ b/test/test-class-name.js @@ -201,6 +201,9 @@ var common = require( './common' ), var name = 'Foo', named = Class( name ).extend( {} ) namedi = Class( name ).implement( Interface( {} ) ).extend( {} ) + + // we should also be able to extend classes in this manner + namede = Class( name ).implement( Interface( {} ) ).extend( named, {} ) ; // ensure what was returned is a valid class @@ -232,6 +235,29 @@ var common = require( './common' ), name, "Name is set on named class via staging method when implementing" ); + + + // we should be able to extend existing classes + assert.equal( + Class.isClass( namede ), + true, + "Named class generated via staging method, implementing an " + + "interface, and extending an existing class is considered " + + "to be a valid class" + ); + + assert.equal( + Class.isInstanceOf( named, namede() ), + true, + "Named class extending base class is instance of the base class" + ); + + assert.equal( + namede.toString(), + name, + "Name is set on named class via staging method when implementing " + + "and extending" + ); } )();