text: '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');
  };
  