diff --git a/cli/src/index.ts b/cli/src/index.ts index c369f5a..b65dd30 100644 --- a/cli/src/index.ts +++ b/cli/src/index.ts @@ -19,6 +19,8 @@ import { CommandLineArguments, CliSpecificOptions } from './types'; import { DeepPartial } from 'mongo-seeding/dist/common'; class CliSeeder { + readonly DEFAULT_INPUT_PATH = './'; + run = async () => { let options: CommandLineArguments; @@ -45,7 +47,7 @@ class CliSeeder { this.useCliSpecificOptions(config as DeepPartial); const seeder = new Seeder(config as DeepPartial); - const collectionsPath = options.data ? options.data : './'; + const collectionsPath = this.getCollectionsPath(options); const collectionReadingConfig = this.getCollectionReadingConfig(options); try { @@ -62,6 +64,14 @@ class CliSeeder { process.exit(0); }; + private getCollectionsPath(options: CommandLineArguments): string { + if (options.data) { + return options.data; + } + + return this.DEFAULT_INPUT_PATH; + } + private getCollectionReadingConfig = ( options: CommandLineArguments, ): SeederCollectionReadingOptions => { diff --git a/cli/src/types.ts b/cli/src/types.ts index 0295e1d..2a48446 100644 --- a/cli/src/types.ts +++ b/cli/src/types.ts @@ -1,4 +1,4 @@ -import { SeederConfig } from 'mongo-seeding'; +import { SeederConfig, SeederCollectionReadingOptions } from 'mongo-seeding'; import { DeepPartial } from 'mongo-seeding/dist/common'; export interface CommandLineOption { @@ -26,7 +26,9 @@ export interface CommandLineArguments { 'transpile-only'?: boolean; } -export type PartialCliOptions = DeepPartial; +export type PartialCliOptions = DeepPartial< + SeederConfig | SeederCollectionReadingOptions | CliSpecificOptions +>; export interface CliSpecificOptions { transpileOnly: boolean; } diff --git a/cli/test/integration/index.ts b/cli/test/integration/index.ts index afc51cf..101d6ce 100644 --- a/cli/test/integration/index.ts +++ b/cli/test/integration/index.ts @@ -141,4 +141,16 @@ describe('CLI', () => { expect(exit).toBeCalledWith(0); } }); + + it('should exit with error on command line arguments error', async () => { + const exit = jest.spyOn(process, 'exit').mockImplementation(code => code); + + process.argv = ['', '', '--what-is-this-parameter', 'dunno']; + await cliSeeder.run(); + + expect(console.error).toBeCalledWith( + expect.stringContaining('InvalidParameterError'), + ); + expect(exit).toBeCalledWith(0); + }); }); diff --git a/cli/test/unit/index.ts b/cli/test/unit/index.ts new file mode 100644 index 0000000..324df22 --- /dev/null +++ b/cli/test/unit/index.ts @@ -0,0 +1,26 @@ +import { cliSeeder } from '../../src/index'; +import { CommandLineArguments } from '../../src/types'; + +describe('Index', () => { + it('should fallback to default input path', () => { + const testCases: Array<{ + options: CommandLineArguments; + expected: string; + }> = [ + { + options: {}, + expected: cliSeeder.DEFAULT_INPUT_PATH, + }, + { + options: { data: '/test/path' }, + expected: '/test/path', + }, + ]; + + for (const testCase of testCases) { + // @ts-ignore + const result = cliSeeder.getCollectionsPath(testCase.options); + expect(result).toEqual(testCase.expected); + } + }); +}); diff --git a/cli/test/unit/options.ts b/cli/test/unit/options.ts index 4bc1f4b..06771d4 100644 --- a/cli/test/unit/options.ts +++ b/cli/test/unit/options.ts @@ -2,7 +2,7 @@ import { createConfigFromOptions, convertEmptyObjectToUndefined, } from '../../src/options'; -import { CommandLineArguments } from '../../src/types'; +import { CommandLineArguments, PartialCliOptions } from '../../src/types'; describe('Options', () => { const previousEnvs = process.env; @@ -18,34 +18,116 @@ describe('Options', () => { }); it('should create config from command line arguments', () => { - const cmdArgs: CommandLineArguments = { - 'db-uri': 'cmdUri', - 'reconnect-timeout': 7000, - }; - - const result = createConfigFromOptions(cmdArgs); - - expect(result).toHaveProperty('database', 'cmdUri'); - expect(result).toHaveProperty('databaseReconnectTimeout', 7000); + const testCases: Array<{ + input: CommandLineArguments; + expected: PartialCliOptions; + }> = [ + { + input: { + 'db-uri': 'cmdUri', + 'reconnect-timeout': 7000, + 'drop-database': true, + 'drop-collections': true, + 'transpile-only': true, + }, + expected: { + database: 'cmdUri', + databaseReconnectTimeout: 7000, + dropDatabase: true, + dropCollections: true, + transpileOnly: true, + }, + }, + { + input: { + 'db-protocol': 'testing://', + 'db-host': 'testHost', + 'db-port': 3232, + 'db-name': 'testName', + 'db-username': 'testUserName', + 'db-password': 'testPasswd', + }, + expected: { + database: { + protocol: 'testing://', + host: 'testHost', + port: 3232, + name: 'testName', + username: 'testUserName', + password: 'testPasswd', + }, + dropDatabase: false, + dropCollections: false, + transpileOnly: false, + }, + }, + ]; - expect(result).toMatchObject({ - database: 'cmdUri', - databaseReconnectTimeout: 7000, - }); + for (const testCase of testCases) { + const result = createConfigFromOptions(testCase.input); + expect(result).toMatchObject(testCase.expected); + } }); it('should read options from environmental variables', () => { - process.env.DB_URI = 'envUri'; - process.env.RECONNECT_TIMEOUT = '5000'; - process.env.DROP_DATABASE = 'true'; + interface Envs { + [key: string]: string; + } + const testCases: Array<{ + envs: Envs; + expected: PartialCliOptions; + }> = [ + { + envs: { + DB_URI: 'cmdUri', + RECONNECT_TIMEOUT: '7000', + DROP_DATABASE: 'true', + DROP_COLLECTIONS: 'true', + TRANSPILE_ONLY: 'true', + }, + expected: { + database: 'cmdUri', + databaseReconnectTimeout: 7000, + dropDatabase: true, + dropCollections: true, + transpileOnly: true, + }, + }, + { + envs: { + DB_PROTOCOL: 'testing://', + DB_HOST: 'testHost', + DB_PORT: '3232', + DB_NAME: 'testName', + DB_USERNAME: 'testUserName', + DB_PASSWORD: 'testPasswd', + }, + expected: { + database: { + protocol: 'testing://', + host: 'testHost', + port: 3232, + name: 'testName', + username: 'testUserName', + password: 'testPasswd', + }, + dropDatabase: false, + dropCollections: false, + transpileOnly: false, + }, + }, + ]; + + for (const testCase of testCases) { + Object.keys(testCase.envs).forEach(key => { + process.env[key] = testCase.envs[key]; + }); - const result = createConfigFromOptions({}); + const result = createConfigFromOptions({}); + expect(result).toMatchObject(testCase.expected); - expect(result).toMatchObject({ - database: 'envUri', - databaseReconnectTimeout: 5000, - dropDatabase: true, - }); + process.env = previousEnvs; + } }); it('should overwrite environmental variables with command line arguments', () => {