<commit_before>/*
 *	Run this test with mocha:
 *	http://visionmedia.github.io/mocha/
 */

var assert = require('assert');
var https = require('https');
var http = require('http');
var path = require('path');
var net = require('net');
var tls = require('tls');

describe('Proxy', function(){
	'use strict';

	var self = this;

	before(function(done){
		self.options = {
			port: 8000,
			host: '127.0.0.1',
			testServerPort: 8080
		};

		self.Proxy = require(path.join(path.dirname(module.filename), '..', 'lib', 'Proxy.js'));
		done();
	});

	after(function(done){
		self.proxy.stop(done);
	});

	it('should exist', function(){
		assert.ok(self.Proxy);
	});

	it('should initialize', function(){
		self.proxy = new self.Proxy(self.options);
		assert.ok(self.proxy);
	});

	it('should start', function(done){
		self.proxy.start(done);
	});

	it('should stop', function(done){
		self.proxy.stop(done);
	});

	it('should start again', function(done){
		self.proxy.start(done);
	});

	it('should stop again', function(done){
		self.proxy.stop(done);
	});

	describe('HTTP', function(){
		before(function(done){
			var init = self.proxy.whenAllDone.bind(self, {todo: 2}, done);
			self.proxy.start(init);

			self.content = "HELLO WORLD!\n";
			self.server = false;
			self.server = http.createServer(function(request, response){
				response.writeHead(200, {
					'Content-Type': 'text/plain',
					'Content-Length': self.content.length
				});
				response.write(self.content);
				response.end();
			});
			self.server.listen(self.options.testServerPort, self.options.host, 511, function(){
				init();
			});
		});

		after(function(done){
			var cleanup = self.proxy.whenAllDone.bind(self, {todo: 2}, done);

			self.server.close(cleanup);
			self.proxy.stop(cleanup);
		});

		it('should get correct answer from server', function(done){
			this.timeout(2000);
			self.target = {
				hostname: self.options.host,
				port: self.options.httpPort,
				path: '/hello',
				headers: {
					'Host': self.options.host+':'+self.options.testServerPort,
					'Content-Type': 'text/plain; charset=utf8'
				},
				agent: false
			};
			var request = http.request(self.target, function(response){
				var downloaded = '';
				response.on('data', function(data){
					downloaded += data;
				});
				response.on('end', function(){
					assert.strictEqual(downloaded, self.content);
					done();
				});
			});
			request.end();
		});
	});

	describe('HTTPS', function(){
		before(function(done){
			var init = self.proxy.whenAllDone.bind(self, {todo: 2}, done);
			self.proxy.start(init);

			self.content = "HELLO WORLD!\n";
			self.server = false;
			self.server = https.createServer(self.options, function(request, response){
				response.writeHead(200, {
					'Content-Type': 'text/plain',
					'Content-Length': self.content.length
				});
				response.write(self.content);
				response.end();
			});
			self.server.listen(self.options.testServerPort, self.options.host, 511, init);
		});

		after(function(done){
			var cleanup = self.proxy.whenAllDone.bind(self, {todo: 2}, done);

			self.server.close(cleanup);
			self.proxy.stop(cleanup);
		});

		it('should get correct answer from server through HTTPS proxy', function(done){
			this.timeout(2000);

			self.target = {
				hostname: self.options.host,
				port: self.options.httpsPort,
				path: '/hello',
				headers: {
					'Host': self.options.host+':'+self.options.testServerPort,
					'Content-Type': 'text/plain; charset=utf8'
				},
				agent: false
			};
			var request = https.request(self.target, function(response){
				var downloaded = '';
				response.on('data', function(data){
					downloaded += data;
				});
				response.on('end', function(){
					assert.strictEqual(downloaded, self.content);
					done();
				});
			});
			request.end();
		});

		it('should get correct answer from server through HTTPS tunnel on HTTP proxy', function(done){
			this.timeout(2000);

			// Based on: https://github.com/joyent/node/issues/2474#issuecomment-3481078
			var tunnel = http.request({ // establishing a tunnel
				host: self.options.host,
				port: self.options.httpPort,
				method: 'CONNECT',
				agent: false,
				path: self.options.host+':'+self.options.testServerPort
			}).on('connect', function(res, socket, head) {
				self.target = {
					hostname: self.options.host,
					socket: socket,
					path: '/hello',
					headers: {
						'Host': self.options.host+':'+self.options.testServerPort,
						'Content-Type': 'text/plain; charset=utf8'
					},
					agent: false
				};
				https.request(self.target, function(response){
					var downloaded = '';
					response.on('data', function(data){
						downloaded += data;
					});
					response.on('end', function(){
						assert.strictEqual(downloaded, self.content);
						done();
					});
				}).end();
			}).end();
		});
	});

	describe('HTTP through another proxy', function(){
		var proxy2;
		var options2 = {
			port: 8005,
			host: '127.0.0.1'
		};

		before(function(done){
			var init = self.proxy.whenAllDone.bind(self, {todo: 3}, done);
			self.proxy.start(init);

			proxy2 = new self.Proxy(options2);
			proxy2.start(init);

			self.content = "HELLO WORLD!\n";
			self.server = false;
			self.server = http.createServer(function(request, response){
				response.writeHead(200, {
					'Content-Type': 'text/plain',
					'Content-Length': self.content.length
				});
				response.write(self.content);
				response.end();
			});
			self.server.listen(self.options.testServerPort, self.options.host, 511, function(){
				init();
			});
		});

		after(function(done){
			var cleanup = self.proxy.whenAllDone.bind(self, {todo: 3}, done);

			proxy2.stop(cleanup);
			self.proxy.stop(cleanup);
			self.server.close(cleanup);
		});

		it('should get correct answer from server', function(done){
			this.timeout(2000);

			options2.proxy = {
				hostname: self.options.host,
				port: self.options.port
			};

			self.target = {
				hostname: options2.host,
				port: options2.httpPort,
				path: 'http://' + self.options.host + ':' + self.options.testServerPort + '/hello',
				headers: {
					'Host': self.options.host+':'+self.options.testServerPort,
					'Content-Type': 'text/plain; charset=utf8'
				},
				agent: false
			};
			var request = http.request(self.target, function(response){
				var downloaded = '';
				response.on('data', function(data){
					downloaded += data;
				});
				response.on('end', function(){
					assert.strictEqual(downloaded, self.content);
					done();
				});
			}).end();
		});
	});

	describe('HTTPS through another proxy', function(){
		var proxy2;
		var options2 = {
			port: 8005,
			host: '127.0.0.1'
		};

		before(function(done){
			var init = self.proxy.whenAllDone.bind(self, {todo: 3}, done);
			self.proxy.start(init);

			proxy2 = new self.Proxy(options2);
			proxy2.start(init);

			self.content = "HELLO WORLD!\n";
			self.server = false;
			self.server = https.createServer(self.options, function(request, response){
				response.writeHead(200, {
					'Content-Type': 'text/plain',
					'Content-Length': self.content.length
				});
				response.write(self.content);
				response.end();
			});
			self.server.listen(self.options.testServerPort, self.options.host, 511, init);
		});

		after(function(done){
			var cleanup = self.proxy.whenAllDone.bind(self, {todo: 3}, done);

			proxy2.stop(cleanup);
			self.server.close(cleanup);
			self.proxy.stop(cleanup);
		});

		it('should get correct answer from server', function(done){
			this.timeout(2000);

			options2.proxy = {
				hostname: self.options.host,
				port: self.options.httpPort
			};

			// Based on: https://github.com/joyent/node/issues/2474#issuecomment-3481078
			var tunnel = http.request({ // establishing a tunnel
				host: options2.host,
				port: options2.httpPort,
				method: 'CONNECT',
				agent: false,
				path: self.options.host+':'+self.options.testServerPort,
			}).on('connect', function(res, socket, head) {
				self.target = {
					hostname: self.options.host,
					socket: socket,
					path: '/hello',
					headers: {
						'Host': self.options.host+':'+self.options.testServerPort,
						'Content-Type': 'text/plain; charset=utf8'
					},
					agent: false
				};
				https.request(self.target, function(response){
					var downloaded = '';
					response.on('data', function(data){
						downloaded += data;
					});
					response.on('end', function(){
						assert.strictEqual(downloaded, self.content);
						done();
					});
				}).end();
			}).end();
		});
	});

	describe('Certificates', function(){
		before(function(done){
			self.options.useSNI = true;

			var init = self.proxy.whenAllDone.bind(self, {todo: 2}, done);
			self.proxy.start(init);

			self.content = "HELLO WORLD!\n";
			self.server = false;
			self.server = https.createServer(self.options, function(request, response){
				response.writeHead(200, {
					'Content-Type': 'text/plain',
					'Content-Length': self.content.length
				});
				response.write(self.content);
				response.end();
			});
			self.server.listen(self.options.testServerPort, self.options.host, 511, init);
		});

		after(function(done){
			var cleanup = self.proxy.whenAllDone.bind(self, {todo: 2}, done);

			self.server.close(cleanup);
			self.proxy.stop(cleanup);

			self.options.useSNI = false;
		});

		it('should get correct answer from server', function(done){
			this.timeout(2000);

			// Based on: https://github.com/joyent/node/issues/2474#issuecomment-3481078
			var tunnel = http.request({ // establishing a tunnel
				host: self.options.host,
				port: self.options.httpPort,
				headers: {
					'Host': 'example.com'
				},
				method: 'CONNECT',
				agent: false,
				path: self.options.host+':'+self.options.testServerPort
			}).on('connect', function(res, socket, head) {
				var ssocket = tls.connect(0, {socket: socket}, function(){
					var cert = ssocket.getPeerCertificate();
					assert.strictEqual(cert.subject.O, 'hyperProxy');
					assert.strictEqual(cert.subject.CN, 'example.com');

					ssocket.write('GET / HTTP/1.1\r\n' +
						'Host: '+self.options.host+':'+self.options.testServerPort+'\r\n' +
						'Connection: close\r\n' +
						'\r\n');
				});
				ssocket.on('data', function(data){});
				ssocket.on('end', done);
			}).end();
		});
	});
});<commit_msg>Added another failing test for SNI certificates.<commit_after>/*
 *	Run this test with mocha:
 *	http://visionmedia.github.io/mocha/
 */

var assert = require('assert');
var https = require('https');
var http = require('http');
var path = require('path');
var net = require('net');
var tls = require('tls');

describe('Proxy', function(){
	'use strict';

	var self = this;

	before(function(done){
		self.options = {
			port: 8000,
			host: '127.0.0.1',
			testServerPort: 8080
		};

		self.Proxy = require(path.join(path.dirname(module.filename), '..', 'lib', 'Proxy.js'));
		done();
	});

	after(function(done){
		self.proxy.stop(done);
	});

	it('should exist', function(){
		assert.ok(self.Proxy);
	});

	it('should initialize', function(){
		self.proxy = new self.Proxy(self.options);
		assert.ok(self.proxy);
	});

	it('should start', function(done){
		self.proxy.start(done);
	});

	it('should stop', function(done){
		self.proxy.stop(done);
	});

	it('should start again', function(done){
		self.proxy.start(done);
	});

	it('should stop again', function(done){
		self.proxy.stop(done);
	});

	describe('HTTP', function(){
		before(function(done){
			var init = self.proxy.whenAllDone.bind(self, {todo: 2}, done);
			self.proxy.start(init);

			self.content = "HELLO WORLD!\n";
			self.server = false;
			self.server = http.createServer(function(request, response){
				response.writeHead(200, {
					'Content-Type': 'text/plain',
					'Content-Length': self.content.length
				});
				response.write(self.content);
				response.end();
			});
			self.server.listen(self.options.testServerPort, self.options.host, 511, function(){
				init();
			});
		});

		after(function(done){
			var cleanup = self.proxy.whenAllDone.bind(self, {todo: 2}, done);

			self.server.close(cleanup);
			self.proxy.stop(cleanup);
		});

		it('should get correct answer from server', function(done){
			this.timeout(2000);
			self.target = {
				hostname: self.options.host,
				port: self.options.httpPort,
				path: '/hello',
				headers: {
					'Host': self.options.host+':'+self.options.testServerPort,
					'Content-Type': 'text/plain; charset=utf8'
				},
				agent: false
			};
			var request = http.request(self.target, function(response){
				var downloaded = '';
				response.on('data', function(data){
					downloaded += data;
				});
				response.on('end', function(){
					assert.strictEqual(downloaded, self.content);
					done();
				});
			});
			request.end();
		});
	});

	describe('HTTPS', function(){
		before(function(done){
			var init = self.proxy.whenAllDone.bind(self, {todo: 2}, done);
			self.proxy.start(init);

			self.content = "HELLO WORLD!\n";
			self.server = false;
			self.server = https.createServer(self.options, function(request, response){
				response.writeHead(200, {
					'Content-Type': 'text/plain',
					'Content-Length': self.content.length
				});
				response.write(self.content);
				response.end();
			});
			self.server.listen(self.options.testServerPort, self.options.host, 511, init);
		});

		after(function(done){
			var cleanup = self.proxy.whenAllDone.bind(self, {todo: 2}, done);

			self.server.close(cleanup);
			self.proxy.stop(cleanup);
		});

		it('should get correct answer from server through HTTPS proxy', function(done){
			this.timeout(2000);

			self.target = {
				hostname: self.options.host,
				port: self.options.httpsPort,
				path: '/hello',
				headers: {
					'Host': self.options.host+':'+self.options.testServerPort,
					'Content-Type': 'text/plain; charset=utf8'
				},
				agent: false
			};
			var request = https.request(self.target, function(response){
				var downloaded = '';
				response.on('data', function(data){
					downloaded += data;
				});
				response.on('end', function(){
					assert.strictEqual(downloaded, self.content);
					done();
				});
			});
			request.end();
		});

		it('should get correct answer from server through HTTPS tunnel on HTTP proxy', function(done){
			this.timeout(2000);

			// Based on: https://github.com/joyent/node/issues/2474#issuecomment-3481078
			var tunnel = http.request({ // establishing a tunnel
				host: self.options.host,
				port: self.options.httpPort,
				method: 'CONNECT',
				agent: false,
				path: self.options.host+':'+self.options.testServerPort
			}).on('connect', function(res, socket, head) {
				self.target = {
					hostname: self.options.host,
					socket: socket,
					path: '/hello',
					headers: {
						'Host': self.options.host+':'+self.options.testServerPort,
						'Content-Type': 'text/plain; charset=utf8'
					},
					agent: false
				};
				https.request(self.target, function(response){
					var downloaded = '';
					response.on('data', function(data){
						downloaded += data;
					});
					response.on('end', function(){
						assert.strictEqual(downloaded, self.content);
						done();
					});
				}).end();
			}).end();
		});
	});

	describe('HTTP through another proxy', function(){
		var proxy2;
		var options2 = {
			port: 8005,
			host: '127.0.0.1'
		};

		before(function(done){
			var init = self.proxy.whenAllDone.bind(self, {todo: 3}, done);
			self.proxy.start(init);

			proxy2 = new self.Proxy(options2);
			proxy2.start(init);

			self.content = "HELLO WORLD!\n";
			self.server = false;
			self.server = http.createServer(function(request, response){
				response.writeHead(200, {
					'Content-Type': 'text/plain',
					'Content-Length': self.content.length
				});
				response.write(self.content);
				response.end();
			});
			self.server.listen(self.options.testServerPort, self.options.host, 511, function(){
				init();
			});
		});

		after(function(done){
			var cleanup = self.proxy.whenAllDone.bind(self, {todo: 3}, done);

			proxy2.stop(cleanup);
			self.proxy.stop(cleanup);
			self.server.close(cleanup);
		});

		it('should get correct answer from server', function(done){
			this.timeout(2000);

			options2.proxy = {
				hostname: self.options.host,
				port: self.options.port
			};

			self.target = {
				hostname: options2.host,
				port: options2.httpPort,
				path: 'http://' + self.options.host + ':' + self.options.testServerPort + '/hello',
				headers: {
					'Host': self.options.host+':'+self.options.testServerPort,
					'Content-Type': 'text/plain; charset=utf8'
				},
				agent: false
			};
			var request = http.request(self.target, function(response){
				var downloaded = '';
				response.on('data', function(data){
					downloaded += data;
				});
				response.on('end', function(){
					assert.strictEqual(downloaded, self.content);
					done();
				});
			}).end();
		});
	});

	describe('HTTPS through another proxy', function(){
		var proxy2;
		var options2 = {
			port: 8005,
			host: '127.0.0.1'
		};

		before(function(done){
			var init = self.proxy.whenAllDone.bind(self, {todo: 3}, done);
			self.proxy.start(init);

			proxy2 = new self.Proxy(options2);
			proxy2.start(init);

			self.content = "HELLO WORLD!\n";
			self.server = false;
			self.server = https.createServer(self.options, function(request, response){
				response.writeHead(200, {
					'Content-Type': 'text/plain',
					'Content-Length': self.content.length
				});
				response.write(self.content);
				response.end();
			});
			self.server.listen(self.options.testServerPort, self.options.host, 511, init);
		});

		after(function(done){
			var cleanup = self.proxy.whenAllDone.bind(self, {todo: 3}, done);

			proxy2.stop(cleanup);
			self.server.close(cleanup);
			self.proxy.stop(cleanup);
		});

		it('should get correct answer from server', function(done){
			this.timeout(2000);

			options2.proxy = {
				hostname: self.options.host,
				port: self.options.httpPort
			};

			// Based on: https://github.com/joyent/node/issues/2474#issuecomment-3481078
			var tunnel = http.request({ // establishing a tunnel
				host: options2.host,
				port: options2.httpPort,
				method: 'CONNECT',
				agent: false,
				path: self.options.host+':'+self.options.testServerPort,
			}).on('connect', function(res, socket, head) {
				self.target = {
					hostname: self.options.host,
					socket: socket,
					path: '/hello',
					headers: {
						'Host': self.options.host+':'+self.options.testServerPort,
						'Content-Type': 'text/plain; charset=utf8'
					},
					agent: false
				};
				https.request(self.target, function(response){
					var downloaded = '';
					response.on('data', function(data){
						downloaded += data;
					});
					response.on('end', function(){
						assert.strictEqual(downloaded, self.content);
						done();
					});
				}).end();
			}).end();
		});
	});

	describe.skip('Certificates', function(){
		before(function(done){
			self.options.useSNI = true;

			var init = self.proxy.whenAllDone.bind(self, {todo: 2}, done);
			self.proxy.start(init);

			self.content = "HELLO WORLD!\n";
			self.server = false;
			self.server = https.createServer(self.options, function(request, response){
				response.writeHead(200, {
					'Content-Type': 'text/plain',
					'Content-Length': self.content.length
				});
				response.write(self.content);
				response.end();
			});
			self.server.listen(self.options.testServerPort, self.options.host, 511, init);
		});

		after(function(done){
			var cleanup = self.proxy.whenAllDone.bind(self, {todo: 2}, done);

			self.server.close(cleanup);
			self.proxy.stop(cleanup);

			self.options.useSNI = false;
		});

		it('should get correct answer from server', function(done){
			this.timeout(2000);

			// Based on: https://github.com/joyent/node/issues/2474#issuecomment-3481078
			var tunnel = http.request({ // establishing a tunnel
				host: self.options.host,
				port: self.options.httpPort,
				headers: {
					'Host': 'example.com'
				},
				method: 'CONNECT',
				agent: false,
				path: self.options.host+':'+self.options.testServerPort
			}).on('connect', function(res, socket, head) {
				var ssocket = tls.connect(0, {socket: socket}, function(){
					ssocket.write('GET / HTTP/1.1\r\n' +
						'Host: '+self.options.host+':'+self.options.testServerPort+'\r\n' +
						'Connection: close\r\n' +
						'\r\n');
					var cert = ssocket.getPeerCertificate();
					assert.strictEqual(cert.subject.O, 'hyperProxy');
					assert.strictEqual(cert.subject.CN, 'example.com');
				});
				ssocket.on('data', function(data){});
				ssocket.on('end', done);
			}).end();
		});

		it('should get correct answer from server - part 2', function(done){
			this.timeout(2000);

			https.request({hostname: self.options.host, port: self.options.httpsPort, headers: {host: 'example.com'}, path: 'https://'+self.options.host+':'+self.options.testServerPort+'/hello'}, function(res){
				res.on('data', function(data){});
				res.on('end', function(){
					var cert = res.connection.getPeerCertificate();
					assert.strictEqual(cert.subject.O, 'hyperProxy');
					assert.strictEqual(cert.subject.CN, 'example.com');
				});

			}).end();
		});
	});
});<|endoftext|>


<commit_before>var assert = require('chai').assert;
var nodemock = require('nodemock');
var net = require('net');
var msgpack = require('msgpack');
var http = require('http');
var Deferred = require('jsdeferred').Deferred;
var client = require('socket.io-client');
var express = require('express');

var FluentReceiver = require('../lib/backend/receiver').FluentReceiver;
exports.FluentReceiver = FluentReceiver;

var Connection = require('../lib/backend/connection').Connection;

var testSendPort = exports.testSendPort = 3333;
var testReceivePort = exports.testReceivePort = 3334;
var testServerPort = exports.testServerPort = 3335;

function connectTo(port) {
  var deferred = new Deferred();
  var clientSocket = new net.Socket();
  clientSocket.on('error', function(error){
    clientSocket.destroy();
    deferred.fail(error);
  });
  clientSocket.connect(port, 'localhost', function(){
    deferred.call(clientSocket);
  });
  return deferred;
}
exports.connectTo = connectTo;
Deferred.register('connectTo', connectTo);

function sendPacketTo(packet, port) {
  var clientSocket;
  return connectTo(port)
    .next(function(newSocket) {
      clientSocket = newSocket;
      var packedPacket = msgpack.pack(packet);
      clientSocket.write(new Buffer(packedPacket));
    })
    .wait(0.01)
    .next(function() {
      clientSocket.destroy();
      clientSocket = undefined;
    })
    .error(function(error) {
      if (clientSocket) {
        clientSocket.destroy();
        clientSocket = undefined;
      }
      throw error;
    });
}
exports.sendPacketTo = sendPacketTo;
Deferred.register('sendPacketTo', sendPacketTo);

function setupServer(handlerOrServer) {
  var deferred = new Deferred();
  var server;
  if ('close' in handlerOrServer) { // it is a server
    server = handlerOrServer;
  } else { // it is a handler
    server = http.createServer(handlerOrServer);
  }
  server.listen(testServerPort, function() {
    deferred.call(server);
  });
  return deferred;
}
exports.setupServer = setupServer;
Deferred.register('setupServer', setupServer);

function sendRequest(method, path, postData, headers) {
  var deferred = new Deferred();

  var options = {
        host: 'localhost',
        port: testServerPort,
        path: path,
        method: method,
        headers: {}
      };

  if (headers) {
    for (var header in headers) {
      if (headers.hasOwnProperty(header))
        options.headers[header] = headers[header];
    }
  }

  Deferred.next(function() {
    var request = http.request(options, function(response) {
          var body = '';
          response.on('data', function(data) {
            body += data;
          });
          response.on('end', function() {
            deferred.call({
              statusCode: response.statusCode,
              body: body
            });
          });
        });
    request.on('error', function(error) {
      deferred.fail(error);
    });

    if (postData) request.write(postData);
    request.end();
  });

  return deferred;
}

function get(path, headers) {
  return sendRequest('GET', path, null, headers);
}
exports.get = get;
Deferred.register('get', function() { return get.apply(this, arguments); });

function post(path, body, headers) {
  return sendRequest('POST', path, body, headers);
}
exports.post = post;
Deferred.register('post', function() { return post.apply(this, arguments); });

function createClientSocket() {
  var deferred = new Deferred();
  var host = 'http://localhost:' + testServerPort;
  var options = { 'force new connection': true };
  var socket = client.connect(host, options);
  socket.on('connect', function() {
    deferred.call(socket);
  });
  return deferred;
}
exports.createClientSocket = createClientSocket;
Deferred.register('createClientSocket', createClientSocket);

function createClientSockets(count) {
  var sockets = [];
  return Deferred.next(function loop() {
    if (sockets.length < count) {
      return createClientSocket()
               .next(function(newSocket) {
                 sockets.push(newSocket);
               })
               .next(loop);
    } else {
      return sockets;
    }
  });
}
exports.createClientSockets = createClientSockets;
Deferred.register('createClientSockets', createClientSockets);

function createStubbedBackendConnection() {
  return {
    emitMessage: function(type, message, callback, options) {
      this.emitMessageCalledArguments.push({
        type:     type,
        message:  message,
        callback: callback,
        options:  options
      });
    },
    emitMessageCalledArguments: [],

    emit: function() {},
    on: function() {},
    removeListener: function() {},
    removeAllListeners: function() {},
    close: function() {}
  };
}
exports.createStubbedBackendConnection = createStubbedBackendConnection;

function setupApplication() {
  var application = express();
  var server;
  var backend;
  return setupServer(application)
    .next(function(newServer) {
      server = newServer;
    })
    .createBackend()
    .next(function(newBackend) {
      backend = newBackend;
      var connection = new Connection({
        tag:      'test',
        hostName: 'localhost',
        port:     testSendPort,
        receivePort: testReceivePort,
        maxRetyrCount: 3,
        retryDelay: 1
      });
      return {
        backend:     backend,
        server:      server,
        application: application,
        connection:  connection
      };
    });
}
exports.setupApplication = setupApplication;
Deferred.register('setupApplication', setupApplication);

function teardownApplication(params) {
  params = params || {};
  if (params.backend) {
    params.backend.close();
    params.backend = undefined;
  }
  if (params.connection) {
    params.connection.close();
    params.connection = undefined;
  }
  if (params.server) {
    params.server.close();
    params.server = undefined;
  }
}
exports.teardownApplication = teardownApplication;
Deferred.register('teardownApplication', teardownApplication);

function readyToDestroyMockedConnection(connection, clientCount) {
  connection = connection
    .mock('removeListener')
      .takes('error', function() {});
  if (clientCount)
    connection = connection.times(clientCount);
  return connection;
}
exports.readyToDestroyMockedConnection = readyToDestroyMockedConnection;

function createBackend() {
  var deferred = new Deferred();
  var backend = new FluentReceiver(testSendPort);

  backend.received = [];
  backend.on('receive', function(data) {
    backend.received.push(data);
    if (backend.reservedResponses.length > 0) {
      var response = backend.reservedResponses.shift();
      if (typeof response == 'function')
        response = response(data);
      sendPacketTo(response, testReceivePort);
    }
  });

  backend.reservedResponses = [];
  backend.reserveResponse = function(response) {
    backend.reservedResponses.push(response);
  };

  backend.assertReceived = function(expectedMessages) {
    assert.deepEqual(this.getMessages().map(function(message) {
                       return { type: message.type,
                                body: message.body };
                     }),
                     expectedMessages);
  };

  backend.getMessages = function() {
    return this.received.map(function(packet) {
      return packet[2];
    });
  };
  backend.getEvents = function() {
    return this.getMessages().map(function(envelope) {
      return envelope.type;
    });
  };
  backend.getBodies = function() {
    return this.getMessages().map(function(envelope) {
      return envelope.body;
    });
  };

  backend.sendMessage = function(type, body) {
    var response = createEnvelope(type, body);
    return sendPacketTo(createPacket(response), testReceivePort)
  };
  backend.sendResponse = function(request, type, body) {
    var response = createReplyEnvelope(request, type, body);
    return sendPacketTo(createPacket(response), testReceivePort)
  };

  backend.listen(function() {
    return deferred.call(backend);
  });

  return deferred;
}
exports.createBackend = createBackend;
Deferred.register('createBackend', createBackend);

function createEnvelope(type, body) {
  var now = new Date();
  var envelope = {
    id:         now.getTime(),
    date:       now.toISOString(),
    replyTo:    'localhost:' + testReceivePort,
    statusCode: 200,
    type:       type,
    body:       body
  };
  return envelope;
}
exports.createEnvelope = createEnvelope;

function createExpectedEnvelope(type, body) {
  var envelope = createEnvelope(type, body);
  envelope.id = TypeOf('string');
  envelope.date = InstanceOf(Date);
  return envelope;
}
exports.createExpectedEnvelope = createExpectedEnvelope;

function createReplyEnvelope(message, type, body) {
  var response = createEnvelope(type, body);
  response.inReplyTo = message.id;
  return response;
}
exports.createReplyEnvelope = createReplyEnvelope;

function createPacket(message, tag) {
  tag = tag || 'test.message';
  return [tag, Date.now(), message];
}
exports.createPacket = createPacket;

function TypeOf(typeString) {
  if (!(this instanceof TypeOf))
    return new TypeOf(typeString);

  this.typeString = typeString;
  if (typeString == 'date') {
    return new InstanceOf(Date);
  }
}
exports.TypeOf = TypeOf;

function InstanceOf(constructor) {
  if (!(this instanceof InstanceOf))
    return new InstanceOf(constructor);

  this.constructorFunction = constructor;
}
exports.InstanceOf = InstanceOf;

function assertEnvelopeEqual(actual, expected) {
  var vs = JSON.stringify(actual) + ' vs ' + JSON.stringify(expected);
  Object.keys(expected).forEach(function(key) {
    var actualValue = actual[key];
    var expectedValue = expected[key];
    if (expectedValue instanceof InstanceOf) {
      if (typeof actualValue == 'string') {
        // Try fo parse the value and create new instance.
        // If this process is failed, it can be an invalid value.
        actualValue = new expectedValue.constructorFunction(actualValue);
      }
      assert.instanceOf(actualValue,
                        expectedValue.constructorFunction,
                        key + ' / ' + vs);
    } else if (expectedValue instanceof TypeOf) {
      assert.typeOf(typeof actualValue,
                    expectedValue.typeString,
                    key + ' / ' + vs);
    } else {
      assert.deepEqual(actualValue, expectedValue, key + ' / ' + vs);
    }
  });
}
assert.envelopeEqual = assertEnvelopeEqual;

function sortKeys(original) {
  if (!original || typeof original != 'object')
    return original;

  if (Array.isArray(original))
    return original.map(sortKeys);

  var sorted = {};
  Object.keys(original).sort().forEach(function(key) {
    sorted[key] = sortKeys(original[key]);
  });
  return sorted;
}

// assert.deepEqual fails when the order of hash keys are different,
// even if they are "eaual" as JSON objects.
function assertEqualJSON(actual, expected) {
  this.deepEqual(sortKeys(actual), sortKeys(expected));
}
assert.equalJSON = assertEqualJSON;

exports.outputAll = {
  startTime:   true,
  elapsedTime: true,
  count:       true,
  attributes:  true,
  recodes:     true
};
<commit_msg>test: Remove obsolete utility<commit_after>var assert = require('chai').assert;
var nodemock = require('nodemock');
var net = require('net');
var msgpack = require('msgpack');
var http = require('http');
var Deferred = require('jsdeferred').Deferred;
var client = require('socket.io-client');
var express = require('express');

var FluentReceiver = require('../lib/backend/receiver').FluentReceiver;
exports.FluentReceiver = FluentReceiver;

var Connection = require('../lib/backend/connection').Connection;

var testSendPort = exports.testSendPort = 3333;
var testReceivePort = exports.testReceivePort = 3334;
var testServerPort = exports.testServerPort = 3335;

function connectTo(port) {
  var deferred = new Deferred();
  var clientSocket = new net.Socket();
  clientSocket.on('error', function(error){
    clientSocket.destroy();
    deferred.fail(error);
  });
  clientSocket.connect(port, 'localhost', function(){
    deferred.call(clientSocket);
  });
  return deferred;
}
exports.connectTo = connectTo;
Deferred.register('connectTo', connectTo);

function sendPacketTo(packet, port) {
  var clientSocket;
  return connectTo(port)
    .next(function(newSocket) {
      clientSocket = newSocket;
      var packedPacket = msgpack.pack(packet);
      clientSocket.write(new Buffer(packedPacket));
    })
    .wait(0.01)
    .next(function() {
      clientSocket.destroy();
      clientSocket = undefined;
    })
    .error(function(error) {
      if (clientSocket) {
        clientSocket.destroy();
        clientSocket = undefined;
      }
      throw error;
    });
}
exports.sendPacketTo = sendPacketTo;
Deferred.register('sendPacketTo', sendPacketTo);

function setupServer(handlerOrServer) {
  var deferred = new Deferred();
  var server;
  if ('close' in handlerOrServer) { // it is a server
    server = handlerOrServer;
  } else { // it is a handler
    server = http.createServer(handlerOrServer);
  }
  server.listen(testServerPort, function() {
    deferred.call(server);
  });
  return deferred;
}
exports.setupServer = setupServer;
Deferred.register('setupServer', setupServer);

function sendRequest(method, path, postData, headers) {
  var deferred = new Deferred();

  var options = {
        host: 'localhost',
        port: testServerPort,
        path: path,
        method: method,
        headers: {}
      };

  if (headers) {
    for (var header in headers) {
      if (headers.hasOwnProperty(header))
        options.headers[header] = headers[header];
    }
  }

  Deferred.next(function() {
    var request = http.request(options, function(response) {
          var body = '';
          response.on('data', function(data) {
            body += data;
          });
          response.on('end', function() {
            deferred.call({
              statusCode: response.statusCode,
              body: body
            });
          });
        });
    request.on('error', function(error) {
      deferred.fail(error);
    });

    if (postData) request.write(postData);
    request.end();
  });

  return deferred;
}

function get(path, headers) {
  return sendRequest('GET', path, null, headers);
}
exports.get = get;
Deferred.register('get', function() { return get.apply(this, arguments); });

function post(path, body, headers) {
  return sendRequest('POST', path, body, headers);
}
exports.post = post;
Deferred.register('post', function() { return post.apply(this, arguments); });

function createClientSocket() {
  var deferred = new Deferred();
  var host = 'http://localhost:' + testServerPort;
  var options = { 'force new connection': true };
  var socket = client.connect(host, options);
  socket.on('connect', function() {
    deferred.call(socket);
  });
  return deferred;
}
exports.createClientSocket = createClientSocket;
Deferred.register('createClientSocket', createClientSocket);

function createClientSockets(count) {
  var sockets = [];
  return Deferred.next(function loop() {
    if (sockets.length < count) {
      return createClientSocket()
               .next(function(newSocket) {
                 sockets.push(newSocket);
               })
               .next(loop);
    } else {
      return sockets;
    }
  });
}
exports.createClientSockets = createClientSockets;
Deferred.register('createClientSockets', createClientSockets);

function createStubbedBackendConnection() {
  return {
    emitMessage: function(type, message, callback, options) {
      this.emitMessageCalledArguments.push({
        type:     type,
        message:  message,
        callback: callback,
        options:  options
      });
    },
    emitMessageCalledArguments: [],

    emit: function() {},
    on: function() {},
    removeListener: function() {},
    removeAllListeners: function() {},
    close: function() {}
  };
}
exports.createStubbedBackendConnection = createStubbedBackendConnection;

function setupApplication() {
  var application = express();
  var server;
  var backend;
  return setupServer(application)
    .next(function(newServer) {
      server = newServer;
    })
    .createBackend()
    .next(function(newBackend) {
      backend = newBackend;
      var connection = new Connection({
        tag:      'test',
        hostName: 'localhost',
        port:     testSendPort,
        receivePort: testReceivePort,
        maxRetyrCount: 3,
        retryDelay: 1
      });
      return {
        backend:     backend,
        server:      server,
        application: application,
        connection:  connection
      };
    });
}
exports.setupApplication = setupApplication;
Deferred.register('setupApplication', setupApplication);

function teardownApplication(params) {
  params = params || {};
  if (params.backend) {
    params.backend.close();
    params.backend = undefined;
  }
  if (params.connection) {
    params.connection.close();
    params.connection = undefined;
  }
  if (params.server) {
    params.server.close();
    params.server = undefined;
  }
}
exports.teardownApplication = teardownApplication;
Deferred.register('teardownApplication', teardownApplication);

function createBackend() {
  var deferred = new Deferred();
  var backend = new FluentReceiver(testSendPort);

  backend.received = [];
  backend.on('receive', function(data) {
    backend.received.push(data);
    if (backend.reservedResponses.length > 0) {
      var response = backend.reservedResponses.shift();
      if (typeof response == 'function')
        response = response(data);
      sendPacketTo(response, testReceivePort);
    }
  });

  backend.reservedResponses = [];
  backend.reserveResponse = function(response) {
    backend.reservedResponses.push(response);
  };

  backend.assertReceived = function(expectedMessages) {
    assert.deepEqual(this.getMessages().map(function(message) {
                       return { type: message.type,
                                body: message.body };
                     }),
                     expectedMessages);
  };

  backend.getMessages = function() {
    return this.received.map(function(packet) {
      return packet[2];
    });
  };
  backend.getEvents = function() {
    return this.getMessages().map(function(envelope) {
      return envelope.type;
    });
  };
  backend.getBodies = function() {
    return this.getMessages().map(function(envelope) {
      return envelope.body;
    });
  };

  backend.sendMessage = function(type, body) {
    var response = createEnvelope(type, body);
    return sendPacketTo(createPacket(response), testReceivePort)
  };
  backend.sendResponse = function(request, type, body) {
    var response = createReplyEnvelope(request, type, body);
    return sendPacketTo(createPacket(response), testReceivePort)
  };

  backend.listen(function() {
    return deferred.call(backend);
  });

  return deferred;
}
exports.createBackend = createBackend;
Deferred.register('createBackend', createBackend);

function createEnvelope(type, body) {
  var now = new Date();
  var envelope = {
    id:         now.getTime(),
    date:       now.toISOString(),
    replyTo:    'localhost:' + testReceivePort,
    statusCode: 200,
    type:       type,
    body:       body
  };
  return envelope;
}
exports.createEnvelope = createEnvelope;

function createExpectedEnvelope(type, body) {
  var envelope = createEnvelope(type, body);
  envelope.id = TypeOf('string');
  envelope.date = InstanceOf(Date);
  return envelope;
}
exports.createExpectedEnvelope = createExpectedEnvelope;

function createReplyEnvelope(message, type, body) {
  var response = createEnvelope(type, body);
  response.inReplyTo = message.id;
  return response;
}
exports.createReplyEnvelope = createReplyEnvelope;

function createPacket(message, tag) {
  tag = tag || 'test.message';
  return [tag, Date.now(), message];
}
exports.createPacket = createPacket;

function TypeOf(typeString) {
  if (!(this instanceof TypeOf))
    return new TypeOf(typeString);

  this.typeString = typeString;
  if (typeString == 'date') {
    return new InstanceOf(Date);
  }
}
exports.TypeOf = TypeOf;

function InstanceOf(constructor) {
  if (!(this instanceof InstanceOf))
    return new InstanceOf(constructor);

  this.constructorFunction = constructor;
}
exports.InstanceOf = InstanceOf;

function assertEnvelopeEqual(actual, expected) {
  var vs = JSON.stringify(actual) + ' vs ' + JSON.stringify(expected);
  Object.keys(expected).forEach(function(key) {
    var actualValue = actual[key];
    var expectedValue = expected[key];
    if (expectedValue instanceof InstanceOf) {
      if (typeof actualValue == 'string') {
        // Try fo parse the value and create new instance.
        // If this process is failed, it can be an invalid value.
        actualValue = new expectedValue.constructorFunction(actualValue);
      }
      assert.instanceOf(actualValue,
                        expectedValue.constructorFunction,
                        key + ' / ' + vs);
    } else if (expectedValue instanceof TypeOf) {
      assert.typeOf(typeof actualValue,
                    expectedValue.typeString,
                    key + ' / ' + vs);
    } else {
      assert.deepEqual(actualValue, expectedValue, key + ' / ' + vs);
    }
  });
}
assert.envelopeEqual = assertEnvelopeEqual;

function sortKeys(original) {
  if (!original || typeof original != 'object')
    return original;

  if (Array.isArray(original))
    return original.map(sortKeys);

  var sorted = {};
  Object.keys(original).sort().forEach(function(key) {
    sorted[key] = sortKeys(original[key]);
  });
  return sorted;
}

// assert.deepEqual fails when the order of hash keys are different,
// even if they are "eaual" as JSON objects.
function assertEqualJSON(actual, expected) {
  this.deepEqual(sortKeys(actual), sortKeys(expected));
}
assert.equalJSON = assertEqualJSON;

exports.outputAll = {
  startTime:   true,
  elapsedTime: true,
  count:       true,
  attributes:  true,
  recodes:     true
};
<|endoftext|>


<commit_before>'use strict';

var Support   = require(__dirname + '/../support')
  , expectsql = Support.expectsql
  , current   = Support.sequelize
  , sql       = current.dialect.QueryGenerator
  , current = Support.sequelize;

// Notice: [] will be replaced by dialect specific tick/quote character when there is not dialect specific expectation but only a default expectation

suite(Support.getTestDialectTeaser('SQL'), function() {
  suite('removeColumn', function () {
    test('schema', function () {
      expectsql(sql.removeColumnQuery({
        schema: 'archive',
        tableName: 'user'
      }, 'email'), {
        default: "ALTER TABLE [archive].[user] DROP COLUMN [email];",
        mysql: "ALTER TABLE `archive.user` DROP `email`;"
      });
    });
  });
});<commit_msg>:style: singlequotes<commit_after>'use strict';

var Support   = require(__dirname + '/../support')
  , expectsql = Support.expectsql
  , current   = Support.sequelize
  , sql       = current.dialect.QueryGenerator;

// Notice: [] will be replaced by dialect specific tick/quote character when there is not dialect specific expectation but only a default expectation

suite(Support.getTestDialectTeaser('SQL'), function() {
  suite('removeColumn', function () {
    test('schema', function () {
      expectsql(sql.removeColumnQuery({
        schema: 'archive',
        tableName: 'user'
      }, 'email'), {
        default: 'ALTER TABLE [archive].[user] DROP COLUMN [email];',
        mysql: 'ALTER TABLE `archive.user` DROP `email`;'
      });
    });
  });
});<|endoftext|>


<commit_before>/* jshint newcap:false */
/// <reference path="../chance.js" />
/// <reference path="../node_modules/underscore/underscore-min.js" />

var expect = chai.expect;

describe("Basics", function () {
    var bool, integer, natural, floating, character, string, temp, chance = new Chance(),
        data, cData;

    describe("Data", function () {
        it("get data", function () {
            data = chance.get("lastNames");
            expect(data).to.be.an('object');
        });

        it("set custom data", function () {
            cData = {lastNames: ["customName", "testLast"]};
            chance.set(cData);
            data = chance.get("lastNames");
            expect(data).to.be.an('array');
            expect(data).to.have.length(2);
        });
    });

    describe("Bool", function () {
        it("returns a random boolean", function () {
            bool = chance.bool();
            expect(bool).to.be.a('boolean');
        });

        it("is within the bounds of what we'd call random", function () {
            var true_count = 0;
            _(1000).times(function () {
                bool = chance.bool();
                if (bool) {
                    true_count++;
                }
            });

            // The probability of this test failing is approximately 4.09e-86.
            // So, in theory, it could give a false negative, but the sun will
            // probably die long before that happens.
            //
            // See calculation here https://gist.github.com/BlaMaeda/cfd886f84dd093cb2ead
            expect(true_count).to.be.within(200, 800);
        });

        it("takes and obeys likelihood", function () {
            var true_count = 0;
            _(1000).times(function () {
                if (chance.bool({likelihood: 30})) {
                    true_count++;
                }
            });

            // Expect it to average around 300
            expect(true_count).to.be.within(200, 400);

            true_count = 0;
            _(1000).times(function () {
                if (chance.bool({likelihood: 99})) {
                    true_count++;
                }
            });

            // Expect it to average at 990
            expect(true_count).to.be.above(900);
        });

        it("throws an error if likelihood < 0 or > 100", function () {
            expect(function () { chance.bool({likelihood: -23}); }).to.throw(RangeError);
            expect(function () { chance.bool({likelihood: 7933}); }).to.throw(RangeError);
        });
    });

    describe("Integer", function () {
        it("returns a random integer", function () {
            integer = chance.integer();
            expect(integer).to.be.a('number');
        });

        it("is sometimes negative, sometimes positive", function () {
            var positive_count = 0;
            _(1000).times(function () {
                integer = chance.integer();
                if (integer > 0) {
                    positive_count++;
                }
            });

            // Note: In very extreme circumstances this test may fail as, by its
            // nature it's random. But it's a low enough percentage that I'm
            // willing to accept it.
            expect(positive_count).to.be.within(200, 800);
        });

        it("can take a zero min and obey it", function () {
            _(1000).times(function () {
                integer = chance.integer({min: 0});
                expect(integer).to.be.above(0);
            });
        });

        it("can take a negative min and obey it", function () {
            _(1000).times(function () {
                integer = chance.integer({min: -25});
                expect(integer).to.be.above(-26);
            });
        });

        it("can take a negative min and negative max and obey both", function () {
            _(1000).times(function () {
                integer = chance.integer({min: -25, max: -1});
                expect(integer).to.be.within(-26, 0);
            });
        });

        it("can take a min with absolute value less than the max and return in range above", function () {
            var count = 0;
            _(1000).times(function () {
                // With a range this large we'd expect most values to be
                // greater than 1 if this works correctly.
                integer = chance.integer({min: -1, max: 1000000});
                if (Math.abs(integer) < 2) {
                    count++;
                }
            });
            expect(count).to.not.be.above(900);
        });

        it("throws an error if min > max", function () {
            expect(function () { chance.natural({min: 1000, max: 500}); }).to.throw(RangeError);
        });
    });

    describe("Natural", function () {
        it("returns a random natural", function () {
            natural = chance.natural();
            expect(natural).to.be.a('number');
        });

        it("throws an error if min < 0", function () {
            expect(function () { chance.natural({min: -23}); }).to.throw(RangeError);
        });

        it("is always positive", function () {
            var positive_count = 0;
            _(1000).times(function () {
                natural = chance.natural();
                if (natural > 0) {
                    positive_count++;
                }
            });

            expect(positive_count).to.equal(1000);
        });

        it("can take just a min and obey it", function () {
            _(1000).times(function () {
                natural = chance.natural({min: 9007199254740991});
                expect(natural).to.be.above(9007199254740990);
            });
        });

        it("can take just a max and obey it", function () {
            _(1000).times(function () {
                natural = chance.natural({max: 100});
                expect(natural).to.be.below(101);
            });
        });

        it("can take both a max and min and obey them both", function () {
            _(1000).times(function () {
                natural = chance.natural({min: 90, max: 100});
                expect(natural).to.be.within(89, 101);
            });
        });

        it("works with both bounds 0", function () {
            _(1000).times(function () {
                natural = chance.natural({min: 0, max: 0});
                expect(natural).to.equal(0);
            });
        });

        it("throws an error if min > max", function () {
            expect(function () { chance.natural({min: 1000, max: 500}); }).to.throw(RangeError);
        });
    });

    describe("Floating", function () {
        it("returns a random floating", function () {
            floating = chance.floating();
            expect(floating).to.be.a('number');
        });

        it("can take both a max and min and obey them both", function () {
            _(1000).times(function () {
                floating = chance.floating({min: 90, max: 100});
                expect(floating).to.be.within(90, 100);
            });
        });

        it("won't take fixed + min that would be out of range", function () {
            expect(function () { chance.floating({fixed: 13, min: -9007199254740992}); }).to.throw(RangeError);
        });

        it("won't take fixed + max that would be out of range", function () {
            expect(function () { chance.floating({fixed: 13, max: 9007199254740992}); }).to.throw(RangeError);
        });

        it("obeys the fixed parameter, when present", function () {
            _(100).times(function () {
                floating = chance.floating({fixed: 4});
                floating = floating.toString().split('.')[1] ? floating.toString().split('.')[1] : '';
                expect(floating).to.have.length.below(5);
            });
        });

        it("can take fixed and obey it", function () {
            _(1000).times(function () {
                floating = chance.floating({fixed: 3});
                temp = parseFloat(floating.toFixed(3));
                expect(floating).to.equal(temp);
            });
        });

        it("won't take both fixed and precision", function () {
            expect(function () { chance.floating({fixed: 2, precision: 8}); }).to.throw(RangeError);
        });
    });

    describe("Character", function () {
        it("returns a character", function () {
            character = chance.character();
            expect(character).to.be.a('string');
            expect(character).to.have.length(1);
        });

        it("pulls only from pool, when specified", function () {
            var pool = 'abcde';
            _(1000).times(function () {
                character = chance.character({pool: pool});
                expect(character).to.match(/[abcde]/);
            });
        });

        it("allows only alpha", function () {
            _(1000).times(function () {
                character = chance.character({alpha: true});
                expect(character).to.match(/[a-zA-Z]/);
            });

            expect(function () { chance.character({alpha: true, symbols: true}); }).to.throw(RangeError);
        });

        it("obeys case", function () {
            _(1000).times(function () {
                character = chance.character({alpha: true});
                expect(character).to.match(/[a-zA-Z]/);
            });

            _(1000).times(function () {
                character = chance.character({alpha: true, casing: 'upper'});
                expect(character).to.match(/[A-Z]/);
            });

            _(1000).times(function () {
                character = chance.character({alpha: true, casing: 'lower'});
                expect(character).to.match(/[a-z]/);
            });
        });

    });

    describe("String", function () {
        it("returns a string", function () {
            string = chance.string();
            expect(string).to.be.a('string');
        });

        it("obeys length, when specified", function () {
            var length;
            _(1000).times(function () {
                // Generate a random length from 1-25
                length = chance.natural({min: 1, max: 25});
                string = chance.string({length: length});
                expect(string).to.have.length(length);
            });
        });

        it("throws an error if length < 0", function () {
            expect(function () { chance.string({length: -23}); }).to.throw(RangeError);
        });

        it("obeys case", function () {
            _(1000).times(function () {
                string = chance.string({alpha: true});
                expect(string).to.match(/[a-zA-Z]+/);
            });

            _(1000).times(function () {
                string = chance.string({alpha: true, casing: 'upper'});
                expect(string).to.match(/[A-Z]+/);
            });

            _(1000).times(function () {
                string = chance.string({alpha: true, casing: 'lower'});
                expect(string).to.match(/[a-z]+/);
            });

        });

        it("obeys symbol", function () {
            _(1000).times(function () {
                string = chance.string({symbols: true});
                expect(string).to.match(/[\!\@\#\$\%\^\&\*\(\)\[\]]+/);
            });
        });

    });
});

describe("Seed", function () {
    var seed, chance1, chance2;

    describe("null works", function () {
        it("works with a null seed", function(done) {
            chance1 = Chance(null);

            // Wait 5 ms before creating chance2 else sometimes they happen on the same
            // tick and end up with the same seed!
            setTimeout(function () {
                chance2 = Chance(null);
                expect(chance1.random()).to.not.equal(chance2.random());
                done();
            }, 5);
        });
    });

    describe("random", function () {
        it("does return differing results if differing seeds provided", function (done) {
            chance1 = new Chance(12345);
            // Wait 5 ms before creating chance2 else sometimes they happen on the same
            // tick and end up with the same seed!
            setTimeout(function () {
                chance2 = new Chance(54321);
                expect(chance1.random()).to.not.equal(chance2.random());
                done();
            }, 5);
        });

        it("does not return repeatable results if no seed provided", function (done) {
            chance1 = new Chance();
            // Wait 5 ms before creating chance2 else sometimes they happen on the same
            // tick and end up with the same seed!
            setTimeout(function () {
                chance2 = new Chance();
                _(1000).times(function () {
                    expect(chance1.random()).to.not.equal(chance2.random());
                });
                done();
            }, 5);
        });

        it("returns repeatable results if seed provided on the Chance object", function () {
            seed = new Date().getTime();
            chance1 = new Chance(seed);
            chance2 = new Chance(seed);

            _(1000).times(function () {
                expect(chance1.random()).to.equal(chance2.random());
            });
        });

        it("returns repeatable results if a string is provided as a seed", function () {
            seed = "foo";
            chance1 = new Chance(seed);
            chance2 = new Chance(seed);

            _(1000).times(function () {
                expect(chance1.random()).to.equal(chance2.random());
            });
        });

        it("returns different results if two different strings are provided", function () {
            chance1 = new Chance("foo");
            chance2 = new Chance("baz");

            _(1000).times(function () {
                expect(chance1.random()).to.not.equal(chance2.random());
            });
        });

        it("returns different results if two different strings are provided redux", function () {
            // Credit to @dan-tilley for noticing this flaw in the old seed
            chance1 = new Chance("abe");
            chance2 = new Chance("acc");

            _(1000).times(function () {
                expect(chance1.random()).to.not.equal(chance2.random());
            });
        });

        it("returns different results if multiple arguments are provided", function () {
            seed = new Date().getTime();
            chance1 = new Chance(seed, "foo");
            chance2 = new Chance(seed, "bar");

            _(1000).times(function () {
                expect(chance1.random()).to.not.equal(chance2.random());
            });
        });
    });

    describe("arbitrary function", function () {
        it("will take an arbitrary function for random, use it", function () {
            var chance = new Chance(function () { return 123; });
            _(1000).times(function () {
                expect(chance.random()).to.equal(123);
            });
        });
    });
});
<commit_msg>Natural can be zero<commit_after>/* jshint newcap:false */
/// <reference path="../chance.js" />
/// <reference path="../node_modules/underscore/underscore-min.js" />

var expect = chai.expect;

describe("Basics", function () {
    var bool, integer, natural, floating, character, string, temp, chance = new Chance(),
        data, cData;

    describe("Data", function () {
        it("get data", function () {
            data = chance.get("lastNames");
            expect(data).to.be.an('object');
        });

        it("set custom data", function () {
            cData = {lastNames: ["customName", "testLast"]};
            chance.set(cData);
            data = chance.get("lastNames");
            expect(data).to.be.an('array');
            expect(data).to.have.length(2);
        });
    });

    describe("Bool", function () {
        it("returns a random boolean", function () {
            bool = chance.bool();
            expect(bool).to.be.a('boolean');
        });

        it("is within the bounds of what we'd call random", function () {
            var true_count = 0;
            _(1000).times(function () {
                bool = chance.bool();
                if (bool) {
                    true_count++;
                }
            });

            // The probability of this test failing is approximately 4.09e-86.
            // So, in theory, it could give a false negative, but the sun will
            // probably die long before that happens.
            //
            // See calculation here https://gist.github.com/BlaMaeda/cfd886f84dd093cb2ead
            expect(true_count).to.be.within(200, 800);
        });

        it("takes and obeys likelihood", function () {
            var true_count = 0;
            _(1000).times(function () {
                if (chance.bool({likelihood: 30})) {
                    true_count++;
                }
            });

            // Expect it to average around 300
            expect(true_count).to.be.within(200, 400);

            true_count = 0;
            _(1000).times(function () {
                if (chance.bool({likelihood: 99})) {
                    true_count++;
                }
            });

            // Expect it to average at 990
            expect(true_count).to.be.above(900);
        });

        it("throws an error if likelihood < 0 or > 100", function () {
            expect(function () { chance.bool({likelihood: -23}); }).to.throw(RangeError);
            expect(function () { chance.bool({likelihood: 7933}); }).to.throw(RangeError);
        });
    });

    describe("Integer", function () {
        it("returns a random integer", function () {
            integer = chance.integer();
            expect(integer).to.be.a('number');
        });

        it("is sometimes negative, sometimes positive", function () {
            var positive_count = 0;
            _(1000).times(function () {
                integer = chance.integer();
                if (integer > 0) {
                    positive_count++;
                }
            });

            // Note: In very extreme circumstances this test may fail as, by its
            // nature it's random. But it's a low enough percentage that I'm
            // willing to accept it.
            expect(positive_count).to.be.within(200, 800);
        });

        it("can take a zero min and obey it", function () {
            _(1000).times(function () {
                integer = chance.integer({min: 0});
                expect(integer).to.be.above(0);
            });
        });

        it("can take a negative min and obey it", function () {
            _(1000).times(function () {
                integer = chance.integer({min: -25});
                expect(integer).to.be.above(-26);
            });
        });

        it("can take a negative min and negative max and obey both", function () {
            _(1000).times(function () {
                integer = chance.integer({min: -25, max: -1});
                expect(integer).to.be.within(-26, 0);
            });
        });

        it("can take a min with absolute value less than the max and return in range above", function () {
            var count = 0;
            _(1000).times(function () {
                // With a range this large we'd expect most values to be
                // greater than 1 if this works correctly.
                integer = chance.integer({min: -1, max: 1000000});
                if (Math.abs(integer) < 2) {
                    count++;
                }
            });
            expect(count).to.not.be.above(900);
        });

        it("throws an error if min > max", function () {
            expect(function () { chance.natural({min: 1000, max: 500}); }).to.throw(RangeError);
        });
    });

    describe("Natural", function () {
        it("returns a random natural", function () {
            natural = chance.natural();
            expect(natural).to.be.a('number');
        });

        it("throws an error if min < 0", function () {
            expect(function () { chance.natural({min: -23}); }).to.throw(RangeError);
        });

        it("is always positive", function () {
            var positive_count = 0;
            _(1000).times(function () {
                natural = chance.natural();
                if (natural >= 0) {
                    positive_count++;
                }
            });

            expect(positive_count).to.equal(1000);
        });

        it("can take just a min and obey it", function () {
            _(1000).times(function () {
                natural = chance.natural({min: 9007199254740991});
                expect(natural).to.be.above(9007199254740990);
            });
        });

        it("can take just a max and obey it", function () {
            _(1000).times(function () {
                natural = chance.natural({max: 100});
                expect(natural).to.be.below(101);
            });
        });

        it("can take both a max and min and obey them both", function () {
            _(1000).times(function () {
                natural = chance.natural({min: 90, max: 100});
                expect(natural).to.be.within(89, 101);
            });
        });

        it("works with both bounds 0", function () {
            _(1000).times(function () {
                natural = chance.natural({min: 0, max: 0});
                expect(natural).to.equal(0);
            });
        });

        it("throws an error if min > max", function () {
            expect(function () { chance.natural({min: 1000, max: 500}); }).to.throw(RangeError);
        });
    });

    describe("Floating", function () {
        it("returns a random floating", function () {
            floating = chance.floating();
            expect(floating).to.be.a('number');
        });

        it("can take both a max and min and obey them both", function () {
            _(1000).times(function () {
                floating = chance.floating({min: 90, max: 100});
                expect(floating).to.be.within(90, 100);
            });
        });

        it("won't take fixed + min that would be out of range", function () {
            expect(function () { chance.floating({fixed: 13, min: -9007199254740992}); }).to.throw(RangeError);
        });

        it("won't take fixed + max that would be out of range", function () {
            expect(function () { chance.floating({fixed: 13, max: 9007199254740992}); }).to.throw(RangeError);
        });

        it("obeys the fixed parameter, when present", function () {
            _(100).times(function () {
                floating = chance.floating({fixed: 4});
                floating = floating.toString().split('.')[1] ? floating.toString().split('.')[1] : '';
                expect(floating).to.have.length.below(5);
            });
        });

        it("can take fixed and obey it", function () {
            _(1000).times(function () {
                floating = chance.floating({fixed: 3});
                temp = parseFloat(floating.toFixed(3));
                expect(floating).to.equal(temp);
            });
        });

        it("won't take both fixed and precision", function () {
            expect(function () { chance.floating({fixed: 2, precision: 8}); }).to.throw(RangeError);
        });
    });

    describe("Character", function () {
        it("returns a character", function () {
            character = chance.character();
            expect(character).to.be.a('string');
            expect(character).to.have.length(1);
        });

        it("pulls only from pool, when specified", function () {
            var pool = 'abcde';
            _(1000).times(function () {
                character = chance.character({pool: pool});
                expect(character).to.match(/[abcde]/);
            });
        });

        it("allows only alpha", function () {
            _(1000).times(function () {
                character = chance.character({alpha: true});
                expect(character).to.match(/[a-zA-Z]/);
            });

            expect(function () { chance.character({alpha: true, symbols: true}); }).to.throw(RangeError);
        });

        it("obeys case", function () {
            _(1000).times(function () {
                character = chance.character({alpha: true});
                expect(character).to.match(/[a-zA-Z]/);
            });

            _(1000).times(function () {
                character = chance.character({alpha: true, casing: 'upper'});
                expect(character).to.match(/[A-Z]/);
            });

            _(1000).times(function () {
                character = chance.character({alpha: true, casing: 'lower'});
                expect(character).to.match(/[a-z]/);
            });
        });

    });

    describe("String", function () {
        it("returns a string", function () {
            string = chance.string();
            expect(string).to.be.a('string');
        });

        it("obeys length, when specified", function () {
            var length;
            _(1000).times(function () {
                // Generate a random length from 1-25
                length = chance.natural({min: 1, max: 25});
                string = chance.string({length: length});
                expect(string).to.have.length(length);
            });
        });

        it("throws an error if length < 0", function () {
            expect(function () { chance.string({length: -23}); }).to.throw(RangeError);
        });

        it("obeys case", function () {
            _(1000).times(function () {
                string = chance.string({alpha: true});
                expect(string).to.match(/[a-zA-Z]+/);
            });

            _(1000).times(function () {
                string = chance.string({alpha: true, casing: 'upper'});
                expect(string).to.match(/[A-Z]+/);
            });

            _(1000).times(function () {
                string = chance.string({alpha: true, casing: 'lower'});
                expect(string).to.match(/[a-z]+/);
            });

        });

        it("obeys symbol", function () {
            _(1000).times(function () {
                string = chance.string({symbols: true});
                expect(string).to.match(/[\!\@\#\$\%\^\&\*\(\)\[\]]+/);
            });
        });

    });
});

describe("Seed", function () {
    var seed, chance1, chance2;

    describe("null works", function () {
        it("works with a null seed", function(done) {
            chance1 = Chance(null);

            // Wait 5 ms before creating chance2 else sometimes they happen on the same
            // tick and end up with the same seed!
            setTimeout(function () {
                chance2 = Chance(null);
                expect(chance1.random()).to.not.equal(chance2.random());
                done();
            }, 5);
        });
    });

    describe("random", function () {
        it("does return differing results if differing seeds provided", function (done) {
            chance1 = new Chance(12345);
            // Wait 5 ms before creating chance2 else sometimes they happen on the same
            // tick and end up with the same seed!
            setTimeout(function () {
                chance2 = new Chance(54321);
                expect(chance1.random()).to.not.equal(chance2.random());
                done();
            }, 5);
        });

        it("does not return repeatable results if no seed provided", function (done) {
            chance1 = new Chance();
            // Wait 5 ms before creating chance2 else sometimes they happen on the same
            // tick and end up with the same seed!
            setTimeout(function () {
                chance2 = new Chance();
                _(1000).times(function () {
                    expect(chance1.random()).to.not.equal(chance2.random());
                });
                done();
            }, 5);
        });

        it("returns repeatable results if seed provided on the Chance object", function () {
            seed = new Date().getTime();
            chance1 = new Chance(seed);
            chance2 = new Chance(seed);

            _(1000).times(function () {
                expect(chance1.random()).to.equal(chance2.random());
            });
        });

        it("returns repeatable results if a string is provided as a seed", function () {
            seed = "foo";
            chance1 = new Chance(seed);
            chance2 = new Chance(seed);

            _(1000).times(function () {
                expect(chance1.random()).to.equal(chance2.random());
            });
        });

        it("returns different results if two different strings are provided", function () {
            chance1 = new Chance("foo");
            chance2 = new Chance("baz");

            _(1000).times(function () {
                expect(chance1.random()).to.not.equal(chance2.random());
            });
        });

        it("returns different results if two different strings are provided redux", function () {
            // Credit to @dan-tilley for noticing this flaw in the old seed
            chance1 = new Chance("abe");
            chance2 = new Chance("acc");

            _(1000).times(function () {
                expect(chance1.random()).to.not.equal(chance2.random());
            });
        });

        it("returns different results if multiple arguments are provided", function () {
            seed = new Date().getTime();
            chance1 = new Chance(seed, "foo");
            chance2 = new Chance(seed, "bar");

            _(1000).times(function () {
                expect(chance1.random()).to.not.equal(chance2.random());
            });
        });
    });

    describe("arbitrary function", function () {
        it("will take an arbitrary function for random, use it", function () {
            var chance = new Chance(function () { return 123; });
            _(1000).times(function () {
                expect(chance.random()).to.equal(123);
            });
        });
    });
});
<|endoftext|>


<commit_before>define(['Chance', 'mocha', 'chai', 'underscore'], function (Chance, mocha, chai, _) {
    var expect = chai.expect;

    describe("Basics", function () {
        var bool, integer, natural, character, string, chance = new Chance();

        describe("Bool", function () {
            it("returns a random boolean", function () {
                bool = chance.bool();
                expect(bool).to.be.a('boolean');
            });

            it("is within the bounds of what we'd call random", function () {
                var true_count = 0;
                _(1000).times(function () {
                    bool = chance.bool();
                    if (bool) {
                        true_count++;
                    }
                });

                // Note: In very extreme circumstances this test may fail as, by its
                // nature it's random. But it's a low enough percentage that I'm
                // willing to accept it.
                // Award to anyone that calculates the actual probability of this
                // test failing and submits a pull request adding it to this comment!
                expect(true_count).to.be.within(200, 800);
            });
        });

        describe("Integer", function () {
            it("returns a random integer", function () {
                integer = chance.integer();
                expect(integer).to.be.a('number');
            });

            it("is sometimes negative, sometimes positive", function () {
                var positive_count = 0;
                _(1000).times(function () {
                    integer = chance.integer();
                    if (integer > 0) {
                        positive_count++;
                    }
                });

                // Note: In very extreme circumstances this test may fail as, by its
                // nature it's random. But it's a low enough percentage that I'm
                // willing to accept it.
                expect(positive_count).to.be.within(200, 800);
            });

            it("can take a zero min and obey it", function () {
                _(1000).times(function () {
                    integer = chance.integer({min: 0});
                    expect(integer).to.be.above(0);
                });
            });

            it("can take a negative min and obey it", function () {
                _(1000).times(function () {
                    integer = chance.integer({min: -25});
                    expect(integer).to.be.above(-26);
                });
            });

            it("can take a negative min and negative max and obey both", function () {
                _(1000).times(function () {
                    integer = chance.integer({min: -25, max: -1});
                    expect(integer).to.be.within(-26, 0);
                });
            });
        });

        describe("Natural", function () {
            it("returns a random natural", function () {
                natural = chance.natural();
                expect(natural).to.be.a('number');
            });

            it("is always positive", function () {
                var positive_count = 0;
                _(1000).times(function () {
                    natural = chance.natural();
                    if (natural > 0) {
                        positive_count++;
                    }
                });

                expect(positive_count).to.equal(1000);
            });

            it("can take just a min and obey it", function () {
                _(1000).times(function () {
                    natural = chance.natural({min: 9007199254740991});
                    expect(natural).to.be.above(9007199254740990);
                });
            });

            it("can take just a max and obey it", function () {
                _(1000).times(function () {
                    natural = chance.natural({max: 100});
                    expect(natural).to.be.below(101);
                });
            });

            it("can take both a max and min and obey them both", function () {
                _(1000).times(function () {
                    natural = chance.natural({min: 90, max: 100});
                    expect(natural).to.be.within(89, 101);
                });
            });
        });

        describe("Character", function () {
            it("returns a character", function () {
                character = chance.character();
                expect(character).to.be.a('string');
                expect(character).to.have.length(1);
            });

            it("pulls only from pool, when specified", function () {
                var pool = 'abcde';
                _(1000).times(function () {
                    character = chance.character({pool: pool});
                    expect(character).to.match(/[abcde]/);
                });
            });

            it("allows only alpha", function () {
                _(1000).times(function () {
                    character = chance.character({alpha: true});
                    expect(character).to.match(/[a-zA-Z]/);
                });

                expect(function () { chance.character({alpha: true, symbols: true}); }).to.throw(RangeError);
            });

            it("obeys case", function () {
                _(1000).times(function () {
                    character = chance.character({alpha: true});
                    expect(character).to.match(/[a-zA-Z]/);
                });

                _(1000).times(function () {
                    character = chance.character({alpha: true, casing: 'upper'});
                    expect(character).to.match(/[A-Z]/);
                });

                _(1000).times(function () {
                    character = chance.character({alpha: true, casing: 'lower'});
                    expect(character).to.match(/[a-z]/);
                });
            });

        });

        describe("String", function () {
            it("returns a string", function () {
                string = chance.string();
                expect(string).to.be.a('string');
            });

            it("obeys length, when specified", function () {
                var length;
                _(1000).times(function () {
                    // Generate a random length from 1-25
                    length = chance.natural({min: 1, max: 25});
                    string = chance.string({length: length});
                    expect(string).to.have.length(length);
                });
            });
        });
    });

    describe("Seed", function () {
        var seed, chance1, chance2;

        describe("random", function () {
            it("does not return repeatable results if no seed provided", function (done) {
                chance1 = new Chance();
                // Wait 5 ms before creating chance2 else sometimes they happen on the same
                // tick and end up with the same seed!
                setTimeout(function () {
                    chance2 = new Chance();
                    _(1000).times(function () {
                        expect(chance1.random()).to.not.equal(chance2.random());
                    });
                    done();
                }, 5);
            });

            it("returns repeatable results if seed provided on the Chance object", function () {
                seed = new Date().getTime();
                chance1 = new Chance(seed);
                chance2 = new Chance(seed);

                _(1000).times(function () {
                    expect(chance1.random()).to.equal(chance2.random());
                });
            });
        });
    });

});
<commit_msg>Add a test for the case @path411 found of the min being used twice to calculate the range of int values<commit_after>define(['Chance', 'mocha', 'chai', 'underscore'], function (Chance, mocha, chai, _) {
    var expect = chai.expect;

    describe("Basics", function () {
        var bool, integer, natural, character, string, chance = new Chance();

        describe("Bool", function () {
            it("returns a random boolean", function () {
                bool = chance.bool();
                expect(bool).to.be.a('boolean');
            });

            it("is within the bounds of what we'd call random", function () {
                var true_count = 0;
                _(1000).times(function () {
                    bool = chance.bool();
                    if (bool) {
                        true_count++;
                    }
                });

                // Note: In very extreme circumstances this test may fail as, by its
                // nature it's random. But it's a low enough percentage that I'm
                // willing to accept it.
                // Award to anyone that calculates the actual probability of this
                // test failing and submits a pull request adding it to this comment!
                expect(true_count).to.be.within(200, 800);
            });
        });

        describe("Integer", function () {
            it("returns a random integer", function () {
                integer = chance.integer();
                expect(integer).to.be.a('number');
            });

            it("is sometimes negative, sometimes positive", function () {
                var positive_count = 0;
                _(1000).times(function () {
                    integer = chance.integer();
                    if (integer > 0) {
                        positive_count++;
                    }
                });

                // Note: In very extreme circumstances this test may fail as, by its
                // nature it's random. But it's a low enough percentage that I'm
                // willing to accept it.
                expect(positive_count).to.be.within(200, 800);
            });

            it("can take a zero min and obey it", function () {
                _(1000).times(function () {
                    integer = chance.integer({min: 0});
                    expect(integer).to.be.above(0);
                });
            });

            it("can take a negative min and obey it", function () {
                _(1000).times(function () {
                    integer = chance.integer({min: -25});
                    expect(integer).to.be.above(-26);
                });
            });

            it("can take a negative min and negative max and obey both", function () {
                _(1000).times(function () {
                    integer = chance.integer({min: -25, max: -1});
                    expect(integer).to.be.within(-26, 0);
                });
            });

            it("can take a min with absolute value less than the max and return in range above", function () {
                var count = 0;
                _(1000).times(function () {
                    // With a range this large we'd expect most values to be
                    // greater than 1 if this works correctly.
                    integer = chance.integer({min: -1, max: 1000000});
                    if (Math.abs(integer) < 2) {
                        count++;
                    }
                });
                expect(count).to.not.be.above(900);
            });
        });

        describe("Natural", function () {
            it("returns a random natural", function () {
                natural = chance.natural();
                expect(natural).to.be.a('number');
            });

            it("is always positive", function () {
                var positive_count = 0;
                _(1000).times(function () {
                    natural = chance.natural();
                    if (natural > 0) {
                        positive_count++;
                    }
                });

                expect(positive_count).to.equal(1000);
            });

            it("can take just a min and obey it", function () {
                _(1000).times(function () {
                    natural = chance.natural({min: 9007199254740991});
                    expect(natural).to.be.above(9007199254740990);
                });
            });

            it("can take just a max and obey it", function () {
                _(1000).times(function () {
                    natural = chance.natural({max: 100});
                    expect(natural).to.be.below(101);
                });
            });

            it("can take both a max and min and obey them both", function () {
                _(1000).times(function () {
                    natural = chance.natural({min: 90, max: 100});
                    expect(natural).to.be.within(89, 101);
                });
            });
        });

        describe("Character", function () {
            it("returns a character", function () {
                character = chance.character();
                expect(character).to.be.a('string');
                expect(character).to.have.length(1);
            });

            it("pulls only from pool, when specified", function () {
                var pool = 'abcde';
                _(1000).times(function () {
                    character = chance.character({pool: pool});
                    expect(character).to.match(/[abcde]/);
                });
            });

            it("allows only alpha", function () {
                _(1000).times(function () {
                    character = chance.character({alpha: true});
                    expect(character).to.match(/[a-zA-Z]/);
                });

                expect(function () { chance.character({alpha: true, symbols: true}); }).to.throw(RangeError);
            });

            it("obeys case", function () {
                _(1000).times(function () {
                    character = chance.character({alpha: true});
                    expect(character).to.match(/[a-zA-Z]/);
                });

                _(1000).times(function () {
                    character = chance.character({alpha: true, casing: 'upper'});
                    expect(character).to.match(/[A-Z]/);
                });

                _(1000).times(function () {
                    character = chance.character({alpha: true, casing: 'lower'});
                    expect(character).to.match(/[a-z]/);
                });
            });

        });

        describe("String", function () {
            it("returns a string", function () {
                string = chance.string();
                expect(string).to.be.a('string');
            });

            it("obeys length, when specified", function () {
                var length;
                _(1000).times(function () {
                    // Generate a random length from 1-25
                    length = chance.natural({min: 1, max: 25});
                    string = chance.string({length: length});
                    expect(string).to.have.length(length);
                });
            });
        });
    });

    describe("Seed", function () {
        var seed, chance1, chance2;

        describe("random", function () {
            it("does not return repeatable results if no seed provided", function (done) {
                chance1 = new Chance();
                // Wait 5 ms before creating chance2 else sometimes they happen on the same
                // tick and end up with the same seed!
                setTimeout(function () {
                    chance2 = new Chance();
                    _(1000).times(function () {
                        expect(chance1.random()).to.not.equal(chance2.random());
                    });
                    done();
                }, 5);
            });

            it("returns repeatable results if seed provided on the Chance object", function () {
                seed = new Date().getTime();
                chance1 = new Chance(seed);
                chance2 = new Chance(seed);

                _(1000).times(function () {
                    expect(chance1.random()).to.equal(chance2.random());
                });
            });
        });
    });

});
<|endoftext|>


<commit_before>describe('ax5.ui.toast TEST', function () {
    it('toast.push("message", callback)', function (done) {
        var message = 'Toast message';
        var toast = new ax5.ui.toast({
            containerPosition: 'top-right',
            displayTime: 0,
            animateTime: 0,
            onStateChanged: function () {
                var $toastEl = $('#' + this.toastId);
                if (this.state == 'open') {
                    $toastEl.find('.ax-toast-body').text().should.equal(message);
                } else if (this.state == 'close') {
                    should($toastEl.get(0)).undefined();
                    done();
                }
            }
        });

        toast.push(message, function () {
            should(this.toastId).String();
        });
    });

    it('toast.confirm("message", callback)', function (done) {
        var message = 'Toast message';
        var toast = new ax5.ui.toast({
            containerPosition: 'top-right',
            displayTime: 0,
            animateTime: 0,
            onStateChanged: function () {
                var $toastEl = $('#' + this.toastId);
                if (this.state == 'open') {
                    $toastEl.find('.ax-toast-body').text().should.equal(message);
                } else if (this.state == 'close') {
                    should($toastEl.get(0)).undefined();
                    done();
                }
            }
        });

        toast.confirm(message, function () {
            should(this.toastId).String();
        });

        setTimeout(function () {
            $('[data-ax-toast-btn="ok"]').click();
        }, 20);
    });
});

describe('ax5toast method TEST', function () {
    var that;
    var myUI;

    beforeEach(function () {
        myUI = new ax5.ui.toast({
            displayTime: 100,
            animateTime: 100,
            onStateChanged: function () {
                that = this;
            }
        });
    });

    afterEach(function () {
        myUI = null;
    });

    it('toast push open test', function (done) {
        myUI.push('message');
        done(
            ae.equalAll('message', that.self.queue[0].msg)
            || ae.equalAll('open', that.state)
        );
    });

    it('toast push close test', function (done) {
        myUI.push('message');
        setTimeout(function () {
            done(
                ae.equalAll(0, that.self.queue.length)
                || ae.equalAll('close', that.state)
            );
        }, myUI.config.animateTime + myUI.config.displayTime + 50);
    });

    it('toast confirm open test', function (done) {
        myUI.confirm('message');
        done(
            ae.equalAll('message', that.self.queue[0].msg)
            || ae.equalAll('open', that.state)
        );
    });

    it('toast confirm close test', function (done) {
        myUI.confirm('message');
        $('[data-ax-toast-btn="ok"]').click();
        setTimeout(function () {
            done(
                ae.equalAll(0, that.self.queue.length)
                || ae.equalAll('close', that.state)
            );
        }, myUI.config.animateTime + myUI.config.displayTime + 50);
    });
});<commit_msg>update test code<commit_after>describe('ax5.ui.toast TEST', function () {
    it('toast.push("message", callback)', function (done) {
        var message = 'Toast message';
        var toast = new ax5.ui.toast({
            containerPosition: 'top-right',
            displayTime: 0,
            animateTime: 0,
            onStateChanged: function () {
                var $toastEl = $('#' + this.toastId);
                if (this.state == 'open') {
                    $toastEl.find('.ax-toast-body').text().should.equal(message);
                } else if (this.state == 'close') {
                    should($toastEl.get(0)).undefined();
                    done();
                }
            }
        });

        toast.push(message, function () {
            should(this.toastId).String();
        });
    });

    it('toast.confirm("message", callback)', function (done) {
        var message = 'Toast message';
        var toast = new ax5.ui.toast({
            containerPosition: 'top-right',
            displayTime: 0,
            animateTime: 0,
            onStateChanged: function () {
                var $toastEl = $('#' + this.toastId);
                if (this.state == 'open') {
                    $toastEl.find('.ax-toast-body').text().should.equal(message);
                } else if (this.state == 'close') {
                    should($toastEl.get(0)).undefined();
                    done();
                }
            }
        });

        toast.confirm(message, function () {
            should(this.toastId).String();
        });

        setTimeout(function () {
            $('[data-ax-toast-btn="ok"]').click();
        }, 20);
    });
});

describe('ax5toast method TEST', function () {
    var that;
    var myUI;

    beforeEach(function () {
        myUI = new ax5.ui.toast({
            displayTime: 100,
            animateTime: 100,
            onStateChanged: function () {
                that = this;
            }
        });
    });

    afterEach(function () {
        myUI = null;
    });

    it('toast push open test', function (done) {
        myUI.push('message');
        done(
            ae.equalAll('message', that.self.queue[0].msg)
            || ae.equalAll('open', that.state)
        );
    });

    it('toast push close test', function (done) {
        myUI.push('message');
        setTimeout(function () {
            done(
                ae.equalAll(0, that.self.queue.length)
                || ae.equalAll('close', that.state)
            );
        }, myUI.config.animateTime + myUI.config.displayTime + 50);
    });

    it('toast confirm open test', function (done) {
        myUI.confirm('message');
        done(
            ae.equalAll('message', that.self.queue[0].msg)
            || ae.equalAll('open', that.state)
        );
    });

    it('toast confirm close test', function (done) {
        myUI.confirm('message');
        $('[data-ax-toast-btn="ok"]').click();
        setTimeout(function () {
            done(
                ae.equalAll(0, that.self.queue.length)
                || ae.equalAll('close', that.state)
            );
        }, myUI.config.animateTime + myUI.config.displayTime + 50);
    });

    it('toast close test', function (done) {
        myUI.confirm('message');
        myUI.close();
        setTimeout(function () {
            done(
                ae.equalAll(0, that.self.queue.length)
                || ae.equalAll('close', that.state)
            );
        }, myUI.config.animateTime + myUI.config.displayTime + 50);
    });
});<|endoftext|>