| 'use strict'; |
| |
| const utils = require('../utils'); |
| const Context = require('../context'); |
| const Mocha = require('../mocha'); |
| const collectFiles = require('./collect-files'); |
| |
| /** |
| * Exports the `watchRun` function that runs mocha in "watch" mode. |
| * @see module:lib/cli/run-helpers |
| * @module |
| * @private |
| */ |
| |
| /** |
| * Run Mocha in "watch" mode |
| * @param {Mocha} mocha - Mocha instance |
| * @param {Object} opts - Options |
| * @param {string} opts.ui - User interface |
| * @param {Object} fileCollectParams - Parameters that control test |
| * file collection. See `lib/cli/collect-files.js`. |
| * @param {string[]} fileCollectParams.extension - List of extensions to watch |
| * @private |
| */ |
| module.exports = (mocha, {ui}, fileCollectParams) => { |
| let runner; |
| const files = collectFiles(fileCollectParams); |
| |
| console.log(); |
| hideCursor(); |
| process.on('SIGINT', () => { |
| showCursor(); |
| console.log('\n'); |
| // By UNIX/Posix convention this indicates that the process was |
| // killed by SIGINT which has portable number 2. |
| process.exit(128 + 2); |
| }); |
| |
| const watchFiles = utils.files(process.cwd(), fileCollectParams.extension); |
| let runAgain = false; |
| |
| const loadAndRun = () => { |
| try { |
| mocha.files = files; |
| runAgain = false; |
| runner = mocha.run(() => { |
| runner = null; |
| if (runAgain) { |
| rerun(); |
| } |
| }); |
| } catch (e) { |
| console.log(e.stack); |
| } |
| }; |
| |
| const purge = () => { |
| watchFiles.forEach(Mocha.unloadFile); |
| }; |
| |
| loadAndRun(); |
| |
| const rerun = () => { |
| purge(); |
| eraseLine(); |
| mocha.suite = mocha.suite.clone(); |
| mocha.suite.ctx = new Context(); |
| mocha.ui(ui); |
| loadAndRun(); |
| }; |
| |
| utils.watch(watchFiles, () => { |
| runAgain = true; |
| if (runner) { |
| runner.abort(); |
| } else { |
| rerun(); |
| } |
| }); |
| }; |
| |
| /** |
| * Hide the cursor. |
| * @ignore |
| * @private |
| */ |
| const hideCursor = () => { |
| process.stdout.write('\u001b[?25l'); |
| }; |
| |
| /** |
| * Show the cursor. |
| * @ignore |
| * @private |
| */ |
| const showCursor = () => { |
| process.stdout.write('\u001b[?25h'); |
| }; |
| |
| /** |
| * Erases the line on stdout |
| * @private |
| */ |
| const eraseLine = () => { |
| process.stdout.write('\u001b[2K'); |
| }; |