Skip to content

Commit

Permalink
Merge pull request #3 from Goodluckhf/develop
Browse files Browse the repository at this point in the history
Рефакторинг и валидация манифеста
  • Loading branch information
Goodluckhf committed Jul 8, 2019
2 parents 2ff0ac3 + dd1a964 commit b5491e8
Show file tree
Hide file tree
Showing 33 changed files with 602 additions and 217 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ jobs:
- npm run report-coverage
- stage: release
node_js: '8'
before_script:
- npm prune
script:
- npm run build
- npm run semantic-release
19 changes: 13 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Declarative and simple IoC container for node.js applications

### Usage
```javascript
import {Container} from '@ukitgroup/ioc';
import { IoCContainer } from '@ukitgroup/ioc';

class ServiceA {}

Expand All @@ -35,7 +35,7 @@ const moduleManifest = {


// Then in your composition root just create container
const container = new Container();
const container = new IoCContainer();
container.loadManifests([moduleManifest]);
container.compile();
```
Expand Down Expand Up @@ -186,7 +186,7 @@ const moduleManifest = {
],
};

const container = new Container();
const container = new IoCContainer();
container.loadManifests([moduleManifest]);
container.compile();

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

beforeEach(() => {
ctx.container = TestContainer.createTestModule([
ctx.container = TestIoCContainer.createTestModule([
//... providers definition with mocks
])
ctx.container.compile();
});

it('test case', () => {
// Here you can just get provider by token
// You don't have to transmit module name
const provider = ctx.container.get('providerToken');
});
})
```

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

### TODO:
* support decorators with typescript
* TestContainer for integration tests
* TestIoCContainer for integration tests
* Get public providers by tag
31 changes: 30 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,10 @@
]
},
"dependencies": {
"eerror": "2.0.0"
"class-transformer": "^0.2.3",
"class-validator": "^0.9.1",
"eerror": "2.0.0",
"reflect-metadata": "^0.1.13"
},
"husky": {
"hooks": {
Expand Down Expand Up @@ -114,6 +117,7 @@
"publishConfig": {
"access": "public"
},
"types": "dist/index.d.ts",
"files": [
"dist/**/*.*",
"!dist/**/*.test.*"
Expand Down
77 changes: 0 additions & 77 deletions src/Injector.spec.ts

This file was deleted.

4 changes: 2 additions & 2 deletions src/container.interface.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { ManifestInterface } from './manifest.interface';
import { Token } from './internal-types';
import { ManifestInterface as publicManifestInterface } from './public-interfaces/manifest.interface';

export interface ContainerInterface {
loadManifests(manifests: ManifestInterface[]);
loadManifests(manifests: publicManifestInterface[]);
compile();
get(moduleName: string, token: Token);
}
53 changes: 12 additions & 41 deletions src/container.spec.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,21 @@
import 'reflect-metadata';
import { Container } from './container';
import { Module } from './module';
import { AlreadyCompiledError } from './errors/already-compiled.error';

class TestServiceA {}
class TestServiceB {
constructor(testServiceA) {
describe('IoC container', function() {
beforeEach(() => {
// @ts-ignore
this.testServiceA = testServiceA;
}
}

describe('IoC container', () => {
it('should parse manifest to module', () => {
const container = new Container();
const diManifest = {
moduleName: 'tesModule',
providers: [
{
token: 'testServiceA',
useClass: TestServiceA,
},
],
};

container.loadManifests([diManifest]);
// @ts-ignore
expect(container.modules.size).toEqual(1);
// @ts-ignore
expect([...container.modules.values()][0]).toBeInstanceOf(Module);
this.container = new Container({}, {});
});

it('Should throw error if has already compiled', () => {
const container = new Container();
const diManifest = {
moduleName: 'tesModule',
providers: [
{
token: 'testServiceA',
useClass: TestServiceA,
},
],
};
container.loadManifests([diManifest]);
container.compile();
expect(() => {
container.compile();
}).toThrow(AlreadyCompiledError);
expect.assertions(1);
this.container.applyPublicProviders = () => {};
this.container.compile();
try {
this.container.compile();
} catch (e) {
expect(e).toBeInstanceOf(AlreadyCompiledError);
}
});
});
29 changes: 22 additions & 7 deletions src/container.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { ContainerInterface } from './container.interface';
import { ManifestInterface } from './manifest.interface';
import { buildPublicToken } from './helpers';
import { InstanceWrapperFactory } from './instance-wrapper-factory';
import { Module } from './module';
import { Injector } from './injector';
import { ModuleHasAlreadyExists } from './errors/module-has-already-exists.error';
Expand All @@ -13,24 +11,41 @@ import {
ModuleInterface,
Token,
} from './internal-types';
import { InstanceWrapperFactoryInterface } from './instance-wrapper-factory.interface';
import { ManifestTransformerInterface } from './manifest-transformer.interface';
import { ManifestInterface as publicManifestInterface } from './public-interfaces/manifest.interface';
import { ManifestInterface } from './dto/manifest.interface';

export class Container implements ContainerInterface {
private readonly instanceWrapperFactory: InstanceWrapperFactoryInterface;

private readonly manifestTransformer: ManifestTransformerInterface;

private readonly publicProviders: Map<Token, InstanceWrapperInterface>;

private readonly modules: Map<string, ModuleInterface>;

private compiled: boolean;

public constructor() {
public constructor(
instanceWrapperAbstractFactory: InstanceWrapperFactoryInterface,
manifestTransformer: ManifestTransformerInterface,
) {
this.instanceWrapperFactory = instanceWrapperAbstractFactory;
this.manifestTransformer = manifestTransformer;

this.publicProviders = new Map();
this.modules = new Map();
this.compiled = false;
}

public loadManifests(manifests: ManifestInterface[]) {
const instanceWrapperFactory = new InstanceWrapperFactory();
manifests.forEach(manifest => {
const newModule = new Module(instanceWrapperFactory, manifest);
public loadManifests(manifestsData: publicManifestInterface[]) {
const parsedManifests: ManifestInterface[] = this.manifestTransformer.transform(
manifestsData,
);

parsedManifests.forEach(manifest => {
const newModule = new Module(this.instanceWrapperFactory, manifest);
if (this.modules.has(newModule.name)) {
throw new ModuleHasAlreadyExists().combine({ module: newModule.name });
}
Expand Down
26 changes: 0 additions & 26 deletions src/dependency.ts

This file was deleted.

Loading

0 comments on commit b5491e8

Please sign in to comment.