From e05a65d5faaa56231ad272c53fa8d22db0d72a51 Mon Sep 17 00:00:00 2001 From: Mike Gerwitz Date: Mon, 7 Mar 2011 00:14:43 -0500 Subject: [PATCH] Initial concept of inheriting protected/private members --- lib/class.js | 10 +++++- test/test-class-visibility.js | 60 +++++++++++++++++++++++++++++++++-- 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/lib/class.js b/lib/class.js index 9a86c13..cfae254 100644 --- a/lib/class.js +++ b/lib/class.js @@ -794,9 +794,17 @@ function attachPropInit( prototype, properties, members ) this, class_instance[ this.__iid ], properties[ 'public' ] ); + // use whatever was returned by the property proxy (which may not be a + // proxy, depending on JS engine support) class_instance[ this.__iid ] = inst_props; - propobj.setup( inst_props, properties, members ); + // if we're inheriting, perform a setup that doesn't include everything + // that we don't want (e.g. private properties) + var setup = ( inherit ) + ? propobj.setupInherited + : propobj.setup + ; + setup( inst_props, properties, members ); }); } diff --git a/test/test-class-visibility.js b/test/test-class-visibility.js index bf28361..c535a75 100644 --- a/test/test-class-visibility.js +++ b/test/test-class-visibility.js @@ -36,7 +36,7 @@ var common = require( './common' ), privf = function() { return priv; }, // new anonymous class instance - foo = Class.extend( { + Foo = Class.extend( { 'public pub': pub, 'protected peeps': prot, 'private parts': priv, @@ -60,7 +60,14 @@ var common = require( './common' ), { this[ name ] = value; }, - })(); + }), + + // instance of Foo + foo = Foo(), + + // subtype + sub_foo = Foo.extend( {} )() +; /** @@ -220,3 +227,52 @@ var common = require( './common' ), ); } )(); + +/** + * Inheritance 101; protected members should be available to subtypes + */ +( function testProtectedMembersAreInheritedFromParent() +{ + assert.equal( + sub_foo.getProp( 'peeps' ), + prot, + "Protected properties are available to subtypes" + ); + + // invoke rather than checking for equality, because the method may be + // wrapped + assert.equal( + sub_foo.getProp( 'protf' )(), + prot, + "Protected methods are available to subtypes" + ); +} )(); + + +/** + * Interface 101-2: We do not want private members to be available to subtypes. + */ +( function testPrivateMembersOfSupertypesAreInaccessibleToSubtypes() +{ + // browsers that do not support the property proxy will not support + // encapsulating properties + if ( !( propobj.supportsPropProxy() ) ) + { + return; + } + + assert.equal( + sub_foo.getProp( 'parts' ), + undefined, + "Private properties of supertypes should be unavailable to subtypes" + ); + + // invoke rather than checking for equality, because the method may be + // wrapped + assert.equal( + sub_foo.getProp( 'privf' ), + undefined, + "Private methods of supertypes should be unavailable to subtypes" + ); +} )(); +