Skip to content

Commit b5491e8

Browse files
authored
Merge pull request #3 from Goodluckhf/develop
Рефакторинг и валидация манифеста
2 parents 2ff0ac3 + dd1a964 commit b5491e8

33 files changed

+602
-217
lines changed

.travis.yml

+2
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ jobs:
4747
- npm run report-coverage
4848
- stage: release
4949
node_js: '8'
50+
before_script:
51+
- npm prune
5052
script:
5153
- npm run build
5254
- npm run semantic-release

README.md

+13-6
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Declarative and simple IoC container for node.js applications
1717

1818
### Usage
1919
```javascript
20-
import {Container} from '@ukitgroup/ioc';
20+
import { IoCContainer } from '@ukitgroup/ioc';
2121

2222
class ServiceA {}
2323

@@ -35,7 +35,7 @@ const moduleManifest = {
3535

3636

3737
// Then in your composition root just create container
38-
const container = new Container();
38+
const container = new IoCContainer();
3939
container.loadManifests([moduleManifest]);
4040
container.compile();
4141
```
@@ -186,7 +186,7 @@ const moduleManifest = {
186186
],
187187
};
188188

189-
const container = new Container();
189+
const container = new IoCContainer();
190190
container.loadManifests([moduleManifest]);
191191
container.compile();
192192

@@ -198,16 +198,22 @@ http.listen(port);
198198
### Testing
199199
We provide a comfortable way for testing
200200
```javascript
201-
import {TestContainer} from '@ukitgroup/ioc';
201+
import { TestIoCContainer } from '@ukitgroup/ioc';
202202
describe('Unit test', () => {
203203
const ctx = {}
204204

205205
beforeEach(() => {
206-
ctx.container = TestContainer.createTestModule([
206+
ctx.container = TestIoCContainer.createTestModule([
207207
//... providers definition with mocks
208208
])
209209
ctx.container.compile();
210210
});
211+
212+
it('test case', () => {
213+
// Here you can just get provider by token
214+
// You don't have to transmit module name
215+
const provider = ctx.container.get('providerToken');
216+
});
211217
})
212218
```
213219

@@ -216,4 +222,5 @@ More examples you can find in [integration tests](https://github.com/Goodluckhf/
216222

217223
### TODO:
218224
* support decorators with typescript
219-
* TestContainer for integration tests
225+
* TestIoCContainer for integration tests
226+
* Get public providers by tag

package-lock.json

+30-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,10 @@
8585
]
8686
},
8787
"dependencies": {
88-
"eerror": "2.0.0"
88+
"class-transformer": "^0.2.3",
89+
"class-validator": "^0.9.1",
90+
"eerror": "2.0.0",
91+
"reflect-metadata": "^0.1.13"
8992
},
9093
"husky": {
9194
"hooks": {
@@ -114,6 +117,7 @@
114117
"publishConfig": {
115118
"access": "public"
116119
},
120+
"types": "dist/index.d.ts",
117121
"files": [
118122
"dist/**/*.*",
119123
"!dist/**/*.test.*"

src/Injector.spec.ts

-77
This file was deleted.

src/container.interface.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { ManifestInterface } from './manifest.interface';
21
import { Token } from './internal-types';
2+
import { ManifestInterface as publicManifestInterface } from './public-interfaces/manifest.interface';
33

44
export interface ContainerInterface {
5-
loadManifests(manifests: ManifestInterface[]);
5+
loadManifests(manifests: publicManifestInterface[]);
66
compile();
77
get(moduleName: string, token: Token);
88
}

src/container.spec.ts

+12-41
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,21 @@
1+
import 'reflect-metadata';
12
import { Container } from './container';
2-
import { Module } from './module';
33
import { AlreadyCompiledError } from './errors/already-compiled.error';
44

5-
class TestServiceA {}
6-
class TestServiceB {
7-
constructor(testServiceA) {
5+
describe('IoC container', function() {
6+
beforeEach(() => {
87
// @ts-ignore
9-
this.testServiceA = testServiceA;
10-
}
11-
}
12-
13-
describe('IoC container', () => {
14-
it('should parse manifest to module', () => {
15-
const container = new Container();
16-
const diManifest = {
17-
moduleName: 'tesModule',
18-
providers: [
19-
{
20-
token: 'testServiceA',
21-
useClass: TestServiceA,
22-
},
23-
],
24-
};
25-
26-
container.loadManifests([diManifest]);
27-
// @ts-ignore
28-
expect(container.modules.size).toEqual(1);
29-
// @ts-ignore
30-
expect([...container.modules.values()][0]).toBeInstanceOf(Module);
8+
this.container = new Container({}, {});
319
});
3210

3311
it('Should throw error if has already compiled', () => {
34-
const container = new Container();
35-
const diManifest = {
36-
moduleName: 'tesModule',
37-
providers: [
38-
{
39-
token: 'testServiceA',
40-
useClass: TestServiceA,
41-
},
42-
],
43-
};
44-
container.loadManifests([diManifest]);
45-
container.compile();
46-
expect(() => {
47-
container.compile();
48-
}).toThrow(AlreadyCompiledError);
12+
expect.assertions(1);
13+
this.container.applyPublicProviders = () => {};
14+
this.container.compile();
15+
try {
16+
this.container.compile();
17+
} catch (e) {
18+
expect(e).toBeInstanceOf(AlreadyCompiledError);
19+
}
4920
});
5021
});

src/container.ts

+22-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import { ContainerInterface } from './container.interface';
2-
import { ManifestInterface } from './manifest.interface';
32
import { buildPublicToken } from './helpers';
4-
import { InstanceWrapperFactory } from './instance-wrapper-factory';
53
import { Module } from './module';
64
import { Injector } from './injector';
75
import { ModuleHasAlreadyExists } from './errors/module-has-already-exists.error';
@@ -13,24 +11,41 @@ import {
1311
ModuleInterface,
1412
Token,
1513
} from './internal-types';
14+
import { InstanceWrapperFactoryInterface } from './instance-wrapper-factory.interface';
15+
import { ManifestTransformerInterface } from './manifest-transformer.interface';
16+
import { ManifestInterface as publicManifestInterface } from './public-interfaces/manifest.interface';
17+
import { ManifestInterface } from './dto/manifest.interface';
1618

1719
export class Container implements ContainerInterface {
20+
private readonly instanceWrapperFactory: InstanceWrapperFactoryInterface;
21+
22+
private readonly manifestTransformer: ManifestTransformerInterface;
23+
1824
private readonly publicProviders: Map<Token, InstanceWrapperInterface>;
1925

2026
private readonly modules: Map<string, ModuleInterface>;
2127

2228
private compiled: boolean;
2329

24-
public constructor() {
30+
public constructor(
31+
instanceWrapperAbstractFactory: InstanceWrapperFactoryInterface,
32+
manifestTransformer: ManifestTransformerInterface,
33+
) {
34+
this.instanceWrapperFactory = instanceWrapperAbstractFactory;
35+
this.manifestTransformer = manifestTransformer;
36+
2537
this.publicProviders = new Map();
2638
this.modules = new Map();
2739
this.compiled = false;
2840
}
2941

30-
public loadManifests(manifests: ManifestInterface[]) {
31-
const instanceWrapperFactory = new InstanceWrapperFactory();
32-
manifests.forEach(manifest => {
33-
const newModule = new Module(instanceWrapperFactory, manifest);
42+
public loadManifests(manifestsData: publicManifestInterface[]) {
43+
const parsedManifests: ManifestInterface[] = this.manifestTransformer.transform(
44+
manifestsData,
45+
);
46+
47+
parsedManifests.forEach(manifest => {
48+
const newModule = new Module(this.instanceWrapperFactory, manifest);
3449
if (this.modules.has(newModule.name)) {
3550
throw new ModuleHasAlreadyExists().combine({ module: newModule.name });
3651
}

src/dependency.ts

-26
This file was deleted.

0 commit comments

Comments
 (0)