<commit_before>/*global describe, it, before, __dirname */
var testUtils = require('./helper/test-utils'),
    assert = testUtils.assert;

var _      = require('underscore'),
    fs     = require('fs'),
    sf     = require('../lib/jsforce'),
    config = require('./config/salesforce');

/**
 *
 */
describe("metadata", function() {

  this.timeout(40000); // set timeout to 40 sec.

  var conn = testUtils.createConnection(config);

  /**
   *
   */
  before(function(done) {
    testUtils.establishConnection(conn, config, done);
  });

  /**
   *
   */
  describe("asynchronous metadata call sequence", function() {

    /**
     *
     */
    describe("create metadata asynchronously", function() {
      var asyncResults;

      it("should create custom objects", function(done) {
        var metadata = [{
          fullName: 'TestObject1__c',
          label: 'Test Object 1',
          pluralLabel: 'Test Object 1',
          nameField: {
            type: 'Text',
            label: 'Test Object Name'
          },
          deploymentStatus: 'Deployed',
          sharingModel: 'ReadWrite'
        }, {
          fullName: 'TestObject2__c',
          label: 'Test Object 2',
          pluralLabel: 'Test Object 2',
          nameField: {
            type: 'AutoNumber',
            label: 'Test Object #'
          },
          deploymentStatus: 'InDevelopment',
          sharingModel: 'Private'
        }];
        conn.metadata.createAsync('CustomObject', metadata, function(err, results) {
          if (err) { throw err; }
          assert.ok(_.isArray(results));
          assert.ok(results.length === metadata.length);
          _.forEach(results, function(result) {
            assert.ok(_.isString(result.id));
          });
          asyncResults = results;
        }.check(done));
      });

      it("should get finished status in completion", function(done) {
        var ids = _.map(asyncResults, function(ar){ return ar.id; });
        conn.metadata.checkStatus(ids).complete(function(err, results) {
          if (err) { throw err; }
          assert.ok(_.isArray(results));
          assert.ok(results.length === ids.length);
          _.forEach(results, function(result) {
            assert.ok(result.done === true);
            assert.ok(result.state === 'Completed');
          });
        }.check(done));
      });

      it("should create custom fields", function(done) {
        var metadata = [{
          type: 'Text',
          fullName: 'TestObject1__c.TextField__c',
          label: 'Text #1',
          length: 50
        }, {
          type: 'TextArea',
          fullName: 'TestObject1__c.TextAreaField__c',
          label: 'Text Area #1'
        }, {
          type: 'Number',
          fullName: 'TestObject1__c.NumberField__c',
          label: 'Number #1',
          precision: 18,
          scale: 2
        }, {
          type: 'AutoNumber',
          fullName: 'TestObject1__c.AutoNumberField__c',
          label: 'Auto Number #1'
        }];
        conn.metadata.createAsync('CustomField', metadata).complete(function(err, results) {
          if (err) { throw err; }
          assert.ok(_.isArray(results));
          assert.ok(results.length === metadata.length);
          _.forEach(results, function(result) {
            assert.ok(_.isString(result.id));
            assert.ok(result.done === true);
            assert.ok(result.state === "Completed");
          });
        }.check(done));
      });

    });

    /**
     *
     */
    describe("update metadata asynchronously", function() {
      it("should update custom fields", function(done) {
        var updateMetadata = [{
          currentName: 'TestObject1__c.AutoNumberField__c',
          metadata: {
            type: 'Text',
            fullName: 'TestObject2__c.AutoNumberField2__c',
            label: 'Auto Number #2',
            length: 50
          }
        }];
        conn.metadata.updateAsync('CustomField', updateMetadata).complete(function(err, results) {
          if (err) { throw err; }
          assert.ok(_.isArray(results));
          assert.ok(results.length === updateMetadata.length);
          _.forEach(results, function(result) {
            assert.ok(_.isString(result.id));
            assert.ok(result.done === true);
            assert.ok(result.state === "Completed");
          });
        }.check(done));
      });
    });

    /**
     *
     */
    describe("delete metadata asynchronously", function() {
      it("should delete custom objects", function(done) {
        var metadata = [{
          fullName: 'TestObject1__c',
        }, {
          fullName: 'TestObject2__c',
        }];
        conn.metadata.deleteAsync('CustomObject', metadata).complete(function(err, results) {
          if (err) { throw err; }
          assert.ok(_.isArray(results));
          assert.ok(results.length === metadata.length);
          _.forEach(results, function(result) {
            assert.ok(_.isString(result.id));
          });
        }.check(done));
      });
    });

  }); // end of asynchronous call tests

  /**
   * Synchronous call tests (createSync, read, updateSync, rename, deleteSync)
   */
  describe("synchronous metadata call sequence", function() {

    var metadata = [{
      fullName: 'TestObjectSync1__c',
      label: 'Test Object Sync 1',
      pluralLabel: 'Test Object Sync 1',
      nameField: {
        type: 'Text',
        label: 'Test Object Name'
      },
      deploymentStatus: 'Deployed',
      sharingModel: 'ReadWrite'
    }, {
      fullName: 'TestObjectSync2__c',
      label: 'Test Object Sync 2',
      pluralLabel: 'Test Object 2',
      nameField: {
        type: 'AutoNumber',
        label: 'Test Object #'
      },
      deploymentStatus: 'InDevelopment',
      sharingModel: 'Private'
    }];
    var fullNames = _.map(metadata, function(meta) { return meta.fullName; });
    var rmetadata = null;

    /**
     *
     */
    describe("create metadata synchronously", function() {
      it("should create custom objects", function(done) {
        conn.metadata.create('CustomObject', metadata, function(err, results) {
          if (err) { throw err; }
          assert.ok(_.isArray(results));
          assert.ok(results.length === metadata.length);
          _.forEach(results, function(result) {
            assert.ok(result.success === true);
            assert.ok(_.isString(result.fullName));
          });
        }.check(done));
      });
    });

    /**
     *
     */
    describe("read metadata synchronously", function() {
      it("should read created custom objects metadata", function(done) {
        conn.metadata.read('CustomObject', fullNames, function(err, results) {
          if (err) { throw err; }
          assert.ok(_.isArray(results));
          assert.ok(results.length === fullNames.length);
          _.forEach(results, function(result) {
            assert.ok(_.isString(result.fullName));
            assert.ok(result.nameField);
            assert.ok(_.isString(result.nameField.label));
          });
          rmetadata = results;
        }.check(done));
      });
    });

    /**
     *
     */
    describe("update metadata synchronously", function() {
      it("should update custom objects", function(done) {
        rmetadata[0].label = 'Updated Test Object Sync 2';
        rmetadata[1].deploymentStatus = 'Deployed';
        conn.metadata.update('CustomObject', rmetadata, function(err, results) {
          if (err) { throw err; }
          assert.ok(_.isArray(results));
          assert.ok(results.length === fullNames.length);
          _.forEach(results, function(result) {
            assert.ok(result.success === true);
            assert.ok(_.isString(result.fullName));
          });
          rmetadata = results;
        }.check(done));
      });
    });

    /**
     *
     */
    describe("rename metadata synchronously", function() {
      it("should rename a custom object", function(done) {
        var oldName = fullNames[0], newName = 'Updated' + oldName;
        conn.metadata.rename('CustomObject', oldName, newName).then(function(result) {
          assert.ok(result.success === true);
          assert.ok(_.isString(result.fullName));
          assert.ok(result.fullName === oldName);
          return conn.metadata.read('CustomObject', newName);
        }).then(function(result) {
          assert.ok(_.isString(result.fullName));
          assert.ok(result.fullName === newName);
          fullNames[0] = result.fullName;
        }).then(done, done);
      });
    });

    /**
     *
     */
    describe("delete metadata synchronously", function() {
      it("should delete custom objects", function(done) {
        conn.metadata.delete('CustomObject', fullNames, function(err, results) {
          if (err) { throw err; }
          assert.ok(_.isArray(results));
          assert.ok(results.length === fullNames.length);
          _.forEach(results, function(result) {
            assert.ok(result.success === true);
            assert.ok(_.isString(result.fullName));
          });
        }.check(done));
      });
    });

  }); // end of synchronous call tests

if (testUtils.isNodeJS) {

  /**
   *
   */
  describe("deploy metadata in packaged file", function() {
    it("should deploy package", function(done) {
      var zipStream = fs.createReadStream(__dirname + "/data/MyPackage.zip");
      conn.metadata.deploy(zipStream, { runTests: [ 'MyApexTriggerTest' ] }).complete(function(err, result) {
        if (err) { throw err; }
        assert.ok(result.done === true);
        assert.ok(result.success === true);
        assert.ok(result.status === 'Succeeded');
        assert.ok(result.numberComponentErrors === 0);
        assert.ok(result.numberComponentsDeployed === result.numberComponentsTotal);
        assert.ok(result.numberTestsCompleted === 1);
      }.check(done));
    });
  });

}

  /**
   *
   */
  describe("retrieve metadata in packaged file", function() {
    it("should retrieve package", function(done) {
      var bufs = [];
      conn.metadata.retrieve({ packageNames: [ 'My Test Package' ] })
                   .stream()
                   .on('data', function(d) {
                     bufs.push(d);
                   })
                   .on('end', function() {
                     assert.ok(bufs.length > 0);
                     done();
                   })
                   .on('error', function(err) {
                     done(err);
                   });
    });
  });

});
<commit_msg>add metadata upsert test case<commit_after>/*global describe, it, before, __dirname */
var testUtils = require('./helper/test-utils'),
    assert = testUtils.assert;

var _      = require('underscore'),
    fs     = require('fs'),
    sf     = require('../lib/jsforce'),
    config = require('./config/salesforce');

/**
 *
 */
describe("metadata", function() {

  this.timeout(40000); // set timeout to 40 sec.

  var conn = testUtils.createConnection(config);

  /**
   *
   */
  before(function(done) {
    testUtils.establishConnection(conn, config, done);
  });

  /**
   *
   */
  describe("asynchronous metadata call sequence", function() {

    /**
     *
     */
    describe("create metadata asynchronously", function() {
      var asyncResults;

      it("should create custom objects", function(done) {
        var metadata = [{
          fullName: 'TestObject1__c',
          label: 'Test Object 1',
          pluralLabel: 'Test Object 1',
          nameField: {
            type: 'Text',
            label: 'Test Object Name'
          },
          deploymentStatus: 'Deployed',
          sharingModel: 'ReadWrite'
        }, {
          fullName: 'TestObject2__c',
          label: 'Test Object 2',
          pluralLabel: 'Test Object 2',
          nameField: {
            type: 'AutoNumber',
            label: 'Test Object #'
          },
          deploymentStatus: 'InDevelopment',
          sharingModel: 'Private'
        }];
        conn.metadata.createAsync('CustomObject', metadata, function(err, results) {
          if (err) { throw err; }
          assert.ok(_.isArray(results));
          assert.ok(results.length === metadata.length);
          _.forEach(results, function(result) {
            assert.ok(_.isString(result.id));
          });
          asyncResults = results;
        }.check(done));
      });

      it("should get finished status in completion", function(done) {
        var ids = _.map(asyncResults, function(ar){ return ar.id; });
        conn.metadata.checkStatus(ids).complete(function(err, results) {
          if (err) { throw err; }
          assert.ok(_.isArray(results));
          assert.ok(results.length === ids.length);
          _.forEach(results, function(result) {
            assert.ok(result.done === true);
            assert.ok(result.state === 'Completed');
          });
        }.check(done));
      });

      it("should create custom fields", function(done) {
        var metadata = [{
          type: 'Text',
          fullName: 'TestObject1__c.TextField__c',
          label: 'Text #1',
          length: 50
        }, {
          type: 'TextArea',
          fullName: 'TestObject1__c.TextAreaField__c',
          label: 'Text Area #1'
        }, {
          type: 'Number',
          fullName: 'TestObject1__c.NumberField__c',
          label: 'Number #1',
          precision: 18,
          scale: 2
        }, {
          type: 'AutoNumber',
          fullName: 'TestObject1__c.AutoNumberField__c',
          label: 'Auto Number #1'
        }];
        conn.metadata.createAsync('CustomField', metadata).complete(function(err, results) {
          if (err) { throw err; }
          assert.ok(_.isArray(results));
          assert.ok(results.length === metadata.length);
          _.forEach(results, function(result) {
            assert.ok(_.isString(result.id));
            assert.ok(result.done === true);
            assert.ok(result.state === "Completed");
          });
        }.check(done));
      });

    });

    /**
     *
     */
    describe("update metadata asynchronously", function() {
      it("should update custom fields", function(done) {
        var updateMetadata = [{
          currentName: 'TestObject1__c.AutoNumberField__c',
          metadata: {
            type: 'Text',
            fullName: 'TestObject2__c.AutoNumberField2__c',
            label: 'Auto Number #2',
            length: 50
          }
        }];
        conn.metadata.updateAsync('CustomField', updateMetadata).complete(function(err, results) {
          if (err) { throw err; }
          assert.ok(_.isArray(results));
          assert.ok(results.length === updateMetadata.length);
          _.forEach(results, function(result) {
            assert.ok(_.isString(result.id));
            assert.ok(result.done === true);
            assert.ok(result.state === "Completed");
          });
        }.check(done));
      });
    });

    /**
     *
     */
    describe("delete metadata asynchronously", function() {
      it("should delete custom objects", function(done) {
        var metadata = [{
          fullName: 'TestObject1__c',
        }, {
          fullName: 'TestObject2__c',
        }];
        conn.metadata.deleteAsync('CustomObject', metadata).complete(function(err, results) {
          if (err) { throw err; }
          assert.ok(_.isArray(results));
          assert.ok(results.length === metadata.length);
          _.forEach(results, function(result) {
            assert.ok(_.isString(result.id));
          });
        }.check(done));
      });
    });

  }); // end of asynchronous call tests

  /**
   * Synchronous call tests (createSync, read, updateSync, rename, deleteSync)
   */
  describe("synchronous metadata call sequence", function() {

    var metadata = [{
      fullName: 'TestObjectSync1__c',
      label: 'Test Object Sync 1',
      pluralLabel: 'Test Object Sync 1',
      nameField: {
        type: 'Text',
        label: 'Test Object Name'
      },
      deploymentStatus: 'Deployed',
      sharingModel: 'ReadWrite'
    }, {
      fullName: 'TestObjectSync2__c',
      label: 'Test Object Sync 2',
      pluralLabel: 'Test Object 2',
      nameField: {
        type: 'AutoNumber',
        label: 'Test Object #'
      },
      deploymentStatus: 'InDevelopment',
      sharingModel: 'Private'
    }];
    var fullNames = _.map(metadata, function(meta) { return meta.fullName; });
    var rmetadata = null;

    /**
     *
     */
    describe("create metadata synchronously", function() {
      it("should create custom objects", function(done) {
        conn.metadata.create('CustomObject', metadata, function(err, results) {
          if (err) { throw err; }
          assert.ok(_.isArray(results));
          assert.ok(results.length === metadata.length);
          _.forEach(results, function(result) {
            assert.ok(result.success === true);
            assert.ok(_.isString(result.fullName));
          });
        }.check(done));
      });
    });

    /**
     *
     */
    describe("read metadata synchronously", function() {
      it("should read created custom objects metadata", function(done) {
        conn.metadata.read('CustomObject', fullNames, function(err, results) {
          if (err) { throw err; }
          assert.ok(_.isArray(results));
          assert.ok(results.length === fullNames.length);
          _.forEach(results, function(result) {
            assert.ok(_.isString(result.fullName));
            assert.ok(result.nameField);
            assert.ok(_.isString(result.nameField.label));
          });
          rmetadata = results;
        }.check(done));
      });
    });

    /**
     *
     */
    describe("update metadata synchronously", function() {
      it("should update custom objects", function(done) {
        rmetadata[0].label = 'Updated Test Object Sync 2';
        rmetadata[1].deploymentStatus = 'Deployed';
        conn.metadata.update('CustomObject', rmetadata, function(err, results) {
          if (err) { throw err; }
          assert.ok(_.isArray(results));
          assert.ok(results.length === fullNames.length);
          _.forEach(results, function(result) {
            assert.ok(result.success === true);
            assert.ok(_.isString(result.fullName));
          });
          rmetadata = results;
        }.check(done));
      });
    });

    /**
     *
     */
    describe("upsert metadata synchronously", function() {
      it("should upsert custom objects", function(done) {
        var umetadata = [{
          fullName: 'TestObjectSync2__c',
          label: 'Upserted Object Sync 2',
          pluralLabel: 'Upserted Object Sync 2',
          nameField: {
            type: 'Text',
            label: 'Test Object Name'
          },
          deploymentStatus: 'Deployed',
          sharingModel: 'ReadWrite'
        }, {
          fullName: 'TestObjectSync3__c',
          label: 'Upserted Object Sync 3',
          pluralLabel: 'Upserted Object Sync 3',
          nameField: {
            type: 'Text',
            label: 'Test Object Name'
          },
          deploymentStatus: 'Deployed',
          sharingModel: 'ReadWrite'
        }];
        conn.metadata.upsert('CustomObject', umetadata, function(err, results) {
          if (err) { throw err; }
          assert.ok(_.isArray(results));
          assert.ok(results.length === umetadata.length);
          _.forEach(results, function(result, i) {
            assert.ok(result.success === true);
            assert.ok(result.fullName === umetadata[i].fullName);
          });
        }.check(done));
      });
    });

    /**
     *
     */
    describe("rename metadata synchronously", function() {
      it("should rename a custom object", function(done) {
        var oldName = fullNames[0], newName = 'Updated' + oldName;
        conn.metadata.rename('CustomObject', oldName, newName).then(function(result) {
          assert.ok(result.success === true);
          assert.ok(_.isString(result.fullName));
          assert.ok(result.fullName === oldName);
          return conn.metadata.read('CustomObject', newName);
        }).then(function(result) {
          assert.ok(_.isString(result.fullName));
          assert.ok(result.fullName === newName);
          fullNames[0] = result.fullName;
        }).then(done, done);
      });
    });

    /**
     *
     */
    describe("delete metadata synchronously", function() {
      it("should delete custom objects", function(done) {
        fullNames.push('TestObjectSync3__c');
        conn.metadata.delete('CustomObject', fullNames, function(err, results) {
          if (err) { throw err; }
          assert.ok(_.isArray(results));
          assert.ok(results.length === fullNames.length);
          _.forEach(results, function(result) {
            assert.ok(result.success === true);
            assert.ok(_.isString(result.fullName));
          });
        }.check(done));
      });
    });

  }); // end of synchronous call tests

if (testUtils.isNodeJS) {

  /**
   *
   */
  describe("deploy metadata in packaged file", function() {
    it("should deploy package", function(done) {
      var zipStream = fs.createReadStream(__dirname + "/data/MyPackage.zip");
      conn.metadata.deploy(zipStream, { runTests: [ 'MyApexTriggerTest' ] }).complete(function(err, result) {
        if (err) { throw err; }
        assert.ok(result.done === true);
        assert.ok(result.success === true);
        assert.ok(result.status === 'Succeeded');
        assert.ok(result.numberComponentErrors === 0);
        assert.ok(result.numberComponentsDeployed === result.numberComponentsTotal);
        assert.ok(result.numberTestsCompleted === 1);
      }.check(done));
    });
  });

}

  /**
   *
   */
  describe("retrieve metadata in packaged file", function() {
    it("should retrieve package", function(done) {
      var bufs = [];
      conn.metadata.retrieve({ packageNames: [ 'My Test Package' ] })
                   .stream()
                   .on('data', function(d) {
                     bufs.push(d);
                   })
                   .on('end', function() {
                     assert.ok(bufs.length > 0);
                     done();
                   })
                   .on('error', function(err) {
                     done(err);
                   });
    });
  });

});
<|endoftext|>


<commit_before>describe("m.trust()", function () {
	"use strict"

	it("exists", function () {
		expect(m.trust).to.be.a("function")
	})

	it("returns an instance of String", function () {
		expect(m.trust("foo")).to.be.an.instanceof(String)
	})

	it("does not modify the string", function () {
		expect(m.trust("foo").valueOf()).to.equal("foo")
	})

	it("is not identical to the string", function () {
		expect(m.trust("foo")).to.not.equal("foo")
	})

	// FIXME: implement document.createRange().createContextualFragment() in the
	// mock window for these tests
	dom(function () {
		it("isn't escaped in m.render()", function () {
			var root = document.createElement("div")
			m.render(root, m("div", "a", m.trust("&"), "b"))
			expect(root.childNodes[0].innerHTML).to.equal("a&b")
		})

		it("works with mixed trusted content in div", function () {
			var root = document.createElement("div")
			m.render(root, [m.trust("
1

2
"), m("i", "foo")])
			expect(root.childNodes[2].tagName).to.equal("I")
		})

		it("works with mixed trusted content in text nodes", function () {
			var root = document.createElement("div")
			m.render(root, [
				m.trust("
1
123
2
"),
				m("i", "foo")
			])
			expect(root.childNodes[3].tagName).to.equal("I")
		})

		// TODO: m.trust's contents are having their tags stripped.
		xit("works with mixed trusted content in td", function () {
			var root = document.createElement("table")
			root.appendChild(root = document.createElement("tr"))

			m.render(root, [
				m.trust("1	2	"),
				m("td", "foo")
			])

			expect(root.childNodes[2].tagName).to.equal("TD")
		})

		it("works with trusted content in div", function () {
			var root = document.createElement("div")
			m.render(root, m("div", [
				m("p", "©"),
				m("p", m.trust("©")),
				m.trust("©")
			]))

			expect(root.innerHTML)
				.to.equal("

&copy;

©
©
")
		})
	})
})
<commit_msg>Add test for replaceScriptNodes<commit_after>describe("m.trust()", function () {
	"use strict"

	it("exists", function () {
		expect(m.trust).to.be.a("function")
	})

	it("returns an instance of String", function () {
		expect(m.trust("foo")).to.be.an.instanceof(String)
	})

	it("does not modify the string", function () {
		expect(m.trust("foo").valueOf()).to.equal("foo")
	})

	it("is not identical to the string", function () {
		expect(m.trust("foo")).to.not.equal("foo")
	})

	// FIXME: implement document.createRange().createContextualFragment() in the
	// mock window for these tests
	dom(function () {
		it("isn't escaped in m.render()", function () {
			var root = document.createElement("div")
			m.render(root, m("div", "a", m.trust("&"), "b"))
			expect(root.childNodes[0].innerHTML).to.equal("a&b")
		})

		it("works with mixed trusted content in div", function () {
			var root = document.createElement("div")
			m.render(root, [m.trust("
1

2
"), m("i", "foo")])
			expect(root.childNodes[2].tagName).to.equal("I")
		})

		it("works with mixed trusted content in text nodes", function () {
			var root = document.createElement("div")
			m.render(root, [
				m.trust("
1
123
2
"),
				m("i", "foo")
			])
			expect(root.childNodes[3].tagName).to.equal("I")
		})

		// TODO: m.trust's contents are having their tags stripped.
		xit("works with mixed trusted content in td", function () {
			var root = document.createElement("table")
			root.appendChild(root = document.createElement("tr"))

			m.render(root, [
				m.trust("1	2	"),
				m("td", "foo")
			])

			expect(root.childNodes[2].tagName).to.equal("TD")
		})

		it("works with trusted content in div", function () {
			var root = document.createElement("div")
			m.render(root, m("div", [
				m("p", "©"),
				m("p", m.trust("©")),
				m.trust("©")
			]))

			expect(root.innerHTML)
				.to.equal("

&copy;

©
©
")
		})

		// https://github.com/lhorie/mithril.js/issues/1045
		it("correctly injects script tags and executes them", function () {
			var HTMLString =
			""
			var root = document.createElement("div")
			var child = document.createElement("div")
			root.id = "root"
			root.innerText = "Before"
			root.appendChild(child)
			document.body.appendChild(root)

			m.render(child, m.trust(HTMLString))

			expect(root.innerText).to.equal("After")
		})
	})
})
<|endoftext|>


<commit_before>var expect = require('chai').expect;
var http = require('http');
var RestServer = require('../lib/rest-server').RestServer;
var NixieCron = require('../lib/nixietube-cron').NixieCron;

describe('Nixie Bar', function() {
    var server = new RestServer([], []);
    server.start();

    describe('rest server', function() {
        beforeEach(function() {
            http.request({ "hostname" : "localhost",
                "port" : 8080,
                "path" : "/users",
                "method" : "DELETE"});
        });

        it('should add a user upon request', function() {
            http.request({ "hostname" : "localhost",
                "port" : 8080,
                "path" : "/users/jimbob",
                "method" : "PUT"});
            http.request({ "hostname" : "localhost",
                "port" : 8080,
                "path" : "/users",
                "method" : "GET"});
            expect({username:"jimbob"});
        });

        it('should get all users upon request', function() {
            http.request({ "hostname" : "localhost",
                "port" : 8080,
                "path" : "/users/jimbob",
                "method" : "PUT"});
            http.request({ "hostname" : "localhost",
                "port" : 8080,
                "path" : "/users/pirate",
                "method" : "PUT"});
            http.request({ "hostname" : "localhost",
                "port" : 8080,
                "path" : "/users",
                "method" : "GET"});
            expect({username:"jimbob"}, {username:"pirate"});
        });

        it('should delete users upon request', function() {
            http.request({ "hostname" : "localhost",
                "port" : 8080,
                "path" : "/users/jimbob",
                "method" : "PUT"});
            expect(201);
            http.request({ "hostname" : "localhost",
                "port" : 8080,
                "path" : "/users",
                "method" : "DELETE"});
            expect(201);
            http.request({ "hostname" : "localhost",
                "port" : 8080,
                "path" : "/users",
                "method" : "GET"});
            expect({});
        });

        it('should start the cron job upon request', function() {
            http.request({hostname: "localhost",
                port : 8080,
                path : "/jobs/nixiebar/settings/start",
                method : "PUT"});
            expect(204);
        });

        it('should stop the cron job upon request', function() {
            http.request({hostname: "localhost",
                port : 8080,
                path : "/jobs/nixiebar/settings/stop",
                method : "PUT"});
            expect(204);
        });
    });

    describe('cron job', function() {
        var isClientCalled = false;
        var isDisplayShown = false;
        var untappdUser;
        var untappd_client = {
            getUniqueBeersFor : function(user, callback) {
                isClientCalled = true;
                untappdUser = user;
                callback();
            }
        }
        var nixie_display = {
            display : function() {
                isDisplayShown = true;
            }
        }
        var nixie_cron = new NixieCron([{username:"zombie_killer"}], untappd_client, nixie_display);

        beforeEach(function() {
            isClientCalled = false;
            isDisplayShown = false;
            untappdUser = null;
            nixie_cron.startJob();
        });

        afterEach(function() {
            nixie_cron.stopJob();
        });

        it('should send request for provided Untappd user', function(done) {
            setTimeout(function() {
                expect(untappdUser.username).to.equal("zombie_killer");
                done();
            }, 1005);
        });

        it('should get unique beers for user after a second', function(done) {
            setTimeout(function() {
                expect(isClientCalled).to.be.true;
                done();
            }, 1005);
        });

        it('should send unique beer count for user to nixie tubes for display', function(done) {
            setTimeout(function() {
                expect(isDisplayShown).to.be.true;
                done();
            }, 1005);
        });
    });
});<commit_msg>Reworded tests<commit_after>var expect = require('chai').expect;
var http = require('http');
var RestServer = require('../lib/rest-server').RestServer;
var NixieCron = require('../lib/nixietube-cron').NixieCron;

describe('Nixie Bar', function() {
    var server = new RestServer([], []);
    server.start();

    describe('rest server', function() {
        beforeEach(function() {
            http.request({ "hostname" : "localhost",
                "port" : 8080,
                "path" : "/users",
                "method" : "DELETE"});
        });

        it('should add a user upon request', function() {
            http.request({ "hostname" : "localhost",
                "port" : 8080,
                "path" : "/users/jimbob",
                "method" : "PUT"});
            http.request({ "hostname" : "localhost",
                "port" : 8080,
                "path" : "/users",
                "method" : "GET"});
            expect({username:"jimbob"});
        });

        it('should get all users upon request', function() {
            http.request({ "hostname" : "localhost",
                "port" : 8080,
                "path" : "/users/jimbob",
                "method" : "PUT"});
            http.request({ "hostname" : "localhost",
                "port" : 8080,
                "path" : "/users/pirate",
                "method" : "PUT"});
            http.request({ "hostname" : "localhost",
                "port" : 8080,
                "path" : "/users",
                "method" : "GET"});
            expect({username:"jimbob"}, {username:"pirate"});
        });

        it('should delete users upon request', function() {
            http.request({ "hostname" : "localhost",
                "port" : 8080,
                "path" : "/users/jimbob",
                "method" : "PUT"});
            expect(201);
            http.request({ "hostname" : "localhost",
                "port" : 8080,
                "path" : "/users",
                "method" : "DELETE"});
            expect(201);
            http.request({ "hostname" : "localhost",
                "port" : 8080,
                "path" : "/users",
                "method" : "GET"});
            expect({});
        });

        it('should start the cron job upon request', function() {
            http.request({hostname: "localhost",
                port : 8080,
                path : "/jobs/nixiebar/settings/start",
                method : "PUT"});
            expect(204);
        });

        it('should stop the cron job upon request', function() {
            http.request({hostname: "localhost",
                port : 8080,
                path : "/jobs/nixiebar/settings/stop",
                method : "PUT"});
            expect(204);
        });
    });

    describe('cron job', function() {
        var isClientCalled = false;
        var isDisplayShown = false;
        var untappdUser;
        var untappd_client = {
            getUniqueBeersFor : function(user, callback) {
                isClientCalled = true;
                untappdUser = user;
                callback();
            }
        }
        var nixie_display = {
            display : function() {
                isDisplayShown = true;
            }
        }
        var nixie_cron = new NixieCron([{username:"zombie_killer"}], untappd_client, nixie_display);

        beforeEach(function() {
            isClientCalled = false;
            isDisplayShown = false;
            untappdUser = null;
            nixie_cron.startJob();
        });

        afterEach(function() {
            nixie_cron.stopJob();
        });

        it('should send request for provided Untappd user after a second', function(done) {
            setTimeout(function() {
                expect(untappdUser.username).to.equal("zombie_killer");
                done();
            }, 1005);
        });

        it('should get unique beers for user after a second', function(done) {
            setTimeout(function() {
                expect(isClientCalled).to.be.true;
                done();
            }, 1005);
        });

        it('should send unique beer count for user to display after a second', function(done) {
            setTimeout(function() {
                expect(isDisplayShown).to.be.true;
                done();
            }, 1005);
        });
    });
});<|endoftext|>


<commit_before>// @flow
/* eslint-disable no-use-before-define */

import type {Grid} from '../../types'

export type OpportunityDataset = {
  dataSource: string,
  grid?: Grid,
  key: string,
  name: string
}

export type UploadStatus = {
  completedAt: string,
  completedFeatures: number,
  createdAt: string,
  id: string,
  message: string,
  name: string,
  status: 'DONE' | 'ERROR' | 'PROCESSING' | 'UPLOADING',
  totalFeatures: number,
  totalGrids: number,
  uploadedGrids: number
}

export type State = {
  activeDataset: void | string,
  datasets: OpportunityDataset[],
  uploadStatuses: UploadStatus[]
}

export type Action =
  {type: 'opportunityDatasets/ADD', payload: OpportunityDataset}
| {type: 'opportunityDatasets/REMOVE', payload: OpportunityDataset}
| {type: 'opportunityDatasets/SET_ALL', payload: OpportunityDataset[]}
| {type: 'opportunityDatasets/SET_ACTIVE', payload: void | string}
| {type: 'opportunityDatasets/UPDATE', payload: OpportunityDataset}
| {type: 'opportunityDatasets/UPDATE_UPLOAD_STATUSES', payload: UploadStatus[]}

export type Actions =
  Action
| Array<Action>
| FetchAction
| PromiseAction
| ThunkAction

export type Dispatch = (action: Actions) => any

export type FetchAction = {
  type: 'fetch'
}

export type GetState = () => any

export type PromiseAction = Promise<Action>

export type ThunkAction = (dispatch: Dispatch, getState: () => GetState) => any
<commit_msg>test(flow): Make state immutable<commit_after>// @flow
/* eslint-disable no-use-before-define */

import type {Grid} from '../../types'

export type OpportunityDataset = {
  dataSource: string,
  grid?: Grid,
  key: string,
  name: string
}

export type UploadStatus = {
  completedAt: string,
  completedFeatures: number,
  createdAt: string,
  id: string,
  message: string,
  name: string,
  status: 'DONE' | 'ERROR' | 'PROCESSING' | 'UPLOADING',
  totalFeatures: number,
  totalGrids: number,
  uploadedGrids: number
}

export type State = {
  +activeDataset: void | string,
  +datasets: OpportunityDataset[],
  +uploadStatuses: UploadStatus[]
}

export type Action =
  {type: 'opportunityDatasets/ADD', payload: OpportunityDataset}
| {type: 'opportunityDatasets/REMOVE', payload: OpportunityDataset}
| {type: 'opportunityDatasets/SET_ALL', payload: OpportunityDataset[]}
| {type: 'opportunityDatasets/SET_ACTIVE', payload: void | string}
| {type: 'opportunityDatasets/UPDATE', payload: OpportunityDataset}
| {type: 'opportunityDatasets/UPDATE_UPLOAD_STATUSES', payload: UploadStatus[]}

export type Actions =
  Action
| Array<Action>
| FetchAction
| PromiseAction
| ThunkAction

export type Dispatch = (action: Actions) => any

export type FetchAction = {
  type: 'fetch'
}

export type GetState = () => any

export type PromiseAction = Promise<Action>

export type ThunkAction = (dispatch: Dispatch, getState: () => GetState) => any
<|endoftext|>


<commit_before>import React from 'react';
import TestUtils from 'react/lib/ReactTestUtils';
import Transmitter from './index';
import assert from 'assert';
import sinon from 'sinon';

describe('Transmitter', () => {
	const Component = (props) =>
;
	const VALUE = 'value';
	const FIRST_ACTION_TIMEOUT = 1;
	const SECOND_ACTION_TIMEOUT = 10;

	it('should create React component', () => {
		const Container = Transmitter.create(Component, {});

		assert.ok(TestUtils.isElement(<Container />), 'Container should be a React component');
		assert.equal(Container.displayName, 'ComponentContainer', 'Container should have Component\'s name with suffix');
	});

	it('should create React component if enum is used', () => {
		const Container = Transmitter.create({success: Component}, {});

		assert.ok(TestUtils.isElement(<Container />), 'Container should be a React component');
		assert.equal(Container.displayName, 'ComponentContainer', 'Container should have Component\'s name with suffix');
	});

	it('should raise an error if no components are specified', () => {
		assert.throws(() => Transmitter.create({success: null}, {}), /Success, Failure and Pending should be React components/);
		assert.throws(() => Transmitter.create({}, {}), /Success component should be specified/);
	});

	it('should render Pending component by default', () => {
		const Spinner = () =>
Loading...
;
		const Container = Transmitter.create({success: Component, pending: Spinner}, {});
		const ReactShallow = TestUtils.createRenderer();

		ReactShallow.render(<Container />);

		assert.ok(TestUtils.isElementOfType(ReactShallow.getRenderOutput(), Spinner), 'Pending component should be rendered');
	});

	it('should render Success component with data fetched from fragments', (done) => {
		const Container = Transmitter.create(Component, {
			fragments: {
				thing() {
					return new Promise((resolve) => {
						setTimeout(resolve, FIRST_ACTION_TIMEOUT, VALUE);
					});
				}
			}
		});
		const ReactShallow = TestUtils.createRenderer();

		ReactShallow.render(<Container />);

		setTimeout(() => {
			const Output = ReactShallow.getRenderOutput();

			assert.ok(TestUtils.isElementOfType(Output, Component), 'Success component should be rendered');
			assert.deepEqual(Output.props, { thing: VALUE }, 'Component should be rendered with data fetched via fragments');
			done();
		}, SECOND_ACTION_TIMEOUT);
	});

	// waiting for https://github.com/facebook/react/pull/5247 being merged
	xit('should immediately render Success component if fragments are passed via props', () => {
		const thingFragment = sinon.stub().returns(new Promise((resolve) => {
			setTimeout(resolve, FIRST_ACTION_TIMEOUT, VALUE);
		}));
		const Container = Transmitter.create(Component, {
			fragments: {thing: thingFragment}
		});
		const ReactShallow = TestUtils.createRenderer();

		ReactShallow.render(<Container thing={VALUE} />);

		const Output = ReactShallow.getRenderOutput();

		assert.ok(!thingFragment.called, 'Fragment should not be called');
		assert.ok(TestUtils.isElementOfType(Output, Component), 'Success component should be rendered');
		assert.deepEqual(Output.props, { thing: VALUE }, 'Component should be rendered with data fetched via fragments');
	});

	xit('should call fragments with passed variables', () => {
		// TODO: implement this test
	});

	xit('should use initial variables if actual are not specified', () => {
		// TODO: implement this test
	});

	xit('should dispose subscriptions after unmount', () => {
		// TODO: implement this test
	});

	xit('should actually work with promises, stores and simple observables', () => {
		// TODO: implement this test
	});

	xit('should handle failed streams and render Failure element', () => {
		// TODO: implement this test
	});

	xit('should render `null` for not specified components', () => {
		// TODO: implement this test
	});

	xit('should restart fetching if onRetry was called', () => {
		// TODO: implement this test
	});

	xit('should abort fetching if onAbort was called', () => {
		// TODO: implement this test
	});
});
<commit_msg>added test for passing variables in fragment method<commit_after>import React from 'react';
import TestUtils from 'react/lib/ReactTestUtils';
import Transmitter from './index';
import assert from 'assert';
import sinon from 'sinon';

describe('Transmitter', () => {
	const Component = (props) =>
;
	const VALUE = 'value';
	const FIRST_ACTION_TIMEOUT = 1;
	const SECOND_ACTION_TIMEOUT = 10;

	it('should create React component', () => {
		const Container = Transmitter.create(Component, {});

		assert.ok(TestUtils.isElement(<Container />), 'Container should be a React component');
		assert.equal(Container.displayName, 'ComponentContainer', 'Container should have Component\'s name with suffix');
	});

	it('should create React component if enum is used', () => {
		const Container = Transmitter.create({success: Component}, {});

		assert.ok(TestUtils.isElement(<Container />), 'Container should be a React component');
		assert.equal(Container.displayName, 'ComponentContainer', 'Container should have Component\'s name with suffix');
	});

	it('should raise an error if no components are specified', () => {
		assert.throws(() => Transmitter.create({success: null}, {}), /Success, Failure and Pending should be React components/);
		assert.throws(() => Transmitter.create({}, {}), /Success component should be specified/);
	});

	it('should render Pending component by default', () => {
		const Spinner = () =>
Loading...
;
		const Container = Transmitter.create({success: Component, pending: Spinner}, {});
		const ReactShallow = TestUtils.createRenderer();

		ReactShallow.render(<Container />);

		assert.ok(TestUtils.isElementOfType(ReactShallow.getRenderOutput(), Spinner), 'Pending component should be rendered');
	});

	it('should render Success component with data fetched from fragments', (done) => {
		const Container = Transmitter.create(Component, {
			fragments: {
				thing() {
					return new Promise((resolve) => {
						setTimeout(resolve, FIRST_ACTION_TIMEOUT, VALUE);
					});
				}
			}
		});
		const ReactShallow = TestUtils.createRenderer();

		ReactShallow.render(<Container />);

		setTimeout(() => {
			const Output = ReactShallow.getRenderOutput();

			assert.ok(TestUtils.isElementOfType(Output, Component), 'Success component should be rendered');
			assert.deepEqual(Output.props, { thing: VALUE }, 'Component should be rendered with data fetched via fragments');
			done();
		}, SECOND_ACTION_TIMEOUT);
	});

	// waiting for https://github.com/facebook/react/pull/5247 being merged
	xit('should immediately render Success component if fragments are passed via props', () => {
		const thingFragment = sinon.stub().returns(new Promise((resolve) => {
			setTimeout(resolve, FIRST_ACTION_TIMEOUT, VALUE);
		}));
		const Container = Transmitter.create(Component, {
			fragments: {thing: thingFragment}
		});
		const ReactShallow = TestUtils.createRenderer();

		ReactShallow.render(<Container thing={VALUE} />);

		const Output = ReactShallow.getRenderOutput();

		assert.ok(!thingFragment.called, 'Fragment should not be called');
		assert.ok(TestUtils.isElementOfType(Output, Component), 'Success component should be rendered');
		assert.deepEqual(Output.props, { thing: VALUE }, 'Component should be rendered with data fetched via fragments');
	});

	it('should call fragments with passed variables', () => {
		const thingFragment = sinon.stub().returns(Promise.resolve(VALUE));
		const Container = Transmitter.create(Component, {
			fragments: {thing: thingFragment}
		});
		const ReactShallow = TestUtils.createRenderer();
		const variables = {id: VALUE};

		ReactShallow.render(<Container variables={variables} />);

		assert.ok(thingFragment.calledWith(variables), 'Fragment should be called with passed variables');
	});

	xit('should use initial variables if actual are not specified', () => {
		// TODO: implement this test
	});

	xit('should dispose subscriptions after unmount', () => {
		// TODO: implement this test
	});

	xit('should actually work with promises, stores and simple observables', () => {
		// TODO: implement this test
	});

	xit('should handle failed streams and render Failure element', () => {
		// TODO: implement this test
	});

	xit('should render `null` for not specified components', () => {
		// TODO: implement this test
	});

	xit('should restart fetching if onRetry was called', () => {
		// TODO: implement this test
	});

	xit('should abort fetching if onAbort was called', () => {
		// TODO: implement this test
	});
});
<|endoftext|>


<commit_before>describe('Plugin initialization and component basic construction', function () {
    'use strict';

    it('loads jquery plugin properly', function () {
        expect($('<div>').datetimepicker).toBeDefined();
        expect(typeof $('<div>').datetimepicker).toEqual('function');
        expect($('<div>').datetimepicker.defaults).toBeDefined();
    });

    it('throws an Error if constructing on a structure with no input element', function () {
        var dtp = $('<div>');
        $(document).find('body').append(dtp);

        expect(function () {
            dtp = dtp.datetimepicker();
        }).toThrow();
    });

    it('creates the component with default options on an input element', function () {
        var dtp = $('<input>');
        $(document).find('body').append(dtp);

        expect(function () {
            dtp = dtp.datetimepicker();
        }).not.toThrow();

        expect(dtp).not.toBe(null);
    });

    xit('calls destroy when Element that the component is attached is removed', function () {
        var dtpElement = $('<div>').attr('class', 'row').append($('<div>').attr('class', 'col-md-12').append($('<input>'))),
            dtp;
        $(document).find('body').append(dtpElement);
        dtpElement.datetimepicker();
        dtp = dtpElement.data('DateTimePicker');
        spyOn(dtp, 'destroy').and.callThrough();
        dtpElement.remove();
        expect(dtp.destroy).toHaveBeenCalled();
    });
});

describe('Public API method tests', function () {
    'use strict';
    var dtp,
        dtpElement,
        dpChangeSpy,
        dpShowSpy,
        dpHideSpy,
        dpErrorSpy;

    beforeEach(function () {
        dpChangeSpy = jasmine.createSpy('change.dp event Spy');
        dpShowSpy = jasmine.createSpy('show.dp event Spy');
        dpHideSpy = jasmine.createSpy('hide.dp event Spy');
        dpErrorSpy = jasmine.createSpy('error.dp event Spy');
        dtpElement = $('<input>').attr('id', 'dtp');

        $(document).find('body').append($('<div>').attr('class', 'row').append($('<div>').attr('class', 'col-md-12').append(dtpElement)));
        $(document).find('body').on('change.dp', dpChangeSpy);
        $(document).find('body').on('show.dp', dpShowSpy);
        $(document).find('body').on('hide.dp', dpHideSpy);
        $(document).find('body').on('error.dp', dpErrorSpy);

        dtpElement.datetimepicker();
        dtp = dtpElement.data('DateTimePicker');
    });

    afterEach(function () {
        dtp.destroy();
        dtpElement.remove();
    });

    describe('configuration option name match to public api function', function () {
        Object.getOwnPropertyNames($.fn.datetimepicker.defaults).forEach(function (key) {
            it('has function ' + key + '()', function () {
                expect(dtp[key]).toBeDefined();
            });
        });
    });

    describe('date() function', function () {
        describe('typechecking', function () {
            it('accepts a null', function () {
                expect(function () {
                    dtp.date(null);
                }).not.toThrow();
            });

            it('accepts a string', function () {
                expect(function () {
                    dtp.date('2013/05/24');
                }).not.toThrow();
            });

            it('accepts a Date object', function () {
                expect(function () {
                    dtp.date(new Date());
                }).not.toThrow();
            });

            it('accepts a Moment object', function () {
                expect(function () {
                    dtp.date(moment());
                }).not.toThrow();
            });

            it('does not accept undefined', function () {
                expect(function () {
                    dtp.date(undefined);
                }).toThrow();
            });

            it('does not accept a number', function () {
                expect(function () {
                    dtp.date(0);
                }).toThrow();
            });

            it('does not accept a generic Object', function () {
                expect(function () {
                    dtp.date({});
                }).toThrow();
            });

            it('does not accept a boolean', function () {
                expect(function () {
                    dtp.date(false);
                }).toThrow();
            });
        });

        describe('functionality', function () {
            it('has no date set upon construction', function () {
                expect(dtp.date()).toBe(null);
            });

            it('sets the date correctly', function () {
                var timestamp = moment();
                dtp.date(timestamp);
                expect(dtp.date().isSame(timestamp)).toBe(true);
            });
        });
    });

    describe('format() function', function () {
        describe('typechecking', function () {
            it('accepts a false value', function () {
                expect(function () {
                    dtp.format(false);
                }).not.toThrow();
            });

            it('accepts a string', function () {
                expect(function () {
                    dtp.format('YYYY-MM-DD');
                }).not.toThrow();
            });

            it('does not accept undefined', function () {
                expect(function () {
                    dtp.format(undefined);
                }).toThrow();
            });

            it('does not accept true', function () {
                expect(function () {
                    dtp.format(true);
                }).toThrow();
            });

            it('does not accept a generic Object', function () {
                expect(function () {
                    dtp.format({});
                }).toThrow();
            });
        });

        describe('functionality', function () {
            it('returns no format before format is set', function () {
                expect(dtp.format()).toBe(false);
            });

            it('sets the format correctly', function () {
                dtp.format('YYYY-MM-DD');
                expect(dtp.format()).toBe('YYYY-MM-DD');
            });
        });
    });

    describe('destroy() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.destroy).toBeDefined();
            });
        });
    });

    describe('toggle() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.toggle).toBeDefined();
            });
        });

        // describe('functionality', function () {
        //     it('')
        // });
    });

    describe('show() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.show).toBeDefined();
            });
        });

        describe('functionality', function () {
            it('emits a show event when called while widget is hidden', function () {
                dtp.show();
                expect(dpShowSpy).toHaveBeenCalled();
            });

            it('does not emit a show event when called and widget is already showing', function () {
                dtp.hide();
                dtp.show();
                dpShowSpy.calls.reset();
                dtp.show();
                expect(dpShowSpy).not.toHaveBeenCalled();
            });

            it('actually shows the widget', function () {
                dtp.show();
                expect($(document).find('body').find('.bootstrap-datetimepicker-widget').length).toEqual(1);
            });
        });
    });

    describe('hide() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.hide).toBeDefined();
            });
        });

        describe('functionality', function () {
            it('emits a hide event when called while widget is shown', function () {
                dtp.show();
                dtp.hide();
                expect(dpHideSpy).toHaveBeenCalled();
            });

            it('does not emit a hide event when called while widget is hidden', function () {
                dtp.hide();
                expect(dpHideSpy).not.toHaveBeenCalled();
            });

            it('actually hides the widget', function () {
                dtp.show();
                dtp.hide();
                expect($(document).find('body').find('.bootstrap-datetimepicker-widget').length).toEqual(0);
            });
        });
    });

    describe('disable() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.disable).toBeDefined();
            });
        });
    });

    describe('enable() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.enable).toBeDefined();
            });
        });
    });

    describe('options() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.options).toBeDefined();
            });
        });
    });

    describe('disabledDates() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.disabledDates).toBeDefined();
            });
        });
    });

    describe('enabledDates() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.enabledDates).toBeDefined();
            });
        });
    });

    describe('daysOfWeekDisabled() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.daysOfWeekDisabled).toBeDefined();
            });
        });
    });

    describe('maxDate() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.maxDate).toBeDefined();
            });
        });
    });

    describe('minDate() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.minDate).toBeDefined();
            });
        });
    });

    describe('defaultDate() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.defaultDate).toBeDefined();
            });
        });
        describe('functionality', function () {
            it('returns no defaultDate before defaultDate is set', function () {
                expect(dtp.defaultDate()).toBe(false);
            });

            it('sets the defaultDate correctly', function () {
                var timestamp = moment();
                dtp.defaultDate(timestamp);
                expect(dtp.defaultDate().isSame(timestamp)).toBe(true);
                expect(dtp.date().isSame(timestamp)).toBe(true);
            });

            it('triggers a change event upon setting a default date and input field is empty', function () {
                dtp.date(null);
                dtp.defaultDate(moment());
                expect(dpChangeSpy).toHaveBeenCalled();
            });

            it('does not override input value if it already has one', function () {
                var timestamp = moment();
                dtp.date(timestamp);
                dtp.defaultDate(moment().year(2000));
                expect(dtp.date().isSame(timestamp)).toBe(true);
            });
        });
    });

    describe('locale() function', function () {
        describe('functionality', function () {
            it('it has the same locale as the global moment locale with default options', function () {
                expect(dtp.locale()).toBe(moment.locale());
            });

            it('it switches to a selected locale without affecting global moment locale', function () {
                dtp.locale('el');
                dtp.date(moment());
                expect(dtp.locale()).toBe('el');
                expect(dtp.date().locale()).toBe('el');
                expect(moment.locale()).toBe('en');
            });
        });
    });

    describe('useCurrent() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.useCurrent).toBeDefined();
            });
        });
        describe('check type and parameter validity', function () {
            it('accepts either a boolean value or string', function () {
                var useCurrentOptions = ['year', 'month', 'day', 'hour', 'minute'];

                expect(function () {
                    dtp.useCurrent(false);
                }).not.toThrow();
                expect(function () {
                    dtp.useCurrent(true);
                }).not.toThrow();

                useCurrentOptions.forEach(function (value) {
                    expect(function () {
                        dtp.useCurrent(value);
                    }).not.toThrow();
                });

                expect(function () {
                    dtp.useCurrent('test');
                }).toThrow();
                expect(function () {
                    dtp.useCurrent({});
                }).toThrow();
            });
        });
        describe('functionality', function () {
            it('triggers a change event upon show() and input field is empty', function () {
                dtp.useCurrent(true);
                dtp.show();
                expect(dpChangeSpy).toHaveBeenCalled();
            });
        });
    });

    describe('stepping() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.stepping).toBeDefined();
            });
        });
    });

    describe('collapse() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.collapse).toBeDefined();
            });
        });
    });

    describe('icons() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.icons).toBeDefined();
            });
        });
    });

    describe('useStrict() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.useStrict).toBeDefined();
            });
        });
    });

    describe('sideBySide() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.sideBySide).toBeDefined();
            });
        });
    });

    describe('viewMode() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.viewMode).toBeDefined();
            });
        });
    });

    describe('widgetPositioning() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.widgetPositioning).toBeDefined();
            });
        });
    });

    describe('calendarWeeks() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.calendarWeeks).toBeDefined();
            });
        });
    });

    describe('showTodayButton() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.showTodayButton).toBeDefined();
            });
        });
    });

    describe('showClear() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.showClear).toBeDefined();
            });
        });
    });
});
<commit_msg>Revert "tests"<commit_after>describe('Plugin initialization and component basic construction', function () {
    'use strict';

    it('loads jquery plugin properly', function () {
        expect($('<div>').datetimepicker).toBeDefined();
        expect(typeof $('<div>').datetimepicker).toEqual('function');
        expect($('<div>').datetimepicker.defaults).toBeDefined();
    });

    it('throws an Error if constructing on a structure with no input element', function () {
        var dtp = $('<div>');
        $(document).find('body').append(dtp);

        expect(function () {
            dtp = dtp.datetimepicker();
        }).toThrow();
    });

    it('creates the component with default options on an input element', function () {
        var dtp = $('<input>');
        $(document).find('body').append(dtp);

        expect(function () {
            dtp = dtp.datetimepicker();
        }).not.toThrow();

        expect(dtp).not.toBe(null);
    });

    xit('calls destroy when Element that the component is attached is removed', function () {
        var dtpElement = $('<div>').attr('class', 'row').append($('<div>').attr('class', 'col-md-12').append($('<input>'))),
            dtp;
        $(document).find('body').append(dtpElement);
        dtpElement.datetimepicker();
        dtp = dtpElement.data('DateTimePicker');
        spyOn(dtp, 'destroy').and.callThrough();
        dtpElement.remove();
        expect(dtp.destroy).toHaveBeenCalled();
    });
});

describe('Public API method tests', function () {
    'use strict';
    var dtp,
        dtpElement,
        dpChangeSpy,
        dpShowSpy,
        dpHideSpy,
        dpErrorSpy;

    beforeEach(function () {
        dpChangeSpy = jasmine.createSpy('dp.change event Spy');
        dpShowSpy = jasmine.createSpy('dp.show event Spy');
        dpHideSpy = jasmine.createSpy('dp.hide event Spy');
        dpErrorSpy = jasmine.createSpy('dp.error event Spy');
        dtpElement = $('<input>').attr('id', 'dtp');

        $(document).find('body').append($('<div>').attr('class', 'row').append($('<div>').attr('class', 'col-md-12').append(dtpElement)));
        $(document).find('body').on('dp.change', dpChangeSpy);
        $(document).find('body').on('dp.show', dpShowSpy);
        $(document).find('body').on('dp.hide', dpHideSpy);
        $(document).find('body').on('dp.error', dpErrorSpy);

        dtpElement.datetimepicker();
        dtp = dtpElement.data('DateTimePicker');
    });

    afterEach(function () {
        dtp.destroy();
        dtpElement.remove();
    });

    describe('configuration option name match to public api function', function () {
        Object.getOwnPropertyNames($.fn.datetimepicker.defaults).forEach(function (key) {
            it('has function ' + key + '()', function () {
                expect(dtp[key]).toBeDefined();
            });
        });
    });

    describe('date() function', function () {
        describe('typechecking', function () {
            it('accepts a null', function () {
                expect(function () {
                    dtp.date(null);
                }).not.toThrow();
            });

            it('accepts a string', function () {
                expect(function () {
                    dtp.date('2013/05/24');
                }).not.toThrow();
            });

            it('accepts a Date object', function () {
                expect(function () {
                    dtp.date(new Date());
                }).not.toThrow();
            });

            it('accepts a Moment object', function () {
                expect(function () {
                    dtp.date(moment());
                }).not.toThrow();
            });

            it('does not accept undefined', function () {
                expect(function () {
                    dtp.date(undefined);
                }).toThrow();
            });

            it('does not accept a number', function () {
                expect(function () {
                    dtp.date(0);
                }).toThrow();
            });

            it('does not accept a generic Object', function () {
                expect(function () {
                    dtp.date({});
                }).toThrow();
            });

            it('does not accept a boolean', function () {
                expect(function () {
                    dtp.date(false);
                }).toThrow();
            });
        });

        describe('functionality', function () {
            it('has no date set upon construction', function () {
                expect(dtp.date()).toBe(null);
            });

            it('sets the date correctly', function () {
                var timestamp = moment();
                dtp.date(timestamp);
                expect(dtp.date().isSame(timestamp)).toBe(true);
            });
        });
    });

    describe('format() function', function () {
        describe('typechecking', function () {
            it('accepts a false value', function () {
                expect(function () {
                    dtp.format(false);
                }).not.toThrow();
            });

            it('accepts a string', function () {
                expect(function () {
                    dtp.format('YYYY-MM-DD');
                }).not.toThrow();
            });

            it('does not accept undefined', function () {
                expect(function () {
                    dtp.format(undefined);
                }).toThrow();
            });

            it('does not accept true', function () {
                expect(function () {
                    dtp.format(true);
                }).toThrow();
            });

            it('does not accept a generic Object', function () {
                expect(function () {
                    dtp.format({});
                }).toThrow();
            });
        });

        describe('functionality', function () {
            it('returns no format before format is set', function () {
                expect(dtp.format()).toBe(false);
            });

            it('sets the format correctly', function () {
                dtp.format('YYYY-MM-DD');
                expect(dtp.format()).toBe('YYYY-MM-DD');
            });
        });
    });

    describe('destroy() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.destroy).toBeDefined();
            });
        });
    });

    describe('toggle() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.toggle).toBeDefined();
            });
        });

        // describe('functionality', function () {
        //     it('')
        // });
    });

    describe('show() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.show).toBeDefined();
            });
        });

        describe('functionality', function () {
            it('emits a show event when called while widget is hidden', function () {
                dtp.show();
                expect(dpShowSpy).toHaveBeenCalled();
            });

            it('does not emit a show event when called and widget is already showing', function () {
                dtp.hide();
                dtp.show();
                dpShowSpy.calls.reset();
                dtp.show();
                expect(dpShowSpy).not.toHaveBeenCalled();
            });

            it('actually shows the widget', function () {
                dtp.show();
                expect($(document).find('body').find('.bootstrap-datetimepicker-widget').length).toEqual(1);
            });
        });
    });

    describe('hide() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.hide).toBeDefined();
            });
        });

        describe('functionality', function () {
            it('emits a hide event when called while widget is shown', function () {
                dtp.show();
                dtp.hide();
                expect(dpHideSpy).toHaveBeenCalled();
            });

            it('does not emit a hide event when called while widget is hidden', function () {
                dtp.hide();
                expect(dpHideSpy).not.toHaveBeenCalled();
            });

            it('actually hides the widget', function () {
                dtp.show();
                dtp.hide();
                expect($(document).find('body').find('.bootstrap-datetimepicker-widget').length).toEqual(0);
            });
        });
    });

    describe('disable() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.disable).toBeDefined();
            });
        });
    });

    describe('enable() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.enable).toBeDefined();
            });
        });
    });

    describe('options() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.options).toBeDefined();
            });
        });
    });

    describe('disabledDates() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.disabledDates).toBeDefined();
            });
        });
    });

    describe('enabledDates() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.enabledDates).toBeDefined();
            });
        });
    });

    describe('daysOfWeekDisabled() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.daysOfWeekDisabled).toBeDefined();
            });
        });
    });

    describe('maxDate() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.maxDate).toBeDefined();
            });
        });
    });

    describe('minDate() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.minDate).toBeDefined();
            });
        });
    });

    describe('defaultDate() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.defaultDate).toBeDefined();
            });
        });
        describe('functionality', function () {
            it('returns no defaultDate before defaultDate is set', function () {
                expect(dtp.defaultDate()).toBe(false);
            });

            it('sets the defaultDate correctly', function () {
                var timestamp = moment();
                dtp.defaultDate(timestamp);
                expect(dtp.defaultDate().isSame(timestamp)).toBe(true);
                expect(dtp.date().isSame(timestamp)).toBe(true);
            });

            it('triggers a change event upon setting a default date and input field is empty', function () {
                dtp.date(null);
                dtp.defaultDate(moment());
                expect(dpChangeSpy).toHaveBeenCalled();
            });

            it('does not override input value if it already has one', function () {
                var timestamp = moment();
                dtp.date(timestamp);
                dtp.defaultDate(moment().year(2000));
                expect(dtp.date().isSame(timestamp)).toBe(true);
            });
        });
    });

    describe('locale() function', function () {
        describe('functionality', function () {
            it('it has the same locale as the global moment locale with default options', function () {
                expect(dtp.locale()).toBe(moment.locale());
            });

            it('it switches to a selected locale without affecting global moment locale', function () {
                dtp.locale('el');
                dtp.date(moment());
                expect(dtp.locale()).toBe('el');
                expect(dtp.date().locale()).toBe('el');
                expect(moment.locale()).toBe('en');
            });
        });
    });

    describe('useCurrent() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.useCurrent).toBeDefined();
            });
        });
        describe('check type and parameter validity', function () {
            it('accepts either a boolean value or string', function () {
                var useCurrentOptions = ['year', 'month', 'day', 'hour', 'minute'];

                expect(function () {
                    dtp.useCurrent(false);
                }).not.toThrow();
                expect(function () {
                    dtp.useCurrent(true);
                }).not.toThrow();

                useCurrentOptions.forEach(function (value) {
                    expect(function () {
                        dtp.useCurrent(value);
                    }).not.toThrow();
                });

                expect(function () {
                    dtp.useCurrent('test');
                }).toThrow();
                expect(function () {
                    dtp.useCurrent({});
                }).toThrow();
            });
        });
        describe('functionality', function () {
            it('triggers a change event upon show() and input field is empty', function () {
                dtp.useCurrent(true);
                dtp.show();
                expect(dpChangeSpy).toHaveBeenCalled();
            });
        });
    });

    describe('stepping() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.stepping).toBeDefined();
            });
        });
    });

    describe('collapse() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.collapse).toBeDefined();
            });
        });
    });

    describe('icons() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.icons).toBeDefined();
            });
        });
    });

    describe('useStrict() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.useStrict).toBeDefined();
            });
        });
    });

    describe('sideBySide() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.sideBySide).toBeDefined();
            });
        });
    });

    describe('viewMode() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.viewMode).toBeDefined();
            });
        });
    });

    describe('widgetPositioning() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.widgetPositioning).toBeDefined();
            });
        });
    });

    describe('calendarWeeks() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.calendarWeeks).toBeDefined();
            });
        });
    });

    describe('showTodayButton() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.showTodayButton).toBeDefined();
            });
        });
    });

    describe('showClear() function', function () {
        describe('existence', function () {
            it('is defined', function () {
                expect(dtp.showClear).toBeDefined();
            });
        });
    });
});
<|endoftext|>


<commit_before>'use strict';

// MODULES //

var isObject = require( '@stdlib/assert/is-plain-object' );
var hasOwnProp = require( '@stdlib/assert/has-own-property' );
var isString = require( '@stdlib/assert/is-string' ).isPrimitive;
var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive;
var isPositiveInteger = require( '@stdlib/assert/is-positive-integer' ).isPrimitive;

// MAIN //

/**
* Validates function options.
*
* @private
* @param {Object} opts - destination object
* @param {Options} options - function options
* @param {string} [options.cwd] - current working directory of the child process
* @param {boolean} [options.quiet] - boolean indicating whether to silence examples writing to `stdout`, but allow writing to `stderr`
* @param {boolean} [options.silent] - boolean indicating whether to silence examples writing to both `stdout` and `stderr`
* @param {boolean} [options.verbose] - boolean indicating whether to print plugin meta information
* @returns {(Error|null)} null or an error object
*
* @example
* var opts = {};
* var options = {
*     'quiet': true,
*     'verbose': false
* };
* var err = validate( opts, options );
* if ( err ) {
*     throw err;
* }
*/
function validate( opts, options ) {
	if ( !isObject( options ) ) {
		return new TypeError( 'invalid input argument. Options must be an object. Value: `' + options + '`.' );
	}
	if ( hasOwnProp( options, 'cwd' ) ) {
		if ( !isString( options.cwd ) ) {
			return new TypeError( 'invalid option. `cwd` option must be a string primitive. Option: `' + options.cwd + '`.' );
		}
		opts.cwd = options.cwd;
	}
	if ( hasOwnProp( options, 'quiet' ) ) {
		if ( !isBoolean( options.quiet ) ) {
			return new TypeError( 'invalid option. `quiet` option must be a boolean primitive. Option: `' + options.quiet + '`.' );
		}
		opts.quiet = options.quiet;
	}
	if ( hasOwnProp( options, 'silent' ) ) {
		if ( !isBoolean( options.silent ) ) {
			return new TypeError( 'invalid option. `silent` option must be a boolean primitive. Option: `' + options.silent + '`.' );
		}
		opts.silent = options.silent;
	}
	if ( hasOwnProp( options, 'verbose' ) ) {
		if ( !isBoolean( options.verbose ) ) {
			return new TypeError( 'invalid option. `verbose` option must be a boolean primitive. Option: `' + options.verbose + '`.' );
		}
		opts.verbose = options.verbose;
	}
	if ( hasOwnProp( options, 'maxBuffer' ) ) {
		if ( !isPositiveInteger( options.maxBuffer ) ) {
			return new TypeError( 'invalid option. `maxBuffer` option must be a positive integer. Option: `' + options.maxBuffer + '`.' );
		}
		opts.maxBuffer = options.maxBuffer;
	}
	return null;
} // end FUNCTION validate()

// EXPORTS //

module.exports = validate;
<commit_msg>Add missing parameter<commit_after>'use strict';

// MODULES //

var isObject = require( '@stdlib/assert/is-plain-object' );
var hasOwnProp = require( '@stdlib/assert/has-own-property' );
var isString = require( '@stdlib/assert/is-string' ).isPrimitive;
var isBoolean = require( '@stdlib/assert/is-boolean' ).isPrimitive;
var isPositiveInteger = require( '@stdlib/assert/is-positive-integer' ).isPrimitive;

// MAIN //

/**
* Validates function options.
*
* @private
* @param {Object} opts - destination object
* @param {Options} options - function options
* @param {string} [options.cwd] - current working directory of the child process
* @param {boolean} [options.quiet] - boolean indicating whether to silence examples writing to `stdout`, but allow writing to `stderr`
* @param {boolean} [options.silent] - boolean indicating whether to silence examples writing to both `stdout` and `stderr`
* @param {boolean} [options.verbose] - boolean indicating whether to print plugin meta information
* @param {PositiveInteger} [options.maxBuffer] - maximum buffer size for `stdout` and `stderr`
* @returns {(Error|null)} null or an error object
*
* @example
* var opts = {};
* var options = {
*     'quiet': true,
*     'verbose': false
* };
* var err = validate( opts, options );
* if ( err ) {
*     throw err;
* }
*/
function validate( opts, options ) {
	if ( !isObject( options ) ) {
		return new TypeError( 'invalid input argument. Options must be an object. Value: `' + options + '`.' );
	}
	if ( hasOwnProp( options, 'cwd' ) ) {
		if ( !isString( options.cwd ) ) {
			return new TypeError( 'invalid option. `cwd` option must be a string primitive. Option: `' + options.cwd + '`.' );
		}
		opts.cwd = options.cwd;
	}
	if ( hasOwnProp( options, 'quiet' ) ) {
		if ( !isBoolean( options.quiet ) ) {
			return new TypeError( 'invalid option. `quiet` option must be a boolean primitive. Option: `' + options.quiet + '`.' );
		}
		opts.quiet = options.quiet;
	}
	if ( hasOwnProp( options, 'silent' ) ) {
		if ( !isBoolean( options.silent ) ) {
			return new TypeError( 'invalid option. `silent` option must be a boolean primitive. Option: `' + options.silent + '`.' );
		}
		opts.silent = options.silent;
	}
	if ( hasOwnProp( options, 'verbose' ) ) {
		if ( !isBoolean( options.verbose ) ) {
			return new TypeError( 'invalid option. `verbose` option must be a boolean primitive. Option: `' + options.verbose + '`.' );
		}
		opts.verbose = options.verbose;
	}
	if ( hasOwnProp( options, 'maxBuffer' ) ) {
		if ( !isPositiveInteger( options.maxBuffer ) ) {
			return new TypeError( 'invalid option. `maxBuffer` option must be a positive integer. Option: `' + options.maxBuffer + '`.' );
		}
		opts.maxBuffer = options.maxBuffer;
	}
	return null;
} // end FUNCTION validate()

// EXPORTS //

module.exports = validate;
<|endoftext|>


<commit_before>var utils = require('./connection_utils'),
  inherits = require('util').inherits,
  net = require('net'),
  EventEmitter = require('events').EventEmitter,
  inherits = require('util').inherits,
  MongoReply = require("../responses/mongo_reply").MongoReply,
  Connection = require("./connection").Connection;

var ConnectionPool = exports.ConnectionPool = function(host, port, poolSize, bson, socketOptions) {
  if(typeof host !== 'string') {
    throw new Error("host must be specified [" + host + "]");
  }

  // Set up event emitter
  EventEmitter.call(this);

  // Keep all options for the socket in a specific collection allowing the user to specify the
  // Wished upon socket connection parameters
  this.socketOptions = typeof socketOptions === 'object' ? socketOptions : {};
  this.socketOptions.host = host;
  this.socketOptions.port = port;
  this.socketOptions.domainSocket = false;
  this.bson = bson;
  // PoolSize is always + 1 for special reserved "measurment" socket (like ping, stats etc)
  this.poolSize = poolSize;
  this.minPoolSize = Math.floor(this.poolSize / 2) + 1;

  // Check if the host is a socket
  if(host.match(/^\//)) {
    this.socketOptions.domainSocket = true;
  } else if(typeof port !== 'number') {
    throw new Error("port must be specified ["  + port + "]");
  }

  // Set default settings for the socket options
  utils.setIntegerParameter(this.socketOptions, 'timeout', 0);
  // Delay before writing out the data to the server
  utils.setBooleanParameter(this.socketOptions, 'noDelay', true);
  // Delay before writing out the data to the server
  utils.setIntegerParameter(this.socketOptions, 'keepAlive', 0);
  // Set the encoding of the data read, default is binary == null
  utils.setStringParameter(this.socketOptions, 'encoding', null);
  // Allows you to set a throttling bufferSize if you need to stop overflows
  utils.setIntegerParameter(this.socketOptions, 'bufferSize', 0);

  // Internal structures
  this.openConnections = [];
  // Assign connection id's
  this.connectionId = 0;

  // Current index for selection of pool connection
  this.currentConnectionIndex = 0;
  // The pool state
  this._poolState = 'disconnected';
  // timeout control
  this._timeout = false;
}

inherits(ConnectionPool, EventEmitter);

ConnectionPool.prototype.setMaxBsonSize = function(maxBsonSize) {
  if(maxBsonSize == null){
    maxBsonSize = Connection.DEFAULT_MAX_BSON_SIZE;
  }

  for(var i = 0; i < this.openConnections.length; i++) {
    this.openConnections[i].maxBsonSize = maxBsonSize;
  }
}

// Start a function
var _connect = function(_self) {
  return new function() {
    // Create a new connection instance
    var connection = new Connection(_self.connectionId++, _self.socketOptions);
    // Set logger on pool
    connection.logger = _self.logger;
    // Connect handler
    connection.on("connect", function(err, connection) {
      // Add connection to list of open connections
      _self.openConnections.push(connection);
      // If the number of open connections is equal to the poolSize signal ready pool
      if(_self.openConnections.length === _self.poolSize && _self._poolState !== 'disconnected') {
        // Set connected
        _self._poolState = 'connected';
        // Emit pool ready
        _self.emit("poolReady");
      } else if(_self.openConnections.length < _self.poolSize) {
        // We need to open another connection, make sure it's in the next
        // tick so we don't get a cascade of errors
        process.nextTick(function() {
          _connect(_self);
        });
      }
    });

    var numberOfErrors = 0

    // Error handler
    connection.on("error", function(err, connection) {
      numberOfErrors++;
      // If we are already disconnected ignore the event
      if(_self._poolState != 'disconnected' && _self.listeners("error").length > 0) {
        _self.emit("error", err);
      }

      // Set disconnected
      _self._poolState = 'disconnected';
      // Stop
      _self.stop();
    });

    // Close handler
    connection.on("close", function() {
      // If we are already disconnected ignore the event
      if(_self._poolState !== 'disconnected' && _self.listeners("close").length > 0) {
        _self.emit("close");
      }
      // Set disconnected
      _self._poolState = 'disconnected';
      // Stop
      _self.stop();
    });

    // Timeout handler
    connection.on("timeout", function(err, connection) {
      // If we are already disconnected ignore the event
      if(_self._poolState !== 'disconnected' && _self.listeners("timeout").length > 0) {
        _self.emit("timeout", err);
      }
      // Set disconnected
      _self._poolState = 'disconnected';
      // Stop
      _self.stop();
    });

    // Parse error, needs a complete shutdown of the pool
    connection.on("parseError", function() {
      // If we are already disconnected ignore the event
      if(_self._poolState !== 'disconnected' && _self.listeners("parseError").length > 0) {
        _self.emit("parseError", new Error("parseError occured"));
      }

      _self.stop();
    });

    connection.on("message", function(message) {
      _self.emit("message", message);
    });

    // Start connection in the next tick
    connection.start();
  }();
}

// Start method, will throw error if no listeners are available
// Pass in an instance of the listener that contains the api for
// finding callbacks for a given message etc.
ConnectionPool.prototype.start = function() {
  var markerDate = new Date().getTime();
  var self = this;

  if(this.listeners("poolReady").length == 0) {
    throw "pool must have at least one listener ready that responds to the [poolReady] event";
  }

  // Set pool state to connecting
  this._poolState = 'connecting';
  this._timeout = false;

  _connect(self);
}

// Restart a connection pool (on a close the pool might be in a wrong state)
ConnectionPool.prototype.restart = function() {
  // Close all connections
  this.stop(false);
  // Now restart the pool
  this.start();
}

// Stop the connections in the pool
ConnectionPool.prototype.stop = function(removeListeners) {
  removeListeners = removeListeners == null ? true : removeListeners;
  // Set disconnected
  this._poolState = 'disconnected';

  // Clear all listeners if specified
  if(removeListeners) {
    this.removeAllEventListeners();
  }

  // Close all connections
  for(var i = 0; i < this.openConnections.length; i++) {
    this.openConnections[i].close();
  }

  // Clean up
  this.openConnections = [];
}

// Check the status of the connection
ConnectionPool.prototype.isConnected = function() {
  return this._poolState === 'connected';
}

// Checkout a connection from the pool for usage, or grab a specific pool instance
ConnectionPool.prototype.checkoutConnection = function(id) {
  var index = (this.currentConnectionIndex++ % (this.openConnections.length));
  var connection = this.openConnections[index];
  return connection;
}

ConnectionPool.prototype.getAllConnections = function() {
  return this.openConnections;
}

// Remove all non-needed event listeners
ConnectionPool.prototype.removeAllEventListeners = function() {
  this.removeAllListeners("close");
  this.removeAllListeners("error");
  this.removeAllListeners("timeout");
  this.removeAllListeners("connect");
  this.removeAllListeners("end");
  this.removeAllListeners("parseError");
  this.removeAllListeners("message");
  this.removeAllListeners("poolReady");
}

<commit_msg>connectionPool: close dead connections<commit_after>var utils = require('./connection_utils'),
  inherits = require('util').inherits,
  net = require('net'),
  EventEmitter = require('events').EventEmitter,
  inherits = require('util').inherits,
  MongoReply = require("../responses/mongo_reply").MongoReply,
  Connection = require("./connection").Connection;

var ConnectionPool = exports.ConnectionPool = function(host, port, poolSize, bson, socketOptions) {
  if(typeof host !== 'string') {
    throw new Error("host must be specified [" + host + "]");
  }

  // Set up event emitter
  EventEmitter.call(this);

  // Keep all options for the socket in a specific collection allowing the user to specify the
  // Wished upon socket connection parameters
  this.socketOptions = typeof socketOptions === 'object' ? socketOptions : {};
  this.socketOptions.host = host;
  this.socketOptions.port = port;
  this.socketOptions.domainSocket = false;
  this.bson = bson;
  // PoolSize is always + 1 for special reserved "measurment" socket (like ping, stats etc)
  this.poolSize = poolSize;
  this.minPoolSize = Math.floor(this.poolSize / 2) + 1;

  // Check if the host is a socket
  if(host.match(/^\//)) {
    this.socketOptions.domainSocket = true;
  } else if(typeof port !== 'number') {
    throw new Error("port must be specified ["  + port + "]");
  }

  // Set default settings for the socket options
  utils.setIntegerParameter(this.socketOptions, 'timeout', 0);
  // Delay before writing out the data to the server
  utils.setBooleanParameter(this.socketOptions, 'noDelay', true);
  // Delay before writing out the data to the server
  utils.setIntegerParameter(this.socketOptions, 'keepAlive', 0);
  // Set the encoding of the data read, default is binary == null
  utils.setStringParameter(this.socketOptions, 'encoding', null);
  // Allows you to set a throttling bufferSize if you need to stop overflows
  utils.setIntegerParameter(this.socketOptions, 'bufferSize', 0);

  // Internal structures
  this.openConnections = [];
  // Assign connection id's
  this.connectionId = 0;

  // Current index for selection of pool connection
  this.currentConnectionIndex = 0;
  // The pool state
  this._poolState = 'disconnected';
  // timeout control
  this._timeout = false;
}

inherits(ConnectionPool, EventEmitter);

ConnectionPool.prototype.setMaxBsonSize = function(maxBsonSize) {
  if(maxBsonSize == null){
    maxBsonSize = Connection.DEFAULT_MAX_BSON_SIZE;
  }

  for(var i = 0; i < this.openConnections.length; i++) {
    this.openConnections[i].maxBsonSize = maxBsonSize;
  }
}

// Start a function
var _connect = function(_self) {
  return new function() {
    // Create a new connection instance
    var connection = new Connection(_self.connectionId++, _self.socketOptions);
    // Set logger on pool
    connection.logger = _self.logger;
    // Connect handler
    connection.on("connect", function(err, connection) {
      // Add connection to list of open connections
      _self.openConnections.push(connection);
      // If the number of open connections is equal to the poolSize signal ready pool
      if(_self.openConnections.length === _self.poolSize && _self._poolState !== 'disconnected') {
        // Set connected
        _self._poolState = 'connected';
        // Emit pool ready
        _self.emit("poolReady");
      } else if(_self.openConnections.length < _self.poolSize) {
        // We need to open another connection, make sure it's in the next
        // tick so we don't get a cascade of errors
        process.nextTick(function() {
          _connect(_self);
        });
      }
    });

    var numberOfErrors = 0

    // Error handler
    connection.on("error", function(err, connection) {
      numberOfErrors++;
      // If we are already disconnected ignore the event
      if(_self._poolState != 'disconnected' && _self.listeners("error").length > 0) {
        _self.emit("error", err);
      }

      connection.close();
      _self._poolState = 'disconnected';
      _self.stop();
    });

    // Close handler
    connection.on("close", function() {
      // If we are already disconnected ignore the event
      if(_self._poolState !== 'disconnected' && _self.listeners("close").length > 0) {
        _self.emit("close");
      }
      // Set disconnected
      _self._poolState = 'disconnected';
      // Stop
      _self.stop();
    });

    // Timeout handler
    connection.on("timeout", function(err, connection) {
      // If we are already disconnected ignore the event
      if(_self._poolState !== 'disconnected' && _self.listeners("timeout").length > 0) {
        _self.emit("timeout", err);
      }

      connection.close();
      _self.stop();
    });

    // Parse error, needs a complete shutdown of the pool
    connection.on("parseError", function() {
      // If we are already disconnected ignore the event
      if(_self._poolState !== 'disconnected' && _self.listeners("parseError").length > 0) {
        _self.emit("parseError", new Error("parseError occured"));
      }

      _self.stop();
    });

    connection.on("message", function(message) {
      _self.emit("message", message);
    });

    // Start connection in the next tick
    connection.start();
  }();
}

// Start method, will throw error if no listeners are available
// Pass in an instance of the listener that contains the api for
// finding callbacks for a given message etc.
ConnectionPool.prototype.start = function() {
  var markerDate = new Date().getTime();
  var self = this;

  if(this.listeners("poolReady").length == 0) {
    throw "pool must have at least one listener ready that responds to the [poolReady] event";
  }

  // Set pool state to connecting
  this._poolState = 'connecting';
  this._timeout = false;

  _connect(self);
}

// Restart a connection pool (on a close the pool might be in a wrong state)
ConnectionPool.prototype.restart = function() {
  // Close all connections
  this.stop(false);
  // Now restart the pool
  this.start();
}

// Stop the connections in the pool
ConnectionPool.prototype.stop = function(removeListeners) {
  removeListeners = removeListeners == null ? true : removeListeners;
  // Set disconnected
  this._poolState = 'disconnected';

  // Clear all listeners if specified
  if(removeListeners) {
    this.removeAllEventListeners();
  }

  // Close all connections
  for(var i = 0; i < this.openConnections.length; i++) {
    this.openConnections[i].close();
  }

  // Clean up
  this.openConnections = [];
}

// Check the status of the connection
ConnectionPool.prototype.isConnected = function() {
  return this._poolState === 'connected';
}

// Checkout a connection from the pool for usage, or grab a specific pool instance
ConnectionPool.prototype.checkoutConnection = function(id) {
  var index = (this.currentConnectionIndex++ % (this.openConnections.length));
  var connection = this.openConnections[index];
  return connection;
}

ConnectionPool.prototype.getAllConnections = function() {
  return this.openConnections;
}

// Remove all non-needed event listeners
ConnectionPool.prototype.removeAllEventListeners = function() {
  this.removeAllListeners("close");
  this.removeAllListeners("error");
  this.removeAllListeners("timeout");
  this.removeAllListeners("connect");
  this.removeAllListeners("end");
  this.removeAllListeners("parseError");
  this.removeAllListeners("message");
  this.removeAllListeners("poolReady");
}

<|endoftext|>