1
0
Fork 0

Add Store#populate

* src/store/DiffStore.js (populate): Add method.
* src/store/MemoryStore.js (populate): Add method.
* src/store/Store.js (populate): Add abstract method.
* test/store/DiffStoreTest.js: Add populate tests.
* test/store/MemoryStoreTest.js: Add populate tests.
master
Mike Gerwitz 2017-08-24 14:27:01 -04:00
parent 2a9920cbb7
commit edce23f14b
5 changed files with 163 additions and 4 deletions

View File

@ -132,6 +132,31 @@ module.exports = Class( 'DiffStore' )
},
/**
* Populate store with each element in object `obj`
*
* This is simply a convenient way to call `#add` for each element in an
* object. This does directly call `#add`, so overriding that method
* will also affect this one.
*
* If the intent is to change the behavior of what happens when an item
* is added to the store, override the `#add` method instead of this one
* so that it affects _all_ adds, not just calls to this method.
*
* @param {Object} obj object with which to populate store
*
* @return {Array.<Promise.<Store>>} array of #add promises
*/
'virtual public populate'( obj )
{
return Promise.all(
Object.keys( obj ).map(
key => this.add( key, obj[ key ] )
)
);
},
/**
* Retrieve diff of `key`
*

View File

@ -89,6 +89,31 @@ module.exports = Class( 'MemoryStore' )
},
/**
* Populate store with each element in object `obj`
*
* This is simply a convenient way to call `#add` for each element in an
* object. This does directly call `#add`, so overriding that method
* will also affect this one.
*
* If the intent is to change the behavior of what happens when an item
* is added to the store, override the `#add` method instead of this one
* so that it affects _all_ adds, not just calls to this method.
*
* @param {Object} obj object with which to populate store
*
* @return {Array.<Promise.<Store>>} array of #add promises
*/
'virtual public populate'( obj )
{
return Promise.all(
Object.keys( obj ).map(
key => this.add( key, obj[ key ] )
)
);
},
/**
* Retrieve item from store under `key`
*

View File

@ -1,7 +1,7 @@
/**
* Generic key/value store
*
* Copyright (C) 2016 R-T Specialty, LLC.
* Copyright (C) 2016, 2017 R-T Specialty, LLC.
*
* This file is part of the Liza Data Collection Framework
*
@ -50,6 +50,24 @@ module.exports = Interface( 'Store',
'public add': [ 'key', 'value' ],
/**
* Populate store with each element in object `obj`
*
* This is simply a convenient way to call `#add` for each element in an
* object. This does directly call `#add`, so overriding that method
* will also affect this one.
*
* If the intent is to change the behavior of what happens when an item
* is added to the store, override the `#add` method instead of this one
* so that it affects _all_ adds, not just calls to this method.
*
* @param {Object} obj object with which to populate store
*
* @return {Array.<Promise.<Store>>} array of #add promises
*/
'public populate': [ 'obj' ],
/**
* Retrieve item from store under `key`
*

View File

@ -232,4 +232,39 @@ describe( 'store.DiffStore', () =>
} );
} );
} );
describe( '#populate', () =>
{
it( "#add's each element of object to store", () =>
{
const obj = { foo: {}, bar: {} };
const sut = Sut();
return sut.populate( obj )
.then( ps =>
{
// by reference
expect( sut.get( 'foo' ) )
.to.eventually.equal( obj.foo );
expect( sut.get( 'bar' ) )
.to.eventually.equal( obj.bar );
expect( ps.length )
.to.equal( Object.keys( obj ).length );
} );
} );
it( "fails if any add fails", () =>
{
const e = Error( 'ok' );
const sut = Sut.extend( {
'override add': ( k, v ) => Promise.reject( e )
} )();
return expect( sut.populate( { a: 1 } ) )
.to.eventually.be.rejectedWith( e );
} );
} );
} );

View File

@ -71,6 +71,41 @@ describe( 'store.MemoryStore', () =>
} );
describe( '#populate', () =>
{
it( "#add's each element of object to store", () =>
{
const obj = { foo: {}, bar: {} };
const sut = Sut();
return sut.populate( obj )
.then( ps =>
{
// by reference
expect( sut.get( 'foo' ) )
.to.eventually.equal( obj.foo );
expect( sut.get( 'bar' ) )
.to.eventually.equal( obj.bar );
expect( ps.length )
.to.equal( Object.keys( obj ).length );
} );
} );
it( "fails if any add fails", () =>
{
const e = Error( 'ok' );
const sut = Sut.extend( {
'override add': ( k, v ) => Promise.reject( e )
} )();
return expect( sut.populate( { a: 1 } ) )
.to.eventually.be.rejectedWith( e );
} );
} );
// most things implicitly tested above
describe( '#get', () =>
{
@ -118,7 +153,7 @@ describe( 'store.MemoryStore', () =>
describe( 'with mixin', () =>
{
it( 'allows overriding add', done =>
it( 'allows overriding #add', done =>
{
const expected_key = 'foo';
const expected_value = {};
@ -137,7 +172,28 @@ describe( 'store.MemoryStore', () =>
} );
it( 'allows overriding get', done =>
it( "allows overriding #populate", () =>
{
const obj = {};
let called = false;
return Sut.use(
Trait.extend( Sut,
{
'override populate'( given )
{
expect( given ).to.equal( obj );
called = true;
return Promise.resolve( true );
}
} )
)().populate( obj )
.then( () => expect( called ).to.equal( true ) );
} );
it( 'allows overriding #get', done =>
{
const expected_key = 'bar';
@ -154,7 +210,7 @@ describe( 'store.MemoryStore', () =>
} );
it( 'allows overriding clear', done =>
it( 'allows overriding #clear', done =>
{
Sut.use(
Trait.extend( Sut,