<commit_before>var RiakConnectionAdapter = require('../../').connectionAdapters.Riak;

var Promise = require('promise');
var expect = require('chai').expect;
var sinon = require('sinon');
var promiseCheck = require('../utils').promiseCheck;

describe('Riak', function () {

	describe('Initialization', function () {

		it('should have default values', function () {

			var instance = new RiakConnectionAdapter();

			expect(instance._schema).to.be.equal('http');
			expect(instance._host).to.be.equal('localhost');
			expect(instance._port).to.be.equal(8098);
		});

		it('should have initialized values', function () {

			var instance = new RiakConnectionAdapter({
				schema: 'https',
				host: '127.0.0.1',
				port: 2345
			});

			expect(instance._schema).to.be.equal('https');
			expect(instance._host).to.be.equal('127.0.0.1');
			expect(instance._port).to.be.equal(2345);
		});
	});

	describe('Instance', function () {

		beforeEach(function () {
			this.instance = new RiakConnectionAdapter();
		});

		it('should get the url', function () {
			expect(this.instance._getUrlWithPath('/test/path')).to.be.equal('http://localhost:8098/test/path');
		});

		describe('Buckets', function () {

			beforeEach(function () {
				this.sandbox = sinon.sandbox.create();

				this.request = this.sandbox.stub(this.instance, '_request', function (options) {
					expect(options.method).to.be.equal('GET');
					return Promise.resolve({ body: JSON.stringify({ "buckets": ["test1", "test2", "test12", "test11", "test22"] }) });
				});
			});

			afterEach(function () {
				this.sandbox.restore();
			});

			describe('getBuckets', function () {

				it('should first process all pending promises', function (done) {

					var processed = false;

					this.instance.setPromise(this.instance.getPromise().then(function () {
						processed = true;
					}));

					promiseCheck(this.instance.getBuckets(), function () {
						expect(processed).to.be.true;
					}.bind(this), done);
				});

				it('should request from the correct url', function (done) {
					this.pathSpy = this.sandbox.spy(this.instance, '_getUrlWithPath');

					promiseCheck(this.instance.getBuckets(), function () {
						expect(this.pathSpy.lastCall.args.length).to.be.equal(1);
						expect(this.pathSpy.lastCall.args[0]).to.be.equal('/buckets?buckets=true');
					}.bind(this), done);
				});

				it('should get all buckets', function (done) {

					promiseCheck(this.instance.getBuckets(), function (buckets) {
						expect(buckets).to.be.deep.equal(["test1", "test2", "test12", "test11", "test22"]);
					}, done);
				});

				it('should filter buckets', function (done) {

					promiseCheck(this.instance.getBuckets(function (bucket) {
						return (bucket.substr(0, 5) !== "test1");
					}), function (buckets) {
						expect(buckets).to.be.deep.equal(["test2", "test22"]);
					}, done);
				});
			});

			describe('hasBuckets', function () {

				it('should have bucket', function (done) {

					promiseCheck(this.instance.hasBucket('test2'), function (hasIt) {
						expect(hasIt).to.be.true;
					}.bind(this), done);
				});

				it('should have bucket with filter', function (done) {

					promiseCheck(this.instance.hasBucket('test2', function (bucket) {
						return (bucket.substr(0, 5) !== "test1");
					}), function (hasIt) {
						expect(hasIt).to.be.true;
					}.bind(this), done);
				});

				it('should not have bucket with filter', function (done) {

					promiseCheck(this.instance.hasBucket('test11', function (bucket) {
						return (bucket.substr(0, 5) !== "test1");
					}), function (hasIt) {
						expect(hasIt).to.be.false;
					}.bind(this), done);
				});
			});
		});

		describe('Bucket Keys', function () {

			beforeEach(function () {
				this.sandbox = sinon.sandbox.create();

				this.request = this.sandbox.stub(this.instance, '_request', function (options) {
					expect(options.method).to.be.equal('GET');
					return Promise.resolve({ body: JSON.stringify({ "keys": ["test1", "test2", "test12", "test11", "test22"] }) });
				});
			});

			afterEach(function () {
				this.sandbox.restore();
			});

			describe('getBucketKeys', function () {

				it('should first process all pending promises', function (done) {

					var processed = false;

					this.instance.setPromise(this.instance.getPromise().then(function () {
						processed = true;
					}));

					promiseCheck(this.instance.getBucketKeys(), function () {
						expect(processed).to.be.true;
					}.bind(this), done);
				});

				it('should request from the correct url', function (done) {
					this.pathSpy = this.sandbox.spy(this.instance, '_getUrlWithPath');

					promiseCheck(this.instance.getBucketKeys("test#$bucket"), function () {
						expect(this.pathSpy.lastCall.args.length).to.be.equal(1);
						expect(this.pathSpy.lastCall.args[0]).to.be.equal('/buckets/test%23%24bucket/keys?keys=true');
					}.bind(this), done);
				});

				it('should get all buckets', function (done) {

					promiseCheck(this.instance.getBucketKeys("test#$bucket"), function (buckets) {
						expect(buckets).to.be.deep.equal(["test1", "test2", "test12", "test11", "test22"]);
					}, done);
				});

				it('should filter buckets', function (done) {

					promiseCheck(this.instance.getBucketKeys("test#$bucket", function (bucket) {
						return (bucket.substr(0, 5) !== "test1");
					}), function (buckets) {
						expect(buckets).to.be.deep.equal(["test2", "test22"]);
					}, done);
				});
			});

			describe('hasBucketKey', function () {

				it('should have bucket', function (done) {

					promiseCheck(this.instance.hasBucketKey("test#$bucket", 'test2'), function (hasIt) {
						expect(hasIt).to.be.true;
					}.bind(this), done);
				});

				it('should have bucket with filter', function (done) {

					promiseCheck(this.instance.hasBucketKey("test#$bucket", 'test2', function (bucket) {
						return (bucket.substr(0, 5) !== "test1");
					}), function (hasIt) {
						expect(hasIt).to.be.true;
					}.bind(this), done);
				});

				it('should not have bucket with filter', function (done) {

					promiseCheck(this.instance.hasBucketKey("test#$bucket", 'test11', function (bucket) {
						return (bucket.substr(0, 5) !== "test1");
					}), function (hasIt) {
						expect(hasIt).to.be.false;
					}.bind(this), done);
				});
			});
		});

		describe('Object', function () {

			beforeEach(function () {

				this.sandbox = sinon.sandbox.create();

				this.object = new Buffer(3);
				this.object[0] = 11;
				this.object[1] = 12;
				this.object[2] = 13;

				this.instance.__data = this.object;

				this.request = this.sandbox.stub(this.instance, '_request', function (options) {
					if (options.method === 'GET') {
						return Promise.resolve({ body: this.__data });
					} else if (options.method === 'PUT') {
						this.__data = options.body;
						this.__headers = options.headers;
						return Promise.resolve();
					} else if (options.method === 'DELETE') {
						return Promise.resolve();
					}
				});
			});

			afterEach(function () {
				this.sandbox.restore();
			});

			describe('getObject', function () {

				it('should first process all pending promises', function (done) {

					var processed = false;

					this.instance.setPromise(this.instance.getPromise().then(function () {
						processed = true;
					}));

					promiseCheck(this.instance.getObject("test#$bucket", "test#$key"), function () {
						expect(processed).to.be.true;
					}.bind(this), done);
				});

				it('should request from the correct url', function (done) {
					this.pathSpy = this.sandbox.spy(this.instance, '_getUrlWithPath');

					promiseCheck(this.instance.getObject("test#$bucket", "test#$key"), function () {
						expect(this.pathSpy.lastCall.args.length).to.be.equal(1);
						expect(this.pathSpy.lastCall.args[0]).to.be.equal('/buckets/test%23%24bucket/keys/test%23%24key');
					}.bind(this), done);
				});

				it('should get object', function (done) {

					promiseCheck(this.instance.getObject("test#$bucket", "test#$key"), function (obj) {
						expect(JSON.stringify(obj)).to.be.equal("[11,12,13]");
					}, done);
				});

				it('should get object as JSON', function (done) {

					var expected = {
						test: 23,
						sub: {
							hello: "world"
						}
					};
					this.instance.__data = JSON.stringify(expected);

					promiseCheck(this.instance.getObjectAsJSON("test#$bucket", "test#$key"), function (jsonObj) {
						expect(jsonObj).to.be.deep.equal(expected);
					}, done);
				});
			});

			describe('setObject', function () {

				it('should first process all pending promises', function (done) {

					var processed = false;

					this.instance.setPromise(this.instance.getPromise().then(function () {
						processed = true;
					}));

					promiseCheck(this.instance.setObject("test#$bucket", "test#$key", this.object), function () {
						expect(processed).to.be.true;
					}.bind(this), done);
				});

				it('should request from the correct url', function (done) {
					this.pathSpy = this.sandbox.spy(this.instance, '_getUrlWithPath');

					promiseCheck(this.instance.setObject("test#$bucket", "test#$key", this.object), function () {
						expect(this.pathSpy.lastCall.args.length).to.be.equal(1);
						expect(this.pathSpy.lastCall.args[0]).to.be.equal('/buckets/test%23%24bucket/keys/test%23%24key');
					}.bind(this), done);
				});

				it('should set object', function (done) {

					promiseCheck(this.instance.setObject("test#$bucket", "test#$key", this.object), function () {
						expect(JSON.stringify(this.instance.__data)).to.be.equal("[11,12,13]");
						expect(this.instance.__headers['Content-Type']).to.be.equal("application/octet-stream");
					}.bind(this), done);
				});

				it('should set object with custom mime-type', function (done) {

					promiseCheck(this.instance.setObject("test#$bucket", "test#$key", this.object, "test/mime"), function () {
						expect(this.instance.__headers['Content-Type']).to.be.equal("test/mime");
					}.bind(this), done);
				});

				it('should set object with JSON', function (done) {

					var expected = {
						test: 23,
						sub: {
							hello: "world"
						}
					};

					promiseCheck(this.instance.setObjectFromJSON("test#$bucket", "test#$key", expected), function () {
						expect(JSON.parse(this.instance.__data)).to.be.deep.equal(expected);
						expect(this.instance.__headers['Content-Type']).to.be.equal("application/json");
					}.bind(this), done);
				});
			});

			describe('removeObject', function () {

				it('should first process all pending promises', function (done) {

					var processed = false;

					this.instance.setPromise(this.instance.getPromise().then(function () {
						processed = true;
					}));

					promiseCheck(this.instance.removeObject("test#$bucket", "test#$key", this.object), function () {
						expect(processed).to.be.true;
					}.bind(this), done);
				});

				it('should request from the correct url', function (done) {
					this.pathSpy = this.sandbox.spy(this.instance, '_getUrlWithPath');

					promiseCheck(this.instance.removeObject("test#$bucket", "test#$key", this.object), function () {
						expect(this.pathSpy.lastCall.args.length).to.be.equal(1);
						expect(this.pathSpy.lastCall.args[0]).to.be.equal('/buckets/test%23%24bucket/keys/test%23%24key');
					}.bind(this), done);
				});

				it('should remove object', function (done) {
					promiseCheck(this.instance.removeObject("test#$bucket", "test#$key", this.object), function () {}, done);
				});

				it('should remove all objects', function (done) {

					var removeObjectStub = this.sandbox.stub(this.instance, "removeObject", function () {
						return Promise.resolve();
					});

					this.instance.__data = JSON.stringify({ keys:[ "test1", "test2" ] });

					promiseCheck(this.instance.removeAllObjects("test#$bucket"), function () {

						expect(removeObjectStub.callCount).to.be.equal(2);

						expect(removeObjectStub.getCall(0).args.length).to.be.equal(2);
						expect(removeObjectStub.getCall(0).args[0]).to.be.equal("test#$bucket");
						expect(removeObjectStub.getCall(0).args[1]).to.be.equal("test1");

						expect(removeObjectStub.getCall(1).args.length).to.be.equal(2);
						expect(removeObjectStub.getCall(1).args[0]).to.be.equal("test#$bucket");
						expect(removeObjectStub.getCall(1).args[1]).to.be.equal("test2");

					}.bind(this), done);
				});
			});
		});
	});
});
<commit_msg>Fix Buffer issues in tests with versions 0.8 and 1.1<commit_after>var RiakConnectionAdapter = require('../../').connectionAdapters.Riak;

var Promise = require('promise');
var expect = require('chai').expect;
var sinon = require('sinon');
var promiseCheck = require('../utils').promiseCheck;

describe('Riak', function () {

	describe('Initialization', function () {

		it('should have default values', function () {

			var instance = new RiakConnectionAdapter();

			expect(instance._schema).to.be.equal('http');
			expect(instance._host).to.be.equal('localhost');
			expect(instance._port).to.be.equal(8098);
		});

		it('should have initialized values', function () {

			var instance = new RiakConnectionAdapter({
				schema: 'https',
				host: '127.0.0.1',
				port: 2345
			});

			expect(instance._schema).to.be.equal('https');
			expect(instance._host).to.be.equal('127.0.0.1');
			expect(instance._port).to.be.equal(2345);
		});
	});

	describe('Instance', function () {

		beforeEach(function () {
			this.instance = new RiakConnectionAdapter();
		});

		it('should get the url', function () {
			expect(this.instance._getUrlWithPath('/test/path')).to.be.equal('http://localhost:8098/test/path');
		});

		describe('Buckets', function () {

			beforeEach(function () {
				this.sandbox = sinon.sandbox.create();

				this.request = this.sandbox.stub(this.instance, '_request', function (options) {
					expect(options.method).to.be.equal('GET');
					return Promise.resolve({ body: JSON.stringify({ "buckets": ["test1", "test2", "test12", "test11", "test22"] }) });
				});
			});

			afterEach(function () {
				this.sandbox.restore();
			});

			describe('getBuckets', function () {

				it('should first process all pending promises', function (done) {

					var processed = false;

					this.instance.setPromise(this.instance.getPromise().then(function () {
						processed = true;
					}));

					promiseCheck(this.instance.getBuckets(), function () {
						expect(processed).to.be.true;
					}.bind(this), done);
				});

				it('should request from the correct url', function (done) {
					this.pathSpy = this.sandbox.spy(this.instance, '_getUrlWithPath');

					promiseCheck(this.instance.getBuckets(), function () {
						expect(this.pathSpy.lastCall.args.length).to.be.equal(1);
						expect(this.pathSpy.lastCall.args[0]).to.be.equal('/buckets?buckets=true');
					}.bind(this), done);
				});

				it('should get all buckets', function (done) {

					promiseCheck(this.instance.getBuckets(), function (buckets) {
						expect(buckets).to.be.deep.equal(["test1", "test2", "test12", "test11", "test22"]);
					}, done);
				});

				it('should filter buckets', function (done) {

					promiseCheck(this.instance.getBuckets(function (bucket) {
						return (bucket.substr(0, 5) !== "test1");
					}), function (buckets) {
						expect(buckets).to.be.deep.equal(["test2", "test22"]);
					}, done);
				});
			});

			describe('hasBuckets', function () {

				it('should have bucket', function (done) {

					promiseCheck(this.instance.hasBucket('test2'), function (hasIt) {
						expect(hasIt).to.be.true;
					}.bind(this), done);
				});

				it('should have bucket with filter', function (done) {

					promiseCheck(this.instance.hasBucket('test2', function (bucket) {
						return (bucket.substr(0, 5) !== "test1");
					}), function (hasIt) {
						expect(hasIt).to.be.true;
					}.bind(this), done);
				});

				it('should not have bucket with filter', function (done) {

					promiseCheck(this.instance.hasBucket('test11', function (bucket) {
						return (bucket.substr(0, 5) !== "test1");
					}), function (hasIt) {
						expect(hasIt).to.be.false;
					}.bind(this), done);
				});
			});
		});

		describe('Bucket Keys', function () {

			beforeEach(function () {
				this.sandbox = sinon.sandbox.create();

				this.request = this.sandbox.stub(this.instance, '_request', function (options) {
					expect(options.method).to.be.equal('GET');
					return Promise.resolve({ body: JSON.stringify({ "keys": ["test1", "test2", "test12", "test11", "test22"] }) });
				});
			});

			afterEach(function () {
				this.sandbox.restore();
			});

			describe('getBucketKeys', function () {

				it('should first process all pending promises', function (done) {

					var processed = false;

					this.instance.setPromise(this.instance.getPromise().then(function () {
						processed = true;
					}));

					promiseCheck(this.instance.getBucketKeys(), function () {
						expect(processed).to.be.true;
					}.bind(this), done);
				});

				it('should request from the correct url', function (done) {
					this.pathSpy = this.sandbox.spy(this.instance, '_getUrlWithPath');

					promiseCheck(this.instance.getBucketKeys("test#$bucket"), function () {
						expect(this.pathSpy.lastCall.args.length).to.be.equal(1);
						expect(this.pathSpy.lastCall.args[0]).to.be.equal('/buckets/test%23%24bucket/keys?keys=true');
					}.bind(this), done);
				});

				it('should get all buckets', function (done) {

					promiseCheck(this.instance.getBucketKeys("test#$bucket"), function (buckets) {
						expect(buckets).to.be.deep.equal(["test1", "test2", "test12", "test11", "test22"]);
					}, done);
				});

				it('should filter buckets', function (done) {

					promiseCheck(this.instance.getBucketKeys("test#$bucket", function (bucket) {
						return (bucket.substr(0, 5) !== "test1");
					}), function (buckets) {
						expect(buckets).to.be.deep.equal(["test2", "test22"]);
					}, done);
				});
			});

			describe('hasBucketKey', function () {

				it('should have bucket', function (done) {

					promiseCheck(this.instance.hasBucketKey("test#$bucket", 'test2'), function (hasIt) {
						expect(hasIt).to.be.true;
					}.bind(this), done);
				});

				it('should have bucket with filter', function (done) {

					promiseCheck(this.instance.hasBucketKey("test#$bucket", 'test2', function (bucket) {
						return (bucket.substr(0, 5) !== "test1");
					}), function (hasIt) {
						expect(hasIt).to.be.true;
					}.bind(this), done);
				});

				it('should not have bucket with filter', function (done) {

					promiseCheck(this.instance.hasBucketKey("test#$bucket", 'test11', function (bucket) {
						return (bucket.substr(0, 5) !== "test1");
					}), function (hasIt) {
						expect(hasIt).to.be.false;
					}.bind(this), done);
				});
			});
		});

		describe('Object', function () {

			beforeEach(function () {

				this.sandbox = sinon.sandbox.create();

				this.object = [];
				this.object[0] = 11;
				this.object[1] = 12;
				this.object[2] = 13;

				this.instance.__data = this.object;

				this.request = this.sandbox.stub(this.instance, '_request', function (options) {
					if (options.method === 'GET') {
						return Promise.resolve({ body: this.__data });
					} else if (options.method === 'PUT') {
						this.__data = options.body;
						this.__headers = options.headers;
						return Promise.resolve();
					} else if (options.method === 'DELETE') {
						return Promise.resolve();
					}
				});
			});

			afterEach(function () {
				this.sandbox.restore();
			});

			describe('getObject', function () {

				it('should first process all pending promises', function (done) {

					var processed = false;

					this.instance.setPromise(this.instance.getPromise().then(function () {
						processed = true;
					}));

					promiseCheck(this.instance.getObject("test#$bucket", "test#$key"), function () {
						expect(processed).to.be.true;
					}.bind(this), done);
				});

				it('should request from the correct url', function (done) {
					this.pathSpy = this.sandbox.spy(this.instance, '_getUrlWithPath');

					promiseCheck(this.instance.getObject("test#$bucket", "test#$key"), function () {
						expect(this.pathSpy.lastCall.args.length).to.be.equal(1);
						expect(this.pathSpy.lastCall.args[0]).to.be.equal('/buckets/test%23%24bucket/keys/test%23%24key');
					}.bind(this), done);
				});

				it('should get object', function (done) {

					promiseCheck(this.instance.getObject("test#$bucket", "test#$key"), function (obj) {
						expect(JSON.stringify(obj)).to.be.equal("[11,12,13]");
					}, done);
				});

				it('should get object as JSON', function (done) {

					var expected = {
						test: 23,
						sub: {
							hello: "world"
						}
					};
					this.instance.__data = JSON.stringify(expected);

					promiseCheck(this.instance.getObjectAsJSON("test#$bucket", "test#$key"), function (jsonObj) {
						expect(jsonObj).to.be.deep.equal(expected);
					}, done);
				});
			});

			describe('setObject', function () {

				it('should first process all pending promises', function (done) {

					var processed = false;

					this.instance.setPromise(this.instance.getPromise().then(function () {
						processed = true;
					}));

					promiseCheck(this.instance.setObject("test#$bucket", "test#$key", this.object), function () {
						expect(processed).to.be.true;
					}.bind(this), done);
				});

				it('should request from the correct url', function (done) {
					this.pathSpy = this.sandbox.spy(this.instance, '_getUrlWithPath');

					promiseCheck(this.instance.setObject("test#$bucket", "test#$key", this.object), function () {
						expect(this.pathSpy.lastCall.args.length).to.be.equal(1);
						expect(this.pathSpy.lastCall.args[0]).to.be.equal('/buckets/test%23%24bucket/keys/test%23%24key');
					}.bind(this), done);
				});

				it('should set object', function (done) {

					promiseCheck(this.instance.setObject("test#$bucket", "test#$key", this.object), function () {
						expect(JSON.stringify(this.instance.__data)).to.be.equal("[11,12,13]");
						expect(this.instance.__headers['Content-Type']).to.be.equal("application/octet-stream");
					}.bind(this), done);
				});

				it('should set object with custom mime-type', function (done) {

					promiseCheck(this.instance.setObject("test#$bucket", "test#$key", this.object, "test/mime"), function () {
						expect(this.instance.__headers['Content-Type']).to.be.equal("test/mime");
					}.bind(this), done);
				});

				it('should set object with JSON', function (done) {

					var expected = {
						test: 23,
						sub: {
							hello: "world"
						}
					};

					promiseCheck(this.instance.setObjectFromJSON("test#$bucket", "test#$key", expected), function () {
						expect(JSON.parse(this.instance.__data)).to.be.deep.equal(expected);
						expect(this.instance.__headers['Content-Type']).to.be.equal("application/json");
					}.bind(this), done);
				});
			});

			describe('removeObject', function () {

				it('should first process all pending promises', function (done) {

					var processed = false;

					this.instance.setPromise(this.instance.getPromise().then(function () {
						processed = true;
					}));

					promiseCheck(this.instance.removeObject("test#$bucket", "test#$key", this.object), function () {
						expect(processed).to.be.true;
					}.bind(this), done);
				});

				it('should request from the correct url', function (done) {
					this.pathSpy = this.sandbox.spy(this.instance, '_getUrlWithPath');

					promiseCheck(this.instance.removeObject("test#$bucket", "test#$key", this.object), function () {
						expect(this.pathSpy.lastCall.args.length).to.be.equal(1);
						expect(this.pathSpy.lastCall.args[0]).to.be.equal('/buckets/test%23%24bucket/keys/test%23%24key');
					}.bind(this), done);
				});

				it('should remove object', function (done) {
					promiseCheck(this.instance.removeObject("test#$bucket", "test#$key", this.object), function () {}, done);
				});

				it('should remove all objects', function (done) {

					var removeObjectStub = this.sandbox.stub(this.instance, "removeObject", function () {
						return Promise.resolve();
					});

					this.instance.__data = JSON.stringify({ keys:[ "test1", "test2" ] });

					promiseCheck(this.instance.removeAllObjects("test#$bucket"), function () {

						expect(removeObjectStub.callCount).to.be.equal(2);

						expect(removeObjectStub.getCall(0).args.length).to.be.equal(2);
						expect(removeObjectStub.getCall(0).args[0]).to.be.equal("test#$bucket");
						expect(removeObjectStub.getCall(0).args[1]).to.be.equal("test1");

						expect(removeObjectStub.getCall(1).args.length).to.be.equal(2);
						expect(removeObjectStub.getCall(1).args[0]).to.be.equal("test#$bucket");
						expect(removeObjectStub.getCall(1).args[1]).to.be.equal("test2");

					}.bind(this), done);
				});
			});
		});
	});
});
<|endoftext|>


<commit_before>/*
 * tail-stopall-test.js: Tests for forever.tail() and forever.stopAll()
 *
 * (C) 2010 Nodejitsu Inc.
 * MIT LICENCE
 *
 */

var assert = require('assert'),
    path = require('path'),
    spawn = require('child_process').spawn,
    vows = require('vows'),
    forever = require('../../lib/forever');

vows.describe('forever/core/tail').addBatch({
  "When using forever": {
    "the tail() method": {
      topic: function () {
        var that = this;

        that.child = spawn('node', [path.join(__dirname, '..', 'fixtures', 'start-daemon.js')]);
        setTimeout(function () {
          forever.tail(0, that.callback);
        }, 2000);
      },
      "should respond with logs for the script": function (err, procs) {
        assert.isNull(err);
        assert.isArray(procs);
        procs.forEach(function (proc) {
          assert.isArray(proc.logs);
          assert.isTrue(!!proc.logs.length);
          assert.isTrue(proc.logs.length > 10);
          proc.logs.forEach(function (line) {
            assert.match(line, /^Logging at/);
          });
        });
      }
    }
  }
}).addBatch({
  "When the tests are over": {
    "stop all forever processes": {
      topic: function () {
        forever.stopAll().on('stopAll', this.callback.bind(null, null));
      },
      "should stop the correct number of procs": function (err, procs) {
        assert.isArray(procs);
        assert.lengthOf(procs, 1);
      }
    }
  }
}).export(module);
<commit_msg>[test] Temporary: prevent test failure from deprecation warning in core.<commit_after>/*
 * tail-stopall-test.js: Tests for forever.tail() and forever.stopAll()
 *
 * (C) 2010 Nodejitsu Inc.
 * MIT LICENCE
 *
 */

var assert = require('assert'),
    path = require('path'),
    spawn = require('child_process').spawn,
    vows = require('vows'),
    forever = require('../../lib/forever');

vows.describe('forever/core/tail').addBatch({
  "When using forever": {
    "the tail() method": {
      topic: function () {
        var that = this;

        that.child = spawn('node', [path.join(__dirname, '..', 'fixtures', 'start-daemon.js')]);
        setTimeout(function () {
          forever.tail(0, that.callback);
        }, 2000);
      },
      "should respond with logs for the script": function (err, procs) {
        assert.isNull(err);
        assert.isArray(procs);
        procs.forEach(function (proc) {
          assert.isArray(proc.logs);
          assert.isTrue(!!proc.logs.length);
          assert.isTrue(proc.logs.length > 10);
          // Temporary hack, remove after warnings are gone.
          proc.logs = proc.logs.slice(1);
          proc.logs.forEach(function (line) {
            assert.match(line, /^Logging at/);
          });
        });
      }
    }
  }
}).addBatch({
  "When the tests are over": {
    "stop all forever processes": {
      topic: function () {
        forever.stopAll().on('stopAll', this.callback.bind(null, null));
      },
      "should stop the correct number of procs": function (err, procs) {
        assert.isArray(procs);
        assert.lengthOf(procs, 1);
      }
    }
  }
}).export(module);
<|endoftext|>


<commit_before>
'use strict';

var Utils = require('../lib/Utils'),
	extend = require('util')._extend;

/**
 *
 * @class SwaggerUtils
 * @namespace SwaggerImport
 * @constructor
 *
 * Swagger importer
 */
function SwaggerUtils() {
	this.init();
}

SwaggerUtils.prototype = extend(SwaggerUtils.prototype, Utils.prototype);
SwaggerUtils.prototype =  extend(SwaggerUtils.prototype, {

	constructor : SwaggerUtils,

	/**
	 *
	 * @method init
	 * called by constructor
	 * @returns void
	 * @public
	 */
	init: function () {

	},

	restructureSchema: function (swaggerSchema) {
		return this._map(swaggerSchema);
	},

	_map: function (object) {
		if (typeof object.properties === 'object') {
			return this._mapObject(object.properties);
		}
	},

	_mapObject: function (object) {
		var out = {};

		this.forIn(object, function (key, value) {

			if (value.type && value.type === 'object') {
				console.log(value);
				out[key] = this._mapObject(value);
				return;
			}

			if (value.type && value.type === 'array' && value.items) {
				out[key] = [this._map(value.items)];
				return;
			}

			if (value.type && typeof value.type === 'string') {
				out[key] = value.type;
				return;
			}

			if (value['$ref'] && typeof value['$ref'] === 'string') {
				out[key] = '$ref-' + value['$ref'].replace('#/definitions/', '');
				return;
			}
		});

		return out;
	}

});

module.exports = SwaggerUtils;<commit_msg>[change] #1: add mapping of $ref instead of return null<commit_after>
'use strict';

var Utils = require('../lib/Utils'),
	extend = require('util')._extend;

/**
 *
 * @class SwaggerUtils
 * @namespace SwaggerImport
 * @constructor
 *
 * Swagger importer
 */
function SwaggerUtils() {
	this.init();
}

SwaggerUtils.prototype = extend(SwaggerUtils.prototype, Utils.prototype);
SwaggerUtils.prototype =  extend(SwaggerUtils.prototype, {

	constructor : SwaggerUtils,

	/**
	 *
	 * @method init
	 * called by constructor
	 * @returns void
	 * @public
	 */
	init: function () {

	},

	/**
	 * @method restructureSchema
	 * @param {object} swaggerSchema
	 * @returns {object}
	 * @public
	 */
	restructureSchema: function (swaggerSchema) {
		return this._map(swaggerSchema);
	},

	/**
	 * @method _map
	 * @param {object} object
	 * @returns {object}
	 * @privat
	 */
	_map: function (object) {
		if (typeof object.properties === 'object') {
			return this._mapObject(object.properties);
		}
		if (typeof object['$ref'] === 'string') {
			return this._mapRef(object['$ref']);
		}
		return {};
	},

	/**
	 * @method _mapObject
	 * @param {object} object
	 * @returns {object}
	 * @privat
	 */
	_mapObject: function (object) {
		var out = {};

		this.forIn(object, function (key, value) {

			if (value.type && value.type === 'object') {
				console.log(value);
				out[key] = this._mapObject(value);
				return;
			}

			if (value.type && value.type === 'array' && value.items) {
				out[key] = [this._map(value.items)];
				return;
			}

			if (value['$ref'] && typeof value['$ref'] === 'string') {
				out[key] = this._mapRef(value['$ref']);
				return;
			}

			if (value.type && typeof value.type === 'string') {
				out[key] = value.type;
			}
		});

		return out;
	},

	/**
	 * @method _mapRef
	 * @param {string} value
	 * @returns {string}
	 * @privat
	 */
	_mapRef: function (value) {
		return '$ref-' + value.replace('#/definitions/', '');
	}

});

module.exports = SwaggerUtils;<|endoftext|>


<commit_before>'use strict';

const fetch = require('node-fetch');

const WorldstateObject = require('./WorldstateObject.js');

const bountyRewardRegex = /Tier(A|B|C|D|E)Table(A|B|C)Rewards/i;
const ghoulRewardRegex = /GhoulBountyTable(A|B)Rewards/i;

const determineLocation = (i18n) => {
  const last = String(i18n).split('/').slice(-1)[0];
  const bountyMatches = last.match(bountyRewardRegex);

  const isCetus = /eidolonjob/i.test(i18n);
  const isVallis = /venusjob/i.test(i18n);

  const ghoulMatches = last.match(ghoulRewardRegex);
  const tier = bountyMatches && bountyMatches.length
    ? bountyMatches[1]
    : ghoulMatches && ghoulMatches.length && ghoulMatches[1];
  const rotation = bountyMatches && bountyMatches.length ? bountyMatches[2] : '';
  let levelString = '';

  if (bountyMatches && bountyMatches.length) {
    switch (tier) {
      case 'A':
        levelString = '5 - 15';
        break;
      case 'B':
        levelString = '10 - 30';
        break;
      case 'C':
        levelString = '20 - 40';
        break;
      case 'D':
        levelString = '30 - 50';
        break;
      case 'E':
        levelString = '40 - 60';
        break;
      default:
        break;
    }
  } else {
    switch (tier) {
      case 'A':
        levelString = '15 - 25';
        break;
      case 'B':
        levelString = '40 - 50';
        break;
      default:
        break;
    }
  }
  let location;
  let levelClause;
  if (isCetus) {
    location = 'Earth/Cetus ';
    if (ghoulMatches && ghoulMatches.length) {
      levelClause = `(Level ${levelString} Ghoul Bounty)`;
    } else {
      levelClause = `(Level ${levelString} Cetus Bounty)`;
    }
  }
  if (isVallis) {
    location = 'Venus/Orb Vallis ';
    levelClause = `(Level ${levelString} Orb Vallis Bounty)`;
  }
  const locationWRot = `${location}${levelClause}, Rot ${rotation.length ? rotation : 'A'}`;

  return { location, locationWRot };
};

const getCetusBountyRewards = async (i18n) => {
  try {
    const { location, locationWRot } = determineLocation(i18n);
    const url = `https://api.warframestat.us/drops/search/${encodeURIComponent(location)}?grouped_by=location`;
    const reply = await fetch(url).then(res => res.json());
    const pool = reply[0][locationWRot];
    if (!pool) {
      return ['Pattern Mismatch. Results inaccurate.'];
    }
    const results = pool.rewards;
    if (results) {
      return Array.from(new Set(results.map(result => result.item)));
    }
  } catch (e) {
    // eslint-disable-next-line no-console
    console.error(e);
  }

  return [];
};

/**
 * Represents a syndicate daily mission
 * @extends {WorldstateObject}
 */
class SyndicateJob extends WorldstateObject {
  /**
   * @param   {Object}             data            The syndicate mission data
   * @param   {Date}               expiry          The syndicate job expiration
   * @param   {Object}             deps            The dependencies object
   * @param   {Translator}         deps.translator The string translator
   */
  constructor(data, expiry, { translator, timeDate }) {
    super({ _id: { $oid: `${data.jobType.split('/').slice(-1)[0]}${expiry.getTime()}` } }, { timeDate });

    /**
     * Array of strings describing rewards
     * @type {string}
     */
    this.rewardPool = '';
    getCetusBountyRewards(data.rewards)
      .then((rewards) => {
        this.rewardPool = rewards;
      });

    /**
     * The type of job this is
     * @type {String}
     */
    this.type = translator.languageString(data.jobType);

    /**
     * Array of enemy levels
     * @type {Array.<number>}
     */
    this.enemyLevels = [data.minEnemyLevel, data.maxEnemyLevel];

    /**
     * Array of standing gains per stage of job
     * @type {Array.<number>}
     */
    this.standingStages = data.xpAmounts;
  }
}

module.exports = SyndicateJob;
<commit_msg>allow url override<commit_after>'use strict';

const fetch = require('node-fetch');

const WorldstateObject = require('./WorldstateObject.js');

const apiBase = process.env.API_BASE_URL || 'https://api.warframestat.us';
const bountyRewardRegex = /Tier(A|B|C|D|E)Table(A|B|C)Rewards/i;
const ghoulRewardRegex = /GhoulBountyTable(A|B)Rewards/i;

const determineLocation = (i18n) => {
  const last = String(i18n).split('/').slice(-1)[0];
  const bountyMatches = last.match(bountyRewardRegex);

  const isCetus = /eidolonjob/i.test(i18n);
  const isVallis = /venusjob/i.test(i18n);

  const ghoulMatches = last.match(ghoulRewardRegex);
  const tier = bountyMatches && bountyMatches.length
    ? bountyMatches[1]
    : ghoulMatches && ghoulMatches.length && ghoulMatches[1];
  const rotation = bountyMatches && bountyMatches.length ? bountyMatches[2] : '';
  let levelString = '';

  if (bountyMatches && bountyMatches.length) {
    switch (tier) {
      case 'A':
        levelString = '5 - 15';
        break;
      case 'B':
        levelString = '10 - 30';
        break;
      case 'C':
        levelString = '20 - 40';
        break;
      case 'D':
        levelString = '30 - 50';
        break;
      case 'E':
        levelString = '40 - 60';
        break;
      default:
        break;
    }
  } else {
    switch (tier) {
      case 'A':
        levelString = '15 - 25';
        break;
      case 'B':
        levelString = '40 - 50';
        break;
      default:
        break;
    }
  }
  let location;
  let levelClause;
  if (isCetus) {
    location = 'Earth/Cetus ';
    if (ghoulMatches && ghoulMatches.length) {
      levelClause = `(Level ${levelString} Ghoul Bounty)`;
    } else {
      levelClause = `(Level ${levelString} Cetus Bounty)`;
    }
  }
  if (isVallis) {
    location = 'Venus/Orb Vallis ';
    levelClause = `(Level ${levelString} Orb Vallis Bounty)`;
  }
  const locationWRot = `${location}${levelClause}, Rot ${rotation.length ? rotation : 'A'}`;

  return { location, locationWRot };
};

const getCetusBountyRewards = async (i18n) => {
  try {
    const { location, locationWRot } = determineLocation(i18n);
    const url = `${apiBase}/drops/search/${encodeURIComponent(location)}?grouped_by=location`;
    const reply = await fetch(url).then(res => res.json());
    const pool = reply[0][locationWRot];
    if (!pool) {
      return ['Pattern Mismatch. Results inaccurate.'];
    }
    const results = pool.rewards;
    if (results) {
      return Array.from(new Set(results.map(result => result.item)));
    }
  } catch (e) {
    // eslint-disable-next-line no-console
    console.error(e);
  }

  return [];
};

/**
 * Represents a syndicate daily mission
 * @extends {WorldstateObject}
 */
class SyndicateJob extends WorldstateObject {
  /**
   * @param   {Object}             data            The syndicate mission data
   * @param   {Date}               expiry          The syndicate job expiration
   * @param   {Object}             deps            The dependencies object
   * @param   {Translator}         deps.translator The string translator
   */
  constructor(data, expiry, { translator, timeDate }) {
    super({ _id: { $oid: `${data.jobType.split('/').slice(-1)[0]}${expiry.getTime()}` } }, { timeDate });

    /**
     * Array of strings describing rewards
     * @type {string}
     */
    this.rewardPool = '';
    getCetusBountyRewards(data.rewards)
      .then((rewards) => {
        this.rewardPool = rewards;
      });

    /**
     * The type of job this is
     * @type {String}
     */
    this.type = translator.languageString(data.jobType);

    /**
     * Array of enemy levels
     * @type {Array.<number>}
     */
    this.enemyLevels = [data.minEnemyLevel, data.maxEnemyLevel];

    /**
     * Array of standing gains per stage of job
     * @type {Array.<number>}
     */
    this.standingStages = data.xpAmounts;
  }
}

module.exports = SyndicateJob;
<|endoftext|>


<commit_before>/**
 * Copyright 2015 Netsend.
 *
 * This file is part of Mastersync.
 *
 * Mastersync is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Affero General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * Mastersync is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License along
 * with Mastersync. If not, see <https://www.gnu.org/licenses/>.
 */

/* jshint -W018, -W030, -W116 */

'use strict';

var util = require('util');
var Readable = require('stream').Readable;

var async = require('async');
var bson = require('bson');
var BSON = new bson.BSONPure.BSON();

var Tree;

/**
 * Get a readable stream of the tree in the order of insertion into the tree.
 *
 * @param {Object} tree  tree object
 * @param {Object} [opts]  object containing configurable parameters
 *
 * opts:
 *   id {String|Object}  limit stream to one specific DAG (maintain insertion
 *                       order)
 *   first {base64 String}  first version, offset
 *   last {base64 String}  last version
 *   excludeFirst {Boolean, default false}  whether or not first should be
 *                                          excluded
 *   excludeLast {Boolean, default false}  whether or not last should be
 *                                         excluded
 *   reverse {Boolean, default false}  if true, starts with last version
 *   raw {Boolean, default false}  whether to return a BSON serialized or
 *                                 deserialezed object (false).
 */
function StreamTree(tree, opts) {
  if (typeof tree !== 'object' || Array.isArray(opts)) { throw new TypeError('tree must be an object'); }

  Tree = tree.constructor;

  if (opts == null) { opts = {}; }
  if (typeof opts !== 'object' || Array.isArray(opts)) { throw new TypeError('opts must be an object'); }

  this._id = opts.id;
  if (this._id != null && !Buffer.isBuffer(this._id)) {
    this._id = new Buffer(Tree._ensureString(this._id));
  }

  if (opts.first != null) {
    if (typeof opts.first !== 'number' && typeof opts.first !== 'string') { throw new TypeError('opts.first must be a base64 string or a number'); }
    if (typeof opts.first === 'string' && Buffer.byteLength(opts.first, 'base64') !== tree._vSize) { throw new Error('opts.first must be the same size as the configured vSize'); }
  }
  if (opts.last != null) {
    if (typeof opts.last !== 'number' && typeof opts.last !== 'string') { throw new TypeError('opts.last must be a base64 string or a number'); }
    if (typeof opts.last === 'string' && Buffer.byteLength(opts.last, 'base64') !== tree._vSize) { throw new Error('opts.last must be the same size as the configured vSize'); }
  }
  if (opts.reverse != null && typeof opts.reverse !== 'boolean') { throw new TypeError('opts.reverse must be a boolean'); }
  if (opts.raw != null && typeof opts.raw !== 'boolean') { throw new TypeError('opts.raw must be a boolean'); }
  if (opts.excludeOffset != null && typeof opts.excludeOffset !== 'boolean') { throw new TypeError('opts.excludeOffset must be a boolean'); }

  this.tree = tree;

  this._opts = opts;
  this._opts.objectMode = true;

  Readable.call(this, this._opts);
}

util.inherits(StreamTree, Readable);

// create a range for id, first, last, exlucdeFirst and excludeLast
function determineRange(tree, opts, cb) {
  var first, last;

  var tasks = [function(cb) { process.nextTick(cb); }];

  if (opts.first) {
    // resolve v to i
    tasks.push(function(cb) {
      tree._resolveVtoI(opts.first, function(err, i) {
        if (err) { cb(err); return; }

        first = i;
        cb();
      });
    });
  }

  if (opts.last) {
    // resolve v to i
    tasks.push(function(cb) {
      tree._resolveVtoI(opts.last, function(err, i) {
        if (err) { cb(err); return; }

        last = i;
        cb();
      });
    });
  }

  async.series(tasks, function(err) {
    var r;
    if (opts.id) {
      // start reading the dskey index
      r = tree.getDsKeyRange({ id: opts.id, minI: first, maxI: last});
    } else {
      // start reading the ikey index
      r = tree.getIKeyRange({ minI: first, maxI: last });
    }
    cb(err, r);
  });
}

function openStream(tree, r, opts, cb) {
  var streamOpts = {};

  if (opts.excludeFirst) {
    streamOpts.gt = r.s;
  } else {
    streamOpts.gte = r.s;
  }

  if (opts.excludeLast) {
    streamOpts.lt = r.e;
  } else {
    streamOpts.lte = r.e;
  }

  if (opts.reverse) {
    streamOpts.reverse = true;
  }

  tree._log.info('StreamTree streamOpts %j', streamOpts);

  var it = tree._db.createReadStream(streamOpts);

  cb(null, it);
}

StreamTree.prototype._read = function() {
  if (this._it) {
    this._it.resume();
    return;
  }

  // setup stream
  var that = this;
  var processing = 0;
  var ended = false;

  determineRange(this.tree, this._opts, function(err, r) {
    if (err) { that.emit('error', err); return; }

    that.tree._log.info('StreamTree ikey range %j', r);

    openStream(that.tree, r, that._opts, function(err, it) {
      that._it = it;

      function processItem(item) {
        that.tree._log.debug('StreamTree item push %j', item);

        var cont = that.push(that._opts.raw ? item : BSON.deserialize(item));
        if (!cont) {
          it.pause();
        }
        processing--;
        if (ended && !processing) {
          that.push(null);
        }
      }

      it.on('data', function(obj) {
        processing++;

        if (that._id) {
          // dskey is used
          processItem(obj.value);
        } else {
          // ensure the same order
          it.pause();

          // ikey is used
          var key = Tree.parseKey(obj.key);
          var val = Tree.parseKey(obj.value, { decodeId: 'utf8' });
          var dsKey = that.tree._composeDsKey(val.id, key.i);

          that.tree._db.get(dsKey, function(err, item) {
            if (err) {
              that.tree._log.err('StreamTree %s', err);
              that.emit('error', err);
              return;
            }

            it.resume();
            processItem(item);
          });
        }
      });

      it.on('error', function(err) {
        that.emit('error', err);
      });

      it.on('end', function() {
        ended = true;
        if (!processing) {
          that.tree._log.debug('StreamTree end push null, processing:', processing);
          that.push(null);
        }
      });
    });
  });
};

module.exports = StreamTree;
<commit_msg>StreamTree: change debug info<commit_after>/**
 * Copyright 2015 Netsend.
 *
 * This file is part of Mastersync.
 *
 * Mastersync is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Affero General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * Mastersync is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License along
 * with Mastersync. If not, see <https://www.gnu.org/licenses/>.
 */

/* jshint -W018, -W030, -W116 */

'use strict';

var util = require('util');
var Readable = require('stream').Readable;

var async = require('async');
var bson = require('bson');
var BSON = new bson.BSONPure.BSON();

var Tree;

/**
 * Get a readable stream of the tree in the order of insertion into the tree.
 *
 * @param {Object} tree  tree object
 * @param {Object} [opts]  object containing configurable parameters
 *
 * opts:
 *   id {String|Object}  limit stream to one specific DAG (maintain insertion
 *                       order)
 *   first {base64 String}  first version, offset
 *   last {base64 String}  last version
 *   excludeFirst {Boolean, default false}  whether or not first should be
 *                                          excluded
 *   excludeLast {Boolean, default false}  whether or not last should be
 *                                         excluded
 *   reverse {Boolean, default false}  if true, starts with last version
 *   raw {Boolean, default false}  whether to return a BSON serialized or
 *                                 deserialezed object (false).
 */
function StreamTree(tree, opts) {
  if (typeof tree !== 'object' || Array.isArray(opts)) { throw new TypeError('tree must be an object'); }

  Tree = tree.constructor;

  if (opts == null) { opts = {}; }
  if (typeof opts !== 'object' || Array.isArray(opts)) { throw new TypeError('opts must be an object'); }

  this._id = opts.id;
  if (this._id != null && !Buffer.isBuffer(this._id)) {
    this._id = new Buffer(Tree._ensureString(this._id));
  }

  if (opts.first != null) {
    if (typeof opts.first !== 'number' && typeof opts.first !== 'string') { throw new TypeError('opts.first must be a base64 string or a number'); }
    if (typeof opts.first === 'string' && Buffer.byteLength(opts.first, 'base64') !== tree._vSize) { throw new Error('opts.first must be the same size as the configured vSize'); }
  }
  if (opts.last != null) {
    if (typeof opts.last !== 'number' && typeof opts.last !== 'string') { throw new TypeError('opts.last must be a base64 string or a number'); }
    if (typeof opts.last === 'string' && Buffer.byteLength(opts.last, 'base64') !== tree._vSize) { throw new Error('opts.last must be the same size as the configured vSize'); }
  }
  if (opts.reverse != null && typeof opts.reverse !== 'boolean') { throw new TypeError('opts.reverse must be a boolean'); }
  if (opts.raw != null && typeof opts.raw !== 'boolean') { throw new TypeError('opts.raw must be a boolean'); }
  if (opts.excludeOffset != null && typeof opts.excludeOffset !== 'boolean') { throw new TypeError('opts.excludeOffset must be a boolean'); }

  this.tree = tree;

  this._opts = opts;
  this._opts.objectMode = true;

  Readable.call(this, this._opts);
}

util.inherits(StreamTree, Readable);

// create a range for id, first, last, exlucdeFirst and excludeLast
function determineRange(tree, opts, cb) {
  var first, last;

  var tasks = [function(cb) { process.nextTick(cb); }];

  if (opts.first) {
    // resolve v to i
    tasks.push(function(cb) {
      tree._resolveVtoI(opts.first, function(err, i) {
        if (err) { cb(err); return; }

        first = i;
        cb();
      });
    });
  }

  if (opts.last) {
    // resolve v to i
    tasks.push(function(cb) {
      tree._resolveVtoI(opts.last, function(err, i) {
        if (err) { cb(err); return; }

        last = i;
        cb();
      });
    });
  }

  async.series(tasks, function(err) {
    var r;
    if (opts.id) {
      // start reading the dskey index
      r = tree.getDsKeyRange({ id: opts.id, minI: first, maxI: last});
    } else {
      // start reading the ikey index
      r = tree.getIKeyRange({ minI: first, maxI: last });
    }
    tree._log.info('StreamTree range start: %j, end: %j', r.s.toString('hex'), r.e.toString('hex'));
    cb(err, r);
  });
}

function openStream(tree, r, opts, cb) {
  var streamOpts = {};

  if (opts.excludeFirst) {
    streamOpts.gt = r.s;
  } else {
    streamOpts.gte = r.s;
  }

  if (opts.excludeLast) {
    streamOpts.lt = r.e;
  } else {
    streamOpts.lte = r.e;
  }

  if (opts.reverse) {
    streamOpts.reverse = true;
  }

  tree._log.info('StreamTree streamOpts %j', streamOpts);

  var it = tree._db.createReadStream(streamOpts);

  cb(null, it);
}

StreamTree.prototype._read = function() {
  if (this._it) {
    this._it.resume();
    return;
  }

  // setup stream
  var that = this;
  var processing = 0;
  var ended = false;

  determineRange(this.tree, this._opts, function(err, r) {
    if (err) { that.emit('error', err); return; }

    openStream(that.tree, r, that._opts, function(err, it) {
      that._it = it;

      function processItem(item) {
        that.tree._log.debug('StreamTree item push %j', item);

        var cont = that.push(that._opts.raw ? item : BSON.deserialize(item));
        if (!cont) {
          it.pause();
        }
        processing--;
        if (ended && !processing) {
          that.push(null);
        }
      }

      it.on('data', function(obj) {
        processing++;

        that.tree._log.err('StreamTree item key %j', obj.key);

        if (that._id) {
          // dskey is used
          processItem(obj.value);
        } else {
          // ensure the same order
          it.pause();

          // ikey is used
          var key = Tree.parseKey(obj.key);
          var val = Tree.parseKey(obj.value, { decodeId: 'utf8' });
          var dsKey = that.tree._composeDsKey(val.id, key.i);

          that.tree._db.get(dsKey, function(err, item) {
            if (err) {
              that.tree._log.err('StreamTree %s', err);
              that.emit('error', err);
              return;
            }

            it.resume();
            processItem(item);
          });
        }
      });

      it.on('error', function(err) {
        that.emit('error', err);
      });

      it.on('end', function() {
        ended = true;
        if (!processing) {
          that.tree._log.debug('StreamTree end push null, processing:', processing);
          that.push(null);
        }
      });
    });
  });
};

module.exports = StreamTree;
<|endoftext|>


<commit_before>/* eslint-env jasmine */
var nock = require('nock')
var VoucherifyClient = require('./client-loader')
var fixtures = require('./fixtures')
var reqWithBody = fixtures.reqWithBody
var reqWithoutBody = fixtures.reqWithoutBody

nock.disableNetConnect()

describe('Distributions API', function () {
  var client = new VoucherifyClient({
    applicationId: 'node-sdk-test-id',
    clientSecretKey: 'node-sdk-test-secret'
  })

  describe('publish voucher', function () {
    it('should publish by voucher', function (done) {
      var server = nock('https://api.voucherify.io', reqWithBody)
        .post('/v1/vouchers/publish', {
          campaign: 'test-campaign',
          voucher: 'test-voucher',
          customer: 'test@custom.er'
        })
        .reply(200, {})

      client.distributions.publish({
        campaign: 'test-campaign',
        voucher: 'test-voucher',
        customer: 'test@custom.er'
      })
      .then(function () {
        server.done()
        done()
      })
    })
  })

  describe('create publication', function () {
    it('should create publication', function (done) {
      var server = nock('https://api.voucherify.io', reqWithBody)
        .post('/v1/publications', {
          campaign: {
            name: 'test-campaign',
            count: '5'
          },
          customer: {
              source_id: 'test-source-id',
              email: 'test@custom.er',
              name: 'Test customer name'
          }
        })
        .reply(200, {})

      client.distributions.publications.create({
        campaign: {
          name: 'test-campaign',
          count: '5'
        },
        customer: {
            source_id: 'test-source-id',
            email: 'test@custom.er',
            name: 'Test customer name'
        }
      })
      .then(function () {
        server.done()
        done()
      })
    })
  })

  describe('list publications', function () {
    it('should list all publications', function (done) {
      var server = nock('https://api.voucherify.io', reqWithoutBody)
      .get('/v1/publications')
      .reply(200, [])

      client.distributions.publications.list()
      .then(function () {
        server.done()
        done()
      })
    })

    it('should list all publications (callback)', function (done) {
      var server = nock('https://api.voucherify.io', reqWithoutBody)
      .get('/v1/publications')
      .reply(200, [])

      client.distributions.publications.list(function (err) {
        expect(err).toBeNull()
        server.done()
        done()
      })
    })

    it('should list publications by query', function (done) {
      var server = nock('https://api.voucherify.io', reqWithoutBody)
      .get('/v1/publications')
      .query({campaign: 'test-campaign'})
      .reply(200, [])

      client.distributions.publications.list({campaign: 'test-campaign'})
      .then(function () {
        server.done()
        done()
      })
    })
  })

  describe('exports', function () {
    it('should create export', function (done) {
      var server = nock('https://api.voucherify.io', reqWithBody)
      .post('/v1/exports', {
        exported_object: 'voucher',
        parameters: {}
      })
      .reply(200, {})

      client.distributions.exports.create({
        exported_object: 'voucher',
        parameters: {}
      })
      .then(function () {
        server.done()
        done()
      })
    })

    it('should get export', function (done) {
      var server = nock('https://api.voucherify.io', reqWithoutBody)
      .get('/v1/exports/exp_test-id')
      .reply(200, {})

      client.distributions.exports.get('exp_test-id')
      .then(function () {
        server.done()
        done()
      })
    })

    it('should delete export', function (done) {
      var server = nock('https://api.voucherify.io', reqWithoutBody)
      .delete('/v1/exports/exp_test-id')
      .reply(200, {})

      client.distributions.exports.delete('exp_test-id')
      .then(function () {
        server.done()
        done()
      })
    })
  })
})
<commit_msg>Code style fix<commit_after>/* eslint-env jasmine */
var nock = require('nock')
var VoucherifyClient = require('./client-loader')
var fixtures = require('./fixtures')
var reqWithBody = fixtures.reqWithBody
var reqWithoutBody = fixtures.reqWithoutBody

nock.disableNetConnect()

describe('Distributions API', function () {
  var client = new VoucherifyClient({
    applicationId: 'node-sdk-test-id',
    clientSecretKey: 'node-sdk-test-secret'
  })

  describe('publish voucher', function () {
    it('should publish by voucher', function (done) {
      var server = nock('https://api.voucherify.io', reqWithBody)
        .post('/v1/vouchers/publish', {
          campaign: 'test-campaign',
          voucher: 'test-voucher',
          customer: 'test@custom.er'
        })
        .reply(200, {})

      client.distributions.publish({
        campaign: 'test-campaign',
        voucher: 'test-voucher',
        customer: 'test@custom.er'
      })
      .then(function () {
        server.done()
        done()
      })
    })
  })

  describe('create publication', function () {
    it('should create publication', function (done) {
      var server = nock('https://api.voucherify.io', reqWithBody)
        .post('/v1/publications', {
          campaign: {
            name: 'test-campaign',
            count: '5'
          },
          customer: {
            source_id: 'test-source-id',
            email: 'test@custom.er',
            name: 'Test customer name'
          }
        })
        .reply(200, {})

      client.distributions.publications.create({
        campaign: {
          name: 'test-campaign',
          count: '5'
        },
        customer: {
          source_id: 'test-source-id',
          email: 'test@custom.er',
          name: 'Test customer name'
        }
      })
      .then(function () {
        server.done()
        done()
      })
    })
  })

  describe('list publications', function () {
    it('should list all publications', function (done) {
      var server = nock('https://api.voucherify.io', reqWithoutBody)
      .get('/v1/publications')
      .reply(200, [])

      client.distributions.publications.list()
      .then(function () {
        server.done()
        done()
      })
    })

    it('should list all publications (callback)', function (done) {
      var server = nock('https://api.voucherify.io', reqWithoutBody)
      .get('/v1/publications')
      .reply(200, [])

      client.distributions.publications.list(function (err) {
        expect(err).toBeNull()
        server.done()
        done()
      })
    })

    it('should list publications by query', function (done) {
      var server = nock('https://api.voucherify.io', reqWithoutBody)
      .get('/v1/publications')
      .query({campaign: 'test-campaign'})
      .reply(200, [])

      client.distributions.publications.list({campaign: 'test-campaign'})
      .then(function () {
        server.done()
        done()
      })
    })
  })

  describe('exports', function () {
    it('should create export', function (done) {
      var server = nock('https://api.voucherify.io', reqWithBody)
      .post('/v1/exports', {
        exported_object: 'voucher',
        parameters: {}
      })
      .reply(200, {})

      client.distributions.exports.create({
        exported_object: 'voucher',
        parameters: {}
      })
      .then(function () {
        server.done()
        done()
      })
    })

    it('should get export', function (done) {
      var server = nock('https://api.voucherify.io', reqWithoutBody)
      .get('/v1/exports/exp_test-id')
      .reply(200, {})

      client.distributions.exports.get('exp_test-id')
      .then(function () {
        server.done()
        done()
      })
    })

    it('should delete export', function (done) {
      var server = nock('https://api.voucherify.io', reqWithoutBody)
      .delete('/v1/exports/exp_test-id')
      .reply(200, {})

      client.distributions.exports.delete('exp_test-id')
      .then(function () {
        server.done()
        done()
      })
    })
  })
})
<|endoftext|>


<commit_before>/* global Cache */
const Command = require('../Command')
const DiscordServer = require('../../DiscordServer')
const VirtualGroups = require('../../VirtualGroups')
const request = require('request-promise')

const Contributors = require('../../Contributors.json')

module.exports =
class WhoisCommand extends Command {
  constructor (client) {
    super(client, {
      name: 'whois',
      properName: 'Whois',
      aliases: ['roblox'],
      userPermissions: [],
      description: "`<user>` Get a user's Roblox profile link.",

      args: [
        {
          key: 'member',
          label: 'member',
          prompt: 'What is their username?',
          type: 'member',
          default: false
        }
      ]
    })
  }

  // This is probably the worst file in the entire project, so prepare yourself.
  // TODO: DRY this up and make the method that gets user data a method in DiscordMember
  async fn (msg, args) {
    let member = args.member
    // If no member is specified the member is the message author
    if (!member) member = msg.member
    let data = {}
    if (member) { // If the member specified exists,
      const editMessage = await msg.reply(`:mag: Looking up ${member.displayName.replace(/@/g, '')}`)

      if (member.user.bot) {
        return editMessage.edit(':robot: RoVer cannot look up bots.')
      }
      const id = member.user.id
      try {
        // Read user data from memory, or request it if there isn't any cached.
        data = await Cache.get('users', id)

        if (!data) {
          data = await request({
            uri: `https://verify.eryn.io/api/user/${id}`,
            json: true,
            simple: false
          })
        }
      } catch (e) {
        return editMessage.edit("An error occured while fetching that user's data.")
      }

      if (data.status === 'ok') {
        let apiUserData = {}
        try {
          apiUserData = await request({
            uri: `http://api.roblox.com/users/${data.robloxId}`,
            json: true,
            simple: false
          })
        } catch (e) {
          return editMessage.edit("An error occured while fetching that user's data.")
        }

        if (apiUserData.Username) {
          data.robloxUsername = apiUserData.Username
        }
        const profileLink = `https://www.roblox.com/users/${data.robloxId}/profile`
        const avatarURL = `https://assetgame.roblox.com/Thumbs/Avatar.ashx?username=${encodeURIComponent(data.robloxUsername)}`

        let bio = 'Bio failed to load'
        let joinDate = 'Unknown'
        let pastNames = 'Unknown'
        try {
          const profileSource = await request({
            uri: profileLink
          })

          joinDate = profileSource.match(/Join Date
(.*?)<li/)[1]
          bio = profileSource.match(/<meta name=description content=".*? is one of the millions playing, creating and exploring the endless possibilities of Roblox. Join .*? on Roblox and explore together! ?((?:.|\n)*?)"/m)[1]
          pastNames = profileSource.match(//)[1].substr(0, 1024)
        } catch (e) {}

        let bc = 'Unknown'
        try {
          bc = await Cache.get(`bindings.${data.robloxId}`, 'bc')
          if (!bc) {
            const response = await request({
              uri: `https://groups.roblox.com/v1/users/${encodeURIComponent(data.robloxId)}/group-membership-status`,
              simple: false,
              resolveWithFullResponse: true
            })

            const membershipType = JSON.parse(response.body).membershipType
            bc = 'Regular'

            if (membershipType === 4) {
              bc = 'Premium'
            }

            Cache.set(`bindings.${data.robloxId}`, 'bc', bc)
          }
        } catch (e) {}

        // Make sure the data is cached so we don't have to use the API in the future
        Cache.set('users', id, data)

        // Remove excess new lines in the bio
        while ((bio.match(/\n/mg) || []).length > 3) {
          const lastN = bio.lastIndexOf('\n')
          bio = bio.slice(0, lastN) + bio.slice(lastN + 1)
        }

        // Truncate bio if it's too long
        if (bio.length > 500) {
          bio = bio.substr(0, 500) + '...'
        }

        // Add a space after any @ symbols to prevent tagging @everyone, @here, and @anything else Discord adds
        bio = bio.replace(/(@)/g, '@ ')

        // Double quotes appear as " so fix that
        bio = bio.replace(/(")/g,'"')
        const embed = {
          title: 'View Profile',
          url: profileLink,
          author: {
            name: data.robloxUsername,
            url: profileLink,
            icon_url: avatarURL
          },
          color: member.displayColor,
          thumbnail: {
            url: avatarURL
          },
          description: bio,
          fields: [
            { name: 'Join Date', value: joinDate, inline: true },
            { name: 'Membership', value: bc, inline: true },
            { name: 'Past Usernames', value: pastNames, inline: true }
          ]
        }

        // Nickname Group rank display
        const nicknameGroup = this.server.getSetting('nicknameGroup')
        if (nicknameGroup) {
          const userGroups = await DiscordServer.getRobloxMemberGroups(data.robloxId)

          const serverGroup = userGroups.find(group => group.Id === parseInt(nicknameGroup))

          let isAlly = false
          if (!serverGroup) {
            isAlly = await VirtualGroups._Relationship({ id: data.robloxId }, parseInt(nicknameGroup), DiscordServer, 'allies')
          }

          embed.fields.push({
            name: 'Group Rank',
            value: isAlly ? 'Ally' : (serverGroup ? serverGroup.Role : 'Guest')
          })
        }

        if (Contributors.includes(id)) embed.fields.push({ name: 'User Tags', value: 'RoVer Contributor', inline: true })

        editMessage.edit({ embed: embed }).catch(console.error)
      } else {
        editMessage.edit(`${member.displayName} doesn't seem to be verified.`)
      }
    }
  }
}
<commit_msg>Update WhoisCommand.js<commit_after>/* global Cache */
const Command = require('../Command')
const DiscordServer = require('../../DiscordServer')
const VirtualGroups = require('../../VirtualGroups')
const request = require('request-promise')

const Contributors = require('../../Contributors.json')

module.exports =
class WhoisCommand extends Command {
  constructor (client) {
    super(client, {
      name: 'whois',
      properName: 'Whois',
      aliases: ['roblox'],
      userPermissions: [],
      description: "`<user>` Get a user's Roblox profile link.",

      args: [
        {
          key: 'member',
          label: 'member',
          prompt: 'What is their username?',
          type: 'member',
          default: false
        }
      ]
    })
  }

  // This is probably the worst file in the entire project, so prepare yourself.
  // TODO: DRY this up and make the method that gets user data a method in DiscordMember
  async fn (msg, args) {
    let member = args.member
    // If no member is specified the member is the message author
    if (!member) member = msg.member
    let data = {}
    if (member) { // If the member specified exists,
      const editMessage = await msg.reply(`:mag: Looking up ${member.displayName.replace(/@/g, '')}`)

      if (member.user.bot) {
        return editMessage.edit(':robot: RoVer cannot look up bots.')
      }
      const id = member.user.id
      try {
        // Read user data from memory, or request it if there isn't any cached.
        data = await Cache.get('users', id)

        if (!data) {
          data = await request({
            uri: `https://verify.eryn.io/api/user/${id}`,
            json: true,
            simple: false
          })
        }
      } catch (e) {
        return editMessage.edit("An error occured while fetching that user's data.")
      }

      if (data.status === 'ok') {
        let apiUserData = {}
        try {
          apiUserData = await request({
            uri: `http://api.roblox.com/users/${data.robloxId}`,
            json: true,
            simple: false
          })
        } catch (e) {
          return editMessage.edit("An error occured while fetching that user's data.")
        }

        if (apiUserData.Username) {
          data.robloxUsername = apiUserData.Username
        }
        const profileLink = `https://www.roblox.com/users/${data.robloxId}/profile`
        const avatarURL = `https://assetgame.roblox.com/Thumbs/Avatar.ashx?username=${encodeURIComponent(data.robloxUsername)}`

        let bio = 'Bio failed to load'
        let joinDate = 'Unknown'
        let pastNames = 'Unknown'
        try {
          const profileSource = await request({
            uri: profileLink
          })

          joinDate = profileSource.match(/Join Date
(.*?)<li/)[1]
          bio = profileSource.match(/<meta name=description content=".*? is one of the millions playing, creating and exploring the endless possibilities of Roblox. Join .*? on Roblox and explore together! ?((?:.|\n)*?)"/m)[1]
          pastNames = profileSource.match(//)[1].substr(0, 1024)
        } catch (e) {}

        let bc = 'Unknown'
        try {
          bc = await Cache.get(`bindings.${data.robloxId}`, 'bc')
          if (!bc) {
            const response = await request({
              uri: `https://groups.roblox.com/v1/users/${encodeURIComponent(data.robloxId)}/group-membership-status`,
              simple: false,
              resolveWithFullResponse: true
            })

            const membershipType = JSON.parse(response.body).membershipType
            bc = 'Regular'

            if (membershipType === 4) {
              bc = 'Premium'
            }

            Cache.set(`bindings.${data.robloxId}`, 'bc', bc)
          }
        } catch (e) {}

        // Make sure the data is cached so we don't have to use the API in the future
        Cache.set('users', id, data)

        // Remove excess new lines in the bio
        while ((bio.match(/\n/mg) || []).length > 3) {
          const lastN = bio.lastIndexOf('\n')
          bio = bio.slice(0, lastN) + bio.slice(lastN + 1)
        }

        // Truncate bio if it's too long
        if (bio.length > 500) {
          bio = bio.substr(0, 500) + '...'
        }

        // Add a space after any @ symbols to prevent tagging @everyone, @here, and @anything else Discord adds
        bio = bio.replace(/(@)/gm, '@ ')

        // Double quotes appear as " so fix that
        bio = bio.replace(/(")/g,'"')
        const embed = {
          title: 'View Profile',
          url: profileLink,
          author: {
            name: data.robloxUsername,
            url: profileLink,
            icon_url: avatarURL
          },
          color: member.displayColor,
          thumbnail: {
            url: avatarURL
          },
          description: bio,
          fields: [
            { name: 'Join Date', value: joinDate, inline: true },
            { name: 'Membership', value: bc, inline: true },
            { name: 'Past Usernames', value: pastNames, inline: true }
          ]
        }

        // Nickname Group rank display
        const nicknameGroup = this.server.getSetting('nicknameGroup')
        if (nicknameGroup) {
          const userGroups = await DiscordServer.getRobloxMemberGroups(data.robloxId)

          const serverGroup = userGroups.find(group => group.Id === parseInt(nicknameGroup))

          let isAlly = false
          if (!serverGroup) {
            isAlly = await VirtualGroups._Relationship({ id: data.robloxId }, parseInt(nicknameGroup), DiscordServer, 'allies')
          }

          embed.fields.push({
            name: 'Group Rank',
            value: isAlly ? 'Ally' : (serverGroup ? serverGroup.Role : 'Guest')
          })
        }

        if (Contributors.includes(id)) embed.fields.push({ name: 'User Tags', value: 'RoVer Contributor', inline: true })

        editMessage.edit({ embed: embed }).catch(console.error)
      } else {
        editMessage.edit(`${member.displayName} doesn't seem to be verified.`)
      }
    }
  }
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015 Alex Grant (@localnerve), LocalNerve LLC
 * Copyrights licensed under the BSD License. See the accompanying LICENSE file for terms.
 */
 /* global it */
'use strict';

var test = require('./sauce-travis');

var timeoutLink = 150;

it('should get home page and navigate to others', function(done) {
  test.state.browser
    .get(test.baseUrl)
    .title()
    .should.include('Example')
    .elementByTagName('h2')
    .text()
    .should.include('Welcome')
    .elementByLinkText('About')
    .click()
    .waitForElementByCss('#about h2', timeoutLink)
    .text()
    .should.eventually.include('About')
    .title()
    .should.eventually.include('About')
    .elementByLinkText('Contact')
    .click()
    .waitForElementByCss('#contact h2', timeoutLink)
    .text()
    .should.eventually.include('Contact')
    .title()
    .should.eventually.include('Contact')
    .nodeify(done);
});

it('should get about page and navigate to others', function(done) {
  test.state.browser
    .get(test.baseUrl+'/about')
    .title()
    .should.include('About')
    .elementByTagName('h2')
    .text()
    .should.include('About')
    .elementByLinkText('Home')
    .click()
    .waitForElementByCss('#home h2', timeoutLink)
    .text()
    .should.eventually.include('Welcome')
    .title()
    .should.eventually.include('Example')
    .elementByLinkText('Contact')
    .click()
    .waitForElementByCss('#contact h2', timeoutLink)
    .text()
    .should.eventually.include('Contact')
    .title()
    .should.eventually.include('Contact')
    .nodeify(done);
});

it('should get contact page and navigate to others', function(done) {
  test.state.browser
    .get(test.baseUrl+'/contact')
    .title()
    .should.include('Contact')
    .elementByTagName('h2')
    .text()
    .should.include('Contact')
    .elementByLinkText('Home')
    .click()
    .waitForElementByCss('#home h2', timeoutLink)
    .text()
    .should.eventually.include('Welcome')
    .title()
    .should.eventually.include('Example')
    .elementByLinkText('About')
    .click()
    .waitForElementByCss('#about h2', timeoutLink)
    .text()
    .should.eventually.include('About')
    .title()
    .should.eventually.include('About')
    .nodeify(done);
});
<commit_msg>fixes #33, re-adjust basic-specs<commit_after>/**
 * Copyright (c) 2015 Alex Grant (@localnerve), LocalNerve LLC
 * Copyrights licensed under the BSD License. See the accompanying LICENSE file for terms.
 */
 /* global it */
'use strict';

var test = require('./sauce-travis');

var timeoutLink = 150;

it('should get home page and navigate to others', function(done) {
  test.state.browser
    .get(test.baseUrl)
    .title()
    .should.eventually.include('Example')
    .elementByTagName('h2')
    .text()
    .should.eventually.include('Welcome')
    .elementByLinkText('About')
    .click()
    .waitForElementByCss('#about h2', timeoutLink)
    .text()
    .should.eventually.include('About')
    .title()
    .should.eventually.include('About')
    .elementByLinkText('Contact')
    .click()
    .waitForElementByCss('#contact h2', timeoutLink)
    .text()
    .should.eventually.include('Contact')
    .title()
    .should.eventually.include('Contact')
    .nodeify(done);
});

it('should get about page and navigate to others', function(done) {
  test.state.browser
    .get(test.baseUrl+'/about')
    .title()
    .should.eventually.include('About')
    .elementByTagName('h2')
    .text()
    .should.eventually.include('About')
    .elementByLinkText('Home')
    .click()
    .waitForElementByCss('#home h2', timeoutLink)
    .text()
    .should.eventually.include('Welcome')
    .title()
    .should.eventually.include('Example')
    .elementByLinkText('Contact')
    .click()
    .waitForElementByCss('#contact h2', timeoutLink)
    .text()
    .should.eventually.include('Contact')
    .title()
    .should.eventually.include('Contact')
    .nodeify(done);
});

it('should get contact page and navigate to others', function(done) {
  test.state.browser
    .get(test.baseUrl+'/contact')
    .title()
    .should.eventually.include('Contact')
    .elementByTagName('h2')
    .text()
    .should.eventually.include('Contact')
    .elementByLinkText('Home')
    .click()
    .waitForElementByCss('#home h2', timeoutLink)
    .text()
    .should.eventually.include('Welcome')
    .title()
    .should.eventually.include('Example')
    .elementByLinkText('About')
    .click()
    .waitForElementByCss('#about h2', timeoutLink)
    .text()
    .should.eventually.include('About')
    .title()
    .should.eventually.include('About')
    .nodeify(done);
});
<|endoftext|>