<commit_before>/**
	Slideable is a control that can be dragged either left/right or up/down between a minimum and maximum value.
	When relesed from dragging, a Slideable will animate to it's minimum or maximum position based on the direction dragged.

	The min value may be specified to indicate a position left or top of initial position to which the Slideable may be dragged.
	The max value may be specified to indicate a position right or bottom of initial position to which the Slideable may be dragged.
	The value property may be specified to position the Slideable between its minimum and maximum positions.

	The units may be specified as "px" or "%" and indicate the unit for min, max, and value. The axis property controls if the
	Slideable slides left-right (h) or up-down (v).

	The following control is placed 90% off the screen to the right and slides to its natural position.

		{kind: "onyx.Slideable", value: -90, min: -90, unit: "%", classes: "enyo-fit", style: "width: 300px;", components: [
			{content: "stuff"}
		]}
*/
enyo.kind({
	name: "onyx.Slideable",
	kind: "Control",
	published: {
		//* Specifies direction of sliding h or v
		axis: "h",
		//* A value between min and max to position the Slideable
		value: 0,
		//* Unit for min, max, and value; can be "px" or "%"
		unit: "px",
		//* A minimum value to slide to
		min: 0,
		//* A maximum value to slide to
		max: 0,
		accelerated: "auto",
		//* Set to false to prevent the Slideable from dragging with elasticity past its min/max value.
		overMoving: true,
		//* Set to false to disable dragging.
		draggable: true
	},
	events: {
		//* Event which fires when the Slideable finishes animating.
		onAnimateFinish: ""
	},
	// Set to true to prevent a drag from bubbling beyond the Slideable.
	preventDragPropagation: false,
	//* @protected
	tools: [
		{kind: "Animator", onStep: "animatorStep", onEnd: "animatorComplete"}
	],
	handlers: {
		ondragstart: "dragstart",
		ondrag: "drag",
		ondragfinish: "dragfinish"
	},
	kDragScalar: 1,
	dragEventProp: "dx",
	//* @protected
	create: function() {
		this.inherited(arguments);
		this.acceleratedChanged();
		this.axisChanged();
		this.valueChanged();
		this.addClass("enyo-slideable");
	},
	initComponents: function() {
		this.createComponents(this.tools);
		this.inherited(arguments);
	},
	rendered: function() {
		this.inherited(arguments);
		this.updateDragScalar();
	},
	resizeHandler: function() {
		this.inherited(arguments);
		this.updateDragScalar();
	},
	updateDragScalar: function() {
		if (this.unit == "%") {
			var d = this.getBounds()[this.dimension];
			this.kDragScalar = d ? 100 / d : 1;
		}
	},
	acceleratedChanged: function() {
		enyo.Layout.accelerate(this, this.accelerated);
	},
	axisChanged: function() {
		var h = this.axis == "h";
		this.dragMoveProp = h ? "dx" : "dy";
		this.shouldDragProp = h ? "horizontal" : "vertical";
		this.transform = h ? "translateX" : "translateY";
		this.dimension = h ? "width" : "height";
	},
	valueChanged: function() {
		var v = this.value;
		if (this.isOob(v) && !this.isAnimating()) {
				this.value = this.overMoving ? this.dampValue(v) : this.clampValue(v);
		}
		enyo.Layout.transformValue(this, this.transform, this.value + this.unit);
	},
	getAnimator: function() {
		return this.$.animator;
	},
	isAtMin: function() {
		return this.value <= this.calcMin();
	},
	isAtMax: function() {
		return this.value >= this.calcMax();
	},
	calcMin: function() {
		return this.min;
	},
	calcMax: function() {
		return this.max;
	},
	clampValue: function(inValue) {
		var min = this.calcMin();
		var max = this.calcMax();
		return Math.max(min, Math.min(inValue, max));
	},
	dampValue: function(inValue) {
		return this.dampBound(this.dampBound(inValue, this.min, 1), this.max, -1);
	},
	dampBound: function(inValue, inBoundary, inSign) {
		var v = inValue;
		if (v * inSign < inBoundary * inSign) {
			v = inBoundary + (v - inBoundary) / 4;
		}
		return v;
	},
	// dragging
	shouldDrag: function(inEvent) {
		return this.draggable && inEvent[this.shouldDragProp];
	},
	isOob: function(inValue) {
		return inValue > this.calcMax() || inValue < this.calcMin();
	},
	dragstart: function(inSender, inEvent) {
		if (this.shouldDrag(inEvent)) {
			inEvent.preventNativeDefault();
			this.$.animator.stop();
			inEvent.dragInfo = {};
			this.dragging = true;
			this.drag0 = this.value;
			this.dragd0 = 0;
			return this.preventDragPropagation;
		}
	},
	drag: function(inSender, inEvent) {
		if (this.dragging) {
			inEvent.preventNativeDefault();
			var d = inEvent[this.dragMoveProp] * this.kDragScalar;
			var v = this.drag0 + d;
			var dd = d - this.dragd0;
			this.dragd0 = d;
			if (dd) {
				inEvent.dragInfo.minimizing = dd < 0;
			}
			this.setValue(v);
			return this.preventDragPropagation;
		}
	},
	dragfinish: function(inSender, inEvent) {
		if (this.dragging) {
			this.dragging = false;
			this.completeDrag(inEvent);
			inEvent.preventTap();
			return this.preventDragPropagation;
		}
	},
	completeDrag: function(inEvent) {
		if (this.value !== this.calcMax() && this.value != this.calcMin()) {
			this.animateToMinMax(inEvent.dragInfo.minimizing);
		}
	},
	// animation
	isAnimating: function() {
		return this.$.animator.isAnimating();
	},
	play: function(inStart, inEnd) {
		this.$.animator.play({
			startValue: inStart,
			endValue: inEnd,
			node: this.hasNode()
		});
	},
	//* @public
	//* Animate to the given value.
	animateTo: function(inValue) {
		this.play(this.value, inValue);
	},
	//* Animate to the minimum value
	animateToMin: function() {
		this.animateTo(this.calcMin());
	},
	//* Animate to the maximum value
	animateToMax: function() {
		this.animateTo(this.calcMax());
	},
	//* @protected
	animateToMinMax: function(inMin) {
		if (inMin) {
			this.animateToMin();
		} else {
			this.animateToMax();
		}
	},
	animatorStep: function(inSender) {
		this.setValue(inSender.value);
		return true;
	},
	animatorComplete: function(inSender) {
		this.doAnimateFinish(inSender);
		return true;
	},
	//* @public
	//* Toggle between min and max with animation.
	toggleMinMax: function() {
		this.animateToMinMax(!this.isAtMin());
	}
});<commit_msg>* Slideable: add onChange event.<commit_after>/**
	Slideable is a control that can be dragged either left/right or up/down between a minimum and maximum value.
	When relesed from dragging, a Slideable will animate to it's minimum or maximum position based on the direction dragged.

	The min value may be specified to indicate a position left or top of initial position to which the Slideable may be dragged.
	The max value may be specified to indicate a position right or bottom of initial position to which the Slideable may be dragged.
	The value property may be specified to position the Slideable between its minimum and maximum positions.

	The units may be specified as "px" or "%" and indicate the unit for min, max, and value. The axis property controls if the
	Slideable slides left-right (h) or up-down (v).

	The following control is placed 90% off the screen to the right and slides to its natural position.

		{kind: "onyx.Slideable", value: -90, min: -90, unit: "%", classes: "enyo-fit", style: "width: 300px;", components: [
			{content: "stuff"}
		]}
*/
enyo.kind({
	name: "onyx.Slideable",
	kind: "Control",
	published: {
		//* Specifies direction of sliding h or v
		axis: "h",
		//* A value between min and max to position the Slideable
		value: 0,
		//* Unit for min, max, and value; can be "px" or "%"
		unit: "px",
		//* A minimum value to slide to
		min: 0,
		//* A maximum value to slide to
		max: 0,
		accelerated: "auto",
		//* Set to false to prevent the Slideable from dragging with elasticity past its min/max value.
		overMoving: true,
		//* Set to false to disable dragging.
		draggable: true
	},
	events: {
		//* Event which fires when the Slideable finishes animating.
		onAnimateFinish: "",
		onChange: ""
	},
	// Set to true to prevent a drag from bubbling beyond the Slideable.
	preventDragPropagation: false,
	//* @protected
	tools: [
		{kind: "Animator", onStep: "animatorStep", onEnd: "animatorComplete"}
	],
	handlers: {
		ondragstart: "dragstart",
		ondrag: "drag",
		ondragfinish: "dragfinish"
	},
	kDragScalar: 1,
	dragEventProp: "dx",
	//* @protected
	create: function() {
		this.inherited(arguments);
		this.acceleratedChanged();
		this.axisChanged();
		this.valueChanged();
		this.addClass("enyo-slideable");
	},
	initComponents: function() {
		this.createComponents(this.tools);
		this.inherited(arguments);
	},
	rendered: function() {
		this.inherited(arguments);
		this.updateDragScalar();
	},
	resizeHandler: function() {
		this.inherited(arguments);
		this.updateDragScalar();
	},
	updateDragScalar: function() {
		if (this.unit == "%") {
			var d = this.getBounds()[this.dimension];
			this.kDragScalar = d ? 100 / d : 1;
		}
	},
	acceleratedChanged: function() {
		enyo.Layout.accelerate(this, this.accelerated);
	},
	axisChanged: function() {
		var h = this.axis == "h";
		this.dragMoveProp = h ? "dx" : "dy";
		this.shouldDragProp = h ? "horizontal" : "vertical";
		this.transform = h ? "translateX" : "translateY";
		this.dimension = h ? "width" : "height";
	},
	valueChanged: function() {
		var v = this.value;
		if (this.isOob(v) && !this.isAnimating()) {
				this.value = this.overMoving ? this.dampValue(v) : this.clampValue(v);
		}
		enyo.Layout.transformValue(this, this.transform, this.value + this.unit);
		this.doChange();
	},
	getAnimator: function() {
		return this.$.animator;
	},
	isAtMin: function() {
		return this.value <= this.calcMin();
	},
	isAtMax: function() {
		return this.value >= this.calcMax();
	},
	calcMin: function() {
		return this.min;
	},
	calcMax: function() {
		return this.max;
	},
	clampValue: function(inValue) {
		var min = this.calcMin();
		var max = this.calcMax();
		return Math.max(min, Math.min(inValue, max));
	},
	dampValue: function(inValue) {
		return this.dampBound(this.dampBound(inValue, this.min, 1), this.max, -1);
	},
	dampBound: function(inValue, inBoundary, inSign) {
		var v = inValue;
		if (v * inSign < inBoundary * inSign) {
			v = inBoundary + (v - inBoundary) / 4;
		}
		return v;
	},
	// dragging
	shouldDrag: function(inEvent) {
		return this.draggable && inEvent[this.shouldDragProp];
	},
	isOob: function(inValue) {
		return inValue > this.calcMax() || inValue < this.calcMin();
	},
	dragstart: function(inSender, inEvent) {
		if (this.shouldDrag(inEvent)) {
			inEvent.preventNativeDefault();
			this.$.animator.stop();
			inEvent.dragInfo = {};
			this.dragging = true;
			this.drag0 = this.value;
			this.dragd0 = 0;
			return this.preventDragPropagation;
		}
	},
	drag: function(inSender, inEvent) {
		if (this.dragging) {
			inEvent.preventNativeDefault();
			var d = inEvent[this.dragMoveProp] * this.kDragScalar;
			var v = this.drag0 + d;
			var dd = d - this.dragd0;
			this.dragd0 = d;
			if (dd) {
				inEvent.dragInfo.minimizing = dd < 0;
			}
			this.setValue(v);
			return this.preventDragPropagation;
		}
	},
	dragfinish: function(inSender, inEvent) {
		if (this.dragging) {
			this.dragging = false;
			this.completeDrag(inEvent);
			inEvent.preventTap();
			return this.preventDragPropagation;
		}
	},
	completeDrag: function(inEvent) {
		if (this.value !== this.calcMax() && this.value != this.calcMin()) {
			this.animateToMinMax(inEvent.dragInfo.minimizing);
		}
	},
	// animation
	isAnimating: function() {
		return this.$.animator.isAnimating();
	},
	play: function(inStart, inEnd) {
		this.$.animator.play({
			startValue: inStart,
			endValue: inEnd,
			node: this.hasNode()
		});
	},
	//* @public
	//* Animate to the given value.
	animateTo: function(inValue) {
		this.play(this.value, inValue);
	},
	//* Animate to the minimum value
	animateToMin: function() {
		this.animateTo(this.calcMin());
	},
	//* Animate to the maximum value
	animateToMax: function() {
		this.animateTo(this.calcMax());
	},
	//* @protected
	animateToMinMax: function(inMin) {
		if (inMin) {
			this.animateToMin();
		} else {
			this.animateToMax();
		}
	},
	animatorStep: function(inSender) {
		this.setValue(inSender.value);
		return true;
	},
	animatorComplete: function(inSender) {
		this.doAnimateFinish(inSender);
		return true;
	},
	//* @public
	//* Toggle between min and max with animation.
	toggleMinMax: function() {
		this.animateToMinMax(!this.isAtMin());
	}
});<|endoftext|>


<commit_before>(function(Vizard) {

	var fn = Vizard.prototype
	  ,  $ = Vizard.jQuery;

	fn.controls     = $();
	fn.doctype      = null;
	fn.styleSheets  = null;
	fn.handler      = {};

	fn.entitle = function(title) {
		Vizard.entitle( title, this.document );
	};

	var addRule;
	if ($.browser.msie) {
		addRule = function(selector, rule, index) {
			return this.addRule(selector, rule, index);
		};
	} else {
		addRule = function(selector, rule, index) {
			if (typeof(index) != 'number') index = 0;
			return this.insertRule(selector + ' {' + rule + '}', index);
		};
	}
	fn.addRule = function() { addRule.apply(this.styleSheet, arguments); };

	fn.jQuery = function( selector ) {
		return $( selector, this.document );
	};

	fn.makeSnapshot = function() {
		return this.document.documentElement.innerHTML;
	};

	fn.reset = function() {
		this.snapshot   = this.makeSnapshot();
		this.isModified = false;
	};

	fn.is = function(doctype) {
		if (this.doctype === null) { return false; }
		return this.doctype.publicId.indexOf(doctype) > -1;
	};

	fn.serialize = function() {
		var source;

		if ( this.is('XHTML') ) {
			source = $(this.document).xhtml();
		} else {
			source = $(this.document.documentElement).html();
		}

		return this.outputFilter( source );
	};

	fn.update = function() {
		var snapshot = this.makeSnapshot()
		  , oldLines = difflib.stringAsLines(this.snapshot)
		  , newLines = difflib.stringAsLines(snapshot)
		  , sm       = new difflib.SequenceMatcher(oldLines, newLines)
		  , opcodes  = sm.get_opcodes();

		// not modified only when we have a single opcode ...
		// ... and this opcode says the old and new snapshot are equal
		var modified = (opcodes.length > 1 || opcodes[0][0] != 'equal');

		if (modified) {
			this.controls.garbageCollect().remove();

			this.isModified = true;
			this.snapshot   = snapshot;

			this.display.trigger('change.Vizard');
		}
	};

	// States
	Vizard.INIT        = 'uninitialized';
	Vizard.LOADING     = 'loading';
	Vizard.LOADED      = 'loaded';
	Vizard.INTERACTIVE = 'interactive';
	Vizard.COMPLETE    = 'complete';

	fn.readyState = Vizard.INIT;

	fn.setState = function( state ) {
		this.readyState = state;
		this.display.trigger('onreadystatechange.Vizard', [ state, this ]);
	};

	// ...

	Vizard.fn = fn;

})(Vizard);
<commit_msg>Instead of wrapping, just define the addStyle (previously addRule) method directly on prototype.<commit_after>(function(Vizard) {

	var fn = Vizard.prototype
	  ,  $ = Vizard.jQuery;

	fn.controls     = $();
	fn.doctype      = null;
	fn.styleSheets  = null;
	fn.handler      = {};

	fn.entitle = function(title) {
		Vizard.entitle( title, this.document );
	};

	if ($.browser.msie) {
		fn.addStyle = function(selector, rule, index) {
			return this.styleSheet.addRule(selector, rule, index);
		};
	} else {
		fn.addStyle = function(selector, rule, index) {
			if (typeof(index) != 'number') index = 0;
			return this.styleSheet.insertRule(selector + ' {' + rule + '}', index);
		};
	}

	fn.jQuery = function( selector ) {
		return $( selector, this.document );
	};

	fn.makeSnapshot = function() {
		return this.document.documentElement.innerHTML;
	};

	fn.reset = function() {
		this.snapshot   = this.makeSnapshot();
		this.isModified = false;
	};

	fn.is = function(doctype) {
		if (this.doctype === null) { return false; }
		return this.doctype.publicId.indexOf(doctype) > -1;
	};

	fn.serialize = function() {
		var source;

		if ( this.is('XHTML') ) {
			source = $(this.document).xhtml();
		} else {
			source = $(this.document.documentElement).html();
		}

		return this.outputFilter( source );
	};

	fn.update = function() {
		var snapshot = this.makeSnapshot()
		  , oldLines = difflib.stringAsLines(this.snapshot)
		  , newLines = difflib.stringAsLines(snapshot)
		  , sm       = new difflib.SequenceMatcher(oldLines, newLines)
		  , opcodes  = sm.get_opcodes();

		// not modified only when we have a single opcode ...
		// ... and this opcode says the old and new snapshot are equal
		var modified = (opcodes.length > 1 || opcodes[0][0] != 'equal');

		if (modified) {
			this.controls.garbageCollect().remove();

			this.isModified = true;
			this.snapshot   = snapshot;

			this.display.trigger('change.Vizard');
		}
	};

	// States
	Vizard.INIT        = 'uninitialized';
	Vizard.LOADING     = 'loading';
	Vizard.LOADED      = 'loaded';
	Vizard.INTERACTIVE = 'interactive';
	Vizard.COMPLETE    = 'complete';

	fn.readyState = Vizard.INIT;

	fn.setState = function( state ) {
		this.readyState = state;
		this.display.trigger('onreadystatechange.Vizard', [ state, this ]);
	};

	// ...

	Vizard.fn = fn;

})(Vizard);
<|endoftext|>


<commit_before>/**
 * Vector variable to contain all vector operations and definitions
 */
define({
  /**
   * The representation of a vector is a basic Javascript array
   */
  Interface : [],

  /**
   * Copies the the vector into a new sparse array
   *
   * @param vector
   *          {Array} source
   * @returns {Array} copy
   */
  copy : function (vector) {
    var ret, size, i;

    ret = [];
    size = vector.length;

    for (i = 0; i < size; i += 1) {
      if (vector[i]) {
        ret[i] = vector[i];
      }
    }

    return ret;
  },
  /**
   * dot product of two vectors
   *
   * @param a
   *          {Array} first operand
   * @param b
   *          {Array} second operand
   * @param size
   *          {Integer} supposed size of the vectors (optional, defaults to
   *          max(a.length, b.length))
   * @returns {Number}
   */
  dot : function (a, b, size) {
    var retval, i;

    size = size || Math.max(a.length, b.length);
    retval = 0;

    for (i = 0; i < size; i += 1) {
      retval += (a[i] || 0) * (b[i] || 0);
    }
    return retval;
  },

  /**
   * Fills undefined elements of the vector with 0
   *
   * @param vector
   *          {Array} input and output vector
   * @returns {Array} reference to the vector
   */
  fill : function (vector) {
    var size, i;

    size = vector.length;

    for (i = 0; i < size; i += 1) {
      vector[i] = vector[i] || 0;
    }

    return vector;
  },
  /**
   * scales the vector by the factor
   *
   * @param vector
   *          {Array} vector
   * @param factor
   *          {Number} factor
   * @returns {Array} reference to vector
   */
  scale : function (vector, factor) {
    var size, i;

    size = vector.length;

    for (i = 0; i < size; i += 1) {
      if (vector[i]) {
        vector[i] *= factor;
      }
    }

    return vector;
  },

  /**
   * Sum calculates the sum of all elements of the vector
   *
   * @param vector
   *          {Array} input vector
   * @returns {Number} the vector sum
   */
  sum : function (vector) {
    var sum, size, i;

    sum = 0;
    size = vector.length;

    for (i = 0; i < size; i += 1) {
      sum += vector[i] || 0;
    }

    return sum;
  }

});
<commit_msg>vector: Interface removed<commit_after>/**
 * Vector variable to contain all vector operations and definitions where a
 * vector is represented as a javascript array
 */
define({
  /**
   * Copies the the vector into a new sparse array
   *
   * @param vector
   *          {Array} source
   * @returns {Array} copy
   */
  copy : function (vector) {
    var ret, size, i;

    ret = [];
    size = vector.length;

    for (i = 0; i < size; i += 1) {
      if (vector[i]) {
        ret[i] = vector[i];
      }
    }

    return ret;
  },

  /**
   * dot product of two vectors
   *
   * @param a
   *          {Array} first operand
   * @param b
   *          {Array} second operand
   * @param size
   *          {Integer} supposed size of the vectors (optional, defaults to
   *          max(a.length, b.length))
   * @returns {Number}
   */
  dot : function (a, b, size) {
    var retval, i;

    size = size || Math.max(a.length, b.length);
    retval = 0;

    for (i = 0; i < size; i += 1) {
      retval += (a[i] || 0) * (b[i] || 0);
    }
    return retval;
  },

  /**
   * Fills undefined elements of the vector with 0
   *
   * @param vector
   *          {Array} input and output vector
   * @returns {Array} reference to the vector
   */
  fill : function (vector) {
    var size, i;

    size = vector.length;

    for (i = 0; i < size; i += 1) {
      vector[i] = vector[i] || 0;
    }

    return vector;
  },
  /**
   * scales the vector by the factor
   *
   * @param vector
   *          {Array} vector
   * @param factor
   *          {Number} factor
   * @returns {Array} reference to vector
   */
  scale : function (vector, factor) {
    var size, i;

    size = vector.length;

    for (i = 0; i < size; i += 1) {
      if (vector[i]) {
        vector[i] *= factor;
      }
    }

    return vector;
  },

  /**
   * Sum calculates the sum of all elements of the vector
   *
   * @param vector
   *          {Array} input vector
   * @returns {Number} the vector sum
   */
  sum : function (vector) {
    var sum, size, i;

    sum = 0;
    size = vector.length;

    for (i = 0; i < size; i += 1) {
      sum += vector[i] || 0;
    }

    return sum;
  }

});
<|endoftext|>


<commit_before>'use strict';
const net = require('net');
const {TimeoutError} = require('./errors');

const reentry = Symbol('reentry');

function addTimeout(delay, callback, ...args) {
	// Event loop order is timers, poll, immediates.
	// The timed event may emit during the current tick poll phase, so
	// defer calling the handler until the poll phase completes.
	let immediate;
	const timeout = setTimeout(
		() => {
			immediate = setImmediate(callback, delay, ...args);
			/* istanbul ignore next: added in node v9.7.0 */
			if (immediate.unref) {
				immediate.unref();
			}
		},
		delay
	);
	timeout.unref();
	return () => {
		clearTimeout(timeout);
		clearImmediate(immediate);
	};
}

module.exports = (request, options) => {
	/* istanbul ignore next: this makes sure timed-out isn't called twice */
	if (request[reentry]) {
		return;
	}

	request[reentry] = true;
	const {gotTimeout: delays, host, hostname} = options;
	const timeoutHandler = (delay, event) => {
		request.abort();
		request.emit('error', new TimeoutError(delay, event, options));
	};

	const cancelers = [];
	const cancelTimeouts = () => {
		cancelers.forEach(cancelTimeout => cancelTimeout());
	};

	request.on('error', cancelTimeouts);
	request.once('response', response => {
		response.once('end', cancelTimeouts);
	});

	if (delays.request !== undefined) {
		const cancelTimeout = addTimeout(
			delays.request,
			timeoutHandler,
			'request'
		);
		cancelers.push(cancelTimeout);
	}

	if (delays.socket !== undefined) {
		request.setTimeout(
			delays.socket,
			() => {
				timeoutHandler(delays.socket, 'socket');
			}
		);
	}

	if (delays.lookup !== undefined && !request.socketPath && !net.isIP(hostname || host)) {
		request.once('socket', socket => {
			/* istanbul ignore next: hard to test */
			if (socket.connecting) {
				const cancelTimeout = addTimeout(
					delays.lookup,
					timeoutHandler,
					'lookup'
				);
				cancelers.push(cancelTimeout);
				socket.once('lookup', cancelTimeout);
			}
		});
	}

	if (delays.connect !== undefined) {
		request.once('socket', socket => {
			/* istanbul ignore next: hard to test */
			if (socket.connecting) {
				const timeConnect = () => {
					const cancelTimeout = addTimeout(
						delays.connect,
						timeoutHandler,
						'connect'
					);
					cancelers.push(cancelTimeout);
					return cancelTimeout;
				};

				if (request.socketPath || net.isIP(hostname || host)) {
					socket.once('connect', timeConnect());
				} else {
					socket.once('lookup', () => {
						socket.once('connect', timeConnect());
					});
				}
			}
		});
	}

	if (delays.secureConnect !== undefined && options.protocol === 'https:') {
		request.once('socket', socket => {
			/* istanbul ignore next: hard to test */
			if (socket.connecting) {
				socket.once('connect', () => {
					const cancelTimeout = addTimeout(
						delays.secureConnect,
						timeoutHandler,
						'secureConnect'
					);
					cancelers.push(cancelTimeout);
					socket.once('secureConnect', cancelTimeout);
				});
			}
		});
	}

	if (delays.send !== undefined) {
		request.once('socket', socket => {
			const timeRequest = () => {
				const cancelTimeout = addTimeout(
					delays.send,
					timeoutHandler,
					'send'
				);
				cancelers.push(cancelTimeout);
				return cancelTimeout;
			};
			/* istanbul ignore next: hard to test */
			if (socket.connecting) {
				socket.once('connect', () => {
					request.once('upload-complete', timeRequest());
				});
			} else {
				request.once('upload-complete', timeRequest());
			}
		});
	}

	if (delays.response !== undefined) {
		request.once('upload-complete', () => {
			const cancelTimeout = addTimeout(
				delays.response,
				timeoutHandler,
				'response'
			);
			cancelers.push(cancelTimeout);
			request.once('response', cancelTimeout);
		});
	}
};
<commit_msg>Support electron renderer timings<commit_after>'use strict';
const net = require('net');
const {TimeoutError} = require('./errors');

const reentry = Symbol('reentry');

function addTimeout(delay, callback, ...args) {
	// Event loop order is timers, poll, immediates.
	// The timed event may emit during the current tick poll phase, so
	// defer calling the handler until the poll phase completes.
	let immediate;
	const timeout = setTimeout(
		() => {
			immediate = setImmediate(callback, delay, ...args);
			/* istanbul ignore next: added in node v9.7.0 */
			if (immediate.unref) {
				immediate.unref();
			}
		},
		delay
	);
	/* istanbul ignore next: in order to support electron renderer */
	if (timeout.unref) {
		timeout.unref();
	}

	return () => {
		clearTimeout(timeout);
		clearImmediate(immediate);
	};
}

module.exports = (request, options) => {
	/* istanbul ignore next: this makes sure timed-out isn't called twice */
	if (request[reentry]) {
		return;
	}

	request[reentry] = true;
	const {gotTimeout: delays, host, hostname} = options;
	const timeoutHandler = (delay, event) => {
		request.abort();
		request.emit('error', new TimeoutError(delay, event, options));
	};

	const cancelers = [];
	const cancelTimeouts = () => {
		cancelers.forEach(cancelTimeout => cancelTimeout());
	};

	request.on('error', cancelTimeouts);
	request.once('response', response => {
		response.once('end', cancelTimeouts);
	});

	if (delays.request !== undefined) {
		const cancelTimeout = addTimeout(
			delays.request,
			timeoutHandler,
			'request'
		);
		cancelers.push(cancelTimeout);
	}

	if (delays.socket !== undefined) {
		request.setTimeout(
			delays.socket,
			() => {
				timeoutHandler(delays.socket, 'socket');
			}
		);
	}

	if (delays.lookup !== undefined && !request.socketPath && !net.isIP(hostname || host)) {
		request.once('socket', socket => {
			/* istanbul ignore next: hard to test */
			if (socket.connecting) {
				const cancelTimeout = addTimeout(
					delays.lookup,
					timeoutHandler,
					'lookup'
				);
				cancelers.push(cancelTimeout);
				socket.once('lookup', cancelTimeout);
			}
		});
	}

	if (delays.connect !== undefined) {
		request.once('socket', socket => {
			/* istanbul ignore next: hard to test */
			if (socket.connecting) {
				const timeConnect = () => {
					const cancelTimeout = addTimeout(
						delays.connect,
						timeoutHandler,
						'connect'
					);
					cancelers.push(cancelTimeout);
					return cancelTimeout;
				};

				if (request.socketPath || net.isIP(hostname || host)) {
					socket.once('connect', timeConnect());
				} else {
					socket.once('lookup', () => {
						socket.once('connect', timeConnect());
					});
				}
			}
		});
	}

	if (delays.secureConnect !== undefined && options.protocol === 'https:') {
		request.once('socket', socket => {
			/* istanbul ignore next: hard to test */
			if (socket.connecting) {
				socket.once('connect', () => {
					const cancelTimeout = addTimeout(
						delays.secureConnect,
						timeoutHandler,
						'secureConnect'
					);
					cancelers.push(cancelTimeout);
					socket.once('secureConnect', cancelTimeout);
				});
			}
		});
	}

	if (delays.send !== undefined) {
		request.once('socket', socket => {
			const timeRequest = () => {
				const cancelTimeout = addTimeout(
					delays.send,
					timeoutHandler,
					'send'
				);
				cancelers.push(cancelTimeout);
				return cancelTimeout;
			};
			/* istanbul ignore next: hard to test */
			if (socket.connecting) {
				socket.once('connect', () => {
					request.once('upload-complete', timeRequest());
				});
			} else {
				request.once('upload-complete', timeRequest());
			}
		});
	}

	if (delays.response !== undefined) {
		request.once('upload-complete', () => {
			const cancelTimeout = addTimeout(
				delays.response,
				timeoutHandler,
				'response'
			);
			cancelers.push(cancelTimeout);
			request.once('response', cancelTimeout);
		});
	}
};
<|endoftext|>


<commit_before>;(function() {
  'use strict';

  describe('Klass', function() {
    it('exists as a function', function() {
      expect(window.Klass).toEqual(jasmine.any(Function));
    });

    // should throw an error
    // it('throws?', function() {
    //   expect(window.Klass('stringgg')).toEqual(jasmine.any(Function));
    // });

    it('returns a constructor', function() {
      expect(window.Klass()).toEqual(jasmine.any(Function));
    });

    it('the returned constructor when called with an EMPTY object, "{}" returns an EMPTY object', function() {
      var ReturnedConstructor = window.Klass();
      expect(new ReturnedConstructor()).toEqual({});
    });

    it('the returned constructor when called with an NON-EMPTY object returns an object with the same properties', function() {
      var ReturnedConstructor,
          klassParams = {
            testInstanceVariable: 'hello',
            testInstanceMethod: function() {
              return 'I am an instance method';
            }
          };
      ReturnedConstructor = window.Klass(klassParams);
      expect(new ReturnedConstructor()).toEqual(klassParams);
    });

    describe('the returned constructor', function() {
      var ReturnedConstructor;
      beforeEach(function() {
        ReturnedConstructor = window.Klass();
      });
      it('throws the: "Invalid call to class function, please use the `new Class` to instantiate an object" error when not called with new', function() {
        expect(function() { ReturnedConstructor(); }).toThrow("Invalid call to class function, please use the `new Class` to instantiate an object");
      });

      describe('.extends', function() {
        it('exists as a function', function() {
          var ReturnedConstructor = window.Klass();
          expect(ReturnedConstructor.extends).toEqual(jasmine.any(Function));
        });

        it('accepts an object as a parameter and copies the objects properties into the object that will be created by invoking the constructor', function() {
          var props = {
            foo: 'foo',
            bar: 'bar',
            testFunc: function() {
              return 'baz';
            }
          };
          ReturnedConstructor.extends(props);
          expect(new ReturnedConstructor()).toEqual(props);
        });

        it('throws the error, "ArgumentTypeError in .extends: expected object, got null" when null is received as the parameter', function() {
          expect(function() { ReturnedConstructor.extends(null); }).toThrow('ArgumentTypeError in .extends: expected object, got null');
        });

        it('throws the error, "ArgumentTypeError in .extends: expected object, got string" when a string is received as the parameter', function() {
          expect(function() { ReturnedConstructor.extends('some string') }).toThrow('ArgumentTypeError in .extends: expected object, got string');
        });

        it('throws the error, "ArgumentTypeError in .extends: expected object, got number" when a number is received as the parameter', function() {
          expect(function() { ReturnedConstructor.extends(3) }).toThrow('ArgumentTypeError in .extends: expected object, got number');
        });

        it('throws the error, "ArgumentTypeError in .extends: expected object, got boolean" when a boolean is received as the parameter', function() {
          expect(function() { ReturnedConstructor.extends(true) }).toThrow('ArgumentTypeError in .extends: expected object, got boolean');
          expect(function() { ReturnedConstructor.extends(false) }).toThrow('ArgumentTypeError in .extends: expected object, got boolean');
        });
      });

      describe('.implements', function() {
        it('exists as a function', function() {
          expect(ReturnedConstructor.implements).toEqual(jasmine.any(Function));
        });

        it('accepts an array of method names (strings) as a parameter and checks that the methods are implemented', function() {
          var methodInKlass = function() {
            var Class = window.Klass({ testMethod: function() {} }).implements(['testMethod']);
            new Class();
          };
          var methodInExtends = function() {
            var Class = window.Klass().extends({ testMethod: function() {} }).implements(['testMethod']);
            new Class();
          };

          expect(methodInKlass).not.toThrow();
          expect(methodInExtends).not.toThrow();
        });

        it('throws the error, "ArgumentTypeError in .implements: expected array, got null" when null is received as the parameter', function() {
          expect(function() { ReturnedConstructor.implements(null); }).toThrow('ArgumentTypeError in .implements: expected array, got null');
        });

        it('throws the error, "ArgumentTypeError in .implements: expected array, got string" when string is received as the parameter', function() {
          expect(function() { ReturnedConstructor.implements('some string'); }).toThrow('ArgumentTypeError in .implements: expected array, got string');
        });

        it('throws the error, "ArgumentTypeError in .implements: expected array, got number" when number is received as the parameter', function() {
          expect(function() { ReturnedConstructor.implements(3); }).toThrow('ArgumentTypeError in .implements: expected array, got number');
        });

        it('throws the error, "ArgumentTypeError in .implements: expected array, got boolean" when boolean is received as the parameter', function() {
          expect(function() { ReturnedConstructor.implements(true); }).toThrow('ArgumentTypeError in .implements: expected array, got boolean');
          expect(function() { ReturnedConstructor.implements(false); }).toThrow('ArgumentTypeError in .implements: expected array, got boolean');
        });

        it('throws the error, "ArgumentTypeError in .implements: expected array, got boolean" when boolean is received as the parameter', function() {
          expect(function() { ReturnedConstructor.implements({}); }).toThrow('ArgumentTypeError in .implements: expected array, got object');
        });
      });
    });
  });
})();

// "use strict";

// describe('The `extends` method on the constructor function returned from invoking the Klass function', function() {
//   var FooClass;
//   beforeEach(function() {
//     FooClass = Klass();
//   });

//   it('exists (as a function)', function() {
//     expect(typeof FooClass.extends).toBe('function');
//   });

//   it('throws an ArgumenTypeError when it is invoked with undefined: `ArgumentTypeError in .extends: expected object, got undefined`', function() {
//     expect(function() { FooClass.extends(); }).toThrow('ArgumentTypeError in .extends: expected object, got undefined');
//     expect(function() { FooClass.extends(undefined); }).toThrow('ArgumentTypeError in .extends: expected object, got undefined');
//   });

//   it('throws an ArgumenTypeError when it is invoked with null: `ArgumentTypeError in .extends: expected object, got null`', function() {
//     expect(function() { FooClass.extends(null); }).toThrow('ArgumentTypeError in .extends: expected object, got null');
//   });

//   it('throws an ArgumenTypeError when it is invoked with a function: `ArgumentTypeError in .extends: expected object, got function`', function() {
//     expect(function() { FooClass.extends(function() {}); }).toThrow('ArgumentTypeError in .extends: expected object, got function');
//   });

//   it('takes an object as its parameter and makes it available through prototypal inheritance', function() {
//     var objToExtend = {
//       foo: 'bar',
//       lorem: function() {
//         return 'ipsum';
//       }
//     };
//     FooClass.extends(objToExtend);

//     expect(FooClass.prototype.lorem).toBe(objToExtend.lorem);
//     expect(FooClass.prototype.foo).toBe(objToExtend.foo);
//   });

//   it('returns the same constructor that it is called on (allowing it to be chainable)', function() {
//     expect(FooClass).toBe(FooClass.extends({ foo: 'bar' }));
//   });
// });

// "use strict";

// describe('The `implements` method on the constructor function returned from invoking the Klass function', function() {
//   var FooClass;
//   beforeEach(function() {
//     FooClass = Klass({
//       initialInstanceMethod: function() {}
//     }).extends({
//       parentMethod: function() {}
//     });
//   });

//   it('exists (as a function)', function() {
//     expect(typeof FooClass.implements).toBe('function');
//   });

//   describe('`implements` method\'s ArgumentTypeErrors', function() {
//     it('throws an ArgumenTypeError when passed with undefined: `ArgumentTypeError in .implements: expected array, got undefined`', function() {
//       expect(function() { FooClass.implements(); }).toThrow('ArgumentTypeError in .implements: expected array, got undefined');
//       expect(function() { FooClass.implements(undefined); }).toThrow('ArgumentTypeError in .implements: expected array, got undefined');
//     });

//     it('throws an ArgumenTypeError when passed with null: `ArgumentTypeError in .implements: expected array, got null`', function() {
//       expect(function() { FooClass.implements(null); }).toThrow('ArgumentTypeError in .implements: expected array, got null');
//     });

//     it('throws an ArgumenTypeError when passed with an object: `ArgumentTypeError in .implements: expected array, got object`', function() {
//       expect(function() { FooClass.implements({}); }).toThrow('ArgumentTypeError in .implements: expected array, got object');
//       expect(function() { FooClass.implements(new Object()); }).toThrow('ArgumentTypeError in .implements: expected array, got object');
//     });

//     it('throws an ArgumenTypeError when passed with a function: `ArgumentTypeError in .implements: expected array, got function`', function() {
//       expect(function() { FooClass.implements(function() {}); }).toThrow('ArgumentTypeError in .implements: expected array, got function');
//     });

//     it('throws an ArgumenTypeError when it is _not_ passed a string of functions: `ArgumentTypeError in .implements: expected an array of strings`', function() {
//       expect(function() { FooClass.implements([function() {}]); }).toThrow('ArgumentTypeError in .implements: expected an array of strings');
//       expect(function() { FooClass.implements([{}]); }).toThrow('ArgumentTypeError in .implements: expected an array of strings');
//       expect(function() { FooClass.implements([1]); }).toThrow('ArgumentTypeError in .implements: expected an array of strings');
//       expect(function() { FooClass.implements([1]); }).toThrow('ArgumentTypeError in .implements: expected an array of strings');
//     });
//   });

//   describe('`implement` method\'s ImplementsErrors', function() {
//     it('throws an ImplementsError when testing for the implementation of an _instance_ method or an _extended_ method: ', function() {
//       expect(function() {
//         FooClass.implements(['testMethod']);
//       }).toThrow('ImplementsError: Klass does not implement testMethod');
//     });
//   });

//   it('takes an array of strings that represent method names and attempt to call the methods', function() {
//     FooClass.implements(['initialInstanceMethod', 'parentMethod']);
//     var foo = new FooClass();

//     spyOn(foo,'initialInstanceMethod');
//     foo.initialInstanceMethod();

//     spyOn(foo, 'parentMethod');
//     foo.parentMethod();

//     expect(foo.initialInstanceMethod).toHaveBeenCalled();
//     expect(foo.parentMethod).toHaveBeenCalled();
//   });

//   it('returns the same constructor that it is called on (allowing it to be chainable)', function() {
//     expect(FooClass).toBe(FooClass.implements(['parentMethod']));
//   });
// });<commit_msg>added test cases for the undefined type<commit_after>;(function() {
  'use strict';

  describe('Klass', function() {
    it('exists as a function', function() {
      expect(window.Klass).toEqual(jasmine.any(Function));
    });

    // should throw an error
    // it('throws?', function() {
    //   expect(window.Klass('stringgg')).toEqual(jasmine.any(Function));
    // });

    it('returns a constructor', function() {
      expect(window.Klass()).toEqual(jasmine.any(Function));
    });

    it('the returned constructor when called with an EMPTY object, "{}" returns an EMPTY object', function() {
      var ReturnedConstructor = window.Klass();
      expect(new ReturnedConstructor()).toEqual({});
    });

    it('the returned constructor when called with an NON-EMPTY object returns an object with the same properties', function() {
      var ReturnedConstructor,
          klassParams = {
            testInstanceVariable: 'hello',
            testInstanceMethod: function() {
              return 'I am an instance method';
            }
          };
      ReturnedConstructor = window.Klass(klassParams);
      expect(new ReturnedConstructor()).toEqual(klassParams);
    });

    describe('the returned constructor', function() {
      var ReturnedConstructor;
      beforeEach(function() {
        ReturnedConstructor = window.Klass();
      });
      it('throws the: "Invalid call to class function, please use the `new Class` to instantiate an object" error when not called with new', function() {
        expect(function() { ReturnedConstructor(); }).toThrow("Invalid call to class function, please use the `new Class` to instantiate an object");
      });

      describe('.extends', function() {
        it('exists as a function', function() {
          var ReturnedConstructor = window.Klass();
          expect(ReturnedConstructor.extends).toEqual(jasmine.any(Function));
        });

        it('accepts an object as a parameter and copies the objects properties into the object that will be created by invoking the constructor', function() {
          var props = {
            foo: 'foo',
            bar: 'bar',
            testFunc: function() {
              return 'baz';
            }
          };
          ReturnedConstructor.extends(props);
          expect(new ReturnedConstructor()).toEqual(props);
        });

        it('throws the error, "ArgumentTypeError in .extends: expected object, got undefined" when undefined is received as the parameter', function() {
          expect(function() { ReturnedConstructor.extends(undefined); }).toThrow('ArgumentTypeError in .extends: expected object, got undefined');
        });

        it('throws the error, "ArgumentTypeError in .extends: expected object, got null" when null is received as the parameter', function() {
          expect(function() { ReturnedConstructor.extends(null); }).toThrow('ArgumentTypeError in .extends: expected object, got null');
        });

        it('throws the error, "ArgumentTypeError in .extends: expected object, got string" when a string is received as the parameter', function() {
          expect(function() { ReturnedConstructor.extends('some string') }).toThrow('ArgumentTypeError in .extends: expected object, got string');
        });

        it('throws the error, "ArgumentTypeError in .extends: expected object, got number" when a number is received as the parameter', function() {
          expect(function() { ReturnedConstructor.extends(3) }).toThrow('ArgumentTypeError in .extends: expected object, got number');
        });

        it('throws the error, "ArgumentTypeError in .extends: expected object, got boolean" when a boolean is received as the parameter', function() {
          expect(function() { ReturnedConstructor.extends(true) }).toThrow('ArgumentTypeError in .extends: expected object, got boolean');
          expect(function() { ReturnedConstructor.extends(false) }).toThrow('ArgumentTypeError in .extends: expected object, got boolean');
        });
      });

      describe('.implements', function() {
        it('exists as a function', function() {
          expect(ReturnedConstructor.implements).toEqual(jasmine.any(Function));
        });

        it('accepts an array of method names (strings) as a parameter and checks that the methods are implemented', function() {
          var methodInKlass = function() {
            var Class = window.Klass({ testMethod: function() {} }).implements(['testMethod']);
            new Class();
          };
          var methodInExtends = function() {
            var Class = window.Klass().extends({ testMethod: function() {} }).implements(['testMethod']);
            new Class();
          };

          expect(methodInKlass).not.toThrow();
          expect(methodInExtends).not.toThrow();
        });

        it('throws the error, "ArgumentTypeError in .implements: expected array, got undefined" when undefined is received as the parameter', function() {
          expect(function() { ReturnedConstructor.implements(undefined); }).toThrow('ArgumentTypeError in .implements: expected array, got undefined');
        });

        it('throws the error, "ArgumentTypeError in .implements: expected array, got null" when null is received as the parameter', function() {
          expect(function() { ReturnedConstructor.implements(null); }).toThrow('ArgumentTypeError in .implements: expected array, got null');
        });

        it('throws the error, "ArgumentTypeError in .implements: expected array, got string" when string is received as the parameter', function() {
          expect(function() { ReturnedConstructor.implements('some string'); }).toThrow('ArgumentTypeError in .implements: expected array, got string');
        });

        it('throws the error, "ArgumentTypeError in .implements: expected array, got number" when number is received as the parameter', function() {
          expect(function() { ReturnedConstructor.implements(3); }).toThrow('ArgumentTypeError in .implements: expected array, got number');
        });

        it('throws the error, "ArgumentTypeError in .implements: expected array, got boolean" when boolean is received as the parameter', function() {
          expect(function() { ReturnedConstructor.implements(true); }).toThrow('ArgumentTypeError in .implements: expected array, got boolean');
          expect(function() { ReturnedConstructor.implements(false); }).toThrow('ArgumentTypeError in .implements: expected array, got boolean');
        });

        it('throws the error, "ArgumentTypeError in .implements: expected array, got boolean" when boolean is received as the parameter', function() {
          expect(function() { ReturnedConstructor.implements({}); }).toThrow('ArgumentTypeError in .implements: expected array, got object');
        });
      });
    });
  });
})();

// "use strict";

// describe('The `extends` method on the constructor function returned from invoking the Klass function', function() {
//   var FooClass;
//   beforeEach(function() {
//     FooClass = Klass();
//   });

//   it('exists (as a function)', function() {
//     expect(typeof FooClass.extends).toBe('function');
//   });

//   it('throws an ArgumenTypeError when it is invoked with undefined: `ArgumentTypeError in .extends: expected object, got undefined`', function() {
//     expect(function() { FooClass.extends(); }).toThrow('ArgumentTypeError in .extends: expected object, got undefined');
//     expect(function() { FooClass.extends(undefined); }).toThrow('ArgumentTypeError in .extends: expected object, got undefined');
//   });

//   it('throws an ArgumenTypeError when it is invoked with null: `ArgumentTypeError in .extends: expected object, got null`', function() {
//     expect(function() { FooClass.extends(null); }).toThrow('ArgumentTypeError in .extends: expected object, got null');
//   });

//   it('throws an ArgumenTypeError when it is invoked with a function: `ArgumentTypeError in .extends: expected object, got function`', function() {
//     expect(function() { FooClass.extends(function() {}); }).toThrow('ArgumentTypeError in .extends: expected object, got function');
//   });

//   it('takes an object as its parameter and makes it available through prototypal inheritance', function() {
//     var objToExtend = {
//       foo: 'bar',
//       lorem: function() {
//         return 'ipsum';
//       }
//     };
//     FooClass.extends(objToExtend);

//     expect(FooClass.prototype.lorem).toBe(objToExtend.lorem);
//     expect(FooClass.prototype.foo).toBe(objToExtend.foo);
//   });

//   it('returns the same constructor that it is called on (allowing it to be chainable)', function() {
//     expect(FooClass).toBe(FooClass.extends({ foo: 'bar' }));
//   });
// });

// "use strict";

// describe('The `implements` method on the constructor function returned from invoking the Klass function', function() {
//   var FooClass;
//   beforeEach(function() {
//     FooClass = Klass({
//       initialInstanceMethod: function() {}
//     }).extends({
//       parentMethod: function() {}
//     });
//   });

//   it('exists (as a function)', function() {
//     expect(typeof FooClass.implements).toBe('function');
//   });

//   describe('`implements` method\'s ArgumentTypeErrors', function() {
//     it('throws an ArgumenTypeError when passed with undefined: `ArgumentTypeError in .implements: expected array, got undefined`', function() {
//       expect(function() { FooClass.implements(); }).toThrow('ArgumentTypeError in .implements: expected array, got undefined');
//       expect(function() { FooClass.implements(undefined); }).toThrow('ArgumentTypeError in .implements: expected array, got undefined');
//     });

//     it('throws an ArgumenTypeError when passed with null: `ArgumentTypeError in .implements: expected array, got null`', function() {
//       expect(function() { FooClass.implements(null); }).toThrow('ArgumentTypeError in .implements: expected array, got null');
//     });

//     it('throws an ArgumenTypeError when passed with an object: `ArgumentTypeError in .implements: expected array, got object`', function() {
//       expect(function() { FooClass.implements({}); }).toThrow('ArgumentTypeError in .implements: expected array, got object');
//       expect(function() { FooClass.implements(new Object()); }).toThrow('ArgumentTypeError in .implements: expected array, got object');
//     });

//     it('throws an ArgumenTypeError when passed with a function: `ArgumentTypeError in .implements: expected array, got function`', function() {
//       expect(function() { FooClass.implements(function() {}); }).toThrow('ArgumentTypeError in .implements: expected array, got function');
//     });

//     it('throws an ArgumenTypeError when it is _not_ passed a string of functions: `ArgumentTypeError in .implements: expected an array of strings`', function() {
//       expect(function() { FooClass.implements([function() {}]); }).toThrow('ArgumentTypeError in .implements: expected an array of strings');
//       expect(function() { FooClass.implements([{}]); }).toThrow('ArgumentTypeError in .implements: expected an array of strings');
//       expect(function() { FooClass.implements([1]); }).toThrow('ArgumentTypeError in .implements: expected an array of strings');
//       expect(function() { FooClass.implements([1]); }).toThrow('ArgumentTypeError in .implements: expected an array of strings');
//     });
//   });

//   describe('`implement` method\'s ImplementsErrors', function() {
//     it('throws an ImplementsError when testing for the implementation of an _instance_ method or an _extended_ method: ', function() {
//       expect(function() {
//         FooClass.implements(['testMethod']);
//       }).toThrow('ImplementsError: Klass does not implement testMethod');
//     });
//   });

//   it('takes an array of strings that represent method names and attempt to call the methods', function() {
//     FooClass.implements(['initialInstanceMethod', 'parentMethod']);
//     var foo = new FooClass();

//     spyOn(foo,'initialInstanceMethod');
//     foo.initialInstanceMethod();

//     spyOn(foo, 'parentMethod');
//     foo.parentMethod();

//     expect(foo.initialInstanceMethod).toHaveBeenCalled();
//     expect(foo.parentMethod).toHaveBeenCalled();
//   });

//   it('returns the same constructor that it is called on (allowing it to be chainable)', function() {
//     expect(FooClass).toBe(FooClass.implements(['parentMethod']));
//   });
// });<|endoftext|>


<commit_before>describe("m.postgrest.loader", function(){
  var vm = null;

  beforeEach(function(){
    var then = function(callback){
      callback([]);
    };
    spyOn(m, 'request').and.callFake(function(options){
      expect(vm()).toEqual(true);
      return {then: then};
    });
    vm = m.postgrest.loader(false, m.request, {});
  });

  it("should create vm as a getter/setter", function() {
    expect(vm()).toEqual(false);
    vm(true);
    expect(vm()).toEqual(true);
  });

  it("should update loader state to true before resolving request", function() {
    vm(false);
    vm.load();
    expect(vm()).toEqual(false);
  });

});
<commit_msg>fixes spec<commit_after>describe("m.postgrest.loader", function(){
  var vm = null;

  beforeEach(function(){
    var then = function(callback){
      callback([]);
    };
    spyOn(m, 'request').and.callFake(function(options){
      expect(vm()).toEqual(true);
      return {then: then};
    });
    vm = m.postgrest.loader({}, m.request);
  });

  it("should create vm as a getter/setter", function() {
    expect(vm()).toEqual(false);
    vm(true);
    expect(vm()).toEqual(true);
  });

  it("should update loader state to true before resolving request", function() {
    vm(false);
    vm.load();
    expect(vm()).toEqual(false);
  });

});
<|endoftext|>


<commit_before> var request = require('request');
 require('../testserver.js').startserver();
 describe('Localr API', function() {
     describe('test local connection', function() {
         it('make connection to server', function(done) {
             var url = 'http://localhost:8080/users/test';
             // getting params
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test')
                 }
             };
             request.get(params, function(error, response, body) {
                 expect(response.statusCode).toBe(200);
                 expect(body).toBe('"works"');
                 console.log(body)
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
             console.log("connection works")
         })
     })
     describe('Users', function() {
         describe('create the user', function() {
             it("be able to create a user", function(done) {
                 var url = 'http://localhost:8080/users';
                 var params = {
                     uri: url,
                     headers: {
                         authorization: getBasic('testuser', 'test')
                     }
                 };
                 request.post(params, function(error, response, body) {
                     expect(response.statusCode).toBe(201);
                     body = JSON.parse(body);
                     expect(body.Username).toBe('testuser');
                     expect(body.url).toBe('api.adam-holt.co.uk/users/testuser');
                     if(error) {
                         expect(error.code).not.toBe('ECONNREFUSED');
                     }
                     done();
                 })
             })
             it("be not able to create duplicate user", function(done) {
                 var url = 'http://localhost:8080/users';
                 // getting params
                 var params = {
                     uri: url,
                     headers: {
                         authorization: getBasic('testuser', 'test')
                     }
                 };
                 request.post(params, function(error, response, body) {
                     expect(response.statusCode).toBe(409);
                     if(error) {
                         expect(error.code).not.toBe('ECONNREFUSED');
                     }
                     done();
                 })
             })
         })
     })
     describe('checkin', function() {
         it("be able to checkin", function(done) {
             var url = 'http://localhost:8080/users/checkin?username=testuser&points=10';
             var doc = {
                 username: "testuser",
                 points: 10
             };
             // getting params
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test')
                 },
                 body: JSON.stringify(doc)
             };
             request.put(params, function(error, response, body) {
                 expect(response.statusCode).toBe(200);
                 expect(response.body).toBe("{'Points added':'10'}")
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
         })
         it("check points have been added", function(done) {
             var url = 'http://localhost:8080/users/testuser';
             // getting params
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test')
                 }
             };
             request.get(params, function(error, response, body) {
                 expect(response.statusCode).toBe(200);
                 body = JSON.parse(body);
                 expect(body.points).toBe(10);
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
         })
         it("be able to see where you've checked in", function() {})
     })
     describe("groups", function() {
         it("be able to create a group", function(done) {
             var url = 'http://localhost:8080/groups
             var doc = {
                 username: "testuser",
                 groupname: "testgroup",
                 description: "This is a Test Group",
                 competition: "freshers"
             };
             // getting the parameters
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test'),
                     "content-type":"application/json"
                 },
                 body: JSON.stringify(doc)
             };
             request.post(params, function(error, response, body) {
                 expect(response.statusCode).toBe(201);
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
         })

         it("be able to join a group", function(done) {
             var url = 'http://localhost:8080/users/groups/testgroup';
             // getting params
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test')
                 },
             };
             request.put(params, function(error, response, body) {
                 expect(response.statusCode).toBe(200);
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
         })
         it("be able to delete a group", function(done) {
             var url = 'http://localhost:8080/users/groups';
             var doc = {
                 username: "testuser",
                 groupname: "testgroup",
                 description: "testgroup",
                 competition: "freshers"
             };
             // getting params
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test')
                 },
                 body: JSON.stringify(doc)
             };
             request.del(params, function(error, response, body) {
                 expect(response.statusCode).toBe(200);
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
         })
     });
     describe('businesses', function() {
         it('able to create new business', function(done) {
             var url = 'http://localhost:8080/';
             // getting the parameters
             //
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test')
                 },
             };
             request.put(params, function(error, response, body) {
                 expect(response.statusCode).toBe(201);
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
         })
     })
     describe('Offers', function() {
         it("Be able to add an offer", function(done) {
             var url = 'http://localhost:8080/business/offers';
             var doc = {
                 businessname: 'testbusiness',
                 description: 'description',
                 title: 'test offer',
                 cost: 50
             }
             // getting params
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test')
                 },
                 body: JSON.stringify(doc)
             };
             request.post(params, function(error, response, body) {
                 expect(response.statusCode).toBe(200);
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
         })
         it("Be able to get the latest offers", function(done) {
             var url = 'http://localhost:8080/business/offers/all';
             // getting params
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test')
                 },
             };
             request.get(params, function(error, response, body) {
                 expect(response.statusCode).toBe(200);
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
         })
         it("be able to get a businesses offers", function(done) {
             var url = 'http://localhost:8080/business/offers/testbusiness';
             // getting params
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test')
                 },
             };
             request.get(params, function(error, response, body) {
                 expect(response.statusCode).toBe(200);
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
         })
     })
     it("be able to check what offers youve redeemed", function() {})
     describe('delete all', function() {
         it("be able delete the user", function(done) {
             var url = 'http://localhost:8080/users';
             // getting params
             //
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test')
                 },
             };
             request.del(params, function(error, response, body) {
                 expect(response.statusCode).toBe(200);
                 expect(body).toBe('"Deleted User!"')
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
         })
         it('be able to delete the business', function(done) {
             var url = 'http://localhost:8080/business';
             // getting the parameters
             //
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test')
                 },
             };
             request.del(params, function(error, response, body) {
                 expect(response.statusCode).toBe(200);
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
         })
         it('delete offers', function() {})
         it('delete group', function() {})
     })
 });
 getBasic = function(username, password) {
     return "Basic " + new Buffer(username + ":" + password).toString('base64')
 };<commit_msg>missing quotation<commit_after> var request = require('request');
 require('../testserver.js').startserver();
 describe('Localr API', function() {
     describe('test local connection', function() {
         it('make connection to server', function(done) {
             var url = 'http://localhost:8080/users/test';
             // getting params
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test')
                 }
             };
             request.get(params, function(error, response, body) {
                 expect(response.statusCode).toBe(200);
                 expect(body).toBe('"works"');
                 console.log(body)
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
             console.log("connection works")
         })
     })
     describe('Users', function() {
         describe('create the user', function() {
             it("be able to create a user", function(done) {
                 var url = 'http://localhost:8080/users';
                 var params = {
                     uri: url,
                     headers: {
                         authorization: getBasic('testuser', 'test')
                     }
                 };
                 request.post(params, function(error, response, body) {
                     expect(response.statusCode).toBe(201);
                     body = JSON.parse(body);
                     expect(body.Username).toBe('testuser');
                     expect(body.url).toBe('api.adam-holt.co.uk/users/testuser');
                     if(error) {
                         expect(error.code).not.toBe('ECONNREFUSED');
                     }
                     done();
                 })
             })
             it("be not able to create duplicate user", function(done) {
                 var url = 'http://localhost:8080/users';
                 // getting params
                 var params = {
                     uri: url,
                     headers: {
                         authorization: getBasic('testuser', 'test')
                     }
                 };
                 request.post(params, function(error, response, body) {
                     expect(response.statusCode).toBe(409);
                     if(error) {
                         expect(error.code).not.toBe('ECONNREFUSED');
                     }
                     done();
                 })
             })
         })
     })
     describe('checkin', function() {
         it("be able to checkin", function(done) {
             var url = 'http://localhost:8080/users/checkin?username=testuser&points=10';
             var doc = {
                 username: "testuser",
                 points: 10
             };
             // getting params
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test')
                 },
                 body: JSON.stringify(doc)
             };
             request.put(params, function(error, response, body) {
                 expect(response.statusCode).toBe(200);
                 expect(response.body).toBe("{'Points added':'10'}")
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
         })
         it("check points have been added", function(done) {
             var url = 'http://localhost:8080/users/testuser';
             // getting params
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test')
                 }
             };
             request.get(params, function(error, response, body) {
                 expect(response.statusCode).toBe(200);
                 body = JSON.parse(body);
                 expect(body.points).toBe(10);
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
         })
         it("be able to see where you've checked in", function() {})
     })
     describe("groups", function() {
         it("be able to create a group", function(done) {
             var url = 'http://localhost:8080/groups'
             var doc = {
                 username: "testuser",
                 groupname: "testgroup",
                 description: "This is a Test Group",
                 competition: "freshers"
             };
             // getting the parameters
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test'),
                     "content-type":"application/json"
                 },
                 body: JSON.stringify(doc)
             };
             request.post(params, function(error, response, body) {
                 expect(response.statusCode).toBe(201);
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
         })

         it("be able to join a group", function(done) {
             var url = 'http://localhost:8080/users/groups/testgroup';
             // getting params
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test')
                 },
             };
             request.put(params, function(error, response, body) {
                 expect(response.statusCode).toBe(200);
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
         })
         it("be able to delete a group", function(done) {
             var url = 'http://localhost:8080/users/groups';
             var doc = {
                 username: "testuser",
                 groupname: "testgroup",
                 description: "testgroup",
                 competition: "freshers"
             };
             // getting params
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test')
                 },
                 body: JSON.stringify(doc)
             };
             request.del(params, function(error, response, body) {
                 expect(response.statusCode).toBe(200);
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
         })
     });
     describe('businesses', function() {
         it('able to create new business', function(done) {
             var url = 'http://localhost:8080/';
             // getting the parameters
             //
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test')
                 },
             };
             request.put(params, function(error, response, body) {
                 expect(response.statusCode).toBe(201);
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
         })
     })
     describe('Offers', function() {
         it("Be able to add an offer", function(done) {
             var url = 'http://localhost:8080/business/offers';
             var doc = {
                 businessname: 'testbusiness',
                 description: 'description',
                 title: 'test offer',
                 cost: 50
             }
             // getting params
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test')
                 },
                 body: JSON.stringify(doc)
             };
             request.post(params, function(error, response, body) {
                 expect(response.statusCode).toBe(200);
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
         })
         it("Be able to get the latest offers", function(done) {
             var url = 'http://localhost:8080/business/offers/all';
             // getting params
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test')
                 },
             };
             request.get(params, function(error, response, body) {
                 expect(response.statusCode).toBe(200);
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
         })
         it("be able to get a businesses offers", function(done) {
             var url = 'http://localhost:8080/business/offers/testbusiness';
             // getting params
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test')
                 },
             };
             request.get(params, function(error, response, body) {
                 expect(response.statusCode).toBe(200);
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
         })
     })
     it("be able to check what offers youve redeemed", function() {})
     describe('delete all', function() {
         it("be able delete the user", function(done) {
             var url = 'http://localhost:8080/users';
             // getting params
             //
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test')
                 },
             };
             request.del(params, function(error, response, body) {
                 expect(response.statusCode).toBe(200);
                 expect(body).toBe('"Deleted User!"')
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
         })
         it('be able to delete the business', function(done) {
             var url = 'http://localhost:8080/business';
             // getting the parameters
             //
             var params = {
                 uri: url,
                 headers: {
                     authorization: getBasic('testuser', 'test')
                 },
             };
             request.del(params, function(error, response, body) {
                 expect(response.statusCode).toBe(200);
                 if(error) {
                     expect(error.code).not.toBe('ECONNREFUSED');
                 }
                 done();
             })
         })
         it('delete offers', function() {})
         it('delete group', function() {})
     })
 });
 getBasic = function(username, password) {
     return "Basic " + new Buffer(username + ":" + password).toString('base64')
 };<|endoftext|>


<commit_before>
var Retext = require('..'),
    assert = require('assert');

/* istanbul ignore next: noop */
function noop() {}

describe('Retext()', function () {
    it('should be of type `function`', function () {
        assert(typeof Retext === 'function');
    });

    it('should return a newly initialized `Retext` object, when invoked ' +
        'without arguments', function () {
            assert(new Retext() instanceof Retext);
        }
    );

    it('should set the `parser` attribute to `parse-english`, when invoked ' +
        'without arguments', function () {
            var retext = new Retext();
            assert('parser' in retext);
            assert(typeof retext.parser === 'function');
            assert('fromAST' in retext.parser);
            assert('TextOM' in retext.parser);
        }
    );

    it('should set the `parser` attribute to the passed in parser, ' +
        'when given', function () {
            var retext = new Retext(noop);
            assert('parser' in retext);
            assert(retext.parser === noop);
        }
    );

    it('should create a new context/parser/textom when required, thus ' +
        'not requiring from memory', function () {
            var rootNode1 = new Retext().parse(),
                rootNode2 = new Retext().parse();

            assert(rootNode1 instanceof rootNode1.constructor);
            assert(!(rootNode1 instanceof rootNode2.constructor));
            assert(rootNode2 instanceof rootNode2.constructor);
            assert(!(rootNode2 instanceof rootNode1.constructor));
        }
    );

    it('should set the `plugins` attribute to an empty array', function () {
        var retext = new Retext();
        assert('plugins' in retext);
        assert(retext.plugins instanceof Array);
        assert(retext.hasOwnProperty('plugins'));
        assert(retext.plugins.length === 0);
    });
});

describe('Retext#use', function () {
    it('should be of type `function`', function () {
        assert(typeof Retext.prototype.use === 'function');
        assert(typeof (new Retext()).use === 'function');
    });

    it('should return self', function () {
        var retext = new Retext();
        assert(retext.use(noop) === retext);
    });

    it('should throw, when something other than a function was given',
        function () {
            var retext = new Retext();

            assert.throws(function () {
                retext.use();
            }, /undefined/);

            assert.throws(function () {
                retext.use(null);
            }, /null/);

            assert.throws(function () {
                retext.use(undefined);
            }, /undefined/);

            assert.throws(function () {
                retext.use(true);
            }, /true/);

            assert.throws(function () {
                retext.use({});
            }, /object Object/);
        }
    );

    it('should attach `use`d plugins', function () {
        var retext = new Retext();
        assert(retext.plugins.length === 0);
        retext.use(noop);
        assert(retext.plugins.length === 1);
    });

    it('should not attach `use`d plugins multiple times', function () {
        var retext = new Retext();
        retext.use(noop);
        assert(retext.plugins.length === 1);
        retext.use(noop);
        assert(retext.plugins.length === 1);
    });
});

describe('Retext#parse', function () {
    it('should be of type `function`', function () {
        assert(typeof Retext.prototype.parse === 'function');
        assert(typeof (new Retext()).parse === 'function');
    });

    it('should return an instance of RootNode', function () {
        var retext = new Retext();
        assert(retext.parse() instanceof retext.parser.TextOM.RootNode);
    });

    it('should immediately call the `attach` method on a plugin, when ' +
        '`use` is called', function () {
            var retext = new Retext(),
                isCalled = false;

            /* istanbul ignore next: noop */
            function plugin () {}

            plugin.attach = function () {
                isCalled = true;
            };

            retext.use(plugin);

            assert(isCalled === true);
        }
    );

    it('should not call the `attach` method, when `parse` is called',
        function () {
            var retext = new Retext(),
                isCalled = false;

            function plugin () {}

            plugin.attach = function () {
                isCalled = true;
            };

            retext.use(plugin);

            isCalled = false;

            retext.parse();

            assert(isCalled === false);
        }
    );

    it('should call `use`d plugins, when `parse` is called', function () {
        var retext = new Retext(),
            isCalled = false;

        function plugin () {
            isCalled = true;
        }

        retext.use(plugin);

        assert(isCalled === false);

        retext.parse();

        assert(isCalled === true);
    });

    it('should call `use`d plugins with an instance of RootNode and ' +
        'Retext, when `parse` is called', function () {
            var retext = new Retext(),
                args = null,
                isCalled = false,
                tree;

            function plugin () {
                args = arguments;
            }

            retext.use(plugin);

            tree = retext.parse();

            assert(args[0] === tree);
            assert(args[1] === retext);
        }
    );

    it('should immediately call (during parsing) `use`d plugins, with ' +
        'an instance of RootNode and Retext', function () {
            var retext = new Retext(),
                args = null;

            function nestedPlugin () {
                args = arguments;
            }

            function plugin (tree, retext) {
                retext.use(nestedPlugin);
                assert(args[0] === tree);
                assert(args[1] === retext);
            }

            retext.use(plugin).parse();
        }
    );

    it('should not call (during parsing) `use`d plugins, when already used',
        function () {
            var retext = new Retext();

            function nestedPlugin () {}

            function plugin (tree, retext) {
                var length = retext.plugins.length;
                retext.use(nestedPlugin);
                assert(length === retext.plugins.length);
            }

            retext.use(nestedPlugin).use(plugin).parse();
        }
    );
});
<commit_msg>Made a unit test optional<commit_after>
var Retext = require('..'),
    assert = require('assert');

/* istanbul ignore next: noop */
function noop() {}

describe('Retext()', function () {
    it('should be of type `function`', function () {
        assert(typeof Retext === 'function');
    });

    it('should return a newly initialized `Retext` object, when invoked ' +
        'without arguments', function () {
            assert(new Retext() instanceof Retext);
        }
    );

    it('should set the `parser` attribute to `parse-english`, when invoked ' +
        'without arguments', function () {
            var retext = new Retext();
            assert('parser' in retext);
            assert(typeof retext.parser === 'function');
            assert('fromAST' in retext.parser);
            assert('TextOM' in retext.parser);
        }
    );

    it('should set the `parser` attribute to the passed in parser, ' +
        'when given', function () {
            var retext = new Retext(noop);
            assert('parser' in retext);
            assert(retext.parser === noop);
        }
    );

    /* istanbul ignore else: Node always has a `cache` property */
    if (require.cache) {
        it('should create a new context/parser/textom when required, thus ' +
            'not requiring from memory', function () {
                var rootNode1 = new Retext().parse(),
                    rootNode2 = new Retext().parse();

                assert(rootNode1 instanceof rootNode1.constructor);
                assert(!(rootNode1 instanceof rootNode2.constructor));
                assert(rootNode2 instanceof rootNode2.constructor);
                assert(!(rootNode2 instanceof rootNode1.constructor));
            }
        );
    }

    it('should set the `plugins` attribute to an empty array', function () {
        var retext = new Retext();
        assert('plugins' in retext);
        assert(retext.plugins instanceof Array);
        assert(retext.hasOwnProperty('plugins'));
        assert(retext.plugins.length === 0);
    });
});

describe('Retext#use', function () {
    it('should be of type `function`', function () {
        assert(typeof Retext.prototype.use === 'function');
        assert(typeof (new Retext()).use === 'function');
    });

    it('should return self', function () {
        var retext = new Retext();
        assert(retext.use(noop) === retext);
    });

    it('should throw, when something other than a function was given',
        function () {
            var retext = new Retext();

            assert.throws(function () {
                retext.use();
            }, /undefined/);

            assert.throws(function () {
                retext.use(null);
            }, /null/);

            assert.throws(function () {
                retext.use(undefined);
            }, /undefined/);

            assert.throws(function () {
                retext.use(true);
            }, /true/);

            assert.throws(function () {
                retext.use({});
            }, /object Object/);
        }
    );

    it('should attach `use`d plugins', function () {
        var retext = new Retext();
        assert(retext.plugins.length === 0);
        retext.use(noop);
        assert(retext.plugins.length === 1);
    });

    it('should not attach `use`d plugins multiple times', function () {
        var retext = new Retext();
        retext.use(noop);
        assert(retext.plugins.length === 1);
        retext.use(noop);
        assert(retext.plugins.length === 1);
    });
});

describe('Retext#parse', function () {
    it('should be of type `function`', function () {
        assert(typeof Retext.prototype.parse === 'function');
        assert(typeof (new Retext()).parse === 'function');
    });

    it('should return an instance of RootNode', function () {
        var retext = new Retext();
        assert(retext.parse() instanceof retext.parser.TextOM.RootNode);
    });

    it('should immediately call the `attach` method on a plugin, when ' +
        '`use` is called', function () {
            var retext = new Retext(),
                isCalled = false;

            /* istanbul ignore next: noop */
            function plugin () {}

            plugin.attach = function () {
                isCalled = true;
            };

            retext.use(plugin);

            assert(isCalled === true);
        }
    );

    it('should not call the `attach` method, when `parse` is called',
        function () {
            var retext = new Retext(),
                isCalled = false;

            function plugin () {}

            plugin.attach = function () {
                isCalled = true;
            };

            retext.use(plugin);

            isCalled = false;

            retext.parse();

            assert(isCalled === false);
        }
    );

    it('should call `use`d plugins, when `parse` is called', function () {
        var retext = new Retext(),
            isCalled = false;

        function plugin () {
            isCalled = true;
        }

        retext.use(plugin);

        assert(isCalled === false);

        retext.parse();

        assert(isCalled === true);
    });

    it('should call `use`d plugins with an instance of RootNode and ' +
        'Retext, when `parse` is called', function () {
            var retext = new Retext(),
                args = null,
                isCalled = false,
                tree;

            function plugin () {
                args = arguments;
            }

            retext.use(plugin);

            tree = retext.parse();

            assert(args[0] === tree);
            assert(args[1] === retext);
        }
    );

    it('should immediately call (during parsing) `use`d plugins, with ' +
        'an instance of RootNode and Retext', function () {
            var retext = new Retext(),
                args = null;

            function nestedPlugin () {
                args = arguments;
            }

            function plugin (tree, retext) {
                retext.use(nestedPlugin);
                assert(args[0] === tree);
                assert(args[1] === retext);
            }

            retext.use(plugin).parse();
        }
    );

    it('should not call (during parsing) `use`d plugins, when already used',
        function () {
            var retext = new Retext();

            function nestedPlugin () {}

            function plugin (tree, retext) {
                var length = retext.plugins.length;
                retext.use(nestedPlugin);
                assert(length === retext.plugins.length);
            }

            retext.use(nestedPlugin).use(plugin).parse();
        }
    );
});
<|endoftext|>