[#25] Began refactoring test-class_builder-static into new test case system
parent
79d0c4a62c
commit
3912f2d369
|
@ -246,7 +246,10 @@ exports.prototype.validateGetterSetter = function(
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
var prev = ( prev_data ) ? prev_data.member : null,
|
var prev = ( prev_data ) ? prev_data.member : null,
|
||||||
prev_gs = ( ( prev_data.get || prev_data.set ) ? true : false )
|
prev_gs = ( ( prev_data && (prev_data.get || prev_data.set ) )
|
||||||
|
? true
|
||||||
|
: false
|
||||||
|
)
|
||||||
;
|
;
|
||||||
|
|
||||||
if ( prev || prev_gs )
|
if ( prev || prev_gs )
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var common = require( './common' ),
|
var common = require( './common' ),
|
||||||
assert = require( 'assert' ),
|
|
||||||
fallback = common.require( 'util' ).definePropertyFallback()
|
fallback = common.require( 'util' ).definePropertyFallback()
|
||||||
|
|
||||||
// XXX: get rid of this disgusting mess; we're mid-refactor and all these
|
// XXX: get rid of this disgusting mess; we're mid-refactor and all these
|
||||||
|
@ -42,12 +41,14 @@ var common = require( './common' ),
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
/**
|
require( 'common' ).testCase(
|
||||||
* To provide access to static members, this.__self is made available inside of
|
|
||||||
* instances.
|
|
||||||
*/
|
|
||||||
( function testSelfPropertyReferencesClassDefinition()
|
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* To provide access to static members, this.__self is made available inside
|
||||||
|
* of instances.
|
||||||
|
*/
|
||||||
|
'Self property references class definition': function()
|
||||||
|
{
|
||||||
var val = [ 'baz' ],
|
var val = [ 'baz' ],
|
||||||
Foo = builder.build(
|
Foo = builder.build(
|
||||||
{
|
{
|
||||||
|
@ -59,38 +60,38 @@ var common = require( './common' ),
|
||||||
|
|
||||||
Foo.bar = val;
|
Foo.bar = val;
|
||||||
|
|
||||||
// we must use instanceof here because the __self object has the class in
|
// we must use instanceof here because the __self object has the class
|
||||||
// its prototype chain
|
// in its prototype chain
|
||||||
assert.ok( ( Foo().test().bar === Foo.bar ),
|
this.assertOk( ( Foo().test().bar === Foo.bar ),
|
||||||
"__self property references class definition"
|
"__self property references class definition"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If a static property does not exist, the getter should return undefined.
|
* If a static property does not exist, the getter should return undefined.
|
||||||
*
|
*
|
||||||
* This test exists to ensure an error is not thrown if the property is not
|
* This test exists to ensure an error is not thrown if the property is not
|
||||||
* found. This is because we check each parent and eventually reach the base
|
* found. This is because we check each parent and eventually reach the base
|
||||||
* object. We must ensure the base object does not cause any problems.
|
* object. We must ensure the base object does not cause any problems.
|
||||||
*/
|
*/
|
||||||
( function testStaticPropertyLookupReturnsUndefinedIfNotFound()
|
'Static property lookup returns undefined if not found': function()
|
||||||
{
|
{
|
||||||
var result = builder.build( {} ).$( 'foo' );
|
var result = builder.build( {} ).$( 'foo' );
|
||||||
|
|
||||||
assert.equal( result, undefined,
|
this.assertEqual( result, undefined,
|
||||||
"Static property getter should return undefined if not found"
|
"Static property getter should return undefined if not found"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If supported by the environment, ensure that the accessor method used to
|
* If supported by the environment, ensure that the accessor method used to
|
||||||
* access static properties is not enumerable. It's unnecessary clutter (and
|
* access static properties is not enumerable. It's unnecessary clutter (and
|
||||||
* confusion) otherwise.
|
* confusion) otherwise.
|
||||||
*/
|
*/
|
||||||
( function testStaticPropertyAccessorIsNotEnumerable()
|
'Static property accessor is not enumerable': function()
|
||||||
{
|
{
|
||||||
var get = Object.getOwnPropertyDescriptor,
|
var get = Object.getOwnPropertyDescriptor,
|
||||||
Foo = builder.build( {} );
|
Foo = builder.build( {} );
|
||||||
|
|
||||||
|
@ -100,20 +101,20 @@ var common = require( './common' ),
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.equal( get( Foo, '$' ).enumerable, false,
|
this.assertEqual( get( Foo, '$' ).enumerable, false,
|
||||||
"Static property accessor method should not be enumerable"
|
"Static property accessor method should not be enumerable"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static members, by their nature, should be accessible through the class
|
* Static members, by their nature, should be accessible through the class
|
||||||
* definition itself; that is, without instantiation. It should also not be
|
* definition itself; that is, without instantiation. It should also not be
|
||||||
* available through the generated prototype (and therefore, be unavailable to
|
* available through the generated prototype (and therefore, be unavailable
|
||||||
* instances).
|
* to instances).
|
||||||
*/
|
*/
|
||||||
( function testPublicStaticMembersAreAccessibleViaClassDefinitionOnly()
|
'Public static members are accessible via class definition only': function()
|
||||||
{
|
{
|
||||||
var val = 'foo',
|
var val = 'foo',
|
||||||
val2 = 'bar',
|
val2 = 'bar',
|
||||||
Foo = builder.build(
|
Foo = builder.build(
|
||||||
|
@ -136,39 +137,39 @@ var common = require( './common' ),
|
||||||
} );
|
} );
|
||||||
|
|
||||||
// properties should be accessible via class definition
|
// properties should be accessible via class definition
|
||||||
assert.equal( Foo.$('foo'), val,
|
this.assertEqual( Foo.$('foo'), val,
|
||||||
"Public static properties should be accessible via class definition"
|
"Public static properties should be accessible via class definition"
|
||||||
);
|
);
|
||||||
|
|
||||||
// as long as the above test succeeded, we can then conclude that static
|
// as long as the above test succeeded, we can then conclude that static
|
||||||
// members are public by default if the following succeeds
|
// members are public by default if the following succeeds
|
||||||
assert.equal( Foo.$('bar'), val2,
|
this.assertEqual( Foo.$('bar'), val2,
|
||||||
"Static properties are public by default"
|
"Static properties are public by default"
|
||||||
);
|
);
|
||||||
|
|
||||||
// methods should be accessible via class definition
|
// methods should be accessible via class definition
|
||||||
assert.equal( Foo.baz(), val,
|
this.assertEqual( Foo.baz(), val,
|
||||||
"Public static methods should be accessible via class definition"
|
"Public static methods should be accessible via class definition"
|
||||||
);
|
);
|
||||||
|
|
||||||
// same rules as above, but with a method
|
// same rules as above, but with a method
|
||||||
assert.equal( Foo.foobar(), val2,
|
this.assertEqual( Foo.foobar(), val2,
|
||||||
"Static methods are public by default"
|
"Static methods are public by default"
|
||||||
);
|
);
|
||||||
|
|
||||||
// getter/setter method should not be a part of the prototype
|
// getter/setter method should not be a part of the prototype
|
||||||
assert.equal( Foo.prototype.$, undefined,
|
this.assertEqual( Foo.prototype.$, undefined,
|
||||||
"Public static properties are *not* part of the prototype"
|
"Public static properties are *not* part of the prototype"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as above, but with getters/setters. We can only run this test if
|
* Same as above, but with getters/setters. We can only run this test if
|
||||||
* getters/setters are supported by the engine running it.
|
* getters/setters are supported by the engine running it.
|
||||||
*/
|
*/
|
||||||
( function testPublicStaticGettersSettersAreAccessibleViaClassDefinitionOnly()
|
'Public static getters/setter accessible via class dfn only': function()
|
||||||
{
|
{
|
||||||
// if unsupported, don't bother with the test
|
// if unsupported, don't bother with the test
|
||||||
if ( fallback )
|
if ( fallback )
|
||||||
{
|
{
|
||||||
|
@ -199,45 +200,45 @@ var common = require( './common' ),
|
||||||
// define the class
|
// define the class
|
||||||
var Foo = builder.build( def );
|
var Foo = builder.build( def );
|
||||||
|
|
||||||
assert.equal( Foo.foo, val,
|
this.assertEqual( Foo.foo, val,
|
||||||
"Public static getters are accessible via class definition"
|
"Public static getters are accessible via class definition"
|
||||||
);
|
);
|
||||||
|
|
||||||
Foo.foo = 'moo';
|
Foo.foo = 'moo';
|
||||||
assert.equal( called[ 0 ], true,
|
this.assertEqual( called[ 0 ], true,
|
||||||
"Public static setters are accessible via class definition"
|
"Public static setters are accessible via class definition"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( Foo.bar, val,
|
this.assertEqual( Foo.bar, val,
|
||||||
"Static getters are public by default"
|
"Static getters are public by default"
|
||||||
);
|
);
|
||||||
|
|
||||||
Foo.bar = 'moo';
|
Foo.bar = 'moo';
|
||||||
assert.equal( called[ 1 ], true,
|
this.assertEqual( called[ 1 ], true,
|
||||||
"Static setters are public by default"
|
"Static setters are public by default"
|
||||||
);
|
);
|
||||||
|
|
||||||
// none of these should be available on the prototype
|
// none of these should be available on the prototype
|
||||||
assert.equal( Foo.prototype.foo, undefined,
|
this.assertEqual( Foo.prototype.foo, undefined,
|
||||||
"Public static getters/getters are unavailable on prototype (0)"
|
"Public static getters/getters are unavailable on prototype (0)"
|
||||||
);
|
);
|
||||||
assert.equal( Foo.prototype.bar, undefined,
|
this.assertEqual( Foo.prototype.bar, undefined,
|
||||||
"Public static getters/getters are unavailable on prototype (1)"
|
"Public static getters/getters are unavailable on prototype (1)"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* With non-static methods, 'this' is bound to the instance. In the case of
|
* With non-static methods, 'this' is bound to the instance. In the case of
|
||||||
* static members, we should bind to the class definition (equivalent of
|
* static members, we should bind to the class definition (equivalent of
|
||||||
* this.__self).
|
* this.__self).
|
||||||
*
|
*
|
||||||
* This functionality had already existed previously. When a propobj is not
|
* This functionality had already existed previously. When a propobj is not
|
||||||
* available for an instance, it falls back. This serves as a regression test to
|
* available for an instance, it falls back. This serves as a regression
|
||||||
* ensure this functionality remains.
|
* test to ensure this functionality remains.
|
||||||
*/
|
*/
|
||||||
( function testStaticMethodsNotBoundToInstance()
|
'Static methods not bound to instance': function()
|
||||||
{
|
{
|
||||||
var result = null,
|
var result = null,
|
||||||
Foo = builder.build(
|
Foo = builder.build(
|
||||||
{
|
{
|
||||||
|
@ -252,19 +253,19 @@ var common = require( './common' ),
|
||||||
|
|
||||||
// note that the objects themselves aren't the same, due to the property
|
// note that the objects themselves aren't the same, due to the property
|
||||||
// object
|
// object
|
||||||
assert.equal( result.foo, Foo.foo,
|
this.assertEqual( result.foo, Foo.foo,
|
||||||
"Static members are bound to class definition rather than instance"
|
"Static members are bound to class definition rather than instance"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We don't have the benefit of static members being part of the prototype
|
* We don't have the benefit of static members being part of the prototype
|
||||||
* chain. Inheritance is not automatic. This test deals only with ensuring that
|
* chain. Inheritance is not automatic. This test deals only with ensuring
|
||||||
* *public* static members are inherited by subtypes.
|
* that *public* static members are inherited by subtypes.
|
||||||
*/
|
*/
|
||||||
( function testPublicStaticMembersAreInheritedBySubtypes()
|
'Public static members are inherited by subtypes': function()
|
||||||
{
|
{
|
||||||
var def = {
|
var def = {
|
||||||
'public static foo': 'val',
|
'public static foo': 'val',
|
||||||
'public static func': function() {},
|
'public static func': function() {},
|
||||||
|
@ -289,31 +290,32 @@ var common = require( './common' ),
|
||||||
// extends from the parent and adds an additional
|
// extends from the parent and adds an additional
|
||||||
SubFoo = builder.build( Foo, { 'public static baz': baz } ),
|
SubFoo = builder.build( Foo, { 'public static baz': baz } ),
|
||||||
|
|
||||||
// simply extends from the parent (also serves as a check to ensure that
|
// simply extends from the parent (also serves as a check to ensure
|
||||||
// static members of *all* parents are inherited, not just the
|
// that static members of *all* parents are inherited, not just the
|
||||||
// immediate)
|
// immediate)
|
||||||
SubSubFoo = builder.build( SubFoo, {} )
|
SubSubFoo = builder.build( SubFoo, {} )
|
||||||
;
|
;
|
||||||
|
|
||||||
// properties
|
// properties
|
||||||
assert.equal( SubFoo.$('foo'), Foo.$('foo'),
|
this.assertEqual( SubFoo.$('foo'), Foo.$('foo'),
|
||||||
"Public static properties are inherited by subtypes"
|
"Public static properties are inherited by subtypes"
|
||||||
);
|
);
|
||||||
assert.equal( SubSubFoo.$('foo'), Foo.$('foo'),
|
this.assertEqual( SubSubFoo.$('foo'), Foo.$('foo'),
|
||||||
"Public static properties are inherited by sub-subtypes"
|
"Public static properties are inherited by sub-subtypes"
|
||||||
);
|
);
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
assert.deepEqual( SubFoo.func, Foo.func,
|
this.assertDeepEqual( SubFoo.func, Foo.func,
|
||||||
"Public static methods are inherited by subtypes"
|
"Public static methods are inherited by subtypes"
|
||||||
);
|
);
|
||||||
assert.deepEqual( SubSubFoo.func, Foo.func,
|
this.assertDeepEqual( SubSubFoo.func, Foo.func,
|
||||||
"Public static methods are inherited by sub-subtypes"
|
"Public static methods are inherited by sub-subtypes"
|
||||||
);
|
);
|
||||||
|
|
||||||
// merge
|
// merge
|
||||||
assert.equal( SubFoo.$('baz'), baz,
|
this.assertEqual( SubFoo.$('baz'), baz,
|
||||||
"Subtypes contain both inherited static members as well as their own"
|
"Subtypes contain both inherited static members as well as their " +
|
||||||
|
"own"
|
||||||
);
|
);
|
||||||
|
|
||||||
// getters/setters (if supported by engine)
|
// getters/setters (if supported by engine)
|
||||||
|
@ -321,35 +323,38 @@ var common = require( './common' ),
|
||||||
{
|
{
|
||||||
var super_data = Object.getOwnPropertyDescriptor( Foo, 'bar' ),
|
var super_data = Object.getOwnPropertyDescriptor( Foo, 'bar' ),
|
||||||
sub_data = Object.getOwnPropertyDescriptor( SubFoo, 'bar' ),
|
sub_data = Object.getOwnPropertyDescriptor( SubFoo, 'bar' ),
|
||||||
sub_sub_data = Object.getOwnPropertyDescriptor( SubSubFoo, 'bar' )
|
sub_sub_data = Object.getOwnPropertyDescriptor(
|
||||||
|
SubSubFoo, 'bar'
|
||||||
|
)
|
||||||
;
|
;
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
assert.deepEqual( super_data.get, sub_data.get,
|
this.assertDeepEqual( super_data.get, sub_data.get,
|
||||||
"Public static getters are inherited by subtypes"
|
"Public static getters are inherited by subtypes"
|
||||||
);
|
);
|
||||||
assert.deepEqual( super_data.get, sub_sub_data.get,
|
this.assertDeepEqual( super_data.get, sub_sub_data.get,
|
||||||
"Public static getters are inherited by sub-subtypes"
|
"Public static getters are inherited by sub-subtypes"
|
||||||
);
|
);
|
||||||
|
|
||||||
// setters
|
// setters
|
||||||
assert.deepEqual( super_data.set, sub_data.set,
|
this.assertDeepEqual( super_data.set, sub_data.set,
|
||||||
"Public static setters are inherited by subtypes"
|
"Public static setters are inherited by subtypes"
|
||||||
);
|
);
|
||||||
assert.deepEqual( super_data.set, sub_sub_data.set,
|
this.assertDeepEqual( super_data.set, sub_sub_data.set,
|
||||||
"Public static setters are inherited by sub-subtypes"
|
"Public static setters are inherited by sub-subtypes"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static references should be inherited by subtypes. That is, modifying a
|
* Static references should be inherited by subtypes. That is, modifying a
|
||||||
* static property of a supertype should modify the same static property of the
|
* static property of a supertype should modify the same static property of
|
||||||
* subtype, so long as the subtype has not defined a property of the same name.
|
* the subtype, so long as the subtype has not defined a property of the
|
||||||
|
* same name.
|
||||||
*/
|
*/
|
||||||
( function testPublicStaticPropertyReferencesAreInheritedBySubtypes()
|
'Public static property references are inherited by subtypes': function()
|
||||||
{
|
{
|
||||||
var val = [ 1, 2, 3 ],
|
var val = [ 1, 2, 3 ],
|
||||||
val2 = [ 'a', 'b', 'c' ],
|
val2 = [ 'a', 'b', 'c' ],
|
||||||
|
|
||||||
|
@ -361,42 +366,42 @@ var common = require( './common' ),
|
||||||
;
|
;
|
||||||
|
|
||||||
// the properties should reference the same object
|
// the properties should reference the same object
|
||||||
assert.ok( SubFoo.$('bar') === Foo.$('bar'),
|
this.assertOk( SubFoo.$('bar') === Foo.$('bar'),
|
||||||
"Inherited static properties should share references"
|
"Inherited static properties should share references"
|
||||||
);
|
);
|
||||||
|
|
||||||
// setting a property on Foo should set the property on SubFoo and
|
// setting a property on Foo should set the property on SubFoo and
|
||||||
// vice-versa
|
// vice-versa
|
||||||
Foo.$( 'bar', val2 );
|
Foo.$( 'bar', val2 );
|
||||||
assert.deepEqual( Foo.$( 'bar' ), val2,
|
this.assertDeepEqual( Foo.$( 'bar' ), val2,
|
||||||
"Can set static property values"
|
"Can set static property values"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.ok( Foo.$( 'bar' ) === SubFoo.$( 'bar' ),
|
this.assertOk( Foo.$( 'bar' ) === SubFoo.$( 'bar' ),
|
||||||
"Setting a static property value on a supertype also sets the value " +
|
"Setting a static property value on a supertype also sets the " +
|
||||||
"on subtypes"
|
"value on subtypes"
|
||||||
);
|
);
|
||||||
|
|
||||||
SubFoo.$( 'bar', val );
|
SubFoo.$( 'bar', val );
|
||||||
assert.ok( Foo.$( 'bar' ) === SubFoo.$( 'bar' ) );
|
this.assertOk( Foo.$( 'bar' ) === SubFoo.$( 'bar' ) );
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static members do not have the benefit of prototype chains. We must
|
* Static members do not have the benefit of prototype chains. We must
|
||||||
* implement our own means of traversing the inheritance tree. This is done by
|
* implement our own means of traversing the inheritance tree. This is done
|
||||||
* checking to see if a class has defined the requested property, then
|
* by checking to see if a class has defined the requested property, then
|
||||||
* forwarding the call to the parent if it has not.
|
* forwarding the call to the parent if it has not.
|
||||||
*
|
*
|
||||||
* The process of looking up the property is very important. hasOwnProperty is
|
* The process of looking up the property is very important. hasOwnProperty
|
||||||
* used rather than checking for undefined, because they have drastically
|
* is used rather than checking for undefined, because they have drastically
|
||||||
* different results. Setting a value to undefined (if hasOwnProperty were not
|
* different results. Setting a value to undefined (if hasOwnProperty were
|
||||||
* used) would effectively forward all requests to the base class (since no
|
* not used) would effectively forward all requests to the base class (since
|
||||||
* property would be found), thereby preventing it from ever being written to
|
* no property would be found), thereby preventing it from ever being
|
||||||
* again.
|
* written to again.
|
||||||
*/
|
*/
|
||||||
( function testSettingsStaticPropertiesToUndefinedWillNotCorruptLookupProcess()
|
'Setting static props to undefined will not corrupt lookup': function()
|
||||||
{
|
{
|
||||||
var val = 'baz',
|
var val = 'baz',
|
||||||
Foo = builder.build(
|
Foo = builder.build(
|
||||||
{
|
{
|
||||||
|
@ -406,31 +411,32 @@ var common = require( './common' ),
|
||||||
|
|
||||||
// first check to ensure we can set the value to null
|
// first check to ensure we can set the value to null
|
||||||
Foo.$( 'foo', null );
|
Foo.$( 'foo', null );
|
||||||
assert.strictEqual( Foo.$( 'foo' ), null,
|
this.assertStrictEqual( Foo.$( 'foo' ), null,
|
||||||
"Static properties may be set to null"
|
"Static properties may be set to null"
|
||||||
);
|
);
|
||||||
|
|
||||||
// then undefined (this actually won't do anything)
|
// then undefined (this actually won't do anything)
|
||||||
Foo.$( 'foo', undefined );
|
Foo.$( 'foo', undefined );
|
||||||
assert.strictEqual( Foo.$( 'foo' ), undefined,
|
this.assertStrictEqual( Foo.$( 'foo' ), undefined,
|
||||||
"Static properties may be set to undefined"
|
"Static properties may be set to undefined"
|
||||||
);
|
);
|
||||||
|
|
||||||
// then set back to a scalar
|
// then set back to a scalar
|
||||||
Foo.$( 'foo', val );
|
Foo.$( 'foo', val );
|
||||||
assert.equal( Foo.$( 'foo' ), val,
|
this.assertEqual( Foo.$( 'foo' ), val,
|
||||||
"Setting static property to undefined does not corrupt lookup process"
|
"Setting static property to undefined does not corrupt lookup " +
|
||||||
|
"process"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure that the proper context is returned by static property setters. It
|
* Ensure that the proper context is returned by static property setters. It
|
||||||
* should return the calling class, regardless of whether or not it owns the
|
* should return the calling class, regardless of whether or not it owns the
|
||||||
* property being requested.
|
* property being requested.
|
||||||
*/
|
*/
|
||||||
( function testStaticPropertySettersReturnProperContext()
|
'Static property setters return proper context': function()
|
||||||
{
|
{
|
||||||
var Foo = builder.build(
|
var Foo = builder.build(
|
||||||
{
|
{
|
||||||
'public static foo': '',
|
'public static foo': '',
|
||||||
|
@ -439,24 +445,24 @@ var common = require( './common' ),
|
||||||
SubFoo = builder.build( Foo, {} )
|
SubFoo = builder.build( Foo, {} )
|
||||||
;
|
;
|
||||||
|
|
||||||
assert.ok( Foo.$( 'foo', 'val' ) === Foo,
|
this.assertOk( Foo.$( 'foo', 'val' ) === Foo,
|
||||||
"Static property setter returns self"
|
"Static property setter returns self"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.ok( SubFoo.$( 'foo', 'val' ) === SubFoo,
|
this.assertOk( SubFoo.$( 'foo', 'val' ) === SubFoo,
|
||||||
"Static property setter returns calling class, even if property is " +
|
"Static property setter returns calling class, even if property " +
|
||||||
"owned by a supertype"
|
"is owned by a supertype"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Users should not be permitted to set values of static properties that have
|
* Users should not be permitted to set values of static properties that
|
||||||
* not been declared.
|
* have not been declared.
|
||||||
*/
|
*/
|
||||||
( function testAttemptingToSetUndeclaredStaticPropertyResultsInException()
|
'Attempting to set undeclared static prop results in exception': function()
|
||||||
{
|
{
|
||||||
assert.throws(
|
this.assertThrows(
|
||||||
function()
|
function()
|
||||||
{
|
{
|
||||||
// should throw an exception since property 'foo' has not been
|
// should throw an exception since property 'foo' has not been
|
||||||
|
@ -467,15 +473,15 @@ var common = require( './common' ),
|
||||||
"Attempting to set an undeclaraed static property results in an " +
|
"Attempting to set an undeclaraed static property results in an " +
|
||||||
"exception"
|
"exception"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Protected members should be available from within the class but shouldn't be
|
* Protected members should be available from within the class but shouldn't
|
||||||
* exposed to the world
|
* be exposed to the world
|
||||||
*/
|
*/
|
||||||
( function testProtectedStaticMembersAreAvailableInsideClassOnly()
|
'Protected static members are available inside class only': function()
|
||||||
{
|
{
|
||||||
var val = 'foo',
|
var val = 'foo',
|
||||||
Foo = builder.build(
|
Foo = builder.build(
|
||||||
{
|
{
|
||||||
|
@ -511,34 +517,34 @@ var common = require( './common' ),
|
||||||
},
|
},
|
||||||
} );
|
} );
|
||||||
|
|
||||||
assert.equal( Foo.baz, undefined,
|
this.assertEqual( Foo.baz, undefined,
|
||||||
"Protected methods should not be accessible outside the class"
|
"Protected methods should not be accessible outside the class"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( Foo.staticBaz(), val,
|
this.assertEqual( Foo.staticBaz(), val,
|
||||||
"Protected methods are accessible to static methods"
|
"Protected methods are accessible to static methods"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( Foo().instBaz(), val,
|
this.assertEqual( Foo().instBaz(), val,
|
||||||
"Protected methods are accessible to instance methods"
|
"Protected methods are accessible to instance methods"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( Foo.staticGetProp(), val,
|
this.assertEqual( Foo.staticGetProp(), val,
|
||||||
"Protected static properties are accessible to static methods"
|
"Protected static properties are accessible to static methods"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( Foo().instGetProp(), val,
|
this.assertEqual( Foo().instGetProp(), val,
|
||||||
"Protected static properties are accessible to instance methods"
|
"Protected static properties are accessible to instance methods"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as above, but with getters/setters. We can only run this test if
|
* Same as above, but with getters/setters. We can only run this test if
|
||||||
* getters/setters are supported by the engine running it.
|
* getters/setters are supported by the engine running it.
|
||||||
*/
|
*/
|
||||||
( function testProtectedStaticGettersSettersAreAccessibleInsideClassesOnly()
|
'Protected static getters/setters accessible inside class only': function()
|
||||||
{
|
{
|
||||||
// if unsupported, don't bother with the test
|
// if unsupported, don't bother with the test
|
||||||
if ( fallback )
|
if ( fallback )
|
||||||
{
|
{
|
||||||
|
@ -550,7 +556,8 @@ var common = require( './common' ),
|
||||||
var def = {
|
var def = {
|
||||||
'public static getProp': function()
|
'public static getProp': function()
|
||||||
{
|
{
|
||||||
// getters/setters are not accessed using the accessor method
|
// getters/setters are not accessed using the accessor
|
||||||
|
// method
|
||||||
return this.foo;
|
return this.foo;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -572,29 +579,29 @@ var common = require( './common' ),
|
||||||
// define the class
|
// define the class
|
||||||
var Foo = builder.build( def );
|
var Foo = builder.build( def );
|
||||||
|
|
||||||
assert.equal( Foo.getProp(), val,
|
this.assertEqual( Foo.getProp(), val,
|
||||||
"Protected static getters are accessible from within the class"
|
"Protected static getters are accessible from within the class"
|
||||||
);
|
);
|
||||||
|
|
||||||
Foo.setProp( 'bla' );
|
Foo.setProp( 'bla' );
|
||||||
assert.equal( called[ 0 ], true,
|
this.assertEqual( called[ 0 ], true,
|
||||||
"Protected static setters are accessible from within the class"
|
"Protected static setters are accessible from within the class"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( Foo.foo, undefined,
|
this.assertEqual( Foo.foo, undefined,
|
||||||
"Protected static getters/getters are not public"
|
"Protected static getters/getters are not public"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* As usual, protected members (in this case, static) should be inherited by
|
* As usual, protected members (in this case, static) should be inherited by
|
||||||
* subtypes.
|
* subtypes.
|
||||||
*
|
*
|
||||||
* Long function is long. Kids, don't do this at home.
|
* Long function is long. Kids, don't do this at home.
|
||||||
*/
|
*/
|
||||||
( function testProtectedStaticMembersAreInheritedBySubtypes()
|
'Protected static members are inherited by subtypes': function()
|
||||||
{
|
{
|
||||||
var val = 'baz',
|
var val = 'baz',
|
||||||
val2 = 'bazbaz',
|
val2 = 'bazbaz',
|
||||||
def = {
|
def = {
|
||||||
|
@ -651,24 +658,26 @@ var common = require( './common' ),
|
||||||
SubSubFoo = builder.build( SubFoo, {} )
|
SubSubFoo = builder.build( SubFoo, {} )
|
||||||
;
|
;
|
||||||
|
|
||||||
assert.equal( SubFoo.bar(), val,
|
this.assertEqual( SubFoo.bar(), val,
|
||||||
"Subtypes inherit parents' protected static methods"
|
"Subtypes inherit parents' protected static methods"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( SubFoo.bar2(), val2,
|
this.assertEqual( SubFoo.bar2(), val2,
|
||||||
"Static methods have access to other static methods in the same class"
|
"Static methods have access to other static methods in the same " +
|
||||||
|
"class"
|
||||||
);
|
);
|
||||||
|
|
||||||
// for extra assurance, to ensure our recursive implementation is correct
|
// for extra assurance, to ensure our recursive implementation is
|
||||||
assert.equal( SubSubFoo.bar(), val,
|
// correct
|
||||||
|
this.assertEqual( SubSubFoo.bar(), val,
|
||||||
"Sub-subtypes inherit parents' protected static methods"
|
"Sub-subtypes inherit parents' protected static methods"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( SubFoo.getProp(), val,
|
this.assertEqual( SubFoo.getProp(), val,
|
||||||
"Subtypes inherit parents' protected static properties"
|
"Subtypes inherit parents' protected static properties"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( SubSubFoo.getProp(), val,
|
this.assertEqual( SubSubFoo.getProp(), val,
|
||||||
"Sub-subtypes inherit parents' protected static properties"
|
"Sub-subtypes inherit parents' protected static properties"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -681,30 +690,30 @@ var common = require( './common' ),
|
||||||
;
|
;
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
assert.deepEqual( super_data.get, sub_data.get,
|
this.assertDeepEqual( super_data.get, sub_data.get,
|
||||||
"Protected static getters are inherited by subtypes"
|
"Protected static getters are inherited by subtypes"
|
||||||
);
|
);
|
||||||
assert.deepEqual( super_data.get, sub_sub_data.get,
|
this.assertDeepEqual( super_data.get, sub_sub_data.get,
|
||||||
"Protected static getters are inherited by sub-subtypes"
|
"Protected static getters are inherited by sub-subtypes"
|
||||||
);
|
);
|
||||||
|
|
||||||
// setters
|
// setters
|
||||||
assert.deepEqual( super_data.set, sub_data.set,
|
this.assertDeepEqual( super_data.set, sub_data.set,
|
||||||
"Protected static setters are inherited by subtypes"
|
"Protected static setters are inherited by subtypes"
|
||||||
);
|
);
|
||||||
assert.deepEqual( super_data.set, sub_sub_data.set,
|
this.assertDeepEqual( super_data.set, sub_sub_data.set,
|
||||||
"Protected static setters are inherited by sub-subtypes"
|
"Protected static setters are inherited by sub-subtypes"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private members should be available from within the class, but not outside of
|
* Private members should be available from within the class, but not
|
||||||
* it
|
* outside of it
|
||||||
*/
|
*/
|
||||||
( function testPrivateStaticMembersAreAvailableInsideClassOnly()
|
'Private static members are available inside class only': function()
|
||||||
{
|
{
|
||||||
var val = 'foo',
|
var val = 'foo',
|
||||||
Foo = builder.build(
|
Foo = builder.build(
|
||||||
{
|
{
|
||||||
|
@ -740,34 +749,34 @@ var common = require( './common' ),
|
||||||
},
|
},
|
||||||
} );
|
} );
|
||||||
|
|
||||||
assert.equal( Foo.baz, undefined,
|
this.assertEqual( Foo.baz, undefined,
|
||||||
"Private methods should not be accessible outside the class"
|
"Private methods should not be accessible outside the class"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( Foo.staticBaz(), val,
|
this.assertEqual( Foo.staticBaz(), val,
|
||||||
"Private methods are accessible to static methods"
|
"Private methods are accessible to static methods"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( Foo().instBaz(), val,
|
this.assertEqual( Foo().instBaz(), val,
|
||||||
"Private methods are accessible to instance methods"
|
"Private methods are accessible to instance methods"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( Foo.staticGetProp(), val,
|
this.assertEqual( Foo.staticGetProp(), val,
|
||||||
"Private static properties are accessible to static methods"
|
"Private static properties are accessible to static methods"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( Foo().instGetProp(), val,
|
this.assertEqual( Foo().instGetProp(), val,
|
||||||
"Private static properties are accessible to instance methods"
|
"Private static properties are accessible to instance methods"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private static members should not be inherited by subtypes. Of course. Moving
|
* Private static members should not be inherited by subtypes. Of course.
|
||||||
* along...
|
* Moving along...
|
||||||
*/
|
*/
|
||||||
( function testPrivateStaticMembersAreNotInheritedBySubtypes()
|
'Private static members are not inherited by subtypes': function()
|
||||||
{
|
{
|
||||||
var def = {
|
var def = {
|
||||||
'private static prop': 'foo',
|
'private static prop': 'foo',
|
||||||
'private static priv': function() {},
|
'private static priv': function() {},
|
||||||
|
@ -810,30 +819,32 @@ var common = require( './common' ),
|
||||||
} )
|
} )
|
||||||
;
|
;
|
||||||
|
|
||||||
assert.equal( SubFoo.getPriv(), undefined,
|
this.assertEqual( SubFoo.getPriv(), undefined,
|
||||||
"Private static methods should not be inherited by subtypes"
|
"Private static methods should not be inherited by subtypes"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( SubFoo.getGetSet(), undefined,
|
this.assertEqual( SubFoo.getGetSet(), undefined,
|
||||||
"Private static getters/setters should not be inherited by subtypes"
|
"Private static getters/setters should not be inherited by subtypes"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( SubFoo().instGetProp(), undefined,
|
this.assertEqual( SubFoo().instGetProp(), undefined,
|
||||||
"Private static properties should not be inherited by subtypes (inst)"
|
"Private static properties should not be inherited by subtypes " +
|
||||||
|
"(inst)"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( SubFoo.staticGetProp(), undefined,
|
this.assertEqual( SubFoo.staticGetProp(), undefined,
|
||||||
"Private static properties should not be inherited by subtypes (static)"
|
"Private static properties should not be inherited by subtypes " +
|
||||||
|
"(static)"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as above, but with getters/setters. We can only run this test if
|
* Same as above, but with getters/setters. We can only run this test if
|
||||||
* getters/setters are supported by the engine running it.
|
* getters/setters are supported by the engine running it.
|
||||||
*/
|
*/
|
||||||
( function testPrivateStaticGettersSettersAreAccessibleInsideClassesOnly()
|
'Private static getters/setters accessible inside class only': function()
|
||||||
{
|
{
|
||||||
// if unsupported, don't bother with the test
|
// if unsupported, don't bother with the test
|
||||||
if ( fallback )
|
if ( fallback )
|
||||||
{
|
{
|
||||||
|
@ -845,7 +856,8 @@ var common = require( './common' ),
|
||||||
var def = {
|
var def = {
|
||||||
'public static getProp': function()
|
'public static getProp': function()
|
||||||
{
|
{
|
||||||
// getters/setters are not accessed using the accessor method
|
// getters/setters are not accessed using the accessor
|
||||||
|
// method
|
||||||
return this.foo;
|
return this.foo;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -867,27 +879,27 @@ var common = require( './common' ),
|
||||||
// define the class
|
// define the class
|
||||||
var Foo = builder.build( def );
|
var Foo = builder.build( def );
|
||||||
|
|
||||||
assert.equal( Foo.getProp(), val,
|
this.assertEqual( Foo.getProp(), val,
|
||||||
"Private static getters are accessible from within the class"
|
"Private static getters are accessible from within the class"
|
||||||
);
|
);
|
||||||
|
|
||||||
Foo.setProp( 'bla' );
|
Foo.setProp( 'bla' );
|
||||||
assert.equal( called[ 0 ], true,
|
this.assertEqual( called[ 0 ], true,
|
||||||
"Private static setters are accessible from within the class"
|
"Private static setters are accessible from within the class"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( Foo.foo, undefined,
|
this.assertEqual( Foo.foo, undefined,
|
||||||
"Private static getters/getters are not public"
|
"Private static getters/getters are not public"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public and protected static methods should be able to be overridden by
|
* Public and protected static methods should be able to be overridden by
|
||||||
* subtypes. We needn't test private methods, as they are not inherited.
|
* subtypes. We needn't test private methods, as they are not inherited.
|
||||||
*/
|
*/
|
||||||
( function testStaticMethodsCanBeOverriddenBySubtypes()
|
'Static methods can be overridden by subtypes': function()
|
||||||
{
|
{
|
||||||
var val = 'bar',
|
var val = 'bar',
|
||||||
Foo = builder.build(
|
Foo = builder.build(
|
||||||
{
|
{
|
||||||
|
@ -913,25 +925,26 @@ var common = require( './common' ),
|
||||||
},
|
},
|
||||||
} );
|
} );
|
||||||
|
|
||||||
assert.equal( SubFoo.foo(), val,
|
this.assertEqual( SubFoo.foo(), val,
|
||||||
"Public static methods can be overridden by subtypes"
|
"Public static methods can be overridden by subtypes"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( SubFoo.prot(), val,
|
this.assertEqual( SubFoo.prot(), val,
|
||||||
"Protected static methods can be overridden by subtypes"
|
"Protected static methods can be overridden by subtypes"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This tests very closely to the implementation, which is not good. However,
|
* This tests very closely to the implementation, which is not good.
|
||||||
* it's important to protecting the data. The accessor method works off of
|
* However, it's important to protecting the data. The accessor method works
|
||||||
* context, so it's important to ensure that the data will remain encapsulated
|
* off of context, so it's important to ensure that the data will remain
|
||||||
* if the user attempts to be tricky and bind to a supertype.
|
* encapsulated if the user attempts to be tricky and bind to a supertype.
|
||||||
*/
|
*/
|
||||||
( function testCannotExploitAccessorMethodToGainAccessToParentPrivateProps()
|
'Cannot exploit accessor method to gain access to parent private props':
|
||||||
{
|
function()
|
||||||
|
{
|
||||||
var Foo = builder.build(
|
var Foo = builder.build(
|
||||||
{
|
{
|
||||||
'private static foo': 'bar',
|
'private static foo': 'bar',
|
||||||
|
@ -946,18 +959,18 @@ var common = require( './common' ),
|
||||||
} )
|
} )
|
||||||
;
|
;
|
||||||
|
|
||||||
assert.equal( SubFoo.getParentPrivate(), undefined,
|
this.assertEqual( SubFoo.getParentPrivate(), undefined,
|
||||||
"Cannot exploit accses modifier to gain access to parent private props"
|
"Cannot exploit accses modifier to gain access to parent private props"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static members cannot be overridden. Instead, static members can be *hidden*
|
* Static members cannot be overridden. Instead, static members can be
|
||||||
* if a member of the same name is defined by a subtype.
|
* *hidden* if a member of the same name is defined by a subtype.
|
||||||
*/
|
*/
|
||||||
( function testCannotOverrideStaticMembers()
|
'Cannot override static members': function()
|
||||||
{
|
{
|
||||||
var val_orig = 'foobaz',
|
var val_orig = 'foobaz',
|
||||||
val = 'foobar',
|
val = 'foobar',
|
||||||
|
|
||||||
|
@ -1000,29 +1013,29 @@ var common = require( './common' ),
|
||||||
;
|
;
|
||||||
|
|
||||||
// cannot override
|
// cannot override
|
||||||
assert.notEqual( SubFoo.foo(), val,
|
this.assertNotEqual( SubFoo.foo(), val,
|
||||||
"System does not support overriding static methods"
|
"System does not support overriding static methods"
|
||||||
);
|
);
|
||||||
assert.notEqual( SubFoo.baz(), val,
|
this.assertNotEqual( SubFoo.baz(), val,
|
||||||
"System does not support overriding static properties"
|
"System does not support overriding static properties"
|
||||||
);
|
);
|
||||||
|
|
||||||
// but we can hide them
|
// but we can hide them
|
||||||
assert.equal( SubFoo.bar(), val,
|
this.assertEqual( SubFoo.bar(), val,
|
||||||
"System supports static method hiding"
|
"System supports static method hiding"
|
||||||
);
|
);
|
||||||
assert.equal( SubFoo.getProp(), val,
|
this.assertEqual( SubFoo.getProp(), val,
|
||||||
"System supports static property hiding"
|
"System supports static property hiding"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Since members are statically bound, calls to parent methods should retain
|
* Since members are statically bound, calls to parent methods should retain
|
||||||
* access to their private members.
|
* access to their private members.
|
||||||
*/
|
*/
|
||||||
( function testCallsToParentStaticMethodsRetainPrivateMemberAccess()
|
'Calls to parent static methods retain private member access': function()
|
||||||
{
|
{
|
||||||
var val = 'foobar',
|
var val = 'foobar',
|
||||||
Foo = builder.build(
|
Foo = builder.build(
|
||||||
{
|
{
|
||||||
|
@ -1043,14 +1056,15 @@ var common = require( './common' ),
|
||||||
} )
|
} )
|
||||||
;
|
;
|
||||||
|
|
||||||
assert.equal( SubFoo.getPriv(), val,
|
this.assertEqual( SubFoo.getPriv(), val,
|
||||||
'Calls to parent static methods should retain access to their own ' +
|
'Calls to parent static methods should retain access to their own ' +
|
||||||
'private members when called externally'
|
'private members when called externally'
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( SubFoo.getPriv2(), val,
|
this.assertEqual( SubFoo.getPriv2(), val,
|
||||||
'Calls to parent static methods should retain access to their own ' +
|
'Calls to parent static methods should retain access to their own ' +
|
||||||
'private members when called internally'
|
'private members when called internally'
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
} );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue