/**
 * Runner that executes code and runs mocha if needed
 */

const utils = require('../utils');
const context = require('./context');
const FileRunner = require('./file-runner');
const MochaRunner = require('./mocha-runner');
const htmlReporter = require('../reporter/html');
const logger = require('../utils/logger').create('Runner');


class Runner {
  /**
   * Runs array of code snippets
   *
   * @param {Object[]} files
   * @param {String} files[].code
   * @param {String} files[].path
   * @param {Object} [options]
   * @param {Object} [options.window]
   * @param {Number} [options.timeout]
   * @returns {Promise}
   */
  run(files, options) {
    this._files = Array.isArray(files) ? files : [];
    logger.log(`Running ${this._files.length} file(s)`);
    this._context = context.create({
      console: options.window.sharedConsole,
    });
    this._setupMocha(options);
    return this._runFiles()
      .then(() => this._mochaRunner.hasTests() ? this._mochaRunner.run() : null)
      .then(() => this._finish());
  }

  _finish() {
    logger.log(`Finished ${this._files.length} file(s)`);
  }

  _setupMocha(options) {
    this._mochaRunner = new MochaRunner(this._context);
    this._mochaRunner.setup({
      reporter: htmlReporter.getReporter(options.window),
      timeout: options.timeout,
    });
  }

  _runFiles() {
    return this._files.reduce((res, file) => {
      this._context.__filename = file.path;
      return res.then(() => new FileRunner(file.code, file.path, this._context).run());
    }, Promise.resolve());
  }
}

module.exports = Runner;

/**
 * Run tests
 *
 * @param {Object} params
 * @param {Array} params.urls
 * @param {Object} params.window
 * @param {Number} [params.timeout]
 * @returns {Promise}
 */
exports.run = function (params) {
  return Promise.resolve()
    .then(() => runMocha.setup(params))
    .then(() => fetchFiles(params.urls))
    .then(files => runFiles(files, params.window))
    .then(() => runMocha.hasTests() ? runMocha.run() : null)
    .then(() => finish())
};

function fetchFiles(urls) {
  return urls ? utils.fetchTextFromUrls(urls) : [];
}

@@ -56,16 +56,75 @@
 ed%0A */%0A%0A
+const promise = require('selenium-webdriver/lib/promise');%0A
 const ut
@@ -146,24 +146,24 @@
 ../utils');%0A
-
 const contex
@@ -413,16 +413,138 @@
 %7B%0A  /**%0A
+   * Constructor%0A   */%0A  constructor() %7B%0A    // use default controlflow%0A    this._flow = promise.controlFlow();%0A  %7D%0A  /**%0A
    * Run
@@ -824,32 +824,56 @@
 les, options) %7B%0A
+    this._flow.reset();%0A
     this._files 
@@ -1756,16 +1756,16 @@
 %0A  %7D%0A%7D%0A%0A
+
 module.e
@@ -1785,542 +1785,4 @@
 er;%0A
-%0A/**%0A * Run tests%0A *%0A * @param %7BObject%7D params%0A * @param %7BArray%7D params.urls%0A * @param %7BObject%7D params.window%0A * @param %7BNumber%7D %5Bparams.timeout%5D%0A * @returns %7BPromise%7D%0A */%0Aexports.run = function (params) %7B%0A  return Promise.resolve()%0A    .then(() =%3E runMocha.setup(params))%0A    .then(() =%3E fetchFiles(params.urls))%0A    .then(files =%3E runFiles(files, params.window))%0A    .then(() =%3E runMocha.hasTests() ? runMocha.run() : null)%0A    .then(() =%3E finish())%0A%7D;%0A%0Afunction fetchFiles(urls) %7B%0A  return urls ? utils.fetchTextFromUrls(urls) : %5B%5D;%0A%7D%0A

reset flow before run