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
parent
2136ebedd5
commit
e9cf630d0b
|
@ -107,11 +107,19 @@ function markAbstract( args )
|
||||||
*
|
*
|
||||||
* @param {Object} obj object to override
|
* @param {Object} obj object to override
|
||||||
*
|
*
|
||||||
* @return {undefined}
|
* @return {Object} obj
|
||||||
*/
|
*/
|
||||||
function abstractOverride( 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
|
// wrap extend, applying the abstract flag
|
||||||
obj.extend = function()
|
obj.extend = function()
|
||||||
|
@ -119,5 +127,7 @@ function abstractOverride( obj )
|
||||||
markAbstract( arguments );
|
markAbstract( arguments );
|
||||||
return extend.apply( this, arguments );
|
return extend.apply( this, arguments );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,8 @@ var common = require( './common' ),
|
||||||
util = common.require( 'util' ),
|
util = common.require( 'util' ),
|
||||||
|
|
||||||
Class = common.require( 'class' ),
|
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()' );
|
||||||
|
} )()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue