Skip to content
This repository was archived by the owner on Apr 21, 2024. It is now read-only.

Commit 781b505

Browse files
committed
test: cover main functionality
1 parent 094f7af commit 781b505

File tree

9 files changed

+160
-14
lines changed

9 files changed

+160
-14
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Dependencies, Caches & Artifacts
2+
coverage/
23
dist/
34
node_modules/
45
tsconfig.tsbuildinfo

lambda-ioc/deno/combinators.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { Container, ContainerKey, DependencyFactory } from './container.ts';
1+
import {
2+
ContainerKey,
3+
DependencyFactory,
4+
ReadableContainer,
5+
} from './container.ts';
26
import { ParamsToResolverKeys, TupleO, Zip } from './util.ts';
37

48
/**
@@ -9,8 +13,8 @@ export function singleton<
913
TVal,
1014
TDependencies extends Record<ContainerKey, unknown>,
1115
>(
12-
factory: DependencyFactory<TVal, Container<TDependencies>>,
13-
): DependencyFactory<TVal, Container<TDependencies>> {
16+
factory: DependencyFactory<TVal, ReadableContainer<TDependencies>>,
17+
): DependencyFactory<TVal, ReadableContainer<TDependencies>> {
1418
let result: TVal | undefined
1519

1620
return async (container) => {
@@ -82,7 +86,7 @@ export function constructor<
8286
type FuncContainer<
8387
TParams extends readonly unknown[],
8488
TDependencies extends ParamsToResolverKeys<TParams>,
85-
> = Container<
89+
> = ReadableContainer<
8690
// eslint-disable-next-line @typescript-eslint/no-explicit-any
8791
TupleO<Extract<Zip<TDependencies, TParams>, readonly [ContainerKey, any][]>>
8892
>

lambda-ioc/jest.config.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,17 @@ module.exports = {
1010
testPathIgnorePatterns: [
1111
'node_modules',
1212
'dist'
13-
]
13+
],
14+
collectCoverageFrom: [
15+
'<rootDir>/src/**/*.{js,ts}',
16+
'!<rootDir>/src/**/__tests__/**/*.{js,ts}',
17+
],
18+
coverageThreshold: {
19+
global: {
20+
branches: 99,
21+
functions: 99,
22+
lines: 99,
23+
statements: 99,
24+
},
25+
},
1426
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { constructor, createContainer, singleton } from '..'
2+
3+
describe('constructor', () => {
4+
it('can be registered without parameters', async () => {
5+
class A {}
6+
const container = createContainer().register('A', constructor(A))
7+
const a = await container.resolve('A')
8+
expect(a).toBeInstanceOf(A)
9+
})
10+
11+
it('can be registered with parameters', async () => {
12+
class A {}
13+
class B {
14+
constructor(readonly a: A) {}
15+
}
16+
class C {
17+
constructor(readonly b: B) {}
18+
}
19+
20+
const container = createContainer()
21+
.register('A', constructor(A))
22+
.register('B', constructor(B, 'A'))
23+
.register('C', singleton(constructor(C, 'B')))
24+
25+
// We abuse a bit this test to verify other tangential properties, like
26+
// uniqueness of instances.
27+
const b1 = await container.resolve('B')
28+
const b2 = await container.resolve('B')
29+
30+
expect(b1).toBeInstanceOf(B) // That's the real test.
31+
expect(b2).toBeInstanceOf(B)
32+
expect(b1).not.toBe(b2)
33+
34+
const c1 = await container.resolve('C')
35+
const c2 = await container.resolve('C')
36+
37+
expect(c1).toBeInstanceOf(C)
38+
expect(c2).toBeInstanceOf(C)
39+
expect(c1).toBe(c2)
40+
})
41+
})
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { createContainer } from '..'
2+
3+
describe('container', () => {
4+
it('can register simple values', async () => {
5+
const container = createContainer()
6+
.registerValue('foo', 'bar')
7+
.registerValue('theanswer', 42)
8+
9+
expect(await container.resolve('foo')).toBe('bar')
10+
expect(await container.resolve('theanswer')).toBe(42)
11+
})
12+
13+
it('can register simple factories', async () => {
14+
const container = createContainer()
15+
.register('foo', () => 'bar')
16+
.register('theanswer', () => 42)
17+
18+
expect(await container.resolve('foo')).toBe('bar')
19+
expect(await container.resolve('theanswer')).toBe(42)
20+
})
21+
})

lambda-ioc/src/__tests__/fake.test.ts

Lines changed: 0 additions & 5 deletions
This file was deleted.

lambda-ioc/src/__tests__/func.test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { createContainer, func } from '..'
2+
3+
describe('func', () => {
4+
it('can be registered without parameters', async () => {
5+
const container = createContainer().register(
6+
'foo',
7+
func(() => 'result'),
8+
)
9+
expect((await container.resolve('foo'))()).toBe('result')
10+
})
11+
12+
it('can be registered with parameters', async () => {
13+
const container = createContainer()
14+
.registerValue('a', 3)
15+
.registerValue('b', 5)
16+
.register(
17+
'f',
18+
func((a: number, b: number) => a * b, 'a', 'b'),
19+
)
20+
21+
expect((await container.resolve('f'))()).toBe(15)
22+
})
23+
24+
it('resolves a new function each time', async () => {
25+
const container = createContainer().register(
26+
'foo',
27+
func(() => 'result'),
28+
)
29+
30+
const f1 = await container.resolve('foo')
31+
const f2 = await container.resolve('foo')
32+
33+
expect(f1()).toBe('result')
34+
expect(f2()).toBe('result')
35+
expect(f1).not.toBe(f2)
36+
})
37+
})
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { createContainer, func, singleton } from '..'
2+
3+
describe('singleton', () => {
4+
it('resolves the same instance each time (no dependencies)', async () => {
5+
const container = createContainer().register(
6+
'foo',
7+
singleton(func(() => 'result')),
8+
)
9+
10+
const f1 = await container.resolve('foo')
11+
const f2 = await container.resolve('foo')
12+
13+
expect(f1()).toBe('result')
14+
expect(f2()).toBe('result')
15+
expect(f1).toBe(f2)
16+
})
17+
18+
it('resolves the same instance each time (multiple dependencies)', async () => {
19+
const container = createContainer()
20+
.registerValue('a', 3)
21+
.registerValue('b', 5)
22+
.register('f', singleton(func((a: number, b: number) => a * b, 'a', 'b')))
23+
24+
const f1 = await container.resolve('f')
25+
const f2 = await container.resolve('f')
26+
27+
expect(f1()).toBe(15)
28+
expect(f2()).toBe(15)
29+
expect(f1).toBe(f2)
30+
})
31+
})

lambda-ioc/src/combinators.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { Container, ContainerKey, DependencyFactory } from './container'
1+
import {
2+
ContainerKey,
3+
DependencyFactory,
4+
ReadableContainer,
5+
} from './container'
26
import { ParamsToResolverKeys, TupleO, Zip } from './util'
37

48
/**
@@ -9,8 +13,8 @@ export function singleton<
913
TVal,
1014
TDependencies extends Record<ContainerKey, unknown>,
1115
>(
12-
factory: DependencyFactory<TVal, Container<TDependencies>>,
13-
): DependencyFactory<TVal, Container<TDependencies>> {
16+
factory: DependencyFactory<TVal, ReadableContainer<TDependencies>>,
17+
): DependencyFactory<TVal, ReadableContainer<TDependencies>> {
1418
let result: TVal | undefined
1519

1620
return async (container) => {
@@ -82,7 +86,7 @@ export function constructor<
8286
type FuncContainer<
8387
TParams extends readonly unknown[],
8488
TDependencies extends ParamsToResolverKeys<TParams>,
85-
> = Container<
89+
> = ReadableContainer<
8690
// eslint-disable-next-line @typescript-eslint/no-explicit-any
8791
TupleO<Extract<Zip<TDependencies, TParams>, readonly [ContainerKey, any][]>>
8892
>

0 commit comments

Comments
 (0)