1
0
Fork 0

AbstractClass.implement().extend() will now properly preserve abstract flag on resulting class

- This is a bug fix. The resulting class was not declared abstract, which is a problem if the resulting class chose not to provide a concrete implementation for each of the abstract members.
perfodd
Mike Gerwitz 2011-12-20 20:06:38 -05:00
parent 2136ebedd5
commit e9cf630d0b
2 changed files with 33 additions and 3 deletions

View File

@ -107,11 +107,19 @@ function markAbstract( args )
*
* @param {Object} obj object to override
*
* @return {undefined}
* @return {Object} obj
*/
function abstractOverride( obj )
{
var extend = obj.extend;
var extend = obj.extend,
impl = obj.implement;
// wrap and apply the abstract flag, only if the method is defined (it may
// not be under all circumstances, e.g. after an implement())
impl && ( obj.implement = function()
{
return abstractOverride( impl.apply( this, arguments ) );
} );
// wrap extend, applying the abstract flag
obj.extend = function()
@ -119,5 +127,7 @@ function abstractOverride( obj )
markAbstract( arguments );
return extend.apply( this, arguments );
};
return obj;
}

View File

@ -26,7 +26,8 @@ var common = require( './common' ),
util = common.require( 'util' ),
Class = common.require( 'class' ),
AbstractClass = common.require( 'class_abstract' )
AbstractClass = common.require( 'class_abstract' ),
Interface = common.require( 'interface' )
;
@ -451,3 +452,22 @@ var ConcreteFoo = Class.extend( AbstractFoo,
);
} )();
/**
* Extending an abstract class after an implement() should still result in an
* abstract class. Essentially, we are testing to ensure that the extend()
* method is properly wrapped to flag the resulting class as abstract. This was
* a bug.
*/
( function testImplementingInterfacesWillPreserveAbstractClassDeclaration()
{
assert.doesNotThrow( function()
{
// if not considered abstract, extend() will fail, as it will contain
// abstract member foo
AbstractClass( 'TestImplExtend' )
.implement( Interface( { foo: [] } ) )
.extend( {} );
}, Error, 'Class should still be abstract after implement().extend()' );
} )()