import {resource} from '@avocado/resource'; 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')); ({fromResourceType: {Entity}} = resource(latus)); }); 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'; } }; traits(latus).fromType['TestTrait'] = TestTrait; const trait = await TestTrait.load(); 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; } } traits(latus).fromType['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'; } } const entity = new Entity(); entity.addTrait(AnotherTrait); entity.addTrait(YetAnotherTrait); expect(entity.invokeHook('testHook')).to.deep.equal({AnotherTrait: 69, YetAnotherTrait: 420}); });