Interfaces now have sane/useful values when converted to strings
parent
ec7b4e2b6b
commit
009c4a93e9
|
@ -35,19 +35,20 @@ var util = require( './util' ),
|
||||||
* extended. To extend an existing interface, call its extend() method, or use
|
* extended. To extend an existing interface, call its extend() method, or use
|
||||||
* the extend() method of this module.
|
* the extend() method of this module.
|
||||||
*
|
*
|
||||||
|
* @param {string=} name optional name
|
||||||
* @param {Object} def interface definition
|
* @param {Object} def interface definition
|
||||||
*
|
*
|
||||||
* @return {Interface} new interface
|
* @return {Interface} new interface
|
||||||
*/
|
*/
|
||||||
module.exports = function( def )
|
module.exports = function()
|
||||||
{
|
{
|
||||||
// if the first argument is an object, then we are declaring an interface
|
var def = {},
|
||||||
if ( typeof def !== 'object' )
|
name = '';
|
||||||
|
|
||||||
|
// anonymous interface
|
||||||
|
if ( typeof arguments[ 0 ] === 'object' )
|
||||||
{
|
{
|
||||||
throw TypeError(
|
def = arguments[ 0 ];
|
||||||
"Must provide interface definition when declaring interface"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure we have the proper number of arguments (if they passed in too
|
// ensure we have the proper number of arguments (if they passed in too
|
||||||
// many, it may signify that they don't know what they're doing, and likely
|
// many, it may signify that they don't know what they're doing, and likely
|
||||||
|
@ -59,6 +60,23 @@ module.exports = function( def )
|
||||||
arguments.length + " given."
|
arguments.length + " given."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// named class
|
||||||
|
else if ( typeof arguments[ 0 ] === 'string' )
|
||||||
|
{
|
||||||
|
name = arguments[ 0 ];
|
||||||
|
def = arguments[ 1 ];
|
||||||
|
|
||||||
|
// add the name to the definition
|
||||||
|
def.__name = name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we don't know what to do!
|
||||||
|
throw TypeError(
|
||||||
|
"Expecting anonymous interface definition or named interface definition"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return extend( def );
|
return extend( def );
|
||||||
};
|
};
|
||||||
|
@ -114,12 +132,20 @@ var extend = ( function( extending )
|
||||||
props = args.pop() || {},
|
props = args.pop() || {},
|
||||||
base = args.pop() || Interface,
|
base = args.pop() || Interface,
|
||||||
prototype = new base(),
|
prototype = new base(),
|
||||||
|
iname = '',
|
||||||
|
|
||||||
members = member_builder.initMembers(
|
members = member_builder.initMembers(
|
||||||
prototype, prototype, prototype
|
prototype, prototype, prototype
|
||||||
)
|
)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
// grab the name, if one was provided
|
||||||
|
if ( iname = props.__name )
|
||||||
|
{
|
||||||
|
// we no longer need it
|
||||||
|
delete props.__name;
|
||||||
|
}
|
||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
inheritCheck( prototype );
|
inheritCheck( prototype );
|
||||||
|
|
||||||
|
@ -165,6 +191,8 @@ var extend = ( function( extending )
|
||||||
} );
|
} );
|
||||||
|
|
||||||
attachExtend( new_interface );
|
attachExtend( new_interface );
|
||||||
|
attachStringMethod( new_interface, iname );
|
||||||
|
|
||||||
new_interface.prototype = prototype;
|
new_interface.prototype = prototype;
|
||||||
new_interface.constructor = new_interface;
|
new_interface.constructor = new_interface;
|
||||||
|
|
||||||
|
@ -258,3 +286,20 @@ function attachExtend( func )
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides more sane/useful output when interface is converted to a string
|
||||||
|
*
|
||||||
|
* @param {Object} func interface
|
||||||
|
* @param {string=} iname interface name
|
||||||
|
*
|
||||||
|
* @return {undefined}
|
||||||
|
*/
|
||||||
|
function attachStringMethod( func, iname )
|
||||||
|
{
|
||||||
|
func.toString = ( iname )
|
||||||
|
? function() { return '[object Interface <' + iname + '>]'; }
|
||||||
|
: function() { return '[object Interface]'; }
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
/**
|
||||||
|
* Tests interface naming
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Mike Gerwitz
|
||||||
|
*
|
||||||
|
* This file is part of ease.js.
|
||||||
|
*
|
||||||
|
* ease.js is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free
|
||||||
|
* Software Foundation, either version 3 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @author Mike Gerwitz
|
||||||
|
* @package test
|
||||||
|
*/
|
||||||
|
|
||||||
|
var common = require( './common' ),
|
||||||
|
assert = require( 'assert' ),
|
||||||
|
Interface = common.require( 'interface' )
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interfaces may be named by passing the name as the first argument to the
|
||||||
|
* module
|
||||||
|
*/
|
||||||
|
( function testInterfaceAcceptsName()
|
||||||
|
{
|
||||||
|
assert.doesNotThrow( function()
|
||||||
|
{
|
||||||
|
var iface = Interface( 'Foo', {} );
|
||||||
|
|
||||||
|
assert.equal(
|
||||||
|
Interface.isInterface( iface ),
|
||||||
|
true,
|
||||||
|
"Interface defined with name is returned as a valid interface"
|
||||||
|
);
|
||||||
|
}, Error, "Interface accepts name" );
|
||||||
|
|
||||||
|
// the second argument must be an object
|
||||||
|
assert.throws( function()
|
||||||
|
{
|
||||||
|
Interface( 'Foo', 'Bar' );
|
||||||
|
}, TypeError, "Second argument to named interface must be the definition" );
|
||||||
|
} )();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default, anonymous interfacees should simply state that they are a
|
||||||
|
* interface when they are converted to a string
|
||||||
|
*/
|
||||||
|
( function testConvertingAnonymousInterfaceToStringYieldsInterfaceString()
|
||||||
|
{
|
||||||
|
assert.equal(
|
||||||
|
Interface( {} ).toString(),
|
||||||
|
'[object Interface]',
|
||||||
|
"Converting anonymous interface to string yields interface string"
|
||||||
|
);
|
||||||
|
} )();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the interface is named, then the name should be presented when it is
|
||||||
|
* converted to a string
|
||||||
|
*/
|
||||||
|
( function testConvertingNamedInterfaceToStringYieldsInterfaceStringContainingName()
|
||||||
|
{
|
||||||
|
var name = 'Foo';
|
||||||
|
|
||||||
|
assert.equal(
|
||||||
|
Interface( name, {} ).toString(),
|
||||||
|
'[object Interface <' + name + '>]',
|
||||||
|
"Converting named interface to string yields string with name of " +
|
||||||
|
"interface"
|
||||||
|
);
|
||||||
|
} )();
|
||||||
|
|
Loading…
Reference in New Issue