Вход Регистрация
Файл: error-kitty/node_modules/mocha/lib/runnable.js
Строк: 275
<?php
/**
 * Module dependencies.
 */

var EventEmitter = require('events').EventEmitter
  
, debug = require('debug')('mocha:runnable')
  , 
milliseconds = require('./ms');

/**
 * Save timer references to avoid Sinon interfering (see GH-237).
 */

var Date = global.Date
  
, setTimeout = global.setTimeout
  
, setInterval = global.setInterval
  
, clearTimeout = global.clearTimeout
  
, clearInterval = global.clearInterval;

/**
 * Object#toString().
 */

var toString = Object.prototype.toString;

/**
 * Expose `Runnable`.
 */

module.exports = Runnable;

/**
 * Initialize a new `Runnable` with the given `title` and callback `fn`.
 *
 * @param {String} title
 * @param {Function} fn
 * @api private
 */

function Runnable(title, fn) {
  
this.title = title;
  
this.fn = fn;
  
this.async = fn && fn.length;
  
this.sync = ! this.async;
  
this._timeout = 2000;
  
this._slow = 75;
  
this._enableTimeouts = true;
  
this.timedOut = false;
}

/**
 * Inherit from `EventEmitter.prototype`.
 */

Runnable.prototype.__proto__ = EventEmitter.prototype;

/**
 * Set & get timeout `ms`.
 *
 * @param {Number|String} ms
 * @return {Runnable|Number} ms or self
 * @api private
 */

Runnable.prototype.timeout = function(ms){
  if (
0 == arguments.length) return this._timeout;
  if (
ms === 0) this._enableTimeouts = false;
  if (
'string' == typeof ms) ms = milliseconds(ms);
  
debug('timeout %d', ms);
  
this._timeout = ms;
  if (
this.timer) this.resetTimeout();
  return 
this;
};

/**
 * Set & get slow `ms`.
 *
 * @param {Number|String} ms
 * @return {Runnable|Number} ms or self
 * @api private
 */

Runnable.prototype.slow = function(ms){
  if (
0 === arguments.length) return this._slow;
  if (
'string' == typeof ms) ms = milliseconds(ms);
  
debug('timeout %d', ms);
  
this._slow = ms;
  return 
this;
};

/**
 * Set and & get timeout `enabled`.
 *
 * @param {Boolean} enabled
 * @return {Runnable|Boolean} enabled or self
 * @api private
 */

Runnable.prototype.enableTimeouts = function(enabled){
  if (
arguments.length === 0) return this._enableTimeouts;
  
debug('enableTimeouts %s', enabled);
  
this._enableTimeouts = enabled;
  return 
this;
};

/**
 * Return the full title generated by recursively
 * concatenating the parent's full title.
 *
 * @return {String}
 * @api public
 */

Runnable.prototype.fullTitle = function(){
  return 
this.parent.fullTitle() + ' ' + this.title;
};

/**
 * Clear the timeout.
 *
 * @api private
 */

Runnable.prototype.clearTimeout = function(){
  
clearTimeout(this.timer);
};

/**
 * Inspect the runnable void of private properties.
 *
 * @return {String}
 * @api private
 */

Runnable.prototype.inspect = function(){
  return 
JSON.stringify(this, function(key, val){
    if (
'_' == key[0]) return;
    if (
'parent' == key) return '#<Suite>';
    if (
'ctx' == key) return '#<Context>';
    return 
val;
  }, 
2);
};

/**
 * Reset the timeout.
 *
 * @api private
 */

Runnable.prototype.resetTimeout = function(){
  var 
self = this;
  var 
ms = this.timeout() || 1e9;

  if (!
this._enableTimeouts) return;
  
this.clearTimeout();
  
this.timer = setTimeout(function(){
    
self.callback(new Error('timeout of ' + ms + 'ms exceeded'));
    
self.timedOut = true;
  }, 
ms);
};

/**
 * Whitelist these globals for this test run
 *
 * @api private
 */
Runnable.prototype.globals = function(arr){
  var 
self = this;
  
this._allowedGlobals = arr;
};

/**
 * Run the test and invoke `fn(err)`.
 *
 * @param {Function} fn
 * @api private
 */

Runnable.prototype.run = function(fn){
  var 
self = this
    
, start = new Date
    
, ctx = this.ctx
    
, finished
    
, emitted;

  
// Some times the ctx exists but it is not runnable
  
if (ctx && ctx.runnable) ctx.runnable(this);

  
// called multiple times
  
function multiple(err) {
    if (
emitted) return;
    
emitted = true;
    
self.emit('error', err || new Error('done() called multiple times'));
  }

  
// finished
  
function done(err) {
    var 
ms = self.timeout();
    if (
self.timedOut) return;
    if (
finished) return multiple(err);
    
self.clearTimeout();
    
self.duration = new Date - start;
    
finished = true;
    if (!
err && self.duration > ms && self._enableTimeouts) err = new Error('timeout of ' + ms + 'ms exceeded');
    
fn(err);
  }

  
// for .resetTimeout()
  
this.callback = done;

  
// explicit async with `done` argument
  
if (this.async) {
    
this.resetTimeout();

    try {
      
this.fn.call(ctx, function(err){
        if (
err instanceof Error || toString.call(err) === "[object Error]") return done(err);
        if (
null != err) {
          if (
Object.prototype.toString.call(err) === '[object Object]') {
            return 
done(new Error('done() invoked with non-Error: ' + JSON.stringify(err)));
          } else {
            return 
done(new Error('done() invoked with non-Error: ' + err));
          }
        }
        
done();
      });
    } catch (
err) {
      
done(err);
    }
    return;
  }

  if (
this.asyncOnly) {
    return 
done(new Error('--async-only option in use without declaring `done()`'));
  }

  
// sync or promise-returning
  
try {
    if (
this.pending) {
      
done();
    } else {
      
callFn(this.fn);
    }
  } catch (
err) {
    
done(err);
  }

  function 
callFn(fn) {
    var 
result = fn.call(ctx);
    if (
result && typeof result.then === 'function') {
      
self.resetTimeout();
      
result
        
.then(function() {
          
done()
        },
        function(
reason) {
          
done(reason || new Error('Promise rejected with no or falsy reason'))
        });
    } else {
      
done();
    }
  }
};
?>
Онлайн: 1
Реклама