From bc8ec4e0be598f9ff28db8cc44d10f814642439a Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Mon, 28 Mar 2011 19:17:38 -0400 Subject: [PATCH] Added tests for forced-public methods --- lib/class_builder.js | 29 +++++++-- .../test-class_builder-member-restrictions.js | 65 +++++++++++++++++++ 2 files changed, 89 insertions(+), 5 deletions(-) diff --git a/lib/class_builder.js b/lib/class_builder.js index 8b44eba..127ad2a 100644 --- a/lib/class_builder.js +++ b/lib/class_builder.js @@ -56,18 +56,23 @@ var util = require( __dirname + '/util' ), * Hash of reserved members * * These methods cannot be defined in the class. They are for internal use - * only. + * only. We must check both properties and methods to ensure that neither is + * defined. * * @type {Object.} */ reserved_members = { '__initProps': true }, /** - * Hash of members that must be public + * Hash of methods that must be public + * + * Notice that this is a list of /methods/, not members, because this check + * is performed only for methods. This is for performance reasons. We do not + * have a situation where we will want to check for properties as well. * * @type {Object.} reserved members + * @return {Object.} reserved members */ exports.getReservedMembers = function() { @@ -112,6 +117,20 @@ exports.getReservedMembers = function() }; +/** + * Returns a hash of the forced-public methods + * + * The returned object is a copy of the original. It cannot be used to modify + * the internal list of reserved members. + * + * @return {Object.} forced-public methods + */ +exports.getForcedPublicMethods = function() +{ + return util.clone( public_methods, true ); +}; + + /** * Mimics class inheritance * @@ -411,7 +430,7 @@ function buildMembers( method: function( name, func, is_abstract, keywords ) { // constructor check - if ( public_members[ name ] === true ) + if ( public_methods[ name ] === true ) { if ( keywords[ 'protected' ] || keywords[ 'private' ] ) { diff --git a/test/test-class_builder-member-restrictions.js b/test/test-class_builder-member-restrictions.js index 38f2ccb..8004d06 100644 --- a/test/test-class_builder-member-restrictions.js +++ b/test/test-class_builder-member-restrictions.js @@ -119,3 +119,68 @@ var common = require( './common' ), ); } )(); + +/** + * We want these available for the same reason that we want the restricted + * members available (see above) + */ +( function testCanRetrieveListOfForcedPublicMethods() +{ + var pub = builder.getForcedPublicMethods(), + count = 0; + + assert.ok( pub instanceof Object, + "Can retrieve hash of forced-public methods" + ); + + for ( name in pub ) + { + count++; + } + + // ensure we weren't provided an empty object + assert.notEqual( count, 0, + "Forced-public method list is not empty" + ); +} )(); + + +/** + * See above. Same reason that we don't want reserved members to be modified. + */ +( function testCannotModifyInternalForcedPublicMethodsList() +{ + var val = 'foo'; + + // attempt to add to list + builder.getForcedPublicMethods().foo = val; + + assert.notEqual( + builder.getForcedPublicMethods().foo, + val, + "Cannot alter internal list of forced-public methods" + ); +} )(); + + +/** + * Ensure that an exception will be thrown for each forced-public method that is + * not declared as public in the class definition. + */ +( function testAllForcedPublicMethodsAreForcedToPublic() +{ + var pub = builder.getForcedPublicMethods(); + + // test each of the reserved members + for ( name in pub ) + { + assert.throws( function() + { + var obj = {}; + obj[ name ] = function() {}; + + Class( obj ); + }, Error, "Forced-public methods must be declared as public" ); + } +} )(); +