Skip to content

Commit

Permalink
Merge pull request #193 from deepstreamIO/bug/#138-initial-subscribe-…
Browse files Browse the repository at this point in the history
…value

Bug/#138 initial subscribe value
  • Loading branch information
yasserf committed Jul 28, 2016
2 parents 5369db1 + f95403b commit aebca26
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 53 deletions.
6 changes: 3 additions & 3 deletions src/record/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ List.prototype._hasIndex = function( index ) {

/**
* Establishes the current structure of the list, provided the client has attached any
* add / move / remove listener
* add / move / remove listener
*
* This will be called before any change to the list, regardsless if the change was triggered
* by an incoming message from the server or by the client
Expand Down Expand Up @@ -332,7 +332,7 @@ List.prototype._afterChange = function() {
}
}
}

if( this._hasAddListener || this._hasMoveListener ) {
for( entry in after ) {
if( before[ entry ] === undefined ) {
Expand Down Expand Up @@ -361,7 +361,7 @@ List.prototype._afterChange = function() {
* {
* 'recordA': [ 0, 3 ],
* 'recordB': [ 1 ],
* 'recordC': [ 2 ]
* 'recordC': [ 2 ]
* }
*
* @private
Expand Down
19 changes: 11 additions & 8 deletions src/record/record.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,17 @@ Record.prototype.subscribe = function( path, callback, triggerNow ) {
return;
}

this._eventEmitter.on( args.path || ALL_EVENT, args.callback );

if( args.triggerNow && this.isReady ) {
if( args.path ) {
args.callback( this._getPath( args.path ).getValue() );
} else {
args.callback( this._$data );
}
if( args.triggerNow ) {
this.whenReady(function () {
this._eventEmitter.on( args.path || ALL_EVENT, args.callback );
if( args.path ) {
args.callback( this._getPath( args.path ).getValue() );
} else {
args.callback( this._$data );
}
}.bind(this));
} else {
this._eventEmitter.on( args.path || ALL_EVENT, args.callback );
}
};

Expand Down
110 changes: 68 additions & 42 deletions test-e2e/specs/recordSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,32 @@ describe( 'record', function() {

/**************** TEST ****************/
it( 'subscribes and sets a record', function(done) {
clientA.record.getRecord( 'record1' ).subscribe( 'user.firstname', function( firstname ){
expect( firstname ).toBe( 'Wolfram' );
done();
});
var clientARecord = clientA.record.getRecord( 'record1' );
var clientBRecord = clientB.record.getRecord( 'record1' );

var immediateSubscribeCalled = false;
function immediateSubscribe( data ) {
clientARecord.unsubscribe( immediateSubscribe );
immediateSubscribeCalled = true;
expect( data ).toEqual( {} );
}
expect( clientARecord.isReady ).toBe( false );
clientARecord.subscribe( immediateSubscribe, true );
expect( immediateSubscribeCalled ).toBe( false );

var update = 1;
clientARecord.subscribe( 'user.firstname', function( firstname ){
if( update === 1 ) {
expect( firstname ).toBeUndefined();
} else if( update === 2 ) {
expect( firstname ).toBe( 'Wolfram' );
expect( immediateSubscribeCalled ).toBe( true );
done();
}
update++;
}, true);

clientB.record.getRecord( 'record1' ).set({
clientBRecord.set({
user: {
firstname: 'Wolfram',
lastname: 'Hempel'
Expand Down Expand Up @@ -88,71 +108,77 @@ describe( 'record', function() {
});

it( 'setting a branch path to undefined deletes everything under it', function( done ) {
clientB.record.getRecord( 'record1' ).set( 'objectToDelete', { deleteMe: { key: 'value' } } );
expect( clientB.record.getRecord( 'record1' ).get( 'objectToDelete' ) ).toEqual( { deleteMe: { key: 'value' } } );
var clientARecord = clientA.record.getRecord( 'record1' );
var clientBRecord = clientB.record.getRecord( 'record1' );

clientBRecord.set( 'objectToDelete', { deleteMe: { key: 'value' } } );
expect( clientBRecord.get( 'objectToDelete' ) ).toEqual( { deleteMe: { key: 'value' } } );

setTimeout( function(){
var subscribePath = function( value ){
function subscribePath( value ){
expect( value ).toBeUndefined();
};
clientA.record.getRecord( 'record1' ).subscribe( 'objectToDelete', subscribePath );
clientB.record.getRecord( 'record1' ).subscribe( 'objectToDelete', subscribePath );
clientARecord.subscribe( 'objectToDelete', subscribePath );
clientBRecord.subscribe( 'objectToDelete', subscribePath );

var subscribeObject = function( value ) {
function subscribeObject( value ) {
expect( value ).toEqual( { user: { firstname: 'Wolfram', lastname: 'Hempel' } } );
};
clientA.record.getRecord( 'record1' ).subscribe( subscribeObject );
clientB.record.getRecord( 'record1' ).subscribe( subscribeObject );
clientARecord.subscribe( subscribeObject );
clientBRecord.subscribe( subscribeObject );

expect( clientA.record.getRecord( 'record1' ).get( 'objectToDelete' ) ).toEqual( { deleteMe: { key: 'value' } } );
expect( clientARecord.get( 'objectToDelete' ) ).toEqual( { deleteMe: { key: 'value' } } );

clientB.record.getRecord( 'record1' ).set( 'objectToDelete', undefined );
expect( clientB.record.getRecord( 'record1' ).get( 'objectToDelete' ) ).toBeUndefined();
expect( clientB.record.getRecord( 'record1' ).get() ).toEqual( { user: { firstname: 'Wolfram', lastname: 'Hempel' } } );
expect( clientA.record.getRecord( 'record1' ).get() ).toEqual( { user: { firstname: 'Wolfram', lastname: 'Hempel' }, objectToDelete: { deleteMe: { key: 'value' } } } );
clientBRecord.set( 'objectToDelete', undefined );
expect( clientBRecord.get( 'objectToDelete' ) ).toBeUndefined();
expect( clientBRecord.get() ).toEqual( { user: { firstname: 'Wolfram', lastname: 'Hempel' } } );
expect( clientARecord.get() ).toEqual( { user: { firstname: 'Wolfram', lastname: 'Hempel' }, objectToDelete: { deleteMe: { key: 'value' } } } );

setTimeout(function(){
expect( clientA.record.getRecord( 'record1' ).get() ).toEqual( { user: { firstname: 'Wolfram', lastname: 'Hempel' } } );
expect( clientARecord.get() ).toEqual( { user: { firstname: 'Wolfram', lastname: 'Hempel' } } );

clientA.record.getRecord( 'record1' ).unsubscribe( 'objectToDelete', subscribePath );
clientA.record.getRecord( 'record1' ).unsubscribe( subscribeObject );
clientB.record.getRecord( 'record1' ).unsubscribe( 'objectToDelete', subscribePath );
clientB.record.getRecord( 'record1' ).unsubscribe( subscribeObject );
clientARecord.unsubscribe( 'objectToDelete', subscribePath );
clientARecord.unsubscribe( subscribeObject );
clientBRecord.unsubscribe( 'objectToDelete', subscribePath );
clientBRecord.unsubscribe( subscribeObject );
done();
}, 20 );
}, 20 );
});

it( 'setting a array index to undefined sets it as undefined', function( done ) {
clientB.record.getRecord( 'record1' ).set( 'arrayToDeleteFrom', [ {}, {}, {}, {} ] );
expect( clientB.record.getRecord( 'record1' ).get( 'arrayToDeleteFrom' ) ).toEqual( [ {}, {}, {}, {} ] );
var clientARecord = clientA.record.getRecord( 'record1' );
var clientBRecord = clientB.record.getRecord( 'record1' );

clientBRecord.set( 'arrayToDeleteFrom', [ {}, {}, {}, {} ] );
expect( clientBRecord.get( 'arrayToDeleteFrom' ) ).toEqual( [ {}, {}, {}, {} ] );

setTimeout( function(){
var subscribePath = function( value ){
function subscribePath( value ){
expect( value ).toEqual( [ {}, {}, null, {} ] );
};
clientA.record.getRecord( 'record1' ).subscribe( 'arrayToDeleteFrom', subscribePath );
clientB.record.getRecord( 'record1' ).subscribe( 'arrayToDeleteFrom', subscribePath );
clientARecord.subscribe( 'arrayToDeleteFrom', subscribePath );
clientBRecord.subscribe( 'arrayToDeleteFrom', subscribePath );

var subscribeObject = function( value ) {
function subscribeObject( value ) {
expect( value ).toEqual( { user: { firstname: 'Wolfram', lastname: 'Hempel' }, arrayToDeleteFrom: [ {}, {}, null, {} ] } );
};
clientA.record.getRecord( 'record1' ).subscribe( subscribeObject );
clientB.record.getRecord( 'record1' ).subscribe( subscribeObject );
clientARecord.subscribe( subscribeObject );
clientBRecord.subscribe( subscribeObject );

expect( clientA.record.getRecord( 'record1' ).get( 'arrayToDeleteFrom' ) ).toEqual( [ {}, {}, {}, {} ] );
expect( clientARecord.get( 'arrayToDeleteFrom' ) ).toEqual( [ {}, {}, {}, {} ] );

clientB.record.getRecord( 'record1' ).set( 'arrayToDeleteFrom.2', undefined );
expect( clientB.record.getRecord( 'record1' ).get( 'arrayToDeleteFrom' ) ).toEqual( [ {}, {}, null, {} ] );
expect( clientB.record.getRecord( 'record1' ).get() ).toEqual( { user: { firstname: 'Wolfram', lastname: 'Hempel' }, arrayToDeleteFrom: [ {}, {}, null, {} ] } );
expect( clientA.record.getRecord( 'record1' ).get() ).toEqual( { user: { firstname: 'Wolfram', lastname: 'Hempel' }, arrayToDeleteFrom: [ {}, {}, {}, {} ] } );
clientBRecord.set( 'arrayToDeleteFrom.2', undefined );
expect( clientBRecord.get( 'arrayToDeleteFrom' ) ).toEqual( [ {}, {}, null, {} ] );
expect( clientBRecord.get() ).toEqual( { user: { firstname: 'Wolfram', lastname: 'Hempel' }, arrayToDeleteFrom: [ {}, {}, null, {} ] } );
expect( clientARecord.get() ).toEqual( { user: { firstname: 'Wolfram', lastname: 'Hempel' }, arrayToDeleteFrom: [ {}, {}, {}, {} ] } );

setTimeout(function(){
expect( clientA.record.getRecord( 'record1' ).get() ).toEqual( { user: { firstname: 'Wolfram', lastname: 'Hempel' }, arrayToDeleteFrom: [ {}, {}, null, {} ] } );
clientA.record.getRecord( 'record1' ).unsubscribe( 'objectToDelete', subscribePath );
clientA.record.getRecord( 'record1' ).unsubscribe( subscribeObject );
clientB.record.getRecord( 'record1' ).unsubscribe( 'objectToDelete', subscribePath );
clientB.record.getRecord( 'record1' ).unsubscribe( subscribeObject );
expect( clientARecord.get() ).toEqual( { user: { firstname: 'Wolfram', lastname: 'Hempel' }, arrayToDeleteFrom: [ {}, {}, null, {} ] } );
clientARecord.unsubscribe( 'objectToDelete', subscribePath );
clientARecord.unsubscribe( subscribeObject );
clientBRecord.unsubscribe( 'objectToDelete', subscribePath );
clientBRecord.unsubscribe( subscribeObject );
done();
}, 20 );
}, 20 );
Expand Down Expand Up @@ -276,4 +302,4 @@ describe( 'record', function() {
deepstreamServer.on( 'stopped', done );
deepstreamServer.stop();
});
});
});

0 comments on commit aebca26

Please sign in to comment.