<commit_before>const passport = require('passport');
const LocalAPIKeyStrategy = require('./passport-apikey-strategy');
let services = require('../../services/index');
let logger = require('../log').policy;
let authService = services.auth;
const credentialType = 'key-auth';
passport.use(new LocalAPIKeyStrategy({passReqToCallback: true}, (req, apikey, done) => {
  // key will look like "h1243h1kl23h4kjh:asfasqwerqw"
  if (!apikey) {
    return done(null, false);
  }

  let keyParts = apikey.split(':');

  // as per http://passportjs.org/docs/authorize
  // after authentication  req.user is populated
  // and after authorization req.account is filled in
  authService.authenticateCredential(keyParts[0], keyParts[1], credentialType)
    .then(consumer => {
      if (!consumer) {
        return done(null, false);
      }
      let endpointScopes = req.egContext.apiEndpoint.scopes && req.egContext.apiEndpoint.scopes.map(s => s.scope || s);
      req.user = consumer;

      return authService.authorizeCredential(keyParts[0], credentialType, endpointScopes)
        .then(authorized => {
          if (!authorized) {
            return done(null, false);
          }
          consumer.authorizedScopes = endpointScopes;
          req.account = consumer;
          return done(null, consumer);
        });
    })
    .catch(err => {
      logger.warn(err);
      done(err);
    });
}));

module.exports = function (params) {
  params = params || {};

  return function (req, res, next) {
    params.session = false;
    passport.authenticate('localapikey', params, (err, user, info) => {
      if (err) { return next(err); }
      if (!req.user) { // user is not authenticated
        res.status(401);
        res.send('Forbidden');
      } else if (!req.account) {   // user is not authorized
        res.status(403);
        res.send('Unauthorized');
      } else {
        req.egContext.user = req.account;
        next();
      }
    })(req, res, next);
  };
};
<commit_msg>Fixes logger path (#427)<commit_after>const passport = require('passport');
const LocalAPIKeyStrategy = require('./passport-apikey-strategy');
let services = require('../../services/index');
let logger = require('../../logger').policy;
let authService = services.auth;
const credentialType = 'key-auth';
passport.use(new LocalAPIKeyStrategy({passReqToCallback: true}, (req, apikey, done) => {
  // key will look like "h1243h1kl23h4kjh:asfasqwerqw"
  if (!apikey) {
    return done(null, false);
  }

  let keyParts = apikey.split(':');

  // as per http://passportjs.org/docs/authorize
  // after authentication  req.user is populated
  // and after authorization req.account is filled in
  authService.authenticateCredential(keyParts[0], keyParts[1], credentialType)
    .then(consumer => {
      if (!consumer) {
        return done(null, false);
      }
      let endpointScopes = req.egContext.apiEndpoint.scopes && req.egContext.apiEndpoint.scopes.map(s => s.scope || s);
      req.user = consumer;

      return authService.authorizeCredential(keyParts[0], credentialType, endpointScopes)
        .then(authorized => {
          if (!authorized) {
            return done(null, false);
          }
          consumer.authorizedScopes = endpointScopes;
          req.account = consumer;
          return done(null, consumer);
        });
    })
    .catch(err => {
      logger.warn(err);
      done(err);
    });
}));

module.exports = function (params) {
  params = params || {};

  return function (req, res, next) {
    params.session = false;
    passport.authenticate('localapikey', params, (err, user, info) => {
      if (err) { return next(err); }
      if (!req.user) { // user is not authenticated
        res.status(401);
        res.send('Forbidden');
      } else if (!req.account) {   // user is not authorized
        res.status(403);
        res.send('Unauthorized');
      } else {
        req.egContext.user = req.account;
        next();
      }
    })(req, res, next);
  };
};
<|endoftext|>


<commit_before>'use strict';

var has = Object.prototype.hasOwnProperty;

//
// We store our EE objects in a plain object whose properties are event names.
// If `Object.create(null)` is not supported we prefix the event names with a
// `~` to make sure that the built-in object properties are not overridden or
// used as an attack vector.
// We also assume that `Object.create(null)` is available when the event name
// is an ES6 Symbol.
//
var prefix = typeof Object.create !== 'function' ? '~' : false;

/**
 * Representation of a single EventEmitter function.
 *
 * @param {Function} fn Event handler to be called.
 * @param {Mixed} context Context for function execution.
 * @param {Boolean} [once=false] Only emit once
 * @api private
 */
function EE(fn, context, once) {
  this.fn = fn;
  this.context = context;
  this.once = once || false;
}

/**
 * Minimal EventEmitter interface that is molded against the Node.js
 * EventEmitter interface.
 *
 * @constructor
 * @api public
 */
function EventEmitter() { /* Nothing to set */ }

/**
 * Hold the assigned EventEmitters by name.
 *
 * @type {Object}
 * @private
 */
EventEmitter.prototype._events = undefined;

/**
 * Return an array listing the events for which the emitter has registered
 * listeners.
 *
 * @returns {Array}
 * @api public
 */
EventEmitter.prototype.eventNames = function eventNames() {
  var events = this._events
    , names = []
    , name;

  if (!events) return names;

  for (name in events) {
    if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
  }

  if (Object.getOwnPropertySymbols) {
    return names.concat(Object.getOwnPropertySymbols(events));
  }

  return names;
};

/**
 * Return a list of assigned event listeners.
 *
 * @param {String} event The events that should be listed.
 * @param {Boolean} exists We only need to know if there are listeners.
 * @returns {Array|Boolean}
 * @api public
 */
EventEmitter.prototype.listeners = function listeners(event, exists) {
  var evt = prefix ? prefix + event : event
    , available = this._events && this._events[evt];

  if (exists) return !!available;
  if (!available) return [];
  if (available.fn) return [available.fn];

  for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) {
    ee[i] = available[i].fn;
  }

  return ee;
};

/**
 * Emit an event to all registered event listeners.
 *
 * @param {String} event The name of the event.
 * @returns {Boolean} Indication if we've emitted an event.
 * @api public
 */
EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
  var evt = prefix ? prefix + event : event;

  if (!this._events || !this._events[evt]) return false;

  var listeners = this._events[evt]
    , len = arguments.length
    , args
    , i;

  if ('function' === typeof listeners.fn) {
    if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);

    switch (len) {
      case 1: return listeners.fn.call(listeners.context), true;
      case 2: return listeners.fn.call(listeners.context, a1), true;
      case 3: return listeners.fn.call(listeners.context, a1, a2), true;
      case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
      case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
      case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
    }

    for (i = 1, args = new Array(len -1); i < len; i++) {
      args[i - 1] = arguments[i];
    }

    listeners.fn.apply(listeners.context, args);
  } else {
    var length = listeners.length
      , j;

    for (i = 0; i < length; i++) {
      if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);

      switch (len) {
        case 1: listeners[i].fn.call(listeners[i].context); break;
        case 2: listeners[i].fn.call(listeners[i].context, a1); break;
        case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
        default:
          if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
            args[j - 1] = arguments[j];
          }

          listeners[i].fn.apply(listeners[i].context, args);
      }
    }
  }

  return true;
};

/**
 * Register a new EventListener for the given event.
 *
 * @param {String} event Name of the event.
 * @param {Function} fn Callback function.
 * @param {Mixed} [context=this] The context of the function.
 * @api public
 */
EventEmitter.prototype.on = function on(event, fn, context) {
  var listener = new EE(fn, context || this)
    , evt = prefix ? prefix + event : event;

  if (!this._events) this._events = prefix ? {} : Object.create(null);
  if (!this._events[evt]) this._events[evt] = listener;
  else {
    if (!this._events[evt].fn) this._events[evt].push(listener);
    else this._events[evt] = [
      this._events[evt], listener
    ];
  }

  return this;
};

/**
 * Add an EventListener that's only called once.
 *
 * @param {String} event Name of the event.
 * @param {Function} fn Callback function.
 * @param {Mixed} [context=this] The context of the function.
 * @api public
 */
EventEmitter.prototype.once = function once(event, fn, context) {
  var listener = new EE(fn, context || this, true)
    , evt = prefix ? prefix + event : event;

  if (!this._events) this._events = prefix ? {} : Object.create(null);
  if (!this._events[evt]) this._events[evt] = listener;
  else {
    if (!this._events[evt].fn) this._events[evt].push(listener);
    else this._events[evt] = [
      this._events[evt], listener
    ];
  }

  return this;
};

/**
 * Remove event listeners.
 *
 * @param {String} event The event we want to remove.
 * @param {Function} fn The listener that we need to find.
 * @param {Mixed} context Only remove listeners matching this context.
 * @param {Boolean} once Only remove once listeners.
 * @api public
 */
EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
  var evt = prefix ? prefix + event : event;

  if (!this._events || !this._events[evt]) return this;

  var listeners = this._events[evt]
    , events = [];

  if (fn) {
    if (listeners.fn) {
      if (
           listeners.fn !== fn
        || (once && !listeners.once)
        || (context && listeners.context !== context)
      ) {
        events.push(listeners);
      }
    } else {
      for (var i = 0, length = listeners.length; i < length; i++) {
        if (
             listeners[i].fn !== fn
          || (once && !listeners[i].once)
          || (context && listeners[i].context !== context)
        ) {
          events.push(listeners[i]);
        }
      }
    }
  }

  //
  // Reset the array, or remove it completely if we have no more listeners.
  //
  if (events.length) {
    this._events[evt] = events.length === 1 ? events[0] : events;
  } else {
    delete this._events[evt];
  }

  return this;
};

/**
 * Remove all listeners or only the listeners for the specified event.
 *
 * @param {String} event The event want to remove all listeners for.
 * @api public
 */
EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
  if (!this._events) return this;

  if (event) delete this._events[prefix ? prefix + event : event];
  else this._events = prefix ? {} : Object.create(null);

  return this;
};

//
// Alias methods names because people roll like that.
//
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
EventEmitter.prototype.addListener = EventEmitter.prototype.on;

//
// This function doesn't apply anymore.
//
EventEmitter.prototype.setMaxListeners = function setMaxListeners() {
  return this;
};

//
// Expose the prefix.
//
EventEmitter.prefixed = prefix;

//
// Expose the module.
//
if ('undefined' !== typeof module) {
  module.exports = EventEmitter;
}
<commit_msg>[minor] Remove unnecessary type check<commit_after>'use strict';

var has = Object.prototype.hasOwnProperty;

//
// We store our EE objects in a plain object whose properties are event names.
// If `Object.create(null)` is not supported we prefix the event names with a
// `~` to make sure that the built-in object properties are not overridden or
// used as an attack vector.
// We also assume that `Object.create(null)` is available when the event name
// is an ES6 Symbol.
//
var prefix = typeof Object.create !== 'function' ? '~' : false;

/**
 * Representation of a single EventEmitter function.
 *
 * @param {Function} fn Event handler to be called.
 * @param {Mixed} context Context for function execution.
 * @param {Boolean} [once=false] Only emit once
 * @api private
 */
function EE(fn, context, once) {
  this.fn = fn;
  this.context = context;
  this.once = once || false;
}

/**
 * Minimal EventEmitter interface that is molded against the Node.js
 * EventEmitter interface.
 *
 * @constructor
 * @api public
 */
function EventEmitter() { /* Nothing to set */ }

/**
 * Hold the assigned EventEmitters by name.
 *
 * @type {Object}
 * @private
 */
EventEmitter.prototype._events = undefined;

/**
 * Return an array listing the events for which the emitter has registered
 * listeners.
 *
 * @returns {Array}
 * @api public
 */
EventEmitter.prototype.eventNames = function eventNames() {
  var events = this._events
    , names = []
    , name;

  if (!events) return names;

  for (name in events) {
    if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
  }

  if (Object.getOwnPropertySymbols) {
    return names.concat(Object.getOwnPropertySymbols(events));
  }

  return names;
};

/**
 * Return a list of assigned event listeners.
 *
 * @param {String} event The events that should be listed.
 * @param {Boolean} exists We only need to know if there are listeners.
 * @returns {Array|Boolean}
 * @api public
 */
EventEmitter.prototype.listeners = function listeners(event, exists) {
  var evt = prefix ? prefix + event : event
    , available = this._events && this._events[evt];

  if (exists) return !!available;
  if (!available) return [];
  if (available.fn) return [available.fn];

  for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) {
    ee[i] = available[i].fn;
  }

  return ee;
};

/**
 * Emit an event to all registered event listeners.
 *
 * @param {String} event The name of the event.
 * @returns {Boolean} Indication if we've emitted an event.
 * @api public
 */
EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
  var evt = prefix ? prefix + event : event;

  if (!this._events || !this._events[evt]) return false;

  var listeners = this._events[evt]
    , len = arguments.length
    , args
    , i;

  if (listeners.fn) {
    if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);

    switch (len) {
      case 1: return listeners.fn.call(listeners.context), true;
      case 2: return listeners.fn.call(listeners.context, a1), true;
      case 3: return listeners.fn.call(listeners.context, a1, a2), true;
      case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
      case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
      case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
    }

    for (i = 1, args = new Array(len -1); i < len; i++) {
      args[i - 1] = arguments[i];
    }

    listeners.fn.apply(listeners.context, args);
  } else {
    var length = listeners.length
      , j;

    for (i = 0; i < length; i++) {
      if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);

      switch (len) {
        case 1: listeners[i].fn.call(listeners[i].context); break;
        case 2: listeners[i].fn.call(listeners[i].context, a1); break;
        case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
        default:
          if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
            args[j - 1] = arguments[j];
          }

          listeners[i].fn.apply(listeners[i].context, args);
      }
    }
  }

  return true;
};

/**
 * Register a new EventListener for the given event.
 *
 * @param {String} event Name of the event.
 * @param {Function} fn Callback function.
 * @param {Mixed} [context=this] The context of the function.
 * @api public
 */
EventEmitter.prototype.on = function on(event, fn, context) {
  var listener = new EE(fn, context || this)
    , evt = prefix ? prefix + event : event;

  if (!this._events) this._events = prefix ? {} : Object.create(null);
  if (!this._events[evt]) this._events[evt] = listener;
  else {
    if (!this._events[evt].fn) this._events[evt].push(listener);
    else this._events[evt] = [
      this._events[evt], listener
    ];
  }

  return this;
};

/**
 * Add an EventListener that's only called once.
 *
 * @param {String} event Name of the event.
 * @param {Function} fn Callback function.
 * @param {Mixed} [context=this] The context of the function.
 * @api public
 */
EventEmitter.prototype.once = function once(event, fn, context) {
  var listener = new EE(fn, context || this, true)
    , evt = prefix ? prefix + event : event;

  if (!this._events) this._events = prefix ? {} : Object.create(null);
  if (!this._events[evt]) this._events[evt] = listener;
  else {
    if (!this._events[evt].fn) this._events[evt].push(listener);
    else this._events[evt] = [
      this._events[evt], listener
    ];
  }

  return this;
};

/**
 * Remove event listeners.
 *
 * @param {String} event The event we want to remove.
 * @param {Function} fn The listener that we need to find.
 * @param {Mixed} context Only remove listeners matching this context.
 * @param {Boolean} once Only remove once listeners.
 * @api public
 */
EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
  var evt = prefix ? prefix + event : event;

  if (!this._events || !this._events[evt]) return this;

  var listeners = this._events[evt]
    , events = [];

  if (fn) {
    if (listeners.fn) {
      if (
           listeners.fn !== fn
        || (once && !listeners.once)
        || (context && listeners.context !== context)
      ) {
        events.push(listeners);
      }
    } else {
      for (var i = 0, length = listeners.length; i < length; i++) {
        if (
             listeners[i].fn !== fn
          || (once && !listeners[i].once)
          || (context && listeners[i].context !== context)
        ) {
          events.push(listeners[i]);
        }
      }
    }
  }

  //
  // Reset the array, or remove it completely if we have no more listeners.
  //
  if (events.length) {
    this._events[evt] = events.length === 1 ? events[0] : events;
  } else {
    delete this._events[evt];
  }

  return this;
};

/**
 * Remove all listeners or only the listeners for the specified event.
 *
 * @param {String} event The event want to remove all listeners for.
 * @api public
 */
EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
  if (!this._events) return this;

  if (event) delete this._events[prefix ? prefix + event : event];
  else this._events = prefix ? {} : Object.create(null);

  return this;
};

//
// Alias methods names because people roll like that.
//
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
EventEmitter.prototype.addListener = EventEmitter.prototype.on;

//
// This function doesn't apply anymore.
//
EventEmitter.prototype.setMaxListeners = function setMaxListeners() {
  return this;
};

//
// Expose the prefix.
//
EventEmitter.prefixed = prefix;

//
// Expose the module.
//
if ('undefined' !== typeof module) {
  module.exports = EventEmitter;
}
<|endoftext|>


<commit_before>var net = require('net');
var HOST = '127.0.0.1';
var PORT = 6100;
var _interval = parseInt(process.argv[1]) || 250;
var claves = ['M00'];
var idxI = 0;

function poll()
{

	client = new net.Socket();

	client.connect(PORT, HOST, function() {
		// Write a message to the socket as soon as the client is connected, the server will receive it as message from the client
		curClave = claves[idxI];
		//console.log('>'+curClave+'\r\n');
		client.write(curClave);

		idxI++;
		if (idxI >= claves.length) {
			idxI=0;
			}
	});

	// Add a 'data' event handler for the client socket
	// data is what the server sent to this socket
	client.on('data', function(data) {
		console.log(data.toString());
		// Close the client socket completely
		client.end();
		client.destroy();
	});

	client.on('end', function() {
		//console.log('client disconnected\r\n');
	});

	setTimeout(poll, _interval);
}
poll();

<commit_msg>change poll time 125<commit_after>var net = require('net');
var HOST = '127.0.0.1';
var PORT = 6100;
var _interval = parseInt(process.argv[1]) || 125;
var claves = ['M00'];
var idxI = 0;

function poll()
{

	client = new net.Socket();

	client.connect(PORT, HOST, function() {
		// Write a message to the socket as soon as the client is connected, the server will receive it as message from the client
		curClave = claves[idxI];
		//console.log('>'+curClave+'\r\n');
		client.write(curClave);

		idxI++;
		if (idxI >= claves.length) {
			idxI=0;
			}
	});

	// Add a 'data' event handler for the client socket
	// data is what the server sent to this socket
	client.on('data', function(data) {
		console.log(data.toString());
		// Close the client socket completely
		client.end();
		client.destroy();
	});

	client.on('end', function() {
		//console.log('client disconnected\r\n');
	});

	setTimeout(poll, _interval);
}
poll();

<|endoftext|>


<commit_before>var fs = require( 'fs' );
var util = require( 'util' );
var glob = require( 'glob' );
var peliasConfig = require( 'pelias-config' ).generate();
var combinedStream = require( 'combined-stream' );
var logger = require( 'pelias-logger' ).get( 'openaddresses' );
var peliasDbclient = require( 'pelias-dbclient' );
var through = require('through2');
var peliasModel = require('pelias-model');

var files = glob.sync( '../../whosonfirst-data/data/**/*[0-9].geojson' );

var Document = require('pelias-model').Document;

console.log('importing ' + files.length + ' files');

var wofRecords = {};

files.forEach( function forEach( wofFile ) {
  if (wofFile.indexOf('85633345.geojson') !== -1) {
    return;
  }

  var wofRecord = JSON.parse(fs.readFileSync(wofFile));

  var id = wofRecord.id;

  if (!wofRecord.hasOwnProperty('properties')) {
    console.log(wofFile + ' has no properties');
  }
  else if (!id) {
    console.log(wofFile + ' has no id');
  }
  else {
    if (wofRecords[id]) {
      console.log(id + ' is a duplicate');
    }

    wofRecords[id] = {
      'id': id,
      'n': wofRecord.properties['wof:name'],
      'pr': wofRecord.properties['wof:parent_id'],
      // 'pt': wofRecord.properties['wof:path'],
      // 'h': wofRecord.properties['wof:hierarchy'],
      // 'gh': wofRecord.properties['wof:geomhash'],
      'lat': wofRecord.properties['geom:latitude'],
      'lon': wofRecord.properties['geom:longitude'],
      'pt': wofRecord.properties['wof:placetype'],
      // 'bb': wofRecord.bbox,
      // 'g': wofRecord.geometry
    }
  }
});

console.log(Object.keys(wofRecords).length + ' records loaded');

/**
 * Create the Pelias elasticsearch import pipeline.
 *
 * @return {stream.Writable} The entry point to the elasticsearch pipeline,
 *    which will perform additional processing on inbound `Document` objects
 *    before indexing them in the elasticsearch pelias index.
 */
function createPeliasElasticsearchPipeline(){
  var dbclientMapper = through.obj( function( model, enc, next ){
    this.push({
      _index: 'pelias',
      _type: model.getType(),
      _id: model.getId(),
      data: model
    });
    next();
  });

  var entryPoint = dbclientMapper;
  entryPoint.pipe( peliasDbclient() );

  return entryPoint;
}

var Readable = require('stream').Readable;
var rs = new Readable({objectMode: true});
rs.pipe(createPeliasElasticsearchPipeline());

Object.keys(wofRecords).forEach(function(objectKey) {
  var item = wofRecords[objectKey];
  var model_id = objectKey;
  var wofDoc = new peliasModel.Document( 'whosonfirst', model_id );
  if (item.n) {
    wofDoc.setName('default', item.n);
  } else {
    console.log('item ' + item.id + 'has no name');
  }
  wofDoc.setCentroid({ lat: item.lat, lon: item.lon});

  rs.push(wofDoc);
});

rs.push(null);
<commit_msg>Space<commit_after>var fs = require( 'fs' );
var util = require( 'util' );
var glob = require( 'glob' );
var peliasConfig = require( 'pelias-config' ).generate();
var combinedStream = require( 'combined-stream' );
var logger = require( 'pelias-logger' ).get( 'openaddresses' );
var peliasDbclient = require( 'pelias-dbclient' );
var through = require('through2');
var peliasModel = require('pelias-model');

var files = glob.sync( '../../whosonfirst-data/data/**/*[0-9].geojson' );

var Document = require('pelias-model').Document;

console.log('importing ' + files.length + ' files');

var wofRecords = {};

files.forEach( function forEach( wofFile ) {
  if (wofFile.indexOf('85633345.geojson') !== -1) {
    return;
  }

  var wofRecord = JSON.parse(fs.readFileSync(wofFile));

  var id = wofRecord.id;

  if (!wofRecord.hasOwnProperty('properties')) {
    console.log(wofFile + ' has no properties');
  }
  else if (!id) {
    console.log(wofFile + ' has no id');
  }
  else {
    if (wofRecords[id]) {
      console.log(id + ' is a duplicate');
    }

    wofRecords[id] = {
      'id': id,
      'n': wofRecord.properties['wof:name'],
      'pr': wofRecord.properties['wof:parent_id'],
      // 'pt': wofRecord.properties['wof:path'],
      // 'h': wofRecord.properties['wof:hierarchy'],
      // 'gh': wofRecord.properties['wof:geomhash'],
      'lat': wofRecord.properties['geom:latitude'],
      'lon': wofRecord.properties['geom:longitude'],
      'pt': wofRecord.properties['wof:placetype'],
      // 'bb': wofRecord.bbox,
      // 'g': wofRecord.geometry
    }
  }
});

console.log(Object.keys(wofRecords).length + ' records loaded');

/**
 * Create the Pelias elasticsearch import pipeline.
 *
 * @return {stream.Writable} The entry point to the elasticsearch pipeline,
 *    which will perform additional processing on inbound `Document` objects
 *    before indexing them in the elasticsearch pelias index.
 */
function createPeliasElasticsearchPipeline(){
  var dbclientMapper = through.obj( function( model, enc, next ){
    this.push({
      _index: 'pelias',
      _type: model.getType(),
      _id: model.getId(),
      data: model
    });
    next();
  });

  var entryPoint = dbclientMapper;
  entryPoint.pipe( peliasDbclient() );

  return entryPoint;
}

var Readable = require('stream').Readable;
var rs = new Readable({objectMode: true});
rs.pipe(createPeliasElasticsearchPipeline());

Object.keys(wofRecords).forEach(function(objectKey) {
  var item = wofRecords[objectKey];
  var model_id = objectKey;
  var wofDoc = new peliasModel.Document( 'whosonfirst', model_id );
  if (item.n) {
    wofDoc.setName('default', item.n);
  } else {
    console.log('item ' + item.id + ' has no name');
  }
  wofDoc.setCentroid({ lat: item.lat, lon: item.lon});

  rs.push(wofDoc);
});

rs.push(null);
<|endoftext|>


<commit_before>var _ = require('lodash');
var fs = require('fs');
var path = require('path');
var es6 = require('es6-promise');
var mkdirp = require('mkdirp');
var browserify = require('browserify');
var watchify = require('watchify');
var Writer = require('broccoli-writer');

function Watchify(inputTree, options) {
  if (!(this instanceof Watchify)) {
    return new Watchify(inputTree, options);
  }
  this.options = _.extend(this.getDefaultOptions(), options);
  this.inputTree = inputTree;
  this.watchifyData = watchify.args;
}

Watchify.prototype = Object.create(Writer.prototype);
Watchify.prototype.constructor = Watchify;
Watchify.prototype.getDefaultOptions = function () {
  return {
    entries: [],
    outputFile: '/browserify.js',
    browserify: {},
    require: {}
  };
};

Watchify.prototype.write = function (readTree, destDir) {
  var self = this;
  var o = this.options;

  return readTree(this.inputTree).then(function (srcDir) {
    mkdirp.sync(path.join(destDir, path.dirname(o.outputFile)));

    o.browserify.basedir = srcDir;

    var w = watchify(browserify(_.extend(o.browserify, self.watchifyData)));

    _.each(o.entries, w.add.bind(w));
    _.each(o.require, function (req) {
      w.require.apply(w, req);
    });

    return new es6.Promise(function (resolve, reject) {
      w.bundle(function (err, data) {
        if (err) {
          reject(err);
        } else {
          fs.writeFileSync(path.join(destDir, o.outputFile), data);
          resolve(destDir);
        }
      });
    });
  });
};

module.exports = Watchify;
<commit_msg>Add support for passing excludes to browserify.<commit_after>var _ = require('lodash');
var fs = require('fs');
var path = require('path');
var es6 = require('es6-promise');
var mkdirp = require('mkdirp');
var browserify = require('browserify');
var watchify = require('watchify');
var Writer = require('broccoli-writer');

function Watchify(inputTree, options) {
  if (!(this instanceof Watchify)) {
    return new Watchify(inputTree, options);
  }
  this.options = _.extend(this.getDefaultOptions(), options);
  this.inputTree = inputTree;
  this.watchifyData = watchify.args;
}

Watchify.prototype = Object.create(Writer.prototype);
Watchify.prototype.constructor = Watchify;
Watchify.prototype.getDefaultOptions = function () {
  return {
    entries: [],
    outputFile: '/browserify.js',
    browserify: {},
    require: {},
    transform: [],
    exclude: [],
  };
};

Watchify.prototype.write = function (readTree, destDir) {
  var self = this;
  var o = this.options;

  return readTree(this.inputTree).then(function (srcDir) {
    mkdirp.sync(path.join(destDir, path.dirname(o.outputFile)));

    o.browserify.basedir = srcDir;

    var w = watchify(browserify(_.extend(o.browserify, self.watchifyData)));

    _.each(o.entries, w.add.bind(w));
    _.each(o.require, function (req) {
      w.require.apply(w, req);
    });
    _.each(o.transform, function (tr) {
      w.transform.apply(w, tr);
    });
    _.each(o.exclude, w.exclude.bind(w));

    return new es6.Promise(function (resolve, reject) {
      w.bundle(function (err, data) {
        if (err) {
          reject(err);
        } else {
          fs.writeFileSync(path.join(destDir, o.outputFile), data);
          resolve(destDir);
        }
      });
    });
  });
};

module.exports = Watchify;
<|endoftext|>


<commit_before>'use strict';

// Native
const path = require('path');
const spawn = require('child_process').spawn;

// Packages
const parser = require('minimist');
const pkginfo = require('pkginfo');
const camelcase = require('camelcase');
const chalk = require('chalk');

class Args {
  constructor() {
    // Will later hold registered options and commands
    this.details = {
      options: [],
      commands: [],
      examples: []
    };

    // Configuration defaults
    this.config = {
      help: true,
      version: true,
      usageFilter: null,
      value: null,
      name: null,
      mainColor: 'yellow',
      subColor: 'dim'
    };

    this.printMainColor = chalk;
    this.printSubColor = chalk;
  }

  example(usage, description) {
    if (typeof usage !== 'string' || typeof description !== 'string') {
      throw new Error(
        'Usage for adding an Example: args.example("usage", "description")'
      );
    }
    this.details.examples.push({ usage, description });

    return this;
  }

  examples(list) {
    if (list.constructor !== Array) {
      throw new Error('Item passed to .examples is not an array');
    }

    for (const item of list) {
      const usage = item.usage || false;
      const description = item.description || false;
      this.example(usage, description);
    }

    return this;
  }

  options(list) {
    if (list.constructor !== Array) {
      throw new Error('Item passed to .options is not an array');
    }

    for (const item of list) {
      const preset = item.defaultValue;
      const init = item.init || false;

      this.option(item.name, item.description, preset, init);
    }

    return this;
  }

  option(name, description, defaultValue, init) {
    let usage = [];

    const assignShort = (name, options, short) => {
      if (options.find(flagName => flagName.usage[0] === short)) {
        short = name.charAt(0).toUpperCase();
      }
      return [short, name];
    };

    // If name is an array, pick the values
    // Otherwise just use the whole thing
    switch (name.constructor) {
      case String:
        usage = assignShort(name, this.details.options, name.charAt(0));
        break;
      case Array:
        usage = usage.concat(name);
        break;
      default:
        throw new Error('Invalid name for option');
    }

    // Throw error if short option is too long
    if (usage.length > 0 && usage[0].length > 1) {
      throw new Error('Short version of option is longer than 1 char');
    }

    const optionDetails = {
      defaultValue,
      usage,
      description
    };

    let defaultIsWrong;

    switch (defaultValue) {
      case false:
        defaultIsWrong = true;
        break;
      case null:
        defaultIsWrong = true;
        break;
      case undefined:
        defaultIsWrong = true;
        break;
      default:
        defaultIsWrong = false;
    }

    // Set initializer depending on type of default value
    if (!defaultIsWrong) {
      const initFunction = typeof init === 'function';
      optionDetails.init = initFunction
        ? init
        : this.handleType(defaultValue)[1];
    }

    // Register option to global scope
    this.details.options.push(optionDetails);

    // Allow chaining of .option()
    return this;
  }

  command(usage, description, init, aliases) {
    if (Array.isArray(init)) {
      aliases = init;
      init = undefined;
    }
    if (aliases && Array.isArray(aliases)) {
      usage = [].concat([usage], aliases);
    }

    // Register command to global scope
    this.details.commands.push({
      usage,
      description,
      init: typeof init === 'function' ? init : false
    });

    // Allow chaining of .command()
    return this;
  }

  handleType(value) {
    let type = value;

    if (typeof value !== 'function') {
      type = value.constructor;
    }

    // Depending on the type of the default value,
    // select a default initializer function
    switch (type) {
      case String:
        return ['[value]'];
      case Array:
        return ['<list>'];
      case Number:
      case parseInt:
        return ['<n>', parseInt];
      default:
        return [''];
    }
  }

  readOption(option) {
    let value = option.defaultValue;
    const contents = {};

    // If option has been used, get its value
    for (const name of option.usage) {
      const fromArgs = this.raw[name];
      if (typeof fromArgs !== 'undefined') {
        value = fromArgs;
      }
    }

    // Process the option's value
    for (let name of option.usage) {
      let propVal = value;

      if (
        typeof option.defaultValue !== 'undefined' &&
        typeof propVal !== typeof option.defaultValue
      ) {
        propVal = option.defaultValue;
      }

      let condition = true;

      if (option.init) {
        // Only use the toString initializer if value is a number
        if (option.init === toString) {
          condition = propVal.constructor === Number;
        }

        if (condition) {
          // Pass it through the initializer
          propVal = option.init(propVal);
        }
      }

      // Camelcase option name (skip short flag)
      if (name.length > 1) {
        name = camelcase(name);
      }

      // Add option to list
      contents[name] = propVal;
    }

    return contents;
  }

  getOptions() {
    const options = {};
    const args = {};

    // Copy over the arguments
    Object.assign(args, this.raw);
    delete args._;

    // Set option defaults
    for (const option of this.details.options) {
      if (typeof option.defaultValue === 'undefined') {
        continue;
      }

      Object.assign(options, this.readOption(option));
    }

    // Override defaults if used in command line
    for (const option in args) {
      if (!{}.hasOwnProperty.call(args, option)) {
        continue;
      }

      const related = this.isDefined(option, 'options');

      if (related) {
        const details = this.readOption(related);
        Object.assign(options, details);
      }
    }

    return options;
  }

  generateExamples() {
    const examples = this.details.examples;
    const parts = [];

    for (const item in examples) {
      if (!{}.hasOwnProperty.call(examples, item)) {
        continue;
      }
      const usage = this.printSubColor('$ ' + examples[item].usage);
      const description = this.printMainColor(
        '- ' + examples[item].description
      );
      parts.push(`  ${description}\n\n    ${usage}\n\n`);
    }

    return parts;
  }

  generateDetails(kind) {
    // Get all properties of kind from global scope
    const items = this.details[kind];
    const parts = [];
    const isCmd = kind === 'commands';

    // Sort items alphabetically
    items.sort((a, b) => {
      const first = isCmd ? a.usage : a.usage[1];
      const second = isCmd ? b.usage : b.usage[1];

      switch (true) {
        case first < second:
          return -1;
        case first > second:
          return 1;
        default:
          return 0;
      }
    });

    for (const item in items) {
      if (!{}.hasOwnProperty.call(items, item)) {
        continue;
      }

      let usage = items[item].usage;
      let initial = items[item].defaultValue;

      // If usage is an array, show its contents
      if (usage.constructor === Array) {
        if (isCmd) {
          usage = usage.join(', ');
        } else {
          const isVersion = usage.indexOf('v');
          usage = `-${usage[0]}, --${usage[1]}`;

          if (!initial) {
            initial = items[item].init;
          }

          usage += initial && isVersion === -1
            ? ' ' + this.handleType(initial)[0]
            : '';
        }
      }

      // Overwrite usage with readable syntax
      items[item].usage = usage;
    }

    // Find length of longest option or command
    // Before doing that, make a copy of the original array
    const longest = items.slice().sort((a, b) => {
      return b.usage.length - a.usage.length;
    })[0].usage.length;

    for (const item of items) {
      let usage = item.usage;
      let description = item.description;
      const defaultValue = item.defaultValue;
      const difference = longest - usage.length;

      // Compensate the difference to longest property with spaces
      usage += ' '.repeat(difference);

      // Add some space around it as well
      if (typeof defaultValue !== 'undefined') {
        if (typeof defaultValue === 'boolean') {
          description += ` (${defaultValue ? 'enabled' : 'disabled'} by default)`;
        } else {
          description += ` (defaults to ${JSON.stringify(defaultValue)})`;
        }
      }
      parts.push(
        '  ' +
          this.printMainColor(usage) +
          '  ' +
          this.printSubColor(description)
      );
    }

    return parts;
  }

  runCommand(details, options) {
    // If help is disabled, remove initializer
    if (details.usage === 'help' && !this.config.help) {
      details.init = false;
    }

    // If command has initializer, call it
    if (details.init) {
      const sub = [].concat(this.sub);
      sub.shift();

      return details.init.bind(this)(details.usage, sub, options);
    }

    // Generate full name of binary
    const full = this.binary +
      '-' +
      (Array.isArray(details.usage) ? details.usage[0] : details.usage);

    const args = process.argv;
    let i = 0;

    while (i < 3) {
      args.shift();
      i++;
    }

    // Run binary of sub command
    this.child = spawn(full, args, {
      stdio: 'inherit'
    });

    // Throw an error if something fails within that binary
    this.child.on('error', err => {
      throw err;
    });

    this.child.on('exit', (code, signal) => {
      process.on('exit', () => {
        this.child = null;
        if (signal) {
          process.kill(process.pid, signal);
        } else {
          process.exit(code);
        }
      });
    });

    // proxy SIGINT to child process
    process.on('SIGINT', () => {
      if (this.child) {
        this.child.kill('SIGINT');
        this.child.kill('SIGTERM'); // if that didn't work, we're probably in an infinite loop, so make it die
      }
    });
  }

  checkVersion() {
    const parent = module.parent;

    // Load parent module
    pkginfo(parent);

    // And get its version propery
    const version = parent.exports.version;

    if (version) {
      // If it exists, register it as a default option
      this.option('version', 'Output the version number');

      // And immediately output it if used in command line
      if (this.raw.v || this.raw.version) {
        console.log(version);

        // eslint-disable-next-line unicorn/no-process-exit
        process.exit();
      }
    }
  }

  isDefined(name, list) {
    // Get all items of kind
    const children = this.details[list];

    // Check if a child matches the requested name
    for (const child of children) {
      const usage = child.usage;
      const type = usage.constructor;

      if (type === Array && usage.indexOf(name) > -1) {
        return child;
      }

      if (type === String && usage === name) {
        return child;
      }
    }

    // If nothing matches, item is not defined
    return false;
  }

  parse(argv, options) {
    // Override default option values
    Object.assign(this.config, options);

    if (Array.isArray(this.config.mainColor)) {
      for (const item in this.config.mainColor) {
        if (!{}.hasOwnProperty.call(this.config.mainColor, item)) {
          continue;
        }
        // chain all colors to our print method
        this.printMainColor = this.printMainColor[this.config.mainColor[item]];
      }
    } else {
      this.printMainColor = this.printMainColor[this.config.mainColor];
    }

    if (Array.isArray(this.config.subColor)) {
      for (const item in this.config.subColor) {
        if (!{}.hasOwnProperty.call(this.config.subColor, item)) {
          continue;
        }
        // chain all colors to our print method
        this.printSubColor = this.printSubColor[this.config.subColor[item]];
      }
    } else {
      this.printSubColor = this.printSubColor[this.config.subColor];
    }

    if (this.config.help) {
      // Register default options and commands
      this.option('help', 'Output usage information');
      this.command('help', 'Display help', this.showHelp);
    }

    // Parse arguments using minimist
    this.raw = parser(argv.slice(1), this.config.minimist);
    this.binary = path.basename(this.raw._[0]);

    // If default version is allowed, check for it
    if (this.config.version) {
      this.checkVersion();
    }

    const subCommand = this.raw._[1];
    const helpTriggered = this.raw.h || this.raw.help;

    const args = {};
    const defined = this.isDefined(subCommand, 'commands');
    const optionList = this.getOptions();

    Object.assign(args, this.raw);
    args._.shift();

    // Export sub arguments of command
    this.sub = args._;

    // If sub command is defined, run it
    if (defined) {
      this.runCommand(defined, optionList);
      return {};
    }

    // Show usage information if "help" or "h" option was used
    // And respect the option related to it
    if (this.config.help && helpTriggered) {
      this.showHelp();
    }

    // Hand back list of options
    return optionList;
  }

  showHelp() {
    const name = this.config.name || this.binary.replace('-', ' ');
    const firstBig = word => word.charAt(0).toUpperCase() + word.substr(1);

    const parts = [];

    const groups = {
      commands: true,
      options: true,
      examples: true
    };

    for (const group in groups) {
      if (this.details[group].length > 0) {
        continue;
      }

      groups[group] = false;
    }

    const optionHandle = groups.options ? '[options] ' : '';
    const cmdHandle = groups.commands ? '[command]' : '';
    const value = typeof this.config.value === 'string'
      ? ' ' + this.config.value
      : '';

    parts.push([
      '',
      `Usage: ${this.printMainColor(name)} ${this.printSubColor(optionHandle + cmdHandle + value)}`,
      ''
    ]);

    for (const group in groups) {
      if (!groups[group]) {
        continue;
      }

      parts.push(['', firstBig(group) + ':', '', '']);

      if (group === 'examples') {
        parts.push(this.generateExamples());
      } else {
        parts.push(this.generateDetails(group));
      }

      parts.push(['', '']);
    }

    let output = '';

    // And finally, merge and output them
    for (const part of parts) {
      output += part.join('\n  ');
    }

    if (!groups.commands && !groups.options) {
      output = 'No sub commands or options available';
    }

    const usageFilter = this.config.usageFilter;

    // If filter is available, pass usage information through
    if (typeof usageFilter === 'function') {
      output = usageFilter(output) || output;
    }

    console.log(output);

    // eslint-disable-next-line unicorn/no-process-exit
    process.exit();
  }
}

module.exports = (exports.default = new Args());
<commit_msg>Fixed linting<commit_after>'use strict';

// Native
const path = require('path');
const spawn = require('child_process').spawn;

// Packages
const parser = require('minimist');
const pkginfo = require('pkginfo');
const camelcase = require('camelcase');
const chalk = require('chalk');

class Args {
  constructor() {
    // Will later hold registered options and commands
    this.details = {
      options: [],
      commands: [],
      examples: []
    };

    // Configuration defaults
    this.config = {
      help: true,
      version: true,
      usageFilter: null,
      value: null,
      name: null,
      mainColor: 'yellow',
      subColor: 'dim'
    };

    this.printMainColor = chalk;
    this.printSubColor = chalk;
  }

  example(usage, description) {
    if (typeof usage !== 'string' || typeof description !== 'string') {
      throw new TypeError(
        'Usage for adding an Example: args.example("usage", "description")'
      );
    }
    this.details.examples.push({ usage, description });

    return this;
  }

  examples(list) {
    if (list.constructor !== Array) {
      throw new Error('Item passed to .examples is not an array');
    }

    for (const item of list) {
      const usage = item.usage || false;
      const description = item.description || false;
      this.example(usage, description);
    }

    return this;
  }

  options(list) {
    if (list.constructor !== Array) {
      throw new Error('Item passed to .options is not an array');
    }

    for (const item of list) {
      const preset = item.defaultValue;
      const init = item.init || false;

      this.option(item.name, item.description, preset, init);
    }

    return this;
  }

  option(name, description, defaultValue, init) {
    let usage = [];

    const assignShort = (name, options, short) => {
      if (options.find(flagName => flagName.usage[0] === short)) {
        short = name.charAt(0).toUpperCase();
      }
      return [short, name];
    };

    // If name is an array, pick the values
    // Otherwise just use the whole thing
    switch (name.constructor) {
      case String:
        usage = assignShort(name, this.details.options, name.charAt(0));
        break;
      case Array:
        usage = usage.concat(name);
        break;
      default:
        throw new Error('Invalid name for option');
    }

    // Throw error if short option is too long
    if (usage.length > 0 && usage[0].length > 1) {
      throw new Error('Short version of option is longer than 1 char');
    }

    const optionDetails = {
      defaultValue,
      usage,
      description
    };

    let defaultIsWrong;

    switch (defaultValue) {
      case false:
        defaultIsWrong = true;
        break;
      case null:
        defaultIsWrong = true;
        break;
      case undefined:
        defaultIsWrong = true;
        break;
      default:
        defaultIsWrong = false;
    }

    // Set initializer depending on type of default value
    if (!defaultIsWrong) {
      const initFunction = typeof init === 'function';
      optionDetails.init = initFunction
        ? init
        : this.handleType(defaultValue)[1];
    }

    // Register option to global scope
    this.details.options.push(optionDetails);

    // Allow chaining of .option()
    return this;
  }

  command(usage, description, init, aliases) {
    if (Array.isArray(init)) {
      aliases = init;
      init = undefined;
    }
    if (aliases && Array.isArray(aliases)) {
      usage = [].concat([usage], aliases);
    }

    // Register command to global scope
    this.details.commands.push({
      usage,
      description,
      init: typeof init === 'function' ? init : false
    });

    // Allow chaining of .command()
    return this;
  }

  handleType(value) {
    let type = value;

    if (typeof value !== 'function') {
      type = value.constructor;
    }

    // Depending on the type of the default value,
    // select a default initializer function
    switch (type) {
      case String:
        return ['[value]'];
      case Array:
        return ['<list>'];
      case Number:
      case parseInt:
        return ['<n>', parseInt];
      default:
        return [''];
    }
  }

  readOption(option) {
    let value = option.defaultValue;
    const contents = {};

    // If option has been used, get its value
    for (const name of option.usage) {
      const fromArgs = this.raw[name];
      if (typeof fromArgs !== 'undefined') {
        value = fromArgs;
      }
    }

    // Process the option's value
    for (let name of option.usage) {
      let propVal = value;

      if (
        typeof option.defaultValue !== 'undefined' &&
        typeof propVal !== typeof option.defaultValue
      ) {
        propVal = option.defaultValue;
      }

      let condition = true;

      if (option.init) {
        // Only use the toString initializer if value is a number
        if (option.init === toString) {
          condition = propVal.constructor === Number;
        }

        if (condition) {
          // Pass it through the initializer
          propVal = option.init(propVal);
        }
      }

      // Camelcase option name (skip short flag)
      if (name.length > 1) {
        name = camelcase(name);
      }

      // Add option to list
      contents[name] = propVal;
    }

    return contents;
  }

  getOptions() {
    const options = {};
    const args = {};

    // Copy over the arguments
    Object.assign(args, this.raw);
    delete args._;

    // Set option defaults
    for (const option of this.details.options) {
      if (typeof option.defaultValue === 'undefined') {
        continue;
      }

      Object.assign(options, this.readOption(option));
    }

    // Override defaults if used in command line
    for (const option in args) {
      if (!{}.hasOwnProperty.call(args, option)) {
        continue;
      }

      const related = this.isDefined(option, 'options');

      if (related) {
        const details = this.readOption(related);
        Object.assign(options, details);
      }
    }

    return options;
  }

  generateExamples() {
    const examples = this.details.examples;
    const parts = [];

    for (const item in examples) {
      if (!{}.hasOwnProperty.call(examples, item)) {
        continue;
      }
      const usage = this.printSubColor('$ ' + examples[item].usage);
      const description = this.printMainColor(
        '- ' + examples[item].description
      );
      parts.push(`  ${description}\n\n    ${usage}\n\n`);
    }

    return parts;
  }

  generateDetails(kind) {
    // Get all properties of kind from global scope
    const items = this.details[kind];
    const parts = [];
    const isCmd = kind === 'commands';

    // Sort items alphabetically
    items.sort((a, b) => {
      const first = isCmd ? a.usage : a.usage[1];
      const second = isCmd ? b.usage : b.usage[1];

      switch (true) {
        case first < second:
          return -1;
        case first > second:
          return 1;
        default:
          return 0;
      }
    });

    for (const item in items) {
      if (!{}.hasOwnProperty.call(items, item)) {
        continue;
      }

      let usage = items[item].usage;
      let initial = items[item].defaultValue;

      // If usage is an array, show its contents
      if (usage.constructor === Array) {
        if (isCmd) {
          usage = usage.join(', ');
        } else {
          const isVersion = usage.indexOf('v');
          usage = `-${usage[0]}, --${usage[1]}`;

          if (!initial) {
            initial = items[item].init;
          }

          usage += initial && isVersion === -1
            ? ' ' + this.handleType(initial)[0]
            : '';
        }
      }

      // Overwrite usage with readable syntax
      items[item].usage = usage;
    }

    // Find length of longest option or command
    // Before doing that, make a copy of the original array
    const longest = items.slice().sort((a, b) => {
      return b.usage.length - a.usage.length;
    })[0].usage.length;

    for (const item of items) {
      let usage = item.usage;
      let description = item.description;
      const defaultValue = item.defaultValue;
      const difference = longest - usage.length;

      // Compensate the difference to longest property with spaces
      usage += ' '.repeat(difference);

      // Add some space around it as well
      if (typeof defaultValue !== 'undefined') {
        if (typeof defaultValue === 'boolean') {
          description += ` (${defaultValue ? 'enabled' : 'disabled'} by default)`;
        } else {
          description += ` (defaults to ${JSON.stringify(defaultValue)})`;
        }
      }
      parts.push(
        '  ' +
          this.printMainColor(usage) +
          '  ' +
          this.printSubColor(description)
      );
    }

    return parts;
  }

  runCommand(details, options) {
    // If help is disabled, remove initializer
    if (details.usage === 'help' && !this.config.help) {
      details.init = false;
    }

    // If command has initializer, call it
    if (details.init) {
      const sub = [].concat(this.sub);
      sub.shift();

      return details.init.bind(this)(details.usage, sub, options);
    }

    // Generate full name of binary
    const full = this.binary +
      '-' +
      (Array.isArray(details.usage) ? details.usage[0] : details.usage);

    const args = process.argv;
    let i = 0;

    while (i < 3) {
      args.shift();
      i++;
    }

    // Run binary of sub command
    this.child = spawn(full, args, {
      stdio: 'inherit'
    });

    // Throw an error if something fails within that binary
    this.child.on('error', err => {
      throw err;
    });

    this.child.on('exit', (code, signal) => {
      process.on('exit', () => {
        this.child = null;
        if (signal) {
          process.kill(process.pid, signal);
        } else {
          process.exit(code);
        }
      });
    });

    // Proxy SIGINT to child process
    process.on('SIGINT', () => {
      if (this.child) {
        this.child.kill('SIGINT');
        this.child.kill('SIGTERM'); // If that didn't work, we're probably in an infinite loop, so make it die
      }
    });
  }

  checkVersion() {
    const parent = module.parent;

    // Load parent module
    pkginfo(parent);

    // And get its version propery
    const version = parent.exports.version;

    if (version) {
      // If it exists, register it as a default option
      this.option('version', 'Output the version number');

      // And immediately output it if used in command line
      if (this.raw.v || this.raw.version) {
        console.log(version);

        // eslint-disable-next-line unicorn/no-process-exit
        process.exit();
      }
    }
  }

  isDefined(name, list) {
    // Get all items of kind
    const children = this.details[list];

    // Check if a child matches the requested name
    for (const child of children) {
      const usage = child.usage;
      const type = usage.constructor;

      if (type === Array && usage.indexOf(name) > -1) {
        return child;
      }

      if (type === String && usage === name) {
        return child;
      }
    }

    // If nothing matches, item is not defined
    return false;
  }

  parse(argv, options) {
    // Override default option values
    Object.assign(this.config, options);

    if (Array.isArray(this.config.mainColor)) {
      for (const item in this.config.mainColor) {
        if (!{}.hasOwnProperty.call(this.config.mainColor, item)) {
          continue;
        }

        // Chain all colors to our print method
        this.printMainColor = this.printMainColor[this.config.mainColor[item]];
      }
    } else {
      this.printMainColor = this.printMainColor[this.config.mainColor];
    }

    if (Array.isArray(this.config.subColor)) {
      for (const item in this.config.subColor) {
        if (!{}.hasOwnProperty.call(this.config.subColor, item)) {
          continue;
        }

        // Chain all colors to our print method
        this.printSubColor = this.printSubColor[this.config.subColor[item]];
      }
    } else {
      this.printSubColor = this.printSubColor[this.config.subColor];
    }

    if (this.config.help) {
      // Register default options and commands
      this.option('help', 'Output usage information');
      this.command('help', 'Display help', this.showHelp);
    }

    // Parse arguments using minimist
    this.raw = parser(argv.slice(1), this.config.minimist);
    this.binary = path.basename(this.raw._[0]);

    // If default version is allowed, check for it
    if (this.config.version) {
      this.checkVersion();
    }

    const subCommand = this.raw._[1];
    const helpTriggered = this.raw.h || this.raw.help;

    const args = {};
    const defined = this.isDefined(subCommand, 'commands');
    const optionList = this.getOptions();

    Object.assign(args, this.raw);
    args._.shift();

    // Export sub arguments of command
    this.sub = args._;

    // If sub command is defined, run it
    if (defined) {
      this.runCommand(defined, optionList);
      return {};
    }

    // Show usage information if "help" or "h" option was used
    // And respect the option related to it
    if (this.config.help && helpTriggered) {
      this.showHelp();
    }

    // Hand back list of options
    return optionList;
  }

  showHelp() {
    const name = this.config.name || this.binary.replace('-', ' ');
    const firstBig = word => word.charAt(0).toUpperCase() + word.substr(1);

    const parts = [];

    const groups = {
      commands: true,
      options: true,
      examples: true
    };

    for (const group in groups) {
      if (this.details[group].length > 0) {
        continue;
      }

      groups[group] = false;
    }

    const optionHandle = groups.options ? '[options] ' : '';
    const cmdHandle = groups.commands ? '[command]' : '';
    const value = typeof this.config.value === 'string'
      ? ' ' + this.config.value
      : '';

    parts.push([
      '',
      `Usage: ${this.printMainColor(name)} ${this.printSubColor(optionHandle + cmdHandle + value)}`,
      ''
    ]);

    for (const group in groups) {
      if (!groups[group]) {
        continue;
      }

      parts.push(['', firstBig(group) + ':', '', '']);

      if (group === 'examples') {
        parts.push(this.generateExamples());
      } else {
        parts.push(this.generateDetails(group));
      }

      parts.push(['', '']);
    }

    let output = '';

    // And finally, merge and output them
    for (const part of parts) {
      output += part.join('\n  ');
    }

    if (!groups.commands && !groups.options) {
      output = 'No sub commands or options available';
    }

    const usageFilter = this.config.usageFilter;

    // If filter is available, pass usage information through
    if (typeof usageFilter === 'function') {
      output = usageFilter(output) || output;
    }

    console.log(output);

    // eslint-disable-next-line unicorn/no-process-exit
    process.exit();
  }
}

const instance = new Args();

module.exports = instance;
exports.default = instance;
<|endoftext|>


<commit_before>var test = require('prova');
var mercury = require('mercury');
var _ = require('lodash');
var proxyquire = require('proxyquireify')(require);
var mockLRUCache = require('./mocks/lru-cache');

// 8885 is the expected wspr port to be running for the tests
// @noCallThru ensures this completely overrdies the original config
// instead of inheriting the properties that are not defined here from
// the original dependency
var veyronConfigForTest = {
  'authenticate': false,
  'wspr': 'http://localhost:8885',
  '@noCallThru': true
};

// Require namespaceService but using test specific mocks and configs
var namespaceService =
  proxyquire('../../../../src/services/namespace/service.js', {
    '../../veyron-config': veyronConfigForTest,
    'lru-cache': function() {
      return mockLRUCache;
    }
  });

test('getChildren of default namespace root', function(t) {
  namespaceService.getChildren().
  then(function assertResult(result) {
    assertIsImmutable(t, result);
    // Wait until we finish, we expect 2 top level items: cottage, house
    result.events.on('end', function validate() {
      mercury.watch(result, function(children) {
        children = _.sortBy(children, 'mountedName');
        assertCottage(children[0]);
        assertHouse(children[1]);
        t.end();
      });
    });
    result.events.on('streamError', t.end);
    result.events.on('itemError', t.end);
  }).catch(t.end);

  function assertCottage(item) {
    assertServer(t, item, {
      name: 'cottage',
      objectName: 'cottage',
      isGlobbable: true,
      type: 'mounttable'
    });
  }

  function assertHouse(item) {
    assertServer(t, item, {
      name: 'house',
      objectName: 'house',
      isGlobbable: true,
      type: 'mounttable'
    });
  }
});

test('getChildren of cottage/lawn', function(t) {
  namespaceService.getChildren('cottage/lawn').
  then(function assertResult(result) {
    assertIsImmutable(t, result);
    // Wait until we finish, we expect 3 items back, front and master-sprinkler
    result.events.on('end', function validate() {
      mercury.watch(result, function(children) {
        children = _.sortBy(children, 'mountedName');
        assertBack(children[0]);
        assertSprinkler(children[2]);
        t.end();
      });
    });
    result.events.on('streamError', t.end);
    result.events.on('itemError', t.end);
  }).catch(t.end);

  function assertSprinkler(item) {
    assertServer(t, item, {
      name: 'master-sprinkler',
      objectName: 'cottage/lawn/master-sprinkler',
      isGlobbable: false,
      type: 'unknown'
    });
  }

  function assertBack(item) {
    assertIntermediaryName(t, item, {
      name: 'back',
      objectName: 'cottage/lawn/back'
    });
  }
});

test('getChildren of rooted /localhost:8881/house/kitchen', function(t) {

  // 8881 is the expected root mounttable port to be running for the tests
  namespaceService.getChildren('/localhost:8881/house/kitchen').
  then(function assertResult(result) {
    assertIsImmutable(t, result);
    // Wait until we finish, we expect 2 items, lights and smoke-detector
    result.events.on('end', function validate() {
      mercury.watch(result, function(children) {
        children = _.sortBy(children, 'mountedName');
        assertLightSwitch(children[0]);
        assertSmokeDetector(children[1]);
        t.end();
      });
    });
    result.events.on('streamError', t.end);
    result.events.on('itemError', t.end);
  }).catch(t.end);

  function assertLightSwitch(item) {
    assertServer(t, item, {
      name: 'lights',
      objectName: '/localhost:8881/house/kitchen/lights',
      isGlobbable: false,
      type: 'unknown'
    });
  }

  function assertSmokeDetector(item) {
    assertServer(t, item, {
      name: 'smoke-detector',
      objectName: '/localhost:8881/house/kitchen/smoke-detector',
      isGlobbable: false,
      type: 'unknown'
    });
  }
});

// TODO(aghassemi) reenable when
// https://github.com/veyron/release-issues/issues/465
// is fixed
test.skip('getChildren of non-existing mounttable', function(t) {
  // TODO(aghassemi) why does namespace library return empty results instead of
  // error when globbing rooted names that don't exist?
  namespaceService.getChildren('/DoesNotExist:666/What/Ever').
  then(function assertResult(result) {
    result.events.on('end', function validate() {
      // Expect empty results
      mercury.watch(result, function(children) {
        t.deepEqual(children, []);
        t.end();
      });
    });
    result.events.on('streamError', t.end);
    result.events.on('itemError', t.end);
  }).catch(t.end);
});

test('getNamespaceItem of leaf server', function(t) {
  namespaceService.getNamespaceItem('cottage/lawn/master-sprinkler').
  then(function assertItem(itemObs) {
    assertIsImmutable(t, itemObs);
    var item = itemObs();
    assertServer(t, item, {
      name: 'master-sprinkler',
      objectName: 'cottage/lawn/master-sprinkler',
      isGlobbable: false,
      type: 'unknown'
    });
    t.end();
  }).catch(t.end);
});

test('getNamespaceItem of intermediary name', function(t) {
  namespaceService.getNamespaceItem('cottage/lawn/back').
  then(function assertItem(itemObs) {
    assertIsImmutable(t, itemObs);
    var item = itemObs();
    assertIntermediaryName(t, item, {
      name: 'back',
      objectName: 'cottage/lawn/back'
    });
    t.end();
  }).catch(t.end);
});

test('getNamespaceItem of mounttable leaf server', function(t) {
  namespaceService.getNamespaceItem('cottage').
  then(function assertItem(itemObs) {
    assertIsImmutable(t, itemObs);
    var item = itemObs();
    assertServer(t, item, {
      name: 'cottage',
      objectName: 'cottage',
      isGlobbable: true,
      type: 'mounttable'
    });
    t.end();
  }).catch(t.end);
});

test('search uses caching', function(t) {
  mockLRUCache.reset();

  namespaceService.search('house', '*').
  then(function assertNoCacheHit() {
    t.notOk(mockLRUCache.wasCacheHit('glob|house/*'),
      'first glob call is not a cache hit');

    // Call second time, there should have been a cache hit
    return namespaceService.search('house', '*');
  }).then(function assertCacheHit() {
    t.ok(mockLRUCache.wasCacheHit('glob|house/*'),
      'second glob call is a cache hit');

    // Call glob with same name, different query
    return namespaceService.search('house', 'foo*');
  }).then(function assertNoCacheHit() {
    t.notOk(mockLRUCache.wasCacheHit('glob|house/foo*'),
      'third glob call with different query is not a cache hit');
    t.end();
  }).catch(t.end);
});

test('getSignature uses caching', function(t) {
  mockLRUCache.reset();

  namespaceService.getSignature('house/alarm').then(function() {
    t.notOk(mockLRUCache.wasCacheHit('getSignature|house/alarm'),
      'first getSignature call is not a cache hit');
    // Call a second time
    return namespaceService.getSignature('house/alarm');
  }).then(function() {
    t.ok(mockLRUCache.wasCacheHit('getSignature|house/alarm'),
      'second getSignature call is a cache hit');
    // Call a different name
    return namespaceService.getSignature('house/kitchen/smoke-detector');
  }).then(function() {
    t.notOk(mockLRUCache.wasCacheHit(
      'getSignature|house/kitchen/smoke-detector'
    ),'third getSignature call to a different name is not a cache hit');
    t.end();
  }).catch(t.end);
});

//TODO(aghassemi)
//Tests for:
// Recursive glob
// Glob with some keyword
// Ensuring array is updated when nodes get mounted and unmounted (when we use
// watchGlob)

// Make RPC: good inputs => no error
var okRPCs = {
  'no input':     ['house/alarm', 'status', []],
  'bool input':   ['house/living-room/lights', 'flipSwitch', [true]],
  'int input':    ['cottage/smoke-detector', 'sensitivity', [2]],
  'float input':  ['house/alarm', 'delayArm', [2.5]],
  'string input': ['cottage/pool/speaker', 'playSong', ['Happy Birthday']],
  'slice input':  ['house/master-bedroom/speaker', 'addSongs', [['A', 'B']]],
  '2+ inputs':    ['cottage/pool/heater', 'start', [70, 5]],
};

_.forOwn(okRPCs, function run(params, inputType) {
  test(
    'makeRPC accepts good input - ' + inputType,
    testMakeRPCNoError.bind(null, params)
  );
});

// Make RPC: bad inputs => error
var badRPCs = {
  'no service':    ['mansion/smoke-detector', 'status', []],
  'no method':     ['cottage/pool/speaker', 'status', []],
  'no input':      ['cottage/lights','flipSwitch', null],
  'bad type':      ['cottage/lights','flipSwitch', ['notBool']],
  'lacks input':   ['cottage/pool/heater','start', [80]],
  'invalid input': ['house/living-room/blast-speaker','playSong', ['notThere']]
};

_.forOwn(badRPCs, function run(params, inputType) {
  test(
    'makeRPC errors on bad input - ' + inputType,
    testMakeRPCHasError.bind(null, params)
  );
});

// Make RPC: outputs have the expected # of outputs
test('makeRPC returns output properly', function(t) {
  namespaceService.makeRPC('cottage/alarm', 'panic', []).then(
    function got0Outputs(res) { // 0 outputs: has [] as a result.
      t.ok(res instanceof Array && res.length === 0, '0 outputs => []');

      return namespaceService.makeRPC('house/alarm', 'status', []);
    }
  ).then( // 1 output: (Non-array/slice output) is not an Array.
    function got1Output(res) {
      t.notOk(res instanceof Array, '1 output => not an Array');

      return namespaceService.makeRPC('cottage/smoke-detector', 'test', []);
    }
  ).then( // 1 output: Delayed return. Also not an array.
    function got1OutputDelayed(res) {
      t.notOk(res instanceof Array, '1 output => not an Array');

      return namespaceService.makeRPC('cottage/pool/heater', 'status', []);
    }
  ).then( // 2 outputs: Is an Array of the correct length.
    function got2Outputs(res) {
      var ok = res instanceof Array && res.length === 2;
      t.ok(ok, '2 outputs => length 2 Array');
      t.end();
    }
  ).catch(t.end);
});

/*
 * Test helpers
 */
function assertServer(t, item, vals) {
  assertMountedName(t, item, vals.name);
  assertObjectName(t, item, vals.objectName);
  assertIsServer(t, item);
  if (vals.isGlobbable === true) {
    assertIsGlobbable(t, item);
  } else if(vals.isGlobbable === false) {
    assertIsNotGlobbable(t, item);
  }
  assertHasSignature(t, item);
  assertIsAccessible(t, item);

  if (vals.type === 'unknown') {
    assertUnknownServiceTypeInfo(t, item);
  } else if (vals.type === 'mounttable') {
    assertMounttableServiceTypeInfo(t, item);
  } else {
    t.fail('Unknown type: ' + vals.type);
  }
}

function assertIntermediaryName(t, item, vals) {
  assertMountedName(t, item, vals.name);
  assertObjectName(t, item, vals.objectName);
  assertIsNotServer(t, item);
  assertIsGlobbable(t, item);
}

function assertMountedName(t, item, val) {
  t.ok(item.mountedName, item.mountedName + ': has a mounted name');
  t.equal(item.mountedName, val, item.mountedName + ': mounted name matches');
}

function assertObjectName(t, item, val) {
  t.ok(item.objectName, item.mountedName + ': has an object name');
  t.equal(item.objectName, val, item.mountedName + ': object name matches');
}

function assertIsServer(t, item) {
  t.equal(item.isServer, true, item.mountedName + ': is a server');
  t.ok(item.serverInfo, item.mountedName + ': has server info');
}

function assertIsNotServer(t, item) {
  t.equal(item.isServer, false, item.mountedName + ': is not a server');
  t.notOk(item.serverInfo, item.mountedName + ': does not have server info');
}

function assertIsGlobbable(t, item) {
  t.equal(item.isGlobbable, true, item.mountedName + ': is globbable');
}

function assertIsNotGlobbable(t, item) {
  t.equal(item.isGlobbable, false, item.mountedName + ': is not globbable');
}

function assertHasSignature(t, item) {
  t.ok(item.serverInfo.signature, item.mountedName + ': has a signature');
}

function assertIsAccessible(t, item) {
  t.ok(item.serverInfo.isAccessible, item.mountedName + ': is accessible');
}

function assertIsImmutable(t, observable) {
  t.ok(observable.set === undefined, 'is immutable');
}

/*
 * Asserts that a ServiceTypeInfo is of predefined type of Unknown Service.
 */
function assertUnknownServiceTypeInfo(t, item) {
  var typeInfo = item.serverInfo.typeInfo;
  t.equal(typeInfo.key, 'veyron-unknown',
    item.mountedName + ': unknown type info has the right key');

  t.equal(typeInfo.typeName, 'Service',
    item.mountedName + ': unknown type info has the type name');

  t.equal(typeInfo.description, null,
    item.mountedName + ': unknown type info does not have description');
}

/*
 * Asserts that a ServiceTypeInfo is of predefined type of mounttable.
 */
function assertMounttableServiceTypeInfo(t, item) {
  var typeInfo = item.serverInfo.typeInfo;
  t.equal(typeInfo.key, 'veyron-mounttable',
    item.mountedName + ': mounttable type info has the right key');

  t.equal(typeInfo.typeName, 'Mount Table',
    item.mountedName + ': mounttable type info has the type name');

  t.ok(typeInfo.description,
    item.mountedName + ': mounttable type info has a description');
}
/*
 * Runs a test to ensure the makeRPC call terminates without error.
 */
function testMakeRPCNoError(args, t) {
  namespaceService.makeRPC.apply(null, args).then(function(result) {
    t.pass('completed without error');
    t.end();
  }).catch(function(err) {
    t.fail('should not have returned an error');
    t.end();
  });
}

/*
 * Runs a test to ensure the makeRPC call terminates with an error.
 */
function testMakeRPCHasError(args, t) {
  namespaceService.makeRPC.apply(null, args).then(function(result) {
    t.fail('should not have completed without error');
    t.end();
  }).catch(function(err) {
    t.pass('correctly returned an error');
    t.end();
  });
}<commit_msg>veyron-browser: Reenabling the skipped test.<commit_after>var test = require('prova');
var mercury = require('mercury');
var _ = require('lodash');
var proxyquire = require('proxyquireify')(require);
var mockLRUCache = require('./mocks/lru-cache');

// 8885 is the expected wspr port to be running for the tests
// @noCallThru ensures this completely overrdies the original config
// instead of inheriting the properties that are not defined here from
// the original dependency
var veyronConfigForTest = {
  'authenticate': false,
  'wspr': 'http://localhost:8885',
  '@noCallThru': true
};

// Require namespaceService but using test specific mocks and configs
var namespaceService =
  proxyquire('../../../../src/services/namespace/service.js', {
    '../../veyron-config': veyronConfigForTest,
    'lru-cache': function() {
      return mockLRUCache;
    }
  });

test('getChildren of default namespace root', function(t) {
  namespaceService.getChildren().
  then(function assertResult(result) {
    assertIsImmutable(t, result);
    // Wait until we finish, we expect 2 top level items: cottage, house
    result.events.on('end', function validate() {
      mercury.watch(result, function(children) {
        children = _.sortBy(children, 'mountedName');
        assertCottage(children[0]);
        assertHouse(children[1]);
        t.end();
      });
    });
    result.events.on('streamError', t.end);
    result.events.on('itemError', t.end);
  }).catch(t.end);

  function assertCottage(item) {
    assertServer(t, item, {
      name: 'cottage',
      objectName: 'cottage',
      isGlobbable: true,
      type: 'mounttable'
    });
  }

  function assertHouse(item) {
    assertServer(t, item, {
      name: 'house',
      objectName: 'house',
      isGlobbable: true,
      type: 'mounttable'
    });
  }
});

test('getChildren of cottage/lawn', function(t) {
  namespaceService.getChildren('cottage/lawn').
  then(function assertResult(result) {
    assertIsImmutable(t, result);
    // Wait until we finish, we expect 3 items back, front and master-sprinkler
    result.events.on('end', function validate() {
      mercury.watch(result, function(children) {
        children = _.sortBy(children, 'mountedName');
        assertBack(children[0]);
        assertSprinkler(children[2]);
        t.end();
      });
    });
    result.events.on('streamError', t.end);
    result.events.on('itemError', t.end);
  }).catch(t.end);

  function assertSprinkler(item) {
    assertServer(t, item, {
      name: 'master-sprinkler',
      objectName: 'cottage/lawn/master-sprinkler',
      isGlobbable: false,
      type: 'unknown'
    });
  }

  function assertBack(item) {
    assertIntermediaryName(t, item, {
      name: 'back',
      objectName: 'cottage/lawn/back'
    });
  }
});

test('getChildren of rooted /localhost:8881/house/kitchen', function(t) {

  // 8881 is the expected root mounttable port to be running for the tests
  namespaceService.getChildren('/localhost:8881/house/kitchen').
  then(function assertResult(result) {
    assertIsImmutable(t, result);
    // Wait until we finish, we expect 2 items, lights and smoke-detector
    result.events.on('end', function validate() {
      mercury.watch(result, function(children) {
        children = _.sortBy(children, 'mountedName');
        assertLightSwitch(children[0]);
        assertSmokeDetector(children[1]);
        t.end();
      });
    });
    result.events.on('streamError', t.end);
    result.events.on('itemError', t.end);
  }).catch(t.end);

  function assertLightSwitch(item) {
    assertServer(t, item, {
      name: 'lights',
      objectName: '/localhost:8881/house/kitchen/lights',
      isGlobbable: false,
      type: 'unknown'
    });
  }

  function assertSmokeDetector(item) {
    assertServer(t, item, {
      name: 'smoke-detector',
      objectName: '/localhost:8881/house/kitchen/smoke-detector',
      isGlobbable: false,
      type: 'unknown'
    });
  }
});

test('getChildren of non-existing mounttable', function(t) {
  // TODO(aghassemi) why does namespace library return empty results instead of
  // error when globbing rooted names that don't exist?
  namespaceService.getChildren('/DoesNotExist:666/What/Ever').
  then(function assertResult(result) {
    result.events.on('end', function validate() {
      // Expect empty results
      mercury.watch(result, function(children) {
        t.deepEqual(children, []);
        t.end();
      });
    });
    result.events.on('streamError', t.end);
    result.events.on('itemError', t.end);
  }).catch(t.end);
});

test('getNamespaceItem of leaf server', function(t) {
  namespaceService.getNamespaceItem('cottage/lawn/master-sprinkler').
  then(function assertItem(itemObs) {
    assertIsImmutable(t, itemObs);
    var item = itemObs();
    assertServer(t, item, {
      name: 'master-sprinkler',
      objectName: 'cottage/lawn/master-sprinkler',
      isGlobbable: false,
      type: 'unknown'
    });
    t.end();
  }).catch(t.end);
});

test('getNamespaceItem of intermediary name', function(t) {
  namespaceService.getNamespaceItem('cottage/lawn/back').
  then(function assertItem(itemObs) {
    assertIsImmutable(t, itemObs);
    var item = itemObs();
    assertIntermediaryName(t, item, {
      name: 'back',
      objectName: 'cottage/lawn/back'
    });
    t.end();
  }).catch(t.end);
});

test('getNamespaceItem of mounttable leaf server', function(t) {
  namespaceService.getNamespaceItem('cottage').
  then(function assertItem(itemObs) {
    assertIsImmutable(t, itemObs);
    var item = itemObs();
    assertServer(t, item, {
      name: 'cottage',
      objectName: 'cottage',
      isGlobbable: true,
      type: 'mounttable'
    });
    t.end();
  }).catch(t.end);
});

test('search uses caching', function(t) {
  mockLRUCache.reset();

  namespaceService.search('house', '*').
  then(function assertNoCacheHit() {
    t.notOk(mockLRUCache.wasCacheHit('glob|house/*'),
      'first glob call is not a cache hit');

    // Call second time, there should have been a cache hit
    return namespaceService.search('house', '*');
  }).then(function assertCacheHit() {
    t.ok(mockLRUCache.wasCacheHit('glob|house/*'),
      'second glob call is a cache hit');

    // Call glob with same name, different query
    return namespaceService.search('house', 'foo*');
  }).then(function assertNoCacheHit() {
    t.notOk(mockLRUCache.wasCacheHit('glob|house/foo*'),
      'third glob call with different query is not a cache hit');
    t.end();
  }).catch(t.end);
});

test('getSignature uses caching', function(t) {
  mockLRUCache.reset();

  namespaceService.getSignature('house/alarm').then(function() {
    t.notOk(mockLRUCache.wasCacheHit('getSignature|house/alarm'),
      'first getSignature call is not a cache hit');
    // Call a second time
    return namespaceService.getSignature('house/alarm');
  }).then(function() {
    t.ok(mockLRUCache.wasCacheHit('getSignature|house/alarm'),
      'second getSignature call is a cache hit');
    // Call a different name
    return namespaceService.getSignature('house/kitchen/smoke-detector');
  }).then(function() {
    t.notOk(mockLRUCache.wasCacheHit(
      'getSignature|house/kitchen/smoke-detector'
    ),'third getSignature call to a different name is not a cache hit');
    t.end();
  }).catch(t.end);
});

//TODO(aghassemi)
//Tests for:
// Recursive glob
// Glob with some keyword
// Ensuring array is updated when nodes get mounted and unmounted (when we use
// watchGlob)

// Make RPC: good inputs => no error
var okRPCs = {
  'no input':     ['house/alarm', 'status', []],
  'bool input':   ['house/living-room/lights', 'flipSwitch', [true]],
  'int input':    ['cottage/smoke-detector', 'sensitivity', [2]],
  'float input':  ['house/alarm', 'delayArm', [2.5]],
  'string input': ['cottage/pool/speaker', 'playSong', ['Happy Birthday']],
  'slice input':  ['house/master-bedroom/speaker', 'addSongs', [['A', 'B']]],
  '2+ inputs':    ['cottage/pool/heater', 'start', [70, 5]],
};

_.forOwn(okRPCs, function run(params, inputType) {
  test(
    'makeRPC accepts good input - ' + inputType,
    testMakeRPCNoError.bind(null, params)
  );
});

// Make RPC: bad inputs => error
var badRPCs = {
  'no service':    ['mansion/smoke-detector', 'status', []],
  'no method':     ['cottage/pool/speaker', 'status', []],
  'no input':      ['cottage/lights','flipSwitch', null],
  'bad type':      ['cottage/lights','flipSwitch', ['notBool']],
  'lacks input':   ['cottage/pool/heater','start', [80]],
  'invalid input': ['house/living-room/blast-speaker','playSong', ['notThere']]
};

_.forOwn(badRPCs, function run(params, inputType) {
  test(
    'makeRPC errors on bad input - ' + inputType,
    testMakeRPCHasError.bind(null, params)
  );
});

// Make RPC: outputs have the expected # of outputs
test('makeRPC returns output properly', function(t) {
  namespaceService.makeRPC('cottage/alarm', 'panic', []).then(
    function got0Outputs(res) { // 0 outputs: has [] as a result.
      t.ok(res instanceof Array && res.length === 0, '0 outputs => []');

      return namespaceService.makeRPC('house/alarm', 'status', []);
    }
  ).then( // 1 output: (Non-array/slice output) is not an Array.
    function got1Output(res) {
      t.notOk(res instanceof Array, '1 output => not an Array');

      return namespaceService.makeRPC('cottage/smoke-detector', 'test', []);
    }
  ).then( // 1 output: Delayed return. Also not an array.
    function got1OutputDelayed(res) {
      t.notOk(res instanceof Array, '1 output => not an Array');

      return namespaceService.makeRPC('cottage/pool/heater', 'status', []);
    }
  ).then( // 2 outputs: Is an Array of the correct length.
    function got2Outputs(res) {
      var ok = res instanceof Array && res.length === 2;
      t.ok(ok, '2 outputs => length 2 Array');
      t.end();
    }
  ).catch(t.end);
});

/*
 * Test helpers
 */
function assertServer(t, item, vals) {
  assertMountedName(t, item, vals.name);
  assertObjectName(t, item, vals.objectName);
  assertIsServer(t, item);
  if (vals.isGlobbable === true) {
    assertIsGlobbable(t, item);
  } else if(vals.isGlobbable === false) {
    assertIsNotGlobbable(t, item);
  }
  assertHasSignature(t, item);
  assertIsAccessible(t, item);

  if (vals.type === 'unknown') {
    assertUnknownServiceTypeInfo(t, item);
  } else if (vals.type === 'mounttable') {
    assertMounttableServiceTypeInfo(t, item);
  } else {
    t.fail('Unknown type: ' + vals.type);
  }
}

function assertIntermediaryName(t, item, vals) {
  assertMountedName(t, item, vals.name);
  assertObjectName(t, item, vals.objectName);
  assertIsNotServer(t, item);
  assertIsGlobbable(t, item);
}

function assertMountedName(t, item, val) {
  t.ok(item.mountedName, item.mountedName + ': has a mounted name');
  t.equal(item.mountedName, val, item.mountedName + ': mounted name matches');
}

function assertObjectName(t, item, val) {
  t.ok(item.objectName, item.mountedName + ': has an object name');
  t.equal(item.objectName, val, item.mountedName + ': object name matches');
}

function assertIsServer(t, item) {
  t.equal(item.isServer, true, item.mountedName + ': is a server');
  t.ok(item.serverInfo, item.mountedName + ': has server info');
}

function assertIsNotServer(t, item) {
  t.equal(item.isServer, false, item.mountedName + ': is not a server');
  t.notOk(item.serverInfo, item.mountedName + ': does not have server info');
}

function assertIsGlobbable(t, item) {
  t.equal(item.isGlobbable, true, item.mountedName + ': is globbable');
}

function assertIsNotGlobbable(t, item) {
  t.equal(item.isGlobbable, false, item.mountedName + ': is not globbable');
}

function assertHasSignature(t, item) {
  t.ok(item.serverInfo.signature, item.mountedName + ': has a signature');
}

function assertIsAccessible(t, item) {
  t.ok(item.serverInfo.isAccessible, item.mountedName + ': is accessible');
}

function assertIsImmutable(t, observable) {
  t.ok(observable.set === undefined, 'is immutable');
}

/*
 * Asserts that a ServiceTypeInfo is of predefined type of Unknown Service.
 */
function assertUnknownServiceTypeInfo(t, item) {
  var typeInfo = item.serverInfo.typeInfo;
  t.equal(typeInfo.key, 'veyron-unknown',
    item.mountedName + ': unknown type info has the right key');

  t.equal(typeInfo.typeName, 'Service',
    item.mountedName + ': unknown type info has the type name');

  t.equal(typeInfo.description, null,
    item.mountedName + ': unknown type info does not have description');
}

/*
 * Asserts that a ServiceTypeInfo is of predefined type of mounttable.
 */
function assertMounttableServiceTypeInfo(t, item) {
  var typeInfo = item.serverInfo.typeInfo;
  t.equal(typeInfo.key, 'veyron-mounttable',
    item.mountedName + ': mounttable type info has the right key');

  t.equal(typeInfo.typeName, 'Mount Table',
    item.mountedName + ': mounttable type info has the type name');

  t.ok(typeInfo.description,
    item.mountedName + ': mounttable type info has a description');
}
/*
 * Runs a test to ensure the makeRPC call terminates without error.
 */
function testMakeRPCNoError(args, t) {
  namespaceService.makeRPC.apply(null, args).then(function(result) {
    t.pass('completed without error');
    t.end();
  }).catch(function(err) {
    t.fail('should not have returned an error');
    t.end();
  });
}

/*
 * Runs a test to ensure the makeRPC call terminates with an error.
 */
function testMakeRPCHasError(args, t) {
  namespaceService.makeRPC.apply(null, args).then(function(result) {
    t.fail('should not have completed without error');
    t.end();
  }).catch(function(err) {
    t.pass('correctly returned an error');
    t.end();
  });
}<|endoftext|>


<commit_before>/**
 * Linkit 7688 範例
 * 使用 GPIO 控制 8x8 LED Matrix (共陽)
 * 顯示數字
 *
 * @author Abola Lee
 * @version 1.0
 * @since 2016-01-10
 *
 * @link http://www.gibar.co/2016/01/7688-8x8-led-matrix.html
 */
var mraa = require('mraa');

// 腳位命名參考
//
//
//    \Col 1   2   3   4   5   6   7   8
//Row  \ _13__03__04__10__06__11__15__16_  (針腳)
// 1  09|                               |
// 2  14|                               |
// 3  08|                               |
// 4  12|              8x8              |
// 5  01|           LED Matrix          |
// 6  07|                               |
// 7  02|                               |
// 8  05|_______________________________|
//   (針腳)

// 設定GPIO 接腳
var col = [
      new mraa.Gpio(2)
      , new mraa.Gpio(16)
      , new mraa.Gpio(17)
      , new mraa.Gpio(44)
      , new mraa.Gpio(5)
      , new mraa.Gpio(46)
      , new mraa.Gpio(0)
      , new mraa.Gpio(1)
    ],
    row = [
      new mraa.Gpio(37)
      , new mraa.Gpio(3)
      , new mraa.Gpio(13)
      , new mraa.Gpio(45)
      , new mraa.Gpio(14)
      , new mraa.Gpio(12)
      , new mraa.Gpio(15)
      , new mraa.Gpio(4)
    ];

// 預設全亮測試
for(var idx=0; idx<8; idx++) col[idx].dir(mraa.DIR_OUT_HIGH);
for(var idx=0; idx<8; idx++) row[idx].dir(mraa.DIR_OUT_LOW);

var resetFlag=false;
/**
 * 回復全暗
 */
function reset(){
  resetFlag = true; //
  for(var idx=0; idx<8; idx++) col[idx].write(0);
  for(var idx=0; idx<8; idx++) row[idx].write(0);
  resetFlag=false;
}
<commit_msg>Update 8x8_led_matrix_show_number.js<commit_after>/**
 * Linkit 7688 範例
 * 使用 GPIO 控制 8x8 LED Matrix (共陽)
 * 顯示數字
 *
 * @author Abola Lee
 * @version 1.0
 * @since 2016-01-10
 *
 * @link http://www.gibar.co/2016/01/7688-8x8-led-matrix.html
 */
var mraa = require('mraa');

// 腳位命名參考
//
//
//    \Col 1   2   3   4   5   6   7   8
//Row  \ _13__03__04__10__06__11__15__16_  (針腳)
// 1  09|                               |
// 2  14|                               |
// 3  08|                               |
// 4  12|              8x8              |
// 5  01|           LED Matrix          |
// 6  07|                               |
// 7  02|                               |
// 8  05|_______________________________|
//   (針腳)

// 設定GPIO 接腳
var col = [
      new mraa.Gpio(2)
      , new mraa.Gpio(16)
      , new mraa.Gpio(17)
      , new mraa.Gpio(44)
      , new mraa.Gpio(5)
      , new mraa.Gpio(46)
      , new mraa.Gpio(0)
      , new mraa.Gpio(1)
    ],
    row = [
      new mraa.Gpio(37)
      , new mraa.Gpio(3)
      , new mraa.Gpio(13)
      , new mraa.Gpio(45)
      , new mraa.Gpio(14)
      , new mraa.Gpio(12)
      , new mraa.Gpio(15)
      , new mraa.Gpio(4)
    ];

// 預設全亮測試
for(var idx=0; idx<8; idx++) col[idx].dir(mraa.DIR_OUT_HIGH);
for(var idx=0; idx<8; idx++) row[idx].dir(mraa.DIR_OUT_LOW);

reset();

// 字集設定

var smile = [
[0,0,0,0,0,0,0,0],
[0,1,1,0,0,1,1,0],
[0,1,1,0,0,1,1,0],
[0,1,1,0,0,1,1,0],
[0,0,0,0,0,0,0,0],
[0,1,0,0,0,0,1,0],
[0,0,1,0,0,1,0,0],
[0,0,0,1,1,0,0,0]];

var fontInterval;

function showFont(font){
  clearInterval(fontInterval);
  reset();

  fontInterval = setInterval( function(){
    var r=0;
    while(1){
      // 回到 Row1 重新開始
      if (r>=8) r=0;

      // 熄燈
      reset();

      row[r].write(0);
      for(var c=0; c<8; c++) col[c].write( font[r][c] );

      ++r;
      sleep(5);
    }
  }, 0 );

}

var resetFlag=false;
/**
 * 回復全暗
 */
function reset(){
  resetFlag = true; //
  for(var idx=0; idx<8; idx++) col[idx].write(0);
  for(var idx=0; idx<8; idx++) row[idx].write(1);
  resetFlag=false;
}

/**
 * Simple sleep function
 */
function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}

showFont(smile);
<|endoftext|>


<commit_before>'use strict';

var ease = require('ease').ease;

/* global innerHeight, requestAnimationFrame, scrollX, scrollY */

(function () {
  exports.scrollToOffset = function (offset, duration) {
    if (offset === undefined) {
      throw new Error('missing scroll offset');
    }
    if (duration === undefined) {
      duration = 500;
    }
    var startY = scrollY;
    var maxY = document.body.scrollHeight - innerHeight;
    var targetY = Math.max(0, Math.min(offset, maxY));
    var distance = targetY - startY;
    var startT = Date.now();
    var targetT = startT + duration;
    var onAnimationFrame = function () {
      if (Date.now() >= targetT) {
        scrollTo(scrollX, targetY);
        return;
      }
      var t = (Date.now() - startT) / duration;
      var y = startY + distance * ease(t);
      scrollTo(scrollX, y);
      requestAnimationFrame(onAnimationFrame);
    };
    scrollTo(scrollX, startY);
    requestAnimationFrame(onAnimationFrame);
  };

  exports.scrollElementByIdToHorizontalOffset = function (id, offset, duration) {
    var el = document.getElementById(id);
    if (!el) {
      throw new Error('missing element');
    }
    if (offset === undefined) {
      throw new Error('missing scroll offset');
    }
    if (duration === undefined) {
      duration = 500;
    }
    var startX = el.scrollLeft;
    var maxX = el.scrollWidth - el.clientWidth;
    var targetX = Math.max(0, Math.min(offset, maxX));
    var distance = targetX - startX;
    var startT = Date.now();
    var targetT = startT + duration;
    var onAnimationFrame = function () {
      if (Date.now() >= targetT) {
        el.scrollLeft = targetX;
        return;
      }
      var t = (Date.now() - startT) / duration;
      var x = startX + distance * ease(t);
      el.scrollLeft = x;
      requestAnimationFrame(onAnimationFrame);
    };
    requestAnimationFrame(onAnimationFrame);
  };
})();

exports.getElementOffsetById = function (id) {
  var target = document.getElementById(id);
  if (!target) {
    return undefined;
  }
  var y = 0;
  do {
    y += target.offsetTop;
    target = target.offsetParent;
  } while (target);
  return y;
};

exports.scrollToElementById = function (id, duration) {
  var offset = exports.getElementOffsetById(id);
  if (offset !== undefined) {
    if (location.hash.slice(1) !== id) {
      history.pushState({ offset: offset, id: id }, '', '#' + id);
    }
    exports.scrollToOffset(offset, duration);
  }
};

exports.applyToLocalLinks = function (duration) {
  if (duration === undefined) {
    duration = 500;
  }
  var links = document.querySelectorAll('a[href^="#"]');
  [].forEach.call(links, function (link) {
    link.addEventListener('click', function (event) {
      event.preventDefault();
      exports.scrollToElementById(this.hash.slice(1), duration);
    });
  });
};
<commit_msg>Refactor tweening<commit_after>'use strict';

var ease = require('ease').ease;

/* global innerHeight, requestAnimationFrame, scrollX, scrollY */

function tween(startOffset, maxOffset, offset, duration, callback, endCallback) {
  var targetOffset = Math.max(0, Math.min(offset, maxOffset));
  var distance = targetOffset - startOffset;
  var startTime = Date.now();
  var targetTime = startTime + duration;
  var onAnimationFrame = function () {
    if (Date.now() >= targetTime) {
      callback(targetOffset);
      if (endCallback) {
        endCallback();
      }
    } else {
      var t = (Date.now() - startTime) / duration;
      var o = startOffset + distance * ease(t);
      callback(o);
      requestAnimationFrame(onAnimationFrame);
    }
  };
  requestAnimationFrame(onAnimationFrame);
}

(function () {
  exports.scrollToOffset = function (offset, duration, callback) {
    if (offset === undefined) {
      throw new Error('missing scroll offset');
    }
    if (duration === undefined) {
      duration = 500;
    }
    var startOffset = scrollY;
    var maxOffset = document.body.scrollHeight - innerHeight;
    tween(startOffset, maxOffset, offset, duration, function (y) {
      scrollTo(scrollX, y);
    }, callback);
  };

  exports.scrollElementByIdToHorizontalOffset = function (id, offset, duration, callback) {
    var el = document.getElementById(id);
    if (!el) {
      throw new Error('missing element');
    }
    if (offset === undefined) {
      throw new Error('missing scroll offset');
    }
    if (duration === undefined) {
      duration = 500;
    }
    var startOffset = el.scrollLeft;
    var maxOffset = el.scrollWidth - el.clientWidth;
    tween(startOffset, maxOffset, offset, duration, function (x) {
      el.scrollLeft = x;
    }, callback);
  };
})();

exports.getElementOffsetById = function (id) {
  var target = document.getElementById(id);
  if (!target) {
    return undefined;
  }
  var y = 0;
  do {
    y += target.offsetTop;
    target = target.offsetParent;
  } while (target);
  return y;
};

exports.scrollToElementById = function (id, duration) {
  var offset = exports.getElementOffsetById(id);
  if (offset !== undefined) {
    if (location.hash.slice(1) !== id) {
      history.pushState({ offset: offset, id: id }, '', '#' + id);
    }
    exports.scrollToOffset(offset, duration);
  }
};

exports.applyToLocalLinks = function (duration) {
  if (duration === undefined) {
    duration = 500;
  }
  var links = document.querySelectorAll('a[href^="#"]');
  [].forEach.call(links, function (link) {
    link.addEventListener('click', function (event) {
      event.preventDefault();
      exports.scrollToElementById(this.hash.slice(1), duration);
    });
  });
};
<|endoftext|>