diff --git a/.vscode/launch.json b/.vscode/launch.json index 11796409be2a..c6adda413542 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,8 +11,8 @@ "program": "${workspaceRoot}/packages/build/node_modules/.bin/_mocha", "cwd": "${workspaceRoot}", "args": [ - "--opts", - "${workspaceRoot}/test/mocha.opts", + "--config", + "${workspaceRoot}/packages/build/config/.mocharc.json", "packages/*/dist/__tests__/**/*.js", "-t", "0" diff --git a/docs/site/todo-tutorial-scaffolding.md b/docs/site/todo-tutorial-scaffolding.md index 60d1a3ab6062..c4223068a663 100644 --- a/docs/site/todo-tutorial-scaffolding.md +++ b/docs/site/todo-tutorial-scaffolding.md @@ -78,29 +78,30 @@ package.json tsconfig.json tslint.build.json tslint.json +.mocharc.json ``` -| File | Purpose | -| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `index.ts` | Allows importing contents of the `src` folder (for use elsewhere) | -| `index.js` | Top-level file connecting components of the application. | -| `package.json` | Your application's package manifest. See [package.json](https://docs.npmjs.com/files/package.json) for details. | -| `tsconfig.json` | The TypeScript project configuration. See [tsconfig.json](http://www.typescriptlang.org/docs/handbook/tsconfig-json.html) for details. | -| `tslint.json` | [TSLint configuration](https://palantir.github.io/tslint/usage/tslint-json/) | -| `tslint.build.json` | [TSLint configuration (build only)](https://palantir.github.io/tslint/usage/tslint-json/) | -| `README.md` | The Markdown-based README generated for your application. | -| `LICENSE` | A copy of the MIT license. If you do not wish to use this license, please delete this file. | -| `src/application.ts` | The application class, which extends [`RestApplication`](http://apidocs.strongloop.com/@loopback%2fdocs/rest.html#RestApplication) by default. This is the root of your application, and is where your application will be configured. It also extends [`RepositoryMixin`](https://apidocs.strongloop.com/@loopback%2fdocs/repository.html#RepositoryMixin) which defines the datasource. | -| `src/index.ts` | The starting point of your microservice. This file creates an instance of your application, runs the booter, then attempts to start the [`RestServer`](http://apidocs.strongloop.com/@loopback%2fdocs/rest.html#RestServer) instance bound to the application. | -| `src/sequence.ts` | An extension of the [Sequence](Sequence.md) class used to define the set of actions to take during a REST request/response. | -| `src/controllers/README.md` | Provides information about the controller directory, how to generate new controllers, and where to find more information. | -| `src/controllers/ping.controller.ts` | A basic controller that responds to GET requests at `/ping`. | -| `src/datasources/README.md` | Provides information about the datasources directory, how to generate new datasources, and where to find more information. | -| `src/models/README.md` | Provides information about the models directory, how to generate new models, and where to find more information. | -| `src/repositories/README.md` | Provides information about the repositories directory, how to generate new repositories, and where to find more information. | -| `src/__tests__/README.md` | Please place your tests in this folder. | -| `src/test/mocha.opts` | [Mocha](https://mochajs.org/) configuration for running your application's tests. | -| `src/__tests__/acceptance/ping.controller.acceptance.ts` | An example test to go with the ping controller in `src/controllers`. | +| File | Purpose | +| ---------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `index.ts` | Allows importing contents of the `src` folder (for use elsewhere) | +| `index.js` | Top-level file connecting components of the application. | +| `package.json` | Your application's package manifest. See [package.json](https://docs.npmjs.com/files/package.json) for details. | +| `tsconfig.json` | The TypeScript project configuration. See [tsconfig.json](http://www.typescriptlang.org/docs/handbook/tsconfig-json.html) for details. | +| `tslint.json` | [TSLint configuration](https://palantir.github.io/tslint/usage/tslint-json/) | +| `tslint.build.json` | [TSLint configuration (build only)](https://palantir.github.io/tslint/usage/tslint-json/) | +| `README.md` | The Markdown-based README generated for your application. | +| `LICENSE` | A copy of the MIT license. If you do not wish to use this license, please delete this file. | +| `src/application.ts` | The application class, which extends [`RestApplication`](http://apidocs.strongloop.com/@loopback%2fdocs/rest.html#RestApplication) by default. This is the root of your application, and is where your application will be configured. It also extends [`RepositoryMixin`](https://apidocs.strongloop.com/@loopback%2fdocs/repository.html#RepositoryMixin) which defines the datasource. | +| `src/index.ts` | The starting point of your microservice. This file creates an instance of your application, runs the booter, then attempts to start the [`RestServer`](http://apidocs.strongloop.com/@loopback%2fdocs/rest.html#RestServer) instance bound to the application. | +| `src/sequence.ts | An extension of the [Sequence](Sequence.md) class used to define the set of actions to take during a REST request/response. | +| `src/controllers/README.md` | Provides information about the controller directory, how to generate new controllers, and where to find more information. | +| `src/controllers/ping.controller.ts` | A basic controller that responds to GET requests at `/ping`. | +| `src/datasources/README.md` | Provides information about the datasources directory, how to generate new datasources, and where to find more information. | +| `src/models/README.md` | Provides information about the models directory, how to generate new models, and where to find more information. | +| `src/repositories/README.md` | Provides information about the repositories directory, how to generate new repositories, and where to find more information. | +| `src/__tests__/README.md` | Please place your tests in this folder. | +| `src/__tests__/acceptance/ping.controller.acceptance.ts` | An example test to go with the ping controller in `src/controllers`. | +| `.mocharc.json` | [Mocha](https://mochajs.org/) configuration for running your application's tests. | ### Navigation diff --git a/packages/build/bin/run-mocha.js b/packages/build/bin/run-mocha.js index ea6e3365f68d..7a026bdac1dc 100755 --- a/packages/build/bin/run-mocha.js +++ b/packages/build/bin/run-mocha.js @@ -23,16 +23,22 @@ function run(argv, options) { const mochaOpts = argv.slice(2).map(a => a.replace(/\bDIST\b/g, dist)); const setMochaOpts = - !utils.isOptionSet(mochaOpts, '--opts') && - !utils.mochaOptsFileProjectExists(); + !utils.isOptionSet( + mochaOpts, + '--config', // mocha 6.x + '--opts', // legacy + '--package', // mocha 6.x + '--no-config', // mocha 6.x + ) && !utils.mochaConfiguredForProject(); // Add default options // Keep it backward compatible as dryRun if (typeof options === 'boolean') options = {dryRun: options}; options = options || {}; if (setMochaOpts) { - const mochaOptsFile = utils.getConfigFile('mocha.opts'); - mochaOpts.unshift('--opts', mochaOptsFile); + // Use the default `.mocharc.json` from `@loopback/build` + const mochaOptsFile = utils.getConfigFile('.mocharc.json'); + mochaOpts.unshift('--config', mochaOptsFile); } const allowConsoleLogsIx = mochaOpts.indexOf('--allow-console-logs'); diff --git a/packages/build/bin/utils.js b/packages/build/bin/utils.js index 2cefc80b8c94..2aed68dbf403 100644 --- a/packages/build/bin/utils.js +++ b/packages/build/bin/utils.js @@ -214,9 +214,18 @@ function isOptionSet(opts, ...optionNames) { ); } -function mochaOptsFileProjectExists() { - const configFile = path.join(getPackageDir(), 'test/mocha.opts'); - return fs.existsSync(configFile); +function mochaConfiguredForProject() { + const configFiles = [ + '.mocharc.js', + '.mocharc.json', + '.mocharc.yaml', + '.mocharc.yml', + 'test/mocha.opts', + ]; + return configFiles.some(f => { + const configFile = path.join(getPackageDir(), f); + return fs.existsSync(configFile); + }); } exports.getCompilationTarget = getCompilationTarget; @@ -228,4 +237,4 @@ exports.resolveCLI = resolveCLI; exports.runCLI = runCLI; exports.runShell = runShell; exports.isOptionSet = isOptionSet; -exports.mochaOptsFileProjectExists = mochaOptsFileProjectExists; +exports.mochaConfiguredForProject = mochaConfiguredForProject; diff --git a/packages/build/config/.mocharc.json b/packages/build/config/.mocharc.json new file mode 100644 index 000000000000..1be483a88471 --- /dev/null +++ b/packages/build/config/.mocharc.json @@ -0,0 +1,7 @@ +{ + "require": "source-map-support/register", + "recursive": true, + "exit": true, + "reporter": "dot" +} + diff --git a/packages/build/config/mocha.opts b/packages/build/config/mocha.opts deleted file mode 100644 index cec80804eedb..000000000000 --- a/packages/build/config/mocha.opts +++ /dev/null @@ -1,4 +0,0 @@ ---require source-map-support/register ---recursive ---exit ---reporter dot diff --git a/packages/build/test/integration/scripts.integration.js b/packages/build/test/integration/scripts.integration.js index 273eb66f8601..aa37d3d9df69 100644 --- a/packages/build/test/integration/scripts.integration.js +++ b/packages/build/test/integration/scripts.integration.js @@ -365,7 +365,7 @@ describe('mocha', function() { function cleanup() { var run = require('../../bin/run-clean'); - run(['node', 'bin/run-clean', 'test/mocha.opts']); + run(['node', 'bin/run-clean', '.mocharc.json']); } beforeEach(() => { @@ -378,42 +378,50 @@ describe('mocha', function() { process.chdir(cwd); }); - it('loads built-in mocha.opts file', () => { + it('loads built-in .mocharc.json file', () => { var run = require('../../bin/run-mocha'); var command = run(['node', 'bin/run-mocha', '"dist/__tests__"'], true); const builtInMochaOptsFile = path.join( __dirname, - '../../config/mocha.opts', + '../../config/.mocharc.json', ); assert( command.indexOf(builtInMochaOptsFile) !== -1, - '--opts should be set by default', + '--config should be set by default', ); }); - it('honors --opts option', () => { + it('honors --config option', () => { var run = require('../../bin/run-mocha'); var command = run( - ['node', 'bin/run-mocha', '--opts custom/mocha.opts', '"dist/__tests__"'], + [ + 'node', + 'bin/run-mocha', + '--config custom/.mocharc.json', + '"dist/__tests__"', + ], true, ); assert( - command.indexOf('--opts custom/mocha.opts') !== -1, - '--opts custom/mocha.opts should be honored', + command.indexOf('--config custom/.mocharc.json') !== -1, + '--config custom/.mocharc.json should be honored', ); }); - it('loads mocha.opts specific project file', () => { + it('loads .mocharc.json specific project file', () => { var run = require('../../bin/run-mocha'); - const buitInMochaOptsPath = path.join(__dirname, '../../config/mocha.opts'); - const destPath = path.join(__dirname, './fixtures/test/mocha.opts'); + const buitInMochaOptsPath = path.join( + __dirname, + '../../config/.mocharc.json', + ); + const destPath = path.join(__dirname, './fixtures/.mocharc.json'); fs.copyFileSync(buitInMochaOptsPath, destPath); var command = run(['node', 'bin/run-mocha', '"dist/__tests__"'], true); assert( - command.indexOf('--opts') === -1, - 'should skip built-in mocha.opts file when specific project file exist', + command.indexOf('--config') === -1, + 'should skip built-in .mocharc.json file when specific project file exist', ); }); }); diff --git a/packages/cli/generators/project/templates/.mocharc.json b/packages/cli/generators/project/templates/.mocharc.json new file mode 100644 index 000000000000..c00241bf8d84 --- /dev/null +++ b/packages/cli/generators/project/templates/.mocharc.json @@ -0,0 +1,4 @@ +{ + "recursive": true, + "require": "source-map-support/register" +} diff --git a/packages/cli/generators/project/templates/test/mocha.opts b/packages/cli/generators/project/templates/test/mocha.opts deleted file mode 100644 index 43f24ebc7b3d..000000000000 --- a/packages/cli/generators/project/templates/test/mocha.opts +++ /dev/null @@ -1,2 +0,0 @@ ---recursive ---require source-map-support/register diff --git a/packages/cli/lib/project-generator.js b/packages/cli/lib/project-generator.js index 73f281870c70..7203bb180a51 100644 --- a/packages/cli/lib/project-generator.js +++ b/packages/cli/lib/project-generator.js @@ -255,7 +255,7 @@ module.exports = class ProjectGenerator extends BaseGenerator { } if (!this.projectInfo.mocha) { - this.fs.delete(this.destinationPath('test/mocha.opts')); + this.fs.delete(this.destinationPath('.mocharc.json')); } if (!this.projectInfo.vscode) {