<commit_before>/**
 * Basic Finder Queries
 */

var usageError = require('../../utils/usageError'),
    utils = require('../../utils/helpers'),
    normalize = require('../../utils/normalize'),
    sorter = require('../../utils/sorter'),
    Deferred = require('../deferred'),
    Joins = require('./joins'),
    Operations = require('./operations'),
    Integrator = require('../integrator'),
    waterlineCriteria = require('waterline-criteria'),
    _ = require('lodash'),
    async = require('async'),
    hasOwnProperty = utils.object.hasOwnProperty;

module.exports = {

  /**
   * Find a single record that meets criteria
   *
   * @param {Object} criteria to search
   * @param {Function} callback
   * @return Deferred object if no callback
   */

  findOne: function(criteria, cb) {
    var self = this;

    if(typeof criteria === 'function') {
      cb = criteria;
      criteria = null;
    }

    // If the criteria is an array of objects, wrap it in an "or"
    if (Array.isArray(criteria) && _.all(criteria, function(crit) {return _.isObject(crit);})) {
      criteria = {or: criteria};
    }

    // Check if criteria is an integer or string and normalize criteria
    // to object, using the specified primary key field.
    criteria = normalize.expandPK(self, criteria);

    // Normalize criteria
    criteria = normalize.criteria(criteria);

    // Return Deferred or pass to adapter
    if(typeof cb !== 'function') {
      return new Deferred(this, this.findOne, criteria);
    }

    // Transform Search Criteria
    criteria = self._transformer.serialize(criteria);

    // If there was something defined in the criteria that would return no results, don't even
    // run the query and just return an empty result set.
    if(criteria === false) {
      return cb(null, null);
    }

    // Build up an operations set
    var operations = new Operations(self, criteria, 'findOne');

    // Run the operations
    operations.run(function(err, values) {
      if(err) return cb(err);
      if(!values.cache) return cb();

      // If no joins are used grab the only item from the cache and pass to the returnResults
      // function.
      if(!criteria.joins) {
        values = values.cache[self.identity];
        return returnResults(values);
      }

      // If the values are already combined, return the results
      if(values.combined) {
        return returnResults(values.cache[self.identity]);
      }

      // Find the primaryKey of the current model so it can be passed down to the integrator.
      // Use 'id' as a good general default;
      var primaryKey = 'id';

      Object.keys(self._schema.schema).forEach(function(key) {
        if(self._schema.schema[key].hasOwnProperty('primaryKey') && self._schema.schema[key].primaryKey) {
          primaryKey = key;
        }
      });

      // Perform in-memory joins
      Integrator(values.cache, criteria.joins, primaryKey, function(err, results) {
        if(err) return cb(err);
        if(!results) return cb();

        // We need to run one last check on the results using the criteria. This allows a self
        // association where we end up with two records in the cache both having each other as
        // embedded objects and we only want one result. However we need to filter any join criteria
        // out of the top level where query so that searchs by primary key still work.
        var tmpCriteria = _.cloneDeep(criteria.where);
        if(!tmpCriteria) tmpCriteria = {};

        criteria.joins.forEach(function(join) {
          if(!hasOwnProperty(join, 'alias')) return;

          // Check for `OR` criteria
          if(hasOwnProperty(tmpCriteria, 'or')) {
            tmpCriteria.or.forEach(function(search) {
              if(!hasOwnProperty(search, join.alias)) return;
              delete search[join.alias];
            });
            return;
          }

          if(!hasOwnProperty(tmpCriteria, join.alias)) return;
          delete tmpCriteria[join.alias];
        });

        // Pass results into Waterline-Criteria
        var _criteria = { where: tmpCriteria };
        results = waterlineCriteria('parent', { parent: results }, _criteria).results;

        results.forEach(function(res) {

          // Go Ahead and perform any sorts on the associated data
          criteria.joins.forEach(function(join) {
            if(!join.criteria) return;
            var c = normalize.criteria(join.criteria);
            if(!c.sort) return;

            var alias = join.alias;
            res[alias] = sorter(res[alias], c.sort);
          });
        });

        returnResults(results);
      });

      function returnResults(results) {

        if(!results) return cb();

        // Normalize results to an array
        if(!Array.isArray(results) && results) results = [results];

        // Unserialize each of the results before attempting any join logic on them
        var unserializedModels = [];
        results.forEach(function(result) {
          unserializedModels.push(self._transformer.unserialize(result));
        });

        var models = [];
        var joins = criteria.joins ? criteria.joins : [];
        var data = new Joins(joins, unserializedModels, self.identity, self._schema.schema, self.waterline.collections);

        // If `data.models` is invalid (not an array) return early to avoid getting into trouble.
        if (!data || !data.models || !data.models.forEach) {
          return cb(new Error('Values returned from operations set are not an array...'));
        }

        // Create a model for the top level values
        data.models.forEach(function(model) {
          models.push(new self._model(model, data.options));
        });

        cb(null, models[0]);
      }
    });
  },

  /**
   * Find All Records that meet criteria
   *
   * @param {Object} search criteria
   * @param {Object} options
   * @param {Function} callback
   * @return Deferred object if no callback
   */

  find: function(criteria, options, cb) {
    var self = this;

    var usage = utils.capitalize(this.identity) + '.find([criteria],[options]).exec(callback|switchback)';

    if(typeof criteria === 'function') {
      cb = criteria;
      criteria = null;
      options = null;
    }

    if(typeof options === 'function') {
      cb = options;
      options = null;
    }

    // If the criteria is an array of objects, wrap it in an "or"
    if (Array.isArray(criteria) && _.all(criteria, function(crit) {return _.isObject(crit);})) {
      criteria = {or: criteria};
    }

    // Check if criteria is an integer or string and normalize criteria
    // to object, using the specified primary key field.
    criteria = normalize.expandPK(self, criteria);

    // Normalize criteria
    criteria = normalize.criteria(criteria);

    // Validate Arguments
    if(typeof criteria === 'function' || typeof options === 'function') {
      return usageError('Invalid options specified!', usage, cb);
    }

    // Return Deferred or pass to adapter
    if(typeof cb !== 'function') {
      return new Deferred(this, this.find, criteria, options);
    }

    // If there was something defined in the criteria that would return no results, don't even
    // run the query and just return an empty result set.
    if(criteria === false) {
      return cb(null, []);
    }

    // Fold in options
    if(options === Object(options) && criteria === Object(criteria)) {
      criteria = _.extend({}, criteria, options);
    }

    // Transform Search Criteria
    if (!self._transformer) {
      throw new Error('Waterline can not access transformer-- maybe the context of the method is being overridden?');
    }

    criteria = self._transformer.serialize(criteria);

    // Build up an operations set
    var operations = new Operations(self, criteria, 'find');

    // Run the operations
    operations.run(function(err, values) {
      if(err) return cb(err);
      if(!values.cache) return cb();

      // If no joins are used grab current collection's item from the cache and pass to the returnResults
      // function.
      if(!criteria.joins) {
        values = values.cache[self.identity];
        return returnResults(values);
      }

      // If the values are already combined, return the results
      if(values.combined) {
        return returnResults(values.cache[self.identity]);
      }

      // Find the primaryKey of the current model so it can be passed down to the integrator.
      // Use 'id' as a good general default;
      var primaryKey = 'id';

      Object.keys(self._schema.schema).forEach(function(key) {
        if(self._schema.schema[key].hasOwnProperty('primaryKey') && self._schema.schema[key].primaryKey) {
          primaryKey = key;
        }
      });

      // Perform in-memory joins
      Integrator(values.cache, criteria.joins, primaryKey, function(err, results) {
        if(err) return cb(err);
        if(!results) return cb();

        // We need to run one last check on the results using the criteria. This allows a self
        // association where we end up with two records in the cache both having each other as
        // embedded objects and we only want one result. However we need to filter any join criteria
        // out of the top level where query so that searchs by primary key still work.
        var tmpCriteria = _.cloneDeep(criteria.where);
        if(!tmpCriteria) tmpCriteria = {};

        criteria.joins.forEach(function(join) {
          if(!hasOwnProperty(join, 'alias')) return;

          // Check for `OR` criteria
          if(hasOwnProperty(tmpCriteria, 'or')) {
            tmpCriteria.or.forEach(function(search) {
              if(!hasOwnProperty(search, join.alias)) return;
              delete search[join.alias];
            });
            return;
          }

          if(!hasOwnProperty(tmpCriteria, join.alias)) return;
          delete tmpCriteria[join.alias];
        });

        // Pass results into Waterline-Criteria
        var _criteria = { where: tmpCriteria };
        results = waterlineCriteria('parent', { parent: results }, _criteria).results;

        // Serialize values coming from an in-memory join before modelizing
        var _results = [];
        results.forEach(function(res) {

          // Go Ahead and perform any sorts on the associated data
          criteria.joins.forEach(function(join) {
            if(!join.criteria) return;
            var c = normalize.criteria(join.criteria);
            if(!c.sort) return;

            var alias = join.alias;
            res[alias] = sorter(res[alias], c.sort);
          });
        });

        returnResults(results);
      });

      function returnResults(results) {

        if(!results) return cb(null, []);

        // Normalize results to an array
        if(!Array.isArray(results) && results) results = [results];

        // Unserialize each of the results before attempting any join logic on them
        var unserializedModels = [];

        if(results) {
          results.forEach(function(result) {
            unserializedModels.push(self._transformer.unserialize(result));
          });
        }

        var models = [];
        var joins = criteria.joins ? criteria.joins : [];
        var data = new Joins(joins, unserializedModels, self.identity, self._schema.schema, self.waterline.collections);

        // NOTE:
        // If a "belongsTo" (i.e. HAS_FK) association is null, should it be transformed into
        // an empty array here?  That is not what is happening currently, and it can cause
        // unexpected problems when implementing the native join method as an adapter implementor.
        // ~Mike June 22, 2014

        // If `data.models` is invalid (not an array) return early to avoid getting into trouble.
        if (!data || !data.models || !data.models.forEach) {
          return cb(new Error('Values returned from operations set are not an array...'));
        }

        // Create a model for the top level values
        data.models.forEach(function(model) {
          models.push(new self._model(model, data.options));
        });

        cb(null, models);
      }

    });
  },

  where: function() {
    this.find.apply(this, Array.prototype.slice.call(arguments));
  },

  select: function() {
    this.find.apply(this, Array.prototype.slice.call(arguments));
  },

  /**
   * findAll
   * [[ Deprecated! ]]
   *
   * @param  {Object}   criteria
   * @param  {Object}   options
   * @param  {Function} cb
   */
  findAll: function(criteria, options, cb) {
    if(typeof criteria === 'function') {
      cb = criteria;
      criteria = null;
      options = null;
    }

    if(typeof options === 'function') {
      cb = options;
      options = null;
    }

    // Return Deferred or pass to adapter
    if(typeof cb !== 'function') {
      return new Deferred(this, this.findAll, criteria);
    }

    cb(new Error('In Waterline >= 0.9, findAll() has been deprecated in favor of find().' +
                '\nPlease visit the migration guide at http://sailsjs.org for help upgrading.'));
  }

};
<commit_msg>#860:  findOne(undefined).populate() returns error.<commit_after>/**
 * Basic Finder Queries
 */

var usageError = require('../../utils/usageError'),
    utils = require('../../utils/helpers'),
    normalize = require('../../utils/normalize'),
    sorter = require('../../utils/sorter'),
    Deferred = require('../deferred'),
    Joins = require('./joins'),
    Operations = require('./operations'),
    Integrator = require('../integrator'),
    waterlineCriteria = require('waterline-criteria'),
    _ = require('lodash'),
    async = require('async'),
    hasOwnProperty = utils.object.hasOwnProperty;

module.exports = {

  /**
   * Find a single record that meets criteria
   *
   * @param {Object} criteria to search
   * @param {Function} callback
   * @return Deferred object if no callback
   */

  findOne: function(criteria, cb) {
    var self = this;

    if(typeof criteria === 'function') {
      cb = criteria;
      criteria = null;
    }

    // If the criteria is an array of objects, wrap it in an "or"
    if (Array.isArray(criteria) && _.all(criteria, function(crit) {return _.isObject(crit);})) {
      criteria = {or: criteria};
    }

    // Check if criteria is an integer or string and normalize criteria
    // to object, using the specified primary key field.
    criteria = normalize.expandPK(self, criteria);

    // Normalize criteria
    criteria = normalize.criteria(criteria);

    // Return Deferred or pass to adapter
    if(typeof cb !== 'function') {
      return new Deferred(this, this.findOne, criteria);
    }

    // Transform Search Criteria
    criteria = self._transformer.serialize(criteria);

    // If there was something defined in the criteria that would return no results, don't even
    // run the query and just return an empty result set.
    if(criteria === false || criteria.where === null) {
      // Build Default Error Message
      var err = '.findOne() requires a criteria. If you want the first record try .find().limit(1)';
      return cb(err);
    }

    // Build up an operations set
    var operations = new Operations(self, criteria, 'findOne');

    // Run the operations
    operations.run(function(err, values) {
      if(err) return cb(err);
      if(!values.cache) return cb();

      // If no joins are used grab the only item from the cache and pass to the returnResults
      // function.
      if(!criteria.joins) {
        values = values.cache[self.identity];
        return returnResults(values);
      }

      // If the values are already combined, return the results
      if(values.combined) {
        return returnResults(values.cache[self.identity]);
      }

      // Find the primaryKey of the current model so it can be passed down to the integrator.
      // Use 'id' as a good general default;
      var primaryKey = 'id';

      Object.keys(self._schema.schema).forEach(function(key) {
        if(self._schema.schema[key].hasOwnProperty('primaryKey') && self._schema.schema[key].primaryKey) {
          primaryKey = key;
        }
      });

      // Perform in-memory joins
      Integrator(values.cache, criteria.joins, primaryKey, function(err, results) {
        if(err) return cb(err);
        if(!results) return cb();

        // We need to run one last check on the results using the criteria. This allows a self
        // association where we end up with two records in the cache both having each other as
        // embedded objects and we only want one result. However we need to filter any join criteria
        // out of the top level where query so that searchs by primary key still work.
        var tmpCriteria = _.cloneDeep(criteria.where);
        if(!tmpCriteria) tmpCriteria = {};

        criteria.joins.forEach(function(join) {
          if(!hasOwnProperty(join, 'alias')) return;

          // Check for `OR` criteria
          if(hasOwnProperty(tmpCriteria, 'or')) {
            tmpCriteria.or.forEach(function(search) {
              if(!hasOwnProperty(search, join.alias)) return;
              delete search[join.alias];
            });
            return;
          }

          if(!hasOwnProperty(tmpCriteria, join.alias)) return;
          delete tmpCriteria[join.alias];
        });

        // Pass results into Waterline-Criteria
        var _criteria = { where: tmpCriteria };
        results = waterlineCriteria('parent', { parent: results }, _criteria).results;

        results.forEach(function(res) {

          // Go Ahead and perform any sorts on the associated data
          criteria.joins.forEach(function(join) {
            if(!join.criteria) return;
            var c = normalize.criteria(join.criteria);
            if(!c.sort) return;

            var alias = join.alias;
            res[alias] = sorter(res[alias], c.sort);
          });
        });

        returnResults(results);
      });

      function returnResults(results) {

        if(!results) return cb();

        // Normalize results to an array
        if(!Array.isArray(results) && results) results = [results];

        // Unserialize each of the results before attempting any join logic on them
        var unserializedModels = [];
        results.forEach(function(result) {
          unserializedModels.push(self._transformer.unserialize(result));
        });

        var models = [];
        var joins = criteria.joins ? criteria.joins : [];
        var data = new Joins(joins, unserializedModels, self.identity, self._schema.schema, self.waterline.collections);

        // If `data.models` is invalid (not an array) return early to avoid getting into trouble.
        if (!data || !data.models || !data.models.forEach) {
          return cb(new Error('Values returned from operations set are not an array...'));
        }

        // Create a model for the top level values
        data.models.forEach(function(model) {
          models.push(new self._model(model, data.options));
        });

        cb(null, models[0]);
      }
    });
  },

  /**
   * Find All Records that meet criteria
   *
   * @param {Object} search criteria
   * @param {Object} options
   * @param {Function} callback
   * @return Deferred object if no callback
   */

  find: function(criteria, options, cb) {
    var self = this;

    var usage = utils.capitalize(this.identity) + '.find([criteria],[options]).exec(callback|switchback)';

    if(typeof criteria === 'function') {
      cb = criteria;
      criteria = null;
      options = null;
    }

    if(typeof options === 'function') {
      cb = options;
      options = null;
    }

    // If the criteria is an array of objects, wrap it in an "or"
    if (Array.isArray(criteria) && _.all(criteria, function(crit) {return _.isObject(crit);})) {
      criteria = {or: criteria};
    }

    // Check if criteria is an integer or string and normalize criteria
    // to object, using the specified primary key field.
    criteria = normalize.expandPK(self, criteria);

    // Normalize criteria
    criteria = normalize.criteria(criteria);

    // Validate Arguments
    if(typeof criteria === 'function' || typeof options === 'function') {
      return usageError('Invalid options specified!', usage, cb);
    }

    // Return Deferred or pass to adapter
    if(typeof cb !== 'function') {
      return new Deferred(this, this.find, criteria, options);
    }

    // If there was something defined in the criteria that would return no results, don't even
    // run the query and just return an empty result set.
    if(criteria === false) {
      return cb(null, []);
    }

    // Fold in options
    if(options === Object(options) && criteria === Object(criteria)) {
      criteria = _.extend({}, criteria, options);
    }

    // Transform Search Criteria
    if (!self._transformer) {
      throw new Error('Waterline can not access transformer-- maybe the context of the method is being overridden?');
    }

    criteria = self._transformer.serialize(criteria);

    // Build up an operations set
    var operations = new Operations(self, criteria, 'find');

    // Run the operations
    operations.run(function(err, values) {
      if(err) return cb(err);
      if(!values.cache) return cb();

      // If no joins are used grab current collection's item from the cache and pass to the returnResults
      // function.
      if(!criteria.joins) {
        values = values.cache[self.identity];
        return returnResults(values);
      }

      // If the values are already combined, return the results
      if(values.combined) {
        return returnResults(values.cache[self.identity]);
      }

      // Find the primaryKey of the current model so it can be passed down to the integrator.
      // Use 'id' as a good general default;
      var primaryKey = 'id';

      Object.keys(self._schema.schema).forEach(function(key) {
        if(self._schema.schema[key].hasOwnProperty('primaryKey') && self._schema.schema[key].primaryKey) {
          primaryKey = key;
        }
      });

      // Perform in-memory joins
      Integrator(values.cache, criteria.joins, primaryKey, function(err, results) {
        if(err) return cb(err);
        if(!results) return cb();

        // We need to run one last check on the results using the criteria. This allows a self
        // association where we end up with two records in the cache both having each other as
        // embedded objects and we only want one result. However we need to filter any join criteria
        // out of the top level where query so that searchs by primary key still work.
        var tmpCriteria = _.cloneDeep(criteria.where);
        if(!tmpCriteria) tmpCriteria = {};

        criteria.joins.forEach(function(join) {
          if(!hasOwnProperty(join, 'alias')) return;

          // Check for `OR` criteria
          if(hasOwnProperty(tmpCriteria, 'or')) {
            tmpCriteria.or.forEach(function(search) {
              if(!hasOwnProperty(search, join.alias)) return;
              delete search[join.alias];
            });
            return;
          }

          if(!hasOwnProperty(tmpCriteria, join.alias)) return;
          delete tmpCriteria[join.alias];
        });

        // Pass results into Waterline-Criteria
        var _criteria = { where: tmpCriteria };
        results = waterlineCriteria('parent', { parent: results }, _criteria).results;

        // Serialize values coming from an in-memory join before modelizing
        var _results = [];
        results.forEach(function(res) {

          // Go Ahead and perform any sorts on the associated data
          criteria.joins.forEach(function(join) {
            if(!join.criteria) return;
            var c = normalize.criteria(join.criteria);
            if(!c.sort) return;

            var alias = join.alias;
            res[alias] = sorter(res[alias], c.sort);
          });
        });

        returnResults(results);
      });

      function returnResults(results) {

        if(!results) return cb(null, []);

        // Normalize results to an array
        if(!Array.isArray(results) && results) results = [results];

        // Unserialize each of the results before attempting any join logic on them
        var unserializedModels = [];

        if(results) {
          results.forEach(function(result) {
            unserializedModels.push(self._transformer.unserialize(result));
          });
        }

        var models = [];
        var joins = criteria.joins ? criteria.joins : [];
        var data = new Joins(joins, unserializedModels, self.identity, self._schema.schema, self.waterline.collections);

        // NOTE:
        // If a "belongsTo" (i.e. HAS_FK) association is null, should it be transformed into
        // an empty array here?  That is not what is happening currently, and it can cause
        // unexpected problems when implementing the native join method as an adapter implementor.
        // ~Mike June 22, 2014

        // If `data.models` is invalid (not an array) return early to avoid getting into trouble.
        if (!data || !data.models || !data.models.forEach) {
          return cb(new Error('Values returned from operations set are not an array...'));
        }

        // Create a model for the top level values
        data.models.forEach(function(model) {
          models.push(new self._model(model, data.options));
        });

        cb(null, models);
      }

    });
  },

  where: function() {
    this.find.apply(this, Array.prototype.slice.call(arguments));
  },

  select: function() {
    this.find.apply(this, Array.prototype.slice.call(arguments));
  },

  /**
   * findAll
   * [[ Deprecated! ]]
   *
   * @param  {Object}   criteria
   * @param  {Object}   options
   * @param  {Function} cb
   */
  findAll: function(criteria, options, cb) {
    if(typeof criteria === 'function') {
      cb = criteria;
      criteria = null;
      options = null;
    }

    if(typeof options === 'function') {
      cb = options;
      options = null;
    }

    // Return Deferred or pass to adapter
    if(typeof cb !== 'function') {
      return new Deferred(this, this.findAll, criteria);
    }

    cb(new Error('In Waterline >= 0.9, findAll() has been deprecated in favor of find().' +
                '\nPlease visit the migration guide at http://sailsjs.org for help upgrading.'));
  }

};
<|endoftext|>


<commit_before>var vows = require('vows'),
    assert = require('assert'),
    _ = require('underscore'),
    toolbox = require('../../public/javascripts/toolbox'),
    fansi = require('../../public/javascripts/fansi'),
    fs = require('fs'),
    Set = require('set'),
    s = require('../../public/javascripts/s');

var suite = vows.describe('test_top');

var expected_results = [
    fansi.event.setspecg1,                      undefined,
    fansi.event.unknown7,                       '7',
    fansi.event.terminal_config_enable,         47,
    fansi.event.screen_scroll_enable,           [1, 27],
    fansi.event.select_graphic_rendition,       0,
    fansi.event.terminal_config_disable,        4,
    fansi.event.terminal_config_enable,         1,
    fansi.event.set_alternate_keypad_mode,      undefined,
    fansi.event.cursor_position,                [1, 1],
    fansi.event.erase_data,                     2,
    fansi.event.raw_text,                       'Processes: 58 total, 4 running, 54 sleeping, 289 threads',
    fansi.event.cursor_position,                [1,66],
    fansi.event.raw_text,                       '05:47:52\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       'Load Avg: 0.50, 0.37, 0.32\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       'CPU usage: 16.66% user, 50.0% sys, 33.33% idle\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       'SharedLibs: 6924K resident, 6688K data, 0B linkedit.\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       'MemRegions: 8618 total, 828M resident, 20M private, 289M shared.\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       'PhysMem: 674M wired, 1164M active, 511M inactive, 2349M used, 1747M free.\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       'VM: 128G vsize, 1042M framework vsize, 2451749(0) pageins, 182(0) pageouts',
    fansi.event.cursor_position,                [8,1],
    fansi.event.raw_text,                       'Networks: packets: 911737/825M in, 619037/109M out.\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       'Disks: 4193121/8413M read, 1082188/13G written.\r',
    fansi.event.cursor_down,                    2,
    fansi.event.raw_text,                       'PID    COMMAND',
    fansi.event.cursor_forward,                 6,
    fansi.event.raw_text,                       '%CPU TIME     #TH  #WQ  #PORT #MRE RPRVT  RSHRD\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '77100  top',
    fansi.event.cursor_position,                [12, 21],
    fansi.event.raw_text,                       '0.0  00:00.03 1/1  0    21+   32+  784K+  336K+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '77094  mdworker     0.0  00:00.10 3    1    48+   64+  2592K+ 15M+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '77084- Google Chrom 0.0  00:00.40 5    1    95+   173+ 13M+   81M+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '77066- Google Chrom 0.0  00:06.39 3    1    178+  376+ 15M+   99M+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '76883  zsh',
    fansi.event.cursor_position,                [16, 21],
    fansi.event.raw_text,                       '0.0  00:00.04 1    0    17+   44+  856K+  988K+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '76870  zsh',
    fansi.event.cursor_position,                [17, 21],
    fansi.event.raw_text,                       '0.0  00:00.07 1    0    17+   44+  868K+  988K+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '76869  login',
    fansi.event.cursor_position,                [18, 21],
    fansi.event.raw_text,                       '0.0  00:00.05 1    0    22+   53+  480K+  312K+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '76867  Terminal     0.0  00:02.27 5/1  1    108+  109+ 3364K+ 28M+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '76836- Google Chrom 0.0  00:02.39 6    2    97+   273+ 24M+   88M+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '76192  java',
    fansi.event.cursor_position,                [21, 21],
    fansi.event.raw_text,                       '0.0  62:00.95 29   1    505+  828+ 393M+  62M+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '76161- Google Chrom 0.0  00:11.51 5    1    96+   235+ 16M+   83M+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '75841- Google Chrom 0.0  01:28.35 3    1    107+  161+ 17M+   80M+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '75838- Google Chrom 0.0  00:05.64 5    1    96+   198+ 11M+   83M+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '75832- Google Chrom 0.0  06:04.24 17   1    1042+ 327+ 91M+   98M+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '70256  Firewall     0.0  00:00.00 1    0    27+   34+  380K+  248K+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '29319  activitymoni 0.0  10:12.30 1    0    29+   38+  1152K+ 280K+',
    fansi.event.cursor_position,                [27, 1],
    fansi.event.erase_data,                     2,
    fansi.event.terminal_config_disable,        47,
    '_unknown_8',                               '8',
    fansi.event.raw_text,                       '\r',
    fansi.event.terminal_config_disable,        1,
    '_unknown_>',                               '>'
];

var expected_events = [], expected_messages = [];
var pairs = toolbox.partition(2, expected_results);
// I freaking love underscore
expected_events = _.map(pairs, _.first);
expected_messages = _.map(pairs, _.last);

var do_stuff = function(callback, file) {
    var machine = new fansi.Machine();

    var actual_events = [], actual_messages = [];
    var callbacks = [];

    // s.debug_inspect({exp_events: expected_events, exp_msgs: expected_messages});

    _.each(Set.unique(expected_events),
        function(msg) {
            var sink = function(data) {
                // s.debug_inspect({me:this, data:data});

                actual_events.push(this.message);
                if (data.length > 1) {
                    actual_messages.push(data);
                } else {
                    actual_messages.push(data[0]);
                }

                // s.debug_inspect({act_events: actual_events, act_msgs: actual_messages});

                if (actual_events.length == expected_events.length) {
                    // s.debug_inspect({act_events: actual_events, act_msgs: actual_messages});
                    callback(null, [actual_events, actual_messages]);
                }
            };

            var handler = {
                message:msg,
                sink:sink
            };

            machine.on(handler.message, _.bind(handler.sink, handler));
        }
    );

    // start reading the data
    var go_time = function(err, data) {
        if (err) {
            callback(err, null);
        } else {
            machine.read(data.toString());
        }
    };
    fs.readFile(file, go_time);
};

var batch = {
    topic: function() { do_stuff(this.callback, 'test/data/top.raw'); },
    'got events': function(err, val) {
        if (err) {
            s.debug_inspect({err: err});
        }
        s.noisy_verify(val[0], expected_events);
    },
    'got messages': function(err, val) {
        if (err) {
            s.debug_inspect({err: err});
        }
        s.noisy_verify(val[1], expected_messages);
    }
}

suite.addBatch({'a thing': batch});

suite.export(module);
<commit_msg>death to spurious whitespace<commit_after>var vows = require('vows'),
    assert = require('assert'),
    _ = require('underscore'),
    toolbox = require('../../public/javascripts/toolbox'),
    fansi = require('../../public/javascripts/fansi'),
    fs = require('fs'),
    Set = require('set'),
    s = require('../../public/javascripts/s');

var suite = vows.describe('test_top');

var expected_results = [
    fansi.event.setspecg1,                      undefined,
    fansi.event.unknown7,                       '7',
    fansi.event.terminal_config_enable,         47,
    fansi.event.screen_scroll_enable,           [1, 27],
    fansi.event.select_graphic_rendition,       0,
    fansi.event.terminal_config_disable,        4,
    fansi.event.terminal_config_enable,         1,
    fansi.event.set_alternate_keypad_mode,      undefined,
    fansi.event.cursor_position,                [1, 1],
    fansi.event.erase_data,                     2,
    fansi.event.raw_text,                       'Processes: 58 total, 4 running, 54 sleeping, 289 threads',
    fansi.event.cursor_position,                [1,66],
    fansi.event.raw_text,                       '05:47:52\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       'Load Avg: 0.50, 0.37, 0.32\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       'CPU usage: 16.66% user, 50.0% sys, 33.33% idle\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       'SharedLibs: 6924K resident, 6688K data, 0B linkedit.\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       'MemRegions: 8618 total, 828M resident, 20M private, 289M shared.\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       'PhysMem: 674M wired, 1164M active, 511M inactive, 2349M used, 1747M free.\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       'VM: 128G vsize, 1042M framework vsize, 2451749(0) pageins, 182(0) pageouts',
    fansi.event.cursor_position,                [8,1],
    fansi.event.raw_text,                       'Networks: packets: 911737/825M in, 619037/109M out.\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       'Disks: 4193121/8413M read, 1082188/13G written.\r',
    fansi.event.cursor_down,                    2,
    fansi.event.raw_text,                       'PID    COMMAND',
    fansi.event.cursor_forward,                 6,
    fansi.event.raw_text,                       '%CPU TIME     #TH  #WQ  #PORT #MRE RPRVT  RSHRD\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '77100  top',
    fansi.event.cursor_position,                [12, 21],
    fansi.event.raw_text,                       '0.0  00:00.03 1/1  0    21+   32+  784K+  336K+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '77094  mdworker     0.0  00:00.10 3    1    48+   64+  2592K+ 15M+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '77084- Google Chrom 0.0  00:00.40 5    1    95+   173+ 13M+   81M+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '77066- Google Chrom 0.0  00:06.39 3    1    178+  376+ 15M+   99M+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '76883  zsh',
    fansi.event.cursor_position,                [16, 21],
    fansi.event.raw_text,                       '0.0  00:00.04 1    0    17+   44+  856K+  988K+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '76870  zsh',
    fansi.event.cursor_position,                [17, 21],
    fansi.event.raw_text,                       '0.0  00:00.07 1    0    17+   44+  868K+  988K+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '76869  login',
    fansi.event.cursor_position,                [18, 21],
    fansi.event.raw_text,                       '0.0  00:00.05 1    0    22+   53+  480K+  312K+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '76867  Terminal     0.0  00:02.27 5/1  1    108+  109+ 3364K+ 28M+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '76836- Google Chrom 0.0  00:02.39 6    2    97+   273+ 24M+   88M+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '76192  java',
    fansi.event.cursor_position,                [21, 21],
    fansi.event.raw_text,                       '0.0  62:00.95 29   1    505+  828+ 393M+  62M+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '76161- Google Chrom 0.0  00:11.51 5    1    96+   235+ 16M+   83M+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '75841- Google Chrom 0.0  01:28.35 3    1    107+  161+ 17M+   80M+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '75838- Google Chrom 0.0  00:05.64 5    1    96+   198+ 11M+   83M+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '75832- Google Chrom 0.0  06:04.24 17   1    1042+ 327+ 91M+   98M+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '70256  Firewall     0.0  00:00.00 1    0    27+   34+  380K+  248K+\r',
    fansi.event.cursor_down,                    1,
    fansi.event.raw_text,                       '29319  activitymoni 0.0  10:12.30 1    0    29+   38+  1152K+ 280K+',
    fansi.event.cursor_position,                [27, 1],
    fansi.event.erase_data,                     2,
    fansi.event.terminal_config_disable,        47,
    '_unknown_8',                               '8',
    fansi.event.raw_text,                       '\r',
    fansi.event.terminal_config_disable,        1,
    '_unknown_>',                               '>'
];

var expected_events = [], expected_messages = [];
var pairs = toolbox.partition(2, expected_results);
// I freaking love underscore
expected_events = _.map(pairs, _.first);
expected_messages = _.map(pairs, _.last);

var do_stuff = function(callback, file) {
    var machine = new fansi.Machine();

    var actual_events = [], actual_messages = [];
    var callbacks = [];

    // s.debug_inspect({exp_events: expected_events, exp_msgs: expected_messages});

    _.each(Set.unique(expected_events),
        function(msg) {
            var sink = function(data) {
                // s.debug_inspect({me:this, data:data});

                actual_events.push(this.message);
                if (data.length > 1) {
                    actual_messages.push(data);
                } else {
                    actual_messages.push(data[0]);
                }

                // s.debug_inspect({act_events: actual_events, act_msgs: actual_messages});

                if (actual_events.length == expected_events.length) {
                    // s.debug_inspect({act_events: actual_events, act_msgs: actual_messages});
                    callback(null, [actual_events, actual_messages]);
                }
            };

            var handler = {
                message:msg,
                sink:sink
            };

            machine.on(handler.message, _.bind(handler.sink, handler));
        }
    );

    // start reading the data
    var go_time = function(err, data) {
        if (err) {
            callback(err, null);
        } else {
            machine.read(data.toString());
        }
    };
    fs.readFile(file, go_time);
};

var batch = {
    topic: function() { do_stuff(this.callback, 'test/data/top.raw'); },
    'got events': function(err, val) {
        if (err) {
            s.debug_inspect({err: err});
        }
        s.noisy_verify(val[0], expected_events);
    },
    'got messages': function(err, val) {
        if (err) {
            s.debug_inspect({err: err});
        }
        s.noisy_verify(val[1], expected_messages);
    }
}

suite.addBatch({'a thing': batch});

suite.export(module);
<|endoftext|>


<commit_before>const request = require('request');

module.exports = function plugin(bot, info)
{
  'use strict';
  const plugin = {};
  function submit(options)
  {
    request.post(options, (err, response, body) =>
    {
      if(err)
      {
        console.log(err)
      }
      else
      {
       console.log(body);
      }
    });
  }
  function getInfo()
  {
    return new Promise((resolve, reject) =>
    {
      resolve({"server_count": Object.keys(bot.servers).length});
    });
  }
  plugin.updateBotLists = function()
  {
    getInfo().then((status) =>
    {
      console.log(status);
      let botsPW = {
      url: 'https://bots.discord.pw/api/bots/193403332046487552/stats',
      json: true,
      headers: {
        'Authorization': info.config.api.botsPW,
        'content-type': 'application/json'
      },
      body: JSON.stringify(status)
      }
      let botsOrg = {
        url: 'https://discordbots.org/api/bots/193403332046487552/stats',
        json: true,
        headers: {
          'Authorization': info.config.api.botsOrg
        },
        form: status
      }
      submit(botsOrg);
      submit(botsPW);
    });
  }

  return plugin;
}
<commit_msg>Let's try a different method.<commit_after>const request = require('request');

module.exports = function plugin(bot, info)
{
  'use strict';
  const plugin = {};
  function submit(options)
  {
    request(options, (err, response, body) =>
    {
      if(err)
      {
        console.log(err)
      }
      else
      {
       console.log(body);
      }
    });
  }
  function getInfo()
  {
    return new Promise((resolve, reject) =>
    {
      resolve({"server_count": Object.keys(bot.servers).length});
    });
  }
  plugin.updateBotLists = function()
  {
    getInfo().then((status) =>
    {
      let botsPW = {
      url: 'https://bots.discord.pw/api/bots/193403332046487552/stats',
      method: 'POST',
      headers: {
        'Authorization': info.config.api.botsPW,
        'content-type': 'application/json'
      },
      body: JSON.stringify(status)
      }
      let botsOrg = {
        url: 'https://discordbots.org/api/bots/193403332046487552/stats',
        method: 'POST',
        headers: {
          'Authorization': info.config.api.botsOrg
        },
        body: status
      }
      submit(botsOrg);
      submit(botsPW);
    });
  }

  return plugin;
}
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path');
var tty = require('tty');
var expect = require('chai').expect;

var ttycolor = require('../..');
var outlog = path.join(__dirname, '..', '..', 'log', 'out.log');
var errlog = path.join(__dirname, '..', '..', 'log', 'err.log');

var stdout = {reader: null, writer: null}, stderr = {reader: null, writer: null};

describe('ttycolor:', function() {
  beforeEach(function(done) {
    stdout.writer = fs.createWriteStream(outlog, {flags: 'w'});
    stdout.writer.on('open', function(fd) {
      stdout.reader = fs.createReadStream(outlog, 'r');
      stdout.reader.on('open', function(fd) {
        done();
      });
    });
  });
  it('should export properties', function(done) {
    expect(ttycolor.ansi).to.be.a('function');
    expect(ttycolor.attributes).to.be.an('object');
    expect(ttycolor.background).to.be.an('object');
    expect(ttycolor.colors).to.be.an('array');
    expect(ttycolor.console).to.be.an('object');
    expect(ttycolor.foreground).to.be.an('object');
    expect(ttycolor.stringify).to.be.a('function');
    done();
  });
  it('should write to stream', function(done) {
    var input = 'value';
    function cb(value) {
      expect(value).to.be.a('string').that.equals(input);
      stdout.writer.end();
      done();
    }
    console.write({stream: stdout.writer, callback: cb}, input);
  });
  it('should print empty string with no arguments', function(done) {
    function cb(value) {
      expect(value).to.be.a('string').that.equals('');
      stdout.writer.end();
      done();
    }
    console.write({stream: stdout.writer, callback: cb});
  });
  it('should return vanilla string', function(done) {
    var input = 'value';
    var result = ttycolor.debug('%s', input);
    expect(result).to.be.a('string').that.equals(input);
    done();
  });
  it('should return vanilla number', function(done) {
    var input = 3.14;
    var result = ttycolor.debug('%s', input);
    expect(result).to.be.a('string').that.equals('' + input);
    done();
  });
  it('should return vanilla json', function(done) {
    var input = {message: 'json'};
    var result = ttycolor.debug('%j', input);
    expect(result).to.be.a('string').that.equals(JSON.stringify(input));
    done();
  });
})
<commit_msg>Update tests.<commit_after>var fs = require('fs');
var path = require('path');
var tty = require('tty');
var expect = require('chai').expect;

var ttycolor = require('../..');
var outlog = path.join(__dirname, '..', '..', 'log', 'out.log');
var errlog = path.join(__dirname, '..', '..', 'log', 'err.log');

var stdout = {reader: null, writer: null},
  stderr = {reader: null, writer: null};

describe('ttycolor:', function() {
  beforeEach(function(done) {
    stdout.writer = fs.createWriteStream(outlog, {flags: 'w'});
    stdout.writer.on('open', function(fd) {
      done();
    });
  });
  it('should export properties', function(done) {
    expect(ttycolor.ansi).to.be.a('function');
    expect(ttycolor.attributes).to.be.an('object');
    expect(ttycolor.background).to.be.an('object');
    expect(ttycolor.colors).to.be.an('array');
    expect(ttycolor.console).to.be.an('object');
    expect(ttycolor.debug).to.be.a('function');
    expect(ttycolor.foreground).to.be.an('object');
    expect(ttycolor.stringify).to.be.a('function');
    done();
  });
  it('should write to stream', function(done) {
    var input = 'value';
    function cb(value) {
      expect(value).to.be.a('string').that.equals(input);
      stdout.writer.end();
      done();
    }
    console.write({stream: stdout.writer, callback: cb}, input);
  });
  it('should return empty string with no arguments', function(done) {
    var result = ttycolor.debug();
    expect(result).to.be.a('string').that.equals('');
    done();
  });
  it('should return vanilla string', function(done) {
    var input = 'value';
    var result = ttycolor.debug('%s', input);
    expect(result).to.be.a('string').that.equals(input);
    done();
  });
  it('should return vanilla number', function(done) {
    var input = 3.14;
    var result = ttycolor.debug('%s', input);
    expect(result).to.be.a('string').that.equals('' + input);
    done();
  });
  it('should return vanilla json', function(done) {
    var input = {message: 'json'};
    var result = ttycolor.debug('%j', input);
    expect(result).to.be.a('string').that.equals(JSON.stringify(input));
    done();
  });
})
<|endoftext|>


<commit_before>import test from 'ava';

import { grammar } from '../../src/grammar';

test('should parse simple link', (t) => {
  const link = 'test.md';
  const expect = {
    link: {
      url: 'test.md',
      placeholder: 'test.md',
      index: 0,
    },
    scopeReferences: [],
    descendantReferences: [],
  };

  const output = grammar.parse(link);

  t.deepEqual(output, expect);
});

test('should parse link with fallback', (t) => {
  const link = 'animal || fox.md';
  const expect = {
    link: {
      url: 'animal',
      placeholder: 'animal',
      index: 0,
    },
    scopeReferences: [{
      url: 'fox.md',
      placeholder: 'animal',
      index: 10,
    }],
    descendantReferences: [],
  };

  const output = grammar.parse(link);

  t.deepEqual(output, expect);
});

test('should parse link with references', (t) => {
  const link = 'animal vulpis:fox.md reset: singlestring:\'A\' doublestring:"B"';
  const expect = {
    link: {
      url: 'animal',
      placeholder: 'animal',
      index: 0,
    },
    scopeReferences: [],
    descendantReferences: [
      {
        url: 'fox.md',
        placeholder: 'vulpis',
        index: 14,
      },
      {
        url: '""',
        placeholder: 'reset',
        index: 27,
      },
      {
        url: '\'A\'',
        placeholder: 'singlestring',
        index: 41,
      },
      {
        url: '"B"',
        placeholder: 'doublestring',
        index: 58,
      },
    ],
  };

  const output = grammar.parse(link);

  t.deepEqual(output, expect);
});

test('should parse link with fallback and references', (t) => {
  const link = 'animal || fox.md canine:dog.md';
  const expect = {
    link: {
      url: 'animal',
      placeholder: 'animal',
      index: 0,
    },
    scopeReferences: [{
      url: 'fox.md',
      placeholder: 'animal',
      index: 10,
    }],
    descendantReferences: [{
      url: 'dog.md',
      placeholder: 'canine',
      index: 24,
    }],
  };

  const output = grammar.parse(link);

  t.deepEqual(output, expect);
});
<commit_msg>Update: add explicit test for dash within string transcludes<commit_after>import test from 'ava';

import { grammar } from '../../src/grammar';

test('should parse simple link', (t) => {
  const link = 'test.md';
  const expect = {
    link: {
      url: 'test.md',
      placeholder: 'test.md',
      index: 0,
    },
    scopeReferences: [],
    descendantReferences: [],
  };

  const output = grammar.parse(link);

  t.deepEqual(output, expect);
});

test('should parse link with fallback', (t) => {
  const link = 'animal || fox.md';
  const expect = {
    link: {
      url: 'animal',
      placeholder: 'animal',
      index: 0,
    },
    scopeReferences: [{
      url: 'fox.md',
      placeholder: 'animal',
      index: 10,
    }],
    descendantReferences: [],
  };

  const output = grammar.parse(link);

  t.deepEqual(output, expect);
});

test('should parse link with references', (t) => {
  const link = 'animal vulpis:fox.md reset: singlestring:\'foobar\' doublestring:"fizz-buzz"';
  const expect = {
    link: {
      url: 'animal',
      placeholder: 'animal',
      index: 0,
    },
    scopeReferences: [],
    descendantReferences: [
      {
        url: 'fox.md',
        placeholder: 'vulpis',
        index: 14,
      },
      {
        url: '""',
        placeholder: 'reset',
        index: 27,
      },
      {
        url: '\'foobar\'',
        placeholder: 'singlestring',
        index: 41,
      },
      {
        url: '"fizz-buzz"',
        placeholder: 'doublestring',
        index: 63,
      },
    ],
  };

  const output = grammar.parse(link);

  t.deepEqual(output, expect);
});

test('should parse link with fallback and references', (t) => {
  const link = 'animal || fox.md canine:dog.md';
  const expect = {
    link: {
      url: 'animal',
      placeholder: 'animal',
      index: 0,
    },
    scopeReferences: [{
      url: 'fox.md',
      placeholder: 'animal',
      index: 10,
    }],
    descendantReferences: [{
      url: 'dog.md',
      placeholder: 'canine',
      index: 24,
    }],
  };

  const output = grammar.parse(link);

  t.deepEqual(output, expect);
});
<|endoftext|>


<commit_before>// user-api-test.js
//
// Test the client registration API
//
// Copyright 2012, StatusNet Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var assert = require('assert'),
    vows = require('vows'),
    Step = require('step'),
    _ = require('underscore'),
    httputil = require('./lib/http');

var suite = vows.describe('user API');

suite.addBatch({
    'When we set up the app': {
        topic: function() {
            var cb = this.callback,
                config = {port: 4815,
                          hostname: 'localhost',
                          driver: 'memory',
                          params: {},
                          nologger: true
                         },
                makeApp = require('../lib/app').makeApp;

            makeApp(config, function(err, app) {
                if (err) {
                    cb(err, null);
                } else {
                    app.run(function(err) {
                        if (err) {
                            cb(err, null);
                        } else {
                            cb(null, app);
                        }
                    });
                }
            });
        },
        teardown: function(app) {
            app.close();
        },
        'it works': function(err, app) {
            assert.ifError(err);
        },
        'and we check the user list endpoint': {
            topic: function() {
                httputil.options('localhost', 4815, '/api/users', this.callback);
            },
            'it exists': function(err, allow, res, body) {
                assert.ifError(err);
                assert.equal(res.statusCode, 200);
            },
            'it supports GET': function(err, allow, res, body) {
                assert.include(allow, 'GET');
            },
            'it supports POST': function(err, allow, res, body) {
                assert.include(allow, 'GET');
            }
        }
    }
});

suite.export(module);<commit_msg>add a client in user-api<commit_after>// user-api-test.js
//
// Test the client registration API
//
// Copyright 2012, StatusNet Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var assert = require('assert'),
    vows = require('vows'),
    Step = require('step'),
    _ = require('underscore'),
    httputil = require('./lib/http');

var suite = vows.describe('user API');

suite.addBatch({
    'When we set up the app': {
        topic: function() {
            var cb = this.callback,
                config = {port: 4815,
                          hostname: 'localhost',
                          driver: 'memory',
                          params: {},
                          nologger: true
                         },
                makeApp = require('../lib/app').makeApp;

            makeApp(config, function(err, app) {
                if (err) {
                    cb(err, null);
                } else {
                    app.run(function(err) {
                        if (err) {
                            cb(err, null);
                        } else {
                            cb(null, app);
                        }
                    });
                }
            });
        },
        teardown: function(app) {
            app.close();
        },
        'it works': function(err, app) {
            assert.ifError(err);
        },
        'and we check the user list endpoint': {
            topic: function() {
                httputil.options('localhost', 4815, '/api/users', this.callback);
            },
            'it exists': function(err, allow, res, body) {
                assert.ifError(err);
                assert.equal(res.statusCode, 200);
            },
            'it supports GET': function(err, allow, res, body) {
                assert.include(allow, 'GET');
            },
            'it supports POST': function(err, allow, res, body) {
                assert.include(allow, 'GET');
            }
        },
        'and we create a client using the api': {
            topic: function() {
                var cb = this.callback;
                httputil.post('localhost', 4815, '/api/client/register', {type: 'client_associate'}, function(err, res, body) {
                    var cl;
                    if (err) {
                        cb(err, null);
                    } else {
                        try {
                            cl = JSON.parse(body);
                            cb(null, cl);
                        } catch (err) {
                            cb(err, null);
                        }
                    }
                });
            },
            'it works': function(err, cl) {
                assert.ifError(err);
                assert.isObject(cl);
                assert.isString(cl.client_id);
                assert.isString(cl.client_secret);
            }
        }
    }
});

suite.export(module);<|endoftext|>


<commit_before>/*
 * CSS Modal Plugin for displaying an image gallery
 * Author: Jonathan Weiß
 * Date: 2014-05-15
 */

(function (global) {
	'use strict';

	/**
	 * Main modal object
	 */
	var CSSModal = global.CSSModal;
	var _$prev, _$next, _$detailView, _$activeElement;
	var _items = [];
	var _currentItem = 0;
	var _api = {};
	var _options = {};
	var _defaultOptions = {
		endless: true
	};

	/**
	 * Shows the content previous to the current item
	 * @param  {Object} event The incoming touch/click event
	 * @return {void}
	 */
	var showPrevious = function (event) {
		event.preventDefault();
		event.stopPropagation();

		if (_currentItem === 0) {
			if(_options.endless) {
				_currentItem = (_items.length - 1);
			} else {
				_currentItem = 0;
			}
		} else {
			_currentItem--;
		}

		setActiveItem(_currentItem);
	};

	/**
	 * Shows the content next to the current item
	 * @param  {Object} event The incoming touch/click event
	 * @return {void}
	 */
	var showNext = function (event) {
		event.preventDefault();
		event.stopPropagation();

		if (_currentItem === (_items.length - 1)) {
			if(_options.endless) {
				_currentItem = 0;
			}
		} else {
			_currentItem++;
		}

		setActiveItem(_currentItem);
	};

	/**
	 * Returns the detail image element
	 * @param  {Object} $element The current CSS Modal instance
	 * @return {Object} The detail image
	 */
	var _getDetailView = function ($element) {
		var $container = $element.getElementsByClassName('big-image')[0];
		var $img = $container.getElementsByTagName('img')[0];

		return $img;
	};

	/**
	 * Overrides the options based on the data-attribute on the CSSModal
	 * instance
	 * @return {void}
	 */
	var _readOptions = function () {
		var optionsString = _$activeElement.getAttribute('data-options');
		var options = {};
		var entry;

		if (optionsString && optionsString.length > 0) {
			if (window.JSON) {
				try {
					options = JSON.parse(optionsString);
				} catch (ex) { }
			}
			for (entry in options) {
				if (_options[entry]) {
					_options[entry] = options[entry];
				}
			}
		} else {
			_options = {};
			for (entry in _defaultOptions) {
				_options[entry] = _defaultOptions[entry];
			}
		}
	};

	/**
	 * Registers the listerns on the previous / next buttons to enable gallery
	 * navigation
	 * @return {void}
	 */
	var _initNavigation = function (event) {
		_$activeElement = event.detail.modal;

		if (!_$activeElement._galleryEventsBound) {
			_bindEvents(_$activeElement);
			_$activeElement._galleryEventsBound = true;
			_$activeElement._currentItem = 0;
		}

		_readOptions();
		_$detailView = _getDetailView(_$activeElement);
		_currentItem = _$activeElement._currentItem;
		_items = _readContent(_$activeElement);
	};

	/**
	 * Reacts to specific keyboard commands to enable viewing a differnt item
	 * in the gallery
	 * @param  {Object} event The incoming keypress event
	 * @return {void}
	 */
	var _onKeyPress = function (event) {
		if (event.keyCode === 39) {
			showNext(event);
		} else if (event.keyCode === 37) {
			showPrevious(event);
		}
	};

	/**
	 * Wires the previous / next button to the function to navigation through
	 * the gallery
	 * @param  {Object} $element The CSSModal to set up
	 * @return {void}
	 */
	var _bindEvents = function ($element) {
		var events = ['click', 'touch'];
		var i = 0;

		// Setup touch / click events
		_$prev = $element.getElementsByClassName('modal-prev')[0];
		_$next = $element.getElementsByClassName('modal-next')[0];

		for (; i < events.length; i++) {
			CSSModal.on(events[i], _$prev, showPrevious);
			CSSModal.on(events[i], _$next, showNext);
		}

		// Setup keyboard events
		CSSModal.on('keydown', window, _onKeyPress);
	};

	/**
	 * Gathers information about the gallery content and stores it.
	 * @param  {Object} $element The CSSModal to receive the content from
	 * @return {void}
	 */
	var _readContent = function ($element) {
		var contentList = $element.getElementsByClassName('small-images')[0];

		return contentList.getElementsByTagName('a');
	};

	/**
	 * Shows the full content of the designated item
	 * @param {Number} index The index of the item to show
	 */
	var setActiveItem = function (index) {
		var img = _items[index].getElementsByTagName('img')[0];
		var fullImageSrc = img.getAttribute('data-src-fullsize');
		var fullImageAltText = img.getAttribute('alt');

		_$detailView.src = fullImageSrc;
		_$detailView.alt = fullImageAltText;
	};

	/**
	 * Store the index of the currently active item on the gallery instance
	 * @param  {Number} item The index to store
	 * @return {void}
	 */
	var _storeActiveItem = function () {
		_$activeElement._currentItem = _currentItem;
	};

	/**
	 * Initial call
	 */
	var init = function (modal) {
		CSSModal = modal;

		// If CSS Modal is still undefined, throw an error
		if (!CSSModal) {
			throw new Error('Error: CSSModal is not loaded.');
		}

		CSSModal.on('cssmodal:show', document, _initNavigation);
		CSSModal.on('cssmodal:hide', document, _storeActiveItem);

		return _api;
	};

	_api = {
		showNext: showNext,
		showPrevious: showPrevious
	};

	/*
	 * AMD, module loader, global registration
	 */

	// Expose modal for loaders that implement the Node module pattern.
	if (typeof module === 'object' && module && typeof module.exports === 'object') {
		module.exports = _api;

	// Register as an AMD module
	} else if (typeof define === 'function' && define.amd) {

		define(['../modal.js'], init);

	// Export CSSModal into global space
	} else if (typeof global === 'object' && typeof global.document === 'object') {
		init(global.CSSModal);
	}

}(window));
<commit_msg>Listen to touch events<commit_after>/*
 * CSS Modal Plugin for displaying an image gallery
 * Author: Jonathan Weiß
 * Date: 2014-05-15
 */

(function (global) {
	'use strict';

	/**
	 * Main modal object
	 */
	var CSSModal = global.CSSModal;
	var _$prev, _$next, _$detailView, _$activeElement;
	var _items = [];
	var _currentItem = 0;
	var _api = {};
	var _options = {};
	var _defaultOptions = {
		endless: true
	};

	/**
	 * Shows the content previous to the current item
	 * @param  {Object} event The incoming touch/click event
	 * @return {void}
	 */
	var showPrevious = function (event) {
		event.preventDefault();
		event.stopPropagation();

		if (_currentItem === 0) {
			if(_options.endless) {
				_currentItem = (_items.length - 1);
			} else {
				_currentItem = 0;
			}
		} else {
			_currentItem--;
		}

		setActiveItem(_currentItem);
	};

	/**
	 * Shows the content next to the current item
	 * @param  {Object} event The incoming touch/click event
	 * @return {void}
	 */
	var showNext = function (event) {
		event.preventDefault();
		event.stopPropagation();

		if (_currentItem === (_items.length - 1)) {
			if(_options.endless) {
				_currentItem = 0;
			}
		} else {
			_currentItem++;
		}

		setActiveItem(_currentItem);
	};

	/**
	 * Returns the detail image element
	 * @param  {Object} $element The current CSS Modal instance
	 * @return {Object} The detail image
	 */
	var _getDetailView = function ($element) {
		var $container = $element.getElementsByClassName('big-image')[0];
		var $img = $container.getElementsByTagName('img')[0];

		return $img;
	};

	/**
	 * Overrides the options based on the data-attribute on the CSSModal
	 * instance
	 * @return {void}
	 */
	var _readOptions = function () {
		var optionsString = _$activeElement.getAttribute('data-options');
		var options = {};
		var entry;

		if (optionsString && optionsString.length > 0) {
			if (window.JSON) {
				try {
					options = JSON.parse(optionsString);
				} catch (ex) { }
			}
			for (entry in options) {
				if (_options[entry]) {
					_options[entry] = options[entry];
				}
			}
		} else {
			_options = {};
			for (entry in _defaultOptions) {
				_options[entry] = _defaultOptions[entry];
			}
		}
	};

	/**
	 * Registers the listerns on the previous / next buttons to enable gallery
	 * navigation
	 * @return {void}
	 */
	var _initNavigation = function (event) {
		_$activeElement = event.detail.modal;

		if (!_$activeElement._galleryEventsBound) {
			_bindEvents(_$activeElement);
			_$activeElement._galleryEventsBound = true;
			_$activeElement._currentItem = 0;
		}

		_readOptions();
		_$detailView = _getDetailView(_$activeElement);
		_currentItem = _$activeElement._currentItem;
		_items = _readContent(_$activeElement);
	};

	/**
	 * Reacts to specific keyboard commands to enable viewing a differnt item
	 * in the gallery
	 * @param  {Object} event The incoming keypress event
	 * @return {void}
	 */
	var _onKeyPress = function (event) {
		if (event.keyCode === 39) {
			showNext(event);
		} else if (event.keyCode === 37) {
			showPrevious(event);
		}
	};

	/**
	 * Wires the previous / next button to the function to navigation through
	 * the gallery
	 * @param  {Object} $element The CSSModal to set up
	 * @return {void}
	 */
	var _bindEvents = function ($element) {
		var events = ['click', 'touch'];
		var i = 0;

		// Setup touch / click events
		_$prev = $element.getElementsByClassName('modal-prev')[0];
		_$next = $element.getElementsByClassName('modal-next')[0];

		for (; i < events.length; i++) {
			CSSModal.on(events[i], _$prev, showPrevious);
			CSSModal.on(events[i], _$next, showNext);
		}

		// Setup keyboard events
		CSSModal.on('keydown', window, _onKeyPress);

        // Setup swipe events
        CSSModal.on('touch:swipe-left', $element, showPrevious);
        CSSModal.on('touch:swipe-right', $element, showNext);
	};

	/**
	 * Gathers information about the gallery content and stores it.
	 * @param  {Object} $element The CSSModal to receive the content from
	 * @return {void}
	 */
	var _readContent = function ($element) {
		var contentList = $element.getElementsByClassName('small-images')[0];

		return contentList.getElementsByTagName('a');
	};

	/**
	 * Shows the full content of the designated item
	 * @param {Number} index The index of the item to show
	 */
	var setActiveItem = function (index) {
		var img = _items[index].getElementsByTagName('img')[0];
		var fullImageSrc = img.getAttribute('data-src-fullsize');
		var fullImageAltText = img.getAttribute('alt');

		_$detailView.src = fullImageSrc;
		_$detailView.alt = fullImageAltText;
	};

	/**
	 * Store the index of the currently active item on the gallery instance
	 * @param  {Number} item The index to store
	 * @return {void}
	 */
	var _storeActiveItem = function () {
		_$activeElement._currentItem = _currentItem;
	};

	/**
	 * Initial call
	 */
	var init = function (modal) {
        CSSModal = modal;

		// If CSS Modal is still undefined, throw an error
		if (!CSSModal) {
			throw new Error('Error: CSSModal is not loaded.');
		}

		CSSModal.on('cssmodal:show', document, _initNavigation);
		CSSModal.on('cssmodal:hide', document, _storeActiveItem);

		return _api;
	};

	_api = {
		showNext: showNext,
		showPrevious: showPrevious
	};

	/*
	 * AMD, module loader, global registration
	 */

	// Expose modal for loaders that implement the Node module pattern.
	if (typeof module === 'object' && module && typeof module.exports === 'object') {
		module.exports = _api;

	// Register as an AMD module
	} else if (typeof define === 'function' && define.amd) {

		define(['../modal.js'], init);

	// Export CSSModal into global space
	} else if (typeof global === 'object' && typeof global.document === 'object') {
		init(global.CSSModal);
	}

}(window));
<|endoftext|>


<commit_before>/*jshint esversion:6, node:true*/
/*
 * Application Core
 * https://github.com/goliatone/application-core
 *
 * Copyright (c) 2016 goliatone
 * Licensed under the MIT license.
 */
'use strict';

const path = require('path');
const glob = require('glob');
const extend = require('gextend');
const Keypath = require('gkeypath');
const EventEmitter = require('events');
const sanitizeName = require('./utils').sanitizeName;

const DEFAULTS = {
    logger: console,
    autorun: true,
    autoinitialize: true,
    name: 'Application',
    //TODO: monitoring should be enabled only for data processing apps.
    coremodules:['logger', 'errors', 'dispatcher', 'monitoring', 'repl'],
    basepath: process.cwd()
};

class Application extends EventEmitter {
    constructor(options){
        options = extend({}, DEFAULTS, options);

        super();

        if(options.autoinitialize) this.init(options);
    }

    init(config) {
        if(this.initialized) return;
        this.initialized = true;

        config = extend({}, DEFAULTS, config);

        extend(this, config);

        this.register(extend, 'extend');

        /*
         * This is not the most elegant solution
         * but
         */
        if(this.config.app) extend(this, this.config.app);

        this.config = Keypath.wrap(this.config, null, 'data');

        //FIGURE OUT HOW TO MERGE...
        var self = this;
        this.coremodules.map(function(module){
            console.log('coremodule', module);
            this.loadModule(module, path.resolve(path.join(__dirname, module)));
        }, this);

        if(this.loaders){
            //move to it's own file
            if(this.loaders.modules){
                // if(typeof this.loaders.modules === 'string') this.loaders.modules = [this.loaders.modules];
                this.loadDirectory(this.loaders.modules);
            }

            if(this.loaders.handlers){
                // if(typeof this.loaders.handlers === 'string') this.loaders.handlers = [this.loaders.handlers];
                this.loadHanlders(this.loaders.handlers);
            }
        }
    }

    register(instance, name){
        name = sanitizeName(name);
        console.log('- registering "%s"', name);
        this[name] = instance;
    }

    loadDirectory(dir, options){
        if(!path.isAbsolute(dir)){
            dir = path.join(getPathToMain(), dir);
        }

        this.logger.info('load directory %s', dir);

        var files = glob.sync(dir, options);
        var promises = files.map((file) => {
            return this.loadModule(getModuleName(file), file);
        });
        return Promise.all(promises);
    }

    loadHanlders(dir='handlers', options={}){
        if(!path.isAbsolute(dir)){
            dir = path.join(getPathToMain(), dir);
        }
        var pattern = dir;

        this.logger.info('- load handlers %s', dir);

        var files = glob.sync(pattern, options);
        var that = this;

        files.map((file) => {
            this.handle(getModuleName(file), require(file));
        });
    }

    loadModule(id, path){
        this.logger.info('- loading module "%s", %s', id, path);

        var instance,
            output = Promise.defer();

        try {
            //TODO: Define a module interface. Move this to a function that
            //we can override. Right now a module has to have a "init" function.
            instance = require(path).init(this, this.config.get(id, {}));
            output.resolve(instance);
        } catch (e) {
            this.logger.error('ERROR loading module "%s"', id);
            this.logger.error('path %s', path);
            this.logger.error(e.message);
            this.logger.error(e.stack);
            output.reject(e);
        }

        if(instance){
            this.register(instance, id);
        }

        return output.promise;
    }

    resolve(id){
        //This method could return a Promise and a proxy,
        //were we use the proxy to handle calls for instance
        //while its being loaded...
        var instance = this[id];
        return Promise.resolve(instance);
    }

    run(){
        if(this.didRun) return;
        this.didRun = true;

        //TODO: ideally we would have a way to manage each
        //cycle of running hooks. We would register a handler
        //and each whould return a promise, we wouldn't start
        //a new lifecycle until all are done

        setTimeout(() => {
            this.logger.info('Emit "run.pre"');
            this.emit('run.pre');

            this.logger.info('Emit "run"');
            this.emit('run');

            this.logger.info('Emit "run.post"');
            this.emit('run.post');
        }, 0);
    }

    //TODO: rename as command or registerCommand
    handle(event, handler){
        /*
         * Here Were Dragons... if you uncomment this
         * log, handler gets executed (?) and takes everything
         * out of wack.
         */
        // this.logger.info('- register handler for %s', event, handler);

        this.logger.info('- register handler for %s', event);
        handler = handler.bind(this);

        this.on(event, handler);
    }

    close(code, label){
        //here we could run a close routing. Whatever it is, it should not
        //take more than 10 seconds- Serene's default
        return Promise.resolve();
    }

    static loadConfig(options={}, asObject=true){
        if(!options.basepath) options.basepath = getPathToMain();

        var libDefaults = require('simple-config-loader')({
            basepath: __dirname
        });

        options = extend({}, DEFAULTS, libDefaults.data, options);

        var config = require('simple-config-loader')({
            config: options,
            basepath: process.cwd()
        });

        if(asObject) return config._target;
        return config;
    }
}

function getPathToMain(){
    var sep = require('path').sep;
    var main = process.argv[1];
    main = main.split(sep);
    main.pop();
    main = main.join(sep);
    return main;
}

function getModuleName(file){
    return path.basename(file).replace(path.extname(file), '');
}

/**
 * Exports module
 */
module.exports = Application;
<commit_msg>make sanitizeName a function<commit_after>/*jshint esversion:6, node:true*/
/*
 * Application Core
 * https://github.com/goliatone/application-core
 *
 * Copyright (c) 2016 goliatone
 * Licensed under the MIT license.
 */
'use strict';

const path = require('path');
const glob = require('glob');
const extend = require('gextend');
const Keypath = require('gkeypath');
const EventEmitter = require('events');
const sanitizeName = require('./utils').sanitizeName;

const DEFAULTS = {
    logger: console,
    autorun: true,
    autoinitialize: true,
    name: 'Application',
    sanitizeName: sanitizeName,
    //TODO: monitoring should be enabled only for data processing apps.
    coremodules:['logger', 'errors', 'dispatcher', 'monitoring', 'repl'],
    basepath: process.cwd()
};

class Application extends EventEmitter {
    constructor(options){
        options = extend({}, DEFAULTS, options);

        super();

        if(options.autoinitialize) this.init(options);
    }

    init(config) {
        if(this.initialized) return;
        this.initialized = true;

        config = extend({}, DEFAULTS, config);

        extend(this, config);

        this.register(extend, 'extend');

        /*
         * This is not the most elegant solution
         * but
         */
        if(this.config.app) extend(this, this.config.app);

        this.config = Keypath.wrap(this.config, null, 'data');

        //FIGURE OUT HOW TO MERGE...
        var self = this;
        this.coremodules.map(function(module){
            console.log('coremodule', module);
            this.loadModule(module, path.resolve(path.join(__dirname, module)));
        }, this);

        if(this.loaders){
            //move to it's own file
            if(this.loaders.modules){
                // if(typeof this.loaders.modules === 'string') this.loaders.modules = [this.loaders.modules];
                this.loadDirectory(this.loaders.modules);
            }

            if(this.loaders.handlers){
                // if(typeof this.loaders.handlers === 'string') this.loaders.handlers = [this.loaders.handlers];
                this.loadHanlders(this.loaders.handlers);
            }
        }
    }

    register(instance, name){
        name = this.sanitizeName(name);
        console.log('- registering "%s"', name);
        this[name] = instance;
    }

    loadDirectory(dir, options){
        if(!path.isAbsolute(dir)){
            dir = path.join(getPathToMain(), dir);
        }

        this.logger.info('load directory %s', dir);

        var files = glob.sync(dir, options);
        var promises = files.map((file) => {
            return this.loadModule(getModuleName(file), file);
        });
        return Promise.all(promises);
    }

    loadHanlders(dir='handlers', options={}){
        if(!path.isAbsolute(dir)){
            dir = path.join(getPathToMain(), dir);
        }
        var pattern = dir;

        this.logger.info('- load handlers %s', dir);

        var files = glob.sync(pattern, options);
        var that = this;

        files.map((file) => {
            this.handle(getModuleName(file), require(file));
        });
    }

    loadModule(id, path){
        this.logger.info('- loading module "%s", %s', id, path);

        var instance,
            output = Promise.defer();

        try {
            //TODO: Define a module interface. Move this to a function that
            //we can override. Right now a module has to have a "init" function.
            instance = require(path).init(this, this.config.get(id, {}));
            output.resolve(instance);
        } catch (e) {
            this.logger.error('ERROR loading module "%s"', id);
            this.logger.error('path %s', path);
            this.logger.error(e.message);
            this.logger.error(e.stack);
            output.reject(e);
        }

        if(instance){
            this.register(instance, id);
        }

        return output.promise;
    }

    resolve(id){
        //This method could return a Promise and a proxy,
        //were we use the proxy to handle calls for instance
        //while its being loaded...
        var instance = this[id];
        return Promise.resolve(instance);
    }

    run(){
        if(this.didRun) return;
        this.didRun = true;

        //TODO: ideally we would have a way to manage each
        //cycle of running hooks. We would register a handler
        //and each whould return a promise, we wouldn't start
        //a new lifecycle until all are done

        setTimeout(() => {
            this.logger.info('Emit "run.pre"');
            this.emit('run.pre');

            this.logger.info('Emit "run"');
            this.emit('run');

            this.logger.info('Emit "run.post"');
            this.emit('run.post');
        }, 0);
    }

    //TODO: rename as command or registerCommand
    handle(event, handler){
        /*
         * Here Were Dragons... if you uncomment this
         * log, handler gets executed (?) and takes everything
         * out of wack.
         */
        // this.logger.info('- register handler for %s', event, handler);

        this.logger.info('- register handler for %s', event);
        handler = handler.bind(this);

        this.on(event, handler);
    }

    close(code, label){
        //here we could run a close routing. Whatever it is, it should not
        //take more than 10 seconds- Serene's default
        return Promise.resolve();
    }

    static loadConfig(options={}, asObject=true){
        if(!options.basepath) options.basepath = getPathToMain();

        var libDefaults = require('simple-config-loader')({
            basepath: __dirname
        });

        options = extend({}, DEFAULTS, libDefaults.data, options);

        var config = require('simple-config-loader')({
            config: options,
            basepath: process.cwd()
        });

        if(asObject) return config._target;
        return config;
    }
}

function getPathToMain(){
    var sep = require('path').sep;
    var main = process.argv[1];
    main = main.split(sep);
    main.pop();
    main = main.join(sep);
    return main;
}

function getModuleName(file){
    return path.basename(file).replace(path.extname(file), '');
}

/**
 * Exports module
 */
module.exports = Application;
<|endoftext|>


<commit_before>
'use strict';

/**
 * Module dependencies.
 */

const isGeneratorFunction = require('is-generator-function');
const debug = require('debug')('koa:application');
const onFinished = require('on-finished');
const response = require('./response');
const compose = require('koa-compose');
const isJSON = require('koa-is-json');
const context = require('./context');
const request = require('./request');
const statuses = require('statuses');
const Cookies = require('cookies');
const accepts = require('accepts');
const Emitter = require('events');
const assert = require('assert');
const Stream = require('stream');
const http = require('http');
const only = require('only');

/**
 * Expose `Application` class.
 * Inherits from `Emitter.prototype`.
 */

module.exports = class Application extends Emitter {

  /**
   * Initialize a new `Application`.
   *
   * @api public
   */

  constructor() {
    super();

    this.proxy = false;
    this.middleware = [];
    this.subdomainOffset = 2;
    this.env = process.env.NODE_ENV || 'development';
    this.context = Object.create(context);
    this.request = Object.create(request);
    this.response = Object.create(response);
  }

  /**
   * Shorthand for:
   *
   *    http.createServer(app.callback()).listen(...)
   *
   * @param {Mixed} ...
   * @return {Server}
   * @api public
   */

  listen() {
    debug('listen');
    const server = http.createServer(this.callback());
    return server.listen.apply(server, arguments);
  }

  /**
   * Return JSON representation.
   * We only bother showing settings.
   *
   * @return {Object}
   * @api public
   */

  toJSON() {
    return only(this, [
      'subdomainOffset',
      'proxy',
      'env'
    ]);
  }

  /**
   * Inspect implementation.
   *
   * @return {Object}
   * @api public
   */

  inspect() {
    return this.toJSON();
  }

  /**
   * Use the given middleware `fn`.
   *
   * @param {Function} fn
   * @return {Application} self
   * @api public
   */

  use(fn) {
    if (typeof fn !== 'function') throw new TypeError('middleware must be a function!');
    if (isGeneratorFunction(fn)) throw new TypeError('Support for generators has been removed. See the documentation for examples of how to convert old middleware https://github.com/koajs/koa#example-with-old-signature');
    debug('use %s', fn._name || fn.name || '-');
    this.middleware.push(fn);
    return this;
  }

  /**
   * Return a request handler callback
   * for node's native http server.
   *
   * @return {Function}
   * @api public
   */

  callback() {
    const fn = compose(this.middleware);

    if (!this.listeners('error').length) this.on('error', this.onerror);

    return (req, res) => {
      res.statusCode = 404;
      const ctx = this.createContext(req, res);
      onFinished(res, ctx.onerror);
      fn(ctx).then(() => respond(ctx)).catch(ctx.onerror);
    };
  }

  /**
   * Initialize a new context.
   *
   * @api private
   */

  createContext(req, res) {
    const context = Object.create(this.context);
    const request = context.request = Object.create(this.request);
    const response = context.response = Object.create(this.response);
    context.app = request.app = response.app = this;
    context.req = request.req = response.req = req;
    context.res = request.res = response.res = res;
    request.ctx = response.ctx = context;
    request.response = response;
    response.request = request;
    context.onerror = context.onerror.bind(context);
    context.originalUrl = request.originalUrl = req.url;
    context.cookies = new Cookies(req, res, this.keys);
    context.accept = request.accept = accepts(req);
    context.state = {};
    return context;
  }

  /**
   * Default error handler.
   *
   * @param {Error} err
   * @api private
   */

  onerror(err) {
    assert(err instanceof Error, `non-error thrown: ${err}`);

    if (404 == err.status || err.expose) return;
    if (this.silent) return;

    const msg = err.stack || err.toString();
    console.error();
    console.error(msg.replace(/^/gm, '  '));
    console.error();
  }

};

/**
 * Response helper.
 */

function respond(ctx) {
  // allow bypassing koa
  if (false === ctx.respond) return;

  const res = ctx.res;
  if (res.headersSent || !ctx.writable) return;

  let body = ctx.body;
  const code = ctx.status;

  // ignore body
  if (statuses.empty[code]) {
    // strip headers
    ctx.body = null;
    return res.end();
  }

  if ('HEAD' == ctx.method) {
    if (isJSON(body)) ctx.length = Buffer.byteLength(JSON.stringify(body));
    return res.end();
  }

  // status body
  if (null == body) {
    ctx.type = 'text';
    body = ctx.message || String(code);
    ctx.length = Buffer.byteLength(body);
    return res.end(body);
  }

  // responses
  if (Buffer.isBuffer(body)) return res.end(body);
  if ('string' == typeof body) return res.end(body);
  if (body instanceof Stream) return body.pipe(res);

  // body: json
  body = JSON.stringify(body);
  ctx.length = Buffer.byteLength(body);
  res.end(body);
}
<commit_msg>fix the error message<commit_after>
'use strict';

/**
 * Module dependencies.
 */

const isGeneratorFunction = require('is-generator-function');
const debug = require('debug')('koa:application');
const onFinished = require('on-finished');
const response = require('./response');
const compose = require('koa-compose');
const isJSON = require('koa-is-json');
const context = require('./context');
const request = require('./request');
const statuses = require('statuses');
const Cookies = require('cookies');
const accepts = require('accepts');
const Emitter = require('events');
const assert = require('assert');
const Stream = require('stream');
const http = require('http');
const only = require('only');

/**
 * Expose `Application` class.
 * Inherits from `Emitter.prototype`.
 */

module.exports = class Application extends Emitter {

  /**
   * Initialize a new `Application`.
   *
   * @api public
   */

  constructor() {
    super();

    this.proxy = false;
    this.middleware = [];
    this.subdomainOffset = 2;
    this.env = process.env.NODE_ENV || 'development';
    this.context = Object.create(context);
    this.request = Object.create(request);
    this.response = Object.create(response);
  }

  /**
   * Shorthand for:
   *
   *    http.createServer(app.callback()).listen(...)
   *
   * @param {Mixed} ...
   * @return {Server}
   * @api public
   */

  listen() {
    debug('listen');
    const server = http.createServer(this.callback());
    return server.listen.apply(server, arguments);
  }

  /**
   * Return JSON representation.
   * We only bother showing settings.
   *
   * @return {Object}
   * @api public
   */

  toJSON() {
    return only(this, [
      'subdomainOffset',
      'proxy',
      'env'
    ]);
  }

  /**
   * Inspect implementation.
   *
   * @return {Object}
   * @api public
   */

  inspect() {
    return this.toJSON();
  }

  /**
   * Use the given middleware `fn`.
   *
   * @param {Function} fn
   * @return {Application} self
   * @api public
   */

  use(fn) {
    if (typeof fn !== 'function') throw new TypeError('middleware must be a function!');
    if (isGeneratorFunction(fn)) throw new TypeError('Support for generators has been removed. See the documentation for examples of how to convert old middleware https://github.com/koajs/koa/tree/v2.x#old-signature-middleware-v1x');
    debug('use %s', fn._name || fn.name || '-');
    this.middleware.push(fn);
    return this;
  }

  /**
   * Return a request handler callback
   * for node's native http server.
   *
   * @return {Function}
   * @api public
   */

  callback() {
    const fn = compose(this.middleware);

    if (!this.listeners('error').length) this.on('error', this.onerror);

    return (req, res) => {
      res.statusCode = 404;
      const ctx = this.createContext(req, res);
      onFinished(res, ctx.onerror);
      fn(ctx).then(() => respond(ctx)).catch(ctx.onerror);
    };
  }

  /**
   * Initialize a new context.
   *
   * @api private
   */

  createContext(req, res) {
    const context = Object.create(this.context);
    const request = context.request = Object.create(this.request);
    const response = context.response = Object.create(this.response);
    context.app = request.app = response.app = this;
    context.req = request.req = response.req = req;
    context.res = request.res = response.res = res;
    request.ctx = response.ctx = context;
    request.response = response;
    response.request = request;
    context.onerror = context.onerror.bind(context);
    context.originalUrl = request.originalUrl = req.url;
    context.cookies = new Cookies(req, res, this.keys);
    context.accept = request.accept = accepts(req);
    context.state = {};
    return context;
  }

  /**
   * Default error handler.
   *
   * @param {Error} err
   * @api private
   */

  onerror(err) {
    assert(err instanceof Error, `non-error thrown: ${err}`);

    if (404 == err.status || err.expose) return;
    if (this.silent) return;

    const msg = err.stack || err.toString();
    console.error();
    console.error(msg.replace(/^/gm, '  '));
    console.error();
  }

};

/**
 * Response helper.
 */

function respond(ctx) {
  // allow bypassing koa
  if (false === ctx.respond) return;

  const res = ctx.res;
  if (res.headersSent || !ctx.writable) return;

  let body = ctx.body;
  const code = ctx.status;

  // ignore body
  if (statuses.empty[code]) {
    // strip headers
    ctx.body = null;
    return res.end();
  }

  if ('HEAD' == ctx.method) {
    if (isJSON(body)) ctx.length = Buffer.byteLength(JSON.stringify(body));
    return res.end();
  }

  // status body
  if (null == body) {
    ctx.type = 'text';
    body = ctx.message || String(code);
    ctx.length = Buffer.byteLength(body);
    return res.end(body);
  }

  // responses
  if (Buffer.isBuffer(body)) return res.end(body);
  if ('string' == typeof body) return res.end(body);
  if (body instanceof Stream) return body.pipe(res);

  // body: json
  body = JSON.stringify(body);
  ctx.length = Buffer.byteLength(body);
  res.end(body);
}
<|endoftext|>


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

var Emitter = require('component-emitter')

/**
 * Expose `scene`.
 */

module.exports = Application

/**
 * Create a new `Application`.
 */

function Application () {
  if (!(this instanceof Application)) return new Application()
  this.options = {}
  this.sources = {}
  this.element = null
}

/**
 * Mixin `Emitter`.
 */

Emitter(Application.prototype)

/**
 * Add a plugin
 *
 * @param {Function} plugin
 */

Application.prototype.use = function (plugin) {
  plugin(this)
  return this
}

/**
 * Set an option
 *
 * @param {String} name
 */

Application.prototype.option = function (name, val) {
  this.options[name] = val
  return this
}

/**
 * Set value used somewhere in the IO network.
 */

Application.prototype.set = function (name, data) {
  if (this.sources[name] === data) return
  this.sources[name] = data
  this.emit('source', name, data)
  return this
}

/**
 * Mount a virtual element.
 *
 * @param {VirtualElement} element
 */

Application.prototype.mount = function (element) {
  this.element = element
  this.emit('mount', element)
  return this
}

/**
 * Remove the world. Unmount everything.
 */

Application.prototype.unmount = function () {
  if (!this.element) return
  this.element = null
  this.emit('unmount')
  return this
}
<commit_msg>Allowing easier initial mounting<commit_after>/**
 * Module dependencies.
 */

var Emitter = require('component-emitter')

/**
 * Expose `scene`.
 */

module.exports = Application

/**
 * Create a new `Application`.
 *
 * @param {Object} element Optional initial element
 */

function Application (element) {
  if (!(this instanceof Application)) return new Application()
  this.options = {}
  this.sources = {}
  this.element = element
}

/**
 * Mixin `Emitter`.
 */

Emitter(Application.prototype)

/**
 * Add a plugin
 *
 * @param {Function} plugin
 */

Application.prototype.use = function (plugin) {
  plugin(this)
  return this
}

/**
 * Set an option
 *
 * @param {String} name
 */

Application.prototype.option = function (name, val) {
  this.options[name] = val
  return this
}

/**
 * Set value used somewhere in the IO network.
 */

Application.prototype.set = function (name, data) {
  if (this.sources[name] === data) return
  this.sources[name] = data
  this.emit('source', name, data)
  return this
}

/**
 * Mount a virtual element.
 *
 * @param {VirtualElement} element
 */

Application.prototype.mount = function (element) {
  this.element = element
  this.emit('mount', element)
  return this
}

/**
 * Remove the world. Unmount everything.
 */

Application.prototype.unmount = function () {
  if (!this.element) return
  this.element = null
  this.emit('unmount')
  return this
}
<|endoftext|>