<commit_before>var async		= require('async');
var url			= require('url');
var path		= require('path');
var pkg			= require(path.join(__dirname, './package.json'));
var fs			= require('fs');
var inquirer	= require('inquirer');
var program		= require('commander');
var request		= require('request');
var cheerio		= require('cheerio');
var webshot		= require('webshot');
var sluggin		= require('Sluggin').Sluggin;
var directory 	= './20160330/';
var sites		= require(directory + 'sites.js');

program
	.version( pkg.version )
	.parse( process.argv );

/**
 * cleanName( uri );
 * @uri: string | uri
 * return string
 */
var cleanName = function( uri ){

	return sluggin( url.parse(uri).href.replace('www.','').split('//')[1] );

}

/**
 * getScreenshot( sitename );
 * @sitename: string | clean name of site
 * @callback: function | callback
 * return callback
 *
 * get and save a screenshot of each site
 *
 */
function getScreenshot( sitename, callback ){

	var webshotOptions = {
		encoding: 'binary',
		renderDelay: 1000
	};

	webshot(sitename, directory + cleanName( sitename ) + '.png', webshotOptions, function(err) {
		if (err) return callback(err);
		callback(null, '📸  · ' + sitename + ' screenshot OK!');
	});

}

/**
 * getContent( sitename );
 * @sitename: string | clean name of site
 * @callback: function | callback
 * return callback
 *
 * scrape title & description for each site
 *
 */
function getContent( sitename, callback ){

	var title = '';
	var description = '';

	request(sitename, function(error, response, html) {

		if (error || response.statusCode !== 200) return callback(error || new Error('Not found'));

		var $ = cheerio.load(html);

		title = $("title").text();
		description = $('meta[name="description"]').attr('content');

		callback(null, title + ' | ' +  description, sitename);

	});

}

/**
 * writeToFile( @params );
 * @content: string | content scraped
 * @sitename: string | clean name of site
 * @callback: function | callback
 * return callback
 *
 * saves content to file for each site
 *
 */
function writeToFile( content, sitename, cb ) {

	fs.writeFile(directory + cleanName( sitename ) + '.md', content, function(err) {

		if (err) return cb(err);
		cb(null, '📂 · The file ' + cleanName( sitename ) + '.md was created!');

	});

}

/**
 * getContentAndWriteToFile( @params );
 *
 * @uri: string | uri
 * @callback: function | callback
 * return callback
 *
 */
function getContentAndWriteToFile( uri, callback ) {

	async.waterfall([

		async.apply(getContent, uri),
		writeToFile

	], callback);

}

/**
 * parseUrl( @params );
 *
 * @uri: string | uri
 * @callback: function | callback
 * return callback
 *
 */
function parseUrl(uri, callback) {

	async.parallel([

		// take screenshot
		async.apply(getScreenshot, uri),
		// get content & save to file
		async.apply(getContentAndWriteToFile, uri)

	], callback);

}

/**
 * parseSites( @params );
 *
 * @sites: array | of site url's
 * @callback: function | callback
 * return callback
 *
 */
function parseSites(sites, callback) {

	async.map(sites, parseUrl, callback);

}

/**
 * APPLY
 */
parseSites(sites, function(err, results){

	if (err) return console.error(err);

	results.forEach(function(result) {
		result.forEach(function(log) {
			console.log(log);
		});
	});

	console.log('Everything OK');

});

<commit_msg>better console.log messages<commit_after>var async		= require('async');
var url			= require('url');
var path		= require('path');
var pkg			= require(path.join(__dirname, './package.json'));
var fs			= require('fs');
var inquirer	= require('inquirer');
var program		= require('commander');
var request		= require('request');
var cheerio		= require('cheerio');
var webshot		= require('webshot');
var sluggin		= require('Sluggin').Sluggin;
var directory 	= './20160505/';
var sites		= require(directory + 'sites.js');

program
	.version( pkg.version )
	.parse( process.argv );

/**
 * cleanName( uri );
 * @uri: string | uri
 * return string
 */
var cleanName = function( uri ){

	return sluggin( url.parse(uri).href.replace('www.','').split('//')[1] );

}

/**
 * getScreenshot( sitename );
 * @sitename: string | clean name of site
 * @callback: function | callback
 * return callback
 *
 * get and save a screenshot of each site
 *
 */
function getScreenshot( sitename, callback ){

	var webshotOptions = {
		encoding: 'binary',
		renderDelay: 1000
	};

	webshot(sitename, directory + cleanName( sitename ) + '.png', webshotOptions, function(err) {
		if (err) return callback(err);

		console.log('Getting screenshot: ' + sitename);
		callback(null, '📸  · ' + sitename + ' screenshot OK!');
	});

}

/**
 * getContent( sitename );
 * @sitename: string | clean name of site
 * @callback: function | callback
 * return callback
 *
 * scrape title & description for each site
 *
 */
function getContent( sitename, callback ){

	var title = '';
	var description = '';

	request(sitename, function(error, response, html) {

		if (error || response.statusCode !== 200) return callback(error || new Error('Not found'));

		var $ = cheerio.load(html);

		title = $("title").text();
		description = $('meta[name="description"]').attr('content');

		console.log('Getting content: ' + sitename);
		callback(null, title + ' | ' +  description + ' | ' + sitename, sitename);

	});

}

/**
 * writeToFile( @params );
 * @content: string | content scraped
 * @sitename: string | clean name of site
 * @callback: function | callback
 * return callback
 *
 * saves content to file for each site
 *
 */
function writeToFile( content, sitename, callback ) {

	fs.writeFile(directory + cleanName( sitename ) + '.md', content, function(err) {

		if (err) return callback(err);
		callback(null, '📂 · The file ' + cleanName( sitename ) + '.md was created!');

	});

}

/**
 * getContentAndWriteToFile( @params );
 *
 * @uri: string | uri
 * @callback: function | callback
 * return callback
 *
 */
function getContentAndWriteToFile( uri, callback ) {

	async.waterfall([

		async.apply(getContent, uri),
		writeToFile

	], callback);

}

/**
 * parseUrl( @params );
 *
 * @uri: string | uri
 * @callback: function | callback
 * return callback
 *
 */
function parseUrl( uri, callback ) {

	async.parallel([

		// take screenshot
		async.apply(getScreenshot, uri),
		// get content & save to file
		async.apply(getContentAndWriteToFile, uri)

	], callback);

}

/**
 * parseSites( @params );
 *
 * @sites: array | of site url's
 * @callback: function | callback
 * return callback
 *
 */
function parseSites( sites, callback ) {

	async.map(sites, parseUrl, callback);

}

/**
 * APPLY
 */
parseSites(sites, function( err, results ){

	if (err) return console.error(err);

	results.forEach(function(result) {
		result.forEach(function(log) {
			console.log(log);
		});
	});

	console.log('Everything OK');

});

<|endoftext|>


<commit_before>
var util = require('util');
var Writable = require('stream').Writable;
var AWS = require('aws-sdk');

module.exports = createCloudWatchStream;

function createCloudWatchStream(opts) {
  return new CloudWatchStream(opts);
}

util.inherits(CloudWatchStream, Writable);
function CloudWatchStream(opts) {
  Writable.call(this, {objectMode: true});
  this.logGroupName = opts.logGroupName;
  this.logStreamName = opts.logStreamName;
  this.writeInterval = opts.writeInterval || 0;

  this.cloudwatch = new AWS.CloudWatchLogs(opts.cloudWatchLogsOptions);
  this.queuedLogs = [];
  this.sequenceToken = null;
  this.writeQueued = false;
}

CloudWatchStream.prototype._write = function _write(record, _enc, cb) {
  this.queuedLogs.push(record);
  if (!this.writeQueued) {
    this.writeQueued = true;
    setTimeout(this._writeLogs.bind(this), this.writeInterval);
  }
  cb();
};

CloudWatchStream.prototype._writeLogs = function _writeLogs() {
  if (this.sequenceToken === null) {
    return this._getSequenceToken(this._writeLogs.bind(this));
  }
  var log = {
    logGroupName: this.logGroupName,
    logStreamName: this.logStreamName,
    sequenceToken: this.sequenceToken,
    logEvents: this.queuedLogs.map(createCWLog)
  };
  this.queuedLogs = [];
  var obj = this;
  writeLog();

  function writeLog() {
    obj.cloudwatch.putLogEvents(log, function (err, res) {
      if (err) {
        if (err.retryable) return setTimeout(writeLog, obj.writeInterval);
        return obj._error(err);
      }
      obj.sequenceToken = res.nextSequenceToken;
      if (obj.queuedLogs.length) {
        return setTimeout(obj._writeLogs.bind(obj), obj.writeInterval);
      }
      obj.writeQueued = false;
    });
  }
};

CloudWatchStream.prototype._getSequenceToken = function _getSequenceToken(done) {
  var params = {
    logGroupName: this.logGroupName,
    logStreamNamePrefix: this.logStreamName
  };
  var obj = this;
  this.cloudwatch.describeLogStreams(params, function (err, data) {
    if (err) {
      if (err.name === 'ResourceNotFoundException') {
        createLogGroupAndStream(obj.cloudwatch, obj.logGroupName, obj.logStreamName, createStreamCb);
        return;
      }
      obj._error(err);
      return;
    }
    if (data.logStreams.length === 0) {
      createLogStream(obj.cloudwatch, obj.logGroupName, obj.logStreamName, createStreamCb);
      return;
    }
    obj.sequenceToken = data.logStreams[0].uploadSequenceToken;
    done();
  });

  function createStreamCb(err) {
    if (err) return obj._error(err);
    // call again to verify stream was created - silently fails sometimes!
    obj._getSequenceToken(done);
  }
};

CloudWatchStream.prototype._error = function _error(err) {
  if (this.onError) return this.onError(err);
  throw err;
};

function createLogGroupAndStream(cloudwatch, logGroupName, logStreamName, cb) {
  cloudwatch.createLogGroup({
    logGroupName: logGroupName
  }, function (err) {
    if (err) return err;
    createLogStream(cloudwatch, logGroupName, logStreamName, cb);
  });
}

function createLogStream(cloudwatch, logGroupName, logStreamName, cb) {
  cloudwatch.createLogStream({
    logGroupName: logGroupName,
    logStreamName: logStreamName
  }, cb);
}

function createCWLog(bunyanLog) {
  var message = {};
  for (var key in bunyanLog) {
    if (key === 'time') continue;
    message[key] = bunyanLog[key];
  }
  var log = {
    message: JSON.stringify(message),
    timestamp: new Date(bunyanLog.time).getTime()
  };
  return log;
}
<commit_msg>Fixing InvalidSequenceTokenException on multiple loggers.<commit_after>
var util = require('util');
var Writable = require('stream').Writable;
var AWS = require('aws-sdk');

module.exports = createCloudWatchStream;

function createCloudWatchStream(opts) {
  return new CloudWatchStream(opts);
}

util.inherits(CloudWatchStream, Writable);
function CloudWatchStream(opts) {
  Writable.call(this, {objectMode: true});
  this.logGroupName = opts.logGroupName;
  this.logStreamName = opts.logStreamName;
  this.writeInterval = opts.writeInterval || 0;

  this.cloudwatch = new AWS.CloudWatchLogs(opts.cloudWatchLogsOptions);
  this.queuedLogs = [];
  this.sequenceToken = null;
  this.writeQueued = false;
}

CloudWatchStream.prototype._write = function _write(record, _enc, cb) {
  this.queuedLogs.push(record);
  if (!this.writeQueued) {
    this.writeQueued = true;
    setTimeout(this._writeLogs.bind(this), this.writeInterval);
  }
  cb();
};

CloudWatchStream.prototype._writeLogs = function _writeLogs() {
  if (this.sequenceToken === null) {
    return this._getSequenceToken(this._writeLogs.bind(this));
  }
  var log = {
    logGroupName: this.logGroupName,
    logStreamName: this.logStreamName,
    sequenceToken: this.sequenceToken,
    logEvents: this.queuedLogs.map(createCWLog)
  };
  this.queuedLogs = [];
  var obj = this;
  writeLog();

  function writeLog() {
    obj.cloudwatch.putLogEvents(log, function (err, res) {
      if (err) {
        if (err.retryable) return setTimeout(writeLog, obj.writeInterval);
        if (err.code === 'InvalidSequenceTokenException') {
          return obj._getSequenceToken((function () {
            log.sequenceToken = obj.sequenceToken;
            setTimeout(writeLog, obj.writeInterval);
          }));
        }
        return obj._error(err);
      }
      obj.sequenceToken = res.nextSequenceToken;
      if (obj.queuedLogs.length) {
        return setTimeout(obj._writeLogs.bind(obj), obj.writeInterval);
      }
      obj.writeQueued = false;
    });
  }
};

CloudWatchStream.prototype._getSequenceToken = function _getSequenceToken(done) {
  var params = {
    logGroupName: this.logGroupName,
    logStreamNamePrefix: this.logStreamName
  };
  var obj = this;
  this.cloudwatch.describeLogStreams(params, function (err, data) {
    if (err) {
      if (err.name === 'ResourceNotFoundException') {
        createLogGroupAndStream(obj.cloudwatch, obj.logGroupName, obj.logStreamName, createStreamCb);
        return;
      }
      obj._error(err);
      return;
    }
    if (data.logStreams.length === 0) {
      createLogStream(obj.cloudwatch, obj.logGroupName, obj.logStreamName, createStreamCb);
      return;
    }
    obj.sequenceToken = data.logStreams[0].uploadSequenceToken;
    done();
  });

  function createStreamCb(err) {
    if (err) return obj._error(err);
    // call again to verify stream was created - silently fails sometimes!
    obj._getSequenceToken(done);
  }
};

CloudWatchStream.prototype._error = function _error(err) {
  if (this.onError) return this.onError(err);
  throw err;
};

function createLogGroupAndStream(cloudwatch, logGroupName, logStreamName, cb) {
  cloudwatch.createLogGroup({
    logGroupName: logGroupName
  }, function (err) {
    if (err) return err;
    createLogStream(cloudwatch, logGroupName, logStreamName, cb);
  });
}

function createLogStream(cloudwatch, logGroupName, logStreamName, cb) {
  cloudwatch.createLogStream({
    logGroupName: logGroupName,
    logStreamName: logStreamName
  }, cb);
}

function createCWLog(bunyanLog) {
  var message = {};
  for (var key in bunyanLog) {
    if (key === 'time') continue;
    message[key] = bunyanLog[key];
  }
  var log = {
    message: JSON.stringify(message),
    timestamp: new Date(bunyanLog.time).getTime()
  };
  return log;
}
<|endoftext|>


<commit_before>var _       = require('lodash')
var async   = require('async')
var cp      = require('child_process')
var gutil   = require('gulp-util')
var join    = require('path').join
var through = require('through2')

var PLUGIN_NAME = 'gulp-shell'

function shell(commands, options) {
  if (typeof commands === 'string') {
    commands = [commands]
  }

  if (!Array.isArray(commands)) {
    throw new gutil.PluginError(PLUGIN_NAME, 'Missing commands')
  }

  options = _.defaults(options || {}, {
    ignoreErrors: false,
    quiet: false,
    cwd: process.cwd()
  })

  var pathToBin = join(process.cwd(), 'node_modules/.bin')
  var separator = process.platform.match(/^win/) ? ';' : ':'
  var path = pathToBin + separator + process.env.PATH
  var env = _.defaults({PATH: path}, process.env)

  return through.obj(function (file, unused, done) {
    var self = this

    async.eachSeries(commands, function (command, done) {
      command = gutil.template(command, {file: file})

      var child = cp.exec(command, {env: env, cwd: options.cwd}, function (error) {
        done(options.ignoreErrors ? null : error)
      })

      if (!options.quiet) {
        child.stdout.pipe(process.stdout)
        child.stderr.pipe(process.stderr)
      }
    }, function (error) {
      if (error) {
        self.emit('error', new gutil.PluginError(PLUGIN_NAME, error))
      } else {
        self.push(file)
      }
      done()
    })
  })
}

shell.task = function (commands, options) {
  return function () {
    var stream = shell(commands, options)

    stream.write(new gutil.File())
    stream.end()

    return stream
  }
}

module.exports = shell
<commit_msg>Minor change<commit_after>var _       = require('lodash')
var async   = require('async')
var exec    = require('child_process').exec
var gutil   = require('gulp-util')
var join    = require('path').join
var through = require('through2')

var PLUGIN_NAME = 'gulp-shell'

function shell(commands, options) {
  if (typeof commands === 'string') {
    commands = [commands]
  }

  if (!Array.isArray(commands)) {
    throw new gutil.PluginError(PLUGIN_NAME, 'Missing commands')
  }

  options = _.defaults(options || {}, {
    ignoreErrors: false,
    quiet: false,
    cwd: process.cwd()
  })

  var pathToBin = join(process.cwd(), 'node_modules/.bin')
  var separator = process.platform.match(/^win/) ? ';' : ':'
  var path = pathToBin + separator + process.env.PATH
  var env = _.defaults({PATH: path}, process.env)

  return through.obj(function (file, unused, done) {
    var self = this

    async.eachSeries(commands, function (command, done) {
      command = gutil.template(command, {file: file})

      var child = exec(command, {env: env, cwd: options.cwd}, function (error) {
        done(options.ignoreErrors ? null : error)
      })

      if (!options.quiet) {
        child.stdout.pipe(process.stdout)
        child.stderr.pipe(process.stderr)
      }
    }, function (error) {
      if (error) {
        self.emit('error', new gutil.PluginError(PLUGIN_NAME, error))
      } else {
        self.push(file)
      }
      done()
    })
  })
}

shell.task = function (commands, options) {
  return function () {
    var stream = shell(commands, options)

    stream.write(new gutil.File())
    stream.end()

    return stream
  }
}

module.exports = shell
<|endoftext|>


<commit_before>/* globals describe, it */
import assert from 'assert';

import editor from '../src/editor';

import Rx from 'rx';
import {mockDOMResponse} from '@cycle/dom';

import _ from 'lodash';

const onNext = Rx.ReactiveTest.onNext;

import collectionAssert from './test-helper';

describe('the Helix Pi Editor', () => {
  it('exists', () => {
    assert.equal(!!editor, true);
  });

  it('allows recording scenarios', (done) => {
    const scheduler = new Rx.TestScheduler();

    const click$ = scheduler.createHotObservable(
      onNext(250),
      onNext(500)
    );

    const mockedResponse = mockDOMResponse({
      '.record': {
        click: click$
      }
    });

    const results = scheduler.startScheduler(() => {
      return editor({DOM: mockedResponse}).state$;
    });

    collectionAssert.assertEqual([
      onNext(200, state => state.mode === 'editing'),
      onNext(250, state => state.mode === 'recording'),
      onNext(500, state => state.mode === 'editing')
    ], results.messages);

    done();
  });

  it('records the movements of actors', (done) => {
    const scheduler = new Rx.TestScheduler();

    const click$ = scheduler.createHotObservable(
      onNext(250),
      onNext(500)
    );

    const mousedown$ = scheduler.createHotObservable(
      onNext(300)
    );

    const mouseup$ = scheduler.createHotObservable(
      onNext(450)
    );

    const mousemove$ = scheduler.createHotObservable(
      onNext(250, {clientX: 0, clientY: 0}),
      onNext(400, {clientX: 200, clientY: 300})
    );

    const mockedResponse = mockDOMResponse({
      '.app': {
        mousemove: mousemove$,
        mouseup: mouseup$
      },
      '.actor-0': {
        mousedown: mousedown$
      },
      '.record': {
        click: click$
      }
    });

    const results = scheduler.startScheduler(() => {
      return editor({DOM: mockedResponse}).state$
        .map(state => state.animations.map(ani => ani.actors));
    });

    collectionAssert.assertEqual([
      onNext(200, []),
      onNext(250, [{}]),
      onNext(300, [{'0': [{position: {x: 150, y: 150}}]}]),
      onNext(400, [{'0': [{position: {x: 150, y: 150}}, {position: {x: 200, y: 300}}]}]),
      onNext(500, [{'0': [{position: {x: 150, y: 150}}, {position: {x: 200, y: 300}}]}])
    ], results.messages);

    done();
  });

  it('plays back recorded', (done) => {
    const scheduler = new Rx.TestScheduler();

    const click$ = scheduler.createHotObservable(
      onNext(250)
    );

    const mockedResponse = mockDOMResponse({
      '.play': {
        click: click$
      }
    });

    const results = scheduler.startScheduler(() => {
      return editor({DOM: mockedResponse}).state$
        .map(state => state.mode);
    });

    collectionAssert.assertEqual([
      onNext(200, 'editing'),
      onNext(250, 'playing')
    ], results.messages);

    done();
  });
});
<commit_msg>Add failing test for recording time<commit_after>/* globals describe, it */
import assert from 'assert';

import editor from '../src/editor';

import Rx from 'rx';
import {mockDOMResponse} from '@cycle/dom';

import _ from 'lodash';

const onNext = Rx.ReactiveTest.onNext;

import collectionAssert from './test-helper';

describe('the Helix Pi Editor', () => {
  it('exists', () => {
    assert.equal(!!editor, true);
  });

  it('allows recording scenarios', (done) => {
    const scheduler = new Rx.TestScheduler();

    const click$ = scheduler.createHotObservable(
      onNext(250),
      onNext(500)
    );

    const mockedResponse = mockDOMResponse({
      '.record': {
        click: click$
      }
    });

    const results = scheduler.startScheduler(() => {
      return editor({DOM: mockedResponse}).state$;
    });

    collectionAssert.assertEqual([
      onNext(200, state => state.mode === 'editing'),
      onNext(250, state => state.mode === 'recording'),
      onNext(500, state => state.mode === 'editing')
    ], results.messages);

    done();
  });

  it('records the movements of actors', (done) => {
    const scheduler = new Rx.TestScheduler();

    const click$ = scheduler.createHotObservable(
      onNext(250),
      onNext(500)
    );

    const mousedown$ = scheduler.createHotObservable(
      onNext(300)
    );

    const mouseup$ = scheduler.createHotObservable(
      onNext(450)
    );

    const mousemove$ = scheduler.createHotObservable(
      onNext(250, {clientX: 0, clientY: 0}),
      onNext(400, {clientX: 200, clientY: 300})
    );

    const mockedResponse = mockDOMResponse({
      '.app': {
        mousemove: mousemove$,
        mouseup: mouseup$
      },
      '.actor-0': {
        mousedown: mousedown$
      },
      '.record': {
        click: click$
      }
    });

    const results = scheduler.startScheduler(() => {
      return editor({DOM: mockedResponse}).state$
        .map(state => state.animations.map(ani => ani.actors));
    });

    collectionAssert.assertEqual([
      onNext(200, []),
      onNext(250, [{}]),
      onNext(300, [{'0': [{position: {x: 150, y: 150, time: 0}}]}]),
      onNext(400, [{'0': [{position: {x: 150, y: 150, time: 0}}, {position: {x: 200, y: 300, time: 10}}]}]),
      onNext(500, [{'0': [{position: {x: 150, y: 150, time: 0}}, {position: {x: 200, y: 300, time: 10}}]}])
    ], results.messages);

    done();
  });

  it('plays back recorded', (done) => {
    const scheduler = new Rx.TestScheduler();

    const click$ = scheduler.createHotObservable(
      onNext(250)
    );

    const mockedResponse = mockDOMResponse({
      '.play': {
        click: click$
      }
    });

    const results = scheduler.startScheduler(() => {
      return editor({DOM: mockedResponse}).state$
        .map(state => state.mode);
    });

    collectionAssert.assertEqual([
      onNext(200, 'editing'),
      onNext(250, 'playing')
    ], results.messages);

    done();
  });
});
<|endoftext|>


<commit_before>var chai = require('chai');
chai.should();
chai.use(require('chai-as-promised'));
var expect = chai.expect;
var _ = require('lodash');
var request  = require('request');
var Bluebird  = require('bluebird');
var chance = require('chance')();
var Elasto = require('../');

Elasto.basePath = 'http://localhost:9200/circle_test';

describe('Elasto', function() {
    var productList = [];
    var createNewProduct;

    before(function(done){

        var indexSettings = {
            "settings": {
                "number_of_shards": 1,
                "analysis": {
                    "filter": {
                        "autocomplete_filter": {
                            "type": "edge_ngram",
                            "min_gram": 1,
                            "max_gram": 20
                        }
                    },
                    "analyzer": {
                        "autocomplete": {
                            "type": "custom",
                            "tokenizer": "standard",
                            "filter": [
                            "lowercase",
                            "autocomplete_filter"
                            ]
                        }
                    }
                }
            }
        };

        Elasto.deleteIndex()
        .then(function(){
            console.log('putain');
            return Elasto.createIndex(indexSettings);
        })
        .should.eventually.notify(done);
    });

    it('should set the mapping', function(done){
        var productMapping = {
            'properties': {
                'slug': { 'type': 'string', 'index': 'not_analyzed' },
                'name': {
                    'type': 'string',
                    'index_analyzer':  'autocomplete',
                    'search_analyzer': 'standard'
                },
                'location' : { 'type' : 'geo_point' }
            }
        };

        Elasto.setMapping('products', productMapping)
        .should.eventually.notify(done);
    });

    describe('save', function () {

        it('should save a product', function (done) {
            var slug = chance.word();
            var boutique_slug = chance.word();
            var price = chance.integer({min: 1, max: 2000});
            var id = price;
            var productToSave = {
                slug: slug,
                boutique_slug: boutique_slug,
                price: price,
                name: chance.word(),
                location: {
                    lat: 51.5,
                    lon: -0.1467912,
                },
                _id: id // Using price as _id
            };

            var product = Elasto.create('products').set(productToSave);

            product.save()
            .then(function(res){
                return Elasto.query('products').byId(id);
            })
            .then(function(res){
                res._id.should.be.equal(id);
            })
            .should.eventually.notify(done);

        });

        it('should save a product with an external version', function (done) {
            var slug = chance.word();
            var boutique_slug = chance.word();
            var price = chance.integer({min: 1, max: 2000});
            var id = price;
            var productToSave = {
                slug: slug,
                boutique_slug: boutique_slug,
                price: price,
                name: chance.word(),
                location: {
                    lat: 51.5,
                    lon: -0.1467912,
                },
                _id: id // Using price as _id
            };

            var product = Elasto.create('products').set(productToSave);

            product.version(1, 'external').save()
            .then(function(res){
                return Elasto.query('products').byId(id);
            })
            .then(function(res){
                res._id.should.be.equal(id);
            })
            .then(function shouldFailWithVersionConflict(){
                var product = Elasto.create('products').set(productToSave);
                return product.version(1, 'external').save()
                    .then(Bluebird.reject)
                    .catch(function(err){
                        expect(err.message).to.have.string('VersionConflictEngineException');
                        return 'ok';
                    });
            })
            .then(function shouldCommitWithHigherVersion(){
                productToSave.name = '{["."]}';
                var product = Elasto.create('products').set(productToSave);
                return product.version(2, 'external').save();
            })
            .then(function(res){
                return Elasto.query('products').byId(id);
            })
            .then(function(res){
                res._id.should.be.equal(id);
                res.name.should.be.equal('{["."]}');
            })
            .should.eventually.notify(done);

        });
    });

    describe('search', function() {

        before(function(done){

            this.timeout(3000);

            for (var i = 0; i < 20; i++) {
                var slug = chance.word();
                var boutique_slug = chance.word();
                var price = chance.integer({min: 1, max: 2000});

                productList.push({
                    slug: slug,
                    boutique_slug: boutique_slug,
                    price: price,
                    name: 'bro ' + chance.word(),
                    location: {
                        lat: 51.5,
                        lon: -0.1467912,
                    },
                });
            }

            createNewProduct = function(newProduct){
                var id = chance.integer({min: 1, max: 2000});
                var productUrl = [Elasto.basePath, 'products', id].join('/'); // 1: index

                return new Bluebird(function (resolve, reject) {
                    request({
                        url: productUrl,
                        method: 'PUT',
                        json: newProduct
                    }, function (err, res, body) {
                        if (err) return reject(err);
                        return resolve(body);
                    });
                });
            };

            Bluebird.map(productList, function(product){
                return createNewProduct(product);
            })
            // The refresh rate of indexing is 1s by default
            .delay(1500)
            .should.eventually.notify(done);
        });

        it('should return a specific size of objects', function(done) {
            var size = 6;

            Elasto.query('products')
            .size(size)
            .search().then(function (documents){

                documents.should.not.be.equal(undefined);
                documents.length.should.be.equal(size);
            })
            .should.eventually.notify(done);
        });

        it('should return a specific size of objects with where', function(done) {
            var boutique_slug = productList[0].boutique_slug;

            Elasto.query('products')
            .where('boutique_slug', boutique_slug)
            .sort('price')
            .search().then(function (documents){
                documents.should.not.be.equal(undefined);

                var previous = 0;

                documents.map(function(doc){
                    return doc.price;
                }).forEach(function(doc, i){
                    doc.should.not.be.lessThan(previous);
                    previous = doc;
                });

            })
            .should.eventually.notify(done);
        });

        it('should return objects in a certain location', function(done) {
            var radius = 1.5;
            Elasto.query('products')
            .near({
                lat: 51.5,
                lon: -0.1467912,
                radius: radius
            })
            .search().then(function (documents){
                documents.should.not.be.equal(undefined);

                documents.forEach(function(doc){
                    doc.location.lat.should.be.a.Number;
                    doc.location.lon.should.be.a.Number;
                });
            })
            .should.eventually.notify(done);
        });

        it('should return objects in a certain location and sort by distance', function(done) {
            var radius = 1.5;
            Elasto.query('products')
            .near({
                lat: 51.5,
                lon: -0.1467912,
                radius: radius
            })
            .sort('distance')
            .search()
            .then(function (documents){
                documents.should.not.be.equal(undefined);

                documents.forEach(function(doc){
                    doc.location.lat.should.be.a.Number;
                    doc.location.lon.should.be.a.Number;
                });
            })
            .should.eventually.notify(done);
        });

        it('should handle paging', function(done) {
            var oldDocuments = [];

            Elasto.query('products')
            .from(0)
            .size(3)
            .search().then(function (documents){

                documents.should.not.be.equal(undefined);
                documents.length.should.be.equal(3);

                oldDocuments = documents;

                return Elasto.query('products')
                .from(1)
                .size(1)
                .search().then(function (docs){

                    oldDocuments.filter(function(b){
                        return docs[0].slug === b.slug;
                    }).length.should.be.equal(1);
                });

            })
            .should.eventually.notify(done);
        });

        it('should autocomplete the search query', function(done){

            Elasto.query('products').autocomplete('bro')
            .then(function(res){
                res.should.not.be.empty;
                res.forEach(function(product){
                    product.highlight.should.be.ok;
                });
            })
            .should.eventually.notify(done);;
        });

        it('should get documents in a range', function (done) {

            Elasto.query('products').range('price', [0, 1000])
            .search()
            .then(function(res){
                res.should.not.be.empty;
                res.forEach(function(product){
                    product.price.should.be.lessThan(1001);
                    product.price.should.be.greaterThan(-1);
                });
            })
            .should.eventually.notify(done);

        });

        it('should count a query', function (done) {
            Elasto.query('products').count().then(function(count){
                count.should.be.a.Number;
                count.should.be.greaterThan(0);
            })
            .should.eventually.notify(done);
        });

        it ('should delete one record by query', function (done) {
            var oldCount = 110;
            Elasto.query('products').count()
            .then(function (newOldCount) { // get product count before delete
                oldCount = newOldCount;
                return Elasto.query('products')
                    .size(1)
                    .search()
            })
            .then(function (docs) {
                var doc = docs[0];

                return Elasto.query('products')
                    .where('slug', doc.slug)
                    .remove();
            })
            .then(function () {
                return Elasto.query('products').count()
                    .then(function (newCount) {
                        newCount.should.equal(oldCount - 1);
                    });
            })
            .should.eventually.notify(done);
        });

        it ('should not delete all records if params are missing', function (done) {
            Elasto.query('products').count()
            .then(function (oldCount) {

                return Elasto.query('products').remove()
                .then(Bluebird.reject)
                .catch(function noTerms() {
                    return Elasto.query('products').count()
                        .then(function (newCount) {
                            newCount.should.equal(oldCount);
                        });
                });
            })
            .should.eventually.notify(done);
        });

        it('should get multiple documents at once', function (done) {
            var oldSlugs;

            Elasto.query('products').size(5).search()
            .then(function(docs) {
                var oldSlugs = _.map(docs, 'slug');
                return Elasto.query('products').where('slug', oldSlugs).search();
            })
            .then(function(docs) {
                var newSlugs = _.map(docs, 'slug');

                _.difference(oldSlugs, newSlugs).length.should.equal(0);
            })
            .should.eventually.notify(done);
        });

        it('should search with facets', function(done) {

            Elasto.query('products').facets('price', { "terms" : {"field" : "price"} })
            .search().then(function(facets) {
                facets.price.terms.length.should.be.greaterThan(0);
                done();
            });
        });

        it('should do geodistance range', function(done) {

            Elasto.query('products').range('distance', {
                lat: 51.5,
                lon: -0.1467912,
                from: 0,
                to: 1
            })
            .search()
            .then(function(res) {
                res.length.should.be.greaterThan(0);
                done();
            });
        });

        it('should query specific fields', function(done) {
            Elasto.query('products').fields(['name'])
            .search()
            .then(function(res) {
                res.forEach(function(product){
                    _.keys(product).length.should.equal(1);
                    product.name.should.be.ok;
                })
                done();
            });
        });

        it('should sort by distance', function (done) {
            Elasto.query('products')
            .sort('distance', {
                lat: 51,
                lon: -0.14672,
            })
            .search()
            .then(function(res) {

                done();
            });
        });
    });
});
<commit_msg>check for sort in the test<commit_after>var chai = require('chai');
chai.should();
chai.use(require('chai-as-promised'));
var expect = chai.expect;
var _ = require('lodash');
var request  = require('request');
var Bluebird  = require('bluebird');
var chance = require('chance')();
var Elasto = require('../');

Elasto.basePath = 'http://localhost:9200/circle_test';

describe('Elasto', function() {
    var productList = [];
    var createNewProduct;

    before(function(done){

        var indexSettings = {
            "settings": {
                "number_of_shards": 1,
                "analysis": {
                    "filter": {
                        "autocomplete_filter": {
                            "type": "edge_ngram",
                            "min_gram": 1,
                            "max_gram": 20
                        }
                    },
                    "analyzer": {
                        "autocomplete": {
                            "type": "custom",
                            "tokenizer": "standard",
                            "filter": [
                            "lowercase",
                            "autocomplete_filter"
                            ]
                        }
                    }
                }
            }
        };

        Elasto.deleteIndex()
        .then(function(){
            console.log('putain');
            return Elasto.createIndex(indexSettings);
        })
        .should.eventually.notify(done);
    });

    it('should set the mapping', function(done){
        var productMapping = {
            'properties': {
                'slug': { 'type': 'string', 'index': 'not_analyzed' },
                'name': {
                    'type': 'string',
                    'index_analyzer':  'autocomplete',
                    'search_analyzer': 'standard'
                },
                'location' : { 'type' : 'geo_point' }
            }
        };

        Elasto.setMapping('products', productMapping)
        .should.eventually.notify(done);
    });

    describe('save', function () {

        it('should save a product', function (done) {
            var slug = chance.word();
            var boutique_slug = chance.word();
            var price = chance.integer({min: 1, max: 2000});
            var id = price;
            var productToSave = {
                slug: slug,
                boutique_slug: boutique_slug,
                price: price,
                name: chance.word(),
                location: {
                    lat: 51.5,
                    lon: -0.1467912,
                },
                _id: id // Using price as _id
            };

            var product = Elasto.create('products').set(productToSave);

            product.save()
            .then(function(res){
                return Elasto.query('products').byId(id);
            })
            .then(function(res){
                res._id.should.be.equal(id);
            })
            .should.eventually.notify(done);

        });

        it('should save a product with an external version', function (done) {
            var slug = chance.word();
            var boutique_slug = chance.word();
            var price = chance.integer({min: 1, max: 2000});
            var id = price;
            var productToSave = {
                slug: slug,
                boutique_slug: boutique_slug,
                price: price,
                name: chance.word(),
                location: {
                    lat: 51.5,
                    lon: -0.1467912,
                },
                _id: id // Using price as _id
            };

            var product = Elasto.create('products').set(productToSave);

            product.version(1, 'external').save()
            .then(function(res){
                return Elasto.query('products').byId(id);
            })
            .then(function(res){
                res._id.should.be.equal(id);
            })
            .then(function shouldFailWithVersionConflict(){
                var product = Elasto.create('products').set(productToSave);
                return product.version(1, 'external').save()
                    .then(Bluebird.reject)
                    .catch(function(err){
                        expect(err.message).to.have.string('VersionConflictEngineException');
                        return 'ok';
                    });
            })
            .then(function shouldCommitWithHigherVersion(){
                productToSave.name = '{["."]}';
                var product = Elasto.create('products').set(productToSave);
                return product.version(2, 'external').save();
            })
            .then(function(res){
                return Elasto.query('products').byId(id);
            })
            .then(function(res){
                res._id.should.be.equal(id);
                res.name.should.be.equal('{["."]}');
            })
            .should.eventually.notify(done);

        });
    });

    describe('search', function() {

        before(function(done){

            this.timeout(3000);

            for (var i = 0; i < 20; i++) {
                var slug = chance.word();
                var boutique_slug = chance.word();
                var price = chance.integer({min: 1, max: 2000});

                productList.push({
                    slug: slug,
                    boutique_slug: boutique_slug,
                    price: price,
                    name: 'bro ' + chance.word(),
                    location: {
                        lat: 51.5,
                        lon: -0.1467912,
                    },
                });
            }

            createNewProduct = function(newProduct){
                var id = chance.integer({min: 1, max: 2000});
                var productUrl = [Elasto.basePath, 'products', id].join('/'); // 1: index

                return new Bluebird(function (resolve, reject) {
                    request({
                        url: productUrl,
                        method: 'PUT',
                        json: newProduct
                    }, function (err, res, body) {
                        if (err) return reject(err);
                        return resolve(body);
                    });
                });
            };

            Bluebird.map(productList, function(product){
                return createNewProduct(product);
            })
            // The refresh rate of indexing is 1s by default
            .delay(1500)
            .should.eventually.notify(done);
        });

        it('should return a specific size of objects', function(done) {
            var size = 6;

            Elasto.query('products')
            .size(size)
            .search().then(function (documents){

                documents.should.not.be.equal(undefined);
                documents.length.should.be.equal(size);
            })
            .should.eventually.notify(done);
        });

        it('should return a specific size of objects with where', function(done) {
            var boutique_slug = productList[0].boutique_slug;

            Elasto.query('products')
            .where('boutique_slug', boutique_slug)
            .sort('price')
            .search().then(function (documents){
                documents.should.not.be.equal(undefined);

                var previous = 0;

                documents.map(function(doc){
                    return doc.price;
                }).forEach(function(doc, i){
                    doc.should.not.be.lessThan(previous);
                    previous = doc;
                });

            })
            .should.eventually.notify(done);
        });

        it('should return objects in a certain location', function(done) {
            var radius = 1.5;
            Elasto.query('products')
            .near({
                lat: 51.5,
                lon: -0.1467912,
                radius: radius
            })
            .search().then(function (documents){
                documents.should.not.be.equal(undefined);

                documents.forEach(function(doc){
                    doc.location.lat.should.be.a.Number;
                    doc.location.lon.should.be.a.Number;
                });
            })
            .should.eventually.notify(done);
        });

        it('should return objects in a certain location and sort by distance', function(done) {
            var radius = 1.5;
            Elasto.query('products')
            .near({
                lat: 51.5,
                lon: -0.1467912,
                radius: radius
            })
            .sort('distance')
            .search()
            .then(function (documents){
                documents.should.not.be.equal(undefined);

                documents.forEach(function(doc){
                    doc.location.lat.should.be.a.Number;
                    doc.location.lon.should.be.a.Number;
                });
            })
            .should.eventually.notify(done);
        });

        it('should handle paging', function(done) {
            var oldDocuments = [];

            Elasto.query('products')
            .from(0)
            .size(3)
            .search().then(function (documents){

                documents.should.not.be.equal(undefined);
                documents.length.should.be.equal(3);

                oldDocuments = documents;

                return Elasto.query('products')
                .from(1)
                .size(1)
                .search().then(function (docs){

                    oldDocuments.filter(function(b){
                        return docs[0].slug === b.slug;
                    }).length.should.be.equal(1);
                });

            })
            .should.eventually.notify(done);
        });

        it('should autocomplete the search query', function(done){

            Elasto.query('products').autocomplete('bro')
            .then(function(res){
                res.should.not.be.empty;
                res.forEach(function(product){
                    product.highlight.should.be.ok;
                });
            })
            .should.eventually.notify(done);;
        });

        it('should get documents in a range', function (done) {

            Elasto.query('products').range('price', [0, 1000])
            .search()
            .then(function(res){
                res.should.not.be.empty;
                res.forEach(function(product){
                    product.price.should.be.lessThan(1001);
                    product.price.should.be.greaterThan(-1);
                });
            })
            .should.eventually.notify(done);

        });

        it('should count a query', function (done) {
            Elasto.query('products').count().then(function(count){
                count.should.be.a.Number;
                count.should.be.greaterThan(0);
            })
            .should.eventually.notify(done);
        });

        it ('should delete one record by query', function (done) {
            var oldCount = 110;
            Elasto.query('products').count()
            .then(function (newOldCount) { // get product count before delete
                oldCount = newOldCount;
                return Elasto.query('products')
                    .size(1)
                    .search()
            })
            .then(function (docs) {
                var doc = docs[0];

                return Elasto.query('products')
                    .where('slug', doc.slug)
                    .remove();
            })
            .then(function () {
                return Elasto.query('products').count()
                    .then(function (newCount) {
                        newCount.should.equal(oldCount - 1);
                    });
            })
            .should.eventually.notify(done);
        });

        it ('should not delete all records if params are missing', function (done) {
            Elasto.query('products').count()
            .then(function (oldCount) {

                return Elasto.query('products').remove()
                .then(Bluebird.reject)
                .catch(function noTerms() {
                    return Elasto.query('products').count()
                        .then(function (newCount) {
                            newCount.should.equal(oldCount);
                        });
                });
            })
            .should.eventually.notify(done);
        });

        it('should get multiple documents at once', function (done) {
            var oldSlugs;

            Elasto.query('products').size(5).search()
            .then(function(docs) {
                var oldSlugs = _.map(docs, 'slug');
                return Elasto.query('products').where('slug', oldSlugs).search();
            })
            .then(function(docs) {
                var newSlugs = _.map(docs, 'slug');

                _.difference(oldSlugs, newSlugs).length.should.equal(0);
            })
            .should.eventually.notify(done);
        });

        it('should search with facets', function(done) {

            Elasto.query('products').facets('price', { "terms" : {"field" : "price"} })
            .search().then(function(facets) {
                facets.price.terms.length.should.be.greaterThan(0);
                done();
            });
        });

        it('should do geodistance range', function(done) {

            Elasto.query('products').range('distance', {
                lat: 51.5,
                lon: -0.1467912,
                from: 0,
                to: 1
            })
            .search()
            .then(function(res) {
                res.length.should.be.greaterThan(0);
                done();
            });
        });

        it('should query specific fields', function(done) {
            Elasto.query('products').fields(['name'])
            .search()
            .then(function(res) {
                res.forEach(function(product){
                    _.keys(product).length.should.equal(1);
                    product.name.should.be.ok;
                })
                done();
            });
        });

        it('should sort by distance', function (done) {
            Elasto.query('products')
            .sort('distance', {
                lat: 51,
                lon: -0.14672,
            })
            .search()
            .then(function(res) {
                res.forEach(function(product){
                    product.sort[0].should.be.ok;
                });
                done();
            });
        });
    });
});
<|endoftext|>


<commit_before>const resolve = (path, obj) => {
  return path.split('.').reduce((prev, curr) => {
    return prev ? prev[curr] : undefined
  }, obj)
}

module.exports = contact => {
  if (!contact) {
    throw new Error('Missing required input: contact object')
  } else if (!contact.GetPrivatePersonsResult) {
    throw new Error('Malformed contact object')
  }
  const person = resolve('GetPrivatePersonsResult.PrivatePersons.PrivatePersonBase', contact) || resolve('GetPrivatePersonsResult.PrivatePersons.PrivatePersonResult', contact)
  if (!person) {
    return false
  } else if (person.length === 1) {
    return person[0]
  } else if (person.length >= 1) {
    throw new Error('More than 1 person in contact object')
  } else {
    throw new Error('Malformed contact object')
  }
}
<commit_msg>Added unwrap for RPC result<commit_after>const resolve = (path, obj) => {
  return path.split('.').reduce((prev, curr) => {
    return prev ? prev[curr] : undefined
  }, obj)
}

module.exports = contact => {
  if (!contact) {
    throw new Error('Missing required input: contact object')
  } else if (!contact.GetPrivatePersonsResult && !contact.PrivatePersons) {
    throw new Error('Malformed contact object')
  }
  const person = resolve('PrivatePersons', contact) || resolve('GetPrivatePersonsResult.PrivatePersons.PrivatePersonBase', contact) || resolve('GetPrivatePersonsResult.PrivatePersons.PrivatePersonResult', contact)
  if (!person) {
    return false
  } else if (person.length === 1) {
    return person[0]
  } else if (person.length >= 1) {
    throw new Error('More than 1 person in contact object')
  } else {
    throw new Error('Malformed contact object')
  }
}
<|endoftext|>


<commit_before>define({
    environments: [
        {
            'appiumVersion': '1.5.3',
            'deviceName': 'Android Emulator',
            'deviceType': 'phone',
            'deviceOrientation': 'portrait',
            'browserName': 'Browser',
            'platformVersion': '4.4',
            'platformName': 'Android'
        }
        // {
        //     browserName: 'iphone',
        //     version: ['8.1', '9.2'],
        //     recordVideo: false,
        //     recordScreenshots: false
        // },
        // {
        //     browserName: 'android',
        //     version: ['4.4', '5.1'],
        //     recordVideo: false,
        //     recordScreenshots: false
        // },
        // {
        //     browserName: 'chrome',
        //     version: ['31', '32', '54'],
        //     platform: ['Windows 10'],
        //     recordVideo: false,
        //     recordScreenshots: false
        // },
        // {
        //     browserName: 'firefox',
        //     version: ['28', '29', '50'],
        //     platform: ['Windows 10'],
        //     recordVideo: false,
        //     recordScreenshots: false
        // },
        // {
        //     browserName: 'MicrosoftEdge',
        //     version: ['13', '14'],
        //     platform: 'Windows 10',
        //     recordVideo: false,
        //     recordScreenshots: false
        // },
        // {
        //     browserName: 'safari',
        //     version: ['9', '10'],
        //     platform: 'OS X 10.11',
        //     recordVideo: false,
        //     recordScreenshots: false
        // },
        // {
        //     browserName: 'safari',
        //     version: ['7'],
        //     platform: 'OS X 10.9',
        //     recordVideo: false,
        //     recordScreenshots: false
        // },
        // {
        //     browserName: 'internet explorer',
        //     version: ['11'],
        //     platform: 'Windows 7',
        //     recordVideo: false,
        //     recordScreenshots: false
        // }
    ],

    tunnel: 'SauceLabsTunnel',

    maxConcurrency: 5,

    reporters: ['Runner'],

    suites: ['tests/unit/index'],

    excludeInstrumentation: /^(?:tests|node_modules)\//
});
<commit_msg>fallback sauce tests<commit_after>define({
    environments: [
        {
            browserName: 'iphone',
            version: ['8.1', '9.2'],
            recordVideo: false,
            recordScreenshots: false
        },
        {
            browserName: 'android',
            version: ['4.4', '5.1'],
            recordVideo: false,
            recordScreenshots: false
        },
        {
            browserName: 'chrome',
            version: ['31', '32', '54'],
            platform: ['Windows 10'],
            recordVideo: false,
            recordScreenshots: false
        },
        {
            browserName: 'firefox',
            version: ['28', '29', '50'],
            platform: ['Windows 10'],
            recordVideo: false,
            recordScreenshots: false
        },
        {
            browserName: 'MicrosoftEdge',
            version: ['13', '14'],
            platform: 'Windows 10',
            recordVideo: false,
            recordScreenshots: false
        },
        {
            browserName: 'safari',
            version: ['9', '10'],
            platform: 'OS X 10.11',
            recordVideo: false,
            recordScreenshots: false
        },
        {
            browserName: 'safari',
            version: ['7'],
            platform: 'OS X 10.9',
            recordVideo: false,
            recordScreenshots: false
        },
        {
            browserName: 'internet explorer',
            version: ['11'],
            platform: 'Windows 7',
            recordVideo: false,
            recordScreenshots: false
        }
    ],

    tunnel: 'SauceLabsTunnel',

    maxConcurrency: 5,

    reporters: ['Runner'],

    suites: ['tests/unit/index'],

    excludeInstrumentation: /^(?:tests|node_modules)\//
});
<|endoftext|>


<commit_before>#! /usr/bin/env node
const spawn = require('child_process').spawn
const exec = require('child_process').exec

exec('hg branch', (error, stdout, stderr) => {
  if (error) throw (error)

  const JIRA_ISSUE_KEY = stdout.match(/\D{3,4}-\d{1,4}/)
  if (!JIRA_ISSUE_KEY) throw ('No JIRA issue key found on your current branch. Make sure your branch name contains a JIRA issue key.')

  const hgco = spawn('hg', ['commit', '-m', `${process.argv[process.argv.indexOf('-m') + 1]} [${JIRA_ISSUE_KEY}]`], {stdio: 'inherit'})

  process.stdout.on('data', (data) => {
    console.log(data)
  })

  process.stderr.on('data', (data) => {
    console.log(`Error: ${data}`)
  })

  hgco.on('close', () => {
    exec('hg log -l 1', (error, stdout, stderr) => {
      if (error) throw (error)
      console.log('\n' + stdout)
      if (require.main === module) process.exit()
    })
  })
})
<commit_msg>handle no commit message case<commit_after>#! /usr/bin/env node
const spawn = require('child_process').spawn
const exec = require('child_process').exec

exec('hg branch', (error, stdout, stderr) => {
  if (error) throw (error)

  const COMMIT_MESSAGE = process.argv[process.argv.indexOf('-m') + 1]
  const JIRA_ISSUE_KEY = stdout.match(/\D{3,4}-\d{1,4}/)

  if (!COMMIT_MESSAGE) throw ('No commit message provided while it is required.\nUse the following terminal syntax when using hgco:\n"hgco -m \'your commit message goes here\'"')
  if (!JIRA_ISSUE_KEY) throw ('No JIRA issue key found on your current branch. Make sure your branch name contains a JIRA issue key.')

  const hgco = spawn('hg', ['commit', '-m', `${process.argv[process.argv.indexOf('-m') + 1]} [${JIRA_ISSUE_KEY}]`], {stdio: 'inherit'})

  process.stdout.on('data', (data) => {
    console.log(data)
  })

  process.stderr.on('data', (data) => {
    console.log(`Error: ${data}`)
  })

  hgco.on('close', () => {
    exec('hg log -l 1', (error, stdout, stderr) => {
      if (error) throw (error)
      console.log('\n' + stdout)
      if (require.main === module) process.exit()
    })
  })
})
<|endoftext|>


<commit_before>'use strict';

const assume = require('assume');
const errors = require('../errors');
const { assumeFormatted } = require('./helpers');
const { MESSAGE } = require('triple-beam');

const err = new Error('whatever');

const errProps = new Error('another error');
errProps.whatever = true;
errProps.wut = 'some string';

const errInfo = new Error('Already has level');
errInfo.level = 'error';

const errInfoProps = new Error('Level with props');
errInfoProps.level = 'error';
errInfoProps.whatever = true;
errInfoProps.wut = 'some string';

const errLateMessage = new Error();
errLateMessage.message = 'whatever';

describe('errors()({ object })', () => {
  it('errors() returns the original info', assumeFormatted(
    errors(),
    { level: 'info', message: 'whatever' },
    (info) => {
      assume(info.level).is.a('string');
      assume(info.message).is.a('string');
      assume(info.level).equals('info');
      assume(info.message).equals('whatever');
    }
  ));

  it('errors() (default) sets info[MESSAGE]', assumeFormatted(
    errors(),
    { level: 'info', message: err },
    (info) => {
      assume(info.level).is.a('string');
      assume(info.message).is.a('string');
      assume(info.level).equals('info');
      assume(info.message).equals(err.message);
      assume(info[MESSAGE]).equals(err.message);
    }
  ));

  it('errors({ stack: true }) sets info.stack', assumeFormatted(
    errors({ stack: true }),
    { level: 'info', message: err },
    (info) => {
      assume(info.level).is.a('string');
      assume(info.message).is.a('string');
      assume(info.level).equals('info');
      assume(info.message).equals(err.message);
      assume(info[MESSAGE]).equals(err.message);
      assume(info.stack).equals(err.stack);
    }
  ));

  it('errors() sets custom error properties', assumeFormatted(
    errors(),
    { level: 'info', message: errProps },
    (info) => {
      assume(info.level).is.a('string');
      assume(info.message).is.a('string');
      assume(info.level).equals('info');
      assume(info.message).equals(errProps.message);
      assume(info[MESSAGE]).equals(errProps.message);
      assume(info.whatever).true();
      assume(info.wut).equals('some string');
    }
  ));

  it('errors() works with a late-initialized message', assumeFormatted(
    errors(),
    { level: 'info', message: errLateMessage },
    (info) => {
      assume(info.level).is.a('string');
      assume(info.message).is.a('string');
      assume(info.level).equals('info');
      assume(info.message).equals(errLateMessage.message);
      assume(info[MESSAGE]).equals(errLateMessage.message);
    }
  ));
});

describe('errors()(Error)', () => {
  it('errors() (default) sets info[MESSAGE]', assumeFormatted(
    errors(),
    errInfo,
    (info) => {
      assume(info.level).is.a('string');
      assume(info.message).is.a('string');
      assume(info.level).equals(errInfo.level);
      assume(info.message).equals(errInfo.message);
      assume(info[MESSAGE]).equals(errInfo.message);
    },
    { immutable: false }
  ));

  it('errors({ space: 2 }) sets info.stack', assumeFormatted(
    errors({ stack: true }),
    errInfo,
    (info) => {
      assume(info.level).is.a('string');
      assume(info.message).is.a('string');
      assume(info.level).equals(errInfo.level);
      assume(info.message).equals(errInfo.message);
      assume(info[MESSAGE]).equals(errInfo.message);
      assume(info.stack).equals(errInfo.stack);
    },
    { immutable: false }
  ));
});
<commit_msg>Tests for .cause support in errors formatter<commit_after>'use strict';

const assume = require('assume');
const errors = require('../errors');
const { assumeFormatted } = require('./helpers');
const { MESSAGE } = require('triple-beam');

const err = new Error('whatever');

const errProps = new Error('another error');
errProps.whatever = true;
errProps.wut = 'some string';

const errInfo = new Error('Already has level');
errInfo.level = 'error';

const errInfoProps = new Error('Level with props');
errInfoProps.level = 'error';
errInfoProps.whatever = true;
errInfoProps.wut = 'some string';

const errLateMessage = new Error();
errLateMessage.message = 'whatever';

const errWithCause = new Error('wut', { cause: new Error('an error cause') });

describe('errors()({ object })', () => {
  it('errors() returns the original info', assumeFormatted(
    errors(),
    { level: 'info', message: 'whatever' },
    (info) => {
      assume(info.level).is.a('string');
      assume(info.message).is.a('string');
      assume(info.level).equals('info');
      assume(info.message).equals('whatever');
    }
  ));

  it('errors() (default) sets info[MESSAGE]', assumeFormatted(
    errors(),
    { level: 'info', message: err },
    (info) => {
      assume(info.level).is.a('string');
      assume(info.message).is.a('string');
      assume(info.level).equals('info');
      assume(info.message).equals(err.message);
      assume(info[MESSAGE]).equals(err.message);
    }
  ));

  it('errors({ stack: true }) sets info.stack', assumeFormatted(
    errors({ stack: true }),
    { level: 'info', message: err },
    (info) => {
      assume(info.level).is.a('string');
      assume(info.message).is.a('string');
      assume(info.level).equals('info');
      assume(info.message).equals(err.message);
      assume(info[MESSAGE]).equals(err.message);
      assume(info.stack).equals(err.stack);
    }
  ));

  it('errors() sets custom error properties', assumeFormatted(
    errors(),
    { level: 'info', message: errProps },
    (info) => {
      assume(info.level).is.a('string');
      assume(info.message).is.a('string');
      assume(info.level).equals('info');
      assume(info.message).equals(errProps.message);
      assume(info[MESSAGE]).equals(errProps.message);
      assume(info.whatever).true();
      assume(info.wut).equals('some string');
    }
  ));

  it('errors() works with a late-initialized message', assumeFormatted(
    errors(),
    { level: 'info', message: errLateMessage },
    (info) => {
      assume(info.level).is.a('string');
      assume(info.message).is.a('string');
      assume(info.level).equals('info');
      assume(info.message).equals(errLateMessage.message);
      assume(info[MESSAGE]).equals(errLateMessage.message);
    }
  ));

  it('errors({ cause: true }) sets info.cause', assumeFormatted(
    errors({ cause: true }),
    { level: 'info', message: errWithCause },
    (info) => {
      assume(info.level).is.a('string');
      assume(info.message).is.a('string');
      assume(info.level).equals('info');
      assume(info.message).equals(errWithCause.message);
      assume(info[MESSAGE]).equals(errWithCause.message);
      assume(info.cause).equals(errWithCause.cause);
    }
  ));

  it('errors({ stack: true, cause: true }) sets info.stack and info.cause', assumeFormatted(
    errors({ stack: true, cause: true }),
    { level: 'info', message: errWithCause },
    (info) => {
      assume(info.level).is.a('string');
      assume(info.message).is.a('string');
      assume(info.level).equals('info');
      assume(info.message).equals(errWithCause.message);
      assume(info[MESSAGE]).equals(errWithCause.message);
      assume(info.stack).equals(errWithCause.stack);
      assume(info.cause).equals(errWithCause.cause);
    }
  ));
});

describe('errors()(Error)', () => {
  it('errors() (default) sets info[MESSAGE]', assumeFormatted(
    errors(),
    errInfo,
    (info) => {
      assume(info.level).is.a('string');
      assume(info.message).is.a('string');
      assume(info.level).equals(errInfo.level);
      assume(info.message).equals(errInfo.message);
      assume(info[MESSAGE]).equals(errInfo.message);
    },
    { immutable: false }
  ));

  it('errors({ space: 2 }) sets info.stack', assumeFormatted(
    errors({ stack: true }),
    errInfo,
    (info) => {
      assume(info.level).is.a('string');
      assume(info.message).is.a('string');
      assume(info.level).equals(errInfo.level);
      assume(info.message).equals(errInfo.message);
      assume(info[MESSAGE]).equals(errInfo.message);
      assume(info.stack).equals(errInfo.stack);
    },
    { immutable: false }
  ));
});
<|endoftext|>


<commit_before>//
// The fetcher is responsible for fetching new
// trades at the exchange. It will emit `new trades`
// events as soon as it fetches new data.
//
// How often this is depends on:
//
//  - The capability of the exchange (to provide
//  historical data).
//  - The amount of data we get per fetch.
//  - The interval at which we need new data.

var _ = require('lodash');
var moment = require('moment');
var utc = moment.utc;
var log = require('./log.js');

var util = require('./util');
var config = util.getConfig();

var exchangeChecker = require('./exchangeChecker');

var provider = config.watch.exchange.toLowerCase();
var DataProvider = require('../exchanges/' + provider);

var Fetcher = function() {
  _.bindAll(this);

  // Create a public dataProvider object which can retrieve live
  // trade information from an exchange.

  this.watcher = new DataProvider(config.watch);
  this.lastFetch = false;

  this.exchange = exchangeChecker.settings(config.watch);

  this.pair = [
    config.watch.asset,
    config.watch.currency
  ].join('/');

  // console.log(config);
  log.info('Starting to watch the market:',
    this.exchange.name,
    this.pair
  );

  if(!this.exchange.providesHistory) {
    this.on('new trades', function(a) {
      log.debug(
        'Fetched',
        _.size(a.all),
        'new trades, from',
        a.start.format('YYYY-MM-DD HH:mm:ss UTC'),
        'to',
        a.end.format('YYYY-MM-DD HH:mm:ss UTC')
      );
    });
  }
}

var Util = require('util');
var EventEmitter = require('events').EventEmitter;
Util.inherits(Fetcher, EventEmitter);

Fetcher.prototype.start = function() {
  // if this exchange does not support historical trades
  // start fetching.
  if(!this.exchange.providesHistory)
    this.fetch(false);
  else
    console.log(
      'either start looping right away (`since`)',
      'or first determine starting point dynamically'
    );
}

// Set the first & last trade date and set the
// timespan between them.
Fetcher.prototype.setFetchMeta = function(trades) {
  this.firstTrade = _.first(trades);
  this.first = moment.unix(this.firstTrade.date).utc();
  this.lastTrade = _.last(trades);
  this.last = moment.unix(this.lastTrade.date).utc();

  this.fetchTimespan = util.calculateTimespan(this.first, this.last);
}

// *This method is only used if this exchange does not support
// historical data.*
//
// we need to keep polling exchange because we cannot
// access older data. We need to calculate how often we
// we should poll.
//
// Returns amount of ms to wait for until next fetch.
Fetcher.prototype.calculateNextFetch = function(trades) {

  // for now just refetch every minute
  return this.fetchAfter = util.minToMs(1);

  // if the timespan per fetch is fixed at this exchange,
  // just return that number.
  if(this.exchange.fetchTimespan) {
    // todo: if the interval doesn't go in
    // sync with exchange fetchTimes we
    // need to calculate overlapping times.
    //
    // eg: if we can fetch every 60 min but user
    // interval is at 80, we would also need to
    // fetch again at 80 min.
    var min = _.min([
      this.exchange.fetchTimespan,
      config.tradingAdvisor.candleSize
    ]);
    this.fetchAfter = util.minToMs(min);
    // debugging bitstamp
    this.fetchAfter = util.minToMs(1);
    return;
  }

  var minimalInterval = util.minToMs(config.tradingAdvisor.candleSize);

  // if we got the last 100 seconds of trades last
  // time make sure we fetch at least in 55 seconds
  // again.
  var safeTreshold = 0.2;
  var defaultFetchTime = util.minToMs(1);

  if(this.fetchTimespan * safeTreshold > minimalInterval)
    // If the oldest trade in a fetch call > candle size
    // we can just use candle size.
    var fetchAfter = minimalInterval;
  else if(this.fetchTimespan * safeTreshold < defaultFetchTime)
    // If the oldest trade in a fetch call < default time
    // we fetch at default time.
    var fetchAfter = defaultFetchTime;
  else
    // use a safe fetch time to determine
    var fetchAfter = this.fetchTimespan * safeTreshold;

  this.fetchAfter = fetchAfter;
}

Fetcher.prototype.scheduleNextFetch = function() {
  setTimeout(this.fetch, this.fetchAfter);
}

Fetcher.prototype.fetch = function(since) {
  log.debug('Requested', this.pair ,'trade data from', this.exchange.name, '...');
  this.watcher.getTrades(since, this.processTrades, false);
  // this.spoofTrades();
}

Fetcher.prototype.spoofTrades = function() {
  var fs = require('fs');
  trades = JSON.parse( fs.readFileSync('./a3.json', 'utf8') );
  this.processTrades(false, trades);

  setTimeout(this.spoofTrades2, 5000);
}

Fetcher.prototype.spoofTrades2 = function() {
  var fs = require('fs');
  trades = JSON.parse( fs.readFileSync('./a4.json', 'utf8') );
  this.processTrades(false, trades);
}

Fetcher.prototype.processTrades = function(err, trades) {
  if(err)
    throw err;

  this.setFetchMeta(trades);
  this.calculateNextFetch();

  // schedule next fetch
  if(!this.exchange.providesHistory)
    this.scheduleNextFetch();

  this.emit('new trades', {
    timespan: this.fetchTimespan,
    start: this.first,
    first: this.firstTrade,
    end: this.last,
    last: this.lastTrade,
    all: trades,
    nextIn: this.fetchAfter
  });
}

module.exports = Fetcher;<commit_msg>Make sure we have trades to process<commit_after>//
// The fetcher is responsible for fetching new
// trades at the exchange. It will emit `new trades`
// events as soon as it fetches new data.
//
// How often this is depends on:
//
//  - The capability of the exchange (to provide
//  historical data).
//  - The amount of data we get per fetch.
//  - The interval at which we need new data.

var _ = require('lodash');
var moment = require('moment');
var utc = moment.utc;
var log = require('./log.js');

var util = require('./util');
var config = util.getConfig();

var exchangeChecker = require('./exchangeChecker');

var provider = config.watch.exchange.toLowerCase();
var DataProvider = require('../exchanges/' + provider);

var Fetcher = function() {
  _.bindAll(this);

  // Create a public dataProvider object which can retrieve live
  // trade information from an exchange.

  this.watcher = new DataProvider(config.watch);
  this.lastFetch = false;

  this.exchange = exchangeChecker.settings(config.watch);

  this.pair = [
    config.watch.asset,
    config.watch.currency
  ].join('/');

  // console.log(config);
  log.info('Starting to watch the market:',
    this.exchange.name,
    this.pair
  );

  if(!this.exchange.providesHistory) {
    this.on('new trades', function(a) {
      log.debug(
        'Fetched',
        _.size(a.all),
        'new trades, from',
        a.start.format('YYYY-MM-DD HH:mm:ss UTC'),
        'to',
        a.end.format('YYYY-MM-DD HH:mm:ss UTC')
      );
    });
  }
}

var Util = require('util');
var EventEmitter = require('events').EventEmitter;
Util.inherits(Fetcher, EventEmitter);

Fetcher.prototype.start = function() {
  // if this exchange does not support historical trades
  // start fetching.
  if(!this.exchange.providesHistory)
    this.fetch(false);
  else
    console.log(
      'either start looping right away (`since`)',
      'or first determine starting point dynamically'
    );
}

// Set the first & last trade date and set the
// timespan between them.
Fetcher.prototype.setFetchMeta = function(trades) {
  this.firstTrade = _.first(trades);
  this.first = moment.unix(this.firstTrade.date).utc();
  this.lastTrade = _.last(trades);
  this.last = moment.unix(this.lastTrade.date).utc();

  this.fetchTimespan = util.calculateTimespan(this.first, this.last);
}

// *This method is only used if this exchange does not support
// historical data.*
//
// we need to keep polling exchange because we cannot
// access older data. We need to calculate how often we
// we should poll.
//
// Returns amount of ms to wait for until next fetch.
Fetcher.prototype.calculateNextFetch = function(trades) {

  // for now just refetch every minute
  return this.fetchAfter = util.minToMs(1);

  // if the timespan per fetch is fixed at this exchange,
  // just return that number.
  if(this.exchange.fetchTimespan) {
    // todo: if the interval doesn't go in
    // sync with exchange fetchTimes we
    // need to calculate overlapping times.
    //
    // eg: if we can fetch every 60 min but user
    // interval is at 80, we would also need to
    // fetch again at 80 min.
    var min = _.min([
      this.exchange.fetchTimespan,
      config.tradingAdvisor.candleSize
    ]);
    this.fetchAfter = util.minToMs(min);
    // debugging bitstamp
    this.fetchAfter = util.minToMs(1);
    return;
  }

  var minimalInterval = util.minToMs(config.tradingAdvisor.candleSize);

  // if we got the last 100 seconds of trades last
  // time make sure we fetch at least in 55 seconds
  // again.
  var safeTreshold = 0.2;
  var defaultFetchTime = util.minToMs(1);

  if(this.fetchTimespan * safeTreshold > minimalInterval)
    // If the oldest trade in a fetch call > candle size
    // we can just use candle size.
    var fetchAfter = minimalInterval;
  else if(this.fetchTimespan * safeTreshold < defaultFetchTime)
    // If the oldest trade in a fetch call < default time
    // we fetch at default time.
    var fetchAfter = defaultFetchTime;
  else
    // use a safe fetch time to determine
    var fetchAfter = this.fetchTimespan * safeTreshold;

  this.fetchAfter = fetchAfter;
}

Fetcher.prototype.scheduleNextFetch = function() {
  setTimeout(this.fetch, this.fetchAfter);
}

Fetcher.prototype.fetch = function(since) {
  log.debug('Requested', this.pair ,'trade data from', this.exchange.name, '...');
  this.watcher.getTrades(since, this.processTrades, false);
  // this.spoofTrades();
}

Fetcher.prototype.spoofTrades = function() {
  var fs = require('fs');
  trades = JSON.parse( fs.readFileSync('./a3.json', 'utf8') );
  this.processTrades(false, trades);

  setTimeout(this.spoofTrades2, 5000);
}

Fetcher.prototype.spoofTrades2 = function() {
  var fs = require('fs');
  trades = JSON.parse( fs.readFileSync('./a4.json', 'utf8') );
  this.processTrades(false, trades);
}

Fetcher.prototype.processTrades = function(err, trades) {
  if(err)
    throw err;

  // Make sure we have trades to process
  if (trades.length < 1) {
    log.debug('Trade fetch came back empty. Rescheduling...');
    this.calculateNextFetch();
    this.scheduleNextFetch();
    return;
  }

  this.setFetchMeta(trades);
  this.calculateNextFetch();

  // schedule next fetch
  if(!this.exchange.providesHistory)
    this.scheduleNextFetch();

  this.emit('new trades', {
    timespan: this.fetchTimespan,
    start: this.first,
    first: this.firstTrade,
    end: this.last,
    last: this.lastTrade,
    all: trades,
    nextIn: this.fetchAfter
  });
}

module.exports = Fetcher;<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react'

const ImageExists = function(url, callback) {
  var img = new Image()
  img.onload = function() { callback(true) }
  img.onerror = function() { callback(false) }
  img.src = url
}

class IfImg extends Component {
  constructor(props) {
    super()
    this.state = {
      existence: undefined
    }
    this.checkExistence(props)
  }
  render() {
    let { alt, altProps, children, ...rest } = this.props
    return (

        {this.state.existence !== 'undefined' &&
          this.state.existence ?
            (

            ) : (
              {children ? children : alt}
            )
        }

    )
  }
  componentWillReceiveProps(nextProps) {
    if (this.props.src !== nextProps.src) {
      this.setState({existence: undefined})
      this.checkExistence(nextProps)
    }
  }
  checkExistence(props) {
    ImageExists(props.src, (existence) => {
      this.setState({existence: existence})
    })
  }
}

IfImg.propTypes = {
  src: PropTypes.string.isRequired,
  alt: PropTypes.string.isRequired,
  altProps: PropTypes.object,
  children: PropTypes.oneOf([PropTypes.func, PropTypes.element])
}

export default IfImg<commit_msg>refactor<commit_after>import React, { Component, PropTypes } from 'react'

class IfImg extends Component {
  constructor(props) {
    super()
    this.state = {
      existence: undefined
    }
    this.checkExistence(props)
  }
  render() {
    let { alt, altProps, children, ...rest } = this.props
    return (

        {this.state.existence !== 'undefined' &&
          this.state.existence ?
            (

            ) : (
              {children ? children : alt}
            )
        }

    )
  }
  componentWillReceiveProps(nextProps) {
    if (this.props.src !== nextProps.src) {
      this.setState({existence: undefined})
      this.checkExistence(nextProps)
    }
  }
  checkExistence(props) {
    new Promise((resolve, reject) => {
      let img = new Image()
      img.onload = () => { resolve(true) }
      img.onerror = () => { resolve(false) }
      img.src = props.src
    }).then((existence) => {
      this.setState({existence: existence})
    })
  }
}

IfImg.propTypes = {
  src: PropTypes.string.isRequired,
  alt: PropTypes.string.isRequired,
  altProps: PropTypes.object,
  children: PropTypes.oneOf([PropTypes.func, PropTypes.element])
}

export default IfImg<|endoftext|>