import {Trait, traits} from '@avocado/traits'; import {Latus} from '@latus/core'; import {expect} from 'chai'; let latus; let Entity; beforeEach(async () => { latus = Latus.mock({ '@avocado/entity': require('../src'), '@avocado/resource': require('@avocado/resource'), '@avocado/traits': require('@avocado/traits'), }); await Promise.all(latus.invokeFlat('@latus/core/starting')); ({Entity} = latus.get('%resources')); }); it('has sane defaults', () => { const entity = new Entity(); expect(entity.traits).to.deep.equal({}); expect(entity.traitTypes()).to.deep.equal([]); }); it('can add and remove traits', async () => { const entity = new Entity(); const TestTrait = class extends Trait { static get type() { return 'TestTrait'; } }; latus.set('%traits.TestTrait', TestTrait); await entity.addTrait('TestTrait'); expect(entity.is('TestTrait')).to.be.true; entity.removeTrait('TestTrait'); expect(entity.is('TestTrait')).to.be.false; }); it('can add traits asynchronously', async () => { const DELAY = 30; class AsyncTrait extends Trait { static async extendJson(json) { const extended = await super.extendJson(json); await new Promise((resolve) => setTimeout(resolve, DELAY)); return extended; } } latus.set('%traits.Async', AsyncTrait); let start = Date.now(); const entity = await Entity.load({ traits: { Async: {}, }, }); expect(Date.now() - start).to.be.at.least(DELAY * 0.9); }); it('can invoke hooks', async () => { class AnotherTrait extends Trait { hooks() { return { testHook: () => 69, }; } static get type() { return 'AnotherTrait'; } } class YetAnotherTrait extends Trait { hooks() { return { testHook: () => 420, }; } static get type() { return 'YetAnotherTrait'; } } latus.set('%traits.AnotherTrait', AnotherTrait); latus.set('%traits.YetAnotherTrait', YetAnotherTrait); const entity = new Entity(); await entity.addTrait('AnotherTrait'); await entity.addTrait('YetAnotherTrait'); expect(entity.invokeHook('testHook')).to.deep.equal({AnotherTrait: 69, YetAnotherTrait: 420}); });