base-domain
Version:
simple module to help build Domain-Driven Design
401 lines (264 loc) • 12.3 kB
text/coffeescript
facade = require('../create-facade').create()
Facade = facade.constructor
BaseDict = facade.constructor.BaseDict
hobbies = null
describe 'BaseDict', ->
before ->
class Hobby extends Facade.Entity
:
name: .STRING
class NonEntity extends Facade.BaseModel
:
name: .STRING
class HobbyRepository extends Facade.MasterRepository
: 'hobby'
facade.addClass 'hobby', Hobby
facade.addClass 'non-entity', NonEntity
facade.addClass('hobby-repository', HobbyRepository)
hobbyFactory = facade.createFactory('hobby', true)
hobbies = (for name, i in ['keyboard', 'jogging', 'cycling']
hobbyFactory.createFromObject id: 3 - i, name: name
)
it '"loaded", "listeners" and "itemFactory" are hidden properties whereas items is explicit', ->
class HobbyDict extends BaseDict
: -> facade
getFacade: -> facade
: 'hobby'
hobbyDict = new HobbyDict(items: hobbies)
explicitKeys = Object.keys(hobbyDict)
expect(explicitKeys).to.have.length 1
expect(explicitKeys).to.contain 'items'
expect(explicitKeys).not.to.contain 'listeners'
expect(explicitKeys).not.to.contain 'loaded'
expect(explicitKeys).not.to.contain 'itemFactory'
it 'itemFactory is hidden properties, created once referred', ->
class HobbyDict extends BaseDict
: -> facade
getFacade: -> facade
: 'hobby'
hobbyDict = new HobbyDict(items: hobbies)
itemFactory = hobbyDict.itemFactory
expect(itemFactory).to.be.instanceof Facade.BaseFactory
expect(itemFactory).to.equal hobbyDict.itemFactory
it 'can contain custom properties', ->
class HobbyDict extends BaseDict
: -> facade
getFacade: -> facade
: 'hobby'
:
annualCost: .NUMBER
hobbyDict = new HobbyDict(items: hobbies, annualCost: 2000)
expect(hobbyDict).to.have.property 'annualCost', 2000
explicitKeys = Object.keys(hobbyDict)
expect(explicitKeys).to.contain 'annualCost'
describe '@keys', ->
it 'originally returns item.id', ->
class HobbyDict extends BaseDict
: -> facade
getFacade: -> facade
: 'hobby'
dict = new HobbyDict().setItems(hobbies)
expect(dict.ids).to.eql [1,2,3]
describe 'ids', ->
class HobbyDict extends BaseDict
: -> facade
getFacade: -> facade
: 'hobby'
class NonEntityDict extends BaseDict
: -> facade
getFacade: -> facade
: 'non-entity'
it 'get array when the item is Entity', ->
hobbyDict = new HobbyDict()
expect(hobbyDict.ids).to.be.instanceof Array
it 'get null when the item is not Entity', ->
nonEntityDict = new NonEntityDict()
expect(nonEntityDict.ids).to.be.null
it 'get array of ids when the item is Entity', ->
hobbyDict = new HobbyDict(items: hobbies)
expect(hobbyDict.ids).to.deep.equal [1, 2, 3]
describe 'toArray', ->
it 'returns deeply-equal array to items', ->
class HobbyDict extends BaseDict
: -> facade
getFacade: -> facade
: 'hobby'
hobbyDict = new HobbyDict(items: hobbies)
arr = hobbyDict.toArray()
expect(arr).to.have.length 3
for hobby in arr
expect(hobbies).to.include hobby
describe "on('loaded')", ->
it 'loaded after loaded when ids is given in constructor', (done) ->
class HobbyDict extends BaseDict
: -> facade
getFacade: -> facade
: 'hobby'
hobbyDict = new HobbyDict(ids: ['dummy'])
expect(hobbyDict.loaded).to.be.false
expect(hobbyDict.items).not.to.have.property 'dummy'
expect(hobbyDict.ids).to.have.length 0
hobbyDict.on 'loaded', ->
expect(hobbyDict.loaded).to.be.true
expect(hobbyDict.items).to.have.property 'dummy'
done()
it 'executed after event registered when array is given in constructor', (done) ->
class HobbyDict extends BaseDict
: -> facade
getFacade: -> facade
: 'hobby'
hobbyDict = new HobbyDict(items: hobbies)
hobbyDict.on 'loaded', ->
expect(hobbyDict.loaded).to.be.true
expect(hobbyDict.items).to.have.property 1
expect(hobbyDict.items).to.have.property 2
expect(hobbyDict.items).to.have.property 3
done()
describe 'toPlainObject', ->
it 'returns object with ids when item is entity', ->
class HobbyDict extends BaseDict
: -> facade
getFacade: -> facade
: 'hobby'
hobbyDict = new HobbyDict(items: hobbies)
plain = hobbyDict.toPlainObject()
expect(plain).to.have.property 'ids'
expect(plain).not.to.have.property 'items'
it 'returns object with items when item is non-entity', ->
class NonEntityDict extends BaseDict
: -> facade
getFacade: -> facade
: 'non-entity'
nonEntityFactory = facade.createFactory('non-entity', true)
nonEntities = (for name, i in ['keyboard', 'jogging', 'cycling']
nonEntityFactory.createFromObject id: 3 - i, name: name
)
nonEntityDict = new NonEntityDict(items: nonEntities)
plain = nonEntityDict.toPlainObject()
expect(plain).not.to.have.property 'ids'
expect(plain).to.have.property 'items'
expect(plain.items).to.have.property 1
expect(plain.items).to.have.property 2
expect(plain.items).to.have.property 3
it 'returns object with custom properties', ->
class HobbyDict extends BaseDict
: -> facade
getFacade: -> facade
: 'hobby'
:
annualCost: .NUMBER
hobbyDict = new HobbyDict(items: hobbies, annualCost: 2000)
expect(hobbyDict.toPlainObject()).to.have.property 'ids'
expect(hobbyDict.toPlainObject()).to.have.property 'annualCost'
describe 'setIds', ->
class Commodity extends Facade.Entity
:
name: .STRING
class CommodityRepository extends Facade.BaseRepository
: 'commodity'
query: (params) ->
ids = params.where.id.inq
items = [{id: 1, name: 'pencil'}, {id: 2, name: 'toothbrush'}, {id: 3, name: 'potatochips'}]
Promise.resolve (.createFromObject(item) for item in items when item.id in ids)
facade.addClass('commodity', Commodity)
facade.addClass('commodity-repository', CommodityRepository)
it 'can load data by ids synchronously from MasterRepository', (done) ->
class HobbyDict extends BaseDict
: -> facade
getFacade: -> facade
: 'hobby'
HobbyRepository = facade.getRepository 'hobby'
HobbyRepository.load().then ->
dict = new HobbyDict()
dict.setIds(['dummy'])
expect(dict.loaded).to.be.true
expect(dict.items).to.have.property 'dummy'
done()
.catch done
it 'loads data by ids asynchronously from non-MasterRepository', (done) ->
class CommodityDict extends BaseDict
: -> facade
getFacade: -> facade
: 'commodity'
dict = new CommodityDict()
dict.setIds([2, 3])
expect(dict.loaded).to.be.false
expect(dict.items).to.eql {}
dict.on 'loaded', ->
expect(dict.loaded).to.be.true
expect(dict.items).not.to.have.property 1
expect(dict.items).to.have.property 2
expect(dict.items).to.have.property 3
done()
describe 'has', ->
before ->
class HobbyDict extends BaseDict
: -> facade
getFacade: -> facade
: 'hobby'
: (item) -> item.name
= new HobbyDict(items: hobbies)
it 'returns true when item exists', ->
expect(.has('keyboard')).to.be.true
it 'returns false when item does not exist', ->
expect(.has('sailing')).to.be.false
describe 'contains', ->
before ->
class HobbyDict extends BaseDict
: -> facade
getFacade: -> facade
: 'hobby'
: (item) -> item.name
= new HobbyDict(items: hobbies)
it 'returns true when item exists', ->
expect(.contains(hobbies[0])).to.be.true
it 'returns false when item does not exist', ->
newHobby = facade.createFactory('hobby').createFromObject id: 4, name: 'xxx'
expect(.has(newHobby)).to.be.false
it 'returns false when item with same key exists but these two are different', ->
newHobby = facade.createFactory('hobby').createFromObject id: 4, name: 'keyboard'
expect(.has(newHobby)).to.be.false
describe 'get', ->
before ->
class HobbyDict extends BaseDict
: -> facade
getFacade: -> facade
: 'hobby'
: (item) -> item.name
= new HobbyDict(items: hobbies)
it 'returns submodel when key exists', ->
expect(.get('keyboard')).to.be.instanceof facade.getModel('hobby')
it 'returns undefined when key does not exist', ->
expect(.get('xxx')).to.be.undefined
describe 'add', ->
before ->
class HobbyDict extends BaseDict
: -> facade
getFacade: -> facade
: 'hobby'
: (item) -> item.name
= new HobbyDict(items: hobbies)
it 'add item model', ->
newHobby = facade.createFactory('hobby').createFromObject id: 4, name: 'xxx'
.add(newHobby)
expect(.items.xxx).to.be.instanceof facade.getModel 'hobby'
it 'does not add non-item model', ->
newHobby = id: 4, name: 'yyyy'
.add(newHobby)
expect(.items.yyyy).not.to.exist
describe 'remove', ->
beforeEach ->
class HobbyDict extends BaseDict
: -> facade
getFacade: -> facade
: 'hobby'
: (item) -> item.name
= new HobbyDict(items: hobbies)
it 'removes by key', ->
.remove('keyboard')
expect(.items.keyboard).not.to.exist
it 'removes by item', ->
.remove(hobbies[0])
expect(.items.keyboard).not.to.exist
it 'do nothing if no key exists', ->
.remove('xxx')