<commit_before>var GooglePlaces = require('../lib/google-places'),
    vows = require('vows'),
    fakeweb = require('node-fakeweb'),
    assert = require('assert');

fakeweb.allowNetConnect = false;

// fake the search
fakeweb.registerUri({
  uri: 'https://maps.googleapis.com/maps/api/place/search/json?location=42.357799%2C-71.0536364&radius=10&sensor=false&language=en&rankby=prominence&key=fake_key',
  body: '{"results" : [{"name": "Vermonster", "id":"1"}], "status" : "OK"}'
});
// fake the autocomplete
fakeweb.registerUri({
  uri: 'https://maps.googleapis.com/maps/api/place/autocomplete/json?language=en&sensor=false&key=fake_key',
  body: '{"predictions" : [{"description": "Vermonster", "id":"1"}, {"description": "Vermont", "id":"2"}, {"description": "Vermilion", "id": "3"}], "status" : "OK"}'
});
//fake the details
fakeweb.registerUri({
  uri: 'https://maps.googleapis.com/maps/api/place/details/json?reference=ABC123&sensor=false&language=en&key=fake_key',
  body: '{"result" : {"rating": 2.5}, "status" : "OK"}'
});

vows.describe('Url generation').addBatch({
  'default url': {
    topic: new GooglePlaces('fake_key'),

    'should have a default url for place search': function(topic) {
      assert.equal(topic._generateUrl({}, 'search').href, 'https://maps.googleapis.com/maps/api/place/search/json?key=fake_key');
    },

    'should have a default url for place autocomplete': function(topic) {
      assert.equal(topic._generateUrl({}, 'autocomplete').href, 'https://maps.googleapis.com/maps/api/place/autocomplete/json?key=fake_key');
    },

    'should have my key as a query param': function(topic) {
      assert.equal(topic._generateUrl({key: 'fake_key'}, 'search').query, 'key=fake_key');
    }
  }
}).export(module);

vows.describe('Places search').addBatch({
  'new search': {
    topic: function() {
      new GooglePlaces('fake_key').search({}, this.callback);
    },

    'should not have an error': function(err, response){
      assert.isNull(err);
    },

    'should be status OK': function(err, response){
      assert.equal(response.status, 'OK');
    },

    'should include Vermonster': function(err, response){
      assert.equal(response.results[0].name, 'Vermonster');
    }
  }
}).export(module);

vows.describe('Places autocomplete').addBatch({
  'new autocomplete': {
    topic: function() {
      new GooglePlaces('fake_key').autocomplete({}, this.callback);
    },

    'should not have an error': function(err, response){
      assert.isNull(err);
    },

    'should be status OK': function(err, response){
      // console.log(response); process.exit();
      assert.equal(response.status, 'OK');
    },

    'should include Vermonster': function(err, response){
      assert.equal(response.predictions[0].description, 'Vermonster');
    }
  }
}).export(module);

vows.describe('Place details').addBatch({
  'new search': {
    topic: function() {
      new GooglePlaces('fake_key').details({reference: 'ABC123'}, this.callback);
    },
    'should get details': function(err, response){
      assert.equal(response.result.rating, 2.5);
    }
  }
}).export(module);
<commit_msg>Remove sensor from test URLs<commit_after>var GooglePlaces = require('../lib/google-places'),
    vows = require('vows'),
    fakeweb = require('node-fakeweb'),
    assert = require('assert');

fakeweb.allowNetConnect = false;

// fake the search
fakeweb.registerUri({
  uri: 'https://maps.googleapis.com/maps/api/place/search/json?location=42.357799%2C-71.0536364&radius=10&language=en&rankby=prominence&key=fake_key',
  body: '{"results" : [{"name": "Vermonster", "id":"1"}], "status" : "OK"}'
});
// fake the autocomplete
fakeweb.registerUri({
  uri: 'https://maps.googleapis.com/maps/api/place/autocomplete/json?language=en&key=fake_key',
  body: '{"predictions" : [{"description": "Vermonster", "id":"1"}, {"description": "Vermont", "id":"2"}, {"description": "Vermilion", "id": "3"}], "status" : "OK"}'
});
//fake the details
fakeweb.registerUri({
  uri: 'https://maps.googleapis.com/maps/api/place/details/json?reference=ABC123&language=en&key=fake_key',
  body: '{"result" : {"rating": 2.5}, "status" : "OK"}'
});

vows.describe('Url generation').addBatch({
  'default url': {
    topic: new GooglePlaces('fake_key'),

    'should have a default url for place search': function(topic) {
      assert.equal(topic._generateUrl({}, 'search').href, 'https://maps.googleapis.com/maps/api/place/search/json?key=fake_key');
    },

    'should have a default url for place autocomplete': function(topic) {
      assert.equal(topic._generateUrl({}, 'autocomplete').href, 'https://maps.googleapis.com/maps/api/place/autocomplete/json?key=fake_key');
    },

    'should have my key as a query param': function(topic) {
      assert.equal(topic._generateUrl({key: 'fake_key'}, 'search').query, 'key=fake_key');
    }
  }
}).export(module);

vows.describe('Places search').addBatch({
  'new search': {
    topic: function() {
      new GooglePlaces('fake_key').search({}, this.callback);
    },

    'should not have an error': function(err, response){
      assert.isNull(err);
    },

    'should be status OK': function(err, response){
      assert.equal(response.status, 'OK');
    },

    'should include Vermonster': function(err, response){
      assert.equal(response.results[0].name, 'Vermonster');
    }
  }
}).export(module);

vows.describe('Places autocomplete').addBatch({
  'new autocomplete': {
    topic: function() {
      new GooglePlaces('fake_key').autocomplete({}, this.callback);
    },

    'should not have an error': function(err, response){
      assert.isNull(err);
    },

    'should be status OK': function(err, response){
      // console.log(response); process.exit();
      assert.equal(response.status, 'OK');
    },

    'should include Vermonster': function(err, response){
      assert.equal(response.predictions[0].description, 'Vermonster');
    }
  }
}).export(module);

vows.describe('Place details').addBatch({
  'new search': {
    topic: function() {
      new GooglePlaces('fake_key').details({reference: 'ABC123'}, this.callback);
    },
    'should get details': function(err, response){
      assert.equal(response.result.rating, 2.5);
    }
  }
}).export(module);
<|endoftext|>


<commit_before>'use strict';

var Writable = require('stream').Writable;
var sinon = require('sinon');
var Rsvg = require('..').Rsvg;
var fs = require('fs');

describe('Rsvg', function() {

	describe('Rsvg()', function() {
		it('can be constructed with a SVG', function() {
			// Use buffer.
			var svg = new Rsvg(new Buffer('<svg width="5" height="7"></svg>'));
			svg.should.be.an.instanceof(Rsvg);
			svg.width.should.equal(5);
			svg.height.should.equal(7);

			// Use string.
			svg = new Rsvg('<svg width="3" height="8"></svg>');
			svg.width.should.equal(3);
			svg.height.should.equal(8);

			// Not writable anymore
			var onerror = sinon.spy();
			svg.on('error', onerror);
			svg.write('<svg width="3" height="2"></svg>');
			onerror.should.have.been.calledOnce;
			onerror.lastCall.args.should.have.length(1);
			onerror.lastCall.args[0].should.match(/write failure/i);
		});

		it('can be a writable stream', function() {
			// Default constructor.
			var svg = new Rsvg();
			svg.should.be.an.instanceof(Writable);
			svg.width.should.equal(0);
			svg.height.should.equal(0);

			// Write to stream and basic test.
			svg.write('<svg width="4" height="6">').should.be.true;
			svg.width.should.equal(4);
			svg.height.should.equal(6);

			// Stream options.
			svg = new Rsvg({ highWaterMark: 16 });
			svg.write('<svg width="4" height="6">').should.be.false;
		});

		it('emits load event when ready - from stream', function(done) {
			var onload = sinon.spy();
			var svg = new Rsvg();
			svg.on('load', onload);
			svg.write('<svg width="4" height="6">');
			svg.write('</svg>');
			onload.should.not.have.been.called;
			svg.end();
			process.nextTick(function() {
				onload.should.have.been.calledOnce;
				onload.should.have.been.calledWithExactly();
				done();
			});
		});

		it('emits load event when ready - from svg', function(done) {
			var onload = sinon.spy();
			var svg = new Rsvg();
			svg.on('load', onload);
			onload = sinon.spy();
			svg = new Rsvg('<svg width="2" height="3"></svg>');
			svg.on('load', onload);
			onload.should.not.have.been.called;
			process.nextTick(function() {
				onload.should.have.been.calledOnce;
				onload.should.have.been.calledWithExactly();
				done();
			});
		});

		it('gives an error for invalid SVG content', function() {
			// Stream.
			var onerror = sinon.spy();
			var svg = new Rsvg();
			svg.on('error', onerror);
			svg.write('this is not a SVG file');
			onerror.should.have.been.calledOnce;
			svg.write('this is not a SVG file');
			onerror.should.have.been.calledTwice;
			onerror.lastCall.args.should.have.length(1);
			onerror.lastCall.args[0].should.match(/write failure/);

			// Constructed with SVG.
			function loadInvalidSVG() {
				/*jshint -W031 */
				new Rsvg('this is not a SVG file');
				/*jshint +W031 */
			}
			loadInvalidSVG.should.throw(/load failure/i);

			// Regression test on 2014-01-16.
			onerror = sinon.spy();
			svg = new Rsvg();
			svg.on('error', onerror);
			svg.end('<svg width="100" height="100"></svg>invalid');
			onerror.should.have.been.calledOnce;
			onerror.lastCall.args.should.have.length(1);
			onerror.lastCall.args[0].should.match(/write failure/);
		});
	});

	describe('baseURI', function() {
		it('allows to reference external SVGs');
	});

	describe('width', function() {
		it('gives the horizontal size', function() {
			new Rsvg('<svg width="314" height="1"/>').width.should.equal(314);
			new Rsvg('<svg width="257" height="2"/>').width.should.equal(257);
		});
	});

	describe('height', function() {
		it('gives the vertical size', function() {
			new Rsvg('<svg width="1" height="413"/>').height.should.equal(413);
			new Rsvg('<svg width="2" height="752"/>').height.should.equal(752);
		});
	});

	describe('dimensions()', function() {
		it('gives the size of the whole image', function() {
			new Rsvg('<svg width="314" height="257"/>').dimensions().should.deep.equal({
				x: 0,
				y: 0,
				width: 314,
				height: 257
			});
			new Rsvg('<svg width="17" height="19"/>').dimensions().should.deep.equal({
				x: 0,
				y: 0,
				width: 17,
				height: 19
			});
		});

		it('gives the size and position of specific elements', function() {
			var svg = new Rsvg();
			svg.write('<svg width="12" height="10">');
			svg.write('<rect x="-2" y="3" width="7" height="5" id="r1"/>');
			svg.write('<rect x="8" y="4" width="4" height="6" id="r2"/>');
			svg.write('<circle cx="8" cy="3" r="3" id="circ"/>');
			svg.write('</svg>');
			svg.end();

			svg.dimensions().should.deep.equal({
				x: 0,
				y: 0,
				width: 12,
				height: 10
			});
			svg.dimensions(null).should.deep.equal(svg.dimensions());

			svg.dimensions('#r1').should.deep.equal({
				x: -2,
				y: 3,
				width: 7,
				height: 5
			});
			svg.dimensions('#r2').should.deep.equal({
				x: 8,
				y: 4,
				width: 4,
				height: 6
			});
			svg.dimensions('#circ').should.deep.equal({
				x: 5,
				y: 0,
				width: 6,
				height: 6
			});
		});
	});

	describe('hasElement()', function() {
		it('determines whether an element with the given ID exists', function() {
			var svg = new Rsvg();
			svg.write('<svg width="12" height="10">');
			svg.write('<rect x="-2" y="3" width="7" height="5" id="r1"/>');
			svg.write('<rect x="8" y="4" width="4" height="6" id="r2"/>');
			svg.write('<circle cx="8" cy="3" r="3" id="circ"/>');
			svg.write('</svg>');
			svg.end();

			svg.hasElement().should.be.false;
			svg.hasElement(null).should.be.false;
			svg.hasElement('#r1').should.be.true;
			svg.hasElement('#r2').should.be.true;
			svg.hasElement('#circ').should.be.true;
			svg.hasElement('#foo').should.be.false;
			svg.hasElement('r1').should.be.false;
		});
	});

	describe('autocrop()', function() {
		it('finds the drawing area of the SVG');
	});

	describe('render()', function() {
		it('does nothing for an empty SVG document');
		it('renders as a raw memory buffer');
		it('renders as a PNG image');
		it('renders as a PDF document');
		it('renders as a PDF document');
		it('renders in various image sizes');
		it('can render specific SVG elements');
		it('can render a specific area [future]');
		it('can trim the image to a given rect [future]');
		it('can resize to fit inside box [future]');
		it('can resize to fit outside box [future]');
		it('can resize while ignoring aspect ratio [future]');
		it('can resize with a focus point [future]');
		it('can add a background color [future]');
	});

	describe('toString()', function() {
		it('gives a string representation', function() {
			var svg = new Rsvg();
			svg.toString().should.equal('{ [Rsvg] width: 0, height: 0 }');

			svg = new Rsvg('<svg width="3" height="7"></svg>');
			svg.toString().should.equal('{ [Rsvg] width: 3, height: 7 }');
		});
	});

	describe('reference rendering', function () {
		var items = fs.readdirSync('./test/svg/');
		// sinon.assert.pass = function (message) {  console.log(message); };
		items.forEach(function (testcase) {
			if (testcase.slice(-4) === '.svg') {
				it('png image should match the reference image "' + testcase + '"', function () {
					var fn = testcase.slice(0, -4);
					var input = fs.readFileSync('./test/svg/' + fn + '.svg');
					var svg = new Rsvg(input);
					var rendering = new Buffer(svg.render({
						format: 'png',
						width: svg.width,
						height: svg.height
					}).data);

					var compare = function (rendering, referenceFn) {
						var reference = fs.readFileSync('./test/png/' + referenceFn + '.png');
						return Buffer.compare(reference, rendering);
					};

					if( compare(rendering, fn) === 0 ){
						return;
					} else {
						var i = 1;
						while (fs.existsSync('./test/png/' + fn + '-variant' + i + '.png')){
							if ( compare(rendering,  fn + '-variant' + i ) === 0){
								sinon.assert.pass(fn + ' passed using alternative ' + i);
								return;
							}
							i++;
						}
					}

					sinon.assert.fail('image does not match reference:\n' + JSON.stringify(rendering));
				});
			}
		});
	});
});
<commit_msg>Use base64 encoding rather than JSON stringify<commit_after>'use strict';

var Writable = require('stream').Writable;
var sinon = require('sinon');
var Rsvg = require('..').Rsvg;
var fs = require('fs');

describe('Rsvg', function() {

	describe('Rsvg()', function() {
		it('can be constructed with a SVG', function() {
			// Use buffer.
			var svg = new Rsvg(new Buffer('<svg width="5" height="7"></svg>'));
			svg.should.be.an.instanceof(Rsvg);
			svg.width.should.equal(5);
			svg.height.should.equal(7);

			// Use string.
			svg = new Rsvg('<svg width="3" height="8"></svg>');
			svg.width.should.equal(3);
			svg.height.should.equal(8);

			// Not writable anymore
			var onerror = sinon.spy();
			svg.on('error', onerror);
			svg.write('<svg width="3" height="2"></svg>');
			onerror.should.have.been.calledOnce;
			onerror.lastCall.args.should.have.length(1);
			onerror.lastCall.args[0].should.match(/write failure/i);
		});

		it('can be a writable stream', function() {
			// Default constructor.
			var svg = new Rsvg();
			svg.should.be.an.instanceof(Writable);
			svg.width.should.equal(0);
			svg.height.should.equal(0);

			// Write to stream and basic test.
			svg.write('<svg width="4" height="6">').should.be.true;
			svg.width.should.equal(4);
			svg.height.should.equal(6);

			// Stream options.
			svg = new Rsvg({ highWaterMark: 16 });
			svg.write('<svg width="4" height="6">').should.be.false;
		});

		it('emits load event when ready - from stream', function(done) {
			var onload = sinon.spy();
			var svg = new Rsvg();
			svg.on('load', onload);
			svg.write('<svg width="4" height="6">');
			svg.write('</svg>');
			onload.should.not.have.been.called;
			svg.end();
			process.nextTick(function() {
				onload.should.have.been.calledOnce;
				onload.should.have.been.calledWithExactly();
				done();
			});
		});

		it('emits load event when ready - from svg', function(done) {
			var onload = sinon.spy();
			var svg = new Rsvg();
			svg.on('load', onload);
			onload = sinon.spy();
			svg = new Rsvg('<svg width="2" height="3"></svg>');
			svg.on('load', onload);
			onload.should.not.have.been.called;
			process.nextTick(function() {
				onload.should.have.been.calledOnce;
				onload.should.have.been.calledWithExactly();
				done();
			});
		});

		it('gives an error for invalid SVG content', function() {
			// Stream.
			var onerror = sinon.spy();
			var svg = new Rsvg();
			svg.on('error', onerror);
			svg.write('this is not a SVG file');
			onerror.should.have.been.calledOnce;
			svg.write('this is not a SVG file');
			onerror.should.have.been.calledTwice;
			onerror.lastCall.args.should.have.length(1);
			onerror.lastCall.args[0].should.match(/write failure/);

			// Constructed with SVG.
			function loadInvalidSVG() {
				/*jshint -W031 */
				new Rsvg('this is not a SVG file');
				/*jshint +W031 */
			}
			loadInvalidSVG.should.throw(/load failure/i);

			// Regression test on 2014-01-16.
			onerror = sinon.spy();
			svg = new Rsvg();
			svg.on('error', onerror);
			svg.end('<svg width="100" height="100"></svg>invalid');
			onerror.should.have.been.calledOnce;
			onerror.lastCall.args.should.have.length(1);
			onerror.lastCall.args[0].should.match(/write failure/);
		});
	});

	describe('baseURI', function() {
		it('allows to reference external SVGs');
	});

	describe('width', function() {
		it('gives the horizontal size', function() {
			new Rsvg('<svg width="314" height="1"/>').width.should.equal(314);
			new Rsvg('<svg width="257" height="2"/>').width.should.equal(257);
		});
	});

	describe('height', function() {
		it('gives the vertical size', function() {
			new Rsvg('<svg width="1" height="413"/>').height.should.equal(413);
			new Rsvg('<svg width="2" height="752"/>').height.should.equal(752);
		});
	});

	describe('dimensions()', function() {
		it('gives the size of the whole image', function() {
			new Rsvg('<svg width="314" height="257"/>').dimensions().should.deep.equal({
				x: 0,
				y: 0,
				width: 314,
				height: 257
			});
			new Rsvg('<svg width="17" height="19"/>').dimensions().should.deep.equal({
				x: 0,
				y: 0,
				width: 17,
				height: 19
			});
		});

		it('gives the size and position of specific elements', function() {
			var svg = new Rsvg();
			svg.write('<svg width="12" height="10">');
			svg.write('<rect x="-2" y="3" width="7" height="5" id="r1"/>');
			svg.write('<rect x="8" y="4" width="4" height="6" id="r2"/>');
			svg.write('<circle cx="8" cy="3" r="3" id="circ"/>');
			svg.write('</svg>');
			svg.end();

			svg.dimensions().should.deep.equal({
				x: 0,
				y: 0,
				width: 12,
				height: 10
			});
			svg.dimensions(null).should.deep.equal(svg.dimensions());

			svg.dimensions('#r1').should.deep.equal({
				x: -2,
				y: 3,
				width: 7,
				height: 5
			});
			svg.dimensions('#r2').should.deep.equal({
				x: 8,
				y: 4,
				width: 4,
				height: 6
			});
			svg.dimensions('#circ').should.deep.equal({
				x: 5,
				y: 0,
				width: 6,
				height: 6
			});
		});
	});

	describe('hasElement()', function() {
		it('determines whether an element with the given ID exists', function() {
			var svg = new Rsvg();
			svg.write('<svg width="12" height="10">');
			svg.write('<rect x="-2" y="3" width="7" height="5" id="r1"/>');
			svg.write('<rect x="8" y="4" width="4" height="6" id="r2"/>');
			svg.write('<circle cx="8" cy="3" r="3" id="circ"/>');
			svg.write('</svg>');
			svg.end();

			svg.hasElement().should.be.false;
			svg.hasElement(null).should.be.false;
			svg.hasElement('#r1').should.be.true;
			svg.hasElement('#r2').should.be.true;
			svg.hasElement('#circ').should.be.true;
			svg.hasElement('#foo').should.be.false;
			svg.hasElement('r1').should.be.false;
		});
	});

	describe('autocrop()', function() {
		it('finds the drawing area of the SVG');
	});

	describe('render()', function() {
		it('does nothing for an empty SVG document');
		it('renders as a raw memory buffer');
		it('renders as a PNG image');
		it('renders as a PDF document');
		it('renders as a PDF document');
		it('renders in various image sizes');
		it('can render specific SVG elements');
		it('can render a specific area [future]');
		it('can trim the image to a given rect [future]');
		it('can resize to fit inside box [future]');
		it('can resize to fit outside box [future]');
		it('can resize while ignoring aspect ratio [future]');
		it('can resize with a focus point [future]');
		it('can add a background color [future]');
	});

	describe('toString()', function() {
		it('gives a string representation', function() {
			var svg = new Rsvg();
			svg.toString().should.equal('{ [Rsvg] width: 0, height: 0 }');

			svg = new Rsvg('<svg width="3" height="7"></svg>');
			svg.toString().should.equal('{ [Rsvg] width: 3, height: 7 }');
		});
	});

	describe('reference rendering', function () {
		var items = fs.readdirSync('./test/svg/');
		// sinon.assert.pass = function (message) {  console.log(message); };
		items.forEach(function (testcase) {
			if (testcase.slice(-4) === '.svg') {
				it('png image should match the reference image "' + testcase + '"', function () {
					var fn = testcase.slice(0, -4);
					var input = fs.readFileSync('./test/svg/' + fn + '.svg');
					var svg = new Rsvg(input);
					var rendering = new Buffer(svg.render({
						format: 'png',
						width: svg.width,
						height: svg.height
					}).data);

					var compare = function (rendering, referenceFn) {
						var reference = fs.readFileSync('./test/png/' + referenceFn + '.png');
						return Buffer.compare(reference, rendering);
					};

					if( compare(rendering, fn) === 0 ){
						return;
					} else {
						var i = 1;
						while (fs.existsSync('./test/png/' + fn + '-variant' + i + '.png')){
							if ( compare(rendering,  fn + '-variant' + i ) === 0){
								sinon.assert.pass(fn + ' passed using alternative ' + i);
								return;
							}
							i++;
						}
					}
					var base64 = 'data:image/png;base64,' + rendering.toString('base64');
					sinon.assert.fail('image does not match reference:\n' + base64);
				});
			}
		});
	});
});
<|endoftext|>


<commit_before>var http = require('http');
var https = require('https');
var parseUrl = require('url').parse;
var net = require('net');
var path = require('path');
var StringDecoder = require('string_decoder').StringDecoder;
require('should');
require('should-http');
var fs = require('fs');
var fse = require('fs-extra2');
var startWhistle = require('../index');
var socks = require('socksv5');
var util = require('./util.test');
var config = require('./config.test');
var events = require('./events');
var values = util.getValues();
var testList = fs.readdirSync(path.join(__dirname, './units'));
var defaultRules = fs.readFileSync(path.join(__dirname, 'rules.txt'), {encoding: 'utf8'});
var options = {
  key: fs.readFileSync(path.join(__dirname, 'assets/certs/root.key')),
  cert: fs.readFileSync(path.join(__dirname, 'assets/certs/_root.crt'))
};
var count = 6;

var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({ port: config.wsPort });
var WHISTLE_PATH = process.env.WHISTLE_PATH = __dirname;
var PLUGINS_PATH = path.join(WHISTLE_PATH, '.whistle/node_modules');
//Node7及以下使用非SNI Server
if (process.versions.modules <= 51) {
  require('hagent').serverAgent.existsServer = function() {
    return true;
  };
}

fse.removeSync(path.join(WHISTLE_PATH, '.whistle'));
fse.copySync(path.join(__dirname, 'plugins'), PLUGINS_PATH);

wss.on('connection', function connection(ws) {
  var req = ws.upgradeReq;
  ws.on('message', function(msg) {
    ws.send(JSON.stringify({
      type: 'server',
      method: req.method,
      headers: req.headers,
      body: msg
    }, null, '\t'));
  });
});

http.createServer(function(req, res) {
  req.on('error', util.noop);
  res.on('error', util.noop);

  var body = '';
  var decoder = new StringDecoder('utf8');
  req.on('data', function(data) {
    body += decoder.write(data);
  });
  req.on('end', function() {
    body += decoder.end();
    res.end(JSON.stringify({
      type: 'server',
      url: req.url,
      method: req.method,
      headers: req.headers,
      body: body
    }, null, '\t'));
  });
}).listen(config.serverPort, startTest);

https.createServer(options, function(req, res) {
  if (req.url.indexOf('test-remote.rules') !== -1) {
    return res.end('str2.w2.org/index.html file://`(${search.replace(a,b)})`\nstr2.w2.org/index2.html file://`(${query.replace(/a/g,b)})`');
  }
  res.end(JSON.stringify({
    headers: req.headers,
    body: 'test'
  }));
}).listen(config.httpsPort, startTest);
values['options.html'] = {
  method: 'options'
};
var proxy = startWhistle({
  port: config.port,
  storage: 'test_',
  certDir: path.join(__dirname, 'assets/certs'),
  debugMode: true,
  localUIHost: 'local.whistle.com|local2.whistle.com&localn.whistle.com',
  pluginHost: 'test=test.local.whistle.com|b.test.local.whistle.com&test3.local.whistle.com,',
  rules: {
    Default: defaultRules,
    test: {
      rules: 'test.options.com file://{options.html}\n@'
        + path.join(__dirname, 'assets/files/rules.txt')
        + '\n@https://127.0.0.1:' + config.httpsPort + '/test-remote.rules',
      enable: true
    },
    abc: '123'
  },
  values: values,
  copy: true
}, startTest);

proxy.on('tunnelRequest', util.noop);
proxy.on('wsRequest', util.noop);
proxy.on('_request', util.noop);
var socksServer = socks.createServer(function(info, accept, deny) {
  var socket, client;
  if (info.dstPort === 443) {
    if (socket = accept(true)) {
      client = net.connect({
        host: '127.0.0.1',
        port: 5566
      }, function() {
        socket.pipe(client).pipe(socket);
      });
    }
    return;
  }
  if (info.dstPort === 8081) {
    if (socket = accept(true)) {
      client = net.connect({
        host: '127.0.0.1',
        port: 8081
      }, function() {
        socket.pipe(client).pipe(socket);
      });
    }
    return;
  }
  if (socket = accept(true)) {
    var body = JSON.stringify({
      port: config.socksPort
    });
    socket.end([
      'HTTP/1.1 200 OK',
      'Connection: close',
      'Content-Type: text/plain;charset=utf8',
      'Content-Length: ' + Buffer.byteLength(body),
      '',
      body
    ].join('\r\n'));
  }
});

var authSocksServer = socks.createServer(function(info, accept, deny) {
  var socket;
  if (info.dstPort === 443) {
    if (socket = accept(true)) {
      var client = net.connect({
        host: '127.0.0.1',
        port: 5566
      }, function() {
        socket.pipe(client).pipe(socket);
      });
    }
    return;
  }
  if (socket = accept(true)) {
    var body = JSON.stringify({
      port: config.authSocksPort
    });
    socket.end([
      'HTTP/1.1 200 OK',
      'Connection: close',
      'Content-Type: text/plain;charset=utf8',
      'Content-Length: ' + Buffer.byteLength(body),
      '',
      body
    ].join('\r\n'));
  }
});

socksServer.useAuth(socks.auth.None());
authSocksServer.useAuth(socks.auth.UserPassword(function(user, password, cb) {
  cb(user == 'test' && password == 'hello1234');
}));

socksServer.listen(config.socksPort, startTest);
authSocksServer.listen(config.authSocksPort, startTest);

/**
 * 不用处理异常
 */
var server = http.createServer(function(req, res) {
  var fullUrl = /^http:/.test(req.url) ? req.url : 'http://' + req.headers.host + req.url;
  var options = parseUrl(fullUrl);
  delete options.hostname;
  options.host = '127.0.0.1';
  options.method = req.method;
  options.headers = req.headers;
  var client = http.request(options, function(_res) {
    _res.pipe(res);
  });
  req.pipe(client);
});

server.on('connect', function(req, socket) {
  var tunnelUrl = 'tunnel://' + (/^[^:\/]+:\d+$/.test(req.url) ? req.url : req.headers.host);
  var options = parseUrl(tunnelUrl);
  var client = net.connect({
    host: '127.0.0.1',
    port: options.port || 443
  }, function() {
    socket.pipe(client).pipe(socket);
    socket.write('HTTP/1.1 200 Connection Established\r\nProxy-Agent: whistle/test\r\n\r\n');
  });
});

server.listen(config.proxyPort, startTest);

function startTest() {
  if (--count > 0) {
    return;
  }

  var done;
  function testAll() {
    if (done) {
      return;
    }
    done = true;
    var lastUnit = 'ui.test.js';
    testList.splice(testList.indexOf(lastUnit), 1);
    testList.splice(testList.indexOf('tplStr.test.js'), 1);
    testList.push('tplStr.test.js');
    testList = testList.map(function(name) {
      return require('./units/' + name);
    });
    lastUnit = require('./units/' + lastUnit);
    var stride = 30;
    var execUnit = function() {
      var list = testList.slice(0, stride);
      if (!list.length) {
        util.setEnd();
        lastUnit();
        return true;
      }
      testList = testList.slice(stride);
      list.forEach(function(fn) {
        fn();
      });
    };
    execUnit();
    events.on('next', execUnit);
  }
  var index = 0;
  (function getData() {
    var query = '?name=host&value=com&url=com';
    var dataUrl = 'http://local.whistlejs.com/cgi-bin/get-data';
    if (++index > 2) {
      index = 0;
      dataUrl += query + 'ip=self,1.1.1.1';
    } else if (index === 1) {
      dataUrl += query + 'ip=self';
    }
    util.request(dataUrl, function() {
      testAll();
      setTimeout(getData, 10000);
    });
  })();
}

<commit_msg>test: strict mode<commit_after>var http = require('http');
var https = require('https');
var parseUrl = require('url').parse;
var net = require('net');
var path = require('path');
var StringDecoder = require('string_decoder').StringDecoder;
require('should');
require('should-http');
var fs = require('fs');
var fse = require('fs-extra2');
var startWhistle = require('../index');
var socks = require('socksv5');
var util = require('./util.test');
var config = require('./config.test');
var events = require('./events');
var values = util.getValues();
var testList = fs.readdirSync(path.join(__dirname, './units'));
var defaultRules = fs.readFileSync(path.join(__dirname, 'rules.txt'), {encoding: 'utf8'});
var options = {
  key: fs.readFileSync(path.join(__dirname, 'assets/certs/root.key')),
  cert: fs.readFileSync(path.join(__dirname, 'assets/certs/_root.crt'))
};
var count = 6;

var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({ port: config.wsPort });
var WHISTLE_PATH = process.env.WHISTLE_PATH = __dirname;
var PLUGINS_PATH = path.join(WHISTLE_PATH, '.whistle/node_modules');
//Node7及以下使用非SNI Server
if (process.versions.modules <= 51) {
  require('hagent').serverAgent.existsServer = function() {
    return true;
  };
}

fse.removeSync(path.join(WHISTLE_PATH, '.whistle'));
fse.copySync(path.join(__dirname, 'plugins'), PLUGINS_PATH);

wss.on('connection', function connection(ws) {
  var req = ws.upgradeReq;
  ws.on('message', function(msg) {
    ws.send(JSON.stringify({
      type: 'server',
      method: req.method,
      headers: req.headers,
      body: msg
    }, null, '\t'));
  });
});

http.createServer(function(req, res) {
  req.on('error', util.noop);
  res.on('error', util.noop);

  var body = '';
  var decoder = new StringDecoder('utf8');
  req.on('data', function(data) {
    body += decoder.write(data);
  });
  req.on('end', function() {
    body += decoder.end();
    res.end(JSON.stringify({
      type: 'server',
      url: req.url,
      method: req.method,
      headers: req.headers,
      body: body
    }, null, '\t'));
  });
}).listen(config.serverPort, startTest);

https.createServer(options, function(req, res) {
  if (req.url.indexOf('test-remote.rules') !== -1) {
    return res.end('str2.w2.org/index.html file://`(${search.replace(a,b)})`\nstr2.w2.org/index2.html file://`(${query.replace(/a/g,b)})`');
  }
  res.end(JSON.stringify({
    headers: req.headers,
    body: 'test'
  }));
}).listen(config.httpsPort, startTest);
values['options.html'] = {
  method: 'options'
};
var proxy = startWhistle({
  port: config.port,
  storage: 'test_',
  mode: 'strict',
  certDir: path.join(__dirname, 'assets/certs'),
  debugMode: true,
  localUIHost: 'local.whistle.com|local2.whistle.com&localn.whistle.com',
  pluginHost: 'test=test.local.whistle.com|b.test.local.whistle.com&test3.local.whistle.com,',
  rules: {
    Default: defaultRules,
    test: {
      rules: 'test.options.com file://{options.html}\n@'
        + path.join(__dirname, 'assets/files/rules.txt')
        + '\n@https://127.0.0.1:' + config.httpsPort + '/test-remote.rules',
      enable: true
    },
    abc: '123'
  },
  values: values,
  copy: true
}, startTest);

proxy.on('tunnelRequest', util.noop);
proxy.on('wsRequest', util.noop);
proxy.on('_request', util.noop);
var socksServer = socks.createServer(function(info, accept, deny) {
  var socket, client;
  if (info.dstPort === 443) {
    if (socket = accept(true)) {
      client = net.connect({
        host: '127.0.0.1',
        port: 5566
      }, function() {
        socket.pipe(client).pipe(socket);
      });
    }
    return;
  }
  if (info.dstPort === 8081) {
    if (socket = accept(true)) {
      client = net.connect({
        host: '127.0.0.1',
        port: 8081
      }, function() {
        socket.pipe(client).pipe(socket);
      });
    }
    return;
  }
  if (socket = accept(true)) {
    var body = JSON.stringify({
      port: config.socksPort
    });
    socket.end([
      'HTTP/1.1 200 OK',
      'Connection: close',
      'Content-Type: text/plain;charset=utf8',
      'Content-Length: ' + Buffer.byteLength(body),
      '',
      body
    ].join('\r\n'));
  }
});

var authSocksServer = socks.createServer(function(info, accept, deny) {
  var socket;
  if (info.dstPort === 443) {
    if (socket = accept(true)) {
      var client = net.connect({
        host: '127.0.0.1',
        port: 5566
      }, function() {
        socket.pipe(client).pipe(socket);
      });
    }
    return;
  }
  if (socket = accept(true)) {
    var body = JSON.stringify({
      port: config.authSocksPort
    });
    socket.end([
      'HTTP/1.1 200 OK',
      'Connection: close',
      'Content-Type: text/plain;charset=utf8',
      'Content-Length: ' + Buffer.byteLength(body),
      '',
      body
    ].join('\r\n'));
  }
});

socksServer.useAuth(socks.auth.None());
authSocksServer.useAuth(socks.auth.UserPassword(function(user, password, cb) {
  cb(user == 'test' && password == 'hello1234');
}));

socksServer.listen(config.socksPort, startTest);
authSocksServer.listen(config.authSocksPort, startTest);

/**
 * 不用处理异常
 */
var server = http.createServer(function(req, res) {
  var fullUrl = /^http:/.test(req.url) ? req.url : 'http://' + req.headers.host + req.url;
  var options = parseUrl(fullUrl);
  delete options.hostname;
  options.host = '127.0.0.1';
  options.method = req.method;
  options.headers = req.headers;
  var client = http.request(options, function(_res) {
    _res.pipe(res);
  });
  req.pipe(client);
});

server.on('connect', function(req, socket) {
  var tunnelUrl = 'tunnel://' + (/^[^:\/]+:\d+$/.test(req.url) ? req.url : req.headers.host);
  var options = parseUrl(tunnelUrl);
  var client = net.connect({
    host: '127.0.0.1',
    port: options.port || 443
  }, function() {
    socket.pipe(client).pipe(socket);
    socket.write('HTTP/1.1 200 Connection Established\r\nProxy-Agent: whistle/test\r\n\r\n');
  });
});

server.listen(config.proxyPort, startTest);

function startTest() {
  if (--count > 0) {
    return;
  }

  var done;
  function testAll() {
    if (done) {
      return;
    }
    done = true;
    var lastUnit = 'ui.test.js';
    testList.splice(testList.indexOf(lastUnit), 1);
    testList.splice(testList.indexOf('tplStr.test.js'), 1);
    testList.push('tplStr.test.js');
    testList = testList.map(function(name) {
      return require('./units/' + name);
    });
    lastUnit = require('./units/' + lastUnit);
    var stride = 30;
    var execUnit = function() {
      var list = testList.slice(0, stride);
      if (!list.length) {
        util.setEnd();
        lastUnit();
        return true;
      }
      testList = testList.slice(stride);
      list.forEach(function(fn) {
        fn();
      });
    };
    execUnit();
    events.on('next', execUnit);
  }
  var index = 0;
  (function getData() {
    var query = '?name=host&value=com&url=com';
    var dataUrl = 'http://local.whistlejs.com/cgi-bin/get-data';
    if (++index > 2) {
      index = 0;
      dataUrl += query + 'ip=self,1.1.1.1';
    } else if (index === 1) {
      dataUrl += query + 'ip=self';
    }
    util.request(dataUrl, function() {
      testAll();
      setTimeout(getData, 10000);
    });
  })();
}

<|endoftext|>


<commit_before>import test from "jest-t-assert";
import xxhash from "../src";

// The test cases were taken from tests of other implementation and the
// resulting hashes have been generated by running another implementation.
// All cases used the seed 0.
const testCases = [
  { input: "", h32: "02cc5d05", h64: "ef46db3751d8e999" },
  { input: "a", h32: "550d7456", h64: "d24ec4f1a98c6e5b" },
  { input: "as", h32: "9d5a0464", h64: "1c330fb2d66be179" },
  { input: "asd", h32: "3d83552b", h64: "631c37ce72a97393" },
  { input: "asdf", h32: "5e702c32", h64: "415872f599cea71e" },
  { input: "abc", h32: "32d153ff", h64: "44bc2cf5ad770999" },
  { input: "abcd", h32: "a3643705", h64: "de0327b0d25d92cc" },
  { input: "0.7278296545100061", h32: "432c173f", h64: "596877150e8ee48c" },
  {
    input: "Call me Ishmael. Some years ago--never mind how long precisely-",
    h32: "6f320359",
    h64: "02a2e85470d6fd96",
  },
  {
    input:
      "The quick brown fox jumps over the lazy dog http://i.imgur.com/VHQXScB.gif",
    h32: "5ce7b616",
    h64: "93267f9820452ead",
  },
  { input: "heiå", h32: "db5abccc", h64: "b9d3d990d2001a1a" },
  { input: "κόσμε", h32: "d855f606", h64: "a0488960c70d8772" },
];

for (const testCase of testCases) {
  test(`h32 of ${testCase.input}`, async (t) => {
    const hasher = await xxhash();
    const h32 = hasher.h32(testCase.input);
    t.is(h32, testCase.h32);
  });

  test(`h32Raw of ${testCase.input}`, async (t) => {
    const encoder = new TextEncoder();
    const hasher = await xxhash();
    const h32 = hasher
      .h32Raw(encoder.encode(testCase.input))
      .toString(16)
      .padStart(8, "0");
    t.is(h32, testCase.h32);
  });

  test(`streamed h32 of ${testCase.input}`, async (t) => {
    const hasher = await xxhash();
    const h32 = hasher
      .create32()
      .update(testCase.input)
      .digest()
      .toString(16)
      .padStart(8, "0");
    t.is(h32, testCase.h32);
  });

  test(`h64 of ${testCase.input}`, async (t) => {
    const hasher = await xxhash();
    const h64 = hasher.h64(testCase.input);
    t.is(h64, testCase.h64);
  });

  test(`h64Raw of ${testCase.input}`, async (t) => {
    const encoder = new TextEncoder();
    const hasher = await xxhash();
    const h64 = hasher.h64Raw(encoder.encode(testCase.input));
    t.is(h64, BigInt(`0x${testCase.h64}`));
  });

  test(`streamed h64 of ${testCase.input}`, async (t) => {
    const hasher = await xxhash();
    const h64 = hasher
      .create64()
      .update(testCase.input)
      .digest()
      .toString(16)
      .padStart(16, "0");
    t.is(h64, testCase.h64);
  });
}

test("h32 with different seeds produces different hashes", async (t) => {
  const hasher = await xxhash();
  const input = "different seeds";
  const h320 = hasher.h32(input, 0);
  const h32abcd = hasher.h32(input, 0xabcd);
  t.not(h320, h32abcd);
});

test("h64 with different seeds produces different hashes", async (t) => {
  const hasher = await xxhash();
  const input = "different seeds";
  const h640 = hasher.h64(input, 0n);
  const h64lowAbcd = hasher.h64(input, BigInt(0xabcd));
  const h64highAbcd = hasher.h64(input, BigInt(0xabcd) << (32n + BigInt(0)));
  t.not(h640, h64lowAbcd);
  t.not(h640, h64highAbcd);
  t.not(h64lowAbcd, h64highAbcd);
});

test("a string greater than the initial memory size works", async (t) => {
  const hasher = await xxhash();
  const bytesPerPage = 64 * 1024;
  const input = "z".repeat(bytesPerPage + 1);
  const h32 = hasher.h32(input, 0);
  const h64 = hasher.h64(input, 0n);
  t.is(h32, "7871ee9b");
  t.is(h64, "68278ba56dc14510");
});

test("streamed h32 with multiple inputs produces same hash", async (t) => {
  const hasher = await xxhash();
  const { update, digest } = hasher.create32(0);
  update("hello");
  update("world");
  t.is(digest().toString(16).padStart(8, "0"), hasher.h32("helloworld"));
});

test("streamed h64 with multiple inputs produces same hash", async (t) => {
  const hasher = await xxhash();
  const { update, digest } = hasher.create64(0n);
  update("hello");
  update("world");
  t.is(digest().toString(16).padStart(16, "0"), hasher.h64("helloworld"));
});
<commit_msg>Add complete test coverage of new APIs<commit_after>import test from "jest-t-assert";
import xxhash from "../src";

// The test cases were taken from tests of other implementation and the
// resulting hashes have been generated by running another implementation.
// All cases used the seed 0.
const testCases = [
  { input: "", h32: "02cc5d05", h64: "ef46db3751d8e999" },
  { input: "a", h32: "550d7456", h64: "d24ec4f1a98c6e5b" },
  { input: "as", h32: "9d5a0464", h64: "1c330fb2d66be179" },
  { input: "asd", h32: "3d83552b", h64: "631c37ce72a97393" },
  { input: "asdf", h32: "5e702c32", h64: "415872f599cea71e" },
  { input: "abc", h32: "32d153ff", h64: "44bc2cf5ad770999" },
  { input: "abcd", h32: "a3643705", h64: "de0327b0d25d92cc" },
  { input: "0.7278296545100061", h32: "432c173f", h64: "596877150e8ee48c" },
  {
    input: "Call me Ishmael. Some years ago--never mind how long precisely-",
    h32: "6f320359",
    h64: "02a2e85470d6fd96",
  },
  {
    input:
      "The quick brown fox jumps over the lazy dog http://i.imgur.com/VHQXScB.gif",
    h32: "5ce7b616",
    h64: "93267f9820452ead",
  },
  { input: "heiå", h32: "db5abccc", h64: "b9d3d990d2001a1a" },
  { input: "κόσμε", h32: "d855f606", h64: "a0488960c70d8772" },
];

for (const testCase of testCases) {
  test(`h32 of ${testCase.input}`, async (t) => {
    const hasher = await xxhash();
    const h32 = hasher.h32(testCase.input);
    t.is(h32, testCase.h32);
  });

  test(`h32Raw of ${testCase.input}`, async (t) => {
    const encoder = new TextEncoder();
    const hasher = await xxhash();
    const h32 = hasher
      .h32Raw(encoder.encode(testCase.input))
      .toString(16)
      .padStart(8, "0");
    t.is(h32, testCase.h32);
  });

  test(`h32String of ${testCase.input}`, async (t) => {
    const hasher = await xxhash();
    const h32 = hasher.h32String(testCase.input).toString(16).padStart(8, "0");
    t.is(h32, testCase.h32);
  });

  test(`streamed h32 of ${testCase.input}`, async (t) => {
    const hasher = await xxhash();
    const h32 = hasher
      .create32()
      .update(testCase.input)
      .digest()
      .toString(16)
      .padStart(8, "0");
    t.is(h32, testCase.h32);
  });

  test(`h64 of ${testCase.input}`, async (t) => {
    const hasher = await xxhash();
    const h64 = hasher.h64(testCase.input);
    t.is(h64, testCase.h64);
  });

  test(`h64Raw of ${testCase.input}`, async (t) => {
    const encoder = new TextEncoder();
    const hasher = await xxhash();
    const h64 = hasher.h64Raw(encoder.encode(testCase.input));
    t.is(h64, BigInt(`0x${testCase.h64}`));
  });

  test(`h64String of ${testCase.input}`, async (t) => {
    const hasher = await xxhash();
    const h64 = hasher.h64String(testCase.input);
    t.is(h64, BigInt(`0x${testCase.h64}`));
  });

  test(`streamed h64 of ${testCase.input}`, async (t) => {
    const hasher = await xxhash();
    const h64 = hasher
      .create64()
      .update(testCase.input)
      .digest()
      .toString(16)
      .padStart(16, "0");
    t.is(h64, testCase.h64);
  });
}

test("h32 with different seeds produces different hashes", async (t) => {
  const hasher = await xxhash();
  const input = "different seeds";
  const h320 = hasher.h32(input, 0);
  const h32abcd = hasher.h32(input, 0xabcd);
  t.not(h320, h32abcd);
});

test("h64 with different seeds produces different hashes", async (t) => {
  const hasher = await xxhash();
  const input = "different seeds";
  const h640 = hasher.h64(input, 0n);
  const h64lowAbcd = hasher.h64(input, BigInt(0xabcd));
  const h64highAbcd = hasher.h64(input, BigInt(0xabcd) << (32n + BigInt(0)));
  t.not(h640, h64lowAbcd);
  t.not(h640, h64highAbcd);
  t.not(h64lowAbcd, h64highAbcd);
});

test("a string greater than the initial memory size works", async (t) => {
  const hasher = await xxhash();
  const bytesPerPage = 64 * 1024;
  const input = "z".repeat(bytesPerPage + 1);
  const h32 = hasher.h32(input, 0);
  const h64 = hasher.h64(input, 0n);
  t.is(h32, "7871ee9b");
  t.is(h64, "68278ba56dc14510");
});

test("streamed h32 with multiple inputs produces same hash", async (t) => {
  const hasher = await xxhash();
  const { update, digest } = hasher.create32(0);
  update("hello");
  update("world");
  t.is(digest().toString(16).padStart(8, "0"), hasher.h32("helloworld"));
});

test("streamed h64 with multiple inputs produces same hash", async (t) => {
  const hasher = await xxhash();
  const { update, digest } = hasher.create64(0n);
  update("hello");
  update("world");
  t.is(digest().toString(16).padStart(16, "0"), hasher.h64("helloworld"));
});

test("streamed h32 with buffer input produces same hash", async (t) => {
  const input = Buffer.from("helloworld");
  const hasher = await xxhash();
  t.is(hasher.create32(0).update(input).digest(), hasher.h32Raw(input));
});

test("streamed h64 with buffer input produces same hash", async (t) => {
  const input = Buffer.from("helloworld");
  const hasher = await xxhash();
  t.is(hasher.create64(0n).update(input).digest(), hasher.h64Raw(input));
});
<|endoftext|>


<commit_before>var http = require('http');
var https = require('https');
var parseUrl = require('url').parse;
var net = require('net');
var path = require('path');
var StringDecoder = require('string_decoder').StringDecoder;
require('should');
require('should-http');
var fs = require('fs');
var fse = require('fs-extra');
var startWhistle = require('../index');
var socks = require('socksv5');
var util = require('./util.test');
var config = require('./config.test');
var values = util.getValues();
var testList = fs.readdirSync(path.join(__dirname, './units')).map(function(name) {
  return require('./units/' + name);
});
testList = [require('./units/tunnelPolicy.test')];
var options = {
  key: fs.readFileSync(path.join(__dirname, 'assets/certs/root.key')),
  cert: fs.readFileSync(path.join(__dirname, 'assets/certs/root.crt'))
};
var count = 6;

var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({ port: config.wsPort });
var WHISTLE_PATH = process.env.WHISTLE_PATH = __dirname;
var PLUGINS_PATH = path.join(WHISTLE_PATH, '.whistle/node_modules');

fse.removeSync(path.join(WHISTLE_PATH, '.whistle'));
fse.copySync(path.join(__dirname, 'plugins'), PLUGINS_PATH);

wss.on('connection', function connection(ws) {
  var req = ws.upgradeReq;
  ws.on('message', function(msg) {
    ws.send(JSON.stringify({
      type: 'server',
      method: req.method,
      headers: req.headers,
      body: msg
    }, null, '\t'));
  });
});

http.createServer(function(req, res) {
  req.on('error', util.noop);
  res.on('error', util.noop);

  var body = '';
  var decoder = new StringDecoder('utf8');
  req.on('data', function(data) {
    body += decoder.write(data);
  });
  req.on('end', function() {
    body += decoder.end();
    res.end(JSON.stringify({
      type: 'server',
      url: req.url,
      method: req.method,
      headers: req.headers,
      body: body
    }, null, '\t'));
  });
}).listen(config.serverPort, startTest);

https.createServer(options, function(req, res) {
  res.end(JSON.stringify({
    headers: req.headers,
    body: 'test'
  }));
}).listen(config.httpsPort, startTest);

startWhistle({
  port: config.port,
  storage: 'test_',
  debugMode: true,
  localUIHost: 'local.whistle.com',
  rules: fs.readFileSync(path.join(__dirname, 'rules.txt'), {encoding: 'utf8'}),
  values: values
}, startTest);

var socksServer = socks.createServer(function(info, accept, deny) {
  var socket;
  if (info.dstPort === 443) {
    if (socket = accept(true)) {
      var client = net.connect({
        host: '127.0.0.1',
        port: 5566
      }, function() {
        socket.pipe(client).pipe(socket);
      });
    }
    return;
  }
  if (socket = accept(true)) {
    var body = JSON.stringify({
      port: config.socksPort
    });
    socket.end([
      'HTTP/1.1 200 OK',
      'Connection: close',
      'Content-Type: text/plain;charset=utf8',
      'Content-Length: ' + Buffer.byteLength(body),
      '',
      body
    ].join('\r\n'));
  }
});

var authSocksServer = socks.createServer(function(info, accept, deny) {
  var socket;
  if (info.dstPort === 443) {
    if (socket = accept(true)) {
      var client = net.connect({
        host: '127.0.0.1',
        port: 5566
      }, function() {
        socket.pipe(client).pipe(socket);
      });
    }
    return;
  }
  if (socket = accept(true)) {
    var body = JSON.stringify({
      port: config.authSocksPort
    });
    socket.end([
      'HTTP/1.1 200 OK',
      'Connection: close',
      'Content-Type: text/plain;charset=utf8',
      'Content-Length: ' + Buffer.byteLength(body),
      '',
      body
    ].join('\r\n'));
  }
});

socksServer.useAuth(socks.auth.None());
authSocksServer.useAuth(socks.auth.UserPassword(function(user, password, cb) {
  cb(user == 'test' && password == 'hello1234');
}));

socksServer.listen(config.socksPort, startTest);
authSocksServer.listen(config.authSocksPort, startTest);

/**
 * 不用处理异常
 */
var server = http.createServer(function(req, res) {
  var fullUrl = /^http:/.test(req.url) ? req.url : 'http://' + req.headers.host + req.url;
  var options = parseUrl(fullUrl);
  delete options.hostname;
  options.host = '127.0.0.1';
  options.method = req.method;
  options.headers = req.headers;
  var client = http.request(options, function(_res) {
    _res.pipe(res);
  });
  req.pipe(client);
});

server.on('connect', function(req, socket) {
  var tunnelUrl = 'tunnel://' + (/^[^:\/]+:\d+$/.test(req.url) ? req.url : req.headers.host);
  var options = parseUrl(tunnelUrl);
  var client = net.connect({
    host: '127.0.0.1',
    port: options.port || 443
  }, function() {
    socket.pipe(client).pipe(socket);
    socket.write('HTTP/1.1 200 Connection Established\r\nProxy-Agent: whistle/test\r\n\r\n');
  });
});

server.listen(config.proxyPort, startTest);

function startTest() {
  if (--count > 0) {
    return;
  }

  var done;
  function testAll() {
    if (done) {
      return;
    }
    done = true;
    testList.forEach(function(fn) {
      fn();
    });
  }

  (function getData() {
    util.request('http://local.whistlejs.com/cgi-bin/get-data', function() {
      testAll();
      setTimeout(getData, 5000);
    });
  })();
}

<commit_msg>test: tunnel.headers[x-whistle-policy] = tunnel<commit_after>var http = require('http');
var https = require('https');
var parseUrl = require('url').parse;
var net = require('net');
var path = require('path');
var StringDecoder = require('string_decoder').StringDecoder;
require('should');
require('should-http');
var fs = require('fs');
var fse = require('fs-extra');
var startWhistle = require('../index');
var socks = require('socksv5');
var util = require('./util.test');
var config = require('./config.test');
var values = util.getValues();
var testList = fs.readdirSync(path.join(__dirname, './units')).map(function(name) {
  return require('./units/' + name);
});
var options = {
  key: fs.readFileSync(path.join(__dirname, 'assets/certs/root.key')),
  cert: fs.readFileSync(path.join(__dirname, 'assets/certs/root.crt'))
};
var count = 6;

var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({ port: config.wsPort });
var WHISTLE_PATH = process.env.WHISTLE_PATH = __dirname;
var PLUGINS_PATH = path.join(WHISTLE_PATH, '.whistle/node_modules');

fse.removeSync(path.join(WHISTLE_PATH, '.whistle'));
fse.copySync(path.join(__dirname, 'plugins'), PLUGINS_PATH);

wss.on('connection', function connection(ws) {
  var req = ws.upgradeReq;
  ws.on('message', function(msg) {
    ws.send(JSON.stringify({
      type: 'server',
      method: req.method,
      headers: req.headers,
      body: msg
    }, null, '\t'));
  });
});

http.createServer(function(req, res) {
  req.on('error', util.noop);
  res.on('error', util.noop);

  var body = '';
  var decoder = new StringDecoder('utf8');
  req.on('data', function(data) {
    body += decoder.write(data);
  });
  req.on('end', function() {
    body += decoder.end();
    res.end(JSON.stringify({
      type: 'server',
      url: req.url,
      method: req.method,
      headers: req.headers,
      body: body
    }, null, '\t'));
  });
}).listen(config.serverPort, startTest);

https.createServer(options, function(req, res) {
  res.end(JSON.stringify({
    headers: req.headers,
    body: 'test'
  }));
}).listen(config.httpsPort, startTest);

startWhistle({
  port: config.port,
  storage: 'test_',
  debugMode: true,
  localUIHost: 'local.whistle.com',
  rules: fs.readFileSync(path.join(__dirname, 'rules.txt'), {encoding: 'utf8'}),
  values: values
}, startTest);

var socksServer = socks.createServer(function(info, accept, deny) {
  var socket;
  if (info.dstPort === 443) {
    if (socket = accept(true)) {
      var client = net.connect({
        host: '127.0.0.1',
        port: 5566
      }, function() {
        socket.pipe(client).pipe(socket);
      });
    }
    return;
  }
  if (socket = accept(true)) {
    var body = JSON.stringify({
      port: config.socksPort
    });
    socket.end([
      'HTTP/1.1 200 OK',
      'Connection: close',
      'Content-Type: text/plain;charset=utf8',
      'Content-Length: ' + Buffer.byteLength(body),
      '',
      body
    ].join('\r\n'));
  }
});

var authSocksServer = socks.createServer(function(info, accept, deny) {
  var socket;
  if (info.dstPort === 443) {
    if (socket = accept(true)) {
      var client = net.connect({
        host: '127.0.0.1',
        port: 5566
      }, function() {
        socket.pipe(client).pipe(socket);
      });
    }
    return;
  }
  if (socket = accept(true)) {
    var body = JSON.stringify({
      port: config.authSocksPort
    });
    socket.end([
      'HTTP/1.1 200 OK',
      'Connection: close',
      'Content-Type: text/plain;charset=utf8',
      'Content-Length: ' + Buffer.byteLength(body),
      '',
      body
    ].join('\r\n'));
  }
});

socksServer.useAuth(socks.auth.None());
authSocksServer.useAuth(socks.auth.UserPassword(function(user, password, cb) {
  cb(user == 'test' && password == 'hello1234');
}));

socksServer.listen(config.socksPort, startTest);
authSocksServer.listen(config.authSocksPort, startTest);

/**
 * 不用处理异常
 */
var server = http.createServer(function(req, res) {
  var fullUrl = /^http:/.test(req.url) ? req.url : 'http://' + req.headers.host + req.url;
  var options = parseUrl(fullUrl);
  delete options.hostname;
  options.host = '127.0.0.1';
  options.method = req.method;
  options.headers = req.headers;
  var client = http.request(options, function(_res) {
    _res.pipe(res);
  });
  req.pipe(client);
});

server.on('connect', function(req, socket) {
  var tunnelUrl = 'tunnel://' + (/^[^:\/]+:\d+$/.test(req.url) ? req.url : req.headers.host);
  var options = parseUrl(tunnelUrl);
  var client = net.connect({
    host: '127.0.0.1',
    port: options.port || 443
  }, function() {
    socket.pipe(client).pipe(socket);
    socket.write('HTTP/1.1 200 Connection Established\r\nProxy-Agent: whistle/test\r\n\r\n');
  });
});

server.listen(config.proxyPort, startTest);

function startTest() {
  if (--count > 0) {
    return;
  }

  var done;
  function testAll() {
    if (done) {
      return;
    }
    done = true;
    testList.forEach(function(fn) {
      fn();
    });
  }

  (function getData() {
    util.request('http://local.whistlejs.com/cgi-bin/get-data', function() {
      testAll();
      setTimeout(getData, 5000);
    });
  })();
}

<|endoftext|>


<commit_before>var http = require('http');
var StringDecoder = require('string_decoder').StringDecoder;
var should = require('should');
require('should-http');
var startWhistle = require('../index');
var util = require('./util.test');
var config = require('./config.test');
var testList = ['host', 'rule', 'reqSpeed', 'resSpeed', 'reqDelay', 'resDelay', 'file', 'xfile',
                'referer', 'urlParams', 'params', 'ua', 'reqCharset', 'resCharset', 'reqType',
                'resType', 'reqCookies', 'resCookies', 'reqPrepend', 'resPrepend', 'accept', 'etag',
                'cache', 'statusCode', 'redirect', 'replaceStatus', 'reqBody', 'resBody', 'reqAppend', 'resAppend',
                'reqReplace', 'resReplace', 'req.prepend.body.append', 'res.prepend.body.append', 'dispatch',
                'reqCors', 'resCors', 'reqHeaders', 'resHeaders', 'js', 'css', 'html'].map(function(name) {
	return require('./' + name + '.test');
});
var count = 2;

startWhistle({
	port: config.port
}, startTest);

http.createServer(function(req, res) {
	req.on('error', util.noop);
	res.on('error', util.noop);

	var body = '';
	var decoder = new StringDecoder('utf8');
	req.on('data', function(data) {
		body += decoder.write(data);
	});
	req.on('end', function() {
		body += decoder.end();
		res.end(JSON.stringify({
			type: 'server',
			method: req.method,
			headers: req.headers,
			body: body
		}, null, '\t'))
	});
}).listen(config.serverPort, startTest);

function startTest() {
	if (--count > 0) {
		return;
	}

	testList.forEach(function(fn) {
		fn();
	});
}

<commit_msg>test: forward<commit_after>var http = require('http');
var StringDecoder = require('string_decoder').StringDecoder;
var should = require('should');
require('should-http');
var startWhistle = require('../index');
var util = require('./util.test');
var config = require('./config.test');
var testList = ['host', 'rule', 'reqSpeed', 'resSpeed', 'reqDelay', 'resDelay', 'file', 'xfile',
                'referer', 'urlParams', 'params', 'ua', 'reqCharset', 'resCharset', 'reqType',
                'resType', 'reqCookies', 'resCookies', 'reqPrepend', 'resPrepend', 'accept', 'etag',
                'cache', 'statusCode', 'redirect', 'replaceStatus', 'reqBody', 'resBody', 'reqAppend', 'resAppend',
                'reqReplace', 'resReplace', 'req.prepend.body.append', 'res.prepend.body.append', 'dispatch',
                'reqCors', 'resCors', 'reqHeaders', 'resHeaders', 'js', 'css', 'html', 'forward'].map(function(name) {
	return require('./' + name + '.test');
});
var count = 2;

startWhistle({
	port: config.port
}, startTest);

http.createServer(function(req, res) {
	req.on('error', util.noop);
	res.on('error', util.noop);

	var body = '';
	var decoder = new StringDecoder('utf8');
	req.on('data', function(data) {
		body += decoder.write(data);
	});
	req.on('end', function() {
		body += decoder.end();
		res.end(JSON.stringify({
			type: 'server',
			method: req.method,
			headers: req.headers,
			body: body
		}, null, '\t'))
	});
}).listen(config.serverPort, startTest);

function startTest() {
	if (--count > 0) {
		return;
	}

	testList.forEach(function(fn) {
		fn();
	});
}

<|endoftext|>


<commit_before>'use strict';

var expect = require('chai').expect;
var Dalek = require('../index.js');

describe('dalek', function() {

  it('should exist', function(){
    expect(Dalek).to.be.ok;
  });

});
<commit_msg>Improve testharness<commit_after>'use strict';

var expect = require('chai').expect;
var Dalek = require('../index.js');

describe('dalek', function () {

  it('should exist', function () {
    expect(Dalek).to.be.ok;
  });

  it('can shutdown on empty tests', function () {
    var oldProcessExit = process.exit;
    process.exit = function (code) {
      expect(code).to.equal(127);
    };
    var EventEmitter = require('events').EventEmitter;
    var dalek = new Dalek({
      tests: '',
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false,
      advanced: true
    });

    dalek.reporterEvents.on('error', function (message) {
      expect(message).to.equal('No test files given!');
    });

    dalek.driverEmitter.on('killAll', function () {
      expect(true).to.be.true;
    });

    process.exit = oldProcessExit;
  });

  it('can be initialized', function () {
    var dalek = new Dalek({
      tests: ['test/dalek/basic.js'],
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false
    });
    expect(dalek).to.be.ok;
  });

  it('can fire run finished event', function () {
    var dalek = new Dalek({
      tests: ['test/dalek/basic.js'],
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false
    });

    dalek.reporterEvents.on('report:runner:finished', function (data) {
      expect(data).to.be.an('object');
    });

    dalek.reportRunFinished();
  });

  it('can fire tests complete event', function () {
    var dalek = new Dalek({
      tests: ['test/dalek/basic.js'],
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false
    });

    dalek.driverEmitter.on('tests:complete', function () {
      expect(true).to.be.ok;
    });

    dalek.testsuitesFinished();
  });

  it('can update assertion state (success)', function () {
    var dalek = new Dalek({
      tests: ['test/dalek/basic.js'],
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false
    });

    dalek._onReportAssertion({success: true});
    expect(dalek.assertionsPassed).to.equal(1);
    expect(dalek.assertionsFailed).to.equal(0);
    expect(dalek.runnerStatus).to.be.true;
  });

  it('can update assertion state (failure)', function () {
    var dalek = new Dalek({
      tests: ['test/dalek/basic.js'],
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false
    });

    dalek._onReportAssertion({success: false});
    expect(dalek.assertionsPassed).to.equal(0);
    expect(dalek.assertionsFailed).to.equal(1);
    expect(dalek.runnerStatus).to.be.false;
  });

  it('can detect advanced options', function () {
    var dalek = new Dalek({
      tests: ['test/dalek/basic.js'],
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false,
      advanced: true
    });

    expect(dalek.advancedOptions).to.be.true;
  });

  it('can run tests', function () {
    var EventEmitter = require('events').EventEmitter;
    var dalek = new Dalek({
      tests: ['test/dalek/basic.js'],
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false
    });

    dalek.reporterEvents = new EventEmitter();
    dalek.reporterEvents.on('report:runner:started', function () {
      expect(true).to.be.true;
    });
    dalek.run();
  });

});
<|endoftext|>


<commit_before>'use strict';

var expect = require('chai').expect;
var Dalek = require('../index.js');

describe('dalek', function () {

  it('should exist', function () {
    expect(Dalek).to.be.ok;
  });

  it('can shutdown on empty tests', function () {
    var oldProcessExit = process.exit;
    process.exit = function (code) {
      expect(code).to.equal(127);
    };
    var EventEmitter = require('events').EventEmitter;
    var dalek = new Dalek({
      tests: '',
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false,
      advanced: true
    });

    dalek.reporterEvents.on('error', function (message) {
      expect(message).to.equal('No test files given!');
    });

    dalek.driverEmitter.on('killAll', function () {
      expect(true).to.be.true;
    });

    process.exit = oldProcessExit;
  });

  it('can be initialized', function () {
    var dalek = new Dalek({
      tests: ['test/dalek/basic.js'],
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false
    });
    expect(dalek).to.be.ok;
  });

  it('can fire run finished event', function () {
    var dalek = new Dalek({
      tests: ['test/dalek/basic.js'],
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false
    });

    dalek.reporterEvents.on('report:runner:finished', function (data) {
      expect(data).to.be.an('object');
    });

    dalek.reportRunFinished();
  });

  it('can fire tests complete event', function () {
    var dalek = new Dalek({
      tests: ['test/dalek/basic.js'],
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false
    });

    dalek.driverEmitter.on('tests:complete', function () {
      expect(true).to.be.ok;
    });

    dalek.testsuitesFinished();
  });

  it('can update assertion state (success)', function () {
    var dalek = new Dalek({
      tests: ['test/dalek/basic.js'],
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false
    });

    dalek._onReportAssertion({success: true});
    expect(dalek.assertionsPassed).to.equal(1);
    expect(dalek.assertionsFailed).to.equal(0);
    expect(dalek.runnerStatus).to.be.true;
  });

  it('can update assertion state (failure)', function () {
    var dalek = new Dalek({
      tests: ['test/dalek/basic.js'],
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false
    });

    dalek._onReportAssertion({success: false});
    expect(dalek.assertionsPassed).to.equal(0);
    expect(dalek.assertionsFailed).to.equal(1);
    expect(dalek.runnerStatus).to.be.false;
  });

  it('can detect advanced options', function () {
    var dalek = new Dalek({
      tests: ['test/dalek/basic.js'],
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false,
      advanced: true
    });

    expect(dalek.advancedOptions).to.be.true;
  });

  it('can run tests', function () {
    var EventEmitter = require('events').EventEmitter;
    var dalek = new Dalek({
      tests: ['test/dalek/basic.js'],
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false
    });

    dalek.reporterEvents = new EventEmitter();
    dalek.reporterEvents.on('report:runner:started', function () {
      expect(true).to.be.true;
    });
    dalek.run();
  });

});
<commit_msg>Lint tests.<commit_after>'use strict';

var expect = require('chai').expect;
var Dalek = require('../index.js');

describe('dalek', function () {

  it('should exist', function () {
    expect(Dalek).to.be.ok;
  });

  it('can shutdown on empty tests', function () {
    var oldProcessExit = process.exit;
    process.exit = function (code) {
      expect(code).to.equal(127);
    };

    var dalek = new Dalek({
      tests: '',
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false,
      advanced: true
    });

    dalek.reporterEvents.on('error', function (message) {
      expect(message).to.equal('No test files given!');
    });

    dalek.driverEmitter.on('killAll', function () {
      expect(true).to.be.true;
    });

    process.exit = oldProcessExit;
  });

  it('can be initialized', function () {
    var dalek = new Dalek({
      tests: ['test/dalek/basic.js'],
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false
    });
    expect(dalek).to.be.ok;
  });

  it('can fire run finished event', function () {
    var dalek = new Dalek({
      tests: ['test/dalek/basic.js'],
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false
    });

    dalek.reporterEvents.on('report:runner:finished', function (data) {
      expect(data).to.be.an('object');
    });

    dalek.reportRunFinished();
  });

  it('can fire tests complete event', function () {
    var dalek = new Dalek({
      tests: ['test/dalek/basic.js'],
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false
    });

    dalek.driverEmitter.on('tests:complete', function () {
      expect(true).to.be.ok;
    });

    dalek.testsuitesFinished();
  });

  it('can update assertion state (success)', function () {
    var dalek = new Dalek({
      tests: ['test/dalek/basic.js'],
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false
    });

    dalek._onReportAssertion({success: true});
    expect(dalek.assertionsPassed).to.equal(1);
    expect(dalek.assertionsFailed).to.equal(0);
    expect(dalek.runnerStatus).to.be.true;
  });

  it('can update assertion state (failure)', function () {
    var dalek = new Dalek({
      tests: ['test/dalek/basic.js'],
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false
    });

    dalek._onReportAssertion({success: false});
    expect(dalek.assertionsPassed).to.equal(0);
    expect(dalek.assertionsFailed).to.equal(1);
    expect(dalek.runnerStatus).to.be.false;
  });

  it('can detect advanced options', function () {
    var dalek = new Dalek({
      tests: ['test/dalek/basic.js'],
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false,
      advanced: true
    });

    expect(dalek.advancedOptions).to.be.true;
  });

  it('can run tests', function () {
    var EventEmitter = require('events').EventEmitter;
    var dalek = new Dalek({
      tests: ['test/dalek/basic.js'],
      driver: [],
      reporter: [],
      browser: [],
      logLevel: 1,
      noColors: false,
      noSymbols: false
    });

    dalek.reporterEvents = new EventEmitter();
    dalek.reporterEvents.on('report:runner:started', function () {
      expect(true).to.be.true;
    });
    dalek.run();
  });

});
<|endoftext|>


<commit_before>/* jshint ignore:start*/
var DCAGENT_DEBUG_OPEN = true
var ASAP_TIMEOUT = 2000
// 有些单元测试在ci模式下通不过，不知道什么原因
var CI_MODE = false

// 每个Spec开始的时候重新加载SDK避免被上次的结果影响
function loadDCAgent(done) {
  var script = document.createElement('script')
  script.src = 'base/dist/dcagent.v2.src.js?v=' + Date.now()
  script.setAttribute('id', 'dcagent')
  script.onload = done
  document.body.appendChild(script)
}

// 每个Spec结束的时候销毁SDK，避免遗漏的Timer影响数据
function destroyDCAgent(done) {
  var script = document.querySelector('#dcagent')
  document.body.removeChild(script)
  DCAgent.destroy()
  DCAgent = null
  done()
}

jasmine.clock().install()
// 这里也必须mockDate，不然有些Spec会失败
jasmine.clock().mockDate(new Date(2015, 11, 1))
jasmine.Ajax.install()
jasmine.Ajax.stubRequest(/http:\/\/rd.gdatacube.net\/.+/).andReturn({
  "status": 200,
  "contentType": 'text/plain',
  "responseText": 'success',
  "responseHeaders": {
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Headers': 'X-Rate-Limit',
    'X-Rate-Limit': 100
  }
})
<commit_msg>avoid ci bug<commit_after>/* jshint ignore:start*/
var DCAGENT_DEBUG_OPEN = true
var ASAP_TIMEOUT = 2000
// 有些单元测试在ci模式下通不过，不知道什么原因
var CI_MODE = true

// 每个Spec开始的时候重新加载SDK避免被上次的结果影响
function loadDCAgent(done) {
  var script = document.createElement('script')
  script.src = 'base/dist/dcagent.v2.src.js?v=' + Date.now()
  script.setAttribute('id', 'dcagent')
  script.onload = done
  document.body.appendChild(script)
}

// 每个Spec结束的时候销毁SDK，避免遗漏的Timer影响数据
function destroyDCAgent(done) {
  var script = document.querySelector('#dcagent')
  document.body.removeChild(script)
  DCAgent.destroy()
  DCAgent = null
  done()
}

jasmine.clock().install()
// 这里也必须mockDate，不然有些Spec会失败
jasmine.clock().mockDate(new Date(2015, 11, 1))
jasmine.Ajax.install()
jasmine.Ajax.stubRequest(/http:\/\/rd.gdatacube.net\/.+/).andReturn({
  "status": 200,
  "contentType": 'text/plain',
  "responseText": 'success',
  "responseHeaders": {
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Headers': 'X-Rate-Limit',
    'X-Rate-Limit': 100
  }
})
<|endoftext|>


<commit_before>// Karma configuration
// Generated on Thu Jul 30 2015 17:38:26 GMT-0700 (PDT)

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '../',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine', 'requirejs'],

    // list of Karma plugins to use
    // This is someone redundant with what's in package.json,
    // but I like it to be explicit here.
    plugins: [
        'karma-jasmine',
        'karma-phantomjs-launcher',
        'karma-coverage',
        'karma-requirejs',
    ],

    // list of files / patterns to load in the browser
    files: [
      // had to add these all by hand, or Karma goes bugnuts.
      /* These are the external dependencies. The bower components
       * come with a LOT of stuff that isn't necessary, and causes
       * problems when loaded in the test browser. Things like tests,
       * or auto-generated minified AND maxified files that overlap.
       *
       * It's cleaner to just load the list of them by hand, then
       * have the Require apparatus take over.
       */
      {pattern: 'bower_components/jquery/dist/jquery.min.js', included: false},
      {pattern: 'bower_components/q/q.js', included: false},
      {pattern: 'bower_components/underscore/underscore-min.js', included: false},
      {pattern: 'bower_components/jquery-ui/jquery-ui.min.js', included: false},
      {pattern: 'bower_components/jquery-ui/themes/ui-lightness/jquery-ui.min.css', included: false},
      {pattern: 'bower_components/bootstrap/dist/js/bootstrap.min.js', included: false},
      {pattern: 'bower_components/bootstrap/dist/css/bootstrap.min.css', included: false},
      {pattern: 'bower_components/nunjucks/browser/nunjucks.min.js', included: false},
      {pattern: 'bower_components/spark-md5/spark-md5.min.js', included: false},
      {pattern: 'bower_components/lodash/lodash.min.js', included: false},
      {pattern: 'bower_components/postal.js/lib/postal.min.js', included: false},
      {pattern: 'bower_components/datatables/media/js/jquery.dataTables.min.js', included: false},
      {pattern: 'bower_components/datatables/media/css/jquery.dataTables.min.css', included: false},
      {pattern: 'bower_components/datatables-bootstrap3-plugin/media/js/datatables-bootstrap3.min.js', included: false},
      {pattern: 'bower_components/datatables-bootstrap3-plugin/media/css/datatables-bootstrap3.min.css', included: false},
      {pattern: 'bower_components/knockout/dist/knockout.debug.js', included: false},
      {pattern: 'bower_components/knockout-mapping/knockout.mapping.js', included: false},
      {pattern: 'bower_components/angular/angular.js', included: false},
      {pattern: 'bower_components/angular-ui/build/angular-ui.min.js', included: false},
      {pattern: 'bower_components/angular-ui-router/release/angular-ui-router.min.js', included: false},
      {pattern: 'bower_components/angular-ui-bootstrap-bower/ui-bootstrap.min.js', included: false},
      {pattern: 'bower_components/angular-ui-bootstrap-bower/ui-bootstrap-tpls.min.js', included: false},
      {pattern: 'bower_components/blockUI/jquery.blockUI.js', included: false},
      {pattern: 'bower_components/d3/d3.min.js', included: false},
      {pattern: 'bower_components/d3-plugins-sankey/sankey.js', included: false},
      {pattern: 'bower_components/d3-plugins-sankey/sankey.css', included: false},
      {pattern: 'src/etc/jquery-svg-graph-stacked-area.js', included: false},
      {pattern: 'bower_components/node-uuid/uuid.js', included: false},
      {pattern: 'lib/canvastext.js', included: false},
      {pattern: 'lib/popit.js', included: false},
      {pattern: 'lib/knhx.js', included: false},
      {pattern: 'lib/googlepalette.js', included: false},
      {pattern: 'bower_components/google-code-prettify/bin/prettify.min.js', included: false},
      {pattern: 'bower_components/google-code-prettify/bin/prettify.min.css', included: false},
      {pattern: 'bower_components/ace-builds/src-min/ace.js', included: false},
      {pattern: 'bower_components/font-awesome/css/font-awesome.min.css', included: false},
      {pattern: 'bower_components/stacktrace-js/dist/stacktrace.min.js', included: false},

      {pattern: 'bower_components/requirejs-text/text.js', included: false},
      {pattern: 'bower_components/requirejs-json/json.js', included: false},
      {pattern: 'bower_components/require-yaml/yaml.js', included: false},
      {pattern: 'bower_components/js-yaml/dist/js-yaml.min.js', included: false},
      {pattern: 'build/*.yml', included: false},
      {pattern: 'functional-site/config.json', served: true, included: false},
      {pattern: 'functional-site/js/require-config.js', served: true, included: true},

      {pattern: 'src/**/*.js', included: false},
      {pattern: 'test/spec/**/*.js', included: false},

      'test/test-main.js',
    ],

    // list of files to exclude
    exclude: [
      '**/*.swp'
    ],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      'src/**/!(datavis|Tiling_widget|postal.request-response.q).js': ['coverage']
    },

    coverageReporter: {
      dir: 'build/test-coverage/',
      reporters: [
        { type: 'html', subdir: 'html' },
        { type: 'lcov', subdir: 'lcov' }
      ]
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress', 'coverage'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: false,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['PhantomJS'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: true
  })
}
<commit_msg>add chrome, firefox, safari to browser list<commit_after>// Karma configuration
// Generated on Thu Jul 30 2015 17:38:26 GMT-0700 (PDT)

module.exports = function(config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '../',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine', 'requirejs'],

    // list of Karma plugins to use
    // This is someone redundant with what's in package.json,
    // but I like it to be explicit here.
    plugins: [
        'karma-jasmine',
        'karma-phantomjs-launcher',
        'karma-chrome-launcher',
        'karma-firefox-launcher',
        'karma-coverage',
        'karma-requirejs',
    ],

    // list of files / patterns to load in the browser
    files: [
      // had to add these all by hand, or Karma goes bugnuts.
      /* These are the external dependencies. The bower components
       * come with a LOT of stuff that isn't necessary, and causes
       * problems when loaded in the test browser. Things like tests,
       * or auto-generated minified AND maxified files that overlap.
       *
       * It's cleaner to just load the list of them by hand, then
       * have the Require apparatus take over.
       */
      {pattern: 'bower_components/jquery/dist/jquery.min.js', included: false},
      {pattern: 'bower_components/q/q.js', included: false},
      {pattern: 'bower_components/underscore/underscore-min.js', included: false},
      {pattern: 'bower_components/jquery-ui/jquery-ui.min.js', included: false},
      {pattern: 'bower_components/jquery-ui/themes/ui-lightness/jquery-ui.min.css', included: false},
      {pattern: 'bower_components/bootstrap/dist/js/bootstrap.min.js', included: false},
      {pattern: 'bower_components/bootstrap/dist/css/bootstrap.min.css', included: false},
      {pattern: 'bower_components/nunjucks/browser/nunjucks.min.js', included: false},
      {pattern: 'bower_components/spark-md5/spark-md5.min.js', included: false},
      {pattern: 'bower_components/lodash/lodash.min.js', included: false},
      {pattern: 'bower_components/postal.js/lib/postal.min.js', included: false},
      {pattern: 'bower_components/datatables/media/js/jquery.dataTables.min.js', included: false},
      {pattern: 'bower_components/datatables/media/css/jquery.dataTables.min.css', included: false},
      {pattern: 'bower_components/datatables-bootstrap3-plugin/media/js/datatables-bootstrap3.min.js', included: false},
      {pattern: 'bower_components/datatables-bootstrap3-plugin/media/css/datatables-bootstrap3.min.css', included: false},
      {pattern: 'bower_components/knockout/dist/knockout.debug.js', included: false},
      {pattern: 'bower_components/knockout-mapping/knockout.mapping.js', included: false},
      {pattern: 'bower_components/angular/angular.js', included: false},
      {pattern: 'bower_components/angular-ui/build/angular-ui.min.js', included: false},
      {pattern: 'bower_components/angular-ui-router/release/angular-ui-router.min.js', included: false},
      {pattern: 'bower_components/angular-ui-bootstrap-bower/ui-bootstrap.min.js', included: false},
      {pattern: 'bower_components/angular-ui-bootstrap-bower/ui-bootstrap-tpls.min.js', included: false},
      {pattern: 'bower_components/blockUI/jquery.blockUI.js', included: false},
      {pattern: 'bower_components/d3/d3.min.js', included: false},
      {pattern: 'bower_components/d3-plugins-sankey/sankey.js', included: false},
      {pattern: 'bower_components/d3-plugins-sankey/sankey.css', included: false},
      {pattern: 'src/etc/jquery-svg-graph-stacked-area.js', included: false},
      {pattern: 'bower_components/node-uuid/uuid.js', included: false},
      {pattern: 'lib/canvastext.js', included: false},
      {pattern: 'lib/popit.js', included: false},
      {pattern: 'lib/knhx.js', included: false},
      {pattern: 'lib/googlepalette.js', included: false},
      {pattern: 'bower_components/google-code-prettify/bin/prettify.min.js', included: false},
      {pattern: 'bower_components/google-code-prettify/bin/prettify.min.css', included: false},
      {pattern: 'bower_components/ace-builds/src-min/ace.js', included: false},
      {pattern: 'bower_components/font-awesome/css/font-awesome.min.css', included: false},
      {pattern: 'bower_components/stacktrace-js/dist/stacktrace.min.js', included: false},

      {pattern: 'bower_components/requirejs-text/text.js', included: false},
      {pattern: 'bower_components/requirejs-json/json.js', included: false},
      {pattern: 'bower_components/require-yaml/yaml.js', included: false},
      {pattern: 'bower_components/js-yaml/dist/js-yaml.min.js', included: false},
      {pattern: 'build/*.yml', included: false},
      {pattern: 'functional-site/config.json', served: true, included: false},
      {pattern: 'functional-site/js/require-config.js', served: true, included: true},

      {pattern: 'src/**/*.js', included: false},
      {pattern: 'test/spec/**/*.js', included: false},

      'test/test-main.js',
    ],

    // list of files to exclude
    exclude: [
      '**/*.swp'
    ],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      'src/**/!(datavis|Tiling_widget|postal.request-response.q).js': ['coverage']
    },

    coverageReporter: {
      dir: 'build/test-coverage/',
      reporters: [
        { type: 'html', subdir: 'html' },
        { type: 'lcov', subdir: 'lcov' }
      ]
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress', 'coverage'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: false,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['PhantomJS', 'Chrome', 'Firefox'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: true
  })
}
<|endoftext|>


<commit_before>module.exports = function(config) {
  config.set({
    autoWatch: true,
    basePath: '../',
    frameworks: ['qunit'],
    files: [
      'node_modules/jquery/dist/jquery.js',
      'node_modules/qunit-parameterize/qunit-parameterize.js',
      'test/config/setup.js',
      'test/**/*.spec.js'
    ],

    preprocessors: {
      'src/**/*.js': ['webpack'],
      'test/**/*.js': ['webpack']
    },

    reporters: ['progress'],

    exclude: [],
    port: 9876,

    browserStack: {
      project: 'DOMPurify',
      username: process.env.BS_USERNAME,
      accessKey: process.env.BS_ACCESSKEY
    },

    webpack: {
      plugins: [],
      devtool: 'inline-source-map',
      resolve: {
        alias: {},
        modulesDirectories: [
          'test',
          'src',
          'dist'
        ],
        extensions: ['', '.js', '.json']
      },
      externals: {
        jQuery: 'jQuery'
      },
      module: {
        loaders: [{
          test: /\.json$/,
          loader: 'json-loader'
        }]
      }
    },

    webpackMiddleware: {
      noInfo: true
    },

    customLaunchers: {
      bs_win81_ie_11: {
        base: 'BrowserStack',
        browser: 'ie',
        browser_version: '11.0',
        os: 'Windows',
        os_version: '8.1'
      },
      bs_win8_ie_10: {
        base: 'BrowserStack',
        browser: 'ie',
        browser_version: '10.0',
        os: 'Windows',
        os_version: '8'
      },
      bs_mavericks_chrome_44: {
        base: 'BrowserStack',
        device: null,
        os: 'OS X',
        browser_version: '44.0',
        browser: 'chrome',
        os_version: 'Mavericks'
      },
      bs_yosemite_firefox_40: {
        base: 'BrowserStack',
        device: null,
        os: 'OS X',
        browser_version: '40.0',
        browser: 'firefox',
        os_version: 'Yosemite'
      },
      bs_yosemite_safari_8: {
        base: 'BrowserStack',
        device: null,
        os: 'OS X',
        browser_version: '8.0',
        browser: 'safari',
        os_version: 'Yosemite'
      },
      bs_win81_opera_31: {
        base: 'BrowserStack',
        device: null,
        os: 'Windows',
        browser_version: '31',
        browser: 'opera',
        os_version: '8.1'
      },
      bs_win7_firefox_12: {
        base: 'BrowserStack',
        device: null,
        os: 'Windows',
        browser_version: '12.0',
        browser: 'firefox',
        os_version: '7'
      },
      bs_win81_chrome_22: {
        base: 'BrowserStack',
        device: null,
        os: 'Windows',
        browser_version: '22.0',
        browser: 'chrome',
        os_version: '8.1'
      },
      bs_win10_edge_13: {
        base: 'BrowserStack',
        device: null,
        os: 'Windows',
        browser_version: '13.0',
        browser: 'edge',
        os_version: '10'
      },
      bs_win10_firefox_46: {
        base: 'BrowserStack',
        device: null,
        os: 'Windows',
        browser_version: '46.0',
        browser: 'firefox',
        os_version: '10'
      },
      bs_win10_chrome_50: {
        base: 'BrowserStack',
        device: null,
        os: 'Windows',
        browser_version: '50.0',
        browser: 'chrome',
        os_version: '10'
      }
    },

    browsers: [
      'bs_win81_ie_11',
      'bs_win8_ie_10',
      'bs_mavericks_chrome_44',
      'bs_yosemite_firefox_40',
      'bs_yosemite_safari_8',
      'bs_win81_opera_31',
      'bs_win7_firefox_12',
      'bs_win81_chrome_22',
      'bs_win10_edge_13',
      'bs_win10_firefox_46',
      'bs_win10_chrome_50'
    ],

    browserDisconnectTimeout: 10000,
    browserDisconnectTolerance: 1,
    browserNoActivityTimeout: 240000,
    captureTimeout: 240000,

    plugins: [
      'karma-webpack',
      'karma-chrome-launcher',
      'karma-browserstack-launcher',
      'karma-firefox-launcher',
      'karma-qunit'
    ],

    singleRun: true,
    colors: true,
    logLevel: config.LOG_INFO
  });
};
<commit_msg>Changed karma.conf.js to use FF15 instead of FF12 since browserstack unsupported FF12<commit_after>module.exports = function(config) {
  config.set({
    autoWatch: true,
    basePath: '../',
    frameworks: ['qunit'],
    files: [
      'node_modules/jquery/dist/jquery.js',
      'node_modules/qunit-parameterize/qunit-parameterize.js',
      'test/config/setup.js',
      'test/**/*.spec.js'
    ],

    preprocessors: {
      'src/**/*.js': ['webpack'],
      'test/**/*.js': ['webpack']
    },

    reporters: ['progress'],

    exclude: [],
    port: 9876,

    browserStack: {
      project: 'DOMPurify',
      username: process.env.BS_USERNAME,
      accessKey: process.env.BS_ACCESSKEY
    },

    webpack: {
      plugins: [],
      devtool: 'inline-source-map',
      resolve: {
        alias: {},
        modulesDirectories: [
          'test',
          'src',
          'dist'
        ],
        extensions: ['', '.js', '.json']
      },
      externals: {
        jQuery: 'jQuery'
      },
      module: {
        loaders: [{
          test: /\.json$/,
          loader: 'json-loader'
        }]
      }
    },

    webpackMiddleware: {
      noInfo: true
    },

    customLaunchers: {
      bs_win81_ie_11: {
        base: 'BrowserStack',
        browser: 'ie',
        browser_version: '11.0',
        os: 'Windows',
        os_version: '8.1'
      },
      bs_win8_ie_10: {
        base: 'BrowserStack',
        browser: 'ie',
        browser_version: '10.0',
        os: 'Windows',
        os_version: '8'
      },
      bs_mavericks_chrome_44: {
        base: 'BrowserStack',
        device: null,
        os: 'OS X',
        browser_version: '44.0',
        browser: 'chrome',
        os_version: 'Mavericks'
      },
      bs_yosemite_firefox_40: {
        base: 'BrowserStack',
        device: null,
        os: 'OS X',
        browser_version: '40.0',
        browser: 'firefox',
        os_version: 'Yosemite'
      },
      bs_yosemite_safari_8: {
        base: 'BrowserStack',
        device: null,
        os: 'OS X',
        browser_version: '8.0',
        browser: 'safari',
        os_version: 'Yosemite'
      },
      bs_win81_opera_31: {
        base: 'BrowserStack',
        device: null,
        os: 'Windows',
        browser_version: '31',
        browser: 'opera',
        os_version: '8.1'
      },
      bs_win7_firefox_15: {
        base: 'BrowserStack',
        device: null,
        os: 'Windows',
        browser_version: '15.0',
        browser: 'firefox',
        os_version: '7'
      },
      bs_win81_chrome_22: {
        base: 'BrowserStack',
        device: null,
        os: 'Windows',
        browser_version: '22.0',
        browser: 'chrome',
        os_version: '8.1'
      },
      bs_win10_edge_13: {
        base: 'BrowserStack',
        device: null,
        os: 'Windows',
        browser_version: '13.0',
        browser: 'edge',
        os_version: '10'
      },
      bs_win10_firefox_46: {
        base: 'BrowserStack',
        device: null,
        os: 'Windows',
        browser_version: '46.0',
        browser: 'firefox',
        os_version: '10'
      },
      bs_win10_chrome_50: {
        base: 'BrowserStack',
        device: null,
        os: 'Windows',
        browser_version: '50.0',
        browser: 'chrome',
        os_version: '10'
      }
    },

    browsers: [
      'bs_win81_ie_11',
      'bs_win8_ie_10',
      'bs_mavericks_chrome_44',
      'bs_yosemite_firefox_40',
      'bs_yosemite_safari_8',
      'bs_win81_opera_31',
      'bs_win7_firefox_15',
      'bs_win81_chrome_22',
      'bs_win10_edge_13',
      'bs_win10_firefox_46',
      'bs_win10_chrome_50'
    ],

    browserDisconnectTimeout: 10000,
    browserDisconnectTolerance: 1,
    browserNoActivityTimeout: 240000,
    captureTimeout: 240000,

    plugins: [
      'karma-webpack',
      'karma-chrome-launcher',
      'karma-browserstack-launcher',
      'karma-firefox-launcher',
      'karma-qunit'
    ],

    singleRun: true,
    colors: true,
    logLevel: config.LOG_INFO
  });
};
<|endoftext|>