<commit_before>const Prefixer = require('../lib/prefixer');
const parse    = require('postcss/lib/parse');

describe('Prefixer', () => {
    beforeEach(function () {
        this.prefix = new Prefixer();
        return this.css = parse('@-ms-keyframes a { to { } } ' +
                 ':-moz-full-screen { } a { } ' +
                 '@-dev-keyframes s { to { } }');
    });

    describe('.hack()', () =>

    it('registers hacks for subclasses', () => {
        class A extends Prefixer {}

        class Hack extends A {
            static initClass() {
                this.names = ['a', 'b'];
            }
      }
        Hack.initClass();
        A.hack(Hack);

        A.hacks.should.eql({ a: Hack, b: Hack });
        return (Prefixer.hacks === undefined).should.be.true;
    })
  );

    describe('.load()', () =>

    it('loads hacks', () => {
        class A extends Prefixer {
            static initClass() {
                this.prototype.klass = 'a';
            }
      }
        A.initClass();
        class Hack extends A {
            static initClass() {
                this.prototype.klass = 'hack';
            }
      }
        Hack.initClass();
        A.hacks = { hacked: Hack };

        A.load('hacked').klass.should.eql('hack');
        return A.load('a').klass.should.eql('a');
    })
  );

    describe('.clone()', () => {

        it('cleans custom properties', function () {
            const rule = this.css.first.first;
            rule._autoprefixerPrefix = '-ms-';
            rule._autoprefixerValues = { '-ms-': 1 };

            const cloned = Prefixer.clone(rule, { selector: 'from' });
            cloned.selector.should.eql('from');

            (cloned._autoprefixerPrefix === undefined).should.be.true;
            return (cloned._autoprefixerValues === undefined).should.be.true;
        });

        return it('fixed declaration between', () => {
            const css = parse('a { color : black }');
            const cloned = Prefixer.clone(css.first.first);
            return cloned.raws.between.should.eql(' : ');
        });
    });

    return describe('parentPrefix', () => {

        it('works with root node', function () {
            return this.prefix.parentPrefix(this.css).should.be.false;
        });

        it('finds in at-rules', function () {
            return this.prefix.parentPrefix(this.css.first).should.eql('-ms-');
        });

        it('finds in selectors', function () {
            return this.prefix.parentPrefix(this.css.nodes[1]).should.eql('-moz-');
        });

        it('finds in parents', function () {
            this.prefix.parentPrefix(this.css.first.first).should.eql('-ms-');
            return this.prefix.parentPrefix(this.css.nodes[2]).should.be.false;
        });

        it('caches prefix', function () {
            this.prefix.parentPrefix(this.css.first);
            this.css.first._autoprefixerPrefix.should.eql('-ms-');

            this.css.first._autoprefixerPrefix = false;
            return this.prefix.parentPrefix(this.css.first).should.be.false;
        });

        it('finds only browsers prefixes', function () {
            return this.prefix.parentPrefix(this.css.nodes[2]).should.be.false;
        });

        return it('works with selector contained --', function () {
            const css = parse(':--a { color: black }');
            return this.prefix.parentPrefix(css.first.first).should.be.false;
        });
    });
});
<commit_msg>Fix test/prefixer.js<commit_after>const Prefixer = require('../lib/prefixer');
const parse    = require('postcss/lib/parse');

describe('Prefixer', () => {

    beforeEach(function () {
        this.prefix = new Prefixer();
        this.css = parse('@-ms-keyframes a { to { } } ' +
                         ':-moz-full-screen { } a { } ' +
                         '@-dev-keyframes s { to { } }');
    });

    describe('.hack()', () => {

        it('registers hacks for subclasses', () => {
            class A extends Prefixer {}
            class Hack extends A {
                static initClass() {
                    this.names = ['a', 'b'];
                }
            }

            Hack.initClass();
            A.hack(Hack);

            A.hacks.should.eql({ a: Hack, b: Hack });
            (Prefixer.hacks === undefined).should.be.true;
        });

    });

    describe('.load()', () => {

        it('loads hacks', () => {
            class A extends Prefixer {
                static initClass() {
                    this.prototype.klass = 'a';
                }
            }
            A.initClass();
            class Hack extends A {
                static initClass() {
                    this.prototype.klass = 'hack';
                }
            }
            Hack.initClass();
            A.hacks = { hacked: Hack };

            A.load('hacked').klass.should.eql('hack');
            A.load('a').klass.should.eql('a');
        });

    });

    describe('.clone()', () => {

        it('cleans custom properties', function () {
            const rule = this.css.first.first;
            rule._autoprefixerPrefix = '-ms-';
            rule._autoprefixerValues = { '-ms-': 1 };

            const cloned = Prefixer.clone(rule, { selector: 'from' });
            cloned.selector.should.eql('from');

            (cloned._autoprefixerPrefix === undefined).should.be.true;
            (cloned._autoprefixerValues === undefined).should.be.true;
        });

        it('fixed declaration between', () => {
            const css = parse('a { color : black }');
            const cloned = Prefixer.clone(css.first.first);
            cloned.raws.between.should.eql(' : ');
        });
    });

    describe('parentPrefix', () => {

        it('works with root node', function () {
            this.prefix.parentPrefix(this.css).should.be.false;
        });

        it('finds in at-rules', function () {
            this.prefix.parentPrefix(this.css.first).should.eql('-ms-');
        });

        it('finds in selectors', function () {
            this.prefix.parentPrefix(this.css.nodes[1]).should.eql('-moz-');
        });

        it('finds in parents', function () {
            this.prefix.parentPrefix(this.css.first.first).should.eql('-ms-');
            this.prefix.parentPrefix(this.css.nodes[2]).should.be.false;
        });

        it('caches prefix', function () {
            this.prefix.parentPrefix(this.css.first);
            this.css.first._autoprefixerPrefix.should.eql('-ms-');

            this.css.first._autoprefixerPrefix = false;
            this.prefix.parentPrefix(this.css.first).should.be.false;
        });

        it('finds only browsers prefixes', function () {
            this.prefix.parentPrefix(this.css.nodes[2]).should.be.false;
        });

        it('works with selector contained --', function () {
            const css = parse(':--a { color: black }');
            this.prefix.parentPrefix(css.first.first).should.be.false;
        });
    });
});
<|endoftext|>


<commit_before>var Store = require('./store')

module.exports = GameState

function GameState(dispatcher) {
    Store.mixin(this)

    this.playerNames = []
    this.settings = {
        merlin: false,
    }

    dispatcher.onAction(function(payload) {
        var actions = GameState.actions
        if (_.isFunction(actions[payload.action])) {
            actions[payload.action].call(this, payload)
        }
    }.bind(this))
}

GameState.actions = {}

GameState.actions.addPlayer = function(payload) {
    this.playerNames.push(payload.name)
    this._emitChange()
}

GameState.actions.deletePlayer = function(payload) {
    this.playerNames = _.without(this.playerNames, payload.name)
    this._emitChange()
}

GameState.actions.changeSettings = function(payload) {
    _.extend(this.settings, payload.settings)
    this._emitChange()
}
<commit_msg>ignore duplicate name in store<commit_after>var Store = require('./store')

module.exports = GameState

function GameState(dispatcher) {
    Store.mixin(this)

    this.playerNames = []
    this.settings = {
        merlin: false,
    }

    dispatcher.onAction(function(payload) {
        var actions = GameState.actions
        if (_.isFunction(actions[payload.action])) {
            actions[payload.action].call(this, payload)
        }
    }.bind(this))
}

GameState.actions = {}

GameState.actions.addPlayer = function(payload) {
    var name = payload.name
    if (!_.contains(this.playerNames, name)) {
        this.playerNames.push(name)
        this._emitChange()
    } else {
        console.log("ignoring duplicate name", name)
    }
}

GameState.actions.deletePlayer = function(payload) {
    this.playerNames = _.without(this.playerNames, payload.name)
    this._emitChange()
}

GameState.actions.changeSettings = function(payload) {
    _.extend(this.settings, payload.settings)
    this._emitChange()
}
<|endoftext|>


<commit_before>const t = require('ava')
const Renderer = require('..').Renderer
const bel = require('bel')

function toHTMLString(result) {
  let testElement = bel`<span>${result}</span>`
  let ret = testElement.toString()
  ret = ret.substring(6, ret.length - 7)
  return ret
}

t('render should do nothing', t => {
  let r = new Renderer()
  t.is(toHTMLString(r.render(['abc', 'def'])), 'abcdef')
})

t('render should return empty', t => {
  let r = new Renderer()
  t.is(toHTMLString(r.render()), '')
})

t('basic render', t => {
  let r = new Renderer()
  t.is(
    toHTMLString(r.render(['a', { rb: '今日', rt: 'きょう' }, 'b'])),
    'a<ruby>今日<rp>(</rp><rt>きょう</rt><rp>)</rp></ruby>b'
  )
})

t('rb without rt', t => {
  let r = new Renderer()
  t.is(toHTMLString(r.render(['a', { rb: 'b' }, 'c'])), 'abc')
})

t('throw error', t => {
  let r = new Renderer()
  t.throws(() => r.render(NaN))
})

t('should render valid HTML', t => {
  let r = new Renderer()
  t.is(toHTMLString(r.render(['&><'])), '&><')
})
<commit_msg>add test case for custom objects<commit_after>const t = require('ava')
const Renderer = require('..').Renderer
const bel = require('bel')

function toHTMLString(result) {
  let testElement = bel`<span>${result}</span>`
  let ret = testElement.toString()
  ret = ret.substring(6, ret.length - 7)
  return ret
}

t('render should do nothing', t => {
  let r = new Renderer()
  t.is(toHTMLString(r.render(['abc', 'def'])), 'abcdef')
})

t('render should return empty', t => {
  let r = new Renderer()
  t.is(toHTMLString(r.render()), '')
})

t('basic render', t => {
  let r = new Renderer()
  t.is(
    toHTMLString(r.render(['a', { rb: '今日', rt: 'きょう' }, 'b'])),
    'a<ruby>今日<rp>(</rp><rt>きょう</rt><rp>)</rp></ruby>b'
  )
})

t('rb without rt', t => {
  let r = new Renderer()
  t.is(toHTMLString(r.render(['a', { rb: 'b' }, 'c'])), 'abc')
})

t('throw error', t => {
  let r = new Renderer()
  t.throws(() => r.render(NaN))
})

t('should render valid HTML', t => {
  let r = new Renderer()
  t.is(toHTMLString(r.render(['&><'])), '&><')
})

t('custom object support', t => {
  let r = new Renderer()
  t.deepEqual(r.render([{ abc: 123 }]), [{ abc: 123 }])
})
<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc service
 * @name ng.$q
 * @requires $rootScope
 *
 * @description
 * A promise/deferred implementation inspired by [Kris Kowal's Q](https://github.com/kriskowal/q).
 *
 * [The CommonJS Promise proposal](http://wiki.commonjs.org/wiki/Promises) describes a promise as an
 * interface for interacting with an object that represents the result of an action that is
 * performed asynchronously, and may or may not be finished at any given point in time.
 *
 * From the perspective of dealing with error handling, deferred and promise apis are to
 * asynchronous programing what `try`, `catch` and `throw` keywords are to synchronous programing.
 *
 *

 *   // for the purpose of this example let's assume that variables `$q` and `scope` are
 *   // available in the current lexical scope (they could have been injected or passed in).
 *
 *   function asyncGreet(name) {
 *     var deferred = $q.defer();
 *
 *     setTimeout(function() {
 *       // since this fn executes async in a future turn of the event loop, we need to wrap
 *       // our code into an $apply call so that the model changes are properly observed.
 *       scope.$apply(function() {
 *         if (okToGreet(name)) {
 *           deferred.resolve('Hello, ' + name + '!');
 *         } else {
 *           deferred.reject('Greeting ' + name + ' is not allowed.');
 *         }
 *       });
 *     }, 1000);
 *
 *     return deferred.promise;
 *   }
 *
 *   var promise = asyncGreet('Robin Hood');
 *   promise.then(function(greeting) {
 *     alert('Success: ' + greeting);
 *   }, function(reason) {
 *     alert('Failed: ' + reason);
 *   );
 *

 *
 * At first it might not be obvious why this extra complexity is worth the trouble. The payoff
 * comes in the way of
 * [guarantees that promise and deferred apis make](https://github.com/kriskowal/uncommonjs/blob/master/promises/specification.md).
 *
 * Additionally the promise api allows for composition that is very hard to do with the
 * traditional callback ([CPS](http://en.wikipedia.org/wiki/Continuation-passing_style)) approach.
 * For more on this please see the [Q documentation](https://github.com/kriskowal/q) especially the
 * section on serial or parallel joining of promises.
 *
 *
 * # The Deferred API
 *
 * A new instance of deferred is constructed by calling `$q.defer()`.
 *
 * The purpose of the deferred object is to expose the associated Promise instance as well as apis
 * that can be used for signaling the successful or unsuccessful completion of the task.
 *
 * **Methods**
 *
 * - `resolve(value)` – resolves the derived promise with the `value`. If the value is a rejection
 *   constructed via `$q.reject`, the promise will be rejected instead.
 * - `reject(reason)` – rejects the derived promise with the `reason`. This is equivalent to
 *   resolving it with a rejection constructed via `$q.reject`.
 *
 * **Properties**
 *
 * - promise – `{Promise}` – promise object associated with this deferred.
 *
 *
 * # The Promise API
 *
 * A new promise instance is created when a deferred instance is created and can be retrieved by
 * calling `deferred.promise`.
 *
 * The purpose of the promise object is to allow for interested parties to get access to the result
 * of the deferred task when it completes.
 *
 * **Methods**
 *
 * - `then(successCallback, errorCallback)` – regardless of when the promise was or will be resolved
 *   or rejected calls one of the success or error callbacks asynchronously as soon as the result
 *   is available. The callbacks are called with a single argument the result or rejection reason.
 *
 *   This method *returns a new promise* which is resolved or rejected via the return value of the
 *   `successCallback` or `errorCallback`.
 *
 *
 * # Chaining promises
 *
 * Because calling `then` api of a promise returns a new derived promise, it is easily possible
 * to create a chain of promises:
 *
 *

 *   promiseB = promiseA.then(function(result) {
 *     return result + 1;
 *   });
 *
 *   // promiseB will be resolved immediately after promiseA is resolved and it's value will be
 *   // the result of promiseA incremented by 1
 *

 *
 * It is possible to create chains of any length and since a promise can be resolved with another
 * promise (which will defer its resolution further), it is possible to pause/defer resolution of
 * the promises at any point in the chain. This makes it possible to implement powerful apis like
 * $http's response interceptors.
 *
 *
 * # Differences between Kris Kowal's Q and $q
 *
 *  There are three main differences:
 *
 * - $q is integrated with the {@link ng.$rootScope.Scope} Scope model observation
 *   mechanism in angular, which means faster propagation of resolution or rejection into your
 *   models and avoiding unnecessary browser repaints, which would result in flickering UI.
 * - $q promises are recognized by the templating engine in angular, which means that in templates
 *   you can treat promises attached to a scope as if they were the resulting values.
 * - Q has many more features that $q, but that comes at a cost of bytes. $q is tiny, but contains
 *   all the important functionality needed for common async tasks.
 */
function $QProvider() {

  this.$get = ['$rootScope', '$exceptionHandler', function($rootScope, $exceptionHandler) {
    return qFactory(function(callback) {
      $rootScope.$evalAsync(callback);
    }, $exceptionHandler);
  }];
}

/**
 * Constructs a promise manager.
 *
 * @param {function(function)} nextTick Function for executing functions in the next turn.
 * @param {function(...*)} exceptionHandler Function into which unexpected exceptions are passed for
 *     debugging purposes.
 * @returns {object} Promise manager.
 */
function qFactory(nextTick, exceptionHandler) {

  /**
   * @ngdoc
   * @name ng.$q#defer
   * @methodOf ng.$q
   * @description
   * Creates a `Deferred` object which represents a task which will finish in the future.
   *
   * @returns {Deferred} Returns a new instance of deferred.
   */
  var defer = function() {
    var pending = [],
        value, deferred;

    deferred = {

      resolve: function(val) {
        if (pending) {
          var callbacks = pending;
          pending = undefined;
          value = ref(val);

          if (callbacks.length) {
            nextTick(function() {
              var callback;
              for (var i = 0, ii = callbacks.length; i < ii; i++) {
                callback = callbacks[i];
                value.then(callback[0], callback[1]);
              }
            });
          }
        }
      },

      reject: function(reason) {
        deferred.resolve(reject(reason));
      },

      promise: {
        then: function(callback, errback) {
          var result = defer();

          var wrappedCallback = function(value) {
            try {
              result.resolve((callback || defaultCallback)(value));
            } catch(e) {
              exceptionHandler(e);
              result.reject(e);
            }
          };

          var wrappedErrback = function(reason) {
            try {
              result.resolve((errback || defaultErrback)(reason));
            } catch(e) {
              exceptionHandler(e);
              result.reject(e);
            }
          };

          if (pending) {
            pending.push([wrappedCallback, wrappedErrback]);
          } else {
            value.then(wrappedCallback, wrappedErrback);
          }

          return result.promise;
        }
      }
    };

    return deferred;
  };

  var ref = function(value) {
    if (value && value.then) return value;
    return {
      then: function(callback) {
        var result = defer();
        nextTick(function() {
          result.resolve(callback(value));
        });
        return result.promise;
      }
    };
  };

  /**
   * @ngdoc
   * @name ng.$q#reject
   * @methodOf ng.$q
   * @description
   * Creates a promise that is resolved as rejected with the specified `reason`. This api should be
   * used to forward rejection in a chain of promises. If you are dealing with the last promise in
   * a promise chain, you don't need to worry about it.
   *
   * When comparing deferreds/promises to the familiar behavior of try/catch/throw, think of
   * `reject` as the `throw` keyword in JavaScript. This also means that if you "catch" an error via
   * a promise error callback and you want to forward the error to the promise derived from the
   * current promise, you have to "rethrow" the error by returning a rejection constructed via
   * `reject`.
   *
   *

   *   promiseB = promiseA.then(function(result) {
   *     // success: do something and resolve promiseB
   *     //          with the old or a new result
   *     return result;
   *   }, function(reason) {
   *     // error: handle the error if possible and
   *     //        resolve promiseB with newPromiseOrValue,
   *     //        otherwise forward the rejection to promiseB
   *     if (canHandle(reason)) {
   *      // handle the error and recover
   *      return newPromiseOrValue;
   *     }
   *     return $q.reject(reason);
   *   });
   *

   *
   * @param {*} reason Constant, message, exception or an object representing the rejection reason.
   * @returns {Promise} Returns a promise that was already resolved as rejected with the `reason`.
   */
  var reject = function(reason) {
    return {
      then: function(callback, errback) {
        var result = defer();
        nextTick(function() {
          result.resolve((errback || defaultErrback)(reason));
        });
        return result.promise;
      }
    };
  };

  /**
   * @ngdoc
   * @name ng.$q#when
   * @methodOf ng.$q
   * @description
   * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise.
   * This is useful when you are dealing with on object that might or might not be a promise, or if
   * the promise comes from a source that can't be trusted.
   *
   * @param {*} value Value or a promise
   * @returns {Promise} Returns a single promise that will be resolved with an array of values,
   *   each value coresponding to the promise at the same index in the `promises` array. If any of
   *   the promises is resolved with a rejection, this resulting promise will be resolved with the
   *   same rejection.
   */
  var when = function(value, callback, errback) {
    var result = defer(),
        done;

    var wrappedCallback = function(value) {
      try {
        return (callback || defaultCallback)(value);
      } catch (e) {
        exceptionHandler(e);
        return reject(e);
      }
    };

    var wrappedErrback = function(reason) {
      try {
        return (errback || defaultErrback)(reason);
      } catch (e) {
        exceptionHandler(e);
        return reject(e);
      }
    };

    nextTick(function() {
      ref(value).then(function(value) {
        if (done) return;
        done = true;
        result.resolve(ref(value).then(wrappedCallback, wrappedErrback));
      }, function(reason) {
        if (done) return;
        done = true;
        result.resolve(wrappedErrback(reason));
      });
    });

    return result.promise;
  };

  function defaultCallback(value) {
    return value;
  }

  function defaultErrback(reason) {
    return reject(reason);
  }

  /**
   * @ngdoc
   * @name ng.$q#all
   * @methodOf ng.$q
   * @description
   * Combines multiple promises into a single promise that is resolved when all of the input
   * promises are resolved.
   *
   * @param {Array.<Promise>} promises An array of promises.
   * @returns {Promise} Returns a single promise that will be resolved with an array of values,
   *   each value coresponding to the promise at the same index in the `promises` array. If any of
   *   the promises is resolved with a rejection, this resulting promise will be resolved with the
   *   same rejection.
   */
  function all(promises) {
    var deferred = defer(),
        counter = promises.length,
        results = [];

    if (counter) {
      forEach(promises, function(promise, index) {
        ref(promise).then(function(value) {
          if (index in results) return;
          results[index] = value;
          if (!(--counter)) deferred.resolve(results);
        }, function(reason) {
          if (index in results) return;
          deferred.reject(reason);
        });
      });
    } else {
      deferred.resolve(results);
    }

    return deferred.promise;
  }

  return {
    defer: defer,
    reject: reject,
    when: when,
    all: all
  };
}
<commit_msg>docs($q): fix missing bracket in the example<commit_after>'use strict';

/**
 * @ngdoc service
 * @name ng.$q
 * @requires $rootScope
 *
 * @description
 * A promise/deferred implementation inspired by [Kris Kowal's Q](https://github.com/kriskowal/q).
 *
 * [The CommonJS Promise proposal](http://wiki.commonjs.org/wiki/Promises) describes a promise as an
 * interface for interacting with an object that represents the result of an action that is
 * performed asynchronously, and may or may not be finished at any given point in time.
 *
 * From the perspective of dealing with error handling, deferred and promise apis are to
 * asynchronous programing what `try`, `catch` and `throw` keywords are to synchronous programing.
 *
 *

 *   // for the purpose of this example let's assume that variables `$q` and `scope` are
 *   // available in the current lexical scope (they could have been injected or passed in).
 *
 *   function asyncGreet(name) {
 *     var deferred = $q.defer();
 *
 *     setTimeout(function() {
 *       // since this fn executes async in a future turn of the event loop, we need to wrap
 *       // our code into an $apply call so that the model changes are properly observed.
 *       scope.$apply(function() {
 *         if (okToGreet(name)) {
 *           deferred.resolve('Hello, ' + name + '!');
 *         } else {
 *           deferred.reject('Greeting ' + name + ' is not allowed.');
 *         }
 *       });
 *     }, 1000);
 *
 *     return deferred.promise;
 *   }
 *
 *   var promise = asyncGreet('Robin Hood');
 *   promise.then(function(greeting) {
 *     alert('Success: ' + greeting);
 *   }, function(reason) {
 *     alert('Failed: ' + reason);
 *   });
 *

 *
 * At first it might not be obvious why this extra complexity is worth the trouble. The payoff
 * comes in the way of
 * [guarantees that promise and deferred apis make](https://github.com/kriskowal/uncommonjs/blob/master/promises/specification.md).
 *
 * Additionally the promise api allows for composition that is very hard to do with the
 * traditional callback ([CPS](http://en.wikipedia.org/wiki/Continuation-passing_style)) approach.
 * For more on this please see the [Q documentation](https://github.com/kriskowal/q) especially the
 * section on serial or parallel joining of promises.
 *
 *
 * # The Deferred API
 *
 * A new instance of deferred is constructed by calling `$q.defer()`.
 *
 * The purpose of the deferred object is to expose the associated Promise instance as well as apis
 * that can be used for signaling the successful or unsuccessful completion of the task.
 *
 * **Methods**
 *
 * - `resolve(value)` – resolves the derived promise with the `value`. If the value is a rejection
 *   constructed via `$q.reject`, the promise will be rejected instead.
 * - `reject(reason)` – rejects the derived promise with the `reason`. This is equivalent to
 *   resolving it with a rejection constructed via `$q.reject`.
 *
 * **Properties**
 *
 * - promise – `{Promise}` – promise object associated with this deferred.
 *
 *
 * # The Promise API
 *
 * A new promise instance is created when a deferred instance is created and can be retrieved by
 * calling `deferred.promise`.
 *
 * The purpose of the promise object is to allow for interested parties to get access to the result
 * of the deferred task when it completes.
 *
 * **Methods**
 *
 * - `then(successCallback, errorCallback)` – regardless of when the promise was or will be resolved
 *   or rejected calls one of the success or error callbacks asynchronously as soon as the result
 *   is available. The callbacks are called with a single argument the result or rejection reason.
 *
 *   This method *returns a new promise* which is resolved or rejected via the return value of the
 *   `successCallback` or `errorCallback`.
 *
 *
 * # Chaining promises
 *
 * Because calling `then` api of a promise returns a new derived promise, it is easily possible
 * to create a chain of promises:
 *
 *

 *   promiseB = promiseA.then(function(result) {
 *     return result + 1;
 *   });
 *
 *   // promiseB will be resolved immediately after promiseA is resolved and it's value will be
 *   // the result of promiseA incremented by 1
 *

 *
 * It is possible to create chains of any length and since a promise can be resolved with another
 * promise (which will defer its resolution further), it is possible to pause/defer resolution of
 * the promises at any point in the chain. This makes it possible to implement powerful apis like
 * $http's response interceptors.
 *
 *
 * # Differences between Kris Kowal's Q and $q
 *
 *  There are three main differences:
 *
 * - $q is integrated with the {@link ng.$rootScope.Scope} Scope model observation
 *   mechanism in angular, which means faster propagation of resolution or rejection into your
 *   models and avoiding unnecessary browser repaints, which would result in flickering UI.
 * - $q promises are recognized by the templating engine in angular, which means that in templates
 *   you can treat promises attached to a scope as if they were the resulting values.
 * - Q has many more features that $q, but that comes at a cost of bytes. $q is tiny, but contains
 *   all the important functionality needed for common async tasks.
 */
function $QProvider() {

  this.$get = ['$rootScope', '$exceptionHandler', function($rootScope, $exceptionHandler) {
    return qFactory(function(callback) {
      $rootScope.$evalAsync(callback);
    }, $exceptionHandler);
  }];
}

/**
 * Constructs a promise manager.
 *
 * @param {function(function)} nextTick Function for executing functions in the next turn.
 * @param {function(...*)} exceptionHandler Function into which unexpected exceptions are passed for
 *     debugging purposes.
 * @returns {object} Promise manager.
 */
function qFactory(nextTick, exceptionHandler) {

  /**
   * @ngdoc
   * @name ng.$q#defer
   * @methodOf ng.$q
   * @description
   * Creates a `Deferred` object which represents a task which will finish in the future.
   *
   * @returns {Deferred} Returns a new instance of deferred.
   */
  var defer = function() {
    var pending = [],
        value, deferred;

    deferred = {

      resolve: function(val) {
        if (pending) {
          var callbacks = pending;
          pending = undefined;
          value = ref(val);

          if (callbacks.length) {
            nextTick(function() {
              var callback;
              for (var i = 0, ii = callbacks.length; i < ii; i++) {
                callback = callbacks[i];
                value.then(callback[0], callback[1]);
              }
            });
          }
        }
      },

      reject: function(reason) {
        deferred.resolve(reject(reason));
      },

      promise: {
        then: function(callback, errback) {
          var result = defer();

          var wrappedCallback = function(value) {
            try {
              result.resolve((callback || defaultCallback)(value));
            } catch(e) {
              exceptionHandler(e);
              result.reject(e);
            }
          };

          var wrappedErrback = function(reason) {
            try {
              result.resolve((errback || defaultErrback)(reason));
            } catch(e) {
              exceptionHandler(e);
              result.reject(e);
            }
          };

          if (pending) {
            pending.push([wrappedCallback, wrappedErrback]);
          } else {
            value.then(wrappedCallback, wrappedErrback);
          }

          return result.promise;
        }
      }
    };

    return deferred;
  };

  var ref = function(value) {
    if (value && value.then) return value;
    return {
      then: function(callback) {
        var result = defer();
        nextTick(function() {
          result.resolve(callback(value));
        });
        return result.promise;
      }
    };
  };

  /**
   * @ngdoc
   * @name ng.$q#reject
   * @methodOf ng.$q
   * @description
   * Creates a promise that is resolved as rejected with the specified `reason`. This api should be
   * used to forward rejection in a chain of promises. If you are dealing with the last promise in
   * a promise chain, you don't need to worry about it.
   *
   * When comparing deferreds/promises to the familiar behavior of try/catch/throw, think of
   * `reject` as the `throw` keyword in JavaScript. This also means that if you "catch" an error via
   * a promise error callback and you want to forward the error to the promise derived from the
   * current promise, you have to "rethrow" the error by returning a rejection constructed via
   * `reject`.
   *
   *

   *   promiseB = promiseA.then(function(result) {
   *     // success: do something and resolve promiseB
   *     //          with the old or a new result
   *     return result;
   *   }, function(reason) {
   *     // error: handle the error if possible and
   *     //        resolve promiseB with newPromiseOrValue,
   *     //        otherwise forward the rejection to promiseB
   *     if (canHandle(reason)) {
   *      // handle the error and recover
   *      return newPromiseOrValue;
   *     }
   *     return $q.reject(reason);
   *   });
   *

   *
   * @param {*} reason Constant, message, exception or an object representing the rejection reason.
   * @returns {Promise} Returns a promise that was already resolved as rejected with the `reason`.
   */
  var reject = function(reason) {
    return {
      then: function(callback, errback) {
        var result = defer();
        nextTick(function() {
          result.resolve((errback || defaultErrback)(reason));
        });
        return result.promise;
      }
    };
  };

  /**
   * @ngdoc
   * @name ng.$q#when
   * @methodOf ng.$q
   * @description
   * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise.
   * This is useful when you are dealing with on object that might or might not be a promise, or if
   * the promise comes from a source that can't be trusted.
   *
   * @param {*} value Value or a promise
   * @returns {Promise} Returns a single promise that will be resolved with an array of values,
   *   each value coresponding to the promise at the same index in the `promises` array. If any of
   *   the promises is resolved with a rejection, this resulting promise will be resolved with the
   *   same rejection.
   */
  var when = function(value, callback, errback) {
    var result = defer(),
        done;

    var wrappedCallback = function(value) {
      try {
        return (callback || defaultCallback)(value);
      } catch (e) {
        exceptionHandler(e);
        return reject(e);
      }
    };

    var wrappedErrback = function(reason) {
      try {
        return (errback || defaultErrback)(reason);
      } catch (e) {
        exceptionHandler(e);
        return reject(e);
      }
    };

    nextTick(function() {
      ref(value).then(function(value) {
        if (done) return;
        done = true;
        result.resolve(ref(value).then(wrappedCallback, wrappedErrback));
      }, function(reason) {
        if (done) return;
        done = true;
        result.resolve(wrappedErrback(reason));
      });
    });

    return result.promise;
  };

  function defaultCallback(value) {
    return value;
  }

  function defaultErrback(reason) {
    return reject(reason);
  }

  /**
   * @ngdoc
   * @name ng.$q#all
   * @methodOf ng.$q
   * @description
   * Combines multiple promises into a single promise that is resolved when all of the input
   * promises are resolved.
   *
   * @param {Array.<Promise>} promises An array of promises.
   * @returns {Promise} Returns a single promise that will be resolved with an array of values,
   *   each value coresponding to the promise at the same index in the `promises` array. If any of
   *   the promises is resolved with a rejection, this resulting promise will be resolved with the
   *   same rejection.
   */
  function all(promises) {
    var deferred = defer(),
        counter = promises.length,
        results = [];

    if (counter) {
      forEach(promises, function(promise, index) {
        ref(promise).then(function(value) {
          if (index in results) return;
          results[index] = value;
          if (!(--counter)) deferred.resolve(results);
        }, function(reason) {
          if (index in results) return;
          deferred.reject(reason);
        });
      });
    } else {
      deferred.resolve(results);
    }

    return deferred.promise;
  }

  return {
    defer: defer,
    reject: reject,
    when: when,
    all: all
  };
}
<|endoftext|>


<commit_before>var assert = require('assert');
var resourceFork = require('resourceforkjs').resourceFork;

var shan = require('../parsers/shan.js');

describe("shan", function() {
    var rf;
    var miner;
    var thunderforge;
    var shuttle;
    before(async function() {
	rf = new resourceFork("./test/files/shan.ndat", false);

	await rf.read().then(function() {
	    var shans = rf.resources.shän;
	    shuttle = new shan(shans[128]);
	    thunderforge = new shan(shans[380]);
	    miner = new shan(shans[379]);
	}.bind(this));
    });

    it("should parse baseImage ID", function() {
	assert.equal(shuttle.baseImage.ID, 1000);
	assert.equal(thunderforge.baseImage.ID, 1130);
	assert.equal(miner.baseImage.ID, 1128);
    });

    it("should parse baseImage maskID", function() {
	assert.equal(shuttle.baseImage.maskID, 1001);
	assert.equal(thunderforge.baseImage.maskID, 1131);
	assert.equal(miner.baseImage.maskID, 1129);
    });

    it("should parse baseImage setCount", function() {
	// number of sets of images (rotations / animations)
	assert.equal(shuttle.baseImage.setCount, 3);
	assert.equal(thunderforge.baseImage.setCount, 1);
	assert.equal(miner.baseImage.setCount, 6);
    });

    it("should parse baseImage size", function() {
	assert.equal(shuttle.baseImage.size[0], 24);
	assert.equal(shuttle.baseImage.size[1], 24);
	assert.equal(thunderforge.baseImage.size[0], 130);
	assert.equal(thunderforge.baseImage.size[1], 130);
	assert.equal(miner.baseImage.size[0], 80);
	assert.equal(miner.baseImage.size[1], 80);
    });

    it("should parse baseImage.transparency", function() {
	assert.equal(shuttle.baseImage.transparency, 0);
	assert.equal(thunderforge.baseImage.transparency, 0);
	assert.equal(miner.baseImage.transparency, 0);
    });

    it("should parse altImage ID", function() {
	assert.equal(shuttle.altImage.ID, -1);
	assert.equal(thunderforge.altImage.ID, 1330);
	assert.equal(miner.altImage.ID, -1);
    });

    it("should parse altImage maskID", function() {
	assert.equal(shuttle.altImage.maskID, -1);
	assert.equal(thunderforge.altImage.maskID, 1331);
	assert.equal(miner.altImage.maskID, -1);
    });

    it("should parse altImage setCount", function() {
	assert.equal(shuttle.altImage.setCount, 0);
	assert.equal(thunderforge.altImage.setCount, 6);
	assert.equal(miner.altImage.setCount, 0);
    });

    it("should parse altImage size", function() {
	assert.equal(shuttle.altImage.size[0], 0);
	assert.equal(shuttle.altImage.size[1], 0);
	assert.equal(thunderforge.altImage.size[0], 260);
	assert.equal(thunderforge.altImage.size[1], 260);
	assert.equal(miner.altImage.size[0], 0);
	assert.equal(miner.altImage.size[1], 0);
    });

    it("should parse glowImage ID", function() {
	assert.equal(shuttle.glowImage.ID, 1400);
	assert.equal(thunderforge.glowImage.ID, 1530);
	assert.equal(miner.glowImage.ID, 1528);
    });

    it("should parse glowImage maskID", function() {
	assert.equal(shuttle.glowImage.maskID, 1401);
	assert.equal(thunderforge.glowImage.maskID, 1531);
	assert.equal(miner.glowImage.maskID, 1529);
    });
/*
    it("should parse glowImage setCount", function() {
	// set this to baseImage setCount (or 0 if no glow image)
	assert.equal(shuttle.glowImage.setCount, 3);
	assert.equal(thunderforge.glowImage.setCount, 1);
	assert.equal(miner.glowImage.setCount, 6);
    });
*/
    it("should parse glowImage size", function() {
	assert.equal(shuttle.glowImage.size[0], 48);
	assert.equal(shuttle.glowImage.size[1], 48);
	assert.equal(thunderforge.glowImage.size[0], 260);
	assert.equal(thunderforge.glowImage.size[1], 260);
	assert.equal(miner.glowImage.size[0], 80);
	assert.equal(miner.glowImage.size[1], 80);
    });

    it("should parse lightImage ID", function() {
	assert.equal(shuttle.lightImage.ID, 1600);
	assert.equal(thunderforge.lightImage.ID, -1);
	assert.equal(miner.lightImage.ID, 1728);
    });

    it("should parse lightImage maskID", function() {
	assert.equal(shuttle.lightImage.maskID, 1601);
	assert.equal(thunderforge.lightImage.maskID, -1);
	assert.equal(miner.lightImage.maskID, 1729);
    });
/*
    it("should parse lightImage setCount", function() {
	// set this to baseImage setCount (or 0 if no light image)
	assert.equal(shuttle.lightImage.setCount, 3);
	assert.equal(thunderforge.lightImage.setCount, 0);
	assert.equal(miner.lightImage.setCount, 6);
    });
*/
    it("should parse lightImage size", function() {
	assert.equal(shuttle.lightImage.size[0], 48);
	assert.equal(shuttle.lightImage.size[1], 48);
	assert.equal(thunderforge.lightImage.size[0], 0);
	assert.equal(thunderforge.lightImage.size[1], 0);
	assert.equal(miner.lightImage.size[0], 80);
	assert.equal(miner.lightImage.size[1], 80);
    });

    it("should parse weapImage ID", function() {
	assert.equal(shuttle.weapImage.ID, -1);
	assert.equal(thunderforge.weapImage.ID, 1930);
	assert.equal(miner.weapImage.ID, -1);
    });

    it("should parse weapImage maskID", function() {
	assert.equal(shuttle.weapImage.maskID, -1);
	assert.equal(thunderforge.weapImage.maskID, 1931);
	assert.equal(miner.weapImage.maskID, -1);
    });
/*
    it("should parse weapImage setCount", function() {
	// set this to baseImage setCount (or 0 if no weap image)
	assert.equal(shuttle.weapImage.setCount, 0);
	assert.equal(thunderforge.weapImage.setCount, 1);
	assert.equal(miner.weapImage.setCount, 0);
    });
*/
    it("should parse weapImage size", function() {
	assert.equal(shuttle.weapImage.size[0], 0);
	assert.equal(shuttle.weapImage.size[1], 0);
	assert.equal(thunderforge.weapImage.size[0], 260);
	assert.equal(thunderforge.weapImage.size[1], 260);
	assert.equal(miner.weapImage.size[0], 0);
	assert.equal(miner.weapImage.size[1], 0);
    });

    it("should parse flags", function() {
	assert.equal(shuttle.flags.extraFramePurpose, "banking");
	assert.equal(shuttle.flags.stopAnimationWhenDisabled, false);
	assert.equal(shuttle.flags.hideAltSpritesWhenDisabled, false);
	assert.equal(shuttle.flags.hideLightsWhenDisabled, true);
	assert.equal(shuttle.flags.unfoldWhenFiring, false);
	assert.equal(shuttle.flags.adjustForOffset, false);

	assert.equal(thunderforge.flags.extraFramePurpose, "animation");
	assert.equal(thunderforge.flags.stopAnimationWhenDisabled, true);
	assert.equal(thunderforge.flags.hideAltSpritesWhenDisabled, false);
	assert.equal(thunderforge.flags.hideLightsWhenDisabled, true);
	assert.equal(thunderforge.flags.unfoldWhenFiring, false);
	assert.equal(thunderforge.flags.adjustForOffset, false);

	assert.equal(miner.flags.extraFramePurpose, "folding");
	assert.equal(miner.flags.stopAnimationWhenDisabled, false);
	assert.equal(miner.flags.hideAltSpritesWhenDisabled, false);
	assert.equal(miner.flags.hideLightsWhenDisabled, true);
	assert.equal(miner.flags.unfoldWhenFiring, true);
	assert.equal(miner.flags.adjustForOffset, false);
    });

    it("should parse animDelay", function() {
	// frames per animation frame (assuming 30 fps)
	assert.equal(shuttle.animDelay, 0);
	assert.equal(thunderforge.animDelay, 5);
	assert.equal(miner.animDelay, 5);
    });

    it("should parse weapDecay", function() {
	// rate at which weapon glow goes away
	assert.equal(shuttle.weapDecay, 0);
	assert.equal(thunderforge.weapDecay, 50);
	assert.equal(miner.weapDecay, 0);
    });

    it("should parse framesPer", function() {
	assert.equal(shuttle.framesPer, 36);
	assert.equal(thunderforge.framesPer, 64);
	assert.equal(miner.framesPer, 36);
    });
/*
    it("should parse exitPoints", function() {
	assert.equal(shuttle.exitPoints, 0);
	assert.equal(thunderforge.exitPoints, 5);
	assert.equal(miner.exitPoints, 5);
    });
*/

});
<commit_msg>blinking tests<commit_after>var assert = require('assert');
var resourceFork = require('resourceforkjs').resourceFork;

var shan = require('../parsers/shan.js');

describe("shan", function() {
    var rf;
    var miner;
    var thunderforge;
    var shuttle;
    before(async function() {
	rf = new resourceFork("./test/files/shan.ndat", false);

	await rf.read().then(function() {
	    var shans = rf.resources.shän;
	    shuttle = new shan(shans[128]);
	    thunderforge = new shan(shans[380]);
	    miner = new shan(shans[379]);
	}.bind(this));
    });

    it("should parse baseImage ID", function() {
	assert.equal(shuttle.baseImage.ID, 1000);
	assert.equal(thunderforge.baseImage.ID, 1130);
	assert.equal(miner.baseImage.ID, 1128);
    });

    it("should parse baseImage maskID", function() {
	assert.equal(shuttle.baseImage.maskID, 1001);
	assert.equal(thunderforge.baseImage.maskID, 1131);
	assert.equal(miner.baseImage.maskID, 1129);
    });

    it("should parse baseImage setCount", function() {
	// number of sets of images (rotations / animations)
	assert.equal(shuttle.baseImage.setCount, 3);
	assert.equal(thunderforge.baseImage.setCount, 1);
	assert.equal(miner.baseImage.setCount, 6);
    });

    it("should parse baseImage size", function() {
	assert.equal(shuttle.baseImage.size[0], 24);
	assert.equal(shuttle.baseImage.size[1], 24);
	assert.equal(thunderforge.baseImage.size[0], 130);
	assert.equal(thunderforge.baseImage.size[1], 130);
	assert.equal(miner.baseImage.size[0], 80);
	assert.equal(miner.baseImage.size[1], 80);
    });

    it("should parse baseImage.transparency", function() {
	assert.equal(shuttle.baseImage.transparency, 0);
	assert.equal(thunderforge.baseImage.transparency, 0);
	assert.equal(miner.baseImage.transparency, 0);
    });

    it("should parse altImage ID", function() {
	assert.equal(shuttle.altImage.ID, -1);
	assert.equal(thunderforge.altImage.ID, 1330);
	assert.equal(miner.altImage.ID, -1);
    });

    it("should parse altImage maskID", function() {
	assert.equal(shuttle.altImage.maskID, -1);
	assert.equal(thunderforge.altImage.maskID, 1331);
	assert.equal(miner.altImage.maskID, -1);
    });

    it("should parse altImage setCount", function() {
	assert.equal(shuttle.altImage.setCount, 0);
	assert.equal(thunderforge.altImage.setCount, 6);
	assert.equal(miner.altImage.setCount, 0);
    });

    it("should parse altImage size", function() {
	assert.equal(shuttle.altImage.size[0], 0);
	assert.equal(shuttle.altImage.size[1], 0);
	assert.equal(thunderforge.altImage.size[0], 260);
	assert.equal(thunderforge.altImage.size[1], 260);
	assert.equal(miner.altImage.size[0], 0);
	assert.equal(miner.altImage.size[1], 0);
    });

    it("should parse glowImage ID", function() {
	assert.equal(shuttle.glowImage.ID, 1400);
	assert.equal(thunderforge.glowImage.ID, 1530);
	assert.equal(miner.glowImage.ID, 1528);
    });

    it("should parse glowImage maskID", function() {
	assert.equal(shuttle.glowImage.maskID, 1401);
	assert.equal(thunderforge.glowImage.maskID, 1531);
	assert.equal(miner.glowImage.maskID, 1529);
    });
/*
    it("should parse glowImage setCount", function() {
	// set this to baseImage setCount (or 0 if no glow image)
	assert.equal(shuttle.glowImage.setCount, 3);
	assert.equal(thunderforge.glowImage.setCount, 1);
	assert.equal(miner.glowImage.setCount, 6);
    });
*/
    it("should parse glowImage size", function() {
	assert.equal(shuttle.glowImage.size[0], 48);
	assert.equal(shuttle.glowImage.size[1], 48);
	assert.equal(thunderforge.glowImage.size[0], 260);
	assert.equal(thunderforge.glowImage.size[1], 260);
	assert.equal(miner.glowImage.size[0], 80);
	assert.equal(miner.glowImage.size[1], 80);
    });

    it("should parse lightImage ID", function() {
	assert.equal(shuttle.lightImage.ID, 1600);
	assert.equal(thunderforge.lightImage.ID, -1);
	assert.equal(miner.lightImage.ID, 1728);
    });

    it("should parse lightImage maskID", function() {
	assert.equal(shuttle.lightImage.maskID, 1601);
	assert.equal(thunderforge.lightImage.maskID, -1);
	assert.equal(miner.lightImage.maskID, 1729);
    });
/*
    it("should parse lightImage setCount", function() {
	// set this to baseImage setCount (or 0 if no light image)
	assert.equal(shuttle.lightImage.setCount, 3);
	assert.equal(thunderforge.lightImage.setCount, 0);
	assert.equal(miner.lightImage.setCount, 6);
    });
*/
    it("should parse lightImage size", function() {
	assert.equal(shuttle.lightImage.size[0], 48);
	assert.equal(shuttle.lightImage.size[1], 48);
	assert.equal(thunderforge.lightImage.size[0], 0);
	assert.equal(thunderforge.lightImage.size[1], 0);
	assert.equal(miner.lightImage.size[0], 80);
	assert.equal(miner.lightImage.size[1], 80);
    });

    it("should parse weapImage ID", function() {
	assert.equal(shuttle.weapImage.ID, -1);
	assert.equal(thunderforge.weapImage.ID, 1930);
	assert.equal(miner.weapImage.ID, -1);
    });

    it("should parse weapImage maskID", function() {
	assert.equal(shuttle.weapImage.maskID, -1);
	assert.equal(thunderforge.weapImage.maskID, 1931);
	assert.equal(miner.weapImage.maskID, -1);
    });
/*
    it("should parse weapImage setCount", function() {
	// set this to baseImage setCount (or 0 if no weap image)
	assert.equal(shuttle.weapImage.setCount, 0);
	assert.equal(thunderforge.weapImage.setCount, 1);
	assert.equal(miner.weapImage.setCount, 0);
    });
*/
    it("should parse weapImage size", function() {
	assert.equal(shuttle.weapImage.size[0], 0);
	assert.equal(shuttle.weapImage.size[1], 0);
	assert.equal(thunderforge.weapImage.size[0], 260);
	assert.equal(thunderforge.weapImage.size[1], 260);
	assert.equal(miner.weapImage.size[0], 0);
	assert.equal(miner.weapImage.size[1], 0);
    });

    it("should parse flags", function() {
	assert.equal(shuttle.flags.extraFramePurpose, "banking");
	assert.equal(shuttle.flags.stopAnimationWhenDisabled, false);
	assert.equal(shuttle.flags.hideAltSpritesWhenDisabled, false);
	assert.equal(shuttle.flags.hideLightsWhenDisabled, true);
	assert.equal(shuttle.flags.unfoldWhenFiring, false);
	assert.equal(shuttle.flags.adjustForOffset, false);

	assert.equal(thunderforge.flags.extraFramePurpose, "animation");
	assert.equal(thunderforge.flags.stopAnimationWhenDisabled, true);
	assert.equal(thunderforge.flags.hideAltSpritesWhenDisabled, false);
	assert.equal(thunderforge.flags.hideLightsWhenDisabled, true);
	assert.equal(thunderforge.flags.unfoldWhenFiring, false);
	assert.equal(thunderforge.flags.adjustForOffset, false);

	assert.equal(miner.flags.extraFramePurpose, "folding");
	assert.equal(miner.flags.stopAnimationWhenDisabled, false);
	assert.equal(miner.flags.hideAltSpritesWhenDisabled, false);
	assert.equal(miner.flags.hideLightsWhenDisabled, true);
	assert.equal(miner.flags.unfoldWhenFiring, true);
	assert.equal(miner.flags.adjustForOffset, false);
    });

    it("should parse animDelay", function() {
	// frames per animation frame (assuming 30 fps)
	assert.equal(shuttle.animDelay, 0);
	assert.equal(thunderforge.animDelay, 5);
	assert.equal(miner.animDelay, 5);
    });

    it("should parse weapDecay", function() {
	// rate at which weapon glow goes away
	assert.equal(shuttle.weapDecay, 0);
	assert.equal(thunderforge.weapDecay, 50);
	assert.equal(miner.weapDecay, 0);
    });

    it("should parse framesPer", function() {
	assert.equal(shuttle.framesPer, 36);
	assert.equal(thunderforge.framesPer, 64);
	assert.equal(miner.framesPer, 36);
    });

    it("should parse blink mode", function() {
	assert.equal(shuttle.blink.mode, "square");
	assert.equal(thunderforge.blink, null);
	assert.equal(miner.blink.mode, "square");
    });

    it("should parse blink a", function() {
	assert.equal(shuttle.blink.a, 4);
	assert.equal(miner.blink.a, 4);
    });

    it("should parse blink b", function() {
	assert.equal(shuttle.blink.b, 1);
	assert.equal(miner.blink.b, 1);
    });

    it("should parse blink c", function() {
	assert.equal(shuttle.blink.c, 2);
	assert.equal(miner.blink.c, 2);
    });

    it("should parse blink d", function() {
	assert.equal(shuttle.blink.d, 20);
	assert.equal(miner.blink.d, 20);
    });

/*
    it("should parse exitPoints", function() {
	assert.equal(shuttle.exitPoints, 0);
	assert.equal(thunderforge.exitPoints, 5);
	assert.equal(miner.exitPoints, 5);
    });
*/

});
<|endoftext|>


<commit_before>var fs       = require('fs'),
    util     = require('util'),
    uuid     = require('node-uuid'),
    events   = require('events'),
    Data     = require('./data.js').Data;

var npcs_dir         = __dirname + '/../entities/npcs/';
var npcs_scripts_dir = __dirname + '/../scripts/npcs/';
var l10n_dir         = __dirname + '/../l10n/scripts/npcs/';

/**
 * Npc container class. Loads/finds npcs
 */
var Npcs = function () {
	var self = this;
	self.npcs = {};
	self.load_count = {};

	/**
	 * Load NPCs from the configs
	 * @param boolean verbose Whether to do verbose logging
	 * @param callback
	 */
	self.load = function (verbose, callback)
	{
		verbose = verbose || false;
		var log = function (message) { if (verbose) util.log(message); };
		var debug = function (message) { if (verbose) util.debug(message); };

		log("\tExamining npc directory - " + npcs_dir);
		var npcs = fs.readdir(npcs_dir, function (err, files)
		{
			// Load any npc files
			for (j in files) {
				var npc_file = npcs_dir + files[j];
				if (!fs.statSync(npc_file).isFile()) continue;
				if (!npc_file.match(/yml$/)) continue;

				// parse the npc files
				try {
					var npc_def = require('js-yaml').load(fs.readFileSync(npc_file).toString('utf8'));
				} catch (e) {
					log("\t\tError loading npc - " + npc_file + ' - ' + e.message);
					continue;
				}

				// create and load the npcs
				npc_def.forEach(function (npc) {
					var validate = ['keywords', 'short_description', 'vnum'];

					var err = false;
					for (var v in validate) {
						if (!(validate[v] in npc)) {
							log("\t\tError loading npc in file " + npc + ' - no ' + validate[v] + ' specified');
							err = true;
							return;
						}
					}

					// max load for npcs so we don't have 1000 npcs in a room due to respawn
					if (self.load_count[npc.vnum] && self.load_count[npc.vnum] >= npc.load_max) {
						log("\t\tMaxload of " + npc.load_max + " hit for npc " + npc.vnum);
						return;
					}

					npc = new Npc(npc);
					npc.setUuid(uuid.v4());
					log("\t\tLoaded npc [uuid:" + npc.getUuid() + ', vnum:' + npc.vnum + ']');
					self.add(npc);
				});
			}

			if (callback) {
				callback();
			}
		});
	};

	/**
	 * Add an npc and generate a uuid if necessary
	 * @param Npc npc
	 */
	self.add = function (npc)
	{
		if (!npc.getUuid()) {
			npc.setUuid(uuid.v4());
		}
		self.npcs[npc.getUuid()] = npc;
		self.load_count[npc.vnum] = self.load_count[npc.vnum] ? self.load_count[npc.vnum] + 1 : 1;
	};

	/**
	 * Gets all instance of an npc
	 * Not sure exactly what you'd use this method for as you would most likely
	 * rather act upon a single instance of an item
	 * @param int vnum
	 * @return Npc
	 */
	self.getByVnum = function (vnum)
	{
		var objs = [];
		self.each(function (o) {
			if (o.getVnum() === vnum) {
				objs.push(o);
			}
		});
		return objs;
	};

	/**
	 * retreive an instance of an npc by uuid
	 * @param string uid
	 * @return Npc
	 */
	self.get = function (uid)
	{
		return self.npcs[uid];
	};

	/**
	 * proxy Array.each
	 * @param function callback
	 */
	self.each = function (callback)
	{
		for (var obj in self.npcs) {
			callback(self.npcs[obj]);
		}
	};

	/**
	 * Blows away an NPC
	 * WARNING: If you haven't removed the npc from the room it's in shit _will_ break
	 * @param Npc npc
	 */
	self.destroy = function (npc)
	{
		delete self.npcs[npc.getUuid()];
		delete npc;
	};
}

/**
 * Actual class for NPCs
 */
var Npc = function (config)
{
	var self = this;

	self.keywords;
	self.short_description;
	self.attack;
	self.description;
	self.room; // Room that it's in (vnum)
	self.vnum; // Not to be confused with its vnum
	self.inCombat = false;
	self.uuid = null;

	// attributes
	self.attributes = {
		max_health : 0,
		health: 0,
		level: 1
	};

	// Anything affecting the NPC
	self.effects = {
	};

	/**
	 * constructor
	 * @param object config
	 */
	self.init = function (config)
	{
		self.short_description = config.short_description || '';
		self.keywords          = config.keywords    || [];
		self.attack            = config.attack      || {en: 'strike'};
		self.description       = config.description || '';
		self.room              = config.room        || null;
		self.vnum              = config.vnum;
		self.defenses          = {};

		for (var i in config.attributes || {}) {
			self.attributes[i] = config.attributes[i];
		}

		for (var i in config.defenses || {}) {
			self.defenses[i] = config.defenses[i];
		}

		Data.loadListeners(config, l10n_dir, npcs_scripts_dir, Data.loadBehaviors(config, 'npcs/', self));
	};

	/**#@+
	 * Mutators
	 */
	self.getVnum      = function () { return self.vnum; };
	self.getInv       = function () { return self.inventory; };
	self.isInCombat   = function () { return self.inCombat; };
	self.getRoom      = function () { return self.room; };
	self.getUuid      = function () { return self.uuid; };
	self.getAttribute = function (attr) { return typeof self.attributes[attr] !== 'undefined' ? self.attributes[attr] : false; };
	self.setUuid      = function (uid) { self.uuid = uid; };
	self.setRoom      = function (room) { self.room = room; };
	self.setInventory = function (identifier) { self.inventory = identifier; }
	self.setInCombat  = function (combat) { self.inCombat = combat; }
	self.setContainer = function (uid) { self.container = uid; }
	self.setAttribute = function (attr, val) { self.attributes[attr] = val; };
	self.removeEffect = function (aff) { delete self.effects[aff]; };
	self.getDefenses  = function () { return self.defenses; };
	self.getLocations = function () { return Object.keys(self.defenses); };
  self.isPacifist   = () => !self.listeners('combat').length;
	/**#@-*/

	/**
	 * Get currently applied effects
	 * @param string aff
	 * @return Array|Object
	 */
	self.getEffects = function (aff)
	{
		if (aff) {
			return typeof self.effects[aff] !== 'undefined' ? self.effects[aff] : false;
		}
		return self.effects;
	};

	/**
	 * Add, activate and set a timer for an affect
	 * @param string name
	 * @param object affect
	 */
	self.addEffect = function (name, effect)
	{
		if (effect.activate) {
			effect.activate();
		}

		setTimeout(function () {
			if (effect.deactivate) {
				effect.deactivate();
			}
			self.removeEffect(name);
		}, effect.duration * 1000);
		self.effects[name] = 1;
	};

	//TODO: dry-ify the following

	/**
	 * Get the description, localized if possible
	 * @param string locale
	 * @return string
	 */
	self.getDescription = function (locale)
	{
		return typeof self.description === 'string' ?
			self.description :
			(locale in self.description ? self.description[locale] : 'UNTRANSLATED - Contact an admin');
	};

	/**
	 * Get the attack, localized if possible
	 * @param string locale
	 * @return string
	 */
	self.getAttack = function (locale)
	{
		return typeof self.attack === 'string' ?
			self.attack :
			(locale in self.attack ? self.attack[locale] : 'UNTRANSLATED - Contact an admin');
	};

	/**
	 * Get the title, localized if possible
	 * @param string locale
	 * @return string
	 */
	self.getShortDesc = function (locale)
	{
		return typeof self.short_description === 'string' ?
			self.short_description :
			(locale in self.short_description ? self.short_description[locale] : 'UNTRANSLATED - Contact an admin');
	}

	/**
	 * Get the title, localized if possible
	 * @param string locale
	 * @return string
	 */
	self.getKeywords = function (locale)
	{
		return Array.isArray(self.keywords) ?
			self.keywords :
			(locale in self.keywords ? self.keywords[locale] : 'UNTRANSLATED - Contact an admin');
	}

	/**
	 * check to see if an npc has a specific keyword
	 * @param string keyword
	 * @param string locale
	 * @return boolean
	 */
	self.hasKeyword = function (keyword, locale)
	{
		return self.getKeywords(locale).some(function (word) { return keyword === word });
	};

	/**
	 * Get attack speed of an npc
	 * @return float
	 */
	self.getAttackSpeed = function ()
	{
		return self.getAttribute('speed') * 1000 || 1000;
	};

	/**
	 * Get the damage an npc can do
	 * @return obj {min: int, max: int}
	 */
	self.getDamage = function ()
	{
		var base = [1, 20];
		var damage = self.getAttribute('damage') ?
			self.getAttribute('damage').split('-').map(function (i) { return parseInt(i, 10); })
			: base;
		return {min: damage[0], max: damage[1]};
	};

	/**
	 * Get the damage to sanity an npc can do
	 * @return obj {min: int, max: int} || false
	 */
	self.getSanityDamage = function ()
	{
		var damage = self.getAttribute('sanity_damage') ?
			self.getAttribute('sanity_damage').split('-').map(function (i) { return parseInt(i, 10); })
			: false;
		return damage ? {min: damage[0], max: damage[1]} : false;
	};

	/**
	* Helper to get just one area's defense
	* @param string location
	*/
	self.getDefense = function(location){
		location = location || 'body';
		return self.defenses[location] || 0;
	};

	/**
   * Helper to calculate physical damage
   * @param int damage
   * @param string location
   */
  self.damage = function(dmg, location) {
    if (!dmg) return;
    location = location || 'body';
    damageDone = Math.max(1, dmg - calculateDefense(location));
    self.setAttribute('health', Math.max(0, self.getAttribute('health') - damageDone));
    util.log('Damage done to ' + self.getShortDesc('en') + ': ' + damageDone);

    return damageDone;
  };

  function calculateDefense(location) {
    var defense = self.getDefense(location);
    if (location !== 'body')
      defense += self.getDefense('body');
    util.log(self.getShortDesc('en') + ' ' + location + ' def: ' + defense);
    return defense;
  }

	self.init(config);
};
util.inherits(Npc, events.EventEmitter);

exports.Npcs = Npcs;
exports.Npc  = Npc;
<commit_msg>add strict mode, fix delete err :sunny:<commit_after>'use strict';
var fs       = require('fs'),
    util     = require('util'),
    uuid     = require('node-uuid'),
    events   = require('events'),
    Data     = require('./data.js').Data;

var npcs_dir         = __dirname + '/../entities/npcs/';
var npcs_scripts_dir = __dirname + '/../scripts/npcs/';
var l10n_dir         = __dirname + '/../l10n/scripts/npcs/';

/**
 * Npc container class. Loads/finds npcs
 */
var Npcs = function () {
	var self = this;
	self.npcs = {};
	self.load_count = {};

	/**
	 * Load NPCs from the configs
	 * @param boolean verbose Whether to do verbose logging
	 * @param callback
	 */
	self.load = function (verbose, callback)
	{
		verbose = verbose || false;
		var log = function (message) { if (verbose) util.log(message); };
		var debug = function (message) { if (verbose) util.debug(message); };

		log("\tExamining npc directory - " + npcs_dir);
		var npcs = fs.readdir(npcs_dir, function (err, files)
		{
			// Load any npc files
			for (j in files) {
				var npc_file = npcs_dir + files[j];
				if (!fs.statSync(npc_file).isFile()) continue;
				if (!npc_file.match(/yml$/)) continue;

				// parse the npc files
				try {
					var npc_def = require('js-yaml').load(fs.readFileSync(npc_file).toString('utf8'));
				} catch (e) {
					log("\t\tError loading npc - " + npc_file + ' - ' + e.message);
					continue;
				}

				// create and load the npcs
				npc_def.forEach(function (npc) {
					var validate = ['keywords', 'short_description', 'vnum'];

					var err = false;
					for (var v in validate) {
						if (!(validate[v] in npc)) {
							log("\t\tError loading npc in file " + npc + ' - no ' + validate[v] + ' specified');
							err = true;
							return;
						}
					}

					// max load for npcs so we don't have 1000 npcs in a room due to respawn
					if (self.load_count[npc.vnum] && self.load_count[npc.vnum] >= npc.load_max) {
						log("\t\tMaxload of " + npc.load_max + " hit for npc " + npc.vnum);
						return;
					}

					npc = new Npc(npc);
					npc.setUuid(uuid.v4());
					log("\t\tLoaded npc [uuid:" + npc.getUuid() + ', vnum:' + npc.vnum + ']');
					self.add(npc);
				});
			}

			if (callback) {
				callback();
			}
		});
	};

	/**
	 * Add an npc and generate a uuid if necessary
	 * @param Npc npc
	 */
	self.add = function (npc)
	{
		if (!npc.getUuid()) {
			npc.setUuid(uuid.v4());
		}
		self.npcs[npc.getUuid()] = npc;
		self.load_count[npc.vnum] = self.load_count[npc.vnum] ? self.load_count[npc.vnum] + 1 : 1;
	};

	/**
	 * Gets all instance of an npc
	 * Not sure exactly what you'd use this method for as you would most likely
	 * rather act upon a single instance of an item
	 * @param int vnum
	 * @return Npc
	 */
	self.getByVnum = function (vnum)
	{
		var objs = [];
		self.each(function (o) {
			if (o.getVnum() === vnum) {
				objs.push(o);
			}
		});
		return objs;
	};

	/**
	 * retreive an instance of an npc by uuid
	 * @param string uid
	 * @return Npc
	 */
	self.get = function (uid)
	{
		return self.npcs[uid];
	};

	/**
	 * proxy Array.each
	 * @param function callback
	 */
	self.each = function (callback)
	{
		for (var obj in self.npcs) {
			callback(self.npcs[obj]);
		}
	};

	/**
	 * Blows away an NPC
	 * WARNING: If you haven't removed the npc from the room it's in shit _will_ break
	 * @param Npc npc
	 */
	self.destroy = function (npc)
	{
		delete self.npcs[npc.getUuid()];
	};
}

/**
 * Actual class for NPCs
 */
var Npc = function (config)
{
	var self = this;

	self.keywords;
	self.short_description;
	self.attack;
	self.description;
	self.room; // Room that it's in (vnum)
	self.vnum; // Not to be confused with its vnum
	self.inCombat = false;
	self.uuid = null;

	// attributes
	self.attributes = {
		max_health : 0,
		health: 0,
		level: 1
	};

	// Anything affecting the NPC
	self.effects = {
	};

	/**
	 * constructor
	 * @param object config
	 */
	self.init = function (config)
	{
		self.short_description = config.short_description || '';
		self.keywords          = config.keywords    || [];
		self.attack            = config.attack      || {en: 'strike'};
		self.description       = config.description || '';
		self.room              = config.room        || null;
		self.vnum              = config.vnum;
		self.defenses          = {};

		for (var i in config.attributes || {}) {
			self.attributes[i] = config.attributes[i];
		}

		for (var i in config.defenses || {}) {
			self.defenses[i] = config.defenses[i];
		}

		Data.loadListeners(config, l10n_dir, npcs_scripts_dir, Data.loadBehaviors(config, 'npcs/', self));
	};

	/**#@+
	 * Mutators
	 */
	self.getVnum      = function () { return self.vnum; };
	self.getInv       = function () { return self.inventory; };
	self.isInCombat   = function () { return self.inCombat; };
	self.getRoom      = function () { return self.room; };
	self.getUuid      = function () { return self.uuid; };
	self.getAttribute = function (attr) { return typeof self.attributes[attr] !== 'undefined' ? self.attributes[attr] : false; };
	self.setUuid      = function (uid) { self.uuid = uid; };
	self.setRoom      = function (room) { self.room = room; };
	self.setInventory = function (identifier) { self.inventory = identifier; }
	self.setInCombat  = function (combat) { self.inCombat = combat; }
	self.setContainer = function (uid) { self.container = uid; }
	self.setAttribute = function (attr, val) { self.attributes[attr] = val; };
	self.removeEffect = function (aff) { delete self.effects[aff]; };
	self.getDefenses  = function () { return self.defenses; };
	self.getLocations = function () { return Object.keys(self.defenses); };
  self.isPacifist   = () => !self.listeners('combat').length;
	/**#@-*/

	/**
	 * Get currently applied effects
	 * @param string aff
	 * @return Array|Object
	 */
	self.getEffects = function (aff)
	{
		if (aff) {
			return typeof self.effects[aff] !== 'undefined' ? self.effects[aff] : false;
		}
		return self.effects;
	};

	/**
	 * Add, activate and set a timer for an affect
	 * @param string name
	 * @param object affect
	 */
	self.addEffect = function (name, effect)
	{
		if (effect.activate) {
			effect.activate();
		}

		setTimeout(function () {
			if (effect.deactivate) {
				effect.deactivate();
			}
			self.removeEffect(name);
		}, effect.duration * 1000);
		self.effects[name] = 1;
	};

	//TODO: dry-ify the following

	/**
	 * Get the description, localized if possible
	 * @param string locale
	 * @return string
	 */
	self.getDescription = function (locale)
	{
		return typeof self.description === 'string' ?
			self.description :
			(locale in self.description ? self.description[locale] : 'UNTRANSLATED - Contact an admin');
	};

	/**
	 * Get the attack, localized if possible
	 * @param string locale
	 * @return string
	 */
	self.getAttack = function (locale)
	{
		return typeof self.attack === 'string' ?
			self.attack :
			(locale in self.attack ? self.attack[locale] : 'UNTRANSLATED - Contact an admin');
	};

	/**
	 * Get the title, localized if possible
	 * @param string locale
	 * @return string
	 */
	self.getShortDesc = function (locale)
	{
		return typeof self.short_description === 'string' ?
			self.short_description :
			(locale in self.short_description ? self.short_description[locale] : 'UNTRANSLATED - Contact an admin');
	}

	/**
	 * Get the title, localized if possible
	 * @param string locale
	 * @return string
	 */
	self.getKeywords = function (locale)
	{
		return Array.isArray(self.keywords) ?
			self.keywords :
			(locale in self.keywords ? self.keywords[locale] : 'UNTRANSLATED - Contact an admin');
	}

	/**
	 * check to see if an npc has a specific keyword
	 * @param string keyword
	 * @param string locale
	 * @return boolean
	 */
	self.hasKeyword = function (keyword, locale)
	{
		return self.getKeywords(locale).some(function (word) { return keyword === word });
	};

	/**
	 * Get attack speed of an npc
	 * @return float
	 */
	self.getAttackSpeed = function ()
	{
		return self.getAttribute('speed') * 1000 || 1000;
	};

	/**
	 * Get the damage an npc can do
	 * @return obj {min: int, max: int}
	 */
	self.getDamage = function ()
	{
		var base = [1, 20];
		var damage = self.getAttribute('damage') ?
			self.getAttribute('damage').split('-').map(function (i) { return parseInt(i, 10); })
			: base;
		return {min: damage[0], max: damage[1]};
	};

	/**
	 * Get the damage to sanity an npc can do
	 * @return obj {min: int, max: int} || false
	 */
	self.getSanityDamage = function ()
	{
		var damage = self.getAttribute('sanity_damage') ?
			self.getAttribute('sanity_damage').split('-').map(function (i) { return parseInt(i, 10); })
			: false;
		return damage ? {min: damage[0], max: damage[1]} : false;
	};

	/**
	* Helper to get just one area's defense
	* @param string location
	*/
	self.getDefense = function(location){
		location = location || 'body';
		return self.defenses[location] || 0;
	};

	/**
   * Helper to calculate physical damage
   * @param int damage
   * @param string location
   */
  self.damage = function(dmg, location) {
    if (!dmg) return;
    location = location || 'body';
    damageDone = Math.max(1, dmg - calculateDefense(location));
    self.setAttribute('health', Math.max(0, self.getAttribute('health') - damageDone));
    util.log('Damage done to ' + self.getShortDesc('en') + ': ' + damageDone);

    return damageDone;
  };

  function calculateDefense(location) {
    var defense = self.getDefense(location);
    if (location !== 'body')
      defense += self.getDefense('body');
    util.log(self.getShortDesc('en') + ' ' + location + ' def: ' + defense);
    return defense;
  }

	self.init(config);
};
util.inherits(Npc, events.EventEmitter);

exports.Npcs = Npcs;
exports.Npc  = Npc;
<|endoftext|>


<commit_before>exports.run = async (client, message, [type]) => {
    const sqlite3 = require("sqlite3").verbose();
    let db = new sqlite3.Database("./bwd/data/score.sqlite");

    const types = {
        credits: "Credits",
        rep: "Rep"
    }

    const Leaders = [];

    const embed = new client.methods.Embed()
        .setTimestamp()
        .setAuthor("Global Leaderboards", message.guild.iconURL())
        .setColor("#4d5fd");

    db.all(`SELECT * FROM scores ORDER BY ${types[type.toLowerCase()]} DESC LIMIT 10`, [], (err, rows) => {
        if (err) { return console.log(err); }
        var x = 1;
        if (type.toLowerCase() === "credits") {
            rows.forEach((row) => {
                var user = client.funcs.userSearch(client, message, row.userID);
                Leaders.push(`${x}) ${user.tag} - ${types[type.toLowerCase()]}: ${row.credits.toLocaleString()}\n`);
                x++;
            });
        } if (type.toLowerCase() === "rep") {
            rows.forEach((row) => {
                var user = client.funcs.userSearch(client, message, row.userID);
                Leaders.push(`${x}) ${user.tag} - ${types[type.toLowerCase()]}: ${row.rep.toLocaleString()}\n`);
                x++;
            });
        }
        embed.setDescription(Leaders);
        message.channel.send({embed});
    });

    db.close();
};

exports.conf = {
    enabled: true,
    runIn: ["text"],
    aliases: ["glb"],
    permLevel: 0,
    botPerms: [],
    requiredFuncs: [],
};

exports.help = {
    name: "gleaderboard",
    description: "Check the global leaderboards!",
    usage: "<credits|rep>",
    usageDelim: "",
};
<commit_msg>Update gleaderboard.js<commit_after>exports.run = async (client, message, [type]) => {
    const sqlite3 = require("sqlite3").verbose();
    let db = new sqlite3.Database("./bwd/data/score.sqlite");

    const types = {
        credits: "Credits",
        rep: "Rep"
    };

    const Leaders = [];

    const embed = new client.methods.Embed()
        .setTimestamp()
        .setAuthor("Global Leaderboards", message.guild.iconURL())
        .setColor("#4d5fd");

    db.all(`SELECT * FROM scores ORDER BY ${types[type.toLowerCase()]} DESC LIMIT 10`, [], (err, rows) => {
        if (err) { return console.log(err); }
        var x = 1;
        rows.forEach((row) => {
            var user = client.funcs.userSearch(client, message, row.userID);
            if (type.toLowerCase() === "credits") {
                Leaders.push(`${x}) ${user.tag} - ${types[type.toLowerCase()]}: ${row.credits.toLocaleString()}\n`);
            } if (type.toLowerCase() === "rep") {
                Leaders.push(`${x}) ${user.tag} - ${types[type.toLowerCase()]}: ${row.rep.toLocaleString()}\n`);
            }
            x++;
        });
        embed.setDescription(Leaders);
        message.channel.send({embed});
    });
    db.close();
};

exports.conf = {
    enabled: true,
    runIn: ["text"],
    aliases: ["glb"],
    permLevel: 0,
    botPerms: [],
    requiredFuncs: [],
};

exports.help = {
    name: "gleaderboard",
    description: "Check the global leaderboards!",
    usage: "<credits|rep>",
    usageDelim: "",
};
<|endoftext|>


<commit_before>const { Command } = require('discord.js-commando');

const Currency = require('../../Currency');

const currency = new Currency();

module.exports = class MoneyTradeCommand extends Command {
	constructor(client) {
		super(client, {
			name: 'trade-money',
			aliases: ['trade-donut', 'trade-donuts', 'money-trade', 'donut-trade', 'donuts-trade'],
			group: 'currency',
			memberName: 'trade',
			description: 'Trades the money you have earned.',
			details: 'Trades the amount of money you have earned.',

			args: [
				{
					key: 'member',
					prompt: 'What user would you like to give donuts?',
					type: 'member'
				},
				{
					key: 'donuts',
					prompt: 'How many donuts do you want to give that user?',
					type: 'integer'
				}
			]
		});
	}

	async run(msg, args) {
		const user = args.member;
		const donuts = args.donuts;

		if (user.id === msg.author.id) return msg.reply('you can\'t trade donuts with yourself, ya dingus.');
		if (donuts <= 0) return msg.reply('man, get outta here!');

		if (user.bot) return msg.reply('don\'t give your donuts to bots, they don\'t like them. :(');

		const userBalance = await currency.getBalance(msg.author.id);

		if (userBalance < donuts) {
			return msg.reply(`you don't have that many donuts to trade! Your current account balance is ${userBalance} 🍩s.`);
		}

		currency.removeBalance(msg.author.id, donuts);
		currency.addBalance(user.id, donuts);

		return msg.reply(`${user.displayName} successfully received your ${donuts} 🍩s!`);
	}
};
<commit_msg>Remvoe comma<commit_after>const { Command } = require('discord.js-commando');

const Currency = require('../../Currency');

const currency = new Currency();

module.exports = class MoneyTradeCommand extends Command {
	constructor(client) {
		super(client, {
			name: 'trade-money',
			aliases: ['trade-donut', 'trade-donuts', 'money-trade', 'donut-trade', 'donuts-trade'],
			group: 'currency',
			memberName: 'trade',
			description: 'Trades the money you have earned.',
			details: 'Trades the amount of money you have earned.',

			args: [
				{
					key: 'member',
					prompt: 'What user would you like to give donuts?',
					type: 'member'
				},
				{
					key: 'donuts',
					prompt: 'How many donuts do you want to give that user?',
					type: 'integer'
				}
			]
		});
	}

	async run(msg, args) {
		const user = args.member;
		const donuts = args.donuts;

		if (user.id === msg.author.id) return msg.reply('you can\'t trade donuts with yourself, ya dingus.');
		if (user.bot) return msg.reply('don\'t give your donuts to bots, they don\'t like them. :(');
		if (donuts <= 0) return msg.reply('man get outta here!');

		const userBalance = await currency.getBalance(msg.author.id);

		if (userBalance < donuts) {
			return msg.reply(`you don't have that many donuts to trade! Your current account balance is ${userBalance} 🍩s.`);
		}

		currency.removeBalance(msg.author.id, donuts);
		currency.addBalance(user.id, donuts);

		return msg.reply(`${user.displayName} successfully received your ${donuts} 🍩s!`);
	}
};
<|endoftext|>


<commit_before>'use strict';
import {Promise} from 'es6-promise';
import {rakeVerify} from './rubyVerifier'
import logger from './logger';
import _ from 'lodash'
import Mocha from 'mocha'
import fs from 'fs'
import path from 'path'
import pact_dsl from './pact_dsl'

export function runPact(test) {
  let mocha = new Mocha(
  {
    ui: 'pact_dsl'
  })

  mocha.addFile(test)

  mocha.run(function(failures) {
    process.on('exit', function () {
      process.exit(failures);
    });
  })
}

export default class Pact {
  constructor(provider, consumer, options) {
    this.provider = provider
    this.consumer = consumer;
    this.options = options
  }

  providerState(stateName) {
    logger.debug('Running provider state ' + stateName);
    logger.debug('Test', this.consumer);
    return rakeVerify(this.consumer, stateName, this.options)
  }
}
<commit_msg>Added multiple pact support<commit_after>'use strict';
import {Promise} from 'es6-promise';
import {rakeVerify} from './rubyVerifier'
import logger from './logger';
import _ from 'lodash'
import Mocha from 'mocha'
import fs from 'fs'
import path from 'path'
import pact_dsl from './pact_dsl'

function onFailure(failures) {
  process.on('exit', () =>  {
    process.exit(failures);
  })
}

export function runPact(...tests) {
  let mocha = new Mocha({
    ui: 'pact_dsl'
  })

 _(tests).forEach( (test) => {
   mocha.addFile(test)
 })
 mocha.run(onFailure)
}

export default class Pact {
  constructor(provider, consumer, options) {
    this.provider = provider
    this.consumer = consumer;
    this.options = options
  }

  providerState(stateName) {
    logger.debug('Running provider state ' + stateName);
    logger.debug('Test', this.consumer);
    return rakeVerify(this.consumer, stateName, this.options)
  }
}
<|endoftext|>


<commit_before>/**
 * Created by kgrube on 1/5/2016.
 */

/**
 * @private
 */
var Q = require('q'),
    request = require('request'),
    _ = require('lodash'),
    xml2js = require('xml2js').parseString;

/**
 * @typedef {object} Sensor
 * @property {string} name
 * @property {string} sensortype
 * @property {string} interval
 * @property {string} probename
 * @property {string} probegroupname
 * @property {string} parentdevicename
 * @property {string} parentdeviceid
 * @property {string} lastvalue
 * @property {string} lastmessage
 * @property {string} favorite
 * @property {string} statustext
 * @property {string} statusid
 * @property {string} lastup
 * @property {string} lastdown
 * @property {string} lastcheck
 * @property {string} uptime
 * @property {string} uptimetime
 * @property {string} downtime
 * @property {string} downtimetime
 * @property {string} updowntotal
 * @property {string} updownsince
 */

/**
 * @typedef {object} SensorColumns
 * @property {number} objid
 * @property {string} type
 * @property {string} name
 * @property tags
 * @property active
 * @property downtime
 * @property downtimetime
 * @property downtimesince
 * @property uptime
 * @property uptimetime
 * @property uptimesince
 * @property knowntime
 * @property cumsince
 * @property sensor
 * @property interval
 * @property lastcheck
 * @property lastup
 * @property lastdown
 * @property device
 * @property group
 * @property probe
 * @property grpdev
 * @property notifiesx
 * @property intervalx
 * @property access
 * @property dependency
 * @property probegroupdevice
 * @property status
 * @property message
 * @property priority
 * @property lastvalue
 * @property upsens
 * @property downsens
 * @property partialdownsens
 * @property warnsens
 * @property pausedsens
 * @property unusualsens
 * @property undefinedsens
 * @property totalsens
 * @property favorite
 * @property minigraph
 * @property comments
 * @property basetype ??
 * @property baselink ??
 * @property parentid ??
 *
 */

/**
 *
 * @param options
 * @param options.username
 * @param options.passhash
 * @param options.url Base URL of your PRTG installation, e.g. the API is accessible at <url>/API/
 * @constructor
 */
function PRTG(options) {
    if (!options) {
        throw "options must be defined.";
    }

    if (!options.username) {
        throw "options.username must be defined.";
    }

    if (!options.passhash) {
        throw "options.passhash must be defined.";
    }

    if (!options.url) {
        throw "options.url must be defined.";
    }

    this.auth = '&username=' + options.username + '&passhash=' + options.passhash;
    this.url = options.url;

    this.DEFAULTS = {};

    //PRTG uses different notations for these IDs all over the place
    this.DEFAULTS.status = {};
    this.DEFAULTS.status[1] = "Unknown";
    this.DEFAULTS.status[2] = "Scanning";
    this.DEFAULTS.status[3] = "Up";
    this.DEFAULTS.status[4] = "Warning";
    this.DEFAULTS.status[5] = "Down";
    this.DEFAULTS.status[6] = "No Probe";
    this.DEFAULTS.status[7] = "Paused by User";
    this.DEFAULTS.status[8] = "Paused by Dependency";
    this.DEFAULTS.status[9] = "Paused by Schedule";
    this.DEFAULTS.status[10] = "Unusual";
    this.DEFAULTS.status[11] = "Not Licensed";
    this.DEFAULTS.status[12] = "Paused Until";
    this.DEFAULTS.status[13] = "Down (Acknowledged)";
    this.DEFAULTS.status[14] = "Down (Partial)";
    this.DEFAULTS.status['Unknown'] = 1;
    this.DEFAULTS.status['Scanning'] = 2;
    this.DEFAULTS.status['Collecting'] = 2;
    this.DEFAULTS.status['Up'] = 3;
    this.DEFAULTS.status['Warning'] = 4;
    this.DEFAULTS.status['Down'] = 5;
    this.DEFAULTS.status['No Probe'] = 6;
    this.DEFAULTS.status['Paused by User'] = 7;
    this.DEFAULTS.status['PausedbyUser'] = 7;
    this.DEFAULTS.status['Paused by Dependency'] = 8;
    this.DEFAULTS.status['PausedbyDependency'] = 8;
    this.DEFAULTS.status['Paused by Schedule'] = 9;
    this.DEFAULTS.status['PausedbySchedule'] = 9;
    this.DEFAULTS.status['Unusual'] = 10;
    this.DEFAULTS.status['Not Licensed'] = 11;
    this.DEFAULTS.status['PausedbyLicense'] = 11;
    this.DEFAULTS.status['Paused Until'] = 12;
    this.DEFAULTS.status['PausedUntil'] = 12;
    this.DEFAULTS.status['Down (Acknowledged)'] = 13;
    this.DEFAULTS.status['DownAcknowledged'] = 13;
    this.DEFAULTS.status['Down (Partial)'] = 14;
    this.DEFAULTS.status['DownPartial'] = 14;

    this.DEFAULTS.httpCodes = {};
    this.DEFAULTS.httpCodes[200] = "OK";
    this.DEFAULTS.httpCodes[302] = "Found";
    this.DEFAULTS.httpCodes[400] = "Bad Request";
    this.DEFAULTS.httpCodes[401] = "Unauthorized";

}

/**
 *
 * @returns {{}|*}
 */
PRTG.prototype.getDefaults = function () {
    return this.DEFAULTS;
};

/**
 * Return opposite mapping for status to status id
 * @param str
 * @returns {string|number}
 */
PRTG.prototype.getStatus = function(str){
    return this.DEFAULTS.status[str];
};

/**
 *
 * @param {string} path
 * @param {string|string[]} resultPath See https://lodash.com/docs#get
 * @param {function} [parse] parse function that uses signature of fn(string, callback) with callback of fn(err, result)
 * @returns {promise|object}
 */
PRTG.prototype.api = function (path, resultPath, parse) {
    var deferred = Q.defer();
    var self = this;

    var options = {
        url: this.url + path + this.auth
    };

    request(options, function (err, res, data) {
        if (err) {
            deferred.reject(err);
        } else if (res.statusCode != 200) {
            deferred.reject('Error: ' + self.getDefaults().httpCodes[res.statusCode]);
        } else if (res.statusCode === 200) {
            try {
                if (!parse) {
                    deferred.resolve(_.get(JSON.parse(data), resultPath));
                } else {
                    parse(data, function (err, res) {
                        if (!err) {
                            deferred.resolve(_.get(res, resultPath));
                        } else {
                            deferred.reject(err);
                        }
                    });
                }
            } catch (e) {
                deferred.reject(e);
            }
        }
    });

    return deferred.promise;
};

/**
 *
 * @param objid sensor's ID
 * @returns {*|promise|Sensor}
 */
PRTG.prototype.getSensor = function (objid) {
    return this.api('/api/getsensordetails.json?id=' + objid, 'sensordata');
};

/**
 *
 * @param objid
 * @param {string|string[]} [columns] Defaults to 'objid,probe,group,device,sensor,lastvalue,type,name,tags,active,status,grpdev,message'
 * @returns {*|promise|Sensor[]}
 */
PRTG.prototype.getDeviceSensors = function (objid, columns) {
    var path = '/api/table.json?content=sensors&output=json';

    if (columns) {
        if (_.isArray(columns)) {
            columns = columns.join(',');
        }
    } else {
        columns = 'objid,probe,group,device,sensor,lastvalue,type,name,tags,active,status,grpdev,message';
    }
    path += '&columns=' + columns;

    if (objid) {
        path += '&id=' + objid;
    }

    return this.api(path, 'sensors');
};

/**
 *
 * @param objid
 * @param property
 * @returns {promise|Object}
 */
PRTG.prototype.getObjectProperty = function (objid, property) {
    return this.api('/api/getobjectstatus.htm?id=' + objid + '&name=' + property + '&show=text', 'prtg.result', parseXML);
};

/**
 *
 * @param objid
 * @returns {*|promise|string}
 */
PRTG.prototype.getSensorStatusId = function(objid){
    var deferred = Q.defer();

    this.getSensor(objid)
        .then(function(res){
            deferred.resolve(res.statusid);
        })
        .fail(deferred.reject);

    return deferred.promise;
};

PRTG.prototype.getDeviceStatusId = function(objid){
    return this.getSensorStatusId(objid);
};

/**
 *
 * @private
 * @param {string} str xml string to parse
 * @param {function} cb callback(err, res)
 */
function parseXML(str, cb) {
    xml2js(str, {
        emptyTag: null,
        ignoreAttrs: true,
        mergeAttrs: true,
        explicitArray: false,
        trim: true
    }, cb);
}

module.exports = PRTG;
<commit_msg>Add helper functions, add filter support<commit_after>/**
 * Created by kgrube on 1/5/2016.
 */

/**
 * @private
 */
var Q = require('q'),
    request = require('request'),
    _ = require('lodash'),
    xml2js = require('xml2js').parseString;

/**
 * @typedef {object} PRTGFilter
 * @property {string} [filter_drel]         Only include records younger than this setting (for content='messages' and content='tickets' only).
 *                                          Possible values: today, yesterday, 7days, 30days, 12months, forever
 *
 * @property {string[]|string} [filter_status]    Only include sensors with a specific status (for content='sensors' only). Using multiple filter_status fields performs a logical OR.
 *                              See types PRTG.DEFAULTS.status.
 *
 * @property {string[]|string} [filter_tags]       Only include sensors with a specific tag (for content="sensors" only).
 *                                          Using multiple filter_tag fields performs a logical OR.
 *                                          Possible values: @tag(tagname)
 *
 * @property {string|string[]} [filter_xyz] filter_xyz where xyz is any column name used in the columns parameter;
 *                                          Substrings: use filter_xyz=@sub(substring1,substring2);
 *                                          Values not equal/above/below: use filter_xyz=@neq(value), filter_xyz=@above(value), filter_xyz=@below(value)
 *
 * @property {string} [sortby]              Sorts the data.  If this parameter is omitted, the table will be sorted based on the first column.  Add a leading '-' to reverse.
 *                                          Possible values: any column name used in the columns parameter.  (sortby=name, sortby=lastvalue, sortby=-lastvalue)
 */

/**
 * @typedef {object} Sensor
 * @property {string} name
 * @property {string} sensortype
 * @property {string} interval
 * @property {string} probename
 * @property {string} probegroupname
 * @property {string} parentdevicename
 * @property {string} parentdeviceid
 * @property {string} lastvalue
 * @property {string} lastmessage
 * @property {string} favorite
 * @property {string} statustext
 * @property {string} statusid
 * @property {string} lastup
 * @property {string} lastdown
 * @property {string} lastcheck
 * @property {string} uptime
 * @property {string} uptimetime
 * @property {string} downtime
 * @property {string} downtimetime
 * @property {string} updowntotal
 * @property {string} updownsince
 */

/**
 * @typedef {object} SensorColumns
 * @property {number} objid
 * @property {string} type
 * @property {string} name
 * @property tags
 * @property active
 * @property downtime
 * @property downtimetime
 * @property downtimesince
 * @property uptime
 * @property uptimetime
 * @property uptimesince
 * @property knowntime
 * @property cumsince
 * @property sensor
 * @property interval
 * @property lastcheck
 * @property lastup
 * @property lastdown
 * @property device
 * @property group
 * @property probe
 * @property grpdev
 * @property notifiesx
 * @property intervalx
 * @property access
 * @property dependency
 * @property probegroupdevice
 * @property status
 * @property message
 * @property priority
 * @property lastvalue
 * @property upsens
 * @property downsens
 * @property partialdownsens
 * @property warnsens
 * @property pausedsens
 * @property unusualsens
 * @property undefinedsens
 * @property totalsens
 * @property favorite
 * @property minigraph
 * @property comments
 * @property basetype ??
 * @property baselink ??
 * @property parentid ??
 *
 */

/**
 *
 * @param options
 * @param options.username
 * @param options.passhash
 * @param options.url Base URL of your PRTG installation, e.g. the API is accessible at <url>/API/
 * @constructor
 */
function PRTG(options) {
    if (!options) {
        throw "options must be defined.";
    }

    if (!options.username) {
        throw "options.username must be defined.";
    }

    if (!options.passhash) {
        throw "options.passhash must be defined.";
    }

    if (!options.url) {
        throw "options.url must be defined.";
    }

    this.auth = '&username=' + options.username + '&passhash=' + options.passhash;
    this.url = options.url;

    this.DEFAULTS = {};

    //PRTG uses different notations for these IDs all over the place
    this.DEFAULTS.status = {};
    this.DEFAULTS.status[1] = "Unknown";
    this.DEFAULTS.status[2] = "Scanning";
    this.DEFAULTS.status[3] = "Up";
    this.DEFAULTS.status[4] = "Warning";
    this.DEFAULTS.status[5] = "Down";
    this.DEFAULTS.status[6] = "No Probe";
    this.DEFAULTS.status[7] = "Paused by User";
    this.DEFAULTS.status[8] = "Paused by Dependency";
    this.DEFAULTS.status[9] = "Paused by Schedule";
    this.DEFAULTS.status[10] = "Unusual";
    this.DEFAULTS.status[11] = "Not Licensed";
    this.DEFAULTS.status[12] = "Paused Until";
    this.DEFAULTS.status[13] = "Down (Acknowledged)";
    this.DEFAULTS.status[14] = "Down (Partial)";
    this.DEFAULTS.status['Unknown'] = 1;
    this.DEFAULTS.status['Scanning'] = 2;
    this.DEFAULTS.status['Collecting'] = 2;
    this.DEFAULTS.status['Up'] = 3;
    this.DEFAULTS.status['Warning'] = 4;
    this.DEFAULTS.status['Down'] = 5;
    this.DEFAULTS.status['No Probe'] = 6;
    this.DEFAULTS.status['Paused by User'] = 7;
    this.DEFAULTS.status['PausedbyUser'] = 7;
    this.DEFAULTS.status['Paused by Dependency'] = 8;
    this.DEFAULTS.status['PausedbyDependency'] = 8;
    this.DEFAULTS.status['Paused by Schedule'] = 9;
    this.DEFAULTS.status['PausedbySchedule'] = 9;
    this.DEFAULTS.status['Unusual'] = 10;
    this.DEFAULTS.status['Not Licensed'] = 11;
    this.DEFAULTS.status['PausedbyLicense'] = 11;
    this.DEFAULTS.status['Paused Until'] = 12;
    this.DEFAULTS.status['PausedUntil'] = 12;
    this.DEFAULTS.status['Down (Acknowledged)'] = 13;
    this.DEFAULTS.status['DownAcknowledged'] = 13;
    this.DEFAULTS.status['Down (Partial)'] = 14;
    this.DEFAULTS.status['DownPartial'] = 14;

    this.DEFAULTS.httpCodes = {};
    this.DEFAULTS.httpCodes[200] = "OK";
    this.DEFAULTS.httpCodes[302] = "Found";
    this.DEFAULTS.httpCodes[400] = "Bad Request";
    this.DEFAULTS.httpCodes[401] = "Unauthorized";

}

/**
 *
 * @returns {{}|*}
 */
PRTG.prototype.getDefaults = function () {
    return this.DEFAULTS;
};

/**
 * Return opposite mapping for status to status id
 * @param str
 * @returns {string|number}
 */
PRTG.prototype.getStatus = function (str) {
    return this.DEFAULTS.status[str];
};

/**
 *
 * @param {string} path
 * @param {string|string[]} resultPath See https://lodash.com/docs#get
 * @param {function} [parse] parse function that uses signature of fn(string, callback) with callback of fn(err, result)
 * @returns {promise|object}
 */
PRTG.prototype.api = function (path, resultPath, parse) {
    var deferred = Q.defer();
    var self = this;

    var options = {
        url: this.url + path + this.auth
    };

    request(options, function (err, res, data) {
        if (err) {
            deferred.reject(err);
        } else if (res.statusCode != 200) {
            deferred.reject('Error: ' + self.getDefaults().httpCodes[res.statusCode]);
        } else if (res.statusCode === 200) {
            try {
                if (!parse) {
                    deferred.resolve(_.get(JSON.parse(data), resultPath));
                } else {
                    parse(data, function (err, res) {
                        if (!err) {
                            deferred.resolve(_.get(res, resultPath));
                        } else {
                            deferred.reject(err);
                        }
                    });
                }
            } catch (e) {
                deferred.reject(e);
            }
        }
    });

    return deferred.promise;
};

/**
 *
 * @param objid sensor's ID
 * @returns {*|promise|Sensor}
 */
PRTG.prototype.getSensor = function (objid) {
    return this.api('/api/getsensordetails.json?id=' + objid, 'sensordata');
};

/**
 *
 * @param objid
 * @param {string|string[]} [columns] Defaults to 'objid,probe,group,device,sensor,lastvalue,type,name,tags,active,status,grpdev,message'
 * @returns {*|promise|Sensor[]}
 */
PRTG.prototype.getDeviceSensors = function (objid, columns) {
    var path = '/api/table.json?content=sensors&output=json';

    if (columns) {
        if (_.isArray(columns)) {
            columns = columns.join(',');
        }
    } else {
        columns = 'objid,probe,group,device,sensor,lastvalue,type,name,tags,active,status,grpdev,message';
    }
    path += '&columns=' + columns;

    if (objid) {
        path += '&id=' + objid;
    }

    return this.api(path, 'sensors');
};

/**
 *
 * @param objid
 * @param property
 * @returns {promise|Object}
 */
PRTG.prototype.getObjectProperty = function (objid, property) {
    return this.api('/api/getobjectstatus.htm?id=' + objid + '&name=' + property + '&show=text', 'prtg.result', parseXML);
};

/**
 *
 * @param objid
 * @returns {*|promise|string}
 */
PRTG.prototype.getSensorStatusId = function (objid) {
    var deferred = Q.defer();

    this.getSensor(objid)
        .then(function (res) {
            deferred.resolve(res.statusid);
        })
        .fail(deferred.reject);

    return deferred.promise;
};

/**
 * @param objid
 * @returns {*|promise|string}
 */
PRTG.prototype.getDeviceStatusId = function (objid) {
    return this.getSensorStatusId(objid);
};

/**
 * @param columns
 * @param {PRTGFilter} [filter]
 * @param {string|number} [objid] filter set to this object (device/group/probe)
 * @returns {promise|Sensor[]}
 */
PRTG.prototype.getSensors = function (columns, filter, objid) {
    var path = '/api/table.json?content=sensors';

    if (columns) {
        if (_.isArray(columns)) {
            columns = columns.join(',');
        }
    } else {
        columns = 'objid,probe,group,device,sensor,lastvalue,type,name,tags,active,status,grpdev,message';
    }

    path += '&columns=' + columns;

    if (filter) {
        path += parameterize(filter);
    }

    if (objid) {
        path += '&id=' + objid;
    }

    return this.api(path, 'sensors');
};

PRTG.prototype.getDownOrAckSensors = function () {
    return this.getSensors(null, { filter_status: [this.DEFAULTS.status['Down'], this.DEFAULTS.status['DownAcknowledged']] });
};

/**
 *
 * @private
 * @param {string} str xml string to parse
 * @param {function} cb callback(err, res)
 */
function parseXML(str, cb) {
    xml2js(str, {
        emptyTag: null,
        ignoreAttrs: true,
        mergeAttrs: true,
        explicitArray: false,
        trim: true
    }, cb);
}

/**
 *
 * @param {PRTGFilter} filter
 * @returns {string}
 */
function parameterize(filter) {
    var params = [];

    for (var f in filter) {
        if (filter.hasOwnProperty(f)) {
            if (_.isArray(filter[f])) {
                for (var i = 0; i < filter[f].length; i++) {
                    params.push(f + '=' + filter[f][i]);
                }
            } else {
                params.push(f + '=' + filter[f])
            }
        }
    }

    return '&' + params.join('&');
}

module.exports = PRTG;
<|endoftext|>


<commit_before>angular.module('templates-main', ['wrapper/portalng.wrapper.tpl.html']);

angular.module("wrapper/portalng.wrapper.tpl.html", []).run(["$templateCache", function($templateCache) {
  $templateCache.put("wrapper/portalng.wrapper.tpl.html",
    "
Angular Portal version {{apiVersion}}
\n" +
    "| {{app.name}} |\n" +
    "
\n" +
    "

\n" +
    "
\n" +
    "
©2014 Michael Dausmann
\n" +
    "
");
}]);
<commit_msg>remove ignore<commit_after><|endoftext|>