Skip to content

Commit

Permalink
Moved test-interface-name into suite as Interface/TestName
Browse files Browse the repository at this point in the history
  • Loading branch information
mikegerwitz committed Jan 21, 2014
1 parent 7b637db commit a3baa99
Show file tree
Hide file tree
Showing 2 changed files with 251 additions and 243 deletions.
251 changes: 251 additions & 0 deletions test/Interface/NameTest.js
@@ -0,0 +1,251 @@
/**
* Tests interface naming
*
* Copyright (C) 2011, 2013 Mike Gerwitz
*
* This file is part of GNU ease.js.
*
* ease.js is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

require( 'common' ).testCase(
{
caseSetUp: function()
{
this.Sut = this.require( 'interface' );
this.util = this.require( 'util' );
},


/**
* Interfaces may be named by passing the name as the first argument to
* the module
*/
'Interface accepts name': function()
{
var _self = this;
this.assertDoesNotThrow( function()
{
var iface = _self.Sut( 'Foo', {} );
_self.assertOk( _self.Sut.isInterface( iface ) );
}, Error );
},


/**
* The interface definition, which equates to the body of the interface,
* must be an object
*/
'Named interface definition requires that definition be an object':
function()
{
var name = 'Foo';

try
{
this.Sut( name, 'Bar' );

// if all goes well, we'll never get to this point
this.assertFail(
"Second argument to named interface must be the definition"
);
}
catch ( e )
{
this.assertNotEqual(
e.message.match( name ),
null,
"Interface definition argument count error string contains " +
"interface name"
);
}
},


/**
* Extraneous arguments likely indicate a misunderstanding of the API
*/
'Named interface definition is strict on argument count': function()
{
var name = 'Foo',
args = [ name, {}, 'extra' ]
;

// we should be permitted only two arguments
try
{
this.Sut.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 )
{
var errstr = e.message;

this.assertNotEqual(
errstr.match( name ),
null,
"Named interface error should provide interface name"
);

this.assertNotEqual(
errstr.match( args.length + ' given' ),
null,
"Named interface error should provide number of given arguments"
);
}
},


/**
* By default, anonymous interfacees should simply state that they are a
* interface when they are converted to a string
*/
'Converting anonymous interface to string yields generic string':
function()
{
this.assertEqual(
this.Sut( {} ).toString(),
'[object Interface]'
);
},


/**
* If the interface is named, then the name should be presented when it
* is converted to a string
*/
'Converting named interface to string yields string containing name':
function()
{
var name = 'Foo';

this.assertEqual(
this.Sut( name, {} ).toString(),
'[object Interface <' + name + '>]'
);
},


/**
* If an interface name is available, then error messages should use it
* to aid the developer in finding its origin.
*/
'Declaration errors provide interface name if avaiable': function()
{
var Sut = this.Sut;

var name = 'Foo',

// functions used to cause the various errors
tries = [
// properties
function()
{
Sut( name, { prop: 'str' } );
},

// methods
function()
{
Sut( name, { method: function() {} } );
},
]
;

// if we have getter/setter support, add those to the tests
if ( !( this.util.definePropertyFallback() ) )
{
// getter
tries.push( function()
{
var obj = {};
Object.defineProperty( obj, 'getter', {
get: function() {},
enumerable: true,
} );

Sut( name, obj );
} );

// setter
tries.push( function()
{
var obj = {};
Object.defineProperty( obj, 'setter', {
set: function() {},
enumerable: true,
} );

Sut( name, obj );
} );
}

// gather the error strings
var i = tries.length;
while ( i-- )
{
try
{
// cause the error
tries[ i ]();
}
catch ( e )
{
// ensure the error string contains the interface name
this.assertNotEqual(
e.message.match( name ),
null,
"Error contains interface name when available (" + i + ")"
);

return;
}

// we shouldn't get to this point...
this.assertFail( "Expected error. Something's wrong: " + i );
}
},


/**
* When attempting to instantiate an interface, the error message should
* contain its name, if available.
*/
'Interface name is included in instantiation error': function()
{
var name = 'Foo';

try
{
// this should throw an exception (cannot instantiate interfaces)
this.Sut( name )();

// we should never get here
this.assertFail( "Exception expected. There's a bug somewhere." );
}
catch ( e )
{
this.assertNotEqual(
e.message.match( name ),
null,
"Interface name is included in instantiation error message"
);
}
},
} );

0 comments on commit a3baa99

Please sign in to comment.