<commit_before>import Utils from "backburner/utils";
import { DeferredActionQueues } from "backburner/deferred_action_queues";

var slice = [].slice;
var pop = [].pop;
var each = Utils.each;
var isString = Utils.isString;
var isFunction = Utils.isFunction;
var isNumber = Utils.isNumber;
var timers = [];
var global = this;
var NUMBER = /\d+/;

// In IE 6-8, try/finally doesn't work without a catch.
// Unfortunately, this is impossible to test for since wrapping it in a parent try/catch doesn't trigger the bug.
// This tests for another broken try/catch behavior that only exhibits in the same versions of IE.
var needsIETryCatchFix = (function(e,x){
  try{ x(); }
  catch(e) { } // jshint ignore:line
  return !!e;
})();

function isCoercableNumber(number) {
  return isNumber(number) || NUMBER.test(number);
}

function Backburner(queueNames, options) {
  this.queueNames = queueNames;
  this.options = options || {};
  if (!this.options.defaultQueue) {
    this.options.defaultQueue = queueNames[0];
  }
  this.instanceStack = [];
  this._debouncees = [];
  this._throttlers = [];
}

Backburner.prototype = {
  queueNames: null,
  options: null,
  currentInstance: null,
  instanceStack: null,

  begin: function() {
    var options = this.options;
    var onBegin = options && options.onBegin;
    var previousInstance = this.currentInstance;

    if (previousInstance) {
      this.instanceStack.push(previousInstance);
    }

    this.currentInstance = new DeferredActionQueues(this.queueNames, options);
    if (onBegin) {
      onBegin(this.currentInstance, previousInstance);
    }
  },

  end: function() {
    var options = this.options;
    var onEnd = options && options.onEnd;
    var currentInstance = this.currentInstance;
    var nextInstance = null;

    // Prevent double-finally bug in Safari 6.0.2 and iOS 6
    // This bug appears to be resolved in Safari 6.0.5 and iOS 7
    var finallyAlreadyCalled = false;
    try {
      currentInstance.flush();
    } finally {
      if (!finallyAlreadyCalled) {
        finallyAlreadyCalled = true;

        this.currentInstance = null;

        if (this.instanceStack.length) {
          nextInstance = this.instanceStack.pop();
          this.currentInstance = nextInstance;
        }

        if (onEnd) {
          onEnd(currentInstance, nextInstance);
        }
      }
    }
  },

  run: function(target, method /*, args */) {
    var onError = getOnError(this.options);

    this.begin();

    if (!method) {
      method = target;
      target = null;
    }

    if (isString(method)) {
      method = target[method];
    }

    var args = slice.call(arguments, 2);

    // guard against Safari 6's double-finally bug
    var didFinally = false;

    if (onError) {
      try {
        return method.apply(target, args);
      } catch(error) {
        onError(error);
      } finally {
        if (!didFinally) {
          didFinally = true;
          this.end();
        }
      }
    } else {
      try {
        return method.apply(target, args);
      } finally {
        if (!didFinally) {
          didFinally = true;
          this.end();
        }
      }
    }
  },

  defer: function(queueName, target, method /* , args */) {
    if (!method) {
      method = target;
      target = null;
    }

    if (isString(method)) {
      method = target[method];
    }

    var stack = this.DEBUG ? new Error() : undefined;
    var length = arguments.length;
    var args;

    if (length > 3) {
      args = new Array(length - 3);
      for (var i = 3; i < length; i++) {
        args[i-3] = arguments[i];
      }
    } else {
      args = undefined;
    }

    if (!this.currentInstance) { createAutorun(this); }
    return this.currentInstance.schedule(queueName, target, method, args, false, stack);
  },

  deferOnce: function(queueName, target, method /* , args */) {
    if (!method) {
      method = target;
      target = null;
    }

    if (isString(method)) {
      method = target[method];
    }

    var stack = this.DEBUG ? new Error() : undefined;
    var length = arguments.length;
    var args;

    if (length > 3) {
      args = new Array(length - 3);
      for (var i = 3; i < length; i++) {
        args[i-3] = arguments[i];
      }
    } else {
      args = undefined;
    }

    if (!this.currentInstance) { createAutorun(this); }
    return this.currentInstance.schedule(queueName, target, method, args, true, stack);
  },

  setTimeout: function() {
    var l = arguments.length;
    var args = new Array(l);
    for (var x = 0; x < l; x++) {
      args[x] = arguments[x];
    }
    var length = args.length,
        method, wait, target,
        methodOrTarget, methodOrWait, methodOrArgs;

    if (length === 0) {
      return;
    } else if (length === 1) {
      method = args.shift();
      wait = 0;
    } else if (length === 2) {
      methodOrTarget = args[0];
      methodOrWait = args[1];

      if (isFunction(methodOrWait) || isFunction(methodOrTarget[methodOrWait])) {
        target = args.shift();
        method = args.shift();
        wait = 0;
      } else if (isCoercableNumber(methodOrWait)) {
        method = args.shift();
        wait = args.shift();
      } else {
        method = args.shift();
        wait =  0;
      }
    } else {
      var last = args[args.length - 1];

      if (isCoercableNumber(last)) {
        wait = args.pop();
      } else {
        wait = 0;
      }

      methodOrTarget = args[0];
      methodOrArgs = args[1];

      if (isFunction(methodOrArgs) || (isString(methodOrArgs) &&
                                      methodOrTarget !== null &&
                                      methodOrArgs in methodOrTarget)) {
        target = args.shift();
        method = args.shift();
      } else {
        method = args.shift();
      }
    }

    var executeAt = (+new Date()) + parseInt(wait, 10);

    if (isString(method)) {
      method = target[method];
    }

    var onError = getOnError(this.options);

    function fn() {
      if (onError) {
        try {
          method.apply(target, args);
        } catch (e) {
          onError(e);
        }
      } else {
        method.apply(target, args);
      }
    }

    // find position to insert
    var i = searchTimer(executeAt, timers);

    timers.splice(i, 0, executeAt, fn);

    updateLaterTimer(this, executeAt, wait);

    return fn;
  },

  throttle: function(target, method /* , args, wait, [immediate] */) {
    var self = this;
    var args = arguments;
    var immediate = pop.call(args);
    var wait, throttler, index, timer;

    if (isNumber(immediate) || isString(immediate)) {
      wait = immediate;
      immediate = true;
    } else {
      wait = pop.call(args);
    }

    wait = parseInt(wait, 10);

    index = findThrottler(target, method, this._throttlers);
    if (index > -1) { return this._throttlers[index]; } // throttled

    timer = global.setTimeout(function() {
      if (!immediate) {
        self.run.apply(self, args);
      }
      var index = findThrottler(target, method, self._throttlers);
      if (index > -1) {
        self._throttlers.splice(index, 1);
      }
    }, wait);

    if (immediate) {
      self.run.apply(self, args);
    }

    throttler = [target, method, timer];

    this._throttlers.push(throttler);

    return throttler;
  },

  debounce: function(target, method /* , args, wait, [immediate] */) {
    var self = this;
    var args = arguments;
    var immediate = pop.call(args);
    var wait, index, debouncee, timer;

    if (isNumber(immediate) || isString(immediate)) {
      wait = immediate;
      immediate = false;
    } else {
      wait = pop.call(args);
    }

    wait = parseInt(wait, 10);
    // Remove debouncee
    index = findDebouncee(target, method, this._debouncees);

    if (index > -1) {
      debouncee = this._debouncees[index];
      this._debouncees.splice(index, 1);
      clearTimeout(debouncee[2]);
    }

    timer = global.setTimeout(function() {
      if (!immediate) {
        self.run.apply(self, args);
      }
      var index = findDebouncee(target, method, self._debouncees);
      if (index > -1) {
        self._debouncees.splice(index, 1);
      }
    }, wait);

    if (immediate && index === -1) {
      self.run.apply(self, args);
    }

    debouncee = [target, method, timer];

    self._debouncees.push(debouncee);

    return debouncee;
  },

  cancelTimers: function() {
    var clearItems = function(item) {
      clearTimeout(item[2]);
    };

    each(this._throttlers, clearItems);
    this._throttlers = [];

    each(this._debouncees, clearItems);
    this._debouncees = [];

    if (this._laterTimer) {
      clearTimeout(this._laterTimer);
      this._laterTimer = null;
    }
    timers = [];

    if (this._autorun) {
      clearTimeout(this._autorun);
      this._autorun = null;
    }
  },

  hasTimers: function() {
    return !!timers.length || !!this._debouncees.length || !!this._throttlers.length || this._autorun;
  },

  cancel: function(timer) {
    var timerType = typeof timer;

    if (timer && timerType === 'object' && timer.queue && timer.method) { // we're cancelling a deferOnce
      return timer.queue.cancel(timer);
    } else if (timerType === 'function') { // we're cancelling a setTimeout
      for (var i = 0, l = timers.length; i < l; i += 2) {
        if (timers[i + 1] === timer) {
          timers.splice(i, 2); // remove the two elements
          if (i === 0) {
            if (this._laterTimer) { // Active timer? Then clear timer and reset for future timer
              clearTimeout(this._laterTimer);
              this._laterTimer = null;
            }
            if (timers.length > 0) { // Update to next available timer when available
              updateLaterTimer(this, timers[0], timers[0] - (+new Date()));
            }
          }
          return true;
        }
      }
    } else if (Object.prototype.toString.call(timer) === "[object Array]"){ // we're cancelling a throttle or debounce
      return this._cancelItem(findThrottler, this._throttlers, timer) ||
               this._cancelItem(findDebouncee, this._debouncees, timer);
    } else {
      return; // timer was null or not a timer
    }
  },

  _cancelItem: function(findMethod, array, timer){
    var item, index;

    if (timer.length < 3) { return false; }

    index = findMethod(timer[0], timer[1], array);

    if (index > -1) {

      item = array[index];

      if (item[2] === timer[2]) {
        array.splice(index, 1);
        clearTimeout(timer[2]);
        return true;
      }
    }

    return false;
  }
};

Backburner.prototype.schedule = Backburner.prototype.defer;
Backburner.prototype.scheduleOnce = Backburner.prototype.deferOnce;
Backburner.prototype.later = Backburner.prototype.setTimeout;

if (needsIETryCatchFix) {
  var originalRun = Backburner.prototype.run;
  Backburner.prototype.run = wrapInTryCatch(originalRun);

  var originalEnd = Backburner.prototype.end;
  Backburner.prototype.end = wrapInTryCatch(originalEnd);
}

function wrapInTryCatch(func) {
  return function () {
    try {
      return func.apply(this, arguments);
    } catch (e) {
      throw e;
    }
  };
}

function getOnError(options) {
  return options.onError || (options.onErrorTarget && options.onErrorTarget[options.onErrorMethod]);
}

function createAutorun(backburner) {
  backburner.begin();
  backburner._autorun = global.setTimeout(function() {
    backburner._autorun = null;
    backburner.end();
  });
}

function updateLaterTimer(self, executeAt, wait) {
  var now = (+new Date());
  if (!self._laterTimer || executeAt < self._laterTimerExpiresAt || self._laterTimerExpiresAt < now) {

    if (self._laterTimer) {
      // Clear when:
      // - Already expired
      // - New timer is earlier
      clearTimeout(self._laterTimer);

      if (self._laterTimerExpiresAt < now) { // If timer was never triggered
        // Calculate the left-over wait-time
        wait = Math.max(0, executeAt - now);
      }
    }

    self._laterTimer = global.setTimeout(function() {
      self._laterTimer = null;
      self._laterTimerExpiresAt = null;
      executeTimers(self);
    }, wait);

    self._laterTimerExpiresAt = now + wait;
  }
}

function executeTimers(self) {
  var now = +new Date();
  var fns, i, l;

  self.run(function() {
    i = searchTimer(now, timers);

    fns = timers.splice(0, i);

    for (i = 1, l = fns.length; i < l; i += 2) {
      self.schedule(self.options.defaultQueue, null, fns[i]);
    }
  });

  if (timers.length) {
    updateLaterTimer(self, timers[0], timers[0] - now);
  }
}

function findDebouncee(target, method, debouncees) {
  return findItem(target, method, debouncees);
}

function findThrottler(target, method, throttlers) {
  return findItem(target, method, throttlers);
}

function findItem(target, method, collection) {
  var item;
  var index = -1;

  for (var i = 0, l = collection.length; i < l; i++) {
    item = collection[i];
    if (item[0] === target && item[1] === method) {
      index = i;
      break;
    }
  }

  return index;
}

function searchTimer(time, timers) {
  var start = 0;
  var end = timers.length - 2;
  var middle, l;

  while (start < end) {
    // since timers is an array of pairs 'l' will always
    // be an integer
    l = (end - start) / 2;

    // compensate for the index in case even number
    // of pairs inside timers
    middle = start + l - (l % 2);

    if (time >= timers[middle]) {
      start = middle + 2;
    } else {
      end = middle;
    }
  }

  return (time >= timers[start]) ? start + 2 : start;
}

export { Backburner };
<commit_msg>Use instance timers-list instead of shared timers-list<commit_after>import Utils from "backburner/utils";
import { DeferredActionQueues } from "backburner/deferred_action_queues";

var slice = [].slice;
var pop = [].pop;
var each = Utils.each;
var isString = Utils.isString;
var isFunction = Utils.isFunction;
var isNumber = Utils.isNumber;
var global = this;
var NUMBER = /\d+/;

// In IE 6-8, try/finally doesn't work without a catch.
// Unfortunately, this is impossible to test for since wrapping it in a parent try/catch doesn't trigger the bug.
// This tests for another broken try/catch behavior that only exhibits in the same versions of IE.
var needsIETryCatchFix = (function(e,x){
  try{ x(); }
  catch(e) { } // jshint ignore:line
  return !!e;
})();

function isCoercableNumber(number) {
  return isNumber(number) || NUMBER.test(number);
}

function Backburner(queueNames, options) {
  this.queueNames = queueNames;
  this.options = options || {};
  if (!this.options.defaultQueue) {
    this.options.defaultQueue = queueNames[0];
  }
  this.instanceStack = [];
  this._debouncees = [];
  this._throttlers = [];
  this._timers = [];
}

Backburner.prototype = {
  queueNames: null,
  options: null,
  currentInstance: null,
  instanceStack: null,

  begin: function() {
    var options = this.options;
    var onBegin = options && options.onBegin;
    var previousInstance = this.currentInstance;

    if (previousInstance) {
      this.instanceStack.push(previousInstance);
    }

    this.currentInstance = new DeferredActionQueues(this.queueNames, options);
    if (onBegin) {
      onBegin(this.currentInstance, previousInstance);
    }
  },

  end: function() {
    var options = this.options;
    var onEnd = options && options.onEnd;
    var currentInstance = this.currentInstance;
    var nextInstance = null;

    // Prevent double-finally bug in Safari 6.0.2 and iOS 6
    // This bug appears to be resolved in Safari 6.0.5 and iOS 7
    var finallyAlreadyCalled = false;
    try {
      currentInstance.flush();
    } finally {
      if (!finallyAlreadyCalled) {
        finallyAlreadyCalled = true;

        this.currentInstance = null;

        if (this.instanceStack.length) {
          nextInstance = this.instanceStack.pop();
          this.currentInstance = nextInstance;
        }

        if (onEnd) {
          onEnd(currentInstance, nextInstance);
        }
      }
    }
  },

  run: function(target, method /*, args */) {
    var onError = getOnError(this.options);

    this.begin();

    if (!method) {
      method = target;
      target = null;
    }

    if (isString(method)) {
      method = target[method];
    }

    var args = slice.call(arguments, 2);

    // guard against Safari 6's double-finally bug
    var didFinally = false;

    if (onError) {
      try {
        return method.apply(target, args);
      } catch(error) {
        onError(error);
      } finally {
        if (!didFinally) {
          didFinally = true;
          this.end();
        }
      }
    } else {
      try {
        return method.apply(target, args);
      } finally {
        if (!didFinally) {
          didFinally = true;
          this.end();
        }
      }
    }
  },

  defer: function(queueName, target, method /* , args */) {
    if (!method) {
      method = target;
      target = null;
    }

    if (isString(method)) {
      method = target[method];
    }

    var stack = this.DEBUG ? new Error() : undefined;
    var length = arguments.length;
    var args;

    if (length > 3) {
      args = new Array(length - 3);
      for (var i = 3; i < length; i++) {
        args[i-3] = arguments[i];
      }
    } else {
      args = undefined;
    }

    if (!this.currentInstance) { createAutorun(this); }
    return this.currentInstance.schedule(queueName, target, method, args, false, stack);
  },

  deferOnce: function(queueName, target, method /* , args */) {
    if (!method) {
      method = target;
      target = null;
    }

    if (isString(method)) {
      method = target[method];
    }

    var stack = this.DEBUG ? new Error() : undefined;
    var length = arguments.length;
    var args;

    if (length > 3) {
      args = new Array(length - 3);
      for (var i = 3; i < length; i++) {
        args[i-3] = arguments[i];
      }
    } else {
      args = undefined;
    }

    if (!this.currentInstance) { createAutorun(this); }
    return this.currentInstance.schedule(queueName, target, method, args, true, stack);
  },

  setTimeout: function() {
    var l = arguments.length;
    var args = new Array(l);
    for (var x = 0; x < l; x++) {
      args[x] = arguments[x];
    }
    var length = args.length,
        method, wait, target,
        methodOrTarget, methodOrWait, methodOrArgs;

    if (length === 0) {
      return;
    } else if (length === 1) {
      method = args.shift();
      wait = 0;
    } else if (length === 2) {
      methodOrTarget = args[0];
      methodOrWait = args[1];

      if (isFunction(methodOrWait) || isFunction(methodOrTarget[methodOrWait])) {
        target = args.shift();
        method = args.shift();
        wait = 0;
      } else if (isCoercableNumber(methodOrWait)) {
        method = args.shift();
        wait = args.shift();
      } else {
        method = args.shift();
        wait =  0;
      }
    } else {
      var last = args[args.length - 1];

      if (isCoercableNumber(last)) {
        wait = args.pop();
      } else {
        wait = 0;
      }

      methodOrTarget = args[0];
      methodOrArgs = args[1];

      if (isFunction(methodOrArgs) || (isString(methodOrArgs) &&
                                      methodOrTarget !== null &&
                                      methodOrArgs in methodOrTarget)) {
        target = args.shift();
        method = args.shift();
      } else {
        method = args.shift();
      }
    }

    var executeAt = (+new Date()) + parseInt(wait, 10);

    if (isString(method)) {
      method = target[method];
    }

    var onError = getOnError(this.options);

    function fn() {
      if (onError) {
        try {
          method.apply(target, args);
        } catch (e) {
          onError(e);
        }
      } else {
        method.apply(target, args);
      }
    }

    // find position to insert
    var i = searchTimer(executeAt, this._timers);

    this._timers.splice(i, 0, executeAt, fn);

    updateLaterTimer(this, executeAt, wait);

    return fn;
  },

  throttle: function(target, method /* , args, wait, [immediate] */) {
    var self = this;
    var args = arguments;
    var immediate = pop.call(args);
    var wait, throttler, index, timer;

    if (isNumber(immediate) || isString(immediate)) {
      wait = immediate;
      immediate = true;
    } else {
      wait = pop.call(args);
    }

    wait = parseInt(wait, 10);

    index = findThrottler(target, method, this._throttlers);
    if (index > -1) { return this._throttlers[index]; } // throttled

    timer = global.setTimeout(function() {
      if (!immediate) {
        self.run.apply(self, args);
      }
      var index = findThrottler(target, method, self._throttlers);
      if (index > -1) {
        self._throttlers.splice(index, 1);
      }
    }, wait);

    if (immediate) {
      self.run.apply(self, args);
    }

    throttler = [target, method, timer];

    this._throttlers.push(throttler);

    return throttler;
  },

  debounce: function(target, method /* , args, wait, [immediate] */) {
    var self = this;
    var args = arguments;
    var immediate = pop.call(args);
    var wait, index, debouncee, timer;

    if (isNumber(immediate) || isString(immediate)) {
      wait = immediate;
      immediate = false;
    } else {
      wait = pop.call(args);
    }

    wait = parseInt(wait, 10);
    // Remove debouncee
    index = findDebouncee(target, method, this._debouncees);

    if (index > -1) {
      debouncee = this._debouncees[index];
      this._debouncees.splice(index, 1);
      clearTimeout(debouncee[2]);
    }

    timer = global.setTimeout(function() {
      if (!immediate) {
        self.run.apply(self, args);
      }
      var index = findDebouncee(target, method, self._debouncees);
      if (index > -1) {
        self._debouncees.splice(index, 1);
      }
    }, wait);

    if (immediate && index === -1) {
      self.run.apply(self, args);
    }

    debouncee = [target, method, timer];

    self._debouncees.push(debouncee);

    return debouncee;
  },

  cancelTimers: function() {
    var clearItems = function(item) {
      clearTimeout(item[2]);
    };

    each(this._throttlers, clearItems);
    this._throttlers = [];

    each(this._debouncees, clearItems);
    this._debouncees = [];

    if (this._laterTimer) {
      clearTimeout(this._laterTimer);
      this._laterTimer = null;
    }
    this._timers = [];

    if (this._autorun) {
      clearTimeout(this._autorun);
      this._autorun = null;
    }
  },

  hasTimers: function() {
    return !!this._timers.length || !!this._debouncees.length || !!this._throttlers.length || this._autorun;
  },

  cancel: function(timer) {
    var timerType = typeof timer;

    if (timer && timerType === 'object' && timer.queue && timer.method) { // we're cancelling a deferOnce
      return timer.queue.cancel(timer);
    } else if (timerType === 'function') { // we're cancelling a setTimeout
      for (var i = 0, l = this._timers.length; i < l; i += 2) {
        if (this._timers[i + 1] === timer) {
          this._timers.splice(i, 2); // remove the two elements
          if (i === 0) {
            if (this._laterTimer) { // Active timer? Then clear timer and reset for future timer
              clearTimeout(this._laterTimer);
              this._laterTimer = null;
            }
            if (this._timers.length > 0) { // Update to next available timer when available
              updateLaterTimer(this, this._timers[0], this._timers[0] - (+new Date()));
            }
          }
          return true;
        }
      }
    } else if (Object.prototype.toString.call(timer) === "[object Array]"){ // we're cancelling a throttle or debounce
      return this._cancelItem(findThrottler, this._throttlers, timer) ||
               this._cancelItem(findDebouncee, this._debouncees, timer);
    } else {
      return; // timer was null or not a timer
    }
  },

  _cancelItem: function(findMethod, array, timer){
    var item, index;

    if (timer.length < 3) { return false; }

    index = findMethod(timer[0], timer[1], array);

    if (index > -1) {

      item = array[index];

      if (item[2] === timer[2]) {
        array.splice(index, 1);
        clearTimeout(timer[2]);
        return true;
      }
    }

    return false;
  }
};

Backburner.prototype.schedule = Backburner.prototype.defer;
Backburner.prototype.scheduleOnce = Backburner.prototype.deferOnce;
Backburner.prototype.later = Backburner.prototype.setTimeout;

if (needsIETryCatchFix) {
  var originalRun = Backburner.prototype.run;
  Backburner.prototype.run = wrapInTryCatch(originalRun);

  var originalEnd = Backburner.prototype.end;
  Backburner.prototype.end = wrapInTryCatch(originalEnd);
}

function wrapInTryCatch(func) {
  return function () {
    try {
      return func.apply(this, arguments);
    } catch (e) {
      throw e;
    }
  };
}

function getOnError(options) {
  return options.onError || (options.onErrorTarget && options.onErrorTarget[options.onErrorMethod]);
}

function createAutorun(backburner) {
  backburner.begin();
  backburner._autorun = global.setTimeout(function() {
    backburner._autorun = null;
    backburner.end();
  });
}

function updateLaterTimer(self, executeAt, wait) {
  var now = (+new Date());
  if (!self._laterTimer || executeAt < self._laterTimerExpiresAt || self._laterTimerExpiresAt < now) {

    if (self._laterTimer) {
      // Clear when:
      // - Already expired
      // - New timer is earlier
      clearTimeout(self._laterTimer);

      if (self._laterTimerExpiresAt < now) { // If timer was never triggered
        // Calculate the left-over wait-time
        wait = Math.max(0, executeAt - now);
      }
    }

    self._laterTimer = global.setTimeout(function() {
      self._laterTimer = null;
      self._laterTimerExpiresAt = null;
      executeTimers(self);
    }, wait);

    self._laterTimerExpiresAt = now + wait;
  }
}

function executeTimers(self) {
  var now = +new Date();
  var fns, i, l;

  self.run(function() {
    i = searchTimer(now, self._timers);

    fns = self._timers.splice(0, i);

    for (i = 1, l = fns.length; i < l; i += 2) {
      self.schedule(self.options.defaultQueue, null, fns[i]);
    }
  });

  if (self._timers.length) {
    updateLaterTimer(self, self._timers[0], self._timers[0] - now);
  }
}

function findDebouncee(target, method, debouncees) {
  return findItem(target, method, debouncees);
}

function findThrottler(target, method, throttlers) {
  return findItem(target, method, throttlers);
}

function findItem(target, method, collection) {
  var item;
  var index = -1;

  for (var i = 0, l = collection.length; i < l; i++) {
    item = collection[i];
    if (item[0] === target && item[1] === method) {
      index = i;
      break;
    }
  }

  return index;
}

function searchTimer(time, timers) {
  var start = 0;
  var end = timers.length - 2;
  var middle, l;

  while (start < end) {
    // since timers is an array of pairs 'l' will always
    // be an integer
    l = (end - start) / 2;

    // compensate for the index in case even number
    // of pairs inside timers
    middle = start + l - (l % 2);

    if (time >= timers[middle]) {
      start = middle + 2;
    } else {
      end = middle;
    }
  }

  return (time >= timers[start]) ? start + 2 : start;
}

export { Backburner };
<|endoftext|>


<commit_before>var spawn = require('child_process').spawn
  , which = require('./which')
  , utils = require('./utils')
	, children = {};

exports.children = children;

exports.connect = function(io, sessionStore) {

	io
	.set('authorization', function(handshakeData, callback) {
		console.log("authorization");
		if (!handshakeData.headers.cookie) return callback('socket.io: no found cookie.', false);
		var signedCookies = require('express/node_modules/cookie').parse(handshakeData.headers.cookie);
		handshakeData.cookies = require('express/node_modules/connect/lib/utils').parseSignedCookies(signedCookies, '5up3453c43t');
		handshakeData.sid = handshakeData.cookies['sid'];
		callback(null, true);
	})
	.on('connection', function(socket) {
		socket.on('kill', onkill);
		socket.on('spawn', onspawn);
		socket.on('bind', onbind);
	});

	function onkill(options, callback) {
		var pid = options.pid;
		children[pid].p.kill();
		callback(pid);
	}

	function onbind(options, callback) {
		var pid = options.pid;
		var cid = options.cid;
		var clientId = this.id;
  	var child = children[pid];
		var p = child.p;
		if (child.sid != this.handshake.sid) callback(null) // validate session ownership of proc
		p.removeAllListeners();
		p.stdout.removeAllListeners();
		p.stderr.removeAllListeners();
		bindchildexit(p, clientId, cid);
		//bindchildclose(p, clientId, cid);
		bindstdoutdata(p, clientId, cid);
		bindstderrdata(p, clientId, cid);
		//bindstderrclose(p, clientId, cid);
		callback(pid);
	}

	function onspawn(options, callback) {

		var clientId = this.id;
		console.log(clientId);
		var cid = options.cid; // backbone model id - used as the message handle
		var command = options.command;
		var paths = options.paths; paths.pop();
		var opts = command.split(new RegExp('\\s+'));
		var cmd = which.sync(opts.shift());// todo - required for windows only
		var cwd = utils.getPath(paths);
		//ST #0002 - add node parameter
		opts.unshift("--stack_size=1024","--max_old_space_size=20","--max_new_space_size=2048","--max_executable_size=5","--gc_global","--gc_interval=100");
		//ST #0002 - add node parameter
		var child = spawn(cmd, opts, { cwd: cwd });
		var pid = child.pid;

		children[pid] = { p: child, sid: this.handshake.sid, cmd: command, paths: options.paths };

		bindchildexit(child, clientId, cid);
		//bindchildclose(child, clientId, cid);
		callback(pid);
		bindstdoutdata(child, clientId, cid);
		bindstderrdata(child, clientId, cid);
		//bindstderrclose(child, clientId, cid);
	}

	function bindchildexit(child, clientId, cid) {
		child.on('exit', function (code, signal) {
			delete children[this.pid];
			io.sockets.socket(clientId).emit(cid+'_childexit', code);
		});
	}

//	function bindchildclose(child, clientId, cid) {
//		child.on('close', function (code, signal) {
//			io.sockets.socket(clientId).emit(cid+'_childclose', code);
//		});
//	}

	function bindstdoutdata(child, clientId, cid) {
		child.stdout.on('data', function (data) {
			io.sockets.socket(clientId).emit(cid+'_stdoutdata', data.toString());
		});
	}

	function bindstderrdata(child, clientId, cid) {
		child.stderr.on('data', function (data) {
			io.sockets.socket(clientId).emit(cid+'_stderrdata', data.toString());
		});
	}
//
//	function bindstderrclose(child, clientId, cid) {
//		child.stderr.on('close', function (data) {
//			io.sockets.socket(clientId).emit(cid+'_stderrclose', data.toString());
//		});
//	}

}<commit_msg>Revert "optimization parameters in node child processes"<commit_after>var spawn = require('child_process').spawn
  , which = require('./which')
  , utils = require('./utils')
	, children = {};

exports.children = children;

exports.connect = function(io, sessionStore) {

	io
	.set('authorization', function(handshakeData, callback) {
		console.log("authorization");
		if (!handshakeData.headers.cookie) return callback('socket.io: no found cookie.', false);
		var signedCookies = require('express/node_modules/cookie').parse(handshakeData.headers.cookie);
		handshakeData.cookies = require('express/node_modules/connect/lib/utils').parseSignedCookies(signedCookies, '5up3453c43t');
		handshakeData.sid = handshakeData.cookies['sid'];
		callback(null, true);
	})
	.on('connection', function(socket) {
		socket.on('kill', onkill);
		socket.on('spawn', onspawn);
		socket.on('bind', onbind);
	});

	function onkill(options, callback) {
		var pid = options.pid;
		children[pid].p.kill();
		callback(pid);
	}

	function onbind(options, callback) {
		var pid = options.pid;
		var cid = options.cid;
		var clientId = this.id;
  	var child = children[pid];
		var p = child.p;
		if (child.sid != this.handshake.sid) callback(null) // validate session ownership of proc
		p.removeAllListeners();
		p.stdout.removeAllListeners();
		p.stderr.removeAllListeners();
		bindchildexit(p, clientId, cid);
		//bindchildclose(p, clientId, cid);
		bindstdoutdata(p, clientId, cid);
		bindstderrdata(p, clientId, cid);
		//bindstderrclose(p, clientId, cid);
		callback(pid);
	}

	function onspawn(options, callback) {

		var clientId = this.id;
		console.log(clientId);
		var cid = options.cid; // backbone model id - used as the message handle
		var command = options.command;
		var paths = options.paths; paths.pop();
		var opts = command.split(new RegExp('\\s+'));
		var cmd = which.sync(opts.shift());// todo - required for windows only
		var cwd = utils.getPath(paths);
		var child = spawn(cmd, opts, { cwd: cwd });
		var pid = child.pid;

		children[pid] = { p: child, sid: this.handshake.sid, cmd: command, paths: options.paths };

		bindchildexit(child, clientId, cid);
		//bindchildclose(child, clientId, cid);
		callback(pid);
		bindstdoutdata(child, clientId, cid);
		bindstderrdata(child, clientId, cid);
		//bindstderrclose(child, clientId, cid);
	}

	function bindchildexit(child, clientId, cid) {
		child.on('exit', function (code, signal) {
			delete children[this.pid];
			io.sockets.socket(clientId).emit(cid+'_childexit', code);
		});
	}

//	function bindchildclose(child, clientId, cid) {
//		child.on('close', function (code, signal) {
//			io.sockets.socket(clientId).emit(cid+'_childclose', code);
//		});
//	}

	function bindstdoutdata(child, clientId, cid) {
		child.stdout.on('data', function (data) {
			io.sockets.socket(clientId).emit(cid+'_stdoutdata', data.toString());
		});
	}

	function bindstderrdata(child, clientId, cid) {
		child.stderr.on('data', function (data) {
			io.sockets.socket(clientId).emit(cid+'_stderrdata', data.toString());
		});
	}
//
//	function bindstderrclose(child, clientId, cid) {
//		child.stderr.on('close', function (data) {
//			io.sockets.socket(clientId).emit(cid+'_stderrclose', data.toString());
//		});
//	}

}<|endoftext|>


<commit_before>var request = require('supertest')
  , sinon = require('sinon')
  , should = require('chai').should()
  , expect = require('chai').expect
  , mongoose = require('mongoose')
  , MockToken = require('../mockToken')
  , app = require('../../express')
  , TokenModel = mongoose.model('Token');

require('chai').should();
require('sinon-mongoose');

require('../../models/event');
var EventModel = mongoose.model('Event');

describe("event read tests", function() {

  var sandbox;
  before(function() {
    sandbox = sinon.sandbox.create();
  });

  afterEach(function() {
    sandbox.restore();
  });

  var userId = mongoose.Types.ObjectId();
  function mockTokenWithPermission(permission) {
    sandbox.mock(TokenModel)
      .expects('findOne')
      .withArgs({token: "12345"})
      .chain('populate', 'userId')
      .chain('exec')
      .yields(null, MockToken(userId, [permission]));
  }

  it("should read active events", function(done) {
    mockTokenWithPermission('READ_EVENT_ALL');

    var eventId = 1;
    var mockEvent = new EventModel({
      _id: eventId,
      name: 'Mock Event'
    });
    sandbox.mock(EventModel)
      .expects('find')
      .withArgs({ complete: { $ne: true } })
      .yields(null, [mockEvent]);

    request(app)
      .get('/api/events')
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .expect(200)
      .end(done);
  });

  it("should read active events if user has read permission in acl", function(done) {
    mockTokenWithPermission('');

    var mockEvent1 = {
      _id: 1,
      name: 'Mock Event',
      acl: {
        userId: userId,
        role: 'GUEST'
      }
    };
    mockEvent1.acl[userId] = 'GUEST';

    var mockEvent2 = {
      _id: 2,
      name: 'Mock Event',
      acl: {}
    };

    var mockCursor = {
      toArray: function(callback) {
        callback(null, [mockEvent1, mockEvent2]);
      }
    };

    sandbox.mock(EventModel.collection)
      .expects('find')
      .withArgs({ complete: { $ne: true } })
      .yields(null, mockCursor);

    request(app)
      .get('/api/events')
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .expect(200)
      .expect(function(res) {
        should.exist(res.body);
        res.body.should.be.array;
        expect(res.body).to.have.lengthOf(1);
      })
      .end(done);
  });

  it("should read active events if user is part of a team in event", function(done) {
    mockTokenWithPermission('');

    var eventId = 1;

    var mockEvent1 = new EventModel({
      _id: eventId,
      name: 'Mock Event 123',
      teamIds: [],
      acl: {
        1: 'NONE'
      }
    });
    mockEvent1.teamIds[0] = {
      userIds: [userId]
    };

    var mockEvent2 = new EventModel({
      _id: eventId,
      name: 'Mock Event 267',
      acl: {}
    });

    sandbox.mock(EventModel)
      .expects('populate')
      .yields(null, [mockEvent1, mockEvent2]);

    sandbox.mock(EventModel)
      .expects('find')
      .withArgs({ complete: { $ne: true } })
      .yields(null);

    request(app)
      .get('/api/events?populate=false')
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .expect(200)
      .expect(function(res) {
        console.log('res.body', res.body);
        should.exist(res.body);
        res.body.should.be.array;
        expect(res.body).to.have.lengthOf(1);
      })
      .end(done);
  });

  it("should not read events if user is not part of a team in event or in acl", function(done) {
    mockTokenWithPermission('');

    var eventId = 1;

    var mockEvent1 = new EventModel({
      _id: eventId,
      name: 'Mock Event 1',
      acl: {}
    });

    var mockEvent2 = new EventModel({
      _id: eventId,
      name: 'Mock Event 2',
      acl: {}
    });

    sandbox.mock(EventModel)
      .expects('populate')
      .yields(null, [mockEvent1, mockEvent2]);

    sandbox.mock(EventModel)
      .expects('find')
      .withArgs({ complete: { $ne: true } })
      .yields(null);

    request(app)
      .get('/api/events?populate=false')
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .expect(200)
      .expect(function(res) {
        console.log('res.body', res.body);
        should.exist(res.body);
        res.body.should.be.array;
        expect(res.body).to.have.lengthOf(0);
      })
      .end(done);
  });

  it("should read complete events", function(done) {
    mockTokenWithPermission('READ_EVENT_ALL');

    var eventId = 1;
    var mockEvent = new EventModel({
      _id: eventId,
      name: 'Mock Event'
    });
    sandbox.mock(EventModel)
      .expects('find')
      .withArgs({ complete: true })
      .yields(null, [mockEvent]);

    sandbox.mock(EventModel)
      .expects('populate')
      .yields(null, [mockEvent]);

    request(app)
      .get('/api/events')
      .query({state: 'complete'})
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .expect(200)
      .end(done);
  });

  it("should read all events", function(done) {
    mockTokenWithPermission('READ_EVENT_ALL');

    var eventId = 1;
    var mockEvent = new EventModel({
      _id: eventId,
      name: 'Mock Event'
    });
    sandbox.mock(EventModel)
      .expects('find')
      .withArgs({})
      .yields(null, [mockEvent]);

    sandbox.mock(EventModel)
      .expects('populate')
      .yields(null, [mockEvent]);

    request(app)
      .get('/api/events')
      .query({state: 'all'})
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .expect(200)
      .end(done);
  });

  it("should read event by id", function(done) {
    mockTokenWithPermission('READ_EVENT_ALL');

    var eventId = 1;
    var mockEvent = new EventModel({
      _id: eventId,
      name: 'Mock Event'
    });

    sandbox.mock(EventModel)
      .expects('findById')
      .twice()
      .onFirstCall()
      .yields(null, mockEvent)
      .onSecondCall()
      .yields(null, mockEvent);

    request(app)
      .get('/api/events/1')
      .query({state: 'all'})
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .expect(200)
      .end(done);
  });

  it("should fail to read event by id if event does not exist", function(done) {
    mockTokenWithPermission('READ_EVENT_ALL');

    var eventId = 1;
    var mockEvent = new EventModel({
      _id: eventId,
      name: 'Mock Event'
    });

    sandbox.mock(EventModel)
      .expects('findById')
      .twice()
      .onFirstCall()
      .yields(null, mockEvent)
      .onSecondCall()
      .yields(null, null);

    request(app)
      .get('/api/events/2')
      .query({state: 'all'})
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .expect(404)
      .end(done);
  });

  it.skip("should read teams in event", function(done) {
    mockTokenWithPermission('READ_EVENT_ALL');

    var eventId = 1;
    var mockEvent = new EventModel({
      _id: eventId,
      name: 'Mock Event'
    });

    sandbox.mock(EventModel)
      .expects('findById')
      .chain('populate')
      .withArgs({path: 'teamIds'})
      .chain('exec')
      .yields(null, mockEvent);

    request(app)
      .get('/api/events/1/teams')
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .expect(200)
      .end(done);
  });

  it.skip("should read users in event", function(done) {
    mockTokenWithPermission('READ_EVENT_ALL');

    var eventId = 1;
    var mockEvent = new EventModel({
      _id: eventId,
      name: 'Mock Event'
    });

    sandbox.mock(EventModel)
      .expects('findById')
      .chain('populate')
      .withArgs({ path: "teamIds", populate: { path: "userIds" } })
      .chain('exec')
      .yields(null, mockEvent);

    request(app)
      .get('/api/events/1/users')
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .expect(200)
      .end(done);
  });

  it.skip("should read teams in event", function(done) {
    mockTokenWithPermission('READ_EVENT_ALL');

    var eventId = 1;
    var mockEvent = new EventModel({
      _id: eventId,
      name: 'Mock Event'
    });

    sandbox.mock(EventModel)
      .expects('findById')
      .chain('populate')
      .withArgs({
        path: 'teamIds',
        populate: {
          path: 'userIds'
        }
      })
      .chain('exec')
      .yields(null, mockEvent);

    request(app)
      .get('/api/events/1/teams')
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .query({populate: 'users'})
      .expect(200)
      .end(done);
  });
});
<commit_msg>Fixed skipped event team/user tests<commit_after>var request = require('supertest')
  , sinon = require('sinon')
  , should = require('chai').should()
  , expect = require('chai').expect
  , mongoose = require('mongoose')
  , MockToken = require('../mockToken')
  , app = require('../../express')
  , TokenModel = mongoose.model('Token');

require('chai').should();
require('sinon-mongoose');

require('../../models/team');
var TeamModel = mongoose.model('Team');

require('../../models/event');
var EventModel = mongoose.model('Event');

describe("event read tests", function() {

  var sandbox;
  before(function() {
    sandbox = sinon.sandbox.create();
  });

  afterEach(function() {
    sandbox.restore();
  });

  var userId = mongoose.Types.ObjectId();
  function mockTokenWithPermission(permission) {
    sandbox.mock(TokenModel)
      .expects('findOne')
      .withArgs({token: "12345"})
      .chain('populate', 'userId')
      .chain('exec')
      .yields(null, MockToken(userId, [permission]));
  }

  it("should read active events", function(done) {
    mockTokenWithPermission('READ_EVENT_ALL');

    var eventId = 1;
    var mockEvent = new EventModel({
      _id: eventId,
      name: 'Mock Event'
    });
    sandbox.mock(EventModel)
      .expects('find')
      .withArgs({ complete: { $ne: true } })
      .yields(null, [mockEvent]);

    request(app)
      .get('/api/events')
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .expect(200)
      .end(done);
  });

  it("should read active events if user has read permission in acl", function(done) {
    mockTokenWithPermission('');

    var mockEvent1 = {
      _id: 1,
      name: 'Mock Event',
      acl: {
        userId: userId,
        role: 'GUEST'
      }
    };
    mockEvent1.acl[userId] = 'GUEST';

    var mockEvent2 = {
      _id: 2,
      name: 'Mock Event',
      acl: {}
    };

    var mockCursor = {
      toArray: function(callback) {
        callback(null, [mockEvent1, mockEvent2]);
      }
    };

    sandbox.mock(EventModel.collection)
      .expects('find')
      .withArgs({ complete: { $ne: true } })
      .yields(null, mockCursor);

    request(app)
      .get('/api/events')
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .expect(200)
      .expect(function(res) {
        should.exist(res.body);
        res.body.should.be.array;
        expect(res.body).to.have.lengthOf(1);
      })
      .end(done);
  });

  it("should read active events if user is part of a team in event", function(done) {
    mockTokenWithPermission('');

    var eventId = 1;

    var mockEvent1 = new EventModel({
      _id: eventId,
      name: 'Mock Event 123',
      teamIds: [],
      acl: {
        1: 'NONE'
      }
    });
    mockEvent1.teamIds[0] = {
      userIds: [userId]
    };

    var mockEvent2 = new EventModel({
      _id: eventId,
      name: 'Mock Event 267',
      acl: {}
    });

    sandbox.mock(EventModel)
      .expects('populate')
      .yields(null, [mockEvent1, mockEvent2]);

    sandbox.mock(EventModel)
      .expects('find')
      .withArgs({ complete: { $ne: true } })
      .yields(null);

    request(app)
      .get('/api/events?populate=false')
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .expect(200)
      .expect(function(res) {
        console.log('res.body', res.body);
        should.exist(res.body);
        res.body.should.be.array;
        expect(res.body).to.have.lengthOf(1);
      })
      .end(done);
  });

  it("should not read events if user is not part of a team in event or in acl", function(done) {
    mockTokenWithPermission('');

    var eventId = 1;

    var mockEvent1 = new EventModel({
      _id: eventId,
      name: 'Mock Event 1',
      acl: {}
    });

    var mockEvent2 = new EventModel({
      _id: eventId,
      name: 'Mock Event 2',
      acl: {}
    });

    sandbox.mock(EventModel)
      .expects('populate')
      .yields(null, [mockEvent1, mockEvent2]);

    sandbox.mock(EventModel)
      .expects('find')
      .withArgs({ complete: { $ne: true } })
      .yields(null);

    request(app)
      .get('/api/events?populate=false')
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .expect(200)
      .expect(function(res) {
        console.log('res.body', res.body);
        should.exist(res.body);
        res.body.should.be.array;
        expect(res.body).to.have.lengthOf(0);
      })
      .end(done);
  });

  it("should read complete events", function(done) {
    mockTokenWithPermission('READ_EVENT_ALL');

    var eventId = 1;
    var mockEvent = new EventModel({
      _id: eventId,
      name: 'Mock Event'
    });
    sandbox.mock(EventModel)
      .expects('find')
      .withArgs({ complete: true })
      .yields(null, [mockEvent]);

    sandbox.mock(EventModel)
      .expects('populate')
      .yields(null, [mockEvent]);

    request(app)
      .get('/api/events')
      .query({state: 'complete'})
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .expect(200)
      .end(done);
  });

  it("should read all events", function(done) {
    mockTokenWithPermission('READ_EVENT_ALL');

    var eventId = 1;
    var mockEvent = new EventModel({
      _id: eventId,
      name: 'Mock Event'
    });
    sandbox.mock(EventModel)
      .expects('find')
      .withArgs({})
      .yields(null, [mockEvent]);

    sandbox.mock(EventModel)
      .expects('populate')
      .yields(null, [mockEvent]);

    request(app)
      .get('/api/events')
      .query({state: 'all'})
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .expect(200)
      .end(done);
  });

  it("should read event by id", function(done) {
    mockTokenWithPermission('READ_EVENT_ALL');

    var eventId = 1;
    var mockEvent = new EventModel({
      _id: eventId,
      name: 'Mock Event'
    });

    sandbox.mock(EventModel)
      .expects('findById')
      .twice()
      .onFirstCall()
      .yields(null, mockEvent)
      .onSecondCall()
      .yields(null, mockEvent);

    request(app)
      .get('/api/events/1')
      .query({state: 'all'})
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .expect(200)
      .end(done);
  });

  it("should fail to read event by id if event does not exist", function(done) {
    mockTokenWithPermission('READ_EVENT_ALL');

    var eventId = 1;
    var mockEvent = new EventModel({
      _id: eventId,
      name: 'Mock Event'
    });

    sandbox.mock(EventModel)
      .expects('findById')
      .twice()
      .onFirstCall()
      .yields(null, mockEvent)
      .onSecondCall()
      .yields(null, null);

    request(app)
      .get('/api/events/2')
      .query({state: 'all'})
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .expect(404)
      .end(done);
  });

  it("should read teams in event", function(done) {
    mockTokenWithPermission('READ_EVENT_ALL');

    var eventId = 1;
    var mockEvent = new EventModel({
      _id: eventId,
      name: 'Mock Event'
    });

    var eventMock = sandbox.mock(EventModel);

    eventMock.expects('findById')
      .withArgs("1")
      .yields(null, mockEvent);

    eventMock.expects('findById')
      .chain('populate')
      .withArgs({path: 'teamIds'})
      .chain('exec')
      .yields(null, mockEvent);

    request(app)
      .get('/api/events/1/teams')
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .expect(200)
      .end(done);
  });

  it("should read users in event", function(done) {
    mockTokenWithPermission('READ_EVENT_ALL');

    var eventId = 1;
    var mockEvent = new EventModel({
      _id: eventId,
      name: 'Mock Event'
    });

    var eventMock = sandbox.mock(EventModel);

    eventMock.expects('findById')
      .withArgs("1")
      .yields(null, mockEvent);

    eventMock.expects('findById')
      .chain('populate')
      .withArgs({path: 'teamIds', populate: { path: 'userIds' }})
      .chain('exec')
      .yields(null, mockEvent);

    request(app)
      .get('/api/events/1/users')
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .expect(200)
      .end(done);
  });

  it("should read users in event with team access", function(done) {
    mockTokenWithPermission('');

    var eventId = 1;

    var mockTeam = new TeamModel({
      userIds: [userId],
      acl: {}
    });

    var mockEvent = new EventModel({
      _id: eventId,
      name: 'Mock Event 123',
      teamIds: [],
      acl: {
        1: 'NONE'
      }
    });
    mockEvent.teamIds[0] = mockTeam;

    var eventMock = sandbox.mock(EventModel);

    eventMock.expects('findById')
      .withArgs("1")
      .yields(null, mockEvent);

    sandbox.mock(EventModel)
      .expects('populate')
      .yields(null, mockEvent);

    eventMock.expects('findById')
      .chain('populate')
      .withArgs({
        path: 'teamIds',
        populate: {
          path: 'userIds'
        }
      })
      .chain('exec')
      .yields(null, mockEvent);

    request(app)
      .get('/api/events/1/users')
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .query({populate: 'users'})
      .expect(200)
      .end(done);
  });

  it("should read teams in event with team access", function(done) {
    mockTokenWithPermission('');

    var eventId = 1;

    var mockTeam = new TeamModel({
      userIds: [userId],
      acl: {}
    });

    var mockEvent = new EventModel({
      _id: eventId,
      name: 'Mock Event 123',
      teamIds: [],
      acl: {
        1: 'NONE'
      }
    });
    mockEvent.teamIds[0] = mockTeam;

    var eventMock = sandbox.mock(EventModel);

    eventMock.expects('findById')
      .withArgs("1")
      .yields(null, mockEvent);

    sandbox.mock(EventModel)
      .expects('populate')
      .yields(null, mockEvent);

    eventMock.expects('findById')
      .chain('populate')
      .withArgs({
        path: 'teamIds',
        populate: {
          path: 'userIds'
        }
      })
      .chain('exec')
      .yields(null, mockEvent);

    request(app)
      .get('/api/events/1/teams')
      .set('Accept', 'application/json')
      .set('Authorization', 'Bearer 12345')
      .query({populate: 'users'})
      .expect(200)
      .end(done);
  });
});
<|endoftext|>


<commit_before>/* Main unmaze library
   Copyright 2017 Mariusz Skoneczko
   Licensed under the MIT license
*/

const MAZE = {
    FREE: 0,
    WALL: 1,
    END: 2,
    TRAIL: 3
};

class Maze {
    constructor(width, height) {
        if (width < 2 || height < 2) {
            throw new RangeError("Dimensions too small");
        }
        this.width = width;
        this.height = height;

        this.maze = new Array(width);
        // create 'matrix' maze where maze[x][y] such that x < width, y < height
        for (let i = 0; i < width; i++) {
            this.maze[i] = new Array(height);
        }
        this.allWall();
        this.start = {x: null, y: null};
        this.robot = {x: null, y: null};
    }

    allWall() {
        for (let i = 0; i < this.width; i++) {
            for (let j = 0; j < this.height; j++) {
                this.maze[i][j] = MAZE.WALL;
            }
        }
    }

    setStart(x, y) {
        this.start = {x: x, y: y};
    }

    setEnd(x, y) {
        this.maze[x][y] = MAZE.END;
    }

    robotToStart() {
        this.robot.x = this.start.x;
        this.robot.y = this.start.y;
    }

    resetRobot() {
        this.robotToStart();
        for (let i = 0; i < this.width; i++) {
            for (let j= 0; j < this.height; j++) {
                if (this.maze[i][j] === MAZE.TRAIL) {
                    this.maze[i][j] = MAZE.FREE;
                }
            }
        }
    }

    save() {
        return btoa(JSON.stringify({
            maze: this.maze,
            start: this.start
        }));
    }

    load(savedata) {
        let loaddata = JSON.parse(atob(savedata));
        this.maze = loaddata.maze;
        this.start = loaddata.start;
        this.robotToStart();
        this.width = this.maze.length;
        this.height = this.maze[0].length;
    }
}

const SOLVE_STATUS = {
    EXPLORING: 0,
    SOLVED: 1,
    FAILED: 2,
    RETRACING: 3
};

const DIRECTION = {
    UP: 0,
    RIGHT: 1,
    DOWN: 2,
    LEFT: 3
};

const INVERT_DIRECTION = {
    [DIRECTION.UP]: DIRECTION.DOWN,
    [DIRECTION.RIGHT]: DIRECTION.LEFT,
    [DIRECTION.DOWN]: DIRECTION.UP,
    [DIRECTION.LEFT]: DIRECTION.RIGHT
};

class MazeSolver {
    constructor(maze) {
        this.maze = maze;
        this.status = SOLVE_STATUS.EXPLORING;
        this.junction_memory = {};
        this.move_memory = [];
        this.last_direction = null;
        this.steps = 0;
    }

    adjacent() {
        let up, right, down, left;

        if (this.maze.robot.y === 0) {
            up = MAZE.WALL;
        } else {
            up = this.maze.maze[this.maze.robot.x][this.maze.robot.y - 1];
        }

        if (this.maze.robot.x === this.maze.width - 1) {
            right = MAZE.WALL;
        } else {
            right = this.maze.maze[this.maze.robot.x + 1][this.maze.robot.y];
        }

        if (this.maze.robot.y === this.maze.height - 1) {
            down = MAZE.WALL;
        } else {
            down = this.maze.maze[this.maze.robot.x][this.maze.robot.y + 1];
        }

        if (this.maze.robot.x === 0) {
            left = MAZE.WALL;
        } else {
            left = this.maze.maze[this.maze.robot.x - 1][this.maze.robot.y];
        }

        return {
            [DIRECTION.UP]: up,
            [DIRECTION.RIGHT]: right,
            [DIRECTION.DOWN]: down,
            [DIRECTION.LEFT]: left
        };
    }

    isSolved() {
        if (this.maze.maze[this.maze.robot.x][this.maze.robot.y] === MAZE.END) {
            return true;
        } else {
            return false;
        }
    }

    possibleNext(adjacent) {
        let possibilities = [];
        for (let key in adjacent) {
            if (adjacent[key] === MAZE.FREE || adjacent[key] === MAZE.END) {
                possibilities.push(parseInt(key));
            }
        }
        return possibilities;
    }

    isJunction(possibilities) {
        if (possibilities.length > 1) {
            return true;
        } else {
            return false;
        }
    }

    isDeadEnd(possibilities) {
        if (possibilities.length === 0) {
            return true;
        } else {
            return false;
        }
    }

    move(direction, log=true) {
        if (log) this.move_memory.push(direction);
        this.last_direction = direction;
        if (direction === DIRECTION.UP) {
            this.maze.robot.y -= 1;
        } else if (direction === DIRECTION.RIGHT) {
            this.maze.robot.x += 1;
        } else if (direction === DIRECTION.DOWN) {
            this.maze.robot.y += 1;
        } else if (direction === DIRECTION.LEFT) {
            this.maze.robot.x -= 1;
        }
    }

    explore(possibilities) {
        if (this.isJunction(possibilities)) {
            if (this.junction_memory[[this.maze.robot.x, this.maze.robot.y].toString()] === undefined) {
                // new junction!
                let direction = possibilities[0];
                this.junction_memory[[this.maze.robot.x, this.maze.robot.y].toString()] = [direction];
                // set down trail to avoid considering this a new junction if there is a loop
                this.maze.maze[this.maze.robot.x][this.maze.robot.y] = MAZE.TRAIL;
                this.move(direction);
            } else {
                // we already handled this junction before
                this.move(INVERT_DIRECTION[this.move_memory.pop()], false);
                this.maze.maze[this.maze.robot.x][this.maze.robot.y] = MAZE.FREE;
                this.status = SOLVE_STATUS.RETRACING;
            }
        } else if (this.isDeadEnd(possibilities)) {
            // move back to last position and THEN retrace: handles loops correctly
            this.move(INVERT_DIRECTION[this.move_memory.pop()], false);
            // remove trail
            this.maze.maze[this.maze.robot.x][this.maze.robot.y] = MAZE.FREE;
            this.status = SOLVE_STATUS.RETRACING;
        } else {
            // move to the next available space
            // but first, set down a trail tile (BEFORE moving)
            this.maze.maze[this.maze.robot.x][this.maze.robot.y] = MAZE.TRAIL;
            this.move(possibilities[0]);
        }
    }

    goBack() {
        if (this.maze.robot.x === this.maze.start.x && this.maze.robot.y === this.maze.start.y) {
            this.status = SOLVE_STATUS.FAILED;
        } else {
            let direction = INVERT_DIRECTION[this.move_memory.pop()];
            this.move(direction, false);
            // remove trail
            this.maze.maze[this.maze.robot.x][this.maze.robot.y] = MAZE.FREE;
        }
    }

    retrace(adjacent, possibilities) {
        if (this.isJunction(possibilities)) {
            // choose a direction we have not been in before, or continue retracing if there is none
            let junction_paths = this.junction_memory[[this.maze.robot.x, this.maze.robot.y].toString()];
            let direction = null;
            for (let possibility of possibilities) {
                // possibility that we have not been to before
                if (junction_paths.indexOf(possibility) === -1) {
                    direction = possibility;
                    break;
                }
            }
            if (direction === null) {
                // we have been everywhere possible from this junction
                this.goBack();
            } else {
                junction_paths.push(direction);
                this.maze.maze[this.maze.robot.x][this.maze.robot.y] = MAZE.TRAIL;
                this.status = SOLVE_STATUS.EXPLORING;
                this.move(direction);
            }
        } else {
            this.goBack();
        }
    }

    ai() {
        let adjacent = this.adjacent();
        let possibilities = this.possibleNext(adjacent);

        if (this.isSolved()) {
            this.status = SOLVE_STATUS.SOLVED;
            return;
        }

        if (this.status === SOLVE_STATUS.EXPLORING) {
            this.explore(possibilities);
        } else if (this.status === SOLVE_STATUS.RETRACING) {
            this.retrace(adjacent, possibilities);
        }
    }

    done() {
        if (this.status === SOLVE_STATUS.SOLVED || this.status === SOLVE_STATUS.FAILED) {
            return true;
        } else {
            return false;
        }
    }

    step() {
        if (!this.done()) {
            this.ai();
            this.steps += 1;
        }

        return this.status;
    }
}
<commit_msg>Removed duplicate code<commit_after>/* Main unmaze library
   Copyright 2017 Mariusz Skoneczko
   Licensed under the MIT license
*/

const MAZE = {
    FREE: 0,
    WALL: 1,
    END: 2,
    TRAIL: 3
};

class Maze {
    constructor(width, height) {
        if (width < 2 || height < 2) {
            throw new RangeError("Dimensions too small");
        }
        this.width = width;
        this.height = height;

        this.maze = new Array(width);
        // create 'matrix' maze where maze[x][y] such that x < width, y < height
        for (let i = 0; i < width; i++) {
            this.maze[i] = new Array(height);
        }
        this.allWall();
        this.start = {x: null, y: null};
        this.robot = {x: null, y: null};
    }

    allWall() {
        for (let i = 0; i < this.width; i++) {
            for (let j = 0; j < this.height; j++) {
                this.maze[i][j] = MAZE.WALL;
            }
        }
    }

    setStart(x, y) {
        this.start = {x: x, y: y};
    }

    setEnd(x, y) {
        this.maze[x][y] = MAZE.END;
    }

    robotToStart() {
        this.robot.x = this.start.x;
        this.robot.y = this.start.y;
    }

    resetRobot() {
        this.robotToStart();
        for (let i = 0; i < this.width; i++) {
            for (let j= 0; j < this.height; j++) {
                if (this.maze[i][j] === MAZE.TRAIL) {
                    this.maze[i][j] = MAZE.FREE;
                }
            }
        }
    }

    save() {
        return btoa(JSON.stringify({
            maze: this.maze,
            start: this.start
        }));
    }

    load(savedata) {
        let loaddata = JSON.parse(atob(savedata));
        this.maze = loaddata.maze;
        this.start = loaddata.start;
        this.robotToStart();
        this.width = this.maze.length;
        this.height = this.maze[0].length;
    }
}

const SOLVE_STATUS = {
    EXPLORING: 0,
    SOLVED: 1,
    FAILED: 2,
    RETRACING: 3
};

const DIRECTION = {
    UP: 0,
    RIGHT: 1,
    DOWN: 2,
    LEFT: 3
};

const INVERT_DIRECTION = {
    [DIRECTION.UP]: DIRECTION.DOWN,
    [DIRECTION.RIGHT]: DIRECTION.LEFT,
    [DIRECTION.DOWN]: DIRECTION.UP,
    [DIRECTION.LEFT]: DIRECTION.RIGHT
};

class MazeSolver {
    constructor(maze) {
        this.maze = maze;
        this.status = SOLVE_STATUS.EXPLORING;
        this.junction_memory = {};
        this.move_memory = [];
        this.last_direction = null;
        this.steps = 0;
    }

    adjacent() {
        let up, right, down, left;

        if (this.maze.robot.y === 0) {
            up = MAZE.WALL;
        } else {
            up = this.maze.maze[this.maze.robot.x][this.maze.robot.y - 1];
        }

        if (this.maze.robot.x === this.maze.width - 1) {
            right = MAZE.WALL;
        } else {
            right = this.maze.maze[this.maze.robot.x + 1][this.maze.robot.y];
        }

        if (this.maze.robot.y === this.maze.height - 1) {
            down = MAZE.WALL;
        } else {
            down = this.maze.maze[this.maze.robot.x][this.maze.robot.y + 1];
        }

        if (this.maze.robot.x === 0) {
            left = MAZE.WALL;
        } else {
            left = this.maze.maze[this.maze.robot.x - 1][this.maze.robot.y];
        }

        return {
            [DIRECTION.UP]: up,
            [DIRECTION.RIGHT]: right,
            [DIRECTION.DOWN]: down,
            [DIRECTION.LEFT]: left
        };
    }

    isSolved() {
        if (this.maze.maze[this.maze.robot.x][this.maze.robot.y] === MAZE.END) {
            return true;
        } else {
            return false;
        }
    }

    possibleNext(adjacent) {
        let possibilities = [];
        for (let key in adjacent) {
            if (adjacent[key] === MAZE.FREE || adjacent[key] === MAZE.END) {
                possibilities.push(parseInt(key));
            }
        }
        return possibilities;
    }

    isJunction(possibilities) {
        if (possibilities.length > 1) {
            return true;
        } else {
            return false;
        }
    }

    isDeadEnd(possibilities) {
        if (possibilities.length === 0) {
            return true;
        } else {
            return false;
        }
    }

    move(direction, log=true) {
        if (log) this.move_memory.push(direction);
        this.last_direction = direction;
        if (direction === DIRECTION.UP) {
            this.maze.robot.y -= 1;
        } else if (direction === DIRECTION.RIGHT) {
            this.maze.robot.x += 1;
        } else if (direction === DIRECTION.DOWN) {
            this.maze.robot.y += 1;
        } else if (direction === DIRECTION.LEFT) {
            this.maze.robot.x -= 1;
        }
    }

    explore(possibilities) {
        if (this.isJunction(possibilities)) {
            if (this.junction_memory[[this.maze.robot.x, this.maze.robot.y].toString()] === undefined) {
                // new junction!
                let direction = possibilities[0];
                this.junction_memory[[this.maze.robot.x, this.maze.robot.y].toString()] = [direction];
                // set down trail to avoid considering this a new junction if there is a loop
                this.maze.maze[this.maze.robot.x][this.maze.robot.y] = MAZE.TRAIL;
                this.move(direction);
            } else {
                // we already handled this junction before
                this.goBack();
                this.status = SOLVE_STATUS.RETRACING;
            }
        } else if (this.isDeadEnd(possibilities)) {
            // move back to last position and THEN retrace: handles loops correctly
            this.goBack();
            this.status = SOLVE_STATUS.RETRACING;
        } else {
            // move to the next available space
            // but first, set down a trail tile (BEFORE moving)
            this.maze.maze[this.maze.robot.x][this.maze.robot.y] = MAZE.TRAIL;
            this.move(possibilities[0]);
        }
    }

    goBack() {
        if (this.maze.robot.x === this.maze.start.x && this.maze.robot.y === this.maze.start.y) {
            this.status = SOLVE_STATUS.FAILED;
        } else {
            let direction = INVERT_DIRECTION[this.move_memory.pop()];
            this.move(direction, false);
            // remove trail
            this.maze.maze[this.maze.robot.x][this.maze.robot.y] = MAZE.FREE;
        }
    }

    retrace(adjacent, possibilities) {
        if (this.isJunction(possibilities)) {
            // choose a direction we have not been in before, or continue retracing if there is none
            let junction_paths = this.junction_memory[[this.maze.robot.x, this.maze.robot.y].toString()];
            let direction = null;
            for (let possibility of possibilities) {
                // possibility that we have not been to before
                if (junction_paths.indexOf(possibility) === -1) {
                    direction = possibility;
                    break;
                }
            }
            if (direction === null) {
                // we have been everywhere possible from this junction
                this.goBack();
            } else {
                junction_paths.push(direction);
                this.maze.maze[this.maze.robot.x][this.maze.robot.y] = MAZE.TRAIL;
                this.status = SOLVE_STATUS.EXPLORING;
                this.move(direction);
            }
        } else {
            this.goBack();
        }
    }

    ai() {
        let adjacent = this.adjacent();
        let possibilities = this.possibleNext(adjacent);

        if (this.isSolved()) {
            this.status = SOLVE_STATUS.SOLVED;
            return;
        }

        if (this.status === SOLVE_STATUS.EXPLORING) {
            this.explore(possibilities);
        } else if (this.status === SOLVE_STATUS.RETRACING) {
            this.retrace(adjacent, possibilities);
        }
    }

    done() {
        if (this.status === SOLVE_STATUS.SOLVED || this.status === SOLVE_STATUS.FAILED) {
            return true;
        } else {
            return false;
        }
    }

    step() {
        if (!this.done()) {
            this.ai();
            this.steps += 1;
        }

        return this.status;
    }
}
<|endoftext|>


<commit_before>const fs = require('fs')
const path = require('path')
const vscode = require('vscode')
const rjson = require('relaxed-json')
const AppDirectory = require('appdirectory')

const Setting = require('./setting')

class Importer {
    constructor() {
        this._readSettingsMap()
    }

    _mapAllSettings(sourceSettings) {
        var mappedSettings = []
        for (var key in sourceSettings) {
            var setting = sourceSettings[key]
            var mapped = this._mapSetting(key, setting)
            if (mapped) {
                mappedSettings.push(mapped)
            }
        }
        return mappedSettings
    }

    _mapSetting(key, value) {
        var mappedSetting = this.settingsMap[key]
        if (mappedSetting) {
            if (typeof mappedSetting === 'string') {
                return new Setting(mappedSetting, value)
            } else if (typeof mappedSetting === 'object') {
                let newKey = Object.keys(mappedSetting[value])[0]
                let newValue = Object.values(mappedSetting[value])[0]
                return new Setting(newKey, newValue)
            }
        }

        return null
    }

    _updateSettings(type, settings) {
        settings.forEach(setting => {
            var namespace = setting.name.split('.')[0]
            var settingName = setting.name.split('.')[1]

            var config = vscode.workspace.getConfiguration(namespace)
            var isGlobalSetting = type == 'global'
            if (config && settingName) {
                config.update(settingName, setting.value, isGlobalSetting)
            }
        })
    }

    _readSettingsMap() {
        var mapPath = path.resolve(__dirname, '..', 'map.json')

        fs.readFile(mapPath, 'UTF-8', (err, data) => {
            if (err) {
                return err
            }
            this.settingsMap = rjson.parse(data.toString())
        })
    }

    importEverything() {
        return Promise.all([
            this.importGlobalSettings(),
            this.importProjectSettings(),
            this.importSnippets()
        ])
    }

    importSnippets() {
        return new Promise((resolve, reject) => {
            resolve()
        })
    }

    importGlobalSettings() {
        return new Promise((resolve, reject) => {
            this.analyzeGlobalSettings()
                .then(mappedSettings => {
                    if (mappedSettings.length) {
                        this._updateSettings('global', mappedSettings)
                    }
                    resolve()
                })
                .catch(reject)
        })
    }

    importProjectSettings() {
        return new Promise((resolve, reject) => {
            this.analyzeProjectSettings()
                .then(mappedSettings => {
                    if (mappedSettings.length) {
                        this._updateSettings('workspace', mappedSettings)
                    }
                    resolve()
                })
                .catch(reject)
        })
    }

    analyze() {
        return new Promise((resolve, reject) => {
            Promise.all([
                this.analyzeProjectSettings(),
                this.analyzeGlobalSettings(),
                this.analyzeSnippets()
            ]).then(data => {
                resolve({
                    projectCount: data[0].length,
                    globalCount: data[1].length,
                    snippetsCount: data[2].length
                })
            })
        })
    }

    analyzeGlobalSettings() {
        var dirs = new AppDirectory('Sublime Text 3')
        var settingsPath = path.resolve(dirs.userData(), 'Packages', 'User', 'Preferences.sublime-settings')

        // TODO: Check if files exists first

        return new Promise((resolve, reject) => {
            fs.readFile(settingsPath, (err, data) => {
                if (err) {
                    reject(err)
                } else {
                    var globalSettings = rjson.parse(data.toString())
                    var mappedGlobalSettings = this._mapAllSettings(globalSettings)
                    resolve(mappedGlobalSettings)
                }
            })
        })
    }

    analyzeProjectSettings() {
        return new Promise((resolve, reject) => {
            // TODO: Handle multi workspaces?
            vscode.workspace.findFiles('*.sublime-project', 2).then(files => {
                if (!files.length) {
                    resolve([]) // No files to map
                    return
                }

                // Take first file
                var projectFilePath = files[0].fsPath

                fs.readFile(projectFilePath, (err, data) => {
                    if (err) {
                        reject(err)
                    } else {
                        var projectFile = rjson.parse(data.toString())
                        var projectSettings = projectFile.settings

                        // Map project settings
                        var mappedProjectSettings = this._mapAllSettings(projectSettings)

                        resolve(mappedProjectSettings)
                    }
                })
            })
        })
    }

    analyzeSnippets() {
        console.log('importSnippets')

        return new Promise((resolve, reject) => {
            resolve([])
        })
    }
}

module.exports = Importer
<commit_msg>hard coded windows intallation path<commit_after>const fs = require('fs')
const path = require('path')
const vscode = require('vscode')
const rjson = require('relaxed-json')
const AppDirectory = require('appdirectory')

const Setting = require('./setting')

class Importer {
    constructor() {
        this._readSettingsMap()
    }

    _mapAllSettings(sourceSettings) {
        var mappedSettings = []
        for (var key in sourceSettings) {
            var setting = sourceSettings[key]
            var mapped = this._mapSetting(key, setting)
            if (mapped) {
                mappedSettings.push(mapped)
            }
        }
        return mappedSettings
    }

    _mapSetting(key, value) {
        var mappedSetting = this.settingsMap[key]
        if (mappedSetting) {
            if (typeof mappedSetting === 'string') {
                return new Setting(mappedSetting, value)
            } else if (typeof mappedSetting === 'object') {
                let newKey = Object.keys(mappedSetting[value])[0]
                let newValue = Object.values(mappedSetting[value])[0]
                return new Setting(newKey, newValue)
            }
        }

        return null
    }

    _updateSettings(type, settings) {
        settings.forEach(setting => {
            var namespace = setting.name.split('.')[0]
            var settingName = setting.name.split('.')[1]

            var config = vscode.workspace.getConfiguration(namespace)
            var isGlobalSetting = type == 'global'
            if (config && settingName) {
                config.update(settingName, setting.value, isGlobalSetting)
            }
        })
    }

    _readSettingsMap() {
        var mapPath = path.resolve(__dirname, '..', 'map.json')

        fs.readFile(mapPath, 'UTF-8', (err, data) => {
            if (err) {
                return err
            }
            this.settingsMap = rjson.parse(data.toString())
        })
    }

    importEverything() {
        return Promise.all([
            this.importGlobalSettings(),
            this.importProjectSettings(),
            this.importSnippets()
        ])
    }

    importSnippets() {
        return new Promise((resolve, reject) => {
            resolve()
        })
    }

    importGlobalSettings() {
        return new Promise((resolve, reject) => {
            this.analyzeGlobalSettings()
                .then(mappedSettings => {
                    if (mappedSettings.length) {
                        this._updateSettings('global', mappedSettings)
                    }
                    resolve()
                })
                .catch(reject)
        })
    }

    importProjectSettings() {
        return new Promise((resolve, reject) => {
            this.analyzeProjectSettings()
                .then(mappedSettings => {
                    if (mappedSettings.length) {
                        this._updateSettings('workspace', mappedSettings)
                    }
                    resolve()
                })
                .catch(reject)
        })
    }

    analyze() {
        return new Promise((resolve, reject) => {
            Promise.all([
                this.analyzeProjectSettings(),
                this.analyzeGlobalSettings(),
                this.analyzeSnippets()
            ]).then(data => {
                resolve({
                    projectCount: data[0].length,
                    globalCount: data[1].length,
                    snippetsCount: data[2].length
                })
            })
        })
    }

    analyzeGlobalSettings() {
        var dirs = 'C:/Users/t-tisali/AppData/Roaming/Sublime Text 3' // new AppDirectory('Sublime Text 3');
        var settingsPath = path.resolve(dirs, 'Packages', 'User', 'Preferences.sublime-settings')

        // TODO: Check if files exists first

        return new Promise((resolve, reject) => {
            fs.readFile(settingsPath, (err, data) => {
                if (err) {
                    reject(err)
                } else {
                    var globalSettings = rjson.parse(data.toString())
                    var mappedGlobalSettings = this._mapAllSettings(globalSettings)
                    resolve(mappedGlobalSettings)
                }
            })
        })
    }

    analyzeProjectSettings() {
        return new Promise((resolve, reject) => {
            // TODO: Handle multi workspaces?
            vscode.workspace.findFiles('*.sublime-project', 2).then(files => {
                if (!files.length) {
                    resolve([]) // No files to map
                    return
                }

                // Take first file
                var projectFilePath = files[0].fsPath

                fs.readFile(projectFilePath, (err, data) => {
                    if (err) {
                        reject(err)
                    } else {
                        var projectFile = rjson.parse(data.toString())
                        var projectSettings = projectFile.settings

                        // Map project settings
                        var mappedProjectSettings = this._mapAllSettings(projectSettings)

                        resolve(mappedProjectSettings)
                    }
                })
            })
        })
    }

    analyzeSnippets() {
        console.log('importSnippets')

        return new Promise((resolve, reject) => {
            resolve([])
        })
    }
}

module.exports = Importer
<|endoftext|>


<commit_before>var config = require("../config/config.js");
var DataModel = require("../model/datamodel.js");
var RequestModel = require("../model/requestmodel.js");
var httpClient = require("./httpclient.js");

//Class Declaration

function Giphy(){
    this.hostname = config.giphy.hostname;
    this.path = config.giphy.path;
    this.api_key = config.giphy.api_key;

    this.output = [];
    this.ircCallback = function(){};
};

module.exports = function(data){
    return new Giphy().set(data);
};

//Class Methods

Giphy.prototype = DataModel();

//IRC Methods

Giphy.prototype.ircRequest = function(Input){
    this.setOne("ircCallback",Input.callback);
    var input = Input.fullText;
    var callback = this.ircAssembleResults.bind(this);
    this.getGif(input,callback);
};

Giphy.prototype.ircAssembleResults = function(err,res){
    if (err){
        this.setOne("output","Bad Giphy Response :(");
    }else{
        try {
            var r = Math.floor(Math.random() * res.data.length);
            console.log(r);
            var gif = res.data[r].images.original.url;
            this.setOne("output",gif);
        } catch(err) {
            this.setOne("output","Couldn't Find a GIF! :(");
        }
    }
    console.log(this.output);
    this.ircOutputResult();
};

Giphy.prototype.ircOutputResult = function(){
    this.ircCallback(this.output);
    this.output = [];
};

// API Methods

Giphy.prototype.getGif = function(input,callback){
    var query = this.setQueryParams({
        q: input,
        api_key: this.api_key
    });
    var options = {
        path: this.path + query
    };
    this.httpRequest("GET",options,callback);
};

Giphy.prototype.httpRequest = function(method,options,callback){
    var request = RequestModel({
        method: method,
        protocol: "HTTP",
        hostname: this.hostname,
        callback: this.httpCatchResults.bind(this,callback)
    }).set(options);
    httpClient().request(request);
};

Giphy.prototype.httpCatchResults = function(callback,err,body,res){
    if (err){
        callback(err);
    }else{
        try {
            var results = JSON.parse(body);
            callback(null,results);
        } catch(err) {
            console.log(err,"Giphy Response Error");
            callback(err);
        }
    }
};

//API Helper Methods
Giphy.prototype.setQueryParams = function(params){
    var q = "?";
    var i = 0;
    for (p in params){
        i > 0 ? q += "&" : "";
        q += p + "=" + params[p];
        i++;
    }
    return encodeURI(q);
};
<commit_msg>Remove Giphy Logging<commit_after>var config = require("../config/config.js");
var DataModel = require("../model/datamodel.js");
var RequestModel = require("../model/requestmodel.js");
var httpClient = require("./httpclient.js");

//Class Declaration

function Giphy(){
    this.hostname = config.giphy.hostname;
    this.path = config.giphy.path;
    this.api_key = config.giphy.api_key;

    this.output = [];
    this.ircCallback = function(){};
};

module.exports = function(data){
    return new Giphy().set(data);
};

//Class Methods

Giphy.prototype = DataModel();

//IRC Methods

Giphy.prototype.ircRequest = function(Input){
    this.setOne("ircCallback",Input.callback);
    var input = Input.fullText;
    var callback = this.ircAssembleResults.bind(this);
    this.getGif(input,callback);
};

Giphy.prototype.ircAssembleResults = function(err,res){
    if (err){
        this.setOne("output","Bad Giphy Response :(");
    }else{
        try {
            var r = Math.floor(Math.random() * res.data.length);
            var gif = res.data[r].images.original.url;
            this.setOne("output",gif);
        } catch(err) {
            this.setOne("output","Couldn't Find a GIF! :(");
        }
    }
    this.ircOutputResult();
};

Giphy.prototype.ircOutputResult = function(){
    this.ircCallback(this.output);
    this.output = [];
};

// API Methods

Giphy.prototype.getGif = function(input,callback){
    var query = this.setQueryParams({
        q: input,
        api_key: this.api_key
    });
    var options = {
        path: this.path + query
    };
    this.httpRequest("GET",options,callback);
};

Giphy.prototype.httpRequest = function(method,options,callback){
    var request = RequestModel({
        method: method,
        protocol: "HTTP",
        hostname: this.hostname,
        callback: this.httpCatchResults.bind(this,callback)
    }).set(options);
    httpClient().request(request);
};

Giphy.prototype.httpCatchResults = function(callback,err,body,res){
    if (err){
        callback(err);
    }else{
        try {
            var results = JSON.parse(body);
            callback(null,results);
        } catch(err) {
            console.log(err,"Giphy Response Error");
            callback(err);
        }
    }
};

//API Helper Methods
Giphy.prototype.setQueryParams = function(params){
    var q = "?";
    var i = 0;
    for (p in params){
        i > 0 ? q += "&" : "";
        q += p + "=" + params[p];
        i++;
    }
    return encodeURI(q);
};
<|endoftext|>


<commit_before>'use strict';

var objectClone = require('clone');
var commandGenerator = require('./../../helpers/commandGenerator');
var workerManager = require('./../../worker/manager');

/**
 * Clone repository into temporary directory.
 *
 * @param  {Object} data An object with options passed as an arguments to CLI (`.options`) and ProjectDescriptor instance (`.project`).
 */
module.exports = function cloneRepository(data) {
  return new Promise(function(resolve, reject) {
    var commandOptions = objectClone(data.options);
    var command = {
      command: commandGenerator('cloner', commandOptions),
      description: 'Cloning repository...',
    };

    workerManager([command], data.options, function(killed, workerOutput) {
      if (killed) {
        reject();
      } else {
        data.options.input = workerOutput.path;
        data.options.hasAutoGeneratedInput = true;

        resolve(data);
      }
    }, function() {
      reject();
    });
  });
}
<commit_msg>Added exception when cloning repository task was failed. #20<commit_after>'use strict';

var objectClone = require('clone');
var commandGenerator = require('./../../helpers/commandGenerator');
var workerManager = require('./../../worker/manager');

/**
 * Clone repository into temporary directory.
 *
 * @param  {Object} data An object with options passed as an arguments to CLI (`.options`) and ProjectDescriptor instance (`.project`).
 */
module.exports = function cloneRepository(data) {
  return new Promise(function(resolve, reject) {
    var commandOptions = objectClone(data.options);
    var command = {
      command: commandGenerator('cloner', commandOptions),
      description: 'Cloning repository...',
    };

    workerManager([command], data.options, function(killed, workerOutput) {
      if (killed) {
        reject();
      } else {
        data.options.input = workerOutput.path;
        data.options.hasAutoGeneratedInput = true;

        resolve(data);
      }
    }, function() {
      reject(new Error('Unable to clone the repository. Check if you have all necessary rights to the repository and try again.'));
    });
  });
}
<|endoftext|>


<commit_before>'use strict';

app.directive('toolbar', [
  'pageService', function (page) {
    return {
      restrict: 'E',
      templateUrl: 'site/toolbar.html',
      scope: {},
      link: function ($scope) {
        $scope.page = page;
        $scope.hover = undefined;
        $scope.hoverToggle = function (hover, $event) {
          $scope.hover = (($scope.hover === hover) ? undefined : hover);
          if ($event)
            $event.stopPropagation();
        };
        $scope.$on('$locationChangeStart', function () {
          $scope.hover = undefined;
        });
        $scope.search = function () {
          page.$location.url(page.router.search()).search($scope.search.data);
          $scope.search.data.q = "";
        };
        $scope.search.data = {};
        /* Not ideal, should really come with the rest of user data: */
        if (!('notifications' in page.models.Login))
          page.models.Login.get({'notifications':true});
      }
    };
  }
]);
<commit_msg>Only make notifications request if logged in<commit_after>'use strict';

app.directive('toolbar', [
  'pageService', function (page) {
    return {
      restrict: 'E',
      templateUrl: 'site/toolbar.html',
      scope: {},
      link: function ($scope) {
        $scope.page = page;
        $scope.hover = undefined;
        $scope.hoverToggle = function (hover, $event) {
          $scope.hover = (($scope.hover === hover) ? undefined : hover);
          if ($event)
            $event.stopPropagation();
        };
        $scope.$on('$locationChangeStart', function () {
          $scope.hover = undefined;
        });
        $scope.search = function () {
          page.$location.url(page.router.search()).search($scope.search.data);
          $scope.search.data.q = "";
        };
        $scope.search.data = {};
        /* Not ideal, should really come with the rest of user data: */
        if (page.models.Login.isLoggedIn() && !('notifications' in page.models.Login))
          page.models.Login.get({'notifications':true});
      }
    };
  }
]);
<|endoftext|>


<commit_before>import assert from 'assert';
import React from 'react/addons';
const TestUtils = React.addons.TestUtils;

describe('find dom nodes', function() {

  describe('finds the right number of nodes', function() {
    it('one', function() {
      let renderedTree = render();
      assert.equal(domNodesFromRenderedTree(renderedTree).length, 1);
    });
    it('two nodes, one nesting level deep', function() {
      let renderedTree = render(

);
      assert.equal(domNodesFromRenderedTree(renderedTree).length, 2);
    });
    it('inner node is NOT a DOM node', function() {
      class NotDomNode extends React.Component { render() { return null; } }
      let renderedTree = render(
<NotDomNode></NotDomNode>
);
      assert.equal(domNodesFromRenderedTree(renderedTree).length, 1);
    });
  });

  describe('returns all nodes', function() {
    it('for one node', function() {
      let renderedTree = render();
      assert.equal(domNodesFromRenderedTree(renderedTree)[0].type, 'b');
    });
    describe('nested nodes', function() {
      describe('two nodes, one level nesting', function() {
        let domNodes;
        beforeEach(function() {
          let renderedTree = render(

);
          domNodes = domNodesFromRenderedTree(renderedTree);
        });
        it('first node is the outer node', () => { assert.equal(domNodes[0].type, 'div'); });
        it('second node is the inner node', () => { assert.equal(domNodes[1].type, 'b'); });
      });
      describe('three nodes, two levels nesting', function() {
        let domNodes;
        beforeEach(function() {
          let renderedTree = render(

);
          domNodes = domNodesFromRenderedTree(renderedTree);
        });
        it('first node is the outer node', () => { assert.equal(domNodes[0].type, 'div'); });
        it('second node is the node on the first level', () => { assert.equal(domNodes[1].type, 'b'); });
        it('third node is the inner node', () => { assert.equal(domNodes[2].type, 'span'); });
      });
      describe('three nodes, one level nesting', function() {
        let domNodes;
        beforeEach(function() {
          let renderedTree = render(

);
          domNodes = domNodesFromRenderedTree(renderedTree);
        });
        it('first node is the outer node', () => { assert.equal(domNodes[0].type, 'div'); });
        it('second node is the 1st node on the first level', () => { assert.equal(domNodes[1].type, 'b'); });
        it('third node is the 2nd node on the first level', () => { assert.equal(domNodes[2].type, 'span'); });
      });
    });
  });

});

function allChildrenFromRenderedTree(children) {
  if (!children) {
    return [];
  }
  if (Array.isArray(children)) {
    return [...children];
  }
  return [children, ...allChildrenFromRenderedTree(children.props.children)];
}
function allNodes(tree) {
  return [tree, ...allChildrenFromRenderedTree(tree.props.children)];
}
const isDomNode = (node) => node.type in React.DOM;
function domNodesFromRenderedTree(tree) {
  return allNodes(tree)
    .filter(isDomNode);
}

function render(componentToRender) {
  const shallowRenderer = TestUtils.createRenderer();
  shallowRenderer.render(componentToRender);
  return shallowRenderer.getRenderOutput();
}

//rendersDomNodeAttributeWithValue
//rendersDomNodeWithInnerText

//return (
//

//
//
{name}

//
{description}

//
//

//);
<commit_msg>Flatten a complex tree and ensure flattened order.<commit_after>import assert from 'assert';
import React from 'react/addons';
const TestUtils = React.addons.TestUtils;

describe('find dom nodes', function() {

  describe('finds the right number of nodes', function() {
    it('one', function() {
      let renderedTree = render();
      assert.equal(domNodesFromRenderedTree(renderedTree).length, 1);
    });
    it('two nodes, one nesting level deep', function() {
      let renderedTree = render(

);
      assert.equal(domNodesFromRenderedTree(renderedTree).length, 2);
    });
    it('if inner node is NOT a DOM node, it does not count', function() {
      class NotDomNode extends React.Component { render() { return null; } }
      let renderedTree = render(
<NotDomNode></NotDomNode>
);
      assert.equal(domNodesFromRenderedTree(renderedTree).length, 1);
    });
  });

  describe('returns all nodes', function() {
    it('for one node', function() {
      let renderedTree = render();
      assert.equal(domNodesFromRenderedTree(renderedTree)[0].type, 'b');
    });
    describe('nested nodes', function() {
      describe('two nodes, one level nesting', function() {
        let domNodes;
        beforeEach(function() {
          let renderedTree = render(

);
          domNodes = domNodesFromRenderedTree(renderedTree);
        });
        it('first node is the outer node', () => { assert.equal(domNodes[0].type, 'div'); });
        it('second node is the inner node', () => { assert.equal(domNodes[1].type, 'b'); });
      });
      describe('three nodes, two levels nesting', function() {
        let domNodes;
        beforeEach(function() {
          let renderedTree = render(

);
          domNodes = domNodesFromRenderedTree(renderedTree);
        });
        it('first node is the outer node', () => { assert.equal(domNodes[0].type, 'div'); });
        it('second node is the node on the first level', () => { assert.equal(domNodes[1].type, 'b'); });
        it('third node is the inner node', () => { assert.equal(domNodes[2].type, 'span'); });
      });
      describe('three nodes, one level nesting', function() {
        let domNodes;
        beforeEach(function() {
          let renderedTree = render(

);
          domNodes = domNodesFromRenderedTree(renderedTree);
        });
        it('first node is the outer node', () => { assert.equal(domNodes[0].type, 'div'); });
        it('second node is the 1st node on the first level', () => { assert.equal(domNodes[1].type, 'b'); });
        it('third node is the 2nd node on the first level', () => { assert.equal(domNodes[2].type, 'span'); });
      });
      describe('many DOM nodes, various nestings', function() {
        let domNodes;
        beforeEach(function() {
          let renderedTree = render(

          );
          domNodes = domNodesFromRenderedTree(renderedTree);
        });
        it('the count is correct', () => { assert.equal(domNodes.length, 8); });
        it('first node is the outer node', () => { assert.equal(domNodes[0].type, 'div'); });
        it('2nd node is `div`', () => { assert.equal(domNodes[1].type, 'div'); });
        it('3rd node is `span`', () => { assert.equal(domNodes[2].type, 'span'); });
        it('4th node is `span`', () => { assert.equal(domNodes[3].type, 'span'); });
        it('5th node is `span`', () => { assert.equal(domNodes[4].type, 'span'); });
        it('6th node is `span`', () => { assert.equal(domNodes[5].type, 'span'); });
        it('7th node is `b`', () => { assert.equal(domNodes[6].type, 'b'); });
      });
    });
  });

});

function moreChildren(tree) {
console.log(tree);
  if (tree.props && tree.props.children) {
    console.log(tree.props.children);
  }
  return [...tree];
}
const ensureToBeArray = (mayBeArray) => Array.isArray(mayBeArray) ? mayBeArray : [mayBeArray];
const flatten = (arr, merged) => [...arr, ...merged];
function allChildrenFromRenderedTree({props = {}}) {
  if (!props.children) {
    return [];
  }
  let children = ensureToBeArray(props.children);
  return [...children, ...children.map(allChildrenFromRenderedTree).reduce(flatten)];
}

function allNodes(tree) {
  return [tree, ...allChildrenFromRenderedTree(tree)];
}

const isDomNode = (node) => node.type in React.DOM;
function domNodesFromRenderedTree(tree) {
  return allNodes(tree)
    .filter(isDomNode);
}

function render(componentToRender) {
  const shallowRenderer = TestUtils.createRenderer();
  shallowRenderer.render(componentToRender);
  return shallowRenderer.getRenderOutput();
}

//rendersDomNodeAttributeWithValue
//rendersDomNodeWithInnerText

//return (
//

//
//
{name}

//
{description}

//
//

//);
<|endoftext|>