2011-03-04 00:19:02 -05:00
|
|
|
/**
|
|
|
|
* 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" );
|
2011-03-05 12:57:21 -05:00
|
|
|
} )();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The interface definition, which equates to the body of the interface, must be
|
|
|
|
* an object
|
|
|
|
*/
|
|
|
|
( function testNamedInterfaceDefinitionRequiresThatDefinitionBeAnObject()
|
|
|
|
{
|
|
|
|
var name = 'Foo';
|
2011-03-04 00:19:02 -05:00
|
|
|
|
2011-03-05 12:57:21 -05:00
|
|
|
try
|
2011-03-04 00:19:02 -05:00
|
|
|
{
|
2011-03-05 12:57:21 -05:00
|
|
|
Interface( name, 'Bar' );
|
|
|
|
|
|
|
|
// if all goes well, we'll never get to this point
|
|
|
|
assert.fail(
|
|
|
|
"Second argument to named interface must be the definition"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
catch ( e )
|
|
|
|
{
|
|
|
|
assert.notEqual(
|
2011-03-06 10:37:20 -05:00
|
|
|
e.message.match( name ),
|
2011-03-05 12:57:21 -05:00
|
|
|
null,
|
|
|
|
"Interface definition argument count error string contains " +
|
|
|
|
"interface name"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
} )();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Extraneous arguments likely indicate a misunderstanding of the API
|
|
|
|
*/
|
|
|
|
( function testNamedInterfaceDefinitionIsStrictOnArgumentCount()
|
|
|
|
{
|
|
|
|
var name = 'Foo',
|
|
|
|
args = [ name, {}, 'extra' ]
|
|
|
|
;
|
2011-03-04 23:43:30 -05:00
|
|
|
|
|
|
|
// we should be permitted only two arguments
|
|
|
|
try
|
|
|
|
{
|
|
|
|
Interface.apply( null, args );
|
|
|
|
|
|
|
|
// we should not get to this line (an exception should be thrown due to
|
|
|
|
// too many arguments)
|
|
|
|
assert.fail(
|
|
|
|
"Should accept only two arguments when creating named interface"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
catch ( e )
|
|
|
|
{
|
2011-03-06 10:37:20 -05:00
|
|
|
var errstr = e.message;
|
2011-03-05 12:57:21 -05:00
|
|
|
|
|
|
|
assert.notEqual(
|
|
|
|
errstr.match( name ),
|
|
|
|
null,
|
|
|
|
"Named interface error should provide interface name"
|
|
|
|
);
|
|
|
|
|
2011-03-04 23:43:30 -05:00
|
|
|
assert.notEqual(
|
2011-03-05 12:57:21 -05:00
|
|
|
errstr.match( args.length + ' given' ),
|
2011-03-04 23:43:30 -05:00
|
|
|
null,
|
|
|
|
"Named interface error should provide number of given arguments"
|
|
|
|
);
|
|
|
|
}
|
2011-03-04 00:19:02 -05:00
|
|
|
} )();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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"
|
|
|
|
);
|
|
|
|
} )();
|
|
|
|
|
2011-03-05 17:27:02 -05:00
|
|
|
|
|
|
|
( function testDeclarationErrorsProvideInterfaceNameIsAvailable()
|
|
|
|
{
|
|
|
|
var name = 'Foo',
|
|
|
|
|
|
|
|
// functions used to cause the various errors
|
|
|
|
tries = [
|
|
|
|
// properties
|
|
|
|
function()
|
|
|
|
{
|
|
|
|
Interface( name, { prop: 'str' } );
|
|
|
|
},
|
|
|
|
|
|
|
|
// methods
|
|
|
|
function()
|
|
|
|
{
|
|
|
|
Interface( name, { method: function() {} } );
|
|
|
|
},
|
|
|
|
]
|
|
|
|
;
|
|
|
|
|
|
|
|
// if we have getter/setter support, add those to the tests
|
|
|
|
if ( Object.defineProperty )
|
|
|
|
{
|
|
|
|
// getter
|
|
|
|
tries.push( function()
|
|
|
|
{
|
|
|
|
var obj = {};
|
|
|
|
Object.defineProperty( obj, 'getter', {
|
|
|
|
get: function() {},
|
|
|
|
enumerable: true,
|
|
|
|
} );
|
|
|
|
|
|
|
|
Interface( name, obj );
|
|
|
|
} );
|
|
|
|
|
|
|
|
// setter
|
|
|
|
tries.push( function()
|
|
|
|
{
|
|
|
|
var obj = {};
|
|
|
|
Object.defineProperty( obj, 'setter', {
|
|
|
|
set: function() {},
|
|
|
|
enumerable: true,
|
|
|
|
} );
|
|
|
|
|
|
|
|
Interface( name, obj );
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
|
|
|
// gather the error strings
|
|
|
|
var i = tries.length;
|
|
|
|
while ( i-- )
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// cause the error
|
|
|
|
tries[ i ]();
|
|
|
|
|
|
|
|
// we shouldn't get to this point...
|
|
|
|
assert.fail( "Expected error. Something's wrong." );
|
|
|
|
}
|
|
|
|
catch ( e )
|
|
|
|
{
|
|
|
|
// ensure the error string contains the interface name
|
|
|
|
assert.notEqual(
|
2011-03-06 10:37:20 -05:00
|
|
|
e.message.match( name ),
|
2011-03-05 17:27:02 -05:00
|
|
|
null,
|
|
|
|
"Error contains interface name when available (" + i + ")"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} )();
|
|
|
|
|
2011-03-05 21:46:44 -05:00
|
|
|
|
|
|
|
( function testInterfaceNameIsIncludedInInstantiationError()
|
|
|
|
{
|
|
|
|
var name = 'Foo';
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// this should throw an exception (cannot instantiate interfaces)
|
|
|
|
Interface( name )();
|
|
|
|
|
|
|
|
// we should never get here
|
|
|
|
assert.fail( "Exception expected. There's a bug somewhere." );
|
|
|
|
}
|
|
|
|
catch ( e )
|
|
|
|
{
|
|
|
|
assert.notEqual(
|
2011-03-06 10:37:20 -05:00
|
|
|
e.message.match( name ),
|
2011-03-05 21:46:44 -05:00
|
|
|
null,
|
|
|
|
"Interface name is included in instantiation error message"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
} )();
|
|
|
|
|