From df8546b597f148fae66c4cc17edd8ba312b4609f Mon Sep 17 00:00:00 2001 From: nikaple Date: Tue, 9 Nov 2021 20:20:49 +0800 Subject: [PATCH] test: add test case for multiple schemas (#20) --- README.md | 35 ++++++++++++++++++++++++++++++ tests/e2e/multiple-schemas.spec.ts | 25 +++++++++++++++++++++ tests/src/.env.part1 | 1 + tests/src/.env.part2 | 1 + tests/src/app.module.ts | 27 ++++++++++++++++++++++- tests/src/config.model.ts | 9 ++++++++ 6 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 tests/e2e/multiple-schemas.spec.ts create mode 100644 tests/src/.env.part1 create mode 100644 tests/src/.env.part2 diff --git a/README.md b/README.md index 2cccc35f..88d62a65 100644 --- a/README.md +++ b/README.md @@ -535,6 +535,41 @@ export class Config { } ``` +## Multiple Schemas + +Just call `TypedConfigModule.forRoot` multiple times, and you're ready to go! + +> PS: Please do not share any class or sub-class between schemas, or Nest.js won't know which class to inject. + +```ts +// config.ts +export class FooConfig { + @IsString() + foo!: string; +} +export class BazConfig { + @IsString() + baz!: string; +} + +// app.module.ts +@Module({ + imports: [ + // load FooConfig from config file + TypedConfigModule.forRoot({ + schema: FooConfig, + load: fileLoader(), + }), + // load BazConfig from environment variables + TypedConfigModule.forRoot({ + schema: BazConfig, + load: dotenvLoader(), + }), + ], +}) +export class AppModule {} +``` + ## Custom validate function If the default `validate` function doesn't suite your use case, you can provide it like in the example below: diff --git a/tests/e2e/multiple-schemas.spec.ts b/tests/e2e/multiple-schemas.spec.ts new file mode 100644 index 00000000..b0b1d099 --- /dev/null +++ b/tests/e2e/multiple-schemas.spec.ts @@ -0,0 +1,25 @@ +import { INestApplication } from '@nestjs/common'; +import { Test } from '@nestjs/testing'; +import { AppModule } from '../src/app.module'; +import { BazConfig, FooConfig } from '../src/config.model'; + +describe('Multiple config schemas', () => { + let app: INestApplication; + + it(`should merge configs from all loaders`, async () => { + const module = await Test.createTestingModule({ + imports: [AppModule.withMultipleSchemas()], + }).compile(); + + app = module.createNestApplication(); + await app.init(); + + const fooConfig = app.get(FooConfig); + const bazConfig = app.get(BazConfig); + + expect(fooConfig.foo).toBe('bar'); + expect(bazConfig.baz).toBe('qux'); + + await app.close(); + }); +}); diff --git a/tests/src/.env.part1 b/tests/src/.env.part1 new file mode 100644 index 00000000..c9f0304f --- /dev/null +++ b/tests/src/.env.part1 @@ -0,0 +1 @@ +foo=bar \ No newline at end of file diff --git a/tests/src/.env.part2 b/tests/src/.env.part2 new file mode 100644 index 00000000..d10d1abe --- /dev/null +++ b/tests/src/.env.part2 @@ -0,0 +1 @@ +baz=qux \ No newline at end of file diff --git a/tests/src/app.module.ts b/tests/src/app.module.ts index fd0dc5a9..a4d0c2b9 100644 --- a/tests/src/app.module.ts +++ b/tests/src/app.module.ts @@ -12,7 +12,13 @@ import { dotenvLoader, DotenvLoaderOptions, } from '../../lib/loader/dotenv-loader'; -import { Config, DirectoryConfig, TableConfig } from './config.model'; +import { + BazConfig, + Config, + DirectoryConfig, + FooConfig, + TableConfig, +} from './config.model'; const loadYaml = function loadYaml(filepath: string, content: string) { try { @@ -61,6 +67,25 @@ export class AppModule { }; } + static withMultipleSchemas(): DynamicModule { + return { + module: AppModule, + imports: [ + TypedConfigModule.forRoot({ + schema: FooConfig, + load: dotenvLoader({ + envFilePath: join(__dirname, '../src/.env.part1'), + }), + }), + TypedConfigModule.forRoot({ + schema: BazConfig, + load: dotenvLoader({ + envFilePath: join(__dirname, '../src/.env.part2'), + }), + }), + ], + }; + } static withToml(): DynamicModule { return { module: AppModule, diff --git a/tests/src/config.model.ts b/tests/src/config.model.ts index 1c7fcc3f..1b0d27ca 100644 --- a/tests/src/config.model.ts +++ b/tests/src/config.model.ts @@ -46,3 +46,12 @@ export class DirectoryConfig { @IsDefined() public readonly table!: TableConfig; } + +export class FooConfig { + @IsString() + foo!: string; +} +export class BazConfig { + @IsString() + baz!: string; +}