UNPKG

@triviality/core

Version:
250 lines (196 loc) 5.65 kB
import triviality, { createFeatureFactoryContext, FF, RegistrySet, ServiceFunctionReferenceContainer, SetupFeatureServices, } from '../..'; import { invokeFeatureFactory } from '../../invokeFeatureFactory'; it('Can merge features', async () => { interface MyFeatureServices { foo: number; bar: string; } const container = new ServiceFunctionReferenceContainer(); const context = createFeatureFactoryContext<{}, {}>({ container, invoke: invokeFeatureFactory }); const myFeature: FF<MyFeatureServices> = () => ({ bar: () => 'bar', foo: () => 1, }); const services = context.merge(myFeature).services('bar', 'foo'); await container.build(); expect(services.foo()).toEqual(1); expect(services.bar()).toEqual('bar'); }); it('Merged services can use default services', async () => { const spy = jest.fn(); const myFeature: FF<{}, SetupFeatureServices> = ({ registers: { setupCallbacks } }) => ({ ...setupCallbacks(() => spy), }); await triviality().add(({ merge }) => { merge(myFeature); return {}; }).build(); expect(spy).toBeCalled(); }); it('Can merge multiple features', async () => { interface UserServices { users: number; } const userFeature: FF<UserServices> = () => ({ users: () => 3, }); interface BuildingServices { buildings: number; } const buildingFeature: FF<BuildingServices> = () => ({ buildings: () => 10, }); const container = new ServiceFunctionReferenceContainer(); const context = createFeatureFactoryContext<{}, {}>({ container, invoke: invokeFeatureFactory }); const services = context .merge(userFeature) .with(buildingFeature) .services('users', 'buildings'); await container.build(); expect(services.users()).toEqual(3); expect(services.buildings()).toEqual(10); }); it('Can merge multiple times', async () => { interface User { age: number; } let a = 20; interface UserServices { users: User; } const userFeature: FF<UserServices> = () => ({ users: () => { a *= 2; return { age: a }; }, }); interface Building { size: number; } interface BuildingServices { buildings: Building; } let i = 0; const buildingFeature: FF<BuildingServices> = () => ({ buildings: () => { i += 1; return ({ size: i }); }, }); interface MyFeatureServices { buildings1: Building; buildings2: Building; users1: User; users2: User; } const myFeature: FF<MyFeatureServices> = ({ merge }) => { const withUserFeature = merge(userFeature); const { buildings: buildings1, users: users1 } = withUserFeature .with(buildingFeature) .services('buildings', 'users'); const { buildings: buildings2, users: users2 } = withUserFeature .with(buildingFeature) .services('buildings', 'users'); return { buildings1, buildings2, users1, users2, }; }; const { buildings1: b1, buildings2: b2, users1: u1, users2: u2 } = await triviality().add(myFeature).build(); expect(b1).toEqual({ size: 1 }); expect(b2).toEqual({ size: 2 }); expect(u1).toEqual({ age: 40 }); expect(u2).toEqual({ age: 40 }); }); it('Can merge multiple services', async () => { interface F1 { one: number; } const f1: FF<F1> = () => ({ one: () => 1 }); interface F2 { two: number; } const f2: FF<F2> = () => ({ two: () => 2 }); interface F3 { three: number; } const f3: FF<F3> = () => ({ three: () => 3 }); interface MyFeature extends F1, F2, F3 { } const myFeature: FF<MyFeature, {}> = ({ merge }) => { return merge(f1).with(f2).with(f3).all(); }; const { one, two, three } = await triviality() .add(myFeature) .build(); expect([one, two, three]).toEqual([1, 2, 3]); }); it('Can override merged services', async () => { interface Orginal { one: number; } const orginalFeature: FF<Orginal> = () => ({ one: () => 1 }); interface F2 { two: number; } const f2: FF<F2, Orginal> = ({ one: o }) => ({ two: () => o() + 2 }); interface F3 { three: number; } const f3: FF<F3, Orginal> = ({ one: o }) => ({ three: () => o() + 3 }); interface MyFeature extends Orginal, F2, F3 { } const myFeature: FF<MyFeature, {}> = ({ merge }) => { return merge(orginalFeature).with(f2).with(f3).all(); }; const myFeatureOverride: FF<{}, Orginal> = ({ override: { one: o } }) => { return { ...o(() => 10), }; }; const { one, two, three } = await triviality() .add(myFeature) .add(myFeatureOverride) .build(); expect([one, two, three]).toEqual([10, 12, 13]); }); it('Can directly fetch all new services', async () => { interface User { name: string; } interface UserServices { users: RegistrySet<User>; } const userFeature: FF<UserServices> = ({ registerSet }) => ({ users: registerSet(), }); const johnUserFeature: FF<{}, UserServices> = ({ registers: { users } }) => ({ ...users(() => ({ name: 'John' })), }); const JaneUserFeature: FF<{}, UserServices> = ({ registers: { users } }) => ({ ...users(() => ({ name: 'Jane' })), }); interface MyFeatureServices { names: string[]; users: RegistrySet<User>; } const myFeature: FF<MyFeatureServices, {}> = ({ merge }) => { const { users } = merge(userFeature).with(johnUserFeature).with(JaneUserFeature).services('users'); return { users, names: () => users().map(({ name }) => name), }; }; const { names } = await triviality() .add(myFeature) .build(); expect(names).toEqual(['John', 'Jane']); });