Converted a number of test cases to new XUnit-style format
parent
0d306b63c8
commit
28bf9e6421
|
@ -21,25 +21,22 @@
|
||||||
* @author Mike Gerwitz
|
* @author Mike Gerwitz
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
require( 'common' ).testCase(
|
||||||
var common = require( './common' ),
|
{
|
||||||
assert = require( 'assert' ),
|
caseSetUp: function()
|
||||||
|
{
|
||||||
// SUT
|
this.Sut = this.require( 'FallbackVisibilityObjectFactory' );
|
||||||
FallbackVisibilityObjectFactory =
|
|
||||||
common.require( 'FallbackVisibilityObjectFactory' ),
|
|
||||||
|
|
||||||
// parent of SUT
|
// parent of SUT
|
||||||
VisibilityObjectFactory = common.require( 'VisibilityObjectFactory' ),
|
this.VisibilityObjectFactory =
|
||||||
|
this.require( 'VisibilityObjectFactory' );
|
||||||
|
|
||||||
sut = FallbackVisibilityObjectFactory(),
|
this.props = this.methods = {
|
||||||
|
|
||||||
props = methods = {
|
|
||||||
'public': {},
|
'public': {},
|
||||||
'protected': {},
|
'protected': {},
|
||||||
'private': {},
|
'private': {},
|
||||||
}
|
};
|
||||||
;
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,64 +45,66 @@ var common = require( './common' ),
|
||||||
*
|
*
|
||||||
* Consistency is key with these sorts of things.
|
* Consistency is key with these sorts of things.
|
||||||
*/
|
*/
|
||||||
( function testCanInstantiateWithAndWithoutNewKeyword()
|
'Can instantiate with and without `new` keyword': function()
|
||||||
{
|
{
|
||||||
// with 'new' keyword
|
// with 'new' keyword
|
||||||
assert.ok(
|
this.assertOk(
|
||||||
( new FallbackVisibilityObjectFactory() )
|
( new this.Sut() ) instanceof this.Sut,
|
||||||
instanceof FallbackVisibilityObjectFactory,
|
"Should be able to instantiate FallbackVisibilityObjectFactory " +
|
||||||
"Should be able to instantiate FallbackVisibilityObjectFactory with " +
|
"with 'new' keyword"
|
||||||
"'new' keyword"
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// without 'new' keyword
|
// without 'new' keyword
|
||||||
assert.ok(
|
this.assertOk(
|
||||||
FallbackVisibilityObjectFactory()
|
this.Sut() instanceof this.Sut,
|
||||||
instanceof FallbackVisibilityObjectFactory,
|
|
||||||
"Should be able to instantiate FallbackVisibilityObjectFactory " +
|
"Should be able to instantiate FallbackVisibilityObjectFactory " +
|
||||||
"without 'new' keyword"
|
"without 'new' keyword"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* VisibilityObjectFactory should be part of our prototype chain.
|
* VisibilityObjectFactory should be part of our prototype chain.
|
||||||
*/
|
*/
|
||||||
( function testInheritsFromVisibilityObjectFactory()
|
'Inherits from visibility object factory': function()
|
||||||
{
|
{
|
||||||
// check an instance, rather than __proto__, because older engines do not
|
// check an instance, rather than __proto__, because older engines do
|
||||||
// support it
|
// not support it
|
||||||
assert.ok(
|
this.assertOk(
|
||||||
FallbackVisibilityObjectFactory() instanceof VisibilityObjectFactory,
|
this.Sut() instanceof this.VisibilityObjectFactory,
|
||||||
"Fallback should inherit from VisibilityObjectFactory"
|
"Fallback should inherit from VisibilityObjectFactory"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We're falling back because we do not support the private visibility layer (or
|
* We're falling back because we do not support the private visibility layer
|
||||||
* any layers, for that matter). Ensure it's not created.
|
* (or any layers, for that matter). Ensure it's not created.
|
||||||
*/
|
*/
|
||||||
( function testSetupMethodShouldNotAddPrivateLayer()
|
'Setup method should not add private layer': function()
|
||||||
{
|
{
|
||||||
var dest = {},
|
var dest = {},
|
||||||
obj = sut.setup( dest, props, methods );
|
obj = this.Sut().setup( dest, this.props, this.methods );
|
||||||
|
|
||||||
assert.strictEqual( dest, obj,
|
this.assertStrictEqual( dest, obj,
|
||||||
"Private visibility layer is not added atop destination"
|
"Private visibility layer is not added atop destination"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
( function testCreatingPropertyProxyShouldSimplyReturnSelf()
|
/**
|
||||||
|
* Getters/setters are unsupported (thus the fallback).
|
||||||
|
*/
|
||||||
|
'Creating property proxy should simply return self': function()
|
||||||
{
|
{
|
||||||
var base = {},
|
var base = {},
|
||||||
dest = {};
|
dest = {};
|
||||||
|
|
||||||
assert.strictEqual(
|
this.assertStrictEqual(
|
||||||
sut.createPropProxy( base, dest, props ),
|
this.Sut().createPropProxy( base, dest, this.props ),
|
||||||
base,
|
base,
|
||||||
"Creating property proxy should simply return original object"
|
"Creating property proxy should simply return original object"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
} );
|
||||||
|
|
||||||
|
|
|
@ -22,11 +22,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
var common = require( './common' ),
|
require( 'common' ).testCase(
|
||||||
assert = require( 'assert' ),
|
{
|
||||||
|
caseSetUp: function()
|
||||||
Sut = common.require( 'MethodWrapperFactory' )
|
{
|
||||||
;
|
this.Sut = this.require( 'MethodWrapperFactory' );
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,31 +36,31 @@ var common = require( './common' ),
|
||||||
*
|
*
|
||||||
* Consistency is key with these sorts of things.
|
* Consistency is key with these sorts of things.
|
||||||
*/
|
*/
|
||||||
( function testCanInstantiateWithAndWithoutNewKeyword()
|
'Can instantiate with and without new keyword': function()
|
||||||
{
|
{
|
||||||
// with 'new' keyword
|
// with 'new' keyword
|
||||||
assert.ok(
|
this.assertOk(
|
||||||
( new Sut() )
|
( new this.Sut() ) instanceof this.Sut,
|
||||||
instanceof Sut,
|
|
||||||
"Should be able to instantiate MethodWrapperFactory with " +
|
"Should be able to instantiate MethodWrapperFactory with " +
|
||||||
"'new' keyword"
|
"'new' keyword"
|
||||||
);
|
);
|
||||||
|
|
||||||
// without 'new' keyword
|
// without 'new' keyword
|
||||||
assert.ok( ( Sut() instanceof Sut ),
|
this.assertOk( ( this.Sut() instanceof this.Sut ),
|
||||||
"Should be able to instantiate MethodWrapperFactory " +
|
"Should be able to instantiate MethodWrapperFactory " +
|
||||||
"without 'new' keyword"
|
"without 'new' keyword"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The factory itself is rather simple. The class should accept a factory
|
* The factory itself is rather simple. The class should accept a factory
|
||||||
* function which should return the wrapped method.
|
* function which should return the wrapped method.
|
||||||
*/
|
*/
|
||||||
( function testProvidedFactoryFunctionIsProperlyCalled()
|
'Provided factory function is properly called': function()
|
||||||
{
|
{
|
||||||
var called = false,
|
var _self = this,
|
||||||
|
called = false,
|
||||||
method = function() {},
|
method = function() {},
|
||||||
super_method = function() {},
|
super_method = function() {},
|
||||||
cid = 55,
|
cid = 55,
|
||||||
|
@ -68,7 +69,7 @@ var common = require( './common' ),
|
||||||
keywords = { 'static': true, 'public': true },
|
keywords = { 'static': true, 'public': true },
|
||||||
retval = 'foobar';
|
retval = 'foobar';
|
||||||
|
|
||||||
var result = Sut(
|
var result = this.Sut(
|
||||||
function(
|
function(
|
||||||
given_method, given_super, given_cid, givenGetInst, given_name,
|
given_method, given_super, given_cid, givenGetInst, given_name,
|
||||||
given_keywords
|
given_keywords
|
||||||
|
@ -76,27 +77,27 @@ var common = require( './common' ),
|
||||||
{
|
{
|
||||||
called = true;
|
called = true;
|
||||||
|
|
||||||
assert.equal( given_method, method,
|
_self.assertEqual( given_method, method,
|
||||||
"Factory method should be provided with method to wrap"
|
"Factory method should be provided with method to wrap"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( given_super, super_method,
|
_self.assertEqual( given_super, super_method,
|
||||||
"Factory method should be provided with super method"
|
"Factory method should be provided with super method"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( given_cid, cid,
|
_self.assertEqual( given_cid, cid,
|
||||||
"Factory method should be provided with cid"
|
"Factory method should be provided with cid"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( givenGetInst, getInst,
|
_self.assertEqual( givenGetInst, getInst,
|
||||||
"Factory method should be provided with proper inst function"
|
"Factory method should be provided with proper inst function"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( given_name, name,
|
_self.assertEqual( given_name, name,
|
||||||
"Factory method should be provided with proper method name"
|
"Factory method should be provided with proper method name"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( given_keywords, keywords,
|
_self.assertEqual( given_keywords, keywords,
|
||||||
"Factory method should be provided with proper keywords"
|
"Factory method should be provided with proper keywords"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -106,12 +107,12 @@ var common = require( './common' ),
|
||||||
|
|
||||||
// we'll include this in addition to the following assertion (which is
|
// we'll include this in addition to the following assertion (which is
|
||||||
// redundant) to make debugging more clear
|
// redundant) to make debugging more clear
|
||||||
assert.equal( called, true,
|
this.assertEqual( called, true,
|
||||||
"Given factory method should be called"
|
"Given factory method should be called"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( result, retval,
|
this.assertEqual( result, retval,
|
||||||
"Should return value from factory function"
|
"Should return value from factory function"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
} );
|
||||||
|
|
|
@ -21,19 +21,40 @@
|
||||||
* @author Mike Gerwitz
|
* @author Mike Gerwitz
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var common = require( './common' ),
|
require( 'common' ).testCase(
|
||||||
assert = require( 'assert' ),
|
{
|
||||||
util = common.require( 'util' ),
|
caseSetUp: function()
|
||||||
sut = common.require( 'MethodWrappers' )
|
{
|
||||||
;
|
// common assertions between a couple of proxy tests
|
||||||
|
this.proxyErrorAssertCommon = function( e, prop, method )
|
||||||
|
{
|
||||||
|
this.assertOk(
|
||||||
|
e.message.search( 'Unable to proxy' ) > -1,
|
||||||
|
"Unexpected error received: " + e.message
|
||||||
|
);
|
||||||
|
|
||||||
|
this.assertOk(
|
||||||
|
( ( e.message.search( prop ) > -1 )
|
||||||
|
&& ( e.message.search( method ) > -1 )
|
||||||
|
),
|
||||||
|
"Error should contain property and method names"
|
||||||
|
);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
setUp: function()
|
||||||
|
{
|
||||||
|
this._sut = this.require( 'MethodWrappers' );
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The wrappers accept a function that should return the instance to be bound to
|
* The wrappers accept a function that should return the instance to be
|
||||||
* 'this' when invoking a method. This has some important consequences, such as
|
* bound to 'this' when invoking a method. This has some important
|
||||||
* the ability to implement protected/private members.
|
* consequences, such as the ability to implement protected/private members.
|
||||||
*/
|
*/
|
||||||
( function testMethodInvocationBindsThisToPassedInstance()
|
'Method invocation binds `this` to passed instance': function()
|
||||||
{
|
{
|
||||||
var instance = function() {},
|
var instance = function() {},
|
||||||
val = 'fooboo',
|
val = 'fooboo',
|
||||||
|
@ -47,7 +68,7 @@ var common = require( './common' ),
|
||||||
return instance;
|
return instance;
|
||||||
},
|
},
|
||||||
|
|
||||||
method = sut.standard.wrapNew(
|
method = this._sut.standard.wrapNew(
|
||||||
function()
|
function()
|
||||||
{
|
{
|
||||||
return this.foo;
|
return this.foo;
|
||||||
|
@ -55,7 +76,7 @@ var common = require( './common' ),
|
||||||
null, 0, getInst
|
null, 0, getInst
|
||||||
),
|
),
|
||||||
|
|
||||||
override = sut.standard.wrapOverride(
|
override = this._sut.standard.wrapOverride(
|
||||||
function()
|
function()
|
||||||
{
|
{
|
||||||
return this.foo2;
|
return this.foo2;
|
||||||
|
@ -68,32 +89,33 @@ var common = require( './common' ),
|
||||||
instance.foo = val;
|
instance.foo = val;
|
||||||
instance.foo2 = val2;
|
instance.foo2 = val2;
|
||||||
|
|
||||||
assert.equal( method(), val,
|
this.assertEqual( method(), val,
|
||||||
"Calling method will bind 'this' to passed instance"
|
"Calling method will bind 'this' to passed instance"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal( override(), val2,
|
this.assertEqual( override(), val2,
|
||||||
"Calling method override will bind 'this' to passed instance"
|
"Calling method override will bind 'this' to passed instance"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The __super property is defined for method overrides and permits invoking the
|
* The __super property is defined for method overrides and permits invoking
|
||||||
* overridden method (method of the supertype).
|
* the overridden method (method of the supertype).
|
||||||
*
|
*
|
||||||
* In this test, we are not looking to assert that __super matches the super
|
* In this test, we are not looking to assert that __super matches the super
|
||||||
* method. Rather, we want to ensure it /invokes/ it. This is because the super
|
* method. Rather, we want to ensure it /invokes/ it. This is because the
|
||||||
* method may be wrapped to provide additional functionality. We don't know, we
|
* super method may be wrapped to provide additional functionality. We don't
|
||||||
* don't care. We just want to make sure it's functioning properly.
|
* know, we don't care. We just want to make sure it's functioning properly.
|
||||||
*/
|
*/
|
||||||
( function testOverridenMethodShouldContainReferenceToSuperMethod()
|
'Overriden method should contain reference to super method': function()
|
||||||
{
|
{
|
||||||
var orig_called = false,
|
var _self = this,
|
||||||
|
orig_called = false,
|
||||||
getInst = function() {},
|
getInst = function() {},
|
||||||
|
|
||||||
// "super" method
|
// "super" method
|
||||||
method = sut.standard.wrapNew(
|
method = this._sut.standard.wrapNew(
|
||||||
function()
|
function()
|
||||||
{
|
{
|
||||||
orig_called = true;
|
orig_called = true;
|
||||||
|
@ -102,17 +124,17 @@ var common = require( './common' ),
|
||||||
),
|
),
|
||||||
|
|
||||||
// override method
|
// override method
|
||||||
override = sut.standard.wrapOverride(
|
override = this._sut.standard.wrapOverride(
|
||||||
function()
|
function()
|
||||||
{
|
{
|
||||||
assert.notEqual(
|
_self.assertNotEqual(
|
||||||
this.__super,
|
this.__super,
|
||||||
undefined,
|
undefined,
|
||||||
"__super is defined for overridden method"
|
"__super is defined for overridden method"
|
||||||
);
|
);
|
||||||
|
|
||||||
this.__super();
|
this.__super();
|
||||||
assert.equal(
|
_self.assertEqual(
|
||||||
orig_called,
|
orig_called,
|
||||||
true,
|
true,
|
||||||
"Invoking __super calls super method"
|
"Invoking __super calls super method"
|
||||||
|
@ -124,7 +146,7 @@ var common = require( './common' ),
|
||||||
|
|
||||||
// invoke the method to run the above assertions
|
// invoke the method to run the above assertions
|
||||||
override();
|
override();
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -132,10 +154,10 @@ var common = require( './common' ),
|
||||||
* protected/private members), __super may not be properly bound.
|
* protected/private members), __super may not be properly bound.
|
||||||
*
|
*
|
||||||
* This test is in response to a bug found after implementing visibility
|
* This test is in response to a bug found after implementing visibility
|
||||||
* support. The __super() method was previously defined on 'this', which may or
|
* support. The __super() method was previously defined on 'this', which may
|
||||||
* may not be the context that is actually used. Likely, it's not.
|
* or may not be the context that is actually used. Likely, it's not.
|
||||||
*/
|
*/
|
||||||
( function testSuperMethodWorksProperlyWhenContextDiffers()
|
'Super method works properly when context differs': function()
|
||||||
{
|
{
|
||||||
var super_called = false,
|
var super_called = false,
|
||||||
retobj = {},
|
retobj = {},
|
||||||
|
@ -146,7 +168,7 @@ var common = require( './common' ),
|
||||||
},
|
},
|
||||||
|
|
||||||
// super method to be overridden
|
// super method to be overridden
|
||||||
method = sut.standard.wrapNew(
|
method = this._sut.standard.wrapNew(
|
||||||
function()
|
function()
|
||||||
{
|
{
|
||||||
super_called = true;
|
super_called = true;
|
||||||
|
@ -155,7 +177,7 @@ var common = require( './common' ),
|
||||||
),
|
),
|
||||||
|
|
||||||
// the overriding method
|
// the overriding method
|
||||||
override = sut.standard.wrapOverride(
|
override = this._sut.standard.wrapOverride(
|
||||||
function()
|
function()
|
||||||
{
|
{
|
||||||
this.__super();
|
this.__super();
|
||||||
|
@ -168,17 +190,17 @@ var common = require( './common' ),
|
||||||
override();
|
override();
|
||||||
|
|
||||||
// ensure that the super method was called
|
// ensure that the super method was called
|
||||||
assert.equal( super_called, true,
|
this.assertEqual( super_called, true,
|
||||||
"__super() method is called even when context differs"
|
"__super() method is called even when context differs"
|
||||||
);
|
);
|
||||||
|
|
||||||
// finally, ensure that __super is no longer set on the returned object
|
// finally, ensure that __super is no longer set on the returned object
|
||||||
// after the call to ensure that the caller cannot break encapsulation by
|
// after the call to ensure that the caller cannot break encapsulation
|
||||||
// stealing a method reference (sneaky, sneaky)
|
// by stealing a method reference (sneaky, sneaky)
|
||||||
assert.equal( retobj.__super, undefined,
|
this.assertEqual( retobj.__super, undefined,
|
||||||
"__super() method is unset after being called"
|
"__super() method is unset after being called"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -186,7 +208,7 @@ var common = require( './common' ),
|
||||||
* appropriate method. The return value should also be proxied back to the
|
* appropriate method. The return value should also be proxied back to the
|
||||||
* caller.
|
* caller.
|
||||||
*/
|
*/
|
||||||
( function testProxyWillProperlyForwardCallToDestinationObject()
|
'Proxy will properly forward calls to destination object': function()
|
||||||
{
|
{
|
||||||
var name = 'someMethod',
|
var name = 'someMethod',
|
||||||
propname = 'dest',
|
propname = 'dest',
|
||||||
|
@ -211,29 +233,32 @@ var common = require( './common' ),
|
||||||
// acts like a class instance
|
// acts like a class instance
|
||||||
inst = { dest: dest },
|
inst = { dest: dest },
|
||||||
|
|
||||||
proxy = sut.standard.wrapProxy( propname, null, 0, getInst, name )
|
proxy = this._sut.standard.wrapProxy(
|
||||||
|
propname, null, 0, getInst, name
|
||||||
|
)
|
||||||
;
|
;
|
||||||
|
|
||||||
assert.strictEqual( method_retval, proxy.apply( inst, args ),
|
this.assertStrictEqual( method_retval, proxy.apply( inst, args ),
|
||||||
"Proxy call should return the value from the destination"
|
"Proxy call should return the value from the destination"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.deepEqual( args, args_given,
|
this.assertDeepEqual( args, args_given,
|
||||||
"All arguments should be properly forwarded to the destination"
|
"All arguments should be properly forwarded to the destination"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the destination object returns itself, then we should return the context
|
* If the destination object returns itself, then we should return the
|
||||||
* in which the proxy was called; this ensures that we do not break
|
* context in which the proxy was called; this ensures that we do not break
|
||||||
* encapsulation. Consequently, it also provides a more consistent and sensical
|
* encapsulation. Consequently, it also provides a more consistent and
|
||||||
* API and permits method chaining.
|
* sensical API and permits method chaining.
|
||||||
*
|
*
|
||||||
* If this is not the desired result, then the user is free to forefit the proxy
|
* If this is not the desired result, then the user is free to forefit the
|
||||||
* wrapper and instead use a normal method, manually proxying the call.
|
* proxy wrapper and instead use a normal method, manually proxying the
|
||||||
|
* call.
|
||||||
*/
|
*/
|
||||||
( function testProxyReturnValueIsReplacedWithContextIfDestinationReturnsSelf()
|
'Proxy retval is replaced with context if dest returns self': function()
|
||||||
{
|
{
|
||||||
var propname = 'foo',
|
var propname = 'foo',
|
||||||
method = 'bar',
|
method = 'bar',
|
||||||
|
@ -248,7 +273,7 @@ var common = require( './common' ),
|
||||||
|
|
||||||
inst = { foo: foo },
|
inst = { foo: foo },
|
||||||
|
|
||||||
ret = sut.standard.wrapProxy(
|
ret = this._sut.standard.wrapProxy(
|
||||||
propname, null, 0,
|
propname, null, 0,
|
||||||
function()
|
function()
|
||||||
{
|
{
|
||||||
|
@ -258,35 +283,18 @@ var common = require( './common' ),
|
||||||
).call( inst )
|
).call( inst )
|
||||||
;
|
;
|
||||||
|
|
||||||
assert.strictEqual( inst, ret,
|
this.assertStrictEqual( inst, ret,
|
||||||
"Proxy should return instance in place of destination, if returned"
|
"Proxy should return instance in place of destination, if returned"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
// common assertions between a couple of proxy tests
|
|
||||||
function proxyErrorAssertCommon( e, prop, method )
|
|
||||||
{
|
|
||||||
assert.ok(
|
|
||||||
e.message.search( 'Unable to proxy' ) > -1,
|
|
||||||
"Unexpected error received: " + e.message
|
|
||||||
);
|
|
||||||
|
|
||||||
assert.ok(
|
|
||||||
( ( e.message.search( prop ) > -1 )
|
|
||||||
&& ( e.message.search( method ) > -1 )
|
|
||||||
),
|
|
||||||
"Error should contain property and method names"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rather than allowing a cryptic error to be thrown by the engine, take some
|
* Rather than allowing a cryptic error to be thrown by the engine, take
|
||||||
* initiative and attempt to detect when a call will fail due to the destination
|
* some initiative and attempt to detect when a call will fail due to the
|
||||||
* not being an object.
|
* destination not being an object.
|
||||||
*/
|
*/
|
||||||
( function testProxyThrowsErrorIfCallWillFailDueToNonObject()
|
'Proxy throws error if call will faill due to non-object': function()
|
||||||
{
|
{
|
||||||
var prop = 'noexist',
|
var prop = 'noexist',
|
||||||
method = 'foo';
|
method = 'foo';
|
||||||
|
@ -294,7 +302,7 @@ function proxyErrorAssertCommon( e, prop, method )
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// should fail because 'noexist' does not exist on the object
|
// should fail because 'noexist' does not exist on the object
|
||||||
sut.standard.wrapProxy(
|
this._sut.standard.wrapProxy(
|
||||||
prop, null, 0,
|
prop, null, 0,
|
||||||
function() { return {}; },
|
function() { return {}; },
|
||||||
method
|
method
|
||||||
|
@ -302,22 +310,22 @@ function proxyErrorAssertCommon( e, prop, method )
|
||||||
}
|
}
|
||||||
catch ( e )
|
catch ( e )
|
||||||
{
|
{
|
||||||
proxyErrorAssertCommon( e, prop, method );
|
this.proxyErrorAssertCommon( e, prop, method );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.fail(
|
this.assertFail(
|
||||||
"Error should be thrown if proxy would fail due to a non-object"
|
"Error should be thrown if proxy would fail due to a non-object"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rather than allowing a cryptic error to be thrown by the engine, take some
|
* Rather than allowing a cryptic error to be thrown by the engine, take
|
||||||
* initiative and attempt to detect when a call will fail due to the destination
|
* some initiative and attempt to detect when a call will fail due to the
|
||||||
* method not being a function.
|
* destination method not being a function.
|
||||||
*/
|
*/
|
||||||
( function testProxyThrowsErrorIfCallWillFailDueToNonObject()
|
'Proxy throws error if call will fail due to non-function': function()
|
||||||
{
|
{
|
||||||
var prop = 'dest',
|
var prop = 'dest',
|
||||||
method = 'foo';
|
method = 'foo';
|
||||||
|
@ -325,7 +333,7 @@ function proxyErrorAssertCommon( e, prop, method )
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// should fail because 'noexist' does not exist on the object
|
// should fail because 'noexist' does not exist on the object
|
||||||
sut.standard.wrapProxy(
|
this._sut.standard.wrapProxy(
|
||||||
prop, null, 0,
|
prop, null, 0,
|
||||||
function() { return { dest: { foo: 'notafunc' } }; },
|
function() { return { dest: { foo: 'notafunc' } }; },
|
||||||
method
|
method
|
||||||
|
@ -333,21 +341,22 @@ function proxyErrorAssertCommon( e, prop, method )
|
||||||
}
|
}
|
||||||
catch ( e )
|
catch ( e )
|
||||||
{
|
{
|
||||||
proxyErrorAssertCommon( e, prop, method );
|
this.proxyErrorAssertCommon( e, prop, method );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.fail(
|
this.assertFail(
|
||||||
"Error should be thrown if proxy would fail due to a non-function"
|
"Error should be thrown if proxy would fail due to a non-function"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the `static' keyword is provided, then the proxy mustn't operate on
|
* If the `static' keyword is provided, then the proxy mustn't operate on
|
||||||
* instance properties. Instead, the static accessor method $() must be used.
|
* instance properties. Instead, the static accessor method $() must be
|
||||||
|
* used.
|
||||||
*/
|
*/
|
||||||
( function testCanProxyToStaticMembers()
|
'Can proxy to static members': function()
|
||||||
{
|
{
|
||||||
var getInst = function()
|
var getInst = function()
|
||||||
{
|
{
|
||||||
|
@ -375,9 +384,12 @@ function proxyErrorAssertCommon( e, prop, method )
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
assert.strictEqual( val,
|
this.assertStrictEqual( val,
|
||||||
sut.standard.wrapProxy( 'foo', null, 0, getInst, 'method', keywords )(),
|
this._sut.standard.wrapProxy(
|
||||||
|
'foo', null, 0, getInst, 'method', keywords
|
||||||
|
)(),
|
||||||
"Should properly proxy to static membesr via static accessor method"
|
"Should properly proxy to static membesr via static accessor method"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
} );
|
||||||
|
|
||||||
|
|
|
@ -21,57 +21,62 @@
|
||||||
* @author Mike Gerwitz
|
* @author Mike Gerwitz
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
require( 'common' ).testCase(
|
||||||
|
{
|
||||||
|
caseSetUp: function()
|
||||||
|
{
|
||||||
|
this.sut = this.require( 'VisibilityObjectFactoryFactory' );
|
||||||
|
|
||||||
var common = require( './common' ),
|
this.VisibilityObjectFactory =
|
||||||
assert = require( 'assert' ),
|
this.require( 'VisibilityObjectFactory' );
|
||||||
util = common.require( 'util' ),
|
|
||||||
|
|
||||||
sut = common.require( 'VisibilityObjectFactoryFactory' ),
|
this.FallbackVisibilityObjectFactory =
|
||||||
|
this.require( 'FallbackVisibilityObjectFactory' );
|
||||||
|
|
||||||
VisibilityObjectFactory = common.require( 'VisibilityObjectFactory' ),
|
this.util = this.require( 'util' );
|
||||||
|
},
|
||||||
FallbackVisibilityObjectFactory =
|
|
||||||
common.require( 'FallbackVisibilityObjectFactory' )
|
|
||||||
;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* By default, if supported by our environment, we should use the standard
|
* By default, if supported by our environment, we should use the standard
|
||||||
* factory to provide proper visibility support.
|
* factory to provide proper visibility support.
|
||||||
*/
|
*/
|
||||||
( function testReturnsStandardIfNotFallingBack()
|
'Returns standard factory if not falling back': function()
|
||||||
{
|
{
|
||||||
// don't bother with the test if we don't support the standard visibility
|
// don't bother with the test if we don't support the standard visibility
|
||||||
// object
|
// object
|
||||||
if ( util.definePropertyFallback() )
|
if ( this.util.definePropertyFallback() )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.ok(
|
this.assertOk(
|
||||||
( sut.fromEnvironment() instanceof VisibilityObjectFactory ),
|
( this.sut.fromEnvironment()
|
||||||
|
instanceof this.VisibilityObjectFactory ),
|
||||||
"Creates standard VisibilityObjectFactory if supported"
|
"Creates standard VisibilityObjectFactory if supported"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If not supported by our environment, we should be permitted to fall back to a
|
* If not supported by our environment, we should be permitted to fall back to a
|
||||||
* working implementation that sacrifices visibility support.
|
* working implementation that sacrifices visibility support.
|
||||||
*/
|
*/
|
||||||
( function testReturnsFallbackFactoryIfFallingBack()
|
'Returns fallback factory if falling back': function()
|
||||||
{
|
{
|
||||||
var old = util.definePropertyFallback();
|
var old = this.util.definePropertyFallback();
|
||||||
|
|
||||||
// force fallback
|
// force fallback
|
||||||
util.definePropertyFallback( true );
|
this.util.definePropertyFallback( true );
|
||||||
|
|
||||||
assert.ok(
|
this.assertOk(
|
||||||
( sut.fromEnvironment() instanceof FallbackVisibilityObjectFactory ),
|
( this.sut.fromEnvironment()
|
||||||
|
instanceof this.FallbackVisibilityObjectFactory
|
||||||
|
),
|
||||||
"Creates fallback VisibilityObjectFactory if falling back"
|
"Creates fallback VisibilityObjectFactory if falling back"
|
||||||
);
|
);
|
||||||
|
|
||||||
// restore fallback
|
// restore fallback
|
||||||
util.definePropertyFallback( old );
|
this.util.definePropertyFallback( old );
|
||||||
} )();
|
},
|
||||||
|
} );
|
||||||
|
|
|
@ -21,23 +21,14 @@
|
||||||
* @author Mike Gerwitz
|
* @author Mike Gerwitz
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
require( 'common' ).testCase(
|
||||||
var common = require( './common' ),
|
|
||||||
assert = require( 'assert' );
|
|
||||||
|
|
||||||
// we cannot perform these tests if it's not supported by our environment
|
|
||||||
if ( common.require( 'util' ).definePropertyFallback() )
|
|
||||||
{
|
{
|
||||||
return;
|
caseSetUp: function()
|
||||||
}
|
{
|
||||||
|
this.Sut = this.require( 'VisibilityObjectFactory' );
|
||||||
// SUT
|
|
||||||
var VisibilityObjectFactory = common.require( 'VisibilityObjectFactory' ),
|
|
||||||
|
|
||||||
sut = VisibilityObjectFactory(),
|
|
||||||
|
|
||||||
// properties are expected to be in a specific format
|
// properties are expected to be in a specific format
|
||||||
props = {
|
this.props = {
|
||||||
'public': {
|
'public': {
|
||||||
pub: [ [ 'foo' ], {} ],
|
pub: [ [ 'foo' ], {} ],
|
||||||
},
|
},
|
||||||
|
@ -47,9 +38,9 @@ var VisibilityObjectFactory = common.require( 'VisibilityObjectFactory' ),
|
||||||
'private': {
|
'private': {
|
||||||
priv: [ [ 'baz' ], {} ],
|
priv: [ [ 'baz' ], {} ],
|
||||||
},
|
},
|
||||||
},
|
};
|
||||||
|
|
||||||
methods = {
|
this.methods = {
|
||||||
'public': {
|
'public': {
|
||||||
fpub: ( function()
|
fpub: ( function()
|
||||||
{
|
{
|
||||||
|
@ -65,8 +56,21 @@ var VisibilityObjectFactory = common.require( 'VisibilityObjectFactory' ),
|
||||||
'private': {
|
'private': {
|
||||||
fpriv: function() {},
|
fpriv: function() {},
|
||||||
},
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
setUp: function()
|
||||||
|
{
|
||||||
|
// we cannot perform these tests if they are not supported by our
|
||||||
|
// environment
|
||||||
|
if ( this.require( 'util' ).definePropertyFallback() )
|
||||||
|
{
|
||||||
|
this.skip();
|
||||||
}
|
}
|
||||||
;
|
|
||||||
|
this.sut = this.Sut();
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,32 +79,33 @@ var VisibilityObjectFactory = common.require( 'VisibilityObjectFactory' ),
|
||||||
*
|
*
|
||||||
* Consistency is key with these sorts of things.
|
* Consistency is key with these sorts of things.
|
||||||
*/
|
*/
|
||||||
( function testCanInstantiateWithAndWithoutNewKeyword()
|
'Can instantiate with and without `new` keyword': function()
|
||||||
{
|
{
|
||||||
// with 'new' keyword
|
// with `new` keyword
|
||||||
assert.ok(
|
this.assertOk(
|
||||||
( new VisibilityObjectFactory() ) instanceof VisibilityObjectFactory,
|
( new this.Sut() ) instanceof this.Sut,
|
||||||
"Should be able to instantiate VisibilityObjectFactory with 'new' " +
|
"Should be able to instantiate VisibilityObjectFactory with " +
|
||||||
"keyword"
|
"'new' keyword"
|
||||||
);
|
);
|
||||||
|
|
||||||
// without 'new' keyword
|
// without `new` keyword
|
||||||
assert.ok( VisibilityObjectFactory() instanceof VisibilityObjectFactory,
|
this.assertOk( this.Sut() instanceof this.Sut,
|
||||||
"Should be able to instantiate VisibilityObjectFactory without 'new' " +
|
"Should be able to instantiate VisibilityObjectFactory without " +
|
||||||
"keyword"
|
"'new' keyword"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* One of the core requirements for proper visibility support is the ability to
|
* One of the core requirements for proper visibility support is the ability
|
||||||
* create a proxy object. Proxy objects transfer gets/sets of a certain property
|
* to create a proxy object. Proxy objects transfer gets/sets of a certain
|
||||||
* to another object. This allows objects to be layered atop each other while
|
* property to another object. This allows objects to be layered atop each
|
||||||
* still permitting gets/sets to fall through.
|
* other while still permitting gets/sets to fall through.
|
||||||
*/
|
*/
|
||||||
( function testCanCreatePropertyProxy()
|
'Can create property proxy': function()
|
||||||
{
|
{
|
||||||
var base = {},
|
var _self = this,
|
||||||
|
base = {},
|
||||||
dest = {},
|
dest = {},
|
||||||
props = { one: true, two: true, three: true },
|
props = { one: true, two: true, three: true },
|
||||||
val = 'foo',
|
val = 'foo',
|
||||||
|
@ -108,7 +113,7 @@ var VisibilityObjectFactory = common.require( 'VisibilityObjectFactory' ),
|
||||||
;
|
;
|
||||||
|
|
||||||
// create proxy of props to base on dest
|
// create proxy of props to base on dest
|
||||||
sut.createPropProxy( base, dest, props );
|
this.sut.createPropProxy( base, dest, props );
|
||||||
|
|
||||||
// check to ensure the properties are properly proxied
|
// check to ensure the properties are properly proxied
|
||||||
for ( var prop in props )
|
for ( var prop in props )
|
||||||
|
@ -116,12 +121,12 @@ var VisibilityObjectFactory = common.require( 'VisibilityObjectFactory' ),
|
||||||
dest[ prop ] = val;
|
dest[ prop ] = val;
|
||||||
|
|
||||||
// check proxy
|
// check proxy
|
||||||
assert.equal( dest[ prop ], val,
|
_self.assertEqual( dest[ prop ], val,
|
||||||
"Property can be set/retrieved on destination object"
|
"Property can be set/retrieved on destination object"
|
||||||
);
|
);
|
||||||
|
|
||||||
// check base
|
// check base
|
||||||
assert.equal( base[ prop ], val,
|
_self.assertEqual( base[ prop ], val,
|
||||||
"Property can be set via proxy and retrieved on base"
|
"Property can be set via proxy and retrieved on base"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -129,29 +134,31 @@ var VisibilityObjectFactory = common.require( 'VisibilityObjectFactory' ),
|
||||||
base[ prop ] = val2;
|
base[ prop ] = val2;
|
||||||
|
|
||||||
// re-check proxy
|
// re-check proxy
|
||||||
assert.equal( dest[ prop ], val2,
|
_self.assertEqual( dest[ prop ], val2,
|
||||||
"Property can be set on base and retrieved on dest object"
|
"Property can be set on base and retrieved on dest object"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An additional layer should be created, which will hold the private members.
|
* An additional layer should be created, which will hold the private
|
||||||
|
* members.
|
||||||
*/
|
*/
|
||||||
( function testSetupCreatesPrivateLayer()
|
'Setup creates private layer': function()
|
||||||
{
|
{
|
||||||
var dest = { foo: [] },
|
var dest = { foo: [] },
|
||||||
obj = sut.setup( dest, props, methods );
|
obj = this.sut.setup( dest, this.props, this.methods );
|
||||||
|
|
||||||
assert.notEqual( obj, dest,
|
this.assertNotEqual( obj, dest,
|
||||||
"Returned object should not be the destination object"
|
"Returned object should not be the destination object"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.strictEqual( obj.foo, dest.foo,
|
this.assertStrictEqual( obj.foo, dest.foo,
|
||||||
"Destination object is part of the prototype chain of the returned obj"
|
"Destination object is part of the prototype chain of the " +
|
||||||
|
"returned obj"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -160,131 +167,131 @@ var VisibilityObjectFactory = common.require( 'VisibilityObjectFactory' ),
|
||||||
* prevent them from being accessed by subtypes if set by a parent method
|
* prevent them from being accessed by subtypes if set by a parent method
|
||||||
* invocation. (The same is true in reverse.)
|
* invocation. (The same is true in reverse.)
|
||||||
*/
|
*/
|
||||||
( function testPrivateLayerIncludesProtectedMemberProxy()
|
'Private layer includes protected member proxy': function()
|
||||||
{
|
{
|
||||||
var dest = {},
|
var dest = {},
|
||||||
obj = sut.setup( dest, props, methods ),
|
obj = this.sut.setup( dest, this.props, this.methods ),
|
||||||
val = 'foo'
|
val = 'foo'
|
||||||
;
|
;
|
||||||
|
|
||||||
obj.prot = val;
|
obj.prot = val;
|
||||||
assert.equal( dest.prot, val,
|
this.assertEqual( dest.prot, val,
|
||||||
"Protected values are proxied from private layer"
|
"Protected values are proxied from private layer"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public properties should be initialized on the destination object to ensure
|
* Public properties should be initialized on the destination object to
|
||||||
* that references are not shared between instances (that'd be a pretty nasty
|
* ensure that references are not shared between instances (that'd be a
|
||||||
* bug).
|
* pretty nasty bug).
|
||||||
*
|
*
|
||||||
* Note that we do not care about public methods, because they're assumed to
|
* Note that we do not care about public methods, because they're assumed to
|
||||||
* already be part of the prototype chain. The visibility object is only
|
* already be part of the prototype chain. The visibility object is only
|
||||||
* intended to handle levels of visibility that are not directly implemented in
|
* intended to handle levels of visibility that are not directly implemented
|
||||||
* JS. Public methods are a direct consequence of adding a property to the
|
* in JS. Public methods are a direct consequence of adding a property to
|
||||||
* prototype chain.
|
* the prototype chain.
|
||||||
*/
|
*/
|
||||||
( function testPublicPropertiesAreCopiedToDestinationObject()
|
'Public properties are copied to destination object': function()
|
||||||
{
|
{
|
||||||
var dest = {};
|
var dest = {};
|
||||||
sut.setup( dest, props, methods );
|
this.sut.setup( dest, this.props, this.methods );
|
||||||
|
|
||||||
// values should match
|
// values should match
|
||||||
assert.equal( dest.pub[ 0 ], props[ 'public' ].pub[ 0 ],
|
this.assertEqual( dest.pub[ 0 ], this.props[ 'public' ].pub[ 0 ],
|
||||||
"Public properties are properly initialized"
|
"Public properties are properly initialized"
|
||||||
);
|
);
|
||||||
|
|
||||||
// ensure references are not shared (should be cloned)
|
// ensure references are not shared (should be cloned)
|
||||||
assert.notStrictEqual( dest.pub, props[ 'public' ].pub,
|
this.assertNotStrictEqual( dest.pub, this.props[ 'public' ].pub,
|
||||||
"Public properties should not be copied by reference"
|
"Public properties should not be copied by reference"
|
||||||
);
|
);
|
||||||
|
|
||||||
// method references should NOT be transferred (they're assumed to already
|
// method references should NOT be transferred (they're assumed to
|
||||||
// be a part of the prototype chain, since they're outside the scope of the
|
// already be a part of the prototype chain, since they're outside the
|
||||||
// visibility object)
|
// scope of the visibility object)
|
||||||
assert.equal( dest.fpub, undefined,
|
this.assertEqual( dest.fpub, undefined,
|
||||||
"Public method references should not be copied"
|
"Public method references should not be copied"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Protected properties should be copied over for the same reason that public
|
* Protected properties should be copied over for the same reason that
|
||||||
* properties should, in addition to the fact that the protected members are not
|
* public properties should, in addition to the fact that the protected
|
||||||
* likely to be present on the destination object. In addition, methods will be
|
* members are not likely to be present on the destination object. In
|
||||||
* copied over.
|
* addition, methods will be copied over.
|
||||||
*/
|
*/
|
||||||
( function testProtectedPropertiesAndMethodsAreAddedToDestinationObject()
|
'Protected properties and methods are added to dest object': function()
|
||||||
{
|
{
|
||||||
var dest = {};
|
var dest = {};
|
||||||
sut.setup( dest, props, methods );
|
this.sut.setup( dest, this.props, this.methods );
|
||||||
|
|
||||||
// values should match
|
// values should match
|
||||||
assert.equal( dest.prot[ 0 ], props[ 'protected' ].prot[ 0 ],
|
this.assertEqual( dest.prot[ 0 ], this.props[ 'protected' ].prot[ 0 ],
|
||||||
"Protected properties are properly initialized"
|
"Protected properties are properly initialized"
|
||||||
);
|
);
|
||||||
|
|
||||||
// ensure references are not shared (should be cloned)
|
// ensure references are not shared (should be cloned)
|
||||||
assert.notStrictEqual( dest.prot, props[ 'protected' ].prot,
|
this.assertNotStrictEqual( dest.prot, this.props[ 'protected' ].prot,
|
||||||
"Protected properties should not be copied by reference"
|
"Protected properties should not be copied by reference"
|
||||||
);
|
);
|
||||||
|
|
||||||
// protected method references should be copied
|
// protected method references should be copied
|
||||||
assert.strictEqual( dest.fprot, methods[ 'protected' ].fprot,
|
this.assertStrictEqual( dest.fprot, this.methods[ 'protected' ].fprot,
|
||||||
"Protected members should be copied by reference"
|
"Protected members should be copied by reference"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public members should *always* take precedence over protected. The reason for
|
* Public members should *always* take precedence over protected. The reason
|
||||||
* this is because, if a protected member is overridden and made public by a
|
* for this is because, if a protected member is overridden and made public
|
||||||
* subtype, we need to ensure that the protected member of the supertype doesn't
|
* by a subtype, we need to ensure that the protected member of the
|
||||||
* take precedence. The reason it would take precedence by default is because
|
* supertype doesn't take precedence. The reason it would take precedence by
|
||||||
* the protected visibility object is laid *atop* the public, meaning it comes
|
* default is because the protected visibility object is laid *atop* the
|
||||||
* first in the prototype chain.
|
* public, meaning it comes first in the prototype chain.
|
||||||
*/
|
*/
|
||||||
( function testPublicMethodsAreNotOverwrittenByProtected()
|
'Public methods are not overwritten by default': function()
|
||||||
{
|
{
|
||||||
// use the public method
|
// use the public method
|
||||||
var dest = { fpub: methods[ 'public' ].fpub };
|
var dest = { fpub: this.methods[ 'public' ].fpub };
|
||||||
|
|
||||||
// add duplicate method to protected
|
// add duplicate method to protected
|
||||||
methods[ 'protected' ].fpub = function() {};
|
this.methods[ 'protected' ].fpub = function() {};
|
||||||
|
|
||||||
sut.setup( dest, props, methods );
|
this.sut.setup( dest, this.props, this.methods );
|
||||||
|
|
||||||
// ensure our public method is still referenced
|
// ensure our public method is still referenced
|
||||||
assert.strictEqual( dest.fpub, methods[ 'public' ].fpub,
|
this.assertStrictEqual( dest.fpub, this.methods[ 'public' ].fpub,
|
||||||
"Public methods should not be overwritten by protected methods"
|
"Public methods should not be overwritten by protected methods"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same situation with private members as protected, with the exception that we
|
* Same situation with private members as protected, with the exception that
|
||||||
* do not need to worry about the overlay problem (in regards to methods). This
|
* we do not need to worry about the overlay problem (in regards to
|
||||||
* is simply because private members are not inherited.
|
* methods). This is simply because private members are not inherited.
|
||||||
*/
|
*/
|
||||||
( function testPrivatePropertiesAndMethodsAreAddedToDestinationObject()
|
'Private properties and methods are added to dest object': function()
|
||||||
{
|
{
|
||||||
var dest = {},
|
var dest = {},
|
||||||
obj = sut.setup( dest, props, methods );
|
obj = this.sut.setup( dest, this.props, this.methods );
|
||||||
|
|
||||||
// values should match
|
// values should match
|
||||||
assert.equal( obj.priv[ 0 ], props[ 'private' ].priv[ 0 ],
|
this.assertEqual( obj.priv[ 0 ], this.props[ 'private' ].priv[ 0 ],
|
||||||
"Private properties are properly initialized"
|
"Private properties are properly initialized"
|
||||||
);
|
);
|
||||||
|
|
||||||
// ensure references are not shared (should be cloned)
|
// ensure references are not shared (should be cloned)
|
||||||
assert.notStrictEqual( obj.priv, props[ 'private' ].priv,
|
this.assertNotStrictEqual( obj.priv, this.props[ 'private' ].priv,
|
||||||
"Private properties should not be copied by reference"
|
"Private properties should not be copied by reference"
|
||||||
);
|
);
|
||||||
|
|
||||||
// private method references should be copied
|
// private method references should be copied
|
||||||
assert.strictEqual( obj.fpriv, methods[ 'private' ].fpriv,
|
this.assertStrictEqual( obj.fpriv, this.methods[ 'private' ].fpriv,
|
||||||
"Private members should be copied by reference"
|
"Private members should be copied by reference"
|
||||||
);
|
);
|
||||||
} )();
|
},
|
||||||
|
} );
|
||||||
|
|
Loading…
Reference in New Issue