@triviality/core
Version:
Purely typed service container
62 lines (57 loc) • 2.08 kB
text/typescript
import { SF } from '../../ServiceFactory';
import {
createFeatureFactoryServicesContext,
instancesByTags,
servicesByTags,
ServicesContext,
} from '../ServicesContext';
import { ServiceFunctionReferenceContainer } from '../../Container';
import { TaggedServiceFactoryReference } from '../../Value/TaggedServiceFactoryReference';
import { always } from 'ramda';
type FetchA = (tag: 'foo') => SF<number>;
type FetchB = (tag: 'bar') => SF<string>;
it('Can fetch services', () => {
const fetchService: FetchA & FetchB = jest.fn((tag: 'foo' | 'bar'): any => {
return () => tag === 'foo' ? 1 : 'test';
});
const withServices = servicesByTags<'foo', SF<number>, 'bar', SF<string>>(fetchService);
const context: ServicesContext<{ foo: SF<number>, bar: SF<string> }> = {
dependencies: null as any,
service: null as any,
services: withServices as any,
instances: null as any,
instance: null as any,
};
const [foo, bar] = context.services('foo', 'bar');
expect(fetchService).not.toBeCalled();
expect(foo()).toEqual(1);
expect(bar()).toEqual('test');
});
it('Can fetch service instances', () => {
const fetchServices = jest.fn((_tags: string[]): any => {
return [() => 1, () => 2];
});
const withServices = instancesByTags(fetchServices as any);
const context: ServicesContext<{ foo: SF<number>, bar: SF<string> }> = {
dependencies: null as any,
service: null as any,
services: null as any,
instances: withServices as any,
instance: null as any,
};
const [foo, bar] = context.instances('foo', 'bar');
expect(fetchServices).toBeCalledWith('foo', 'bar');
expect(foo).toEqual(1);
expect(bar).toEqual(2);
});
it('Can fetch single service instance', async () => {
const container = new ServiceFunctionReferenceContainer();
container.add(new TaggedServiceFactoryReference({
tag: 'foo',
factory: always('bar'),
feature: () => Object,
}));
const context = createFeatureFactoryServicesContext(container);
await container.build();
expect(context.instance('foo')).toEqual('bar');
});