Interface.isInstanceOf now accounts for interface interop
More information in the merged commit message.textend
commit
bbfac76c34
|
@ -500,7 +500,7 @@ function _isInstanceOf( type, instance )
|
||||||
var meta;
|
var meta;
|
||||||
if ( !instance.__cid || !( meta = ClassBuilder.getMeta( proto ) ) )
|
if ( !instance.__cid || !( meta = ClassBuilder.getMeta( proto ) ) )
|
||||||
{
|
{
|
||||||
return false;
|
return isCompat( type, instance );
|
||||||
}
|
}
|
||||||
|
|
||||||
var implemented = meta.implemented,
|
var implemented = meta.implemented,
|
||||||
|
|
|
@ -23,13 +23,26 @@ require( 'common' ).testCase(
|
||||||
{
|
{
|
||||||
caseSetUp: function()
|
caseSetUp: function()
|
||||||
{
|
{
|
||||||
this.Sut = this.require( 'interface' );
|
this.Sut = this.require( 'interface' );
|
||||||
|
this.Class = this.require( 'class' );
|
||||||
|
|
||||||
this.I = this.Sut(
|
this.I = this.Sut(
|
||||||
{
|
{
|
||||||
foo: [ 'a', 'b' ],
|
foo: [ 'a', 'b' ],
|
||||||
bar: [ 'a' ],
|
bar: [ 'a' ],
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
this.assertICompat = function( I, inst )
|
||||||
|
{
|
||||||
|
this.assertOk( I.isCompatible( inst ) );
|
||||||
|
this.assertOk( this.Sut.isInstanceOf( I, inst ) );
|
||||||
|
};
|
||||||
|
|
||||||
|
this.assertNotICompat = function( I, inst )
|
||||||
|
{
|
||||||
|
this.assertOk( !I.isCompatible( inst ) );
|
||||||
|
this.assertOk( !this.Sut.isInstanceOf( I, inst ) );
|
||||||
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,12 +81,14 @@ require( 'common' ).testCase(
|
||||||
bar: function( a ) {},
|
bar: function( a ) {},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var p = new P();
|
||||||
|
|
||||||
// instance should therefore be conforming
|
// instance should therefore be conforming
|
||||||
this.assertOk( this.I.isCompatible( new P() ) );
|
this.assertICompat( this.I, p );
|
||||||
|
|
||||||
// ah but why stop there? (note that this implies that *any* object,
|
// ah but why stop there? (note that this implies that *any* object,
|
||||||
// prototype or not, can conform to an interface)
|
// prototype or not, can conform to an interface)
|
||||||
this.assertOk( this.I.isCompatible( P.prototype ) );
|
this.assertICompat( this.I, P.prototype );
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,8 +104,8 @@ require( 'common' ).testCase(
|
||||||
foo: function( a, b ) {},
|
foo: function( a, b ) {},
|
||||||
};
|
};
|
||||||
|
|
||||||
this.assertOk( !( this.I.isCompatible( new P() ) ) );
|
this.assertNotICompat( this.I, new P() );
|
||||||
this.assertOk( !( this.I.isCompatible( P.prototype ) ) );
|
this.assertNotICompat( this.I, P.prototype );
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
@ -111,7 +126,7 @@ require( 'common' ).testCase(
|
||||||
var obj = { foo: function( a ) {} },
|
var obj = { foo: function( a ) {} },
|
||||||
I = this.Sut( { foo: [ 'a', 'b' ] } );
|
I = this.Sut( { foo: [ 'a', 'b' ] } );
|
||||||
|
|
||||||
this.assertOk( !( I.isCompatible( obj ) ) );
|
this.assertNotICompat( I, obj );
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,7 +139,7 @@ require( 'common' ).testCase(
|
||||||
var obj = { foo: function( a, b, c ) {} },
|
var obj = { foo: function( a, b, c ) {} },
|
||||||
I = this.Sut( { foo: [ 'a', 'b' ] } );
|
I = this.Sut( { foo: [ 'a', 'b' ] } );
|
||||||
|
|
||||||
this.assertOk( I.isCompatible( obj ) );
|
this.assertICompat( I, obj );
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
@ -137,7 +152,7 @@ require( 'common' ).testCase(
|
||||||
var obj = { foo: {} },
|
var obj = { foo: {} },
|
||||||
I = this.Sut( { foo: [] } );
|
I = this.Sut( { foo: [] } );
|
||||||
|
|
||||||
this.assertOk( !( I.isCompatible( obj ) ) );
|
this.assertNotICompat( I, obj );
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
@ -151,7 +166,44 @@ require( 'common' ).testCase(
|
||||||
var obj = { foo: function() {}, bar: function() {} },
|
var obj = { foo: function() {}, bar: function() {} },
|
||||||
I = this.Sut( { foo: [] } );
|
I = this.Sut( { foo: [] } );
|
||||||
|
|
||||||
this.assertOk( I.isCompatible( obj ) );
|
this.assertICompat( I, obj );
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When an object is instantiated from an ease.js class, it does not
|
||||||
|
* matter if the interface is compatible: in order to be considered an
|
||||||
|
* instance some interface I, the instance's type must implement I; in
|
||||||
|
* this sense, ease.js' interface typing is strict, allowing *intent* to
|
||||||
|
* be conveyed.
|
||||||
|
*
|
||||||
|
* An example of why this is important can be found in the
|
||||||
|
* interoperability section of the manual.
|
||||||
|
*/
|
||||||
|
'Objects can be compatible but not instances of interface': function()
|
||||||
|
{
|
||||||
|
// same API, different interface objects
|
||||||
|
var Ia = this.Sut( { foo: [] } ),
|
||||||
|
Ib = this.Sut( { foo: [] } );
|
||||||
|
|
||||||
|
var dfn = { foo: function() {} },
|
||||||
|
Ca = this.Class.implement( Ia ).extend( dfn ),
|
||||||
|
Cb = this.Class.implement( Ib ).extend( dfn );
|
||||||
|
|
||||||
|
var ia = Ca(),
|
||||||
|
ib = Cb();
|
||||||
|
|
||||||
|
// clearly the two are compatible, regardless of their type
|
||||||
|
this.assertOk( Ia.isCompatible( ia ) );
|
||||||
|
this.assertOk( Ia.isCompatible( ib ) );
|
||||||
|
this.assertOk( Ib.isCompatible( ia ) );
|
||||||
|
this.assertOk( Ib.isCompatible( ib ) );
|
||||||
|
|
||||||
|
// but ia is *not* an instance of Ib, nor ib of Ia
|
||||||
|
this.assertOk( this.Sut.isInstanceOf( Ia, ia ) );
|
||||||
|
this.assertOk( !this.Sut.isInstanceOf( Ia, ib ) );
|
||||||
|
this.assertOk( this.Sut.isInstanceOf( Ib, ib ) );
|
||||||
|
this.assertOk( !this.Sut.isInstanceOf( Ib, ia ) );
|
||||||
},
|
},
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue