<commit_before>import winston from 'winston';
import fs from 'fs';
import path from 'path';
import DailyRotateFile from 'winston-daily-rotate-file';
import _ from 'lodash';
import defaults  from '../../defaults';

const logger = new winston.Logger();
const additionalTransports = [];

function updateTransports(options) {
  let transports = Object.assign({}, logger.transports);
  if (options) {
    let silent = options.silent;
    delete options.silent;
    if (_.isNull(options.dirname)) {
      delete transports['parse-server'];
      delete transports['parse-server-error'];
    } else if (!_.isUndefined(options.dirname)) {
      transports['parse-server'] = new (DailyRotateFile)(
        Object.assign({
          filename: 'parse-server.info',
          name: 'parse-server',
        }, options));
      transports['parse-server-error'] = new (DailyRotateFile)(
        Object.assign({
          filename: 'parse-server.err',
          name: 'parse-server-error',
          level: 'error'
        }, options));
    }

    transports.console = new (winston.transports.Console)(
      Object.assign({
        colorize: true,
        name: 'console',
        silent
      }, options));
  }
  // Mount the additional transports
  additionalTransports.forEach((transport) => {
    transports[transport.name] = transport;
  });
  logger.configure({
    transports: _.values(transports)
  });
}

export function configureLogger({
  logsFolder = defaults.logsFolder,
  jsonLogs = defaults.jsonLogs,
  logLevel = winston.level,
  verbose = defaults.verbose,
  silent = defaults.silent } = {}) {

  if (verbose) {
    logLevel = 'verbose';
  }

  winston.level = logLevel;
  const options = {};

  if (logsFolder) {
    if (!path.isAbsolute(logsFolder)) {
      logsFolder = path.resolve(process.cwd(), logsFolder);
    }
    try {
      fs.mkdirSync(logsFolder);
    } catch (exception) {}
  }
  options.dirname = logsFolder;
  options.level = logLevel;
  options.silent = silent;

  if (jsonLogs) {
    options.json = true;
    options.stringify = true;
  }
  updateTransports(options);
}

export function addTransport(transport) {
  additionalTransports.push(transport);
  updateTransports();
}

export function removeTransport(transport) {
  let transportName = typeof transport == 'string' ? transport : transport.name;
  let transports = Object.assign({}, logger.transports);
  delete transports[transportName];
  logger.configure({
    transports: _.values(transports)
  });
  _.remove(additionalTransports, (transport) => {
    return transport.name === transportName;
  });
}

export { logger, addTransport, configureLogger, removeTransport };
export default logger;
<commit_msg>[PinParse] master<commit_after>import winston from 'winston';
import fs from 'fs';
import path from 'path';
import DailyRotateFile from 'winston-daily-rotate-file';
import _ from 'lodash';
import defaults  from '../../defaults';

const logger = new winston.Logger();
const additionalTransports = [];

function updateTransports(options) {
  let transports = Object.assign({}, logger.transports);
  if (options) {
    let silent = options.silent;
    delete options.silent;
    if (_.isNull(options.dirname)) {
      delete transports['parse-server'];
      delete transports['parse-server-error'];
    } else if (!_.isUndefined(options.dirname)) {
      transports['parse-server'] = new (DailyRotateFile)(
        Object.assign({
          filename: 'parse-server.info',
          name: 'parse-server',
        }, options));
      transports['parse-server-error'] = new (DailyRotateFile)(
        Object.assign({
          filename: 'parse-server.err',
          name: 'parse-server-error',
          level: 'error'
        }, options));
    }

    transports.console = new (winston.transports.Console)(
      Object.assign({
        colorize: true,
        name: 'console',
        silent
      }, options));
  }
  // Mount the additional transports
  additionalTransports.forEach((transport) => {
    transports[transport.name] = transport;
  });
  logger.configure({
    transports: _.values(transports)
  });
}

export function configureLogger({
  logsFolder = defaults.logsFolder,
  jsonLogs = defaults.jsonLogs,
  logLevel = winston.level,
  verbose = defaults.verbose,
  silent = defaults.silent } = {}) {

  if (verbose) {
    logLevel = 'verbose';
  }

  winston.level = logLevel;
  const options = {};

  if (logsFolder) {
    if (!path.isAbsolute(logsFolder)) {
      logsFolder = path.resolve(process.cwd(), logsFolder);
    }
    try {
      fs.mkdirSync(logsFolder);
    } catch (exception) {}
  }
  options.dirname = logsFolder;
  options.level = logLevel;
  options.silent = silent;

  if (jsonLogs) {
    options.json = true;
    options.stringify = true;
  }
  updateTransports(options);
}

export function addTransport(transport) {
  additionalTransports.push(transport);
  updateTransports();
}

export function removeTransport(transport) {
  let transportName = typeof transport == 'string' ? transport : transport.name;
  let transports = Object.assign({}, logger.transports);
  delete transports[transportName];
  logger.configure({
    transports: _.values(transports)
  });
  _.remove(additionalTransports, (transport) => {
    return transport.name === transportName;
  });
}

export { logger};
export default logger;
<|endoftext|>


<commit_before>/**
 * @overview
 *
 */
<commit_msg>Basic helpers<commit_after>/**
 * @overview
 *  Provides basic helper functions for common operations with records,
 *  like {@link isAbyssalShip} or {@link getShipSpeed}.
 *
 * @since 0.4.0
 */
import { cond, always, equals, T } from 'ramda';

/**
 * @type {function}
 * @param {ShipRecord} ship
 * @returns {boolean}
 */
export const isAbyssalShip = (ship) => ship.shipId >= 500 && ship.shipId <= 900;

/**
 * @type {function}
 * @param {ShipRecord} ship
 * @returns {number}
 * @todo Use less magic numbers
 */
export const getShipSpeed = (ship) => cond([
  [equals(0), always('zero')],
  [equals(5), always('five')],
  [equals(10), always('ten')],
  [T, always('fallthrough')]
])(ship.stats.speed);

/**
 * @type {function}
 * @param {ShipRecord} ship
 * @returns {number}
 */
export const getShipRange = (ship) => ship.stats.range;
<|endoftext|>


<commit_before>/*
 clickhax - a node.js/mongo click heatmap solution

 Original by xxx (http://github.com/xxx/heatmap), MIT License

 Copyright (c) 2010 xxx, Chris Heald

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.

******************************************/

(function ($) {
  var heat = {},
      canvasWidth,
      canvasHeight,
      context,
			canvas,
      cache = { toHue: {}, hueToRGB: {} },
      renderHeat,
      toHue,
      hueToRGB,
      renderStartTime,
			normalizeHeat;

	/* Effectively a grayscale 9x9 image to be used to paint both opacity and heat
	   If you'd like to generate an array from your own image (of any size as long as it's square), use something like the following:

		var img = new Image();
		var dim = 9;		// Width of the image
		var imgd;
		img.src = "hm.png";
		img.onload = function() {
			context.drawImage(img, 0, 0, dim, dim, 0, 0, dim, dim);
			console.log(context.getImageData(0, 0, dim, dim).data);
		}
	*/

  var clickMask = [2, 7, 18, 34, 47, 40, 23, 10, 3, 5, 20, 63, 123, 157, 143, 90, 37, 10, 11, 53, 146, 212, 230, 224, 184, 91, 25, 18, 86, 198, 238, 241, 240, 224, 145, 41, 22, 97, 208, 239, 241, 241, 231, 158, 46, 18, 86, 198, 238, 241, 240, 224, 145, 41, 11, 53, 146, 212, 230, 224, 184, 91, 25, 5, 20, 63, 123, 157, 143, 90, 37, 10, 2, 7, 18, 34, 47, 40, 23, 10, 3];
	var clickWidth = Math.sqrt(clickMask.length);

  applyMask = function (heat) {
    var key, i, j, initialI, initialJ, maskSeg;
		var newheat = {};

    maskSeg = Math.floor(clickWidth / 2);
		for (key in heat) {
			var x = Math.floor(key / 3000);
			var y = key % 3000;

			initialI = x - maskSeg;
			initialJ = y - maskSeg;

			for (i = initialI; i <= x + maskSeg; i += 1) {
				if (i < 0 || i >= canvasWidth) { continue; }

				for (j = initialJ; j <= y + maskSeg; j += 1) {
					if (j < 0 || j >= canvasHeight) { continue; }
					key = i * 3000 + j;
					newheat[key] = newheat[key] || (heat[key] && heat[key]) || 0;
					var idx = ((j - initialJ) + (i - initialI) * clickWidth);
					newheat[key] += Math.floor(clickMask[idx]);
				}
			}
		}
		return newheat;
  };

  normalizeHeat = function (heat) {
    var minHeat, maxHeat, heatValues = [], normalizedHeat = {}, denominator, key;

    for (key in heat) { heatValues.push(heat[key]); }
    minHeat = Math.min.apply(this, heatValues);
    maxHeat = Math.max.apply(this, heatValues);
    denominator = maxHeat - minHeat;
    if (denominator === 0 || denominator === Number.NEGATIVE_INFINITY) { denominator = 1; }
    for (key in heat) { normalizedHeat[key] = Math.floor(255 * ((heat[key] - minHeat) / denominator)); }
    return normalizedHeat;
  };

  renderHeat = function (heat) {
    var x, y, splitKey, rgb;

		heat = applyMask(heat);
		heat = normalizeHeat(heat);

		context.fillStyle = "rgb(116, 119, 130)";
    context.clearRect(0, 0, canvasWidth, canvasHeight);
		context.fillRect(0, 0, canvasWidth, canvasHeight);

    $.each(heat, function (key, value) {
			if(value != 0) {
				key = parseInt(key);
				y = key % 3000;
				x = Math.floor(key / 3000);

				rgb = hueToRGB(toHue(value), 1, 1);

				context.fillStyle = "rgba(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "," + value / 16 + ")";
				context.fillRect(x, y, 1, 1);
			}
    });
    canvas.css({opacity: 0}).show().animate({opacity: 0.5}, 350);
  };

  /*
   * take normalized heat value from above and
   * convert it to a 0 (red, hot) - 240 (blue, cold) range.
   * we assume the passed normalized values are
   *  0 (cold) - 255 (hot)
   */
  toHue = function (value) {
    if (cache.toHue[value]) { return cache.toHue[value]; }
    cache.toHue[value] = 240 - Math.floor((value * 240) / 255);
    return cache.toHue[value];
  };

  /*
   * HSV to RGB color conversion
   *
   * pulled from http://snipplr.com/view.php?codeview&id=14590
   *
   * h: 0-360 , whole numbers
   * s: 0-1, decimals ok
   * v: 0-1, decimals ok
   */
  hueToRGB = function (h, s, v) {
    var r, g, b, i, f, p, q, t, cachekey = h + "/" + s + "/" + v;

    if (cache.hueToRGB[cachekey]) { return cache.hueToRGB[cachekey]; }

    // Make sure our arguments stay in-range
    h = Math.max(0, Math.min(360, h));
    s = Math.max(0, Math.min(1, s));
    v = Math.max(0, Math.min(1, v));

     // Achromatic (grey)
    if (s === 0) {
      r = g = b = v;
      return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
    }

    h /= 60; // sector 0 to 5
    i = Math.floor(h);
    f = h - i; // factorial part of h
    p = v * (1 - s);
    q = v * (1 - s * f);
    t = v * (1 - s * (1 - f));

    switch (i) {
    case 0:
      r = v;
      g = t;
      b = p;
      break;

    case 1:
      r = q;
      g = v;
      b = p;
      break;

    case 2:
      r = p;
      g = v;
      b = t;
      break;

    case 3:
      r = p;
      g = q;
      b = v;
      break;

    case 4:
      r = t;
      g = p;
      b = v;
      break;

    default: // case 5:
      r = v;
      g = p;
      b = q;
    }

    cache.hueToRGB[cachekey] = [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
    return cache.hueToRGB[cachekey];
  };

	var defaults = {
		endpoint: window.location.protocol + "//" + window.location.hostname + ":3123",
		trigger: null
	}

	$.fn.clickhax = function(settings) {

		canvas = $('#heatmapOverlay');
		if(canvas.length == 0) {
			$("body").append("<canvas id='heatmapOverlay' style='position: absolute; top: 0; left: 0; right: 0, bottom: 0; display: none;'>This requires canvas support.</canvas>");
			canvas = $('#heatmapOverlay');
			canvas.click(function() { canvas.fadeOut('fast'); });
			if(!context) { context = canvas.get(0).getContext('2d'); }
		}

		var options = $.extend({}, defaults, settings);
		return this.each(function() {
			var tracker = this;
			$(this).mousedown(function(e) {
				var off = $(this).offset();
				$.post(options.endpoint, {x: e.pageX - off.left, y: e.pageY - off.top});
			});

			if(options.trigger) {
				$(options.trigger).click(function() {
					var $e = $(tracker);
					var off = $e.offset()
					var w = $e.width() + parseInt($e.css("padding-left")) + parseInt($e.css("padding-right")) + parseInt($e.css("borderLeftWidth")) + parseInt($e.css("borderRightWidth"));
					var h = $e.height() + parseInt($e.css("padding-top")) + parseInt($e.css("padding-bottom")) + parseInt($e.css("borderTopWidth")) + parseInt($e.css("borderBottomWidth"));
					canvas.attr({
						width: w,
						height: h
					}).css({
						top: off.top + "px",
						left: off.left + "px"
					});

					canvasWidth = canvas.width();
					canvasHeight = canvas.width();

					$.getJSON(options.endpoint, function(data) { renderHeat(data); });
					return false;
				});
			}
		});
	};
})(jQuery);<commit_msg>Draw heat properly when appropriate<commit_after>/*
 clickhax - a node.js/mongo click heatmap solution

 Original by xxx (http://github.com/xxx/heatmap), MIT License

 Copyright (c) 2010 xxx, Chris Heald

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.

******************************************/

(function ($) {
  var heat = {},
      canvasWidth,
      canvasHeight,
      context,
			canvas,
      cache = { toHue: {}, hueToRGB: {} },
      renderHeat,
      toHue,
      hueToRGB,
      renderStartTime,
			normalizeHeat;

	/* Effectively a grayscale 9x9 image to be used to paint both opacity and heat
	   If you'd like to generate an array from your own image (of any size as long as it's square), use something like the following:

		var img = new Image();
		var dim = 9;		// Width of the image
		var imgd;
		img.src = "hm.png";
		img.onload = function() {
			context.drawImage(img, 0, 0, dim, dim, 0, 0, dim, dim);
			console.log(context.getImageData(0, 0, dim, dim).data);
		}
	*/

  // var clickMask = [2, 7, 18, 34, 47, 40, 23, 10, 3, 5, 20, 63, 123, 157, 143, 90, 37, 10, 11, 53, 146, 212, 230, 224, 184, 91, 25, 18, 86, 198, 238, 241, 240, 224, 145, 41, 22, 97, 208, 239, 241, 241, 231, 158, 46, 18, 86, 198, 238, 241, 240, 224, 145, 41, 11, 53, 146, 212, 230, 224, 184, 91, 25, 5, 20, 63, 123, 157, 143, 90, 37, 10, 2, 7, 18, 34, 47, 40, 23, 10, 3];
	var clickMask = [0, 0, 1, 4, 8, 10, 13, 14, 14, 11, 9, 5, 2, 1, 0, 0, 1, 6, 11, 20, 27, 34, 38, 36, 30, 22, 13, 7, 3, 1, 1, 6, 13, 26, 43, 60, 73, 79, 76, 64, 47, 30, 17, 8, 2, 4, 12, 26, 50, 79, 107, 129, 136, 130, 112, 86, 57, 32, 15, 6, 8, 21, 45, 81, 123, 160, 185, 195, 188, 168, 132, 90, 53, 26, 10, 12, 31, 65, 112, 164, 204, 225, 231, 229, 212, 175, 125, 76, 38, 15, 16, 41, 81, 138, 193, 229, 238, 240, 240, 233, 204, 151, 94, 48, 20, 18, 44, 90, 151, 206, 236, 240, 241, 241, 240, 216, 164, 103, 53, 23, 17, 43, 89, 148, 204, 235, 240, 241, 241, 239, 215, 162, 101, 53, 22, 14, 37, 77, 131, 187, 225, 238, 240, 239, 230, 198, 146, 89, 45, 18, 11, 28, 60, 104, 154, 195, 217, 224, 220, 202, 164, 116, 69, 34, 13, 7, 19, 41, 73, 112, 146, 170, 180, 174, 153, 120, 81, 46, 23, 9, 3, 10, 23, 43, 69, 94, 112, 121, 115, 98, 75, 48, 27, 12, 5, 1, 5, 11, 22, 36, 50, 61, 67, 63, 53, 39, 25, 13, 6, 2, 0, 1, 5, 9, 15, 23, 27, 30, 28, 24, 17, 10, 6, 2, 0]
	var clickWidth = Math.sqrt(clickMask.length);

  applyMask = function (heat) {
    var key, i, j, initialI, initialJ, maskSeg;
		var newheat = {};

    maskSeg = Math.floor(clickWidth / 2);
		for (key in heat) {
			var x = Math.floor(key / 3000);
			var y = key % 3000;

			initialI = x - maskSeg;
			initialJ = y - maskSeg;

			for (i = initialI; i <= x + maskSeg; i += 1) {
				if (i < 0 || i >= canvasWidth) { continue; }

				for (j = initialJ; j <= y + maskSeg; j += 1) {
					if (j < 0 || j >= canvasHeight) { continue; }
					key = i * 3000 + j;
					var idx = ((j - initialJ) + (i - initialI) * clickWidth);
					newheat[key] = newheat[key] || heat[key] || 0;
					newheat[key] += clickMask[idx];
				}
			}
		}
		return newheat;
  };

  normalizeHeat = function (heat) {
    var minHeat, maxHeat, heatValues = [], normalizedHeat = {}, denominator, key;

    for (key in heat) { heatValues.push(heat[key]); }
    minHeat = Math.min.apply(this, heatValues);
    maxHeat = Math.max.apply(this, heatValues);
    denominator = maxHeat - minHeat;
    if (denominator === 0 || denominator === Number.NEGATIVE_INFINITY) { denominator = 1; }
    for (key in heat) { normalizedHeat[key] = Math.floor(255 * ((heat[key] - minHeat) / denominator)); }
    return normalizedHeat;
  };

  renderHeat = function (heat) {
    var x, y, splitKey, rgb;

		heat = applyMask(heat);
		heat = normalizeHeat(heat);

		context.fillStyle = "rgb(116, 119, 130)";
    context.clearRect(0, 0, canvasWidth, canvasHeight);
		context.fillRect(0, 0, canvasWidth, canvasHeight);

    $.each(heat, function (key, value) {
			if(value != 0) {
				key = parseInt(key);
				y = key % 3000;
				x = Math.floor(key / 3000);

				rgb = hueToRGB(toHue(value), 1, 1);

				context.fillStyle = "rgba(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "," + value / 16 + ")";
				context.fillRect(x, y, 1, 1);
			}
    });
    canvas.css({opacity: 0}).show().animate({opacity: 0.5}, 350);
  };

  /*
   * take normalized heat value from above and
   * convert it to a 0 (red, hot) - 240 (blue, cold) range.
   * we assume the passed normalized values are
   *  0 (cold) - 255 (hot)
   */
  toHue = function (value) {
    if (cache.toHue[value]) { return cache.toHue[value]; }
    cache.toHue[value] = 255 - Math.floor(value);
    return cache.toHue[value];
  };

  /*
   * HSV to RGB color conversion
   *
   * pulled from http://snipplr.com/view.php?codeview&id=14590
   *
   * h: 0-360 , whole numbers
   * s: 0-1, decimals ok
   * v: 0-1, decimals ok
   */
  hueToRGB = function (h, s, v) {
    var r, g, b, i, f, p, q, t, cachekey = h + "/" + s + "/" + v;

    if (cache.hueToRGB[cachekey]) { return cache.hueToRGB[cachekey]; }

    // Make sure our arguments stay in-range
    h = Math.max(0, Math.min(360, h));
    s = Math.max(0, Math.min(1, s));
    v = Math.max(0, Math.min(1, v));

     // Achromatic (grey)
    if (s === 0) {
      r = g = b = v;
      return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
    }

    h /= 60; // sector 0 to 5
    i = Math.floor(h);
    f = h - i; // factorial part of h
    p = v * (1 - s);
    q = v * (1 - s * f);
    t = v * (1 - s * (1 - f));

    switch (i) {
    case 0:
      r = v;
      g = t;
      b = p;
      break;

    case 1:
      r = q;
      g = v;
      b = p;
      break;

    case 2:
      r = p;
      g = v;
      b = t;
      break;

    case 3:
      r = p;
      g = q;
      b = v;
      break;

    case 4:
      r = t;
      g = p;
      b = v;
      break;

    default: // case 5:
      r = v;
      g = p;
      b = q;
    }

    cache.hueToRGB[cachekey] = [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
    return cache.hueToRGB[cachekey];
  };

	var defaults = {
		endpoint: window.location.protocol + "//" + window.location.hostname + ":3123",
		trigger: null
	}

	$.fn.clickhax = function(settings) {

		canvas = $('#heatmapOverlay');
		if(canvas.length == 0) {
			$("body").append("<canvas id='heatmapOverlay' style='position: absolute; top: 0; left: 0; right: 0, bottom: 0; display: none;'>This requires canvas support.</canvas>");
			canvas = $('#heatmapOverlay');
			canvas.click(function() { canvas.fadeOut('fast'); });
			if(!context) { context = canvas.get(0).getContext('2d'); }

			/*
			var img = new Image();
			var dim = 15;		// Width of the image
			img.src = "hm.png";
			img.onload = function() {
				var pa = [];
				context.drawImage(img, 0, 0, dim, dim, 0, 0, dim, dim);
				var data = context.getImageData(0, 0, dim, dim)
				for(i=0; i<data.width*data.width;i++) {
					pa[pa.length] = data.data[i*4];
				}
				console.log(data);
				console.log(pa);
			}
			*/
		}

		var options = $.extend({}, defaults, settings);
		return this.each(function() {
			var tracker = this;
			$(this).mousedown(function(e) {
				var off = $(this).offset();
				$.post(options.endpoint, {x: e.pageX - off.left, y: e.pageY - off.top});
			});

			if(options.trigger) {
				$(options.trigger).click(function() {
					var $e = $(tracker);
					var off = $e.offset()
					var w = $e.width() + parseInt($e.css("padding-left")) + parseInt($e.css("padding-right")) + parseInt($e.css("borderLeftWidth")) + parseInt($e.css("borderRightWidth"));
					var h = $e.height() + parseInt($e.css("padding-top")) + parseInt($e.css("padding-bottom")) + parseInt($e.css("borderTopWidth")) + parseInt($e.css("borderBottomWidth"));
					canvas.attr({
						width: w,
						height: h
					}).css({
						top: off.top + "px",
						left: off.left + "px"
					});

					canvasWidth = canvas.width();
					canvasHeight = canvas.width();

					$.getJSON(options.endpoint, function(data) { renderHeat(data); });
					return false;
				});
			}
		});
	};
})(jQuery);<|endoftext|>


<commit_before>'use strict'

/**
 * Test dependencies
 */
const path = require('path')
const chai = require('chai')
const sinon = require('sinon')
const sinonChai = require('sinon-chai')

/**
 * Assertions
 */
chai.use(sinonChai)
chai.should()
let expect = chai.expect

/**
 * Code under test
 */
const Initializer = require(path.join(process.cwd(), 'core', 'data', 'Initializer'))
const traverse = Initializer.traverse
const assign = Initializer.assign
const select = Initializer.select
const map = Initializer.map
const getDeepProperty = Initializer.getDeepProperty
const setDeepProperty = Initializer.setDeepProperty

/**
 * Tests
 */
describe('Initializer', () => {

  /**
   * Traverse
   */
  describe('traverse', () => {
    let schema, source, target, operation

    beforeEach(() => {
      schema = {
        a: { type: 'string' },
        b: { type: 'string' },
        c: { properties: { d: { type: 'string' } } }
      }

      source = {
        a: 'a',
        b: 'b',
        c: { d: 'd' }
      }

      target = {}
    })

    it('should traverse schema and source objects', () => {
      operation = sinon.spy()
      Initializer.traverse(schema, source, target, operation)
      operation.should.have.been.calledWith('a', schema.a, source, target)
      operation.should.have.been.calledWith('b', schema.b, source, target)
      operation.should.have.been.calledWith('d', schema.c.properties.d, source.c, {})
    })

    it('should operate on a target object', () => {
      Initializer.traverse(schema, source, target, (key, desc, source, target) => {
        target[key] = source[key]
      })
      target.a.should.equal('a')
      target.b.should.equal('b')
      target.c.d.should.equal('d')
    })
  })

  /**
   * Assign
   */
  describe('assign', () => {
    let key, descriptors, source, target, options

    beforeEach(() => {
      descriptors = {
        simple: {
          type: 'string'
        },
        empty: {
          type: 'string'
        },
        private: {
          type: 'string',
          private: true
        },
        deleted: {
          type: 'string'
        },
        exists: {
          type: 'string'
        },
        immutable: {
          type: 'string',
          immutable: true
        },
        setter: {
          type: 'string',
          set: function (data) { this.setter = `${data.setter}ter` }
        },
        default: {
          type: 'string',
          default: 'default'
        },
        defaultFn: {
          type: 'string',
          default: () => 'default'
        },
        after: {
          type: 'string',
          after: function (data) { this.setAfter = `${data.after} assignment` }
        },
        whitespace: {
          type: 'string'
        },
        whitespaces: {
          type: 'array'
        },
        trim: {
          type: 'string',
          trim: true
        },
        trims: {
          type: 'array',
          trim: true
        },
        leading: {
          type: 'string',
          trim: {
            leading: true
          }
        },
        leadings: {
          type: 'array',
          trim: {
            leading: true
          }
        },
        trailing: {
          type: 'string',
          trim: {
            trailing: true
          }
        },
        trailings: {
          type: 'array',
          trim: {
            trailing: true
          }
        }
      }

      source = {
        simple: 'simple',
        empty: '',
        deleted: 'deleted',
        private: 'private',
        immutable: 'immutable',
        setter: 'set',
        after: 'after',
        whitespace: '  no trim  ',
        whitespaces: [ '  no  ', '  trim  '],
        trim: '  trim  ',
        trims: ['  trim  ', '  trim  '],
        leading: '  leading  ',
        leadings: ['  leading  ', '  leading  '],
        trailing: '  trailing  ',
        trailings: ['  trailing  ', '  trailing  ']
      }

      target = {
        deleted: 'not deleted',
        exists: 'exists'
      }

      options = { $unset: [ 'deleted' ] }
    })

    it('should set a property on target from source', () => {
      assign('simple', descriptors.simple, source, target, options)
      target.simple.should.equal('simple')
    })

    it('should set an empty string on a target from source', () => {
      assign('empty', descriptors.empty, source, target, options)
      target.empty.should.equal('')
    })

    it('should remove target properties marked for deletion with $unset', () => {
      assign('deleted', descriptors.deleted, source, target, options)
      target.should.not.have.property('deleted')
    })

    it('should keep target properties not marked for deletion with $unset', () => {
      assign('exists', descriptors.exists, source, target, options)
      target.should.have.property('exists')
      target.exists.should.equal('exists')
    })

    it('should skip private properties by default', () => {
      assign('private', descriptors.private, source, target, options)
      expect(target.private).to.be.undefined
    })

    it('should optionally assign private properties', () => {
      assign('private', descriptors.private, source, target, { private: true })
      target.private.should.equal('private')
    })

    it.skip('should define immutable properties', () => {
      assign('immutable', descriptors.immutable, source, target, options)
      target.immutable = 'changed'
      target.immutable.should.equal('immutable')
    })

    it('should set a property from a setter method', () => {
      assign('setter', descriptors.setter, source, target, options)
      target.setter.should.equal('setter')
    })

    it('should set a property from a default value', () => {
      assign('default', descriptors.default, source, target, options)
      target.default.should.equal('default')
    })

    it('should set a property from a default function', () => {
      assign('defaultFn', descriptors.defaultFn, source, target, options)
      target.defaultFn.should.equal('default')
    })

    it('should optionally skip default assignment', () => {
      assign('default', descriptors.default, source, target, { defaults: false })
      expect(target.default).to.be.undefined
    })

    it('should invoke an "after" method', () => {
      assign('after', descriptors.after, source, target, options)
      target.setAfter.should.equal('after assignment')
    })

    it('should not trim whitespace in a string by default', () => {
      assign('whitespace', descriptors.whitespace, source, target, options)
      target.whitespace.should.equal(source.whitespace)
    })

    it('should not trim whitespace in an array by default', () => {
      assign('whitespaces', descriptors.whitespaces, source, target, options)
      target.whitespaces.should.equal(source.whitespaces)
    })

    it('should trim both leading and trailing whitespace in a string', () => {
      assign('trim', descriptors.trim, source, target, options)
      target.trim.should.equal('trim')
    })

    it('should trim both leading and trailing whitespace in an array', () => {
      assign('trims', descriptors.trims, source, target, options)
      target.trims.should.eql(['trim', 'trim'])
    })

    it('should trim leading whitespace in a string', () => {
      assign('leading', descriptors.leading, source, target, options)
      target.leading.should.equal('leading  ')
    })

    it('should trim leading whitespace in an array', () => {
      assign('leadings', descriptors.leadings, source, target, options)
      target.leadings.should.eql(['leading  ', 'leading  '])
    })

    it('should trim trailing whitespace in a string', () => {
      assign('trailing', descriptors.trailing, source, target, options)
      target.trailing.should.equal('  trailing')
    })

    it('should trim trailing whitespace ', () => {
      assign('trailings', descriptors.trailings, source, target, options)
      target.trailings.should.eql(['  trailing', '  trailing'])
    })
  })

  describe('map', () => {
    let mapping, source, target

    beforeEach(() => {
      source = {
        a: 'a',
        b: { c: { d: 'e' } },
        f: 'f'
      }

      mapping = {
        'q': 'a',
        'r.s': 'b.c.d',
        'n': function (src) { return Object.keys(src).length }
      }

      target = {}
    })

    it('should assign properties to an object from a mapping', () => {
      map(mapping, source, target)
      target.q.should.equal('a')
      target.r.s.should.equal('e')
      target.n.should.equal(3)
    })

    it('should ignore properties of the source not defined in the mapping', () => {
      map(mapping, source, target)
      expect(target.f).to.be.undefined
    })
  })

  describe('project', () => {
    it('should be tested')
  })

  describe('select', () => {
    let properties, source, target

    beforeEach(() => {
      properties = [ 'a', 'b.c.d' ]

      source = {
        a: 'a',
        b: { c: { d: 'e' } },
        f: 'f'
      }

      target = {}
    })

    it('should assign a subset of a source object\'s properties to a target', () => {
      select(properties, source, target)
      target.a.should.equal('a')
      target.b.c.d.should.equal('e')
    })

    it('should ignore properties not defined in the properties', () => {
      select(properties, source, target)
      expect(target.f).to.be.undefined
    })
  })

  describe('getDeepProperty', () => {
    it('should read a value from nested source objects via chain', () => {
      getDeepProperty({ a: { b: { c: 'c' } } }, ['a', 'b', 'c']).should.equal('c')
    })

    it('should read an empty string', () => {
      getDeepProperty({ a: { b: { c: '' } } }, ['a', 'b', 'c']).should.equal('')
    })
  })

  describe('setDeepProperty', () => {
    it('should read a value from nested source objects via chain', () => {
      let target = {}
      setDeepProperty(target, ['a', 'c'], 'c')
      target.a.c.should.equal('c')
    })

    it('should ignore undefined values', () => {
      let target = { a: 'a', b: 'b' }
      setDeepProperty(target, ['a'], undefined)
      target.a.should.equal('a')
    })

    it('should set empty strings', () => {
      let target = { a: 'a' }
      setDeepProperty(target, ['a'], '')
      target.a.should.equal('')
    })
  })

  describe('initialize', () => {
    it('should be tested')
  })

})
<commit_msg>test(Initializer): test initialize and project<commit_after>'use strict'

/**
 * Test dependencies
 */
const path = require('path')
const chai = require('chai')
const sinon = require('sinon')
const sinonChai = require('sinon-chai')

/**
 * Assertions
 */
chai.use(sinonChai)
chai.should()
let expect = chai.expect

/**
 * Code under test
 */
const Initializer = require(path.join(process.cwd(), 'core', 'data', 'Initializer'))
const initialize = Initializer.initialize
const traverse = Initializer.traverse
const assign = Initializer.assign
const select = Initializer.select
const map = Initializer.map
const project = Initializer.project
const getDeepProperty = Initializer.getDeepProperty
const setDeepProperty = Initializer.setDeepProperty

/**
 * Tests
 */
describe('Initializer', () => {

  /**
   * Traverse
   */
  describe('traverse', () => {
    let schema, source, target, operation

    beforeEach(() => {
      schema = {
        a: { type: 'string' },
        b: { type: 'string' },
        c: { properties: { d: { type: 'string' } } }
      }

      source = {
        a: 'a',
        b: 'b',
        c: { d: 'd' }
      }

      target = {}
    })

    it('should traverse schema and source objects', () => {
      operation = sinon.spy()
      Initializer.traverse(schema, source, target, operation)
      operation.should.have.been.calledWith('a', schema.a, source, target)
      operation.should.have.been.calledWith('b', schema.b, source, target)
      operation.should.have.been.calledWith('d', schema.c.properties.d, source.c, {})
    })

    it('should operate on a target object', () => {
      Initializer.traverse(schema, source, target, (key, desc, source, target) => {
        target[key] = source[key]
      })
      target.a.should.equal('a')
      target.b.should.equal('b')
      target.c.d.should.equal('d')
    })
  })

  /**
   * Assign
   */
  describe('assign', () => {
    let key, descriptors, source, target, options

    beforeEach(() => {
      descriptors = {
        simple: {
          type: 'string'
        },
        empty: {
          type: 'string'
        },
        private: {
          type: 'string',
          private: true
        },
        deleted: {
          type: 'string'
        },
        exists: {
          type: 'string'
        },
        immutable: {
          type: 'string',
          immutable: true
        },
        setter: {
          type: 'string',
          set: function (data) { this.setter = `${data.setter}ter` }
        },
        default: {
          type: 'string',
          default: 'default'
        },
        defaultFn: {
          type: 'string',
          default: () => 'default'
        },
        after: {
          type: 'string',
          after: function (data) { this.setAfter = `${data.after} assignment` }
        },
        whitespace: {
          type: 'string'
        },
        whitespaces: {
          type: 'array'
        },
        trim: {
          type: 'string',
          trim: true
        },
        trims: {
          type: 'array',
          trim: true
        },
        leading: {
          type: 'string',
          trim: {
            leading: true
          }
        },
        leadings: {
          type: 'array',
          trim: {
            leading: true
          }
        },
        trailing: {
          type: 'string',
          trim: {
            trailing: true
          }
        },
        trailings: {
          type: 'array',
          trim: {
            trailing: true
          }
        }
      }

      source = {
        simple: 'simple',
        empty: '',
        deleted: 'deleted',
        private: 'private',
        immutable: 'immutable',
        setter: 'set',
        after: 'after',
        whitespace: '  no trim  ',
        whitespaces: [ '  no  ', '  trim  '],
        trim: '  trim  ',
        trims: ['  trim  ', '  trim  '],
        leading: '  leading  ',
        leadings: ['  leading  ', '  leading  '],
        trailing: '  trailing  ',
        trailings: ['  trailing  ', '  trailing  ']
      }

      target = {
        deleted: 'not deleted',
        exists: 'exists'
      }

      options = { $unset: [ 'deleted' ] }
    })

    it('should set a property on target from source', () => {
      assign('simple', descriptors.simple, source, target, options)
      target.simple.should.equal('simple')
    })

    it('should set an empty string on a target from source', () => {
      assign('empty', descriptors.empty, source, target, options)
      target.empty.should.equal('')
    })

    it('should remove target properties marked for deletion with $unset', () => {
      assign('deleted', descriptors.deleted, source, target, options)
      target.should.not.have.property('deleted')
    })

    it('should keep target properties not marked for deletion with $unset', () => {
      assign('exists', descriptors.exists, source, target, options)
      target.should.have.property('exists')
      target.exists.should.equal('exists')
    })

    it('should skip private properties by default', () => {
      assign('private', descriptors.private, source, target, options)
      expect(target.private).to.be.undefined
    })

    it('should optionally assign private properties', () => {
      assign('private', descriptors.private, source, target, { private: true })
      target.private.should.equal('private')
    })

    it.skip('should define immutable properties', () => {
      assign('immutable', descriptors.immutable, source, target, options)
      target.immutable = 'changed'
      target.immutable.should.equal('immutable')
    })

    it('should set a property from a setter method', () => {
      assign('setter', descriptors.setter, source, target, options)
      target.setter.should.equal('setter')
    })

    it('should set a property from a default value', () => {
      assign('default', descriptors.default, source, target, options)
      target.default.should.equal('default')
    })

    it('should set a property from a default function', () => {
      assign('defaultFn', descriptors.defaultFn, source, target, options)
      target.defaultFn.should.equal('default')
    })

    it('should optionally skip default assignment', () => {
      assign('default', descriptors.default, source, target, { defaults: false })
      expect(target.default).to.be.undefined
    })

    it('should invoke an "after" method', () => {
      assign('after', descriptors.after, source, target, options)
      target.setAfter.should.equal('after assignment')
    })

    it('should not trim whitespace in a string by default', () => {
      assign('whitespace', descriptors.whitespace, source, target, options)
      target.whitespace.should.equal(source.whitespace)
    })

    it('should not trim whitespace in an array by default', () => {
      assign('whitespaces', descriptors.whitespaces, source, target, options)
      target.whitespaces.should.equal(source.whitespaces)
    })

    it('should trim both leading and trailing whitespace in a string', () => {
      assign('trim', descriptors.trim, source, target, options)
      target.trim.should.equal('trim')
    })

    it('should trim both leading and trailing whitespace in an array', () => {
      assign('trims', descriptors.trims, source, target, options)
      target.trims.should.eql(['trim', 'trim'])
    })

    it('should trim leading whitespace in a string', () => {
      assign('leading', descriptors.leading, source, target, options)
      target.leading.should.equal('leading  ')
    })

    it('should trim leading whitespace in an array', () => {
      assign('leadings', descriptors.leadings, source, target, options)
      target.leadings.should.eql(['leading  ', 'leading  '])
    })

    it('should trim trailing whitespace in a string', () => {
      assign('trailing', descriptors.trailing, source, target, options)
      target.trailing.should.equal('  trailing')
    })

    it('should trim trailing whitespace ', () => {
      assign('trailings', descriptors.trailings, source, target, options)
      target.trailings.should.eql(['  trailing', '  trailing'])
    })
  })

  describe('map', () => {
    let mapping, source, target

    beforeEach(() => {
      source = {
        a: 'a',
        b: { c: { d: 'e' } },
        f: 'f'
      }

      mapping = {
        'q': 'a',
        'r.s': 'b.c.d',
        'n': function (src) { return Object.keys(src).length }
      }

      target = {}
    })

    it('should assign properties to an object from a mapping', () => {
      map(mapping, source, target)
      target.q.should.equal('a')
      target.r.s.should.equal('e')
      target.n.should.equal(3)
    })

    it('should ignore properties of the source not defined in the mapping', () => {
      map(mapping, source, target)
      expect(target.f).to.be.undefined
    })
  })

  describe('project', () => {
    let mapping, source, target

    beforeEach(() => {
      source = {
        q: 1,
        r: { s: 2 }
      }

      mapping = {
        'q': 'a',
        'r.s': 'b.c.d',
        't': 'e.f'
      }

      target = {}
    })

    it('should project properties to an object from a mapping', () => {
      project(mapping, source, target)
      target.a.should.equal(1)
      target.b.c.d.should.equal(2)
    })

    it('should ignore properties of the source not defined in the mapping', () => {
      project(mapping, source, target)
      expect(target.t).to.be.undefined
    })
  })

  describe('select', () => {
    let properties, source, target

    beforeEach(() => {
      properties = [ 'a', 'b.c.d' ]

      source = {
        a: 'a',
        b: { c: { d: 'e' } },
        f: 'f'
      }

      target = {}
    })

    it('should assign a subset of a source object\'s properties to a target', () => {
      select(properties, source, target)
      target.a.should.equal('a')
      target.b.c.d.should.equal('e')
    })

    it('should ignore properties not defined in the properties', () => {
      select(properties, source, target)
      expect(target.f).to.be.undefined
    })
  })

  describe('getDeepProperty', () => {
    it('should read a value from nested source objects via chain', () => {
      getDeepProperty({ a: { b: { c: 'c' } } }, ['a', 'b', 'c']).should.equal('c')
    })

    it('should read an empty string', () => {
      getDeepProperty({ a: { b: { c: '' } } }, ['a', 'b', 'c']).should.equal('')
    })
  })

  describe('setDeepProperty', () => {
    it('should read a value from nested source objects via chain', () => {
      let target = {}
      setDeepProperty(target, ['a', 'c'], 'c')
      target.a.c.should.equal('c')
    })

    it('should ignore undefined values', () => {
      let target = { a: 'a', b: 'b' }
      setDeepProperty(target, ['a'], undefined)
      target.a.should.equal('a')
    })

    it('should set empty strings', () => {
      let target = { a: 'a' }
      setDeepProperty(target, ['a'], '')
      target.a.should.equal('')
    })
  })

  describe('initialize', () => {
    let schema, source, target, options

    beforeEach(() => {
      schema = {}
      target = {}
    })

    describe('with mapping option', () => {

      beforeEach(() => {
        options = {
          mapping: {}
        }

        sinon.spy(Initializer, 'map')
      })

      it('should map the source to the target', () => {
        Initializer.initialize(schema, source, target, options)
        Initializer.map.should.have.been.calledWith(options.mapping, {}, target)
      })

      after(() => {
        Initializer.map.restore()
      })
    })

    describe('with select option', () => {

      beforeEach(() => {
        options = {
          select: []
        }

        sinon.spy(Initializer, 'select')
      })

      it('should call select over the source object', () => {
        Initializer.initialize(schema, source, target, options)
        Initializer.select.should.have.been.calledWith(options.select, {}, target)
      })

      after(() => {
        Initializer.select.restore()
      })
    })

    describe('with no option', () => {

      beforeEach(() => {
        options = {}
        sinon.spy(Initializer, 'traverse')
      })

      it('should traverse the source object', () => {
        Initializer.initialize(schema, source, target, options)
        Initializer.traverse.should.have.been.calledWith(schema, {}, target, Initializer.assign, options)
      })

      after(() => {
        Initializer.traverse.restore()
      })

    })

  })

})
<|endoftext|>


<commit_before>require.paths.unshift('lib');
require.paths.unshift('./deps/node-paperboy/lib');
require.paths.unshift('./deps/redis-node-client/lib');
require.paths.unshift('./deps/node-smtp/lib');

var config = require('config');
var fs = require('fs');
var sys = require('sys');

var launch = function(){
  require('redis').client(function(client){
    fs.writeFile(config.general.pidFile, ""+process.pid, function(err, data){
        if (err){
            sys.error("Failed to write PID file ("+ config.general.pidFile+"): " + err);
            process.exit(1);
        }
        require('tempalias_http');
        require('tempalias_smtp');
    });
  });
};

try{
    var pd = fs.statSync(config.general.pidFile);
}catch(e){
  pd = null;
}

if (pd && pd.isFile()){
  sys.puts('PID file found. Attempting to kill previous instance if running');
  fs.readFile(config.general.pidFile, function(err, pid){
    if (!err){
      try{
        process.kill(parseInt(pid, 10), 'SIGTERM');
      }catch(e){}
    }
    launch();
  });
}else{
  launch();
}

<commit_msg>work around a bug in current nodes HTTP parser<commit_after>require.paths.unshift('lib');
require.paths.unshift('./deps/node-paperboy/lib');
require.paths.unshift('./deps/redis-node-client/lib');
require.paths.unshift('./deps/node-smtp/lib');

var config = require('config');
var fs = require('fs');
var sys = require('sys');

process.addListener('uncaughtException', function (err) {
  sys.error('Caught exception: ' + err);
});

var launch = function(){
  require('redis').client(function(client){
    fs.writeFile(config.general.pidFile, ""+process.pid, function(err, data){
        if (err){
            sys.error("Failed to write PID file ("+ config.general.pidFile+"): " + err);
            process.exit(1);
        }
        require('tempalias_http');
        require('tempalias_smtp');
    });
  });
};

try{
    var pd = fs.statSync(config.general.pidFile);
}catch(e){
  pd = null;
}

if (pd && pd.isFile()){
  sys.puts('PID file found. Attempting to kill previous instance if running');
  fs.readFile(config.general.pidFile, function(err, pid){
    if (!err){
      try{
        process.kill(parseInt(pid, 10), 'SIGTERM');
      }catch(e){}
    }
    launch();
  });
}else{
  launch();
}

<|endoftext|>


<commit_before>describe('sandbox library - pm api', function () {
    this.timeout(1000 * 60);
    var Sandbox = require('../../../'),

        sampleContextData = {
            globals: [{
                key: 'var1',
                value: 'one'
            }, {
                key: 'var2',
                value: 2,
                type: 'number'
            }],
            environment: [{
                key: 'var1',
                value: 'one-env'
            }, {
                key: 'var2',
                value: 2.5,
                type: 'number'
            }],
            collectionVariables: [{
                key: 'var1',
                value: 'collection-var1',
                type: 'string'
            }, {
                key: 'var3',
                value: 'collection-var3'
            }],
            data: {
                'var1': 'one-data'
            }
        },
        context;

    beforeEach(function (done) {
        Sandbox.createContext({debug: true}, function (err, ctx) {
            context = ctx;
            done(err);
        });
    });

    afterEach(function () {
        context.dispose();
        context = null;
    });

    it('pm object should be in globals', function (done) {
        context.execute(`
            var assert = require('assert');
            assert.strictEqual(typeof pm, 'object');
        `, done);
    });

    describe('info', function () {
        it('must have relevant information', function (done) {
            context.execute({
                listen: 'test',
                script: `
                    var assert = require('assert');

                    assert.strictEqual(pm.info.eventName, 'test', 'event name must be test');
                    assert.strictEqual(pm.info.iteration, 2, 'iteration should be 2');
                    assert.strictEqual(pm.info.iterationCount, 3, 'iteration total should be 3');
                    assert.strictEqual(pm.info.requestName, 'request-name', 'requestName should be accurate');
                    assert.strictEqual(pm.info.requestId, 'request-id', 'requestId should be accurate');
                `
            }, {
                cursor: {
                    iteration: 2,
                    cycles: 3
                },
                legacy: {
                    _itemName: 'request-name',
                    _itemId: 'request-id'
                }

            }, done);
        });
    });

    describe('globals', function () {
        it('must be defined as VariableScope', function (done) {
            context.execute(`
                var assert = require('assert'),
                    VariableScope = require('postman-collection').VariableScope;
                assert.strictEqual(VariableScope.isVariableScope(pm.globals), true);
            `, done);
        });

        it('must be a readonly property', function (done) {
            context.execute(`
                var assert = require('assert'),
                    _globals;

                _globals = pm.globals;
                pm.globals = [];

                assert.strictEqual(pm.globals, _globals, 'property stays inchanged');
            `, done);
        });

        it('must forward global variables forwarded during execution', function (done) {
            context.execute(`
                var assert = require('assert');
                assert.strictEqual(pm.globals.get('var1'), 'one');
                assert.strictEqual(pm.globals.get('var2'), 2);
            `, {context: sampleContextData}, done);
        });

        it('must propagate updated globals from inside sandbox', function (done) {
            context.execute(`
                var assert = require('assert');

                assert.strictEqual(pm.globals.get('var1'), 'one');
                pm.globals.set('var1', 'one-one');
                assert.strictEqual(pm.globals.get('var1'), 'one-one');

            `, {context: sampleContextData}, function (err, exec) {
                expect(err).not.be.ok();
                expect(exec).be.ok();
                expect(exec.globals.values).eql([
                    {type: 'any', value: 'one-one', key: 'var1'},
                    {type: 'number', value: 2, key: 'var2'}
                ]);
                done();
            });
        });

        it('pm.globals.toObject must return a pojo', function (done) {
            context.execute(`
                var assert = require('assert');

                assert.strictEqual(_.isPlainObject(pm.globals.toObject()), true);
                assert.deepEqual(pm.globals.toObject(), {
                    var1: 'one',
                    var2: 2
                });
            `, {context: sampleContextData}, done);
        });
    });

    describe('environment', function () {
        it('must be defined as VariableScope', function (done) {
            context.execute(`
                var assert = require('assert'),
                    VariableScope = require('postman-collection').VariableScope;
                assert.strictEqual(VariableScope.isVariableScope(pm.environment), true);
            `, done);
        });

        it('must be a readonly property', function (done) {
            context.execute(`
                var assert = require('assert'),
                    _environment;

                _environment = pm.globals;
                pm.globals = [];

                assert.strictEqual(pm.globals, _environment, 'property stays inchanged');
            `, done);
        });

        it('must forward environment variables forwarded during execution', function (done) {
            context.execute(`
                var assert = require('assert');
                assert.strictEqual(pm.environment.get('var1'), 'one-env');
                assert.strictEqual(pm.environment.get('var2'), 2.5);
            `, {context: sampleContextData}, done);
        });

        it('must propagate updated environment from inside sandbox', function (done) {
            context.execute(`
                var assert = require('assert');

                assert.strictEqual(pm.environment.get('var1'), 'one-env');
                pm.environment.set('var1', 'one-one-env');
                assert.strictEqual(pm.environment.get('var1'), 'one-one-env');

            `, {context: sampleContextData}, function (err, exec) {
                expect(err).not.be.ok();
                expect(exec).be.ok();
                expect(exec.environment.values).eql([
                    {type: 'any', value: 'one-one-env', key: 'var1'},
                    {type: 'number', value: 2.5, key: 'var2'}
                ]);
                done();
            });
        });

        it('pm.environment.toObject must return a pojo', function (done) {
            context.execute(`
                var assert = require('assert');

                assert.strictEqual(_.isPlainObject(pm.environment.toObject()), true);
                assert.deepEqual(pm.environment.toObject(), {
                    var1: 'one-env',
                    var2: 2.5
                });
            `, {context: sampleContextData}, done);
        });
    });

    describe('request', function () {
        it('must be defined as sdk Request object', function (done) {
            context.execute(`
                var assert = require('assert'),
                    Request = require('postman-collection').Request;
                assert.strictEqual(Request.isRequest(pm.request), true);
            `, {
                context: {
                    request: 'https://postman-echo.com/get?foo=bar'
                }
            }, done);
        });

        it('when serialized should not have assertion helpers added by sandbox', function (done) {
            context.execute(`
                var assert = require('assert'),
                    reqJSON;

                try {
                    reqJSON = pm.request.toJSON();
                    assert.deepEqual(reqJSON.url, {
                        protocol: 'https',
                        path: ['get'],
                        host: ['postman-echo', 'com'],
                        query: [{ key: 'foo', value: 'bar' }],
                        variable: []
                    });
                    assert.strictEqual(reqJSON.method, 'GET');
                    assert.equal(reqJSON.to, undefined);
                }
                catch (e) {
                    assert.equal(e, null);
                }
            `, {
                context: {
                    request: 'https://postman-echo.com/get?foo=bar'
                }
            }, done);
        });

        it('must not be defined if request is missing in generic script target', function (done) {
            context.execute(`
                var assert = require('assert'),
                    Request = require('postman-collection').Request;
                assert.strictEqual(Request.isRequest(pm.request), false);
            `, done);
        });

        it('must be defined in prerequest script even if request is missing in context', function (done) {
            context.execute({
                listen: 'prerequest',
                script: `
                var assert = require('assert'),
                    Request = require('postman-collection').Request;
                assert.strictEqual(Request.isRequest(pm.request), true);
            `
            }, done);
        });

        it('must be defined in test script even if request is missing in context', function (done) {
            context.execute({
                listen: 'test',
                script: `
                var assert = require('assert'),
                    Request = require('postman-collection').Request;
                assert.strictEqual(Request.isRequest(pm.request), true);
            `
            }, done);
        });
    });

    describe('response', function () {
        it('must be defined as sdk Request object', function (done) {
            context.execute(`
                var assert = require('assert'),
                    Response = require('postman-collection').Response;

                assert.strictEqual(Response.isResponse(pm.response), true, 'pm.response should be sdk');
                assert.strictEqual(pm.response.code, 200, 'code should match');
            `, {
                context: {
                    response: {
                        code: 200
                    }
                }
            }, done);
        });

        it('when serialized should not have assertion helpers added by sandbox', function (done) {
            context.execute(`
                var assert = require('assert'),
                    resJSON;

                try {
                    resJSON = pm.response.toJSON();
                    assert.strictEqual(resJSON.code, 200);
                    assert.equal(resJSON.to, undefined);
                }
                catch (e) {
                    assert.equal(e, null);
                }
            `, {
                context: {
                    response: {
                        code: 200
                    }
                }
            }, done);
        });

        it('must not be defined for non test targets', function (done) {
            context.execute(`
                var assert = require('assert'),
                    Response = require('postman-collection').Response;
                assert.strictEqual(Response.isResponse(pm.response), false);
            `, done);
        });

        it('must be defined in test target even when context is missing', function (done) {
            context.execute({
                listen: 'test',
                script: `
                    var assert = require('assert'),
                        Response = require('postman-collection').Response;
                    assert.strictEqual(Response.isResponse(pm.response), true);
                `
            }, done);
        });

        it('must parse response json body', function (done) {
            context.execute(`
                var assert = require('assert');
                assert.equal(pm.response.body, undefined, 'body should not be defined as string');
                assert.deepEqual(pm.response.json(), {
                    foo: "bar"
                });
            `, {
                context: {
                    response: {
                        code: 200,
                        stream: {
                            type: 'Buffer',
                            data: [123, 34, 102, 111, 111, 34, 58, 32, 34, 98, 97, 114, 34, 125]
                        }
                    }
                }
            }, done);
        });
    });

    describe('cookies', function () {
        it('must be available', function (done) {
            context.execute(`
                var assert = require('assert');
                assert.strictEqual(typeof pm.cookies, 'object', 'cookies must be defined');
            `, {
                context: {
                    cookies: []
                }
            }, done);
        });

        it('must convert context cookie array to list', function (done) {
            context.execute(`
                var assert = require('assert');
                assert.strictEqual(pm.cookies.count(), 2, 'two cookies must be present');
            `, {
                context: {
                    cookies: [{
                        name: 'cookie1',
                        value: 'onevalue',
                        httpOnly: true
                    }, {
                        name: 'cookie2',
                        value: 'anothervalue'
                    }]
                }
            }, done);
        });

        it('must return value of one cookie', function (done) {
            context.execute(`
                var assert = require('assert');
                assert.strictEqual(pm.cookies.one('cookie2').value, 'anothervalue', 'value must be defined');
            `, {
                context: {
                    cookies: [{
                        name: 'cookie1',
                        value: 'onevalue',
                        httpOnly: true
                    }, {
                        name: 'cookie2',
                        value: 'anothervalue'
                    }]
                }
            }, done);
        });
    });

    describe('chai', function () {
        it('must be available as expect', function (done) {
            context.execute(`
                var assert = require('assert');
                assert.strictEqual(pm.expect, require('chai').expect);
            `, done);
        });

        it('must work with common assertions', function (done) {
            context.execute(`
                pm.expect(new Error).not.to.be.an('error');
            `, function (err) {
                expect(err).be.ok();
                expect(err).have.property('message', 'expected [Error] not to be an error');
                done();
            });
        });

        it('must pre-assert response', function (done) {
            context.execute(`
                pm.expect(pm.response).to.have.property('to');
                pm.expect(pm.response.to).be.an('object');

                // run a test as well ;-)
                pm.response.to.be.ok;
            `, {
                context: {
                    response: {code: 200}
                }
            }, done);
        });

        it('must pre-assert request', function (done) {
            context.execute(`
                pm.expect(pm.request).to.have.property('to');
                pm.expect(pm.request.to).be.an('object');
            `, {
                context: {
                    request: 'https://postman-echo.com/'
                }
            }, done);
        });
    });

    describe('iterationData', function () {
        it('should be an instance of VariableScope', function (done) {
            context.execute(`
                var assert = require('assert'),
                    VariableScope = require('postman-collection').VariableScope;
                assert.strictEqual(VariableScope.isVariableScope(pm.iterationData), true);
            `, {context: sampleContextData}, done);
        });
        it('pm.data must not exist', function (done) {
            context.execute(`
                var assert = require('assert');

                assert.strictEqual(pm.data, undefined);
            `, {context: sampleContextData}, done);
        });
        it('accesses the current iteration data via pm.iterationData', function (done) {
            context.execute(`
                var assert = require('assert');

                assert.strictEqual(pm.iterationData.get('var1'), 'one-data');
            `, {context: sampleContextData}, done);
        });
        it('pm.iterationData.toObject must return a pojo', function (done) {
            context.execute(`
                var assert = require('assert');

                assert.strictEqual(_.isPlainObject(pm.iterationData.toObject()), true);
                assert.deepEqual(pm.iterationData.toObject(), {
                    var1: 'one-data'
                });
            `, {context: sampleContextData}, done);
        });
    });

    describe('sendRequest', function () {
        it('must be a function exposed', function (done) {
            context.execute(`
                var assert = require('assert');
                assert.strictEqual((typeof pm.sendRequest), 'function');
            `, {context: sampleContextData}, done);
        });

        it('must dispatch an `execution.request.id` event when called', function (done) {
            var executionId = '1';

            context.on('execution.request.' + executionId, function (cursor, id, requestId, req) {
                expect(req.url).to.eql({
                    protocol: 'https',
                    path: ['get'],
                    host: ['postman-echo', 'com'],
                    query: [],
                    variable: []
                });
                done();
            });

            context.execute(`
                pm.sendRequest('https://postman-echo.com/get');
            `, {
                context: sampleContextData,
                id: executionId
            }, function () {}); // eslint-disable-line no-empty-function
        });

        it('must forward response to callback when sent from outside', function (done) {
            var executionId = '2';
            context.on('error', done);

            context.on('execution.error', function (cur, err) {
                expect(err).to.not.be.ok();
                done();
            });

            // @todo find the cause of the error where assertions are not being fired from inside a timer
            context.on('execution.assertion', function (cursor, assertions) {
                assertions.forEach(function (ass) {
                    expect(ass).to.have.property('passed', true);
                    expect(ass).to.have.property('error', null);
                });
                done();
            });

            context.on('execution.request.' + executionId, function (cursor, id, requestId, req) {
                expect(req.url).to.eql({
                    protocol: 'https',
                    path: ['get'],
                    host: ['postman-echo', 'com'],
                    query: [],
                    variable: []
                });
                context.dispatch(`execution.response.${id}`, requestId, null, {
                    code: 200,
                    body: '{"i am": "a json"}'
                });
            });

            context.execute(`
                pm.sendRequest('https://postman-echo.com/get', function (err, res) {
                    pm.test('response', function () {
                        pm.expect(res).to.have.property('code', 200);
                        pm.expect(res.json()).to.have.property('i am', 'a json');
                    });
                });
            `, {
                context: sampleContextData,
                id: executionId
            }, function () {}); // eslint-disable-line no-empty-function
        });
    });
});
<commit_msg>Update pm test to chai<commit_after>describe('sandbox library - pm api', function () {
    this.timeout(1000 * 60);
    var Sandbox = require('../../../'),

        sampleContextData = {
            globals: [{
                key: 'var1',
                value: 'one'
            }, {
                key: 'var2',
                value: 2,
                type: 'number'
            }],
            environment: [{
                key: 'var1',
                value: 'one-env'
            }, {
                key: 'var2',
                value: 2.5,
                type: 'number'
            }],
            collectionVariables: [{
                key: 'var1',
                value: 'collection-var1',
                type: 'string'
            }, {
                key: 'var3',
                value: 'collection-var3'
            }],
            data: {
                'var1': 'one-data'
            }
        },
        context;

    beforeEach(function (done) {
        Sandbox.createContext({debug: true}, function (err, ctx) {
            context = ctx;
            done(err);
        });
    });

    afterEach(function () {
        context.dispose();
        context = null;
    });

    it('pm object should be in globals', function (done) {
        context.execute(`
            var assert = require('assert');
            assert.strictEqual(typeof pm, 'object');
        `, done);
    });

    describe('info', function () {
        it('should have relevant information', function (done) {
            context.execute({
                listen: 'test',
                script: `
                    var assert = require('assert');

                    assert.strictEqual(pm.info.eventName, 'test', 'event name must be test');
                    assert.strictEqual(pm.info.iteration, 2, 'iteration should be 2');
                    assert.strictEqual(pm.info.iterationCount, 3, 'iteration total should be 3');
                    assert.strictEqual(pm.info.requestName, 'request-name', 'requestName should be accurate');
                    assert.strictEqual(pm.info.requestId, 'request-id', 'requestId should be accurate');
                `
            }, {
                cursor: {
                    iteration: 2,
                    cycles: 3
                },
                legacy: {
                    _itemName: 'request-name',
                    _itemId: 'request-id'
                }

            }, done);
        });
    });

    describe('globals', function () {
        it('should be defined as VariableScope', function (done) {
            context.execute(`
                var assert = require('assert'),
                    VariableScope = require('postman-collection').VariableScope;
                assert.strictEqual(VariableScope.isVariableScope(pm.globals), true);
            `, done);
        });

        it('should be a readonly property', function (done) {
            context.execute(`
                var assert = require('assert'),
                    _globals;

                _globals = pm.globals;
                pm.globals = [];

                assert.strictEqual(pm.globals, _globals, 'property stays inchanged');
            `, done);
        });

        it('should forward global variables forwarded during execution', function (done) {
            context.execute(`
                var assert = require('assert');
                assert.strictEqual(pm.globals.get('var1'), 'one');
                assert.strictEqual(pm.globals.get('var2'), 2);
            `, {context: sampleContextData}, done);
        });

        it('should propagate updated globals from inside sandbox', function (done) {
            context.execute(`
                var assert = require('assert');

                assert.strictEqual(pm.globals.get('var1'), 'one');
                pm.globals.set('var1', 'one-one');
                assert.strictEqual(pm.globals.get('var1'), 'one-one');

            `, {context: sampleContextData}, function (err, exec) {
                expect(err).to.be.null;
                expect(exec).to.be.ok;
                expect(exec.globals.values).eql([
                    {type: 'any', value: 'one-one', key: 'var1'},
                    {type: 'number', value: 2, key: 'var2'}
                ]);
                done();
            });
        });

        it('pm.globals.toObject must return a pojo', function (done) {
            context.execute(`
                var assert = require('assert');

                assert.strictEqual(_.isPlainObject(pm.globals.toObject()), true);
                assert.deepEqual(pm.globals.toObject(), {
                    var1: 'one',
                    var2: 2
                });
            `, {context: sampleContextData}, done);
        });
    });

    describe('environment', function () {
        it('should be defined as VariableScope', function (done) {
            context.execute(`
                var assert = require('assert'),
                    VariableScope = require('postman-collection').VariableScope;
                assert.strictEqual(VariableScope.isVariableScope(pm.environment), true);
            `, done);
        });

        it('should be a readonly property', function (done) {
            context.execute(`
                var assert = require('assert'),
                    _environment;

                _environment = pm.globals;
                pm.globals = [];

                assert.strictEqual(pm.globals, _environment, 'property stays inchanged');
            `, done);
        });

        it('should forward environment variables forwarded during execution', function (done) {
            context.execute(`
                var assert = require('assert');
                assert.strictEqual(pm.environment.get('var1'), 'one-env');
                assert.strictEqual(pm.environment.get('var2'), 2.5);
            `, {context: sampleContextData}, done);
        });

        it('should propagate updated environment from inside sandbox', function (done) {
            context.execute(`
                var assert = require('assert');

                assert.strictEqual(pm.environment.get('var1'), 'one-env');
                pm.environment.set('var1', 'one-one-env');
                assert.strictEqual(pm.environment.get('var1'), 'one-one-env');

            `, {context: sampleContextData}, function (err, exec) {
                expect(err).to.be.null;
                expect(exec).to.be.ok;
                expect(exec.environment.values).eql([
                    {type: 'any', value: 'one-one-env', key: 'var1'},
                    {type: 'number', value: 2.5, key: 'var2'}
                ]);
                done();
            });
        });

        it('pm.environment.toObject must return a pojo', function (done) {
            context.execute(`
                var assert = require('assert');

                assert.strictEqual(_.isPlainObject(pm.environment.toObject()), true);
                assert.deepEqual(pm.environment.toObject(), {
                    var1: 'one-env',
                    var2: 2.5
                });
            `, {context: sampleContextData}, done);
        });
    });

    describe('request', function () {
        it('should be defined as sdk Request object', function (done) {
            context.execute(`
                var assert = require('assert'),
                    Request = require('postman-collection').Request;
                assert.strictEqual(Request.isRequest(pm.request), true);
            `, {
                context: {
                    request: 'https://postman-echo.com/get?foo=bar'
                }
            }, done);
        });

        it('when serialized should not have assertion helpers added by sandbox', function (done) {
            context.execute(`
                var assert = require('assert'),
                    reqJSON;

                try {
                    reqJSON = pm.request.toJSON();
                    assert.deepEqual(reqJSON.url, {
                        protocol: 'https',
                        path: ['get'],
                        host: ['postman-echo', 'com'],
                        query: [{ key: 'foo', value: 'bar' }],
                        variable: []
                    });
                    assert.strictEqual(reqJSON.method, 'GET');
                    assert.equal(reqJSON.to, undefined);
                }
                catch (e) {
                    assert.equal(e, null);
                }
            `, {
                context: {
                    request: 'https://postman-echo.com/get?foo=bar'
                }
            }, done);
        });

        it('should not be defined if request is missing in generic script target', function (done) {
            context.execute(`
                var assert = require('assert'),
                    Request = require('postman-collection').Request;
                assert.strictEqual(Request.isRequest(pm.request), false);
            `, done);
        });

        it('should be defined in prerequest script even if request is missing in context', function (done) {
            context.execute({
                listen: 'prerequest',
                script: `
                var assert = require('assert'),
                    Request = require('postman-collection').Request;
                assert.strictEqual(Request.isRequest(pm.request), true);
            `
            }, done);
        });

        it('should be defined in test script even if request is missing in context', function (done) {
            context.execute({
                listen: 'test',
                script: `
                var assert = require('assert'),
                    Request = require('postman-collection').Request;
                assert.strictEqual(Request.isRequest(pm.request), true);
            `
            }, done);
        });
    });

    describe('response', function () {
        it('should be defined as sdk Request object', function (done) {
            context.execute(`
                var assert = require('assert'),
                    Response = require('postman-collection').Response;

                assert.strictEqual(Response.isResponse(pm.response), true, 'pm.response should be sdk');
                assert.strictEqual(pm.response.code, 200, 'code should match');
            `, {
                context: {
                    response: {
                        code: 200
                    }
                }
            }, done);
        });

        it('when serialized should not have assertion helpers added by sandbox', function (done) {
            context.execute(`
                var assert = require('assert'),
                    resJSON;

                try {
                    resJSON = pm.response.toJSON();
                    assert.strictEqual(resJSON.code, 200);
                    assert.equal(resJSON.to, undefined);
                }
                catch (e) {
                    assert.equal(e, null);
                }
            `, {
                context: {
                    response: {
                        code: 200
                    }
                }
            }, done);
        });

        it('should not be defined for non test targets', function (done) {
            context.execute(`
                var assert = require('assert'),
                    Response = require('postman-collection').Response;
                assert.strictEqual(Response.isResponse(pm.response), false);
            `, done);
        });

        it('should be defined in test target even when context is missing', function (done) {
            context.execute({
                listen: 'test',
                script: `
                    var assert = require('assert'),
                        Response = require('postman-collection').Response;
                    assert.strictEqual(Response.isResponse(pm.response), true);
                `
            }, done);
        });

        it('should parse response json body', function (done) {
            context.execute(`
                var assert = require('assert');
                assert.equal(pm.response.body, undefined, 'body should not be defined as string');
                assert.deepEqual(pm.response.json(), {
                    foo: "bar"
                });
            `, {
                context: {
                    response: {
                        code: 200,
                        stream: {
                            type: 'Buffer',
                            data: [123, 34, 102, 111, 111, 34, 58, 32, 34, 98, 97, 114, 34, 125]
                        }
                    }
                }
            }, done);
        });
    });

    describe('cookies', function () {
        it('should be available', function (done) {
            context.execute(`
                var assert = require('assert');
                assert.strictEqual(typeof pm.cookies, 'object', 'cookies must be defined');
            `, {
                context: {
                    cookies: []
                }
            }, done);
        });

        it('should convert context cookie array to list', function (done) {
            context.execute(`
                var assert = require('assert');
                assert.strictEqual(pm.cookies.count(), 2, 'two cookies must be present');
            `, {
                context: {
                    cookies: [{
                        name: 'cookie1',
                        value: 'onevalue',
                        httpOnly: true
                    }, {
                        name: 'cookie2',
                        value: 'anothervalue'
                    }]
                }
            }, done);
        });

        it('should return value of one cookie', function (done) {
            context.execute(`
                var assert = require('assert');
                assert.strictEqual(pm.cookies.one('cookie2').value, 'anothervalue', 'value must be defined');
            `, {
                context: {
                    cookies: [{
                        name: 'cookie1',
                        value: 'onevalue',
                        httpOnly: true
                    }, {
                        name: 'cookie2',
                        value: 'anothervalue'
                    }]
                }
            }, done);
        });
    });

    describe('chai', function () {
        it('should be available as expect', function (done) {
            context.execute(`
                var assert = require('assert');
                assert.strictEqual(pm.expect, require('chai').expect);
            `, done);
        });

        it('should work with common assertions', function (done) {
            context.execute(`
                pm.expect(new Error).to.not.be.an('error');
            `, function (err) {
                expect(err).to.be.ok;
                expect(err).have.property('message', 'expected [Error] not to be an error');
                done();
            });
        });

        it('should pre-assert response', function (done) {
            context.execute(`
                pm.expect(pm.response).to.have.property('to');
                pm.expect(pm.response.to).to.be.an('object');

                // run a test as well ;-)
                pm.response.to.be.ok;
            `, {
                context: {
                    response: {code: 200}
                }
            }, done);
        });

        it('should pre-assert request', function (done) {
            context.execute(`
                pm.expect(pm.request).to.have.property('to');
                pm.expect(pm.request.to).to.be.an('object');
            `, {
                context: {
                    request: 'https://postman-echo.com/'
                }
            }, done);
        });
    });

    describe('iterationData', function () {
        it('should be an instance of VariableScope', function (done) {
            context.execute(`
                var assert = require('assert'),
                    VariableScope = require('postman-collection').VariableScope;
                assert.strictEqual(VariableScope.isVariableScope(pm.iterationData), true);
            `, {context: sampleContextData}, done);
        });
        it('pm.data must not exist', function (done) {
            context.execute(`
                var assert = require('assert');

                assert.strictEqual(pm.data, undefined);
            `, {context: sampleContextData}, done);
        });
        it('accesses the current iteration data via pm.iterationData', function (done) {
            context.execute(`
                var assert = require('assert');

                assert.strictEqual(pm.iterationData.get('var1'), 'one-data');
            `, {context: sampleContextData}, done);
        });
        it('pm.iterationData.toObject must return a pojo', function (done) {
            context.execute(`
                var assert = require('assert');

                assert.strictEqual(_.isPlainObject(pm.iterationData.toObject()), true);
                assert.deepEqual(pm.iterationData.toObject(), {
                    var1: 'one-data'
                });
            `, {context: sampleContextData}, done);
        });
    });

    describe('sendRequest', function () {
        it('should be a function exposed', function (done) {
            context.execute(`
                var assert = require('assert');
                assert.strictEqual((typeof pm.sendRequest), 'function');
            `, {context: sampleContextData}, done);
        });

        it('should dispatch an `execution.request.id` event when called', function (done) {
            var executionId = '1';

            context.on('execution.request.' + executionId, function (cursor, id, requestId, req) {
                expect(req.url).to.eql({
                    protocol: 'https',
                    path: ['get'],
                    host: ['postman-echo', 'com'],
                    query: [],
                    variable: []
                });
                done();
            });

            context.execute(`
                pm.sendRequest('https://postman-echo.com/get');
            `, {
                context: sampleContextData,
                id: executionId
            }, function () {}); // eslint-disable-line no-empty-function
        });

        it('should forward response to callback when sent from outside', function (done) {
            var executionId = '2';
            context.on('error', done);

            context.on('execution.error', function (cur, err) {
                expect(err).to.not.be.ok;
                done();
            });

            // @todo find the cause of the error where assertions are not being fired from inside a timer
            context.on('execution.assertion', function (cursor, assertions) {
                assertions.forEach(function (ass) {
                    expect(ass).to.deep.include({
                        passed: true,
                        error: null
                    });
                });
                done();
            });

            context.on('execution.request.' + executionId, function (cursor, id, requestId, req) {
                expect(req.url).to.eql({
                    protocol: 'https',
                    path: ['get'],
                    host: ['postman-echo', 'com'],
                    query: [],
                    variable: []
                });
                context.dispatch(`execution.response.${id}`, requestId, null, {
                    code: 200,
                    body: '{"i am": "a json"}'
                });
            });

            context.execute(`
                pm.sendRequest('https://postman-echo.com/get', function (err, res) {
                    pm.test('response', function () {
                        pm.expect(res).to.have.property('code', 200);
                        pm.expect(res.json()).to.have.property('i am', 'a json');
                    });
                });
            `, {
                context: sampleContextData,
                id: executionId
            }, function () {}); // eslint-disable-line no-empty-function
        });
    });
});
<|endoftext|>