UNPKG

@difizen/mana-syringe

Version:

175 lines (159 loc) 5.81 kB
/* eslint-disable @typescript-eslint/no-explicit-any */ import 'reflect-metadata'; import assert from 'assert'; import { GlobalContainer } from '../container'; import { register } from '../container'; import { Contribution, contrib } from '../contribution/index'; import { Syringe } from '../core'; import { inject, singleton } from '../decorator'; import { Module } from '../module/index'; import { DefaultContributionProvider } from './contribution-provider'; import { ContributionOptionConfig } from './index'; describe('contribution', () => { it('#register contribution', () => { const FooContribution = Syringe.defineToken('FooContribution'); Contribution.register(register, FooContribution); const provider = GlobalContainer.getNamed(Contribution.Provider, FooContribution); assert(provider instanceof DefaultContributionProvider); assert(GlobalContainer.isBoundNamed(Contribution.Provider, FooContribution)); }); it('#contrib decorator', () => { const FooContribution = Syringe.defineToken('FooContribution'); const BarContribution = Syringe.defineToken('BarContribution'); Contribution.register(register, FooContribution); @singleton({ contrib: FooContribution }) class Foo {} @singleton({ contrib: [FooContribution, BarContribution] }) class Foo1 {} register(Foo); register(Foo1); @singleton() class Bar { public contribs: Contribution.Provider<any>; public bar: Contribution.Provider<any>; constructor( @contrib(FooContribution) contribs: Contribution.Provider<any>, @inject(BarContribution) bar: Contribution.Provider<any>, ) { this.contribs = contribs; this.bar = bar; } } register(Bar); const bar = GlobalContainer.get(Bar); const list = bar.contribs.getContributions(); assert(bar.bar instanceof Foo1); assert(list.length === 2); assert(list.find((item) => item instanceof Foo)); }); it('#contribution option', () => { const FooContribution = Syringe.defineToken('FooContribution'); @singleton({ contrib: FooContribution }) class Foo {} register(Foo); const childContainer = GlobalContainer.createChild(); Contribution.register( childContainer.register.bind(childContainer), FooContribution, { cache: true, }, ); @singleton() class Bar { public pr: Contribution.Provider<any>; constructor(@contrib(FooContribution) pr: Contribution.Provider<any>) { this.pr = pr; } } childContainer.register(Bar); @singleton({ contrib: FooContribution }) class Foo1 {} childContainer.register(Foo1); const bar = childContainer.get(Bar); const list = bar.pr.getContributions(); assert(list.length === 1); assert(list.find((item) => item instanceof Foo1)); const cachelist = bar.pr.getContributions(); assert(list === cachelist); const newlist = bar.pr.getContributions({ cache: false }); assert(list !== newlist && newlist.length === 1); assert(newlist.find((item) => item instanceof Foo1)); const all = bar.pr.getContributions({ recursive: true, cache: false }); assert(all !== newlist && all.length === 2); assert(all.find((item) => item instanceof Foo)); assert(all.find((item) => item instanceof Foo1)); }); it('#contribution event', () => { const FooContribution = Syringe.defineToken('FooContribution'); @singleton({ contrib: FooContribution }) class Foo {} register(Foo); const childContainer = GlobalContainer.createChild(); Contribution.register( childContainer.register.bind(childContainer), FooContribution, { cache: true, }, ); @singleton() class Bar { contributionChanged = false; public pr: Contribution.Provider<any>; constructor(@contrib(FooContribution) pr: Contribution.Provider<any>) { this.pr = pr; this.pr.onChanged(() => { this.contributionChanged = true; }); } } childContainer.register(Bar); const bar = childContainer.get(Bar); @singleton({ contrib: FooContribution }) class Foo1 {} childContainer.register(Foo1); assert(bar.contributionChanged); }); it('#contirbution config', () => { ContributionOptionConfig.recursive = true; const p = GlobalContainer.createChild(); const fooContainer = p.createChild(); const barContainer = p.createChild(); const DemoContribution = Syringe.defineToken('FooContribution'); interface DemoContribution { name: string; } @singleton({ contrib: DemoContribution }) class Foo implements DemoContribution { name = 'foo'; } @singleton({ contrib: DemoContribution }) class Bar implements DemoContribution { name = 'bar'; } @singleton({ contrib: DemoContribution }) class Baz implements DemoContribution { name = 'baz'; } const BazModule = Module().register(Baz); const FooModule = Module().register(Foo).contribution(DemoContribution); const BarModule = Module().register(Bar).contribution(DemoContribution); p.load(BazModule); fooContainer.load(FooModule); barContainer.load(BarModule); const fooProvider = fooContainer.getNamed<Contribution.Provider<DemoContribution>>( Contribution.Provider, DemoContribution, ); const barProvider = barContainer.getNamed<Contribution.Provider<DemoContribution>>( Contribution.Provider, DemoContribution, ); const foos = fooProvider.getContributions(); assert(foos.length === 2); assert(foos.find((item) => item.name === 'foo')); assert(foos.find((item) => item.name === 'baz')); assert(barProvider.getContributions().length === 2); }); });