forked from nestjs/nest
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(core): Add multi provider option
Resolves nestjs#770
- Loading branch information
1 parent
d01a798
commit b74a7b4
Showing
14 changed files
with
474 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { Test } from '@nestjs/testing'; | ||
import { expect } from 'chai'; | ||
import { MultiProviderUseValueModule } from '../src/multi-provider/multi-provider-use-value.module'; | ||
import { MultiProviderUseFactoryModule } from '../src/multi-provider/multi-provider-use-factory.module'; | ||
import { MultiProviderUseClassModule } from '../src/multi-provider/multi-provider-use-class.module'; | ||
import { MultiProviderMixedModule } from '../src/multi-provider/multi-provider-mixed.module'; | ||
import { MutliProviderExportModule } from '../src/multi-provider/multi-provider-export.module'; | ||
import { MixedMultiProviderException } from '@nestjs/core/errors/exceptions/mixed-multi-provider.exception'; | ||
import { MultiProviderCircularModule } from '../src/multi-provider/multi-provider-circular.module'; | ||
|
||
describe('MultiProvider', () => { | ||
it(`should return an array of values when using the "multi" option and "useValue"`, async () => { | ||
const builder = Test.createTestingModule({ | ||
imports: [MultiProviderUseValueModule], | ||
}); | ||
const app = await builder.compile(); | ||
expect(app.get('TEST')).to.deep.eq(['a', 'b']); | ||
}); | ||
|
||
it(`should return an array of values when using the "multi" option and "useFactory"`, async () => { | ||
const builder = Test.createTestingModule({ | ||
imports: [MultiProviderUseFactoryModule], | ||
}); | ||
const app = await builder.compile(); | ||
expect(app.get('TEST')).to.deep.eq(['a', 'b']); | ||
}); | ||
|
||
it(`should return an array of values when using the "multi" option and "useClass"`, async () => { | ||
const builder = Test.createTestingModule({ | ||
imports: [MultiProviderUseClassModule], | ||
}); | ||
const app = await builder.compile(); | ||
expect(app.get('TEST')[0].test()).to.deep.eq('a'); | ||
expect(app.get('TEST')[1].test()).to.deep.eq('b'); | ||
}); | ||
|
||
it(`should return an array of values when using the "multi" option with exported providers`, async () => { | ||
const builder = Test.createTestingModule({ | ||
imports: [MutliProviderExportModule], | ||
}); | ||
const app = await builder.compile(); | ||
expect(app.get('TEST')).to.deep.eq(['a', 'b', 'c']); | ||
}); | ||
|
||
it(`should return an array of values when using the "multi" option with exported providers in a circual module`, async () => { | ||
const builder = Test.createTestingModule({ | ||
imports: [MultiProviderCircularModule], | ||
}); | ||
const app = await builder.compile(); | ||
expect(app.get('TEST')).to.deep.eq(['a', 'b']); | ||
}); | ||
|
||
it(`should throw an error if "mutli" value is mixed with the same token`, async () => { | ||
try { | ||
const builder = Test.createTestingModule({ | ||
imports: [MultiProviderMixedModule], | ||
}); | ||
await builder.compile(); | ||
} catch (err) { | ||
expect(err).to.be.instanceof(MixedMultiProviderException); | ||
} | ||
}); | ||
}); |
29 changes: 29 additions & 0 deletions
29
integration/injector/src/multi-provider/multi-provider-circular.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { Module, forwardRef } from '@nestjs/common'; | ||
|
||
const MULTI_TOKEN = 'TEST'; | ||
|
||
@Module({ | ||
imports: [forwardRef(() => MultiProviderCircularModule)], | ||
providers: [ | ||
{ | ||
provide: MULTI_TOKEN, | ||
multi: true, | ||
useValue: 'a', | ||
}, | ||
], | ||
exports: [MULTI_TOKEN], | ||
}) | ||
class AModule {} | ||
|
||
@Module({ | ||
imports: [forwardRef(() => AModule)], | ||
providers: [ | ||
{ | ||
provide: MULTI_TOKEN, | ||
useValue: 'b', | ||
multi: true, | ||
}, | ||
], | ||
exports: [MULTI_TOKEN], | ||
}) | ||
export class MultiProviderCircularModule {} |
38 changes: 38 additions & 0 deletions
38
integration/injector/src/multi-provider/multi-provider-export.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { Module } from '@nestjs/common'; | ||
|
||
const MULTI_TOKEN = 'TEST'; | ||
const INTERNAL_PROVIDER_TOKEN = 'INTERNAL_PROVIDER_TOKEN'; | ||
|
||
@Module({ | ||
providers: [ | ||
{ | ||
provide: INTERNAL_PROVIDER_TOKEN, | ||
useValue: 'a', | ||
}, | ||
{ | ||
provide: MULTI_TOKEN, | ||
multi: true, | ||
useFactory: arg => arg, | ||
inject: [INTERNAL_PROVIDER_TOKEN], | ||
}, | ||
], | ||
exports: [MULTI_TOKEN], | ||
}) | ||
class AModule {} | ||
|
||
@Module({ | ||
imports: [AModule], | ||
providers: [ | ||
{ | ||
provide: MULTI_TOKEN, | ||
useValue: 'b', | ||
multi: true, | ||
}, | ||
{ | ||
provide: MULTI_TOKEN, | ||
useValue: 'c', | ||
multi: true, | ||
}, | ||
], | ||
}) | ||
export class MutliProviderExportModule {} |
17 changes: 17 additions & 0 deletions
17
integration/injector/src/multi-provider/multi-provider-mixed.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { Module, Inject } from '@nestjs/common'; | ||
|
||
@Module({ | ||
providers: [ | ||
|
||
{ | ||
provide: 'TEST', | ||
useValue: 'a', | ||
multi: true, | ||
}, | ||
{ | ||
provide: 'TEST', | ||
useValue: 'b', | ||
multi: false, | ||
}], | ||
}) | ||
export class MultiProviderMixedModule { } |
32 changes: 32 additions & 0 deletions
32
integration/injector/src/multi-provider/multi-provider-use-class.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { Module, Inject } from '@nestjs/common'; | ||
|
||
class Test1 { | ||
test() { | ||
return 'a'; | ||
} | ||
} | ||
class Test2 { | ||
constructor(@Inject('B_VALUE') private b: string) { } | ||
test() { | ||
return this.b; | ||
} | ||
} | ||
|
||
@Module({ | ||
providers: [ | ||
{ | ||
provide: 'B_VALUE', | ||
useValue: 'b', | ||
}, | ||
{ | ||
provide: 'TEST', | ||
useClass: Test1, | ||
multi: true, | ||
}, | ||
{ | ||
provide: 'TEST', | ||
useClass: Test2, | ||
multi: true, | ||
}], | ||
}) | ||
export class MultiProviderUseClassModule { } |
22 changes: 22 additions & 0 deletions
22
integration/injector/src/multi-provider/multi-provider-use-factory.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { Module } from '@nestjs/common'; | ||
|
||
const BProviderToken = 'BProvider'; | ||
|
||
@Module({ | ||
providers: [{ | ||
provide: 'TEST', | ||
useFactory: () => 'a', | ||
multi: true, | ||
}, | ||
{ | ||
provide: BProviderToken, | ||
useValue: 'b', | ||
}, | ||
{ | ||
provide: 'TEST', | ||
useFactory: (b: string) => b, | ||
inject: [BProviderToken], | ||
multi: true, | ||
}], | ||
}) | ||
export class MultiProviderUseFactoryModule { } |
16 changes: 16 additions & 0 deletions
16
integration/injector/src/multi-provider/multi-provider-use-value.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
|
||
import { Module } from '@nestjs/common'; | ||
|
||
@Module({ | ||
providers: [{ | ||
provide: 'TEST', | ||
useValue: 'a', | ||
multi: true, | ||
}, | ||
{ | ||
provide: 'TEST', | ||
useValue: 'b', | ||
multi: true, | ||
}], | ||
}) | ||
export class MultiProviderUseValueModule { } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
packages/core/errors/exceptions/mixed-multi-provider.exception.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { MIXED_MULTI_PROVIDER_MESSAGE } from '../messages'; | ||
import { RuntimeException } from './runtime.exception'; | ||
|
||
/** | ||
* Errors which should get thrown when the user | ||
* mixes up the `multi` option of a provider | ||
* | ||
* ```typescript | ||
* // Will throw an exception | ||
* @Module({ | ||
* providers: [ | ||
* { | ||
* useValue: 'eng', | ||
* provide: 'LANG', | ||
* multi: true, | ||
* }, | ||
* { | ||
* useValue: 'de', | ||
* provide: 'LANG', | ||
* // Not allowed, because inconsistent value for `multi` | ||
* multi: false, | ||
* }, | ||
* ], | ||
* }) | ||
* ``` | ||
*/ | ||
export class MixedMultiProviderException extends RuntimeException { | ||
constructor(name: string | symbol) { | ||
super(MIXED_MULTI_PROVIDER_MESSAGE(name.toString())); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.