<commit_before>'use strict';

const EventEmitter = require('events').EventEmitter;
const redis = require('redis');
const { createPool } = require('generic-pool');

const FLUSH_CONNECTION = true;
const DEFAULT_STATUS_INTERVAL = 60000
const DEFAULTS = {
    host: '127.0.0.1',
    port: '6379',
    max: 50,
    idleTimeoutMillis: 10000,
    reapIntervalMillis: 1000,
    noReadyCheck: false,
    returnToHead: false,
    unwatchOnRelease: true,
    name: 'default',
    slowPool: {
        log: false,
        elapsedThreshold: 25
    },
    emitter: {
        statusInterval: DEFAULT_STATUS_INTERVAL
    },
    commands: []
};

/**
 * Create a new multi database Redis pool.
 * It will emit `status` event with information about each created pool.
 *
 * @param {Object} options
 * @returns {RedisPool}
 * @constructor
 */
module.exports = class RedisPool extends EventEmitter {
    constructor (options = {}, logger = console) {
        super();

        this.pools = {};
        this.options = Object.assign({}, DEFAULTS, options);
        this.logger = logger;

        this._addCommands();
        this._emitStatus();
    }

    /**
   * Acquire Redis client
   *
   * @param {String|Number} database redis database name
   * @returns {Promise} with the Redis client
   */
    async acquire (database) {
        let pool = this.pools[database];
        if (!pool) {
            pool = this.pools[database] = makePool(this, database);
        }

        const startTime = Date.now();
        const client = await pool.acquire();
        const elapsedTime = Date.now() - startTime;

        if (this.options.slowPool.log && elapsedTime > this.options.slowPool.elapsedThreshold) {
            this.logger.info({ name: this.options.name, db: database, action: 'acquire', elapsed: elapsedTime, waiting: pool.pending });
        }

        if (client instanceof Error) {
            const err = client;
            err.name = this.options.name;
            err.db = database;
            err.action = 'acquire';
            this.logger.error(err);

            throw err;
        }

        return client;
    }

    /**
   * Release resource.
   *
   * @param {String|Number} database redis database name
   * @param {Object} resource resource object to release
   */
    async release (database, resource) {
        if (this.options.unwatchOnRelease) {
            resource.UNWATCH();
        }

        const pool = this.pools[database];

        if (pool) {
            await pool.release(resource);
        }
    }

    _addCommands () {
        if (this.options.commands.length) {
            this.options.commands.forEach(newCommand => redis.add_command(newCommand));
        }
    }

    _emitStatus () {
        setInterval(() => {
            for (const [poolKey, pool] of Object.entries(this.pools)) {
                this.emit('status', {
                    name: this.options.name,
                    db: poolKey,
                    count: pool.size,
                    unused: pool.available,
                    waiting: pool.pending
                });
            }
        }, this._getStatusDelay());
    }

    _getStatusDelay () {
        return (this.options.emitter && this.options.emitter.statusInterval) || DEFAULT_STATUS_INTERVAL;
    }
};

/**
 * Factory to create new Redis pools for a given Redis database
 * @param redisPool
 * @param database
 * @returns {Pool}
 */
function makePool (redisPool, database) {
    const factory = {
        // create function will loop forever if reject is called or exception is thrown
        // https://github.com/coopernurse/node-pool/issues/175
        create () {
            return new Promise(resolve => {
                let settled = false;

                const client = redis.createClient(redisPool.options.port, redisPool.options.host, {
                    no_ready_check: redisPool.options.noReadyCheck
                });

                client.on('error', (err) => {
                    if (!settled) {
                        settled = true;
                        client.end(FLUSH_CONNECTION);

                        if (err) {
                            return resolve(err);
                        }

                        return resolve(client);
                    }
                });

                client.on('ready', () => {
                    client.select(database, err => {
                        if (!settled) {
                            settled = true;

                            if (err) {
                                return resolve(err);
                            }
                            return resolve(client);
                        }
                    });
                });
            });
        },

        destroy (client) {
            return new Promise((resolve, reject) => {
                client.quit(err => {
                    client.end(FLUSH_CONNECTION);
                    if (err) {
                        return reject(err);
                    }
                    return resolve();
                });
            });
        },

        validate (client) {
            return new Promise(resolve => {
                return resolve(client && client.connected);
            });
        }
    };

    const config = {
        max: redisPool.options.max,
        idleTimeoutMillis: redisPool.options.idleTimeoutMillis,
        reapIntervalMillis: redisPool.options.reapIntervalMillis,
        returnToHead: redisPool.options.returnToHead
    };

    return createPool(factory, config);
}
<commit_msg>Log always on error<commit_after>'use strict';

const EventEmitter = require('events').EventEmitter;
const redis = require('redis');
const { createPool } = require('generic-pool');

const FLUSH_CONNECTION = true;
const DEFAULT_STATUS_INTERVAL = 60000
const DEFAULTS = {
    host: '127.0.0.1',
    port: '6379',
    max: 50,
    idleTimeoutMillis: 10000,
    reapIntervalMillis: 1000,
    noReadyCheck: false,
    returnToHead: false,
    unwatchOnRelease: true,
    name: 'default',
    slowPool: {
        log: false,
        elapsedThreshold: 25
    },
    emitter: {
        statusInterval: DEFAULT_STATUS_INTERVAL
    },
    commands: []
};

/**
 * Create a new multi database Redis pool.
 * It will emit `status` event with information about each created pool.
 *
 * @param {Object} options
 * @returns {RedisPool}
 * @constructor
 */
module.exports = class RedisPool extends EventEmitter {
    constructor (options = {}, logger = console) {
        super();

        this.pools = {};
        this.options = Object.assign({}, DEFAULTS, options);
        this.logger = logger;

        this._addCommands();
        this._emitStatus();
    }

    /**
   * Acquire Redis client
   *
   * @param {String|Number} database redis database name
   * @returns {Promise} with the Redis client
   */
    async acquire (database) {
        let pool = this.pools[database];
        if (!pool) {
            pool = this.pools[database] = makePool(this, database);
        }

        const startTime = Date.now();
        const client = await pool.acquire();
        const elapsedTime = Date.now() - startTime;

        if (this.options.slowPool.log && elapsedTime > this.options.slowPool.elapsedThreshold) {
            this.logger.info({ name: this.options.name, db: database, action: 'acquire', elapsed: elapsedTime, waiting: pool.pending });
        }

        if (client instanceof Error) {
            const err = client;
            err.name = this.options.name;
            err.db = database;
            err.action = 'acquire';
            this.logger.error(err);

            throw err;
        }

        return client;
    }

    /**
   * Release resource.
   *
   * @param {String|Number} database redis database name
   * @param {Object} resource resource object to release
   */
    async release (database, resource) {
        if (this.options.unwatchOnRelease) {
            resource.UNWATCH();
        }

        const pool = this.pools[database];

        if (pool) {
            await pool.release(resource);
        }
    }

    _addCommands () {
        if (this.options.commands.length) {
            this.options.commands.forEach(newCommand => redis.add_command(newCommand));
        }
    }

    _emitStatus () {
        setInterval(() => {
            for (const [poolKey, pool] of Object.entries(this.pools)) {
                this.emit('status', {
                    name: this.options.name,
                    db: poolKey,
                    count: pool.size,
                    unused: pool.available,
                    waiting: pool.pending
                });
            }
        }, this._getStatusDelay());
    }

    _getStatusDelay () {
        return (this.options.emitter && this.options.emitter.statusInterval) || DEFAULT_STATUS_INTERVAL;
    }
};

/**
 * Factory to create new Redis pools for a given Redis database
 * @param redisPool
 * @param database
 * @returns {Pool}
 */
function makePool (redisPool, database) {
    const factory = {
        // create function will loop forever if reject is called or exception is thrown
        // https://github.com/coopernurse/node-pool/issues/175
        create () {
            return new Promise(resolve => {
                let settled = false;

                const client = redis.createClient(redisPool.options.port, redisPool.options.host, {
                    no_ready_check: redisPool.options.noReadyCheck
                });

                client.on('error', (err) => {
                    if (settled) {
                        err.name = redisPool.options.name;
                        return redisPool.logger.error(err);
                    }

                    settled = true;
                    client.end(FLUSH_CONNECTION);

                    if (err) {
                        return resolve(err);
                    }

                    return resolve(client);
                });

                client.on('ready', () => {
                    client.select(database, err => {
                        if (!settled) {
                            settled = true;

                            if (err) {
                                return resolve(err);
                            }

                            return resolve(client);
                        }
                    });
                });
            });
        },

        destroy (client) {
            return new Promise((resolve, reject) => {
                client.quit(err => {
                    client.end(FLUSH_CONNECTION);
                    if (err) {
                        return reject(err);
                    }
                    return resolve();
                });
            });
        },

        validate (client) {
            return new Promise(resolve => {
                return resolve(client && client.connected);
            });
        }
    };

    const config = {
        max: redisPool.options.max,
        idleTimeoutMillis: redisPool.options.idleTimeoutMillis,
        reapIntervalMillis: redisPool.options.reapIntervalMillis,
        returnToHead: redisPool.options.returnToHead
    };

    return createPool(factory, config);
}
<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var debug = require('debug')('css-parse');

module.exports = function(css){

  /**
   * Parse stylesheet.
   */

  function stylesheet() {
    return { stylesheet: { rules: rules() }};
  }

  /**
   * Opening brace.
   */

  function open() {
    return match(/^{\s*/);
  }

  /**
   * Closing brace.
   */

  function close() {
    return match(/^}\s*/);
  }

  /**
   * Parse ruleset.
   */

  function rules() {
    var node;
    var rules = [];
    whitespace();
    comments();
    while (css[0] != '}' && (node = atrule() || rule())) {
      comments();
      rules.push(node);
    }
    return rules;
  }

  /**
   * Match `re` and return captures.
   */

  function match(re) {
    var m = re.exec(css);
    if (!m) return;
    css = css.slice(m[0].length);
    return m;
  }

  /**
   * Parse whitespace.
   */

  function whitespace() {
    match(/^\s*/);
  }

  /**
   * Parse comments;
   */

  function comments() {
    while (comment()) ;
  }

  /**
   * Parse comment.
   */

  function comment() {
    if ('/' == css[0] && '*' == css[1]) {
      var i = 2;
      while ('*' != css[i] && '/' != css[i + 1]) ++i;
      i += 2;
      css = css.slice(i);
      whitespace();
      return true;
    }
  }

  /**
   * Parse selector.
   */

  function selector() {
    var m = match(/^([^{]+)/);
    if (!m) return;
    return m[0].trim().split(/\s*,\s*/);
  }

  /**
   * Parse declaration.
   */

  function declaration() {
    // prop
    var prop = match(/^([-\w]+)\s*/);
    if (!prop) return;
    prop = prop[0];

    // :
    if (!match(/^:\s*/)) return;

    // val
    var val = match(/^([^};]+)\s*/);
    if (!val) return;
    val = val[0].trim();

    // ;
    match(/^;\s*/);

    return { property: prop, value: val };
  }

  /**
   * Parse keyframe.
   */

  function keyframe() {
    var m;
    var vals = [];

    while (m = match(/^(from|to|\d+%)\s*/)) {
      vals.push(m[1]);
      match(/^,\s*/);
    }

    if (!vals.length) return;

    return {
      values: vals,
      declarations: declarations()
    };
  }

  /**
   * Parse keyframes.
   */

  function keyframes() {
    var m = match(/^@([-\w]+)?keyframes */);
    if (!m) return;
    var vendor = m[1];

    // identifier
    var m = match(/^([-\w]+)\s+/);
    if (!m) return;
    var name = m[1];

    if (!open()) return;
    comments();

    var frame;
    var frames = [];
    while (frame = keyframe()) {
      frames.push(frame);
      comments();
    }

    if (!close()) return;

    return {
      name: name,
      vendor: vendor,
      keyframes: frames
    };
  }

  /**
   * Parse media.
   */

  function media() {
    var m = match(/^@media *([^{]+)/);
    if (!m) return;
    var media = m[1].trim();

    if (!open()) return;
    comments();

    var style = rules();

    if (!close()) return;

    return { media: media, rules: style };
  }

  /**
   * Parse import
   */

  function atimport() {
    var m = match(/^@import *([^;\n]+);\s*/);
    if (!m) return;
    return { import: m[1].trim() };
  }

  /**
   * Parse declarations.
   */

  function declarations() {
    var decls = [];

    if (!open()) return;
    comments();

    // declarations
    var decl;
    while (decl = declaration()) {
      decls.push(decl);
      comments();
    }

    if (!close()) return;
    return decls;
  }

  /**
   * Parse at rule.
   */

  function atrule() {
    return keyframes()
      || media()
      || atimport();
  }

  /**
   * Parse rule.
   */

  function rule() {
    var sel = selector();
    if (!sel) return;
    comments();
    return { selectors: sel, declarations: declarations() };
  }

  return stylesheet();
};<commit_msg>Support for IE property hacks.<commit_after>/**
 * Module dependencies.
 */

var debug = require('debug')('css-parse');

module.exports = function(css){

  /**
   * Parse stylesheet.
   */

  function stylesheet() {
    return { stylesheet: { rules: rules() }};
  }

  /**
   * Opening brace.
   */

  function open() {
    return match(/^{\s*/);
  }

  /**
   * Closing brace.
   */

  function close() {
    return match(/^}\s*/);
  }

  /**
   * Parse ruleset.
   */

  function rules() {
    var node;
    var rules = [];
    whitespace();
    comments();
    while (css[0] != '}' && (node = atrule() || rule())) {
      comments();
      rules.push(node);
    }
    return rules;
  }

  /**
   * Match `re` and return captures.
   */

  function match(re) {
    var m = re.exec(css);
    if (!m) return;
    css = css.slice(m[0].length);
    return m;
  }

  /**
   * Parse whitespace.
   */

  function whitespace() {
    match(/^\s*/);
  }

  /**
   * Parse comments;
   */

  function comments() {
    while (comment()) ;
  }

  /**
   * Parse comment.
   */

  function comment() {
    if ('/' == css[0] && '*' == css[1]) {
      var i = 2;
      while ('*' != css[i] && '/' != css[i + 1]) ++i;
      i += 2;
      css = css.slice(i);
      whitespace();
      return true;
    }
  }

  /**
   * Parse selector.
   */

  function selector() {
    var m = match(/^([^{]+)/);
    if (!m) return;
    return m[0].trim().split(/\s*,\s*/);
  }

  /**
   * Parse declaration.
   */

  function declaration() {
    // prop
    var prop = match(/^(\*?[-\w]+)\s*/);
    if (!prop) return;
    prop = prop[0];

    // :
    if (!match(/^:\s*/)) return;

    // val
    var val = match(/^([^};]+)\s*/);
    if (!val) return;
    val = val[0].trim();

    // ;
    match(/^;\s*/);

    return { property: prop, value: val };
  }

  /**
   * Parse keyframe.
   */

  function keyframe() {
    var m;
    var vals = [];

    while (m = match(/^(from|to|\d+%)\s*/)) {
      vals.push(m[1]);
      match(/^,\s*/);
    }

    if (!vals.length) return;

    return {
      values: vals,
      declarations: declarations()
    };
  }

  /**
   * Parse keyframes.
   */

  function keyframes() {
    var m = match(/^@([-\w]+)?keyframes */);
    if (!m) return;
    var vendor = m[1];

    // identifier
    var m = match(/^([-\w]+)\s+/);
    if (!m) return;
    var name = m[1];

    if (!open()) return;
    comments();

    var frame;
    var frames = [];
    while (frame = keyframe()) {
      frames.push(frame);
      comments();
    }

    if (!close()) return;

    return {
      name: name,
      vendor: vendor,
      keyframes: frames
    };
  }

  /**
   * Parse media.
   */

  function media() {
    var m = match(/^@media *([^{]+)/);
    if (!m) return;
    var media = m[1].trim();

    if (!open()) return;
    comments();

    var style = rules();

    if (!close()) return;

    return { media: media, rules: style };
  }

  /**
   * Parse import
   */

  function atimport() {
    var m = match(/^@import *([^;\n]+);\s*/);
    if (!m) return;
    return { import: m[1].trim() };
  }

  /**
   * Parse declarations.
   */

  function declarations() {
    var decls = [];

    if (!open()) return;
    comments();

    // declarations
    var decl;
    while (decl = declaration()) {
      decls.push(decl);
      comments();
    }

    if (!close()) return;
    return decls;
  }

  /**
   * Parse at rule.
   */

  function atrule() {
    return keyframes()
      || media()
      || atimport();
  }

  /**
   * Parse rule.
   */

  function rule() {
    var sel = selector();
    if (!sel) return;
    comments();
    return { selectors: sel, declarations: declarations() };
  }

  return stylesheet();
};<|endoftext|>


<commit_before>/**
 * Created by nuintun on 2015/4/27.
 */

'use strict';

var through = require('through2');
var duplexer = require('duplexer2');
var util = require('./lib/util');
var debug = util.debug;
var cache = require('./lib/cache');
var common = require('./lib/common');
var include = require('./lib/include');
var concat = require('./lib/concat');

function main(options){
  var input = through.obj({ objectMode: true });
  var output = through.obj({ objectMode: true });

  // debug
  debug('open: %s', colors.dataBold(util.normalize(util.cwd)));

  var monitor = function (stream){
    stream.on('error', function (e){
      output.emit('error', e);
    });

    return stream;
  };

  monitor(input)
    .pipe(monitor(include(options)))
    .pipe(monitor(concat()))
    .pipe(output);

  return duplexer(input, output);
}

/**
 * Exports module.
 */

main.cache = {};
main.cache.clear = cache.clear;
main.createParser = common.createParser;
module.exports = main;<commit_msg>add source file<commit_after>/**
 * Created by nuintun on 2015/4/27.
 */

'use strict';

var through = require('through2');
var duplexer = require('duplexer2');
var util = require('./lib/util');
var cache = require('./lib/cache');
var common = require('./lib/common');
var include = require('./lib/include');
var concat = require('./lib/concat');
var debug = util.debug;
var colors = util.colors;

function main(options){
  var input = through.obj({ objectMode: true });
  var output = through.obj({ objectMode: true });

  // debug
  debug('open: %s', colors.dataBold(util.normalize(util.cwd)));

  var monitor = function (stream){
    stream.on('error', function (e){
      output.emit('error', e);
    });

    return stream;
  };

  monitor(input)
    .pipe(monitor(include(options)))
    .pipe(monitor(concat()))
    .pipe(output);

  return duplexer(input, output);
}

/**
 * Exports module.
 */

main.cache = {};
main.cache.clear = cache.clear;
main.createParser = common.createParser;
module.exports = main;<|endoftext|>


<commit_before>
module.exports = function(game,opts){
  return new ObjectCollisionMonitor(game,opts)
}

function ObjectCollisionMonitor(game,opts){
  opts = opts || {}
  // add this to game as item
  this.game = game
  this.game.addItem(this)
  this.timeout = opts.timeout || 0
  this.previous_collisions = {}
}

var proto = ObjectCollisionMonitor.prototype

proto.pairKey = function(o1,o2){
  return [o1.toString(),o2.toString()].sort()
}

proto.tick = function(dt){
  var o1,o2,pairkey,prev,now,delta
  // check n^2 game items for overlap

  // o1
  for (var i=0; i<this.game.items.length; i++){
    o1 = this.game.items[i]
    if (!this.isCollidable(o1)) continue

    // o2
    for (var j=0; j<this.game.items.length; j++){
      // this is a symmetric matrix, so ignore
      // the diagonal (self-self colisions don't make
      // sense) and all of the lower diagonal elements
      // to avoid repeat considerations
      if (j<=i) continue

      o2 = this.game.items[j]
      if (!this.isCollidable(o2)) continue

      // check timeout for this pair
      pairkey = this.pairKey(o1,o2)
      prev = this.previous_collisions[pairkey] || 0
      now = Date.now()
      delta = now-prev
      if (delta > this.timeout){
        // collision?
        if (this.collides(o1,o2)){
          this.previous_collisions[pairkey] = Date.now()
          this.game.emit('object-collision',o1,o2)
        }
      }

    }
  } // end for
}

proto.isCollidable = function(object){
  return 'position' in object && 'aabb' in object
}

proto.collides = function(o1,o2){
  var aabb1 = o1.aabb()
  // var p1 = o1.position
  var aabb2 = o2.aabb()
  // var p2 = o2.position
  return aabb1.intersects(aabb2)
}

// Ignore interations betwen o1 and o2 for the specified
// amount of time. Duration overrides the default timeout.
proto.ignoreCollisions = function(duration,o1,o2){
  var adjusted_ts = Date.now() - this.timeout + duration
  this.previous_collisions[this.pairKey(o1,o2)] = adjusted_ts
}

<commit_msg>added ability to ignore objects entirely (exclude from all collisions indefinitely)<commit_after>
module.exports = function(game,opts){
  return new ObjectCollisionMonitor(game,opts)
}

function ObjectCollisionMonitor(game,opts){
  opts = opts || {}
  // add this to game as item
  this.game = game
  this.game.addItem(this)
  this.timeout = opts.timeout || 0
  this.previous_collisions = {}
  this.ignore_objects = {}
}

var proto = ObjectCollisionMonitor.prototype

proto.pairKey = function(o1,o2){
  return [o1.toString(),o2.toString()].sort()
}

proto.tick = function(dt){
  var o1,o2,pairkey,prev,now,delta
  // check n^2 game items for overlap

  // o1
  for (var i=0; i<this.game.items.length; i++){
    o1 = this.game.items[i]
    if (!this.isCollidable(o1)) continue

    // o2
    for (var j=0; j<this.game.items.length; j++){
      // this is a symmetric matrix, so ignore
      // the diagonal (self-self colisions don't make
      // sense) and all of the lower diagonal elements
      // to avoid repeat considerations
      if (j<=i) continue

      o2 = this.game.items[j]
      if (!this.isCollidable(o2)) continue

      // check timeout for this pair
      pairkey = this.pairKey(o1,o2)
      prev = this.previous_collisions[pairkey] || 0
      now = Date.now()
      delta = now-prev
      if (delta > this.timeout){
        // collision?
        if (this.collides(o1,o2)){
          this.previous_collisions[pairkey] = Date.now()
          this.game.emit('object-collision',o1,o2)
        }
      }

    } // end for o2
  } // end for o1
}

proto.isCollidable = function(object){
  return 'position' in object
    && 'aabb' in object
    && !(object in this.ignore_objects)
}

proto.collides = function(o1,o2){
  var aabb1 = o1.aabb()
  var aabb2 = o2.aabb()
  return aabb1.intersects(aabb2)
}

proto.ignoreObject = function(object){
  this.ignore_objects[object] = true
}

// Ignore interations betwen o1 and o2 for the specified
// amount of time. Duration overrides the default timeout.
proto.ignoreCollisions = function(duration,o1,o2){
  var adjusted_ts = Date.now() - this.timeout + duration
  this.previous_collisions[this.pairKey(o1,o2)] = adjusted_ts
}

<|endoftext|>


<commit_before>// ==UserScript==
// @name        CheckChangelogFromGithubRelease
// @namespace   http://efcl.info/
// @description Check ChangeLog from Github Relase page.
// @license     MIT
// @include     https://github.com/*/*/releases/tag/*
// @version     1.2
// @grant       GM_xmlhttpRequest
// ==/UserScript==
"use strict";
var githubAPI = require("./lib/github_api");
var githubDOM = require("./lib/github_dom");
var searcher = require("./lib/seacher");
var injector = require("./lib/injector");
var treePromise = new Promise(function (resolve, reject) {
    githubAPI.getTree({
        "owner": githubDOM.getOwner(),
        "name": githubDOM.getRepoName(),
        "tagName": githubDOM.getTagName()
    }, function (error, res) {
        if (error) {
            reject(error);
        } else {
            resolve(res);
        }
    })
});

treePromise.then(JSON.parse)
    .then(searcher.findChangeLogInTrees)
    .then(function (result) {
        if (!result) {
            return Promise.reject(new Error("Not found CHANGELOG in Repogitory."));
        }
        injector.injectChangelogLink(result.path);
    })
    .catch(function (error) {
        console.error(error);
    });

<commit_msg>1.2.1<commit_after>// ==UserScript==
// @name        CheckChangelogFromGithubRelease
// @namespace   http://efcl.info/
// @description Check ChangeLog from Github Relase page.
// @license     MIT
// @include     https://github.com/*/*/releases/tag/*
// @version     1.2.1
// @grant       GM_xmlhttpRequest
// ==/UserScript==
"use strict";
var githubAPI = require("./lib/github_api");
var githubDOM = require("./lib/github_dom");
var searcher = require("./lib/seacher");
var injector = require("./lib/injector");
var treePromise = new Promise(function (resolve, reject) {
    githubAPI.getTree({
        "owner": githubDOM.getOwner(),
        "name": githubDOM.getRepoName(),
        "tagName": githubDOM.getTagName()
    }, function (error, res) {
        if (error) {
            reject(error);
        } else {
            resolve(res);
        }
    })
});

treePromise.then(JSON.parse)
    .then(searcher.findChangeLogInTrees)
    .then(function (result) {
        if (!result) {
            return Promise.reject(new Error("Not found CHANGELOG in Repogitory."));
        }
        injector.injectChangelogLink(result.path);
    })
    .catch(function (error) {
        console.error(error);
    });

<|endoftext|>


<commit_before>ehehheh
<commit_msg>added index framework<commit_after>'use strict';

<|endoftext|>


<commit_before>require('./bot');
require('./web');<commit_msg>Ready<commit_after>require('./bot.js');
require('./web.js');
<|endoftext|>


<commit_before>'use strict';
/**
 * Created by jazarja, 4ossiblellc on 9/20/16.
 */

var _ = require('lodash');
var merge = require('deepmerge');

// Webpack specific case
if (typeof merge !== 'function') {
  merge = merge.default
}

var isEmpty = function (map) {
  for(var key in map) {
    if(map.hasOwnProperty(key)) {
      return false;
    }
  }
  return true;
};

var deepDiffMapper = function () {
  return {
    VALUE_CREATED: 'created',
    VALUE_UPDATED: 'updated',
    VALUE_DELETED: 'deleted',
    VALUE_UNCHANGED: 'unchanged',
    map: function (obj1, obj2) {
      if(this.isFunction(obj1) || this.isFunction(obj2)) {
        throw 'Invalid argument. Function given, object expected.';
      }
      if(this.isValue(obj1) || this.isValue(obj2)) {
        return {
          type: this.compareValues(obj1, obj2),
          data: obj2,
          dataType: (obj1 === undefined) ? typeof obj2 : typeof obj1,
        };
      }
      if(this.isArray(obj1) || this.isArray(obj2)) {
        return {
          type: this.compareValues(obj1, obj2),
          data: obj2,
          dataType: "list"
        };
      }

      var diff = {};
      var key;
      for(key in obj1) {
        if(this.isFunction(obj1[key])) {
          continue;
        }

        var value2 = undefined;
        if('undefined' !== typeof (obj2[key])) {
          value2 = obj2[key];
        }

        diff[key] = this.map(obj1[key], value2);
      }
      for(key in obj2) {
        if(this.isFunction(obj2[key]) || ('undefined' !== typeof (diff[key]))) {
          continue;
        }

        diff[key] = this.map(undefined, obj2[key]);
      }

      return diff;

    },
    compareValues: function (value1, value2) {
      if(value1 === value2) {
        return this.VALUE_UNCHANGED;
      }
      if('undefined' === typeof (value1)) {
        return this.VALUE_CREATED;
      }
      if('undefined' === typeof (value2)) {
        return this.VALUE_DELETED;
      }

      return this.VALUE_UPDATED;
    },
    isFunction: function (obj) {
      return {}.toString.apply(obj) === '[object Function]';
    },
    isArray: function (obj) {
      return {}.toString.apply(obj) === '[object Array]';
    },
    isObject: function (obj) {
      return {}.toString.apply(obj) === '[object Object]';
    },
    isValue: function (obj) {
      return !this.isObject(obj) && !this.isArray(obj);
    }
  };
}();

var removeSpecialChars = function (s) {
  return s.replace(/\./g, "").replace(/:/g, "").replace(/#/g, "");
};

var removeSpecialCharsInExpression = function (s) {
  return s.replace(/\.|:|#|-/g, "");
};

var updateExpressionGenerator = function (compareResult, options, path,
  excludeFields) {

  var request = {
    UpdateExpression: "",
    ExpressionAttributeNames: {},
    ExpressionAttributeValues: {}
  };

  var setExpression = "";
  var hasSetExpression = false;
  var removeExpression = "";
  var hasRemoveExpression = false;

  var filterOutDeleteFields = function (obj, path) {
    var wholeList = {
      updateList: [],
      removeList: []
    };
    var name;
    for(var i in obj) {
      // console.log(i + " = " + JSON.stringify(obj[i], null, 4) +
      //   ", hasOwnProperty: " + obj.hasOwnProperty(
      //     i));
      // console.log("");

      // if(Array.isArray(obj[i])) {
      //   obj[i].forEach(arrayRemoveFunc);
      // } else

      if(obj.hasOwnProperty(i) && typeof obj[i] === "object") {

        if(obj[i].type === "updated" && (obj[i].data === "" || obj[i].data ===
            undefined)) {
          wholeList.removeList.push({
            "name": (path ? path + "." : "") + i,
          });
        } else if((obj[i].type === "updated" || obj[i].type === "created") && obj[i].data !== undefined) {
          //console.log("pushed => " + obj[i].dataType, (path ?  path + "." : "") +  i + " = " + obj[i].data);
          wholeList.updateList.push({
            "name": (path ? path + "." : "") + i,
            "value": obj[i].data,
            "dataType": obj[i].dataType
          });
        } else
        if((obj[i].type === undefined && obj[i].data === undefined) ||
          (obj[i].type && obj[i].type !== "deleted" && obj[i].type !==
            "unchanged")) {
          var partial = isNaN(Number(i)) ? "." + i : "[" + i + "]";
          name = path !== null ? path + partial : i;
          // console.log("- nested object ->", name, obj[i].dataType);
          var childList = filterOutDeleteFields(obj[i], name);
          wholeList.updateList = wholeList.updateList.concat(childList.updateList);
          wholeList.removeList = wholeList.removeList.concat(childList.removeList);
        }
      }
    }

    // console.log("returning updateList: " + updateList);
    return wholeList;
  };

  var wholeList = filterOutDeleteFields(compareResult, null);
  wholeList.updateList.forEach(function (expr) {
    // change this logic to have # in front of .
    var propName = expr.name.replace(/&/g, "").replace(/_/g, "").replace(
      /\[/g, "").replace(/\]/g, "");

    var splittedByDotPropName = expr.name.split(".");
    var propNameExpressionName = "#" + splittedByDotPropName.map(removeSpecialCharsInExpression).join(".#");
    splittedByDotPropName.forEach(function (partialName) {
      request.ExpressionAttributeNames["#" + removeSpecialCharsInExpression(partialName)] =
        partialName;
    });
    var propNameExpressionValue = ":" + removeSpecialCharsInExpression(propName);

    if(hasSetExpression) {
      setExpression += ", " + propNameExpressionName + " = " + propNameExpressionValue + "";
    } else {
      setExpression += "SET " + propNameExpressionName + " = " + propNameExpressionValue + "";
      hasSetExpression = true;
    }

    request.ExpressionAttributeValues[propNameExpressionValue] = expr.value;
  });

  wholeList.removeList.forEach(function (expr, index) {
    // var propName = expr.name.replace(/&/g, "").replace(/_/g, "").replace(
    //   /\[/g, "").replace(/\]/g, "");

    var splittedByDotPropName = expr.name.split(".");
    var propNameExpressionName = "#" + splittedByDotPropName.map(removeSpecialChars).join(".#");
    splittedByDotPropName.forEach(function (partialName) {
      request.ExpressionAttributeNames["#" + removeSpecialChars(partialName)] =
        partialName;
    });

    if(hasRemoveExpression) {
      removeExpression += ", " + propNameExpressionName + "";
    } else {
      removeExpression += "REMOVE " + propNameExpressionName + "";
      hasRemoveExpression = true;
    }

  });

  if(isEmpty(request.ExpressionAttributeNames)) {
    delete request.ExpressionAttributeNames;
  }

  if(hasSetExpression && hasRemoveExpression) {
    request.UpdateExpression = setExpression.trim() + " " + removeExpression.trim();
  } else
  if(hasSetExpression) {
    request.UpdateExpression = setExpression.trim();
  } else
  if(hasRemoveExpression) {
    request.UpdateExpression = removeExpression.trim();
  }

  return request;
};

var removeExpressionGenerator = function (original, removes, compareResult,
  path, itemUniqueId) {

  var request = {
    UpdateExpression: "",
    ExpressionAttributeNames: {},
    ExpressionAttributeValues: {}
  };

  var setExpression = "";
  var hasSetExpression = false;
  var removeExpression = "";
  var hasRemoveExpression = false;

  var filterOutCreateFields = function (obj, path) {
    var updateList = [];
    var name;
    for(var i in obj) {
      // console.log(i + " = " + JSON.stringify(obj[i], null, 4) +
      //   ", hasOwnProperty: " + obj.hasOwnProperty(
      //     i));
      // console.log("");

      // if(Array.isArray(obj[i])) {
      //   obj[i].forEach(arrayRemoveFunc);
      // } else

      if(obj.hasOwnProperty(i) && typeof obj[i] === "object") {

        if((obj[i].type === "updated" || obj[i].type === "deleted") && obj[
            i].data) {
          //console.log("pushed => " + obj[i].dataType, (path ?  path + "." : "") +  i + " = " + obj[i].data);
          updateList.push({
            "name": (path ? path + "." : "") + i,
            "value": obj[i].data,
            "dataType": obj[i].dataType
          });
        } else
        if((obj[i].type === undefined && obj[i].data === undefined) ||
          (obj[i].type && obj[i].type !== "created" && obj[i].type !==
            "unchanged")) {
          var partial = isNaN(parseInt(i, 10)) ? "." + i : "[" + i + "]";
          name = path !== null ? path + partial : i;
          // console.log("- nested object ->", name, obj[i].dataType);
          updateList = updateList.concat(filterOutCreateFields(obj[i], name));
        }
      }
    }

    // console.log("returning updateList: " + updateList);
    return updateList;
  };

  var updateList = filterOutCreateFields(compareResult, null);

  updateList.forEach(function (expr) {
    var propName = expr.name.replace(/&/g, "").replace(/_/g, "").replace(
      /\[/g, "").replace(/\]/g, "");

    var splittedByDotPropName, propNameExpressionName;

    if(expr.dataType !== "list") {
      splittedByDotPropName = expr.name.split(".");
      propNameExpressionName = "#" + splittedByDotPropName.map(removeSpecialChars).join(".#");
      splittedByDotPropName.forEach(function (partialName) {
        request.ExpressionAttributeNames["#" + removeSpecialChars(partialName)] =
          partialName;
      });

      if(hasRemoveExpression) {
        removeExpression += ", " + propNameExpressionName + "";
      } else {
        removeExpression += "REMOVE " + propNameExpressionName + "";
        hasRemoveExpression = true;
      }

    } else
    if(expr.value && expr.value.length === 0) {
      splittedByDotPropName = expr.name.split(".");
      propNameExpressionName = "#" + splittedByDotPropName.map(removeSpecialChars).join(".#");
      splittedByDotPropName.forEach(function (partialName) {
        request.ExpressionAttributeNames["#" + removeSpecialChars(partialName)] =
          partialName;
      });

      if(hasRemoveExpression) {
        removeExpression += ", " + propNameExpressionName + "";
      } else {
        removeExpression += "REMOVE " + propNameExpressionName + "";
        hasRemoveExpression = true;
      }

    }
  });

  // List element updates

  updateList.forEach(function (expr) {
    var propName = expr.name.replace(/&/g, "").replace(/_/g, "").replace(
      /\[/g, "").replace(/\]/g, "");

    var splittedByDotPropName, propNameExpressionName,
      propNameExpressionValue;

    if(expr.dataType !== "list") {

    } else {
      var value = null;
      // Remove any elements that specified in removes json
      if(typeof _.get(original, expr.name)[0] === "object" || typeof _.get(
          removes, expr.name)[0] === "object") {
        if(typeof itemUniqueId === 'undefined' || itemUniqueId == null) {
          console.error(
            "Found object in a list, but no itemUniqueId parameter specified"
          );
          value = _.xorBy(_.get(original, expr.name), _.get(removes, expr
            .name), "id");
        } else {
          value = _.xorBy(_.get(original, expr.name), _.get(removes, expr
            .name), itemUniqueId);
        }
      } else {
        value = _.xor(_.get(original, expr.name), _.get(removes, expr.name));
      }

      splittedByDotPropName = expr.name.split(".");
      propNameExpressionName = "#" + splittedByDotPropName.map(removeSpecialChars).join(".#");
      splittedByDotPropName.forEach(function (partialName) {
        request.ExpressionAttributeNames["#" + removeSpecialChars(partialName)] =
          partialName;
      });
      propNameExpressionValue = ":" + removeSpecialChars(propName);

      if(value.length === 0) {
        // Remove
        if(hasRemoveExpression) {
          // subsequent elements
          removeExpression += ", " + propNameExpressionName;
        } else {
          // first element
          removeExpression = "REMOVE " + propNameExpressionName + "";
          hasRemoveExpression = true;
        }

      } else {
        // Set/Update
        request.ExpressionAttributeValues[propNameExpressionValue] =
          value;

        if(hasSetExpression) {
          // Subsequent element
          setExpression += ", " + propNameExpressionName + " = " +
            propNameExpressionValue + "";
        } else {
          setExpression = "SET " + propNameExpressionName + " = " +
            propNameExpressionValue + "";
          hasSetExpression = true;
        }
      }
    }
  });

  if(isEmpty(request.ExpressionAttributeNames)) {
    delete request.ExpressionAttributeNames;
  }

  if(isEmpty(request.ExpressionAttributeValues)) {
    delete request.ExpressionAttributeValues;
  }

  if(hasSetExpression && hasRemoveExpression) {
    request.UpdateExpression = removeExpression.trim() + " " + setExpression.trim();
  } else
  if(hasSetExpression) {
    request.UpdateExpression = setExpression.trim();
  } else
  if(hasRemoveExpression) {
    request.UpdateExpression = removeExpression.trim();
  }

  return request;
};

// make sure the ES5 Array.isArray() method exists
if(!Array.isArray) {
  Array.isArray = function (arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
  };
}

function emptyArrays(data) {
  for(var key in data) {
    if(key !== undefined) {
      // console.log("key: ", key);
      var item = data[key];
      if(item !== undefined && Array.isArray(item)) {
        // see if the array is empty
        // remove this item from the parent object
        // console.log("deleting the item:" + JSON.stringify(item));
        data[key] = [];
        // if this item is an object, then recurse into it
        // to remove empty arrays in it too
      } else if(item !== undefined && typeof item === "object") {
        emptyArrays(item);
      }
    }
  }
}

exports.generateRemoveExpression = function (original, removes, itemUniqueId) {
  return removeExpressionGenerator(original, removes, deepDiffMapper.map(
    removes, original), null, itemUniqueId);
};

exports.generateUpdateExpression = function (original, updates, options) {

  if(options && options.arrayMerge && options.arrayMerge === "replaceMerge") {
    emptyArrays(original);
    delete options.arrayMerge;
  }

  var merged = merge(original, updates);

  return updateExpressionGenerator(deepDiffMapper.map(
    original, merged
  ), options, null);
};

module.exports = {
  getRemoveExpression: exports.generateRemoveExpression,
  getUpdateExpression: exports.generateUpdateExpression
};
<commit_msg>added more special characters to remove list<commit_after>'use strict';
/**
 * Created by jazarja, 4ossiblellc on 9/20/16.
 */

var _ = require('lodash');
var merge = require('deepmerge');

// Webpack specific case
if (typeof merge !== 'function') {
  merge = merge.default
}

var isEmpty = function (map) {
  for(var key in map) {
    if(map.hasOwnProperty(key)) {
      return false;
    }
  }
  return true;
};

var deepDiffMapper = function () {
  return {
    VALUE_CREATED: 'created',
    VALUE_UPDATED: 'updated',
    VALUE_DELETED: 'deleted',
    VALUE_UNCHANGED: 'unchanged',
    map: function (obj1, obj2) {
      if(this.isFunction(obj1) || this.isFunction(obj2)) {
        throw 'Invalid argument. Function given, object expected.';
      }
      if(this.isValue(obj1) || this.isValue(obj2)) {
        return {
          type: this.compareValues(obj1, obj2),
          data: obj2,
          dataType: (obj1 === undefined) ? typeof obj2 : typeof obj1,
        };
      }
      if(this.isArray(obj1) || this.isArray(obj2)) {
        return {
          type: this.compareValues(obj1, obj2),
          data: obj2,
          dataType: "list"
        };
      }

      var diff = {};
      var key;
      for(key in obj1) {
        if(this.isFunction(obj1[key])) {
          continue;
        }

        var value2 = undefined;
        if('undefined' !== typeof (obj2[key])) {
          value2 = obj2[key];
        }

        diff[key] = this.map(obj1[key], value2);
      }
      for(key in obj2) {
        if(this.isFunction(obj2[key]) || ('undefined' !== typeof (diff[key]))) {
          continue;
        }

        diff[key] = this.map(undefined, obj2[key]);
      }

      return diff;

    },
    compareValues: function (value1, value2) {
      if(value1 === value2) {
        return this.VALUE_UNCHANGED;
      }
      if('undefined' === typeof (value1)) {
        return this.VALUE_CREATED;
      }
      if('undefined' === typeof (value2)) {
        return this.VALUE_DELETED;
      }

      return this.VALUE_UPDATED;
    },
    isFunction: function (obj) {
      return {}.toString.apply(obj) === '[object Function]';
    },
    isArray: function (obj) {
      return {}.toString.apply(obj) === '[object Array]';
    },
    isObject: function (obj) {
      return {}.toString.apply(obj) === '[object Object]';
    },
    isValue: function (obj) {
      return !this.isObject(obj) && !this.isArray(obj);
    }
  };
}();

var removeSpecialChars = function (s) {
  return s.replace(/\./g, "").replace(/:/g, "").replace(/#/g, "").replace(/\//g, "").replace(" ", "");
};

var removeSpecialCharsInExpression = function (s) {
  return s.replace(/\.|:|#|-/g, "");
};

var updateExpressionGenerator = function (compareResult, options, path,
  excludeFields) {

  var request = {
    UpdateExpression: "",
    ExpressionAttributeNames: {},
    ExpressionAttributeValues: {}
  };

  var setExpression = "";
  var hasSetExpression = false;
  var removeExpression = "";
  var hasRemoveExpression = false;

  var filterOutDeleteFields = function (obj, path) {
    var wholeList = {
      updateList: [],
      removeList: []
    };
    var name;
    for(var i in obj) {
      // console.log(i + " = " + JSON.stringify(obj[i], null, 4) +
      //   ", hasOwnProperty: " + obj.hasOwnProperty(
      //     i));
      // console.log("");

      // if(Array.isArray(obj[i])) {
      //   obj[i].forEach(arrayRemoveFunc);
      // } else

      if(obj.hasOwnProperty(i) && typeof obj[i] === "object") {

        if(obj[i].type === "updated" && (obj[i].data === "" || obj[i].data ===
            undefined)) {
          wholeList.removeList.push({
            "name": (path ? path + "." : "") + i,
          });
        } else if((obj[i].type === "updated" || obj[i].type === "created") && obj[i].data !== undefined) {
          //console.log("pushed => " + obj[i].dataType, (path ?  path + "." : "") +  i + " = " + obj[i].data);
          wholeList.updateList.push({
            "name": (path ? path + "." : "") + i,
            "value": obj[i].data,
            "dataType": obj[i].dataType
          });
        } else
        if((obj[i].type === undefined && obj[i].data === undefined) ||
          (obj[i].type && obj[i].type !== "deleted" && obj[i].type !==
            "unchanged")) {
          var partial = isNaN(Number(i)) ? "." + i : "[" + i + "]";
          name = path !== null ? path + partial : i;
          // console.log("- nested object ->", name, obj[i].dataType);
          var childList = filterOutDeleteFields(obj[i], name);
          wholeList.updateList = wholeList.updateList.concat(childList.updateList);
          wholeList.removeList = wholeList.removeList.concat(childList.removeList);
        }
      }
    }

    // console.log("returning updateList: " + updateList);
    return wholeList;
  };

  var wholeList = filterOutDeleteFields(compareResult, null);
  wholeList.updateList.forEach(function (expr) {
    // change this logic to have # in front of .
    var propName = expr.name.replace(/&/g, "").replace(/_/g, "").replace(
      /\[/g, "").replace(/\]/g, "");

    var splittedByDotPropName = expr.name.split(".");
    var propNameExpressionName = "#" + splittedByDotPropName.map(removeSpecialCharsInExpression).join(".#");
    splittedByDotPropName.forEach(function (partialName) {
      request.ExpressionAttributeNames["#" + removeSpecialCharsInExpression(partialName)] =
        partialName;
    });
    var propNameExpressionValue = ":" + removeSpecialCharsInExpression(propName);

    if(hasSetExpression) {
      setExpression += ", " + propNameExpressionName + " = " + propNameExpressionValue + "";
    } else {
      setExpression += "SET " + propNameExpressionName + " = " + propNameExpressionValue + "";
      hasSetExpression = true;
    }

    request.ExpressionAttributeValues[propNameExpressionValue] = expr.value;
  });

  wholeList.removeList.forEach(function (expr, index) {
    // var propName = expr.name.replace(/&/g, "").replace(/_/g, "").replace(
    //   /\[/g, "").replace(/\]/g, "");

    var splittedByDotPropName = expr.name.split(".");
    var propNameExpressionName = "#" + splittedByDotPropName.map(removeSpecialChars).join(".#");
    splittedByDotPropName.forEach(function (partialName) {
      request.ExpressionAttributeNames["#" + removeSpecialChars(partialName)] =
        partialName;
    });

    if(hasRemoveExpression) {
      removeExpression += ", " + propNameExpressionName + "";
    } else {
      removeExpression += "REMOVE " + propNameExpressionName + "";
      hasRemoveExpression = true;
    }

  });

  if(isEmpty(request.ExpressionAttributeNames)) {
    delete request.ExpressionAttributeNames;
  }

  if(hasSetExpression && hasRemoveExpression) {
    request.UpdateExpression = setExpression.trim() + " " + removeExpression.trim();
  } else
  if(hasSetExpression) {
    request.UpdateExpression = setExpression.trim();
  } else
  if(hasRemoveExpression) {
    request.UpdateExpression = removeExpression.trim();
  }

  return request;
};

var removeExpressionGenerator = function (original, removes, compareResult,
  path, itemUniqueId) {

  var request = {
    UpdateExpression: "",
    ExpressionAttributeNames: {},
    ExpressionAttributeValues: {}
  };

  var setExpression = "";
  var hasSetExpression = false;
  var removeExpression = "";
  var hasRemoveExpression = false;

  var filterOutCreateFields = function (obj, path) {
    var updateList = [];
    var name;
    for(var i in obj) {
      // console.log(i + " = " + JSON.stringify(obj[i], null, 4) +
      //   ", hasOwnProperty: " + obj.hasOwnProperty(
      //     i));
      // console.log("");

      // if(Array.isArray(obj[i])) {
      //   obj[i].forEach(arrayRemoveFunc);
      // } else

      if(obj.hasOwnProperty(i) && typeof obj[i] === "object") {

        if((obj[i].type === "updated" || obj[i].type === "deleted") && obj[
            i].data) {
          //console.log("pushed => " + obj[i].dataType, (path ?  path + "." : "") +  i + " = " + obj[i].data);
          updateList.push({
            "name": (path ? path + "." : "") + i,
            "value": obj[i].data,
            "dataType": obj[i].dataType
          });
        } else
        if((obj[i].type === undefined && obj[i].data === undefined) ||
          (obj[i].type && obj[i].type !== "created" && obj[i].type !==
            "unchanged")) {
          var partial = isNaN(parseInt(i, 10)) ? "." + i : "[" + i + "]";
          name = path !== null ? path + partial : i;
          // console.log("- nested object ->", name, obj[i].dataType);
          updateList = updateList.concat(filterOutCreateFields(obj[i], name));
        }
      }
    }

    // console.log("returning updateList: " + updateList);
    return updateList;
  };

  var updateList = filterOutCreateFields(compareResult, null);

  updateList.forEach(function (expr) {
    var propName = expr.name.replace(/&/g, "").replace(/_/g, "").replace(
      /\[/g, "").replace(/\]/g, "");

    var splittedByDotPropName, propNameExpressionName;

    if(expr.dataType !== "list") {
      splittedByDotPropName = expr.name.split(".");
      propNameExpressionName = "#" + splittedByDotPropName.map(removeSpecialChars).join(".#");
      splittedByDotPropName.forEach(function (partialName) {
        request.ExpressionAttributeNames["#" + removeSpecialChars(partialName)] =
          partialName;
      });

      if(hasRemoveExpression) {
        removeExpression += ", " + propNameExpressionName + "";
      } else {
        removeExpression += "REMOVE " + propNameExpressionName + "";
        hasRemoveExpression = true;
      }

    } else
    if(expr.value && expr.value.length === 0) {
      splittedByDotPropName = expr.name.split(".");
      propNameExpressionName = "#" + splittedByDotPropName.map(removeSpecialChars).join(".#");
      splittedByDotPropName.forEach(function (partialName) {
        request.ExpressionAttributeNames["#" + removeSpecialChars(partialName)] =
          partialName;
      });

      if(hasRemoveExpression) {
        removeExpression += ", " + propNameExpressionName + "";
      } else {
        removeExpression += "REMOVE " + propNameExpressionName + "";
        hasRemoveExpression = true;
      }

    }
  });

  // List element updates

  updateList.forEach(function (expr) {
    var propName = expr.name.replace(/&/g, "").replace(/_/g, "").replace(
      /\[/g, "").replace(/\]/g, "");

    var splittedByDotPropName, propNameExpressionName,
      propNameExpressionValue;

    if(expr.dataType !== "list") {

    } else {
      var value = null;
      // Remove any elements that specified in removes json
      if(typeof _.get(original, expr.name)[0] === "object" || typeof _.get(
          removes, expr.name)[0] === "object") {
        if(typeof itemUniqueId === 'undefined' || itemUniqueId == null) {
          console.error(
            "Found object in a list, but no itemUniqueId parameter specified"
          );
          value = _.xorBy(_.get(original, expr.name), _.get(removes, expr
            .name), "id");
        } else {
          value = _.xorBy(_.get(original, expr.name), _.get(removes, expr
            .name), itemUniqueId);
        }
      } else {
        value = _.xor(_.get(original, expr.name), _.get(removes, expr.name));
      }

      splittedByDotPropName = expr.name.split(".");
      propNameExpressionName = "#" + splittedByDotPropName.map(removeSpecialChars).join(".#");
      splittedByDotPropName.forEach(function (partialName) {
        request.ExpressionAttributeNames["#" + removeSpecialChars(partialName)] =
          partialName;
      });
      propNameExpressionValue = ":" + removeSpecialChars(propName);

      if(value.length === 0) {
        // Remove
        if(hasRemoveExpression) {
          // subsequent elements
          removeExpression += ", " + propNameExpressionName;
        } else {
          // first element
          removeExpression = "REMOVE " + propNameExpressionName + "";
          hasRemoveExpression = true;
        }

      } else {
        // Set/Update
        request.ExpressionAttributeValues[propNameExpressionValue] =
          value;

        if(hasSetExpression) {
          // Subsequent element
          setExpression += ", " + propNameExpressionName + " = " +
            propNameExpressionValue + "";
        } else {
          setExpression = "SET " + propNameExpressionName + " = " +
            propNameExpressionValue + "";
          hasSetExpression = true;
        }
      }
    }
  });

  if(isEmpty(request.ExpressionAttributeNames)) {
    delete request.ExpressionAttributeNames;
  }

  if(isEmpty(request.ExpressionAttributeValues)) {
    delete request.ExpressionAttributeValues;
  }

  if(hasSetExpression && hasRemoveExpression) {
    request.UpdateExpression = removeExpression.trim() + " " + setExpression.trim();
  } else
  if(hasSetExpression) {
    request.UpdateExpression = setExpression.trim();
  } else
  if(hasRemoveExpression) {
    request.UpdateExpression = removeExpression.trim();
  }

  return request;
};

// make sure the ES5 Array.isArray() method exists
if(!Array.isArray) {
  Array.isArray = function (arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
  };
}

function emptyArrays(data) {
  for(var key in data) {
    if(key !== undefined) {
      // console.log("key: ", key);
      var item = data[key];
      if(item !== undefined && Array.isArray(item)) {
        // see if the array is empty
        // remove this item from the parent object
        // console.log("deleting the item:" + JSON.stringify(item));
        data[key] = [];
        // if this item is an object, then recurse into it
        // to remove empty arrays in it too
      } else if(item !== undefined && typeof item === "object") {
        emptyArrays(item);
      }
    }
  }
}

exports.generateRemoveExpression = function (original, removes, itemUniqueId) {
  return removeExpressionGenerator(original, removes, deepDiffMapper.map(
    removes, original), null, itemUniqueId);
};

exports.generateUpdateExpression = function (original, updates, options) {

  if(options && options.arrayMerge && options.arrayMerge === "replaceMerge") {
    emptyArrays(original);
    delete options.arrayMerge;
  }

  var merged = merge(original, updates);

  return updateExpressionGenerator(deepDiffMapper.map(
    original, merged
  ), options, null);
};

module.exports = {
  getRemoveExpression: exports.generateRemoveExpression,
  getUpdateExpression: exports.generateUpdateExpression
};
<|endoftext|>


<commit_before>/**
 * Module dependencies
 */

var xhr = require('xhr');
var EventSource = require('./eventsource');
var XHRPolling = require('./xhrpolling');
var utils = require('./utils');
var status = utils.status;

/**
 * Expose Bullet
 */

module.exports = Bullet;

/**
 * Defaults
 */

var DELAY_DEFAULT = 80;
var DELAY_MAX = 10000;

var TRANSPORTS = [
  'websocket',
  'eventsource',
  'xhrpolling'
];

/**
 * Bullet
 *
 * @param {String} url
 * @param {Object} options
 */

function Bullet(url, opts) {
  if (!(this instanceof Bullet)) return new Bullet(url, opts);
  opts = opts || {};

  this.url = url;
  this.delay = DELAY_DEFAULT;
  this.transports = opts.transports || TRANSPORTS;
  this.init();
}

/**
 * Noops
 */

utils.handlers(Bullet.prototype);
Bullet.prototype.onheartbeat = noop;
Bullet.prototype.ondisconnect = noop;
function noop() {}

/**
 * Set the connection url
 *
 * The connection will automatically be reloaded
 *
 * @param {String} url
 * @return {Bullet}
 * @api public
 */

Bullet.prototype.setURL = function(url) {
  this.url = url;
  if (this.transport) this.transport.close();
  return this;
};

/**
 * Send data over the socket
 *
 * @param {String} data
 * @api public
 */

Bullet.prototype.send = function(data) {
  if (!this.transport) return false;
  return this.transport.send(data);
};

/**
 * Close the socket connection
 *
 * @return {Bullet}
 * @api public
 */

Bullet.prototype.close = function() {
  this.readyState = status.CLOSING;
  if (this.transport) this.transport.close();
  return this;
};

/**
 * Initialize the connection
 *
 * @api private
 */

Bullet.prototype.init = function() {
  var self = this;
  var Transport = getTransport(self.transports, self.cursor);

  if (!Transport) {
    delete self.cursor;
    self.ondisconnect();

    setTimeout(function() {self.init();}, DELAY_MAX);
    return false;
  }

  var t = self.transport = new Transport(self.url);
  self.cursor = t.__cursor;

  t.onopen = function() {
    if (t.heart) self.heartbeat = setInterval(function() {self.onheartbeat();}, 20000);
    if (self.readyState === status.OPEN) return;
    self.delay = DELAY_DEFAULT;
    self.readyState = status.OPEN;
    self.onopen();
  };

  t.onerror = t.onclose = function() {
    if (self.readyState === status.CLOSED || !t) return;
    var prev = t.__cursor;
    delete self.transport;
    t = null;
    clearInterval(self.heartbeat);

    if (self.readyState === status.CLOSING) {
      self.readyState = status.CLOSED;
      return self.onclose();
    }

    var delay = self.delay *= 2;
    if (delay > DELAY_MAX) delay = self.delay = DELAY_MAX;

    // try the next transport - this one disconnected while connecting
    if (self.readyState === status.CONNECTING) {
      self.cursor = prev + 1;
      delay = self.delay = DELAY_DEFAULT;
    }

    setTimeout(function() {self.init();}, delay);
  };

  t.onmessage = function(e) {
    self.onmessage(e);
  };
};

/**
 * Feature detection
 */

function getTransport(acceptable, i) {
  if (typeof i === 'undefined') i = 0;
  if (acceptable.length <= i) return false;

  var key = acceptable[i];
  if (typeof key === 'function') return function(url) {
    var t = new key(url);
    t.__cursor = i;
    return t;
  };

  var transport = transports[key];
  var Transport;
  if (transport && (Transport = transport())) return function(url) {
    var t = new Transport(url);
    t.__cursor = i;
    return t;
  };

  return getTransport(acceptable, i + 1);
}

var transports = {
  websocket: function () {
    var transport = window.WebSocket || window.MozWebSocket;
    if (!transport) return false;
    transport.prototype.heart = true;
    return transport;
  },
  eventsource: function() {
    if (!window.EventSource) return false;
    return EventSource;
  },
  xhrpolling: function() {
    return XHRPolling;
  }
};
<commit_msg>more cleanup<commit_after>/**
 * Module dependencies
 */

var xhr = require('xhr');
var EventSource = require('./eventsource');
var XHRPolling = require('./xhrpolling');
var utils = require('./utils');
var status = utils.status;

/**
 * Expose Bullet
 */

module.exports = Bullet;

/**
 * Defaults
 */

var DELAY_DEFAULT = 80;
var DELAY_MAX = 10000;

var TRANSPORTS = [
  'websocket',
  'eventsource',
  'xhrpolling'
];

/**
 * Bullet
 *
 * @param {String} url
 * @param {Object} options
 */

function Bullet(url, opts) {
  if (!(this instanceof Bullet)) return new Bullet(url, opts);
  opts = opts || {};

  this.url = url;
  this.delay = DELAY_DEFAULT;
  this.transports = opts.transports || TRANSPORTS;
  this.init();
}

/**
 * Noops
 */

utils.handlers(Bullet.prototype);
Bullet.prototype.onheartbeat = noop;
Bullet.prototype.ondisconnect = noop;
function noop() {}

/**
 * Set the connection url
 *
 * The connection will automatically be reloaded
 *
 * @param {String} url
 * @return {Bullet}
 * @api public
 */

Bullet.prototype.setURL = function(url) {
  this.url = url;
  if (this.transport) this.transport.close();
  return this;
};

/**
 * Send data over the socket
 *
 * @param {String} data
 * @api public
 */

Bullet.prototype.send = function(data) {
  if (!this.transport) return false;
  return this.transport.send(data);
};

/**
 * Close the socket connection
 *
 * @return {Bullet}
 * @api public
 */

Bullet.prototype.close = function() {
  this.readyState = status.CLOSING;
  if (this.transport) this.transport.close();
  return this;
};

/**
 * Initialize the connection
 *
 * @api private
 */

Bullet.prototype.init = function() {
  var self = this;
  var Transport = getTransport(self.transports, self.cursor);

  if (!Transport) {
    delete self.cursor;
    self.ondisconnect();

    setTimeout(function() {self.init();}, DELAY_MAX);
    return false;
  }

  var t = self.transport = new Transport(self.url);
  self.cursor = t.__cursor;

  t.onopen = function() {
    if (t.heart) t.heart = setInterval(function() {self.onheartbeat();}, 20000);
    if (self.readyState === status.OPEN) return;
    self.delay = DELAY_DEFAULT;
    self.readyState = status.OPEN;
    self.onopen();
  };

  t.onerror = t.onclose = function() {
    if (self.readyState === status.CLOSED || !t) return;
    var prev = t.__cursor;
    clearInterval(t.heart);

    delete self.transport;
    t = null;

    if (self.readyState === status.CLOSING) {
      self.readyState = status.CLOSED;
      return self.onclose();
    }

    var delay = self.delay *= 2;
    if (delay > DELAY_MAX) delay = self.delay = DELAY_MAX;

    // try the next transport - this one disconnected while connecting
    if (self.readyState === status.CONNECTING) {
      self.cursor = prev + 1;
      delay = self.delay = DELAY_DEFAULT;
    }

    setTimeout(function() {self.init();}, delay);
  };

  t.onmessage = function(e) {
    self.onmessage(e);
  };
};

/**
 * Feature detection
 */

function getTransport(acceptable, i) {
  if (typeof i === 'undefined') i = 0;
  if (acceptable.length <= i) return false;

  var key = acceptable[i];
  if (typeof key === 'function') return function(url) {
    var t = new key(url);
    t.__cursor = i;
    return t;
  };

  var transport = transports[key];
  var Transport;
  if (transport && (Transport = transport())) return function(url) {
    var t = new Transport(url);
    t.__cursor = i;
    return t;
  };

  return getTransport(acceptable, i + 1);
}

var transports = {
  websocket: function () {
    var transport = window.WebSocket || window.MozWebSocket;
    if (!transport) return false;
    transport.prototype.heart = true;
    return transport;
  },
  eventsource: function() {
    if (!window.EventSource) return false;
    return EventSource;
  },
  xhrpolling: function() {
    return XHRPolling;
  }
};
<|endoftext|>


<commit_before>var express = require("express"),
  bodyParser = require('body-parser'),
  pjson = require('./package.json'),
  git = require('git-rev-sync'),
  koop = require('./lib');

module.exports = function( config ) {
  var app = express(), route, controller, model;

  // keep track of the registered services
  app.services = [];

  koop.config = config;

  // init the koop log based on config params
  koop.log = new koop.Logger( config );

  // log every request
  //app.use(function(req, res, next) {
    //koop.log.debug("%s %s", req.method, req.url);
    //next();
  //});

  // store the sha so we know what version of koop this is
  app.status = {
    version: pjson.version,
    sha: git.long(),
    providers: {}
  };

  // handle POST requests
  app.use(bodyParser());

  app.set('view engine', 'ejs');

  // serve the index
  app.get("/", function(req, res, next) {
    res.render(__dirname + '/views/index');
  });

  // serve the index
  app.get("/services", function(req, res, next) {
    res.json(app.services);
  });

  // register providers into the app
  // sets up models, routes -> controllers/handlers
  app.register = function(provider){
    // only register if the provider has a name
    if ( provider.name ) {
      app.services.push( provider.name );

      // save the provider onto the app
      model = new provider.model( koop );

      // pass the model to the controller
      controller = new provider.controller( model );

      // if a provider has a status object store it
      if ( provider.status ) {
        app.status.providers[provider.name] = provider.status;
      }

      // binds a series of standard routes
      if ( provider.name && provider.pattern ) {
        app._bindDefaultRoutes(provider.name, provider.pattern, controller );
      }

      // add each route, the routes let us override defaults etc.
      app._bindRoutes( provider.routes, controller );
    }
  };

  var defaultRoutes = {
    'featureserver': ['/FeatureServer/:layer/:method', '/FeatureServer/:layer', '/FeatureServer'],
    'preview':['/preview'],
    'drop':['/drop']
  };

  // assigns a series of default routes; assumes
  app._bindDefaultRoutes = function( name, pattern, controller ){
    var routes, handler;
    for ( handler in defaultRoutes ){
      if ( controller[ handler ] ){
        defaultRoutes[ handler ].forEach(function(route){
          app[ 'get' ]( '/'+ name + pattern + route, controller[ handler ]);
        });
      }
    }
  };

  // bind each route in a list to controller handler
  app._bindRoutes = function( routes, controller ){
    for ( route in routes ){
      var path = route.split(' ');
      app[ path[0] ]( path[1], controller[ routes[ route ] ]);
    }
  };

  // init koop centralized file access
  // this allows us to turn the FS access off globally
  koop.files = new koop.Files( koop );
  koop.tiles = new koop.Tiles( koop );
  koop.thumbnail = new koop.Thumbnail( koop );
  // Need the exporter to have access to the cache so we pass it Koop
  koop.exporter = new koop.Exporter( koop );
  koop.Cache = new koop.DataCache( koop );

  // Start the Cache DB with the conn string from config
  if ( config && config.db ) {
    if ( config.db.postgis ) {
      koop.Cache.db = koop.PostGIS.connect( config.db.postgis.conn );
    } else if ( config && config.db.sqlite ) {
      koop.Cache.db = koop.SQLite.connect( config.db.sqlite );
    }
    koop.Cache.db.log = koop.log;
  } else if (config && !config.db){
    console.log('Exiting since no DB configuration found in config');
    process.exit();
  }

  return app;

};
<commit_msg>change /services to /providers<commit_after>var express = require("express"),
  bodyParser = require('body-parser'),
  pjson = require('./package.json'),
  git = require('git-rev-sync'),
  koop = require('./lib');

module.exports = function( config ) {
  var app = express(), route, controller, model;

  // keep track of the registered services
  app.services = [];

  koop.config = config;

  // init the koop log based on config params
  koop.log = new koop.Logger( config );

  // log every request
  //app.use(function(req, res, next) {
    //koop.log.debug("%s %s", req.method, req.url);
    //next();
  //});

  // store the sha so we know what version of koop this is
  app.status = {
    version: pjson.version,
    sha: git.long(),
    providers: {}
  };

  // handle POST requests
  app.use(bodyParser());

  app.set('view engine', 'ejs');

  // serve the index
  app.get("/", function(req, res, next) {
    res.render(__dirname + '/views/index');
  });

  // serve the index
  app.get("/providers", function(req, res, next) {
    res.json(app.services);
  });

  // register providers into the app
  // sets up models, routes -> controllers/handlers
  app.register = function(provider){
    // only register if the provider has a name
    if ( provider.name ) {
      app.services.push( provider.name );

      // save the provider onto the app
      model = new provider.model( koop );

      // pass the model to the controller
      controller = new provider.controller( model );

      // if a provider has a status object store it
      if ( provider.status ) {
        app.status.providers[provider.name] = provider.status;
      }

      // binds a series of standard routes
      if ( provider.name && provider.pattern ) {
        app._bindDefaultRoutes(provider.name, provider.pattern, controller );
      }

      // add each route, the routes let us override defaults etc.
      app._bindRoutes( provider.routes, controller );
    }
  };

  var defaultRoutes = {
    'featureserver': ['/FeatureServer/:layer/:method', '/FeatureServer/:layer', '/FeatureServer'],
    'preview':['/preview'],
    'drop':['/drop']
  };

  // assigns a series of default routes; assumes
  app._bindDefaultRoutes = function( name, pattern, controller ){
    var routes, handler;
    for ( handler in defaultRoutes ){
      if ( controller[ handler ] ){
        defaultRoutes[ handler ].forEach(function(route){
          app[ 'get' ]( '/'+ name + pattern + route, controller[ handler ]);
        });
      }
    }
  };

  // bind each route in a list to controller handler
  app._bindRoutes = function( routes, controller ){
    for ( route in routes ){
      var path = route.split(' ');
      app[ path[0] ]( path[1], controller[ routes[ route ] ]);
    }
  };

  // init koop centralized file access
  // this allows us to turn the FS access off globally
  koop.files = new koop.Files( koop );
  koop.tiles = new koop.Tiles( koop );
  koop.thumbnail = new koop.Thumbnail( koop );
  // Need the exporter to have access to the cache so we pass it Koop
  koop.exporter = new koop.Exporter( koop );
  koop.Cache = new koop.DataCache( koop );

  // Start the Cache DB with the conn string from config
  if ( config && config.db ) {
    if ( config.db.postgis ) {
      koop.Cache.db = koop.PostGIS.connect( config.db.postgis.conn );
    } else if ( config && config.db.sqlite ) {
      koop.Cache.db = koop.SQLite.connect( config.db.sqlite );
    }
    koop.Cache.db.log = koop.log;
  } else if (config && !config.db){
    console.log('Exiting since no DB configuration found in config');
    process.exit();
  }

  return app;

};
<|endoftext|>


<commit_before>var yadda = require('yadda');
var Filter = require('broccoli-filter');
var path = require('path');
var inflected = require( 'inflected' );

/* jshint node: true */
'use strict';

// voorbeeld van de brocolli-filter readme. bah en bah
FeatureParser.prototype = Object.create(Filter.prototype);
FeatureParser.prototype.constructor = FeatureParser;
function FeatureParser(inputNode, testFramework) {
  this.testFramework = testFramework;
  Filter.call(this, inputNode);
}
FeatureParser.prototype.extensions = ['feature', 'spec', 'specification'];
FeatureParser.prototype.targetExtension = 'js';
FeatureParser.prototype.processString = function(content, relativePath) {
  var feature = new yadda.parsers.FeatureParser().parse(content);
  var basePath = relativePath.split('/').slice(0,2).join('/');
  var nestedPath = relativePath.split('/').length > 4 ? relativePath.split('/').slice(3,-1).join('/') + '/' : '';
  var fileName = relativePath.split('/').slice(-1)[0].split('.')[0]; //remove extension

  var unitIndex = relativePath.split('/').indexOf('unit');
  var testType = unitIndex === -1? 'acceptance' : 'unit'; // Find if the current test is an acceptance or unit test
  var unitType = testType === 'unit'? relativePath.split('/').slice(unitIndex+1,unitIndex+2)[0] : false;
  var unitModule = testType === 'unit'? inflected.singularize(unitType)+':'+fileName : false;
  var stepsPath = basePath + "/"+testType+"/steps/" ;

  var head = [
    "import Ember from 'ember';",
    this.getTestFrameworkImport(),
    "import yadda from '" + basePath + "/helpers/yadda';",
    "import * as library from '" + stepsPath + nestedPath + fileName + "-steps';",
    "import startApp from '" + basePath + "/helpers/start-app';",
    "",
    this.getTestFeature(unitModule, fileName),
    "",
    "testFeature("
  ].join('\n');
  var foot = ');';

  return head + JSON.stringify(feature, null, 2) + foot;
};
FeatureParser.prototype.getDestFilePath = function (relativePath) {
  var ext = path.extname(relativePath);
  if(ext === '.feature' || ext === '.spec' || ext === '.specifiation') {
    return relativePath.replace(ext, '-test.js');
  }
  return null;
};
FeatureParser.prototype.getTestFrameworkImport = function() {
  switch (this.testFramework) {
    case 'mocha':
      return 'import { afterEach, beforeEach, describe, it } from \'mocha\';';
    default: // qunit
      return 'import { moduleFor, moduleForComponent, test } from \'ember-qunit\';\
              import {module} from \'qunit\';';
  }
};
FeatureParser.prototype.getTestFeature = function(unitModule,fileName ) {
  var testFeature;
  switch (this.testFramework) {
    case 'mocha':
      testFeature = [
        "function testFeature(feature) {",
        "  describe(`Feature: ${feature.title}`, () => {",
        "    beforeEach(function() {",
        "      this.application = startApp();",
        "    });",
        "    afterEach(function() {",
        "      Ember.run(this.application, 'destroy');",
        "    });",
        "    ",
        "    feature.scenarios.forEach(function(scenario) {",
        "      it(`Scenario: ${scenario.title}`, function() {",
        "        return new Ember.RSVP.Promise(function(resolve) { yadda.Yadda(library.default(), this).yadda(scenario.steps, { ctx: {} }, resolve); });",
        "      });",
        "    });",
        "  });",
        "};"
      ];
      break;
    default: // qunit
      if(unitModule && unitModule.indexOf('component') === 0){
        testFeature = [
          "function testFeature(feature) {",
          "  moduleForComponent('"+fileName+"', `Feature: ${feature.title}`,{",
          "     unit:true,",
          "     needs: feature.annotations.needs? feature.annotations.needs.split(',') : [],",
          "});",

          "  feature.scenarios.forEach(function(scenario) {",
          "    test(`Scenario: ${scenario.title}`, function(assert) {",
          "      expect(scenario.steps.length);",
          "      let self = this;",
          "      return new Ember.RSVP.Promise(function(resolve){ yadda.Yadda(library.default(assert), self).yadda(scenario.steps, { ctx: {} }, resolve); });",
          "    });",
          "  });",
          "};"
        ];
      }else if(unitModule && unitModule.indexOf('model') === 0){
        // TODO: Implement unit test for models
        // use moduleForModel
      }else if(unitModule){
        // TODO: Implement unit test for generic classes
        // use moduleFor
      }else{
        testFeature = [
          "function testFeature(feature) {",
          "  module(`Feature: ${feature.title}`, {",
          "    beforeEach: function() {",
          "      this.application = startApp();",
          "    },",
          "    afterEach: function() {",
          "      Ember.run(this.application, 'destroy');",
          "    }",
          "  });",

          "  feature.scenarios.forEach(function(scenario) {",
          "    test(`Scenario: ${scenario.title}`, function(assert) {",
          "      expect(scenario.steps.length);",
          "      return new Ember.RSVP.Promise(function (resolve) { yadda.Yadda(library.default(assert), this).yadda(scenario.steps, { ctx: {} }, resolve); });",
          "    });",
          "  });",
          "};"
        ];
      }

  }
  return testFeature.join('\n');
};

module.exports = {
  name: 'ember-cli-yadda',
  getTestFramework: function() {
    var packages = Object.keys(this.project.addonPackages);
    if (packages.indexOf('ember-cli-mocha') > -1) {
      return 'mocha';
    } else {
      return 'qunit';
    }
  },
  setupPreprocessorRegistry: function(type, registry) {
    var testFramework = this.getTestFramework();
    registry.add('js', {
      name: 'ember-cli-yadda',
      ext: ['feature', 'spec', 'specification'],
      toTree: function(tree, inputPath, outputPath) {
        return new FeatureParser(tree, testFramework);
      }
    });
  },
  blueprintsPath: function() {
    return path.join(__dirname, 'blueprints', this.getTestFramework());
  },
  included: function(app) {
    this._super.included(app);
    app.import(app.bowerDirectory + '/yadda/dist/yadda-0.15.4.js', { type: 'test' });
  },
  isDevelopingAddon: function() {
   return true;
  }
};
<commit_msg>refactor(index): Whitespace fixes<commit_after>var yadda = require('yadda');
var Filter = require('broccoli-filter');
var path = require('path');
var inflected = require('inflected');

/* jshint node: true */
'use strict';

// voorbeeld van de brocolli-filter readme. bah en bah
FeatureParser.prototype = Object.create(Filter.prototype);
FeatureParser.prototype.constructor = FeatureParser;
function FeatureParser(inputNode, testFramework) {
  this.testFramework = testFramework;
  Filter.call(this, inputNode);
}
FeatureParser.prototype.extensions = ['feature', 'spec', 'specification'];
FeatureParser.prototype.targetExtension = 'js';
FeatureParser.prototype.processString = function(content, relativePath) {
  var feature = new yadda.parsers.FeatureParser().parse(content);
  var basePath = relativePath.split('/').slice(0,2).join('/');
  var nestedPath = relativePath.split('/').length > 4 ? relativePath.split('/').slice(3,-1).join('/') + '/' : '';
  var fileName = relativePath.split('/').slice(-1)[0].split('.')[0]; //remove extension

  var unitIndex = relativePath.split('/').indexOf('unit');
  var testType = unitIndex === -1? 'acceptance' : 'unit'; // Find if the current test is an acceptance or unit test
  var unitType = testType === 'unit'? relativePath.split('/').slice(unitIndex+1,unitIndex+2)[0] : false;
  var unitModule = testType === 'unit'? inflected.singularize(unitType)+':'+fileName : false;
  var stepsPath = basePath + "/"+testType+"/steps/" ;

  var head = [
    "import Ember from 'ember';",
    this.getTestFrameworkImport(),
    "import yadda from '" + basePath + "/helpers/yadda';",
    "import * as library from '" + stepsPath + nestedPath + fileName + "-steps';",
    "import startApp from '" + basePath + "/helpers/start-app';",
    "",
    this.getTestFeature(unitModule, fileName),
    "",
    "testFeature("
  ].join('\n');
  var foot = ');';

  return head + JSON.stringify(feature, null, 2) + foot;
};
FeatureParser.prototype.getDestFilePath = function (relativePath) {
  var ext = path.extname(relativePath);
  if(ext === '.feature' || ext === '.spec' || ext === '.specifiation') {
    return relativePath.replace(ext, '-test.js');
  }
  return null;
};
FeatureParser.prototype.getTestFrameworkImport = function() {
  switch (this.testFramework) {
    case 'mocha':
      return 'import { afterEach, beforeEach, describe, it } from \'mocha\';';
    default: // qunit
      return 'import { moduleFor, moduleForComponent, test } from \'ember-qunit\';\
              import { module } from \'qunit\';';
  }
};
FeatureParser.prototype.getTestFeature = function(unitModule,fileName) {
  var testFeature;
  switch (this.testFramework) {
    case 'mocha':
      testFeature = [
        "function testFeature(feature) {",
        "  describe(`Feature: ${feature.title}`, () => {",
        "    beforeEach(function() {",
        "      this.application = startApp();",
        "    });",
        "    afterEach(function() {",
        "      Ember.run(this.application, 'destroy');",
        "    });",
        "    ",
        "    feature.scenarios.forEach(function(scenario) {",
        "      it(`Scenario: ${scenario.title}`, function() {",
        "        return new Ember.RSVP.Promise(function(resolve) { yadda.Yadda(library.default(), this).yadda(scenario.steps, { ctx: {} }, resolve); });",
        "      });",
        "    });",
        "  });",
        "};"
      ];
      break;
    default: // qunit
      if(unitModule && unitModule.indexOf('component') === 0) {
        testFeature = [
          "function testFeature(feature) {",
          "  moduleForComponent('"+fileName+"', `Feature: ${feature.title}`, {",
          "     unit:true,",
          "     needs: feature.annotations.needs? feature.annotations.needs.split(',') : [],",
          "});",

          "  feature.scenarios.forEach(function(scenario) {",
          "    test(`Scenario: ${scenario.title}`, function(assert) {",
          "      expect(scenario.steps.length);",
          "      let self = this;",
          "      return new Ember.RSVP.Promise(function(resolve){ yadda.Yadda(library.default(assert), self).yadda(scenario.steps, { ctx: {} }, resolve); });",
          "    });",
          "  });",
          "};"
        ];
      } else if(unitModule && unitModule.indexOf('model') === 0) {
        // TODO: Implement unit test for models
        // use moduleForModel
      } else if(unitModule) {
        // TODO: Implement unit test for generic classes
        // use moduleFor
      } else {
        testFeature = [
          "function testFeature(feature) {",
          "  module(`Feature: ${feature.title}`, {",
          "    beforeEach: function() {",
          "      this.application = startApp();",
          "    },",
          "    afterEach: function() {",
          "      Ember.run(this.application, 'destroy');",
          "    }",
          "  });",

          "  feature.scenarios.forEach(function(scenario) {",
          "    test(`Scenario: ${scenario.title}`, function(assert) {",
          "      expect(scenario.steps.length);",
          "      return new Ember.RSVP.Promise(function (resolve) { yadda.Yadda(library.default(assert), this).yadda(scenario.steps, { ctx: {} }, resolve); });",
          "    });",
          "  });",
          "};"
        ];
      }
  }
  return testFeature.join('\n');
};

module.exports = {
  name: 'ember-cli-yadda',
  getTestFramework: function() {
    var packages = Object.keys(this.project.addonPackages);
    if (packages.indexOf('ember-cli-mocha') > -1) {
      return 'mocha';
    } else {
      return 'qunit';
    }
  },
  setupPreprocessorRegistry: function(type, registry) {
    var testFramework = this.getTestFramework();
    registry.add('js', {
      name: 'ember-cli-yadda',
      ext: ['feature', 'spec', 'specification'],
      toTree: function(tree, inputPath, outputPath) {
        return new FeatureParser(tree, testFramework);
      }
    });
  },
  blueprintsPath: function() {
    return path.join(__dirname, 'blueprints', this.getTestFramework());
  },
  included: function(app) {
    this._super.included(app);
    app.import(app.bowerDirectory + '/yadda/dist/yadda-0.15.4.js', { type: 'test' });
  },
  isDevelopingAddon: function() {
   return true;
  }
};
<|endoftext|>


<commit_before>var Crafty = require('craftyjs');
var keydown = require('keydown');
var Hammer = require('hammerjs');

// var dat = require('exdat');

var assets = {
	"images" : "assets/notion_logo.png"
};

var params = {
	scene: 'simple-touch'
}

var scenes = [
	'gravity',
	'simple-touch'
];
var sceneIndex = 0;

var dims;
var ctx;
var touchEvents;

// loading scene
Crafty.defineScene("loading", function() {
	Crafty.background("#000");
  Crafty.e("2D, Canvas, Text")
	  .attr({ w: 100, h: 20, x: 150, y: 120 })
	  .text("Loading")
	  .textColor("#FFFFFF");
});

//
// Balloon component
//
Crafty.c('Balloon', {
	init: function() {
		this.requires('2D, WebGL');

		// trigger the Offscreen event if balloon goes offscreen
		this.bind('Move', function(e) {
			if(e._y < 0) {
				this.trigger('Offscreen');
			}
		});

		// move on every frame
		this.bind('EnterFrame', this.move)

	},
	move: function(e) {
		this.y = this.y-1;
	},
	hit: function() {
		this.destroy();
		this.trigger('Hit');
	}
});

//
// Intro gravity scene
//
Crafty.defineScene("gravity",
	function init() {
	Crafty.background("rgb(150,200,255)");

	// logo
	var logo = Crafty.e('2D, WebGL, Image, Draggable, Gravity')
		.image('assets/notion_logo.png')
		.gravity('2D');
	  // .attr({x: dims.width/2-size/2, y: dims.height/2-size/2, w: size, h: size})

	// bottom platform
	var platform = Crafty.e('2D, WebGL, Color')
									.color(0, 255, 100, 1)
									.attr({x: 0, y: dims.height-5, w: dims.width, h: 10});
	},
	function uninit() {
		Crafty('2D').get().forEach(function(e) { e.destroy(); });
	}
);

//
// Simple touch interface scene
//

Crafty.defineScene("simple-touch",
	function init() {
		Crafty.background("rgb(150,200,255)");

		// var dims = getDims();

		var balloon;

		function createBalloon() {
			balloon = Crafty.e('2D, WebGL, Color, Touch, Mouse, Balloon');
			balloon
				.color('red')
				.attr({ w: 50, h: 50, x: Math.random()*dims.width, y: dims.height-50 })

			// check if balloon is offscreen
			balloon.bind("Offscreen", balloon.destroy);

			// create new balloon when balloon is destroyed
			balloon.bind("Hit", createBalloon);

			balloon.bind('MouseDown', balloon.hit );
			balloon.bind('TouchDown', balloon.hit );

		}

		createBalloon();
	},
	function uninit() {
		Crafty('2D').get().forEach(function(e) { e.destroy(); });
	}
);

function getDims() {

	if(!ctx) {
		Crafty.webgl.init();
		ctx = Crafty.webgl.context;
	}
	return { width: ctx.drawingBufferWidth, height: ctx.drawingBufferHeight };
}

// setup crafty
Crafty.init();
Crafty.enterScene("loading");

// var gui = new dat.GUI();
// gui.add(params, 'scene', ['gravity', 'simple-touch']).onChange(function(val) {
// 	Crafty.enterScene(val);
// });

function nextScene() {
	if(sceneIndex+1 < scenes.length) {
		sceneIndex++;
	} else {
		sceneIndex = 0;
	}
	Crafty.enterScene(scenes[sceneIndex]);
}

function previousScene() {
	if(sceneIndex-1 >= 0) {
		sceneIndex--;
	} else {
		sceneIndex = scenes.length-1;
	}
	Crafty.enterScene(scenes[sceneIndex]);
}

// load & go!
Crafty.load(assets, function() {
	dims = getDims();
	touchEvents = new Hammer(Crafty.stage.elem);
	Crafty.enterScene(scenes[sceneIndex]);

	// touch events
	touchEvents.on('swipeleft', previousScene);
	touchEvents.on('swiperight', nextScene);

	// mouse events
	keydown('<left>').on('pressed', previousScene);
	keydown('<right>').on('pressed', nextScene);

});
<commit_msg>Fix balloon hit event<commit_after>var Crafty = require('craftyjs');
var keydown = require('keydown');
var Hammer = require('hammerjs');

// var dat = require('exdat');

var assets = {
	"images" : "assets/notion_logo.png"
};

var params = {
	scene: 'simple-touch'
}

var scenes = [
	'gravity',
	'simple-touch'
];
var sceneIndex = 0;

var dims;
var ctx;
var touchEvents;

// loading scene
Crafty.defineScene("loading", function() {
	Crafty.background("#000");
  Crafty.e("2D, Canvas, Text")
	  .attr({ w: 100, h: 20, x: 150, y: 120 })
	  .text("Loading")
	  .textColor("#FFFFFF");
});

//
// Balloon component
//
Crafty.c('Balloon', {
	init: function() {
		this.requires('2D, WebGL');

		// trigger the Offscreen event if balloon goes offscreen
		this.bind('Move', function(e) {
			if(e._y < 0) {
				this.trigger('Offscreen');
			}
		});

		// move on every frame
		this.bind('EnterFrame', this.move)

	},
	move: function(e) {
		this.y = this.y-1;
	},
	hit: function() {
		this.trigger('Hit');
		this.destroy();
	}
});

//
// Intro gravity scene
//
Crafty.defineScene("gravity",
	function init() {
	Crafty.background("rgb(150,200,255)");

	// logo
	var logo = Crafty.e('2D, WebGL, Image, Draggable, Gravity')
		.image('assets/notion_logo.png')
		.gravity('2D');
	  // .attr({x: dims.width/2-size/2, y: dims.height/2-size/2, w: size, h: size})

	// bottom platform
	var platform = Crafty.e('2D, WebGL, Color')
									.color(0, 255, 100, 1)
									.attr({x: 0, y: dims.height-5, w: dims.width, h: 10});
	},
	function uninit() {
		Crafty('2D').get().forEach(function(e) { e.destroy(); });
	}
);

//
// Simple touch interface scene
//

Crafty.defineScene("simple-touch",
	function init() {
		Crafty.background("rgb(150,200,255)");

		// var dims = getDims();

		var balloon;

		function createBalloon() {
			balloon = Crafty.e('2D, WebGL, Color, Touch, Mouse, Balloon');
			balloon
				.color('red')
				.attr({ w: 50, h: 50, x: Math.random()*dims.width, y: dims.height-50 })

			// check if balloon is offscreen
			balloon.bind("Offscreen", balloon.destroy);

			// create new balloon when balloon is hit
			balloon.bind("Hit", createBalloon);

			balloon.bind('MouseDown', balloon.hit );
			balloon.bind('TouchDown', balloon.hit );

		}

		createBalloon();
	},
	function uninit() {
		Crafty('2D').get().forEach(function(e) { e.destroy(); });
	}
);

function getDims() {

	if(!ctx) {
		Crafty.webgl.init();
		ctx = Crafty.webgl.context;
	}
	return { width: ctx.drawingBufferWidth, height: ctx.drawingBufferHeight };
}

// setup crafty
Crafty.init();
Crafty.enterScene("loading");

// var gui = new dat.GUI();
// gui.add(params, 'scene', ['gravity', 'simple-touch']).onChange(function(val) {
// 	Crafty.enterScene(val);
// });

function nextScene() {
	if(sceneIndex+1 < scenes.length) {
		sceneIndex++;
	} else {
		sceneIndex = 0;
	}
	Crafty.enterScene(scenes[sceneIndex]);
}

function previousScene() {
	if(sceneIndex-1 >= 0) {
		sceneIndex--;
	} else {
		sceneIndex = scenes.length-1;
	}
	Crafty.enterScene(scenes[sceneIndex]);
}

// load & go!
Crafty.load(assets, function() {
	dims = getDims();
	touchEvents = new Hammer(Crafty.stage.elem);
	Crafty.enterScene(scenes[sceneIndex]);

	// touch events
	touchEvents.on('swipeleft', previousScene);
	touchEvents.on('swiperight', nextScene);

	// mouse events
	keydown('<left>').on('pressed', previousScene);
	keydown('<right>').on('pressed', nextScene);

});
<|endoftext|>