<commit_before>import {Evented} from '../core/Events';
import {Map} from '../map/Map';
import * as Util from '../core/Util';

/*
 * @class Layer
 * @inherits Evented
 * @aka L.Layer
 * @aka ILayer
 *
 * A set of methods from the Layer base class that all Leaflet layers use.
 * Inherits all methods, options and events from `L.Evented`.
 *
 * @example
 *
 * ```js
 * var layer = L.Marker(latlng).addTo(map);
 * layer.addTo(map);
 * layer.remove();
 * ```
 *
 * @event add: Event
 * Fired after the layer is added to a map
 *
 * @event remove: Event
 * Fired after the layer is removed from a map
 */

export var Layer = Evented.extend({

	// Classes extending `L.Layer` will inherit the following options:
	options: {
		// @option pane: String = 'overlayPane'
		// By default the layer will be added to the map's [overlay pane](#map-overlaypane). Overriding this option will cause the layer to be placed on another pane by default.
		pane: 'overlayPane',

		// @option attribution: String = null
		// String to be shown in the attribution control, e.g. "© OpenStreetMap contributors". It describes the layer data and is often a legal obligation towards copyright holders and tile providers.
		attribution: null,

		bubblingMouseEvents: true
	},

	/* @section
	 * Classes extending `L.Layer` will inherit the following methods:
	 *
	 * @method addTo(map: Map|LayerGroup): this
	 * Adds the layer to the given map or layer group.
	 */
	addTo: function (map) {
		map.addLayer(this);
		return this;
	},

	// @method remove: this
	// Removes the layer from the map it is currently active on.
	remove: function () {
		return this.removeFrom(this._map || this._mapToAdd);
	},

	// @method removeFrom(map: Map): this
	// Removes the layer from the given map
	removeFrom: function (obj) {
		if (obj) {
			obj.removeLayer(this);
		}
		return this;
	},

	// @method getPane(name? : String): HTMLElement
	// Returns the `HTMLElement` representing the named pane on the map. If `name` is omitted, returns the pane for this layer.
	getPane: function (name) {
		return this._map.getPane(name ? (this.options[name] || name) : this.options.pane);
	},

	addInteractiveTarget: function (targetEl) {
		this._map._targets[Util.stamp(targetEl)] = this;
		return this;
	},

	removeInteractiveTarget: function (targetEl) {
		delete this._map._targets[Util.stamp(targetEl)];
		return this;
	},

	// @method getAttribution: String
	// Used by the `attribution control`, returns the [attribution option](#gridlayer-attribution).
	getAttribution: function () {
		return this.options.attribution;
	},

	_layerAdd: function (e) {
		var map = e.target;

		// check in case layer gets added and then removed before the map is ready
		if (!map.hasLayer(this)) { return; }

		this._map = map;
		this._zoomAnimated = map._zoomAnimated;

		if (this.getEvents) {
			var events = this.getEvents();
			map.on(events, this);
			this.once('remove', function () {
				map.off(events, this);
			}, this);
		}

		this.onAdd(map);

		if (this.getAttribution && map.attributionControl) {
			map.attributionControl.addAttribution(this.getAttribution());
		}

		this.fire('add');
		map.fire('layeradd', {layer: this});
	}
});

/* @section Extension methods
 * @uninheritable
 *
 * Every layer should extend from `L.Layer` and (re-)implement the following methods.
 *
 * @method onAdd(map: Map): this
 * Should contain code that creates DOM elements for the layer, adds them to `map panes` where they should belong and puts listeners on relevant map events. Called on [`map.addLayer(layer)`](#map-addlayer).
 *
 * @method onRemove(map: Map): this
 * Should contain all clean up code that removes the layer's elements from the DOM and removes listeners previously added in [`onAdd`](#layer-onadd). Called on [`map.removeLayer(layer)`](#map-removelayer).
 *
 * @method getEvents(): Object
 * This optional method should return an object like `{ viewreset: this._reset }` for [`addEventListener`](#evented-addeventlistener). The event handlers in this object will be automatically added and removed from the map with your layer.
 *
 * @method getAttribution(): String
 * This optional method should return a string containing HTML to be shown on the `Attribution control` whenever the layer is visible.
 *
 * @method beforeAdd(map: Map): this
 * Optional method. Called on [`map.addLayer(layer)`](#map-addlayer), before the layer is added to the map, before events are initialized, without waiting until the map is in a usable state. Use for early initialization only.
 */

/* @namespace Map
 * @section Layer events
 *
 * @event layeradd: LayerEvent
 * Fired when a new layer is added to the map.
 *
 * @event layerremove: LayerEvent
 * Fired when some layer is removed from the map
 *
 * @section Methods for Layers and Controls
 */
Map.include({
	// @method addLayer(layer: Layer): this
	// Adds the given layer to the map
	addLayer: function (layer) {
		if (!layer._layerAdd) {
			throw new Error('The provided object is not a Layer.');
		}

		var id = Util.stamp(layer);
		if (this._layers[id]) { return this; }
		this._layers[id] = layer;

		layer._mapToAdd = this;

		if (layer.beforeAdd) {
			layer.beforeAdd(this);
		}

		this.whenReady(layer._layerAdd, layer);

		return this;
	},

	// @method removeLayer(layer: Layer): this
	// Removes the given layer from the map.
	removeLayer: function (layer) {
		var id = Util.stamp(layer);

		if (!this._layers[id]) { return this; }

		if (this._loaded) {
			layer.onRemove(this);
		}

		if (layer.getAttribution && this.attributionControl) {
			this.attributionControl.removeAttribution(layer.getAttribution());
		}

		delete this._layers[id];

		if (this._loaded) {
			this.fire('layerremove', {layer: layer});
			layer.fire('remove');
		}

		layer._map = layer._mapToAdd = null;

		return this;
	},

	// @method hasLayer(layer: Layer): Boolean
	// Returns `true` if the given layer is currently added to the map
	hasLayer: function (layer) {
		return !!layer && (Util.stamp(layer) in this._layers);
	},

	/* @method eachLayer(fn: Function, context?: Object): this
	 * Iterates over the layers of the map, optionally specifying context of the iterator function.
	 * ```
	 * map.eachLayer(function(layer){
	 *     layer.bindPopup('Hello');
	 * });
	 * ```
	 */
	eachLayer: function (method, context) {
		for (var i in this._layers) {
			method.call(context, this._layers[i]);
		}
		return this;
	},

	_addLayers: function (layers) {
		layers = layers ? (Util.isArray(layers) ? layers : [layers]) : [];

		for (var i = 0, len = layers.length; i < len; i++) {
			this.addLayer(layers[i]);
		}
	},

	_addZoomLimit: function (layer) {
		if (isNaN(layer.options.maxZoom) || !isNaN(layer.options.minZoom)) {
			this._zoomBoundLayers[Util.stamp(layer)] = layer;
			this._updateZoomLevels();
		}
	},

	_removeZoomLimit: function (layer) {
		var id = Util.stamp(layer);

		if (this._zoomBoundLayers[id]) {
			delete this._zoomBoundLayers[id];
			this._updateZoomLevels();
		}
	},

	_updateZoomLevels: function () {
		var minZoom = Infinity,
		    maxZoom = -Infinity,
		    oldZoomSpan = this._getZoomSpan();

		for (var i in this._zoomBoundLayers) {
			var options = this._zoomBoundLayers[i].options;

			minZoom = options.minZoom === undefined ? minZoom : Math.min(minZoom, options.minZoom);
			maxZoom = options.maxZoom === undefined ? maxZoom : Math.max(maxZoom, options.maxZoom);
		}

		this._layersMaxZoom = maxZoom === -Infinity ? undefined : maxZoom;
		this._layersMinZoom = minZoom === Infinity ? undefined : minZoom;

		// @section Map state change events
		// @event zoomlevelschange: Event
		// Fired when the number of zoomlevels on the map is changed due
		// to adding or removing a layer.
		if (oldZoomSpan !== this._getZoomSpan()) {
			this.fire('zoomlevelschange');
		}

		if (this.options.maxZoom === undefined && this._layersMaxZoom && this.getZoom() > this._layersMaxZoom) {
			this.setZoom(this._layersMaxZoom);
		}
		if (this.options.minZoom === undefined && this._layersMinZoom && this.getZoom() < this._layersMinZoom) {
			this.setZoom(this._layersMinZoom);
		}
	}
});
<commit_msg>Change L.Marker to L.marker in example (#6636)<commit_after>import {Evented} from '../core/Events';
import {Map} from '../map/Map';
import * as Util from '../core/Util';

/*
 * @class Layer
 * @inherits Evented
 * @aka L.Layer
 * @aka ILayer
 *
 * A set of methods from the Layer base class that all Leaflet layers use.
 * Inherits all methods, options and events from `L.Evented`.
 *
 * @example
 *
 * ```js
 * var layer = L.marker(latlng).addTo(map);
 * layer.addTo(map);
 * layer.remove();
 * ```
 *
 * @event add: Event
 * Fired after the layer is added to a map
 *
 * @event remove: Event
 * Fired after the layer is removed from a map
 */

export var Layer = Evented.extend({

	// Classes extending `L.Layer` will inherit the following options:
	options: {
		// @option pane: String = 'overlayPane'
		// By default the layer will be added to the map's [overlay pane](#map-overlaypane). Overriding this option will cause the layer to be placed on another pane by default.
		pane: 'overlayPane',

		// @option attribution: String = null
		// String to be shown in the attribution control, e.g. "© OpenStreetMap contributors". It describes the layer data and is often a legal obligation towards copyright holders and tile providers.
		attribution: null,

		bubblingMouseEvents: true
	},

	/* @section
	 * Classes extending `L.Layer` will inherit the following methods:
	 *
	 * @method addTo(map: Map|LayerGroup): this
	 * Adds the layer to the given map or layer group.
	 */
	addTo: function (map) {
		map.addLayer(this);
		return this;
	},

	// @method remove: this
	// Removes the layer from the map it is currently active on.
	remove: function () {
		return this.removeFrom(this._map || this._mapToAdd);
	},

	// @method removeFrom(map: Map): this
	// Removes the layer from the given map
	removeFrom: function (obj) {
		if (obj) {
			obj.removeLayer(this);
		}
		return this;
	},

	// @method getPane(name? : String): HTMLElement
	// Returns the `HTMLElement` representing the named pane on the map. If `name` is omitted, returns the pane for this layer.
	getPane: function (name) {
		return this._map.getPane(name ? (this.options[name] || name) : this.options.pane);
	},

	addInteractiveTarget: function (targetEl) {
		this._map._targets[Util.stamp(targetEl)] = this;
		return this;
	},

	removeInteractiveTarget: function (targetEl) {
		delete this._map._targets[Util.stamp(targetEl)];
		return this;
	},

	// @method getAttribution: String
	// Used by the `attribution control`, returns the [attribution option](#gridlayer-attribution).
	getAttribution: function () {
		return this.options.attribution;
	},

	_layerAdd: function (e) {
		var map = e.target;

		// check in case layer gets added and then removed before the map is ready
		if (!map.hasLayer(this)) { return; }

		this._map = map;
		this._zoomAnimated = map._zoomAnimated;

		if (this.getEvents) {
			var events = this.getEvents();
			map.on(events, this);
			this.once('remove', function () {
				map.off(events, this);
			}, this);
		}

		this.onAdd(map);

		if (this.getAttribution && map.attributionControl) {
			map.attributionControl.addAttribution(this.getAttribution());
		}

		this.fire('add');
		map.fire('layeradd', {layer: this});
	}
});

/* @section Extension methods
 * @uninheritable
 *
 * Every layer should extend from `L.Layer` and (re-)implement the following methods.
 *
 * @method onAdd(map: Map): this
 * Should contain code that creates DOM elements for the layer, adds them to `map panes` where they should belong and puts listeners on relevant map events. Called on [`map.addLayer(layer)`](#map-addlayer).
 *
 * @method onRemove(map: Map): this
 * Should contain all clean up code that removes the layer's elements from the DOM and removes listeners previously added in [`onAdd`](#layer-onadd). Called on [`map.removeLayer(layer)`](#map-removelayer).
 *
 * @method getEvents(): Object
 * This optional method should return an object like `{ viewreset: this._reset }` for [`addEventListener`](#evented-addeventlistener). The event handlers in this object will be automatically added and removed from the map with your layer.
 *
 * @method getAttribution(): String
 * This optional method should return a string containing HTML to be shown on the `Attribution control` whenever the layer is visible.
 *
 * @method beforeAdd(map: Map): this
 * Optional method. Called on [`map.addLayer(layer)`](#map-addlayer), before the layer is added to the map, before events are initialized, without waiting until the map is in a usable state. Use for early initialization only.
 */

/* @namespace Map
 * @section Layer events
 *
 * @event layeradd: LayerEvent
 * Fired when a new layer is added to the map.
 *
 * @event layerremove: LayerEvent
 * Fired when some layer is removed from the map
 *
 * @section Methods for Layers and Controls
 */
Map.include({
	// @method addLayer(layer: Layer): this
	// Adds the given layer to the map
	addLayer: function (layer) {
		if (!layer._layerAdd) {
			throw new Error('The provided object is not a Layer.');
		}

		var id = Util.stamp(layer);
		if (this._layers[id]) { return this; }
		this._layers[id] = layer;

		layer._mapToAdd = this;

		if (layer.beforeAdd) {
			layer.beforeAdd(this);
		}

		this.whenReady(layer._layerAdd, layer);

		return this;
	},

	// @method removeLayer(layer: Layer): this
	// Removes the given layer from the map.
	removeLayer: function (layer) {
		var id = Util.stamp(layer);

		if (!this._layers[id]) { return this; }

		if (this._loaded) {
			layer.onRemove(this);
		}

		if (layer.getAttribution && this.attributionControl) {
			this.attributionControl.removeAttribution(layer.getAttribution());
		}

		delete this._layers[id];

		if (this._loaded) {
			this.fire('layerremove', {layer: layer});
			layer.fire('remove');
		}

		layer._map = layer._mapToAdd = null;

		return this;
	},

	// @method hasLayer(layer: Layer): Boolean
	// Returns `true` if the given layer is currently added to the map
	hasLayer: function (layer) {
		return !!layer && (Util.stamp(layer) in this._layers);
	},

	/* @method eachLayer(fn: Function, context?: Object): this
	 * Iterates over the layers of the map, optionally specifying context of the iterator function.
	 * ```
	 * map.eachLayer(function(layer){
	 *     layer.bindPopup('Hello');
	 * });
	 * ```
	 */
	eachLayer: function (method, context) {
		for (var i in this._layers) {
			method.call(context, this._layers[i]);
		}
		return this;
	},

	_addLayers: function (layers) {
		layers = layers ? (Util.isArray(layers) ? layers : [layers]) : [];

		for (var i = 0, len = layers.length; i < len; i++) {
			this.addLayer(layers[i]);
		}
	},

	_addZoomLimit: function (layer) {
		if (isNaN(layer.options.maxZoom) || !isNaN(layer.options.minZoom)) {
			this._zoomBoundLayers[Util.stamp(layer)] = layer;
			this._updateZoomLevels();
		}
	},

	_removeZoomLimit: function (layer) {
		var id = Util.stamp(layer);

		if (this._zoomBoundLayers[id]) {
			delete this._zoomBoundLayers[id];
			this._updateZoomLevels();
		}
	},

	_updateZoomLevels: function () {
		var minZoom = Infinity,
		    maxZoom = -Infinity,
		    oldZoomSpan = this._getZoomSpan();

		for (var i in this._zoomBoundLayers) {
			var options = this._zoomBoundLayers[i].options;

			minZoom = options.minZoom === undefined ? minZoom : Math.min(minZoom, options.minZoom);
			maxZoom = options.maxZoom === undefined ? maxZoom : Math.max(maxZoom, options.maxZoom);
		}

		this._layersMaxZoom = maxZoom === -Infinity ? undefined : maxZoom;
		this._layersMinZoom = minZoom === Infinity ? undefined : minZoom;

		// @section Map state change events
		// @event zoomlevelschange: Event
		// Fired when the number of zoomlevels on the map is changed due
		// to adding or removing a layer.
		if (oldZoomSpan !== this._getZoomSpan()) {
			this.fire('zoomlevelschange');
		}

		if (this.options.maxZoom === undefined && this._layersMaxZoom && this.getZoom() > this._layersMaxZoom) {
			this.setZoom(this._layersMaxZoom);
		}
		if (this.options.minZoom === undefined && this._layersMinZoom && this.getZoom() < this._layersMinZoom) {
			this.setZoom(this._layersMinZoom);
		}
	}
});
<|endoftext|>


<commit_before>/*
 * Namespace: lb.base.log
 * Logging Adapter Module for Base Library
 *
 * Author:
 * Eric Bréchemier <legalbox@eric.brechemier.name>
 *
 * Copyright:
 * Legal-Box SAS (c) 2010-2011, All Rights Reserved
 *
 * License:
 * BSD License
 * http://creativecommons.org/licenses/BSD/
 *
 * Version:
 * 2011-01-05
 */
/*requires lb.base.js */
/*jslint white:false, plusplus:false */
/*global lb, goog */
// preserve the module, if already loaded
lb.base.log = lb.base.log || (function() {
  // Builder of
  // Closure for lb.base.log module

  // Define aliases
      /*requires closure/goog.debug.Console.js*/
  var Console = goog.debug.Console,
      /*requires closure/goog.debug.Logger.js*/
      Logger = goog.debug.Logger,
      Level  = goog.debug.Logger.Level,

  // Private fields

    // object - the logger instance (goog.debug.Logger)
    logger;

  function print(message){
    // Function: print(message)
    // Print a message to the log console.
    //
    // Parameter:
    //   message - string, the message to print
    //
    // Notes:
    // The console will be activated if (and only if) Debug=true
    // is present in the URL.
    //
    // The console is initialized on first call.

    if (!logger){
      Console.autoInstall();
      logger = Logger.getLogger('lb');
      logger.setLevel(Level.INFO);
    }
    logger.info(message);
  }

  return { // public API
    print: print
  };
}());
<commit_msg>Test for null instead of relying on type coercion in lb.base.log.print()<commit_after>/*
 * Namespace: lb.base.log
 * Logging Adapter Module for Base Library
 *
 * Author:
 * Eric Bréchemier <legalbox@eric.brechemier.name>
 *
 * Copyright:
 * Legal-Box SAS (c) 2010-2011, All Rights Reserved
 *
 * License:
 * BSD License
 * http://creativecommons.org/licenses/BSD/
 *
 * Version:
 * 2011-04-12
 */
/*requires lb.base.js */
/*jslint white:false, plusplus:false */
/*global lb, goog */
// preserve the module, if already loaded
lb.base.log = lb.base.log || (function() {
  // Builder of
  // Closure for lb.base.log module

  // Define aliases
      /*requires closure/goog.debug.Console.js*/
  var Console = goog.debug.Console,
      /*requires closure/goog.debug.Logger.js*/
      Logger = goog.debug.Logger,
      Level  = goog.debug.Logger.Level,

  // Private fields

    // object - the logger instance (goog.debug.Logger)
    logger = null;

  function print(message){
    // Function: print(message)
    // Print a message to the log console.
    //
    // Parameter:
    //   message - string, the message to print
    //
    // Notes:
    // The console will be activated if (and only if) Debug=true
    // is present in the URL.
    //
    // The console is initialized on first call.

    if (logger===null){
      Console.autoInstall();
      logger = Logger.getLogger('lb');
      logger.setLevel(Level.INFO);
    }
    logger.info(message);
  }

  return { // public API
    print: print
  };
}());
<|endoftext|>


<commit_before>var should=require('should'),
    testrepo="https://github.com/coyotebringsfire/xuexi.git",
    debug=require('debug')('git:getCommits:test'),
    fs=require('fs-plus'),
    async=require('async');

describe("git#getCommits", function getCommitsSuite() {
  this.timeout(0);
  var debug=require('debug')('xuexi:git:test:getCommits:getCommitsSuite'),
      testRepo="/Users/aumkara/workspace/MuMoo";

  beforeEach(function beforeEachTest(done) {
    var debug=require('debug')('xuexi:git:test:gitCloneSuite:after');
    debug("removing /tmp/xuexi.git");
    try {
      debug("removing /tmp/xuexi.git");
      fs.removeSync("/tmp/xuexi.git");
    } catch(e) {
      debug("error removing /tmp/xuexi.git %j", e);
    }
    done();
  });

  after(function afterAllTests(done) {
    var debug=require('debug')('xuexi:git:test:gitCloneSuite:after');
    debug("removing /tmp/xuexi.git");
    try {
      debug("removing /tmp/xuexi.git");
      fs.removeSync("/tmp/xuexi.git");
    } catch(e) {
      debug("error removing /tmp/xuexi.git %j", e);
    }
    done();
  });

  describe("promise style", function promiseStyleSuite() {
    var debug=require('debug')('git:getCommits:test:promiseStyleSuite'),
        testRepo;

    it("should reject the returned promise if called without a repo", function doIt(done) {
      var debug=require('debug')('git:getCommits:test:promiseStyleSuite:doIt'),
          Git=require('../lib/git');
      git=new Git(testrepo);
      git.getCommits()
        .then(function onResolve(msg) {
          var debug=require('debug')('git:getCommits:test:promiseStyleSuite:doIt:onResolve');
          should.fail("Promise was resolved: %j", msg);
          done();
        }, function onReject(err) {
          var debug=require('debug')('git:getCommits:test:promiseStyleSuite:doIt:onReject');
          err.should.be.ok;
          debug("reject error: %j", err);
          done();
        });
    });
    it("should reject the returned promise if called with an invalid repo", function doIt(done) {
      var debug=require('debug')('git:getCommits:test:promiseStyleSuite:doIt'),
          INVALID_REPO="/invalidrepo",
          Git=require('../lib/git');
      git=new Git(testrepo);
      git.getCommits()
        .then(function onResolve(msg) {
          var debug=require('debug')('git:getCommits:test:promiseStyleSuite:doIt:onResolve');
          should.fail("Promise was resolved: %j", msg);
          debug("promise was resolved %j", msg);
          done();
        }, function onReject(err) {
          var debug=require('debug')('git:getCommits:test:promiseStyleSuite:doIt:onReject');
          err.should.be.ok;
          err.message.should.match(/missing required repo dir/);
          debug("reject error: %s", err.message);
          done();
        });
    });
    it("should resolve the returned promise if no errors happen during training", function(done) {
      var debug=require('debug')('git:getCommits:test:promiseStyleSuite:doIt'),
          Git=require('../lib/git');
      //testRepo="/Users/aumkara/workspace/MuMoo";
      git=new Git(testrepo);
      git.clone()
        .then(git.getCommits)
        .then(function onResolve(trainedModel) {
          var debug=require('debug')('git:getCommits:test:promiseStyleSuite:doIt:onResolve');
          debug("Promise was resolved: %j", trainedModel);
          trainedModel.should.be.ok;
          done();
        }, function onReject(err) {
          var debug=require('debug')('git:getCommits:test:promiseStyleSuite:doIt:onReject');
          should.fail("Promise was rejected: %j", err);
          done();
        });
    });
  });
});<commit_msg>refacotred to use rimraf<commit_after>var should=require('should'),
    testrepo="https://github.com/coyotebringsfire/xuexi.git",
    debug=require('debug')('git:getCommits:test'),
    fs=require('fs-plus'),
    async=require('async'),
    rimraf=require('rimraf');

describe("git#getCommits", function getCommitsSuite() {
  this.timeout(0);
  var debug=require('debug')('xuexi:git:test:getCommits:getCommitsSuite'),
      testRepo="/Users/aumkara/workspace/MuMoo";

  beforeEach(function beforeEachTest(done) {
    var debug=require('debug')('xuexi:git:test:gitCloneSuite:after');
    debug("removing /tmp/xuexi");
    rimraf("/tmp/xuexi", function() {
      done();
    });
  });

  after(function afterAllTests(done) {
    var debug=require('debug')('xuexi:git:test:gitCloneSuite:after');
    debug("removing /tmp/xuexi");
    rimraf("/tmp/xuexi", function() {
      done();
    });
  });

  describe("promise style", function promiseStyleSuite() {
    var debug=require('debug')('git:getCommits:test:promiseStyleSuite'),
        testRepo;

    it("should reject the returned promise if called without a repo", function doIt(done) {
      var debug=require('debug')('git:getCommits:test:promiseStyleSuite:doIt'),
          Git=require('../lib/git');
      git=new Git(testrepo);
      git.getCommits()
        .then(function onResolve(msg) {
          var debug=require('debug')('git:getCommits:test:promiseStyleSuite:doIt:onResolve');
          should.fail("Promise was resolved: %j", msg);
          done();
        }, function onReject(err) {
          var debug=require('debug')('git:getCommits:test:promiseStyleSuite:doIt:onReject');
          err.should.be.ok;
          debug("reject error: %j", err);
          done();
        });
    });
    it("should reject the returned promise if called with an invalid repo", function doIt(done) {
      var debug=require('debug')('git:getCommits:test:promiseStyleSuite:doIt'),
          INVALID_REPO="/invalidrepo",
          Git=require('../lib/git');
      git=new Git(testrepo);
      git.getCommits()
        .then(function onResolve(msg) {
          var debug=require('debug')('git:getCommits:test:promiseStyleSuite:doIt:onResolve');
          should.fail("Promise was resolved: %j", msg);
          debug("promise was resolved %j", msg);
          done();
        }, function onReject(err) {
          var debug=require('debug')('git:getCommits:test:promiseStyleSuite:doIt:onReject');
          err.should.be.ok;
          err.message.should.match(/missing required repo dir/);
          debug("reject error: %s", err.message);
          done();
        });
    });
    it("should resolve the returned promise if no errors happen while getting commits", function(done) {
      var debug=require('debug')('git:getCommits:test:promiseStyleSuite:doIt'),
          Git=require('../lib/git');
      //testRepo="/Users/aumkara/workspace/MuMoo";
      debug("cloning repo %s", testrepo);
      git=new Git(testrepo);
      git.clone()
        .then(git.getCommits)
        .then(function onResolve(trainedModel) {
          var debug=require('debug')('git:getCommits:test:promiseStyleSuite:doIt:onResolve');
          debug("Promise was resolved: %j", trainedModel);
          trainedModel.should.be.ok;
          done();
        }, function onReject(err) {
          var debug=require('debug')('git:getCommits:test:promiseStyleSuite:doIt:onReject');
          should.fail("Promise was rejected: %j", err);
          done();
        });
    });
  });
});<|endoftext|>


<commit_before>/**
 * @fileoverview Tests for jsx-no-comment-textnodes
 * @author Ben Vinegar
 */

'use strict';

// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------

const RuleTester = require('eslint').RuleTester;
const rule = require('../../../lib/rules/jsx-no-comment-textnodes');

const parsers = require('../../helpers/parsers');

const parserOptions = {
  ecmaVersion: 2018,
  sourceType: 'module',
  ecmaFeatures: {
    jsx: true,
  },
};

// ------------------------------------------------------------------------------
// Tests
// ------------------------------------------------------------------------------

const ruleTester = new RuleTester({ parserOptions });
ruleTester.run('jsx-no-comment-textnodes', rule, {
  valid: parsers.all([
    {
      code: `
        class Comp1 extends Component {
          render() {
            return (

                {/* valid */}

            );
          }
        }
      `,
    },
    {
      code: `
        class Comp1 extends Component {
          render() {
            return (
              <>
                {/* valid */}
              </>
            );
          }
        }
      `,
      features: ['fragment'],
    },
    {
      code: `
        class Comp1 extends Component {
          render() {
            return (
{/* valid */}
);
          }
        }
      `,
    },
    {
      code: `
        class Comp1 extends Component {
          render() {
            const bar = (
{/* valid */}
);
            return bar;
          }
        }
      `,
    },
    {
      code: `
        var Hello = createReactClass({
          foo: (
{/* valid */}
),
          render() {
            return this.foo;
          },
        });
      `,
    },
    {
      code: `
        class Comp1 extends Component {
          render() {
            return (

                {/* valid */}
                {/* valid 2 */}
                {/* valid 3 */}

            );
          }
        }
      `,
    },
    {
      code: `
        class Comp1 extends Component {
          render() {
            return (

            );
          }
        }
      `,
    },
    {
      code: `
        var foo = require('foo');
      `,
    },
    {
      code: `
        <Foo bar='test'>
          {/* valid */}
        </Foo>
      `,
    },
    {
      code: `

           https://www.example.com/attachment/download/1

      `,
    },

    // inside element declarations
    {
      code: `
        <Foo /* valid */ placeholder={'foo'}/>
      `,
    },
    {
      code: `
        </* valid */></>
      `,
      features: ['fragment'],
    },
    {
      code: `
        <></* valid *//>
      `,
      features: ['fragment', 'no-ts'], // TODO: FIXME: figure out why both TS parsers fail on this
    },
    {
      code: `
        <Foo title={'foo' /* valid */}/>
      `,
    },
    {
      code: '
// TODO: Write perfect code
',
    },
    {
      code: '
/* TODO: Write perfect code */
',
    },
  ]),

  invalid: parsers.all([
    {
      code: `
        class Comp1 extends Component {
          render() {
            return (
// invalid
);
          }
        }
      `,
      features: ['no-ts-old'], // TODO: FIXME: remove this and figure out why the old TS parser hangs here
      errors: [{ messageId: 'putCommentInBraces' }],
    },
    {
      code: `
        class Comp1 extends Component {
          render() {
            return (<>// invalid</>);
          }
        }
      `,
      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove this and figure out why the old TS parser hangs here
      errors: [{ messageId: 'putCommentInBraces' }],
    },
    {
      code: `
        class Comp1 extends Component {
          render() {
            return (
/* invalid */
);
          }
        }
      `,
      features: ['no-ts-old'], // TODO: FIXME: remove this and figure out why the old TS parser hangs here
      errors: [{ messageId: 'putCommentInBraces' }],
    },
    {
      code: `
        class Comp1 extends Component {
          render() {
            return (

                // invalid

            );
          }
        }
      `,
      errors: [{ messageId: 'putCommentInBraces' }],
    },
    {
      code: `
        class Comp1 extends Component {
          render() {
            return (

                asdjfl
                /* invalid */
                foo

            );
          }
        }
      `,
      errors: [{ messageId: 'putCommentInBraces' }],
    },
    {
      code: `
        class Comp1 extends Component {
          render() {
            return (

                {'asdjfl'}
                // invalid
                {'foo'}

            );
          }
        }
      `,
      errors: [{ messageId: 'putCommentInBraces' }],
    },
    {
      code: `
        const Component2 = () => {
          return /*;
        };
      `,
      features: ['no-ts-old'], // TODO: FIXME: remove this and figure out why the old TS parser hangs here
      errors: [{ messageId: 'putCommentInBraces' }],
    },
  ]),
});
<commit_msg>[Tests] `jsx-no-comment-textnodes`: add passing test case<commit_after>/**
 * @fileoverview Tests for jsx-no-comment-textnodes
 * @author Ben Vinegar
 */

'use strict';

// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------

const RuleTester = require('eslint').RuleTester;
const rule = require('../../../lib/rules/jsx-no-comment-textnodes');

const parsers = require('../../helpers/parsers');

const parserOptions = {
  ecmaVersion: 2018,
  sourceType: 'module',
  ecmaFeatures: {
    jsx: true,
  },
};

// ------------------------------------------------------------------------------
// Tests
// ------------------------------------------------------------------------------

const ruleTester = new RuleTester({ parserOptions });
ruleTester.run('jsx-no-comment-textnodes', rule, {
  valid: parsers.all([
    {
      code: `
        class Comp1 extends Component {
          render() {
            return (

                {/* valid */}

            );
          }
        }
      `,
    },
    {
      code: `
        class Comp1 extends Component {
          render() {
            return (
              <>
                {/* valid */}
              </>
            );
          }
        }
      `,
      features: ['fragment'],
    },
    {
      code: `
        class Comp1 extends Component {
          render() {
            return (
{/* valid */}
);
          }
        }
      `,
    },
    {
      code: `
        class Comp1 extends Component {
          render() {
            const bar = (
{/* valid */}
);
            return bar;
          }
        }
      `,
    },
    {
      code: `
        var Hello = createReactClass({
          foo: (
{/* valid */}
),
          render() {
            return this.foo;
          },
        });
      `,
    },
    {
      code: `
        class Comp1 extends Component {
          render() {
            return (

                {/* valid */}
                {/* valid 2 */}
                {/* valid 3 */}

            );
          }
        }
      `,
    },
    {
      code: `
        class Comp1 extends Component {
          render() {
            return (

            );
          }
        }
      `,
    },
    {
      code: `
        var foo = require('foo');
      `,
    },
    {
      code: `
        <Foo bar='test'>
          {/* valid */}
        </Foo>
      `,
    },
    {
      code: `

           https://www.example.com/attachment/download/1

      `,
    },

    // inside element declarations
    {
      code: `
        <Foo /* valid */ placeholder={'foo'}/>
      `,
    },
    {
      code: `
        </* valid */></>
      `,
      features: ['fragment'],
    },
    {
      code: `
        <></* valid *//>
      `,
      features: ['fragment', 'no-ts'], // TODO: FIXME: figure out why both TS parsers fail on this
    },
    {
      code: `
        <Foo title={'foo' /* valid */}/>
      `,
    },
    {
      code: '
// TODO: Write perfect code
',
    },
    {
      code: '
/* TODO: Write perfect code */
',
    },
    {
      code: `

          // ...

      `,
    },
  ]),

  invalid: parsers.all([
    {
      code: `
        class Comp1 extends Component {
          render() {
            return (
// invalid
);
          }
        }
      `,
      features: ['no-ts-old'], // TODO: FIXME: remove this and figure out why the old TS parser hangs here
      errors: [{ messageId: 'putCommentInBraces' }],
    },
    {
      code: `
        class Comp1 extends Component {
          render() {
            return (<>// invalid</>);
          }
        }
      `,
      features: ['fragment', 'no-ts-old'], // TODO: FIXME: remove this and figure out why the old TS parser hangs here
      errors: [{ messageId: 'putCommentInBraces' }],
    },
    {
      code: `
        class Comp1 extends Component {
          render() {
            return (
/* invalid */
);
          }
        }
      `,
      features: ['no-ts-old'], // TODO: FIXME: remove this and figure out why the old TS parser hangs here
      errors: [{ messageId: 'putCommentInBraces' }],
    },
    {
      code: `
        class Comp1 extends Component {
          render() {
            return (

                // invalid

            );
          }
        }
      `,
      errors: [{ messageId: 'putCommentInBraces' }],
    },
    {
      code: `
        class Comp1 extends Component {
          render() {
            return (

                asdjfl
                /* invalid */
                foo

            );
          }
        }
      `,
      errors: [{ messageId: 'putCommentInBraces' }],
    },
    {
      code: `
        class Comp1 extends Component {
          render() {
            return (

                {'asdjfl'}
                // invalid
                {'foo'}

            );
          }
        }
      `,
      errors: [{ messageId: 'putCommentInBraces' }],
    },
    {
      code: `
        const Component2 = () => {
          return /*;
        };
      `,
      features: ['no-ts-old'], // TODO: FIXME: remove this and figure out why the old TS parser hangs here
      errors: [{ messageId: 'putCommentInBraces' }],
    },
  ]),
});
<|endoftext|>


<commit_before>/**
 * Parses an SMD and provides methods to read information from it for working with RESTful services.
 * Uses the format defined by Kris Zyp and utilized by Dojo for RPC stores
 */
define([
    "./declare",
    "./ServiceDescriptorReader",
    "./log",
    "./util",
    "./AmdResolver"
], function (
    declare,
    ServiceDescriptorReader,
    logger,
    Util,
    AmdResolver
) {

    var util = new Util(),
        module = declare(ServiceDescriptorReader, {
            /**
             * Constructor requires a JSONSchema-compliant SMD file in Zyp format.
             */
            constructor: function (schema, refResolver) {

                logger.debug("Creating reader for schema", schema);

                if (!refResolver) {
                    refResolver = new AmdResolver({path: "", altSeparator: "\\.", synchronous: true}).resolver;
                }

                this.smd = schema;

                //finds all $ref instances and replaces with the actual object
                //similar to dojox.json.ref.resolveJson, but doesn't get hung up on circular references
                //TODO: should we assume all schemas have been resolved prior, and remove this step?
                function resolveRef(subobj, parent, parentKey) {
                    if (!subobj.resolved) {
                        Object.keys(subobj).forEach(function (key) {
                            var Ref, value = subobj[key];
                            if (key === "$ref") {
                                logger.debug("Resolving $ref: " + value);
                                Ref = refResolver(value);
                                value = typeof Ref === 'function' ? new Ref() : Ref;
                                if (!util.isUndefined(value) && !value.resolved) {
                                    subobj.resolved = true;
                                    resolveRef(value, subobj, key);
                                }
                                parent[parentKey] = value;
                            } else if (typeof value === "object") {
                                resolveRef(value, subobj, key);
                            }
                        });
                    }
                }

                function getExtendedProperties(obj, props) {
                    var parent = (obj && obj["extends"]), propsObj = [], items = [], itemProps;

                    if (typeof parent !== "undefined") {

                        items = util.isArray(parent) ? parent : [parent]; //can be multiple-inheritance

                        items.forEach(function (item) {
                            itemProps = item.properties || {};
                            Object.keys(itemProps).forEach(function (key) {
                                var value = item.properties[key];
                                if (key !== "__parent") {
                                    propsObj.push({
                                        parentId: item.id,
                                        key: key,
                                        value: value
                                    });
                                }
                            });

                        }, this);

                        props.push(propsObj);
                        props = getExtendedProperties(parent, props);
                    }

                    return props;

                }

                //looks in JSONSchema objects for "extends" and copies properties to children
            function resolveExtensions(schema) {

                var xprops, props;

                xprops = getExtendedProperties(schema, []);

                //unwind the property stack so that the earliest gets inheritance link
                schema.properties = schema.properties || {};
                function copyprop(item) { //util to get around jslint complaints about doing this directly in loop
                    schema.properties[item.key] = item.value;
                }

                while (xprops.length > 0) {
                    props = xprops.pop();
                    props.forEach(copyprop);
                }
            }

            // mix-in parameters for extended schemas
            function resolveExtendedParameters(obj) {

                // assume all references are resolved, just copy parameters down the
                // inheritence chain. If I am derived check base first.
                if (obj["extends"]) {
                    resolveExtendedParameters(obj["extends"]);
                    obj.parameters = obj.parameters || [];
                    obj.parameters = obj.parameters.concat(obj["extends"].parameters);
                }
            }

            //copies properties from parent as defaults, as well as extensions for params
            function resolveProperties(schema) {

                logger.debug("Resolving sub-properties for " + schema.id);

                // resolve inherited global parameters
                resolveExtendedParameters(schema);

                Object.keys(schema.services || {}).forEach(function (key) {
                    var value = schema.services[key];
                    //value.target = value.target ? schema.target + value.target : schema.target; //TODO: should this build concat paths? that is currently handled in getServiceUrl function
                    value.returns = value.returns || schema.returns;
                    value.transport = value.transport || schema.transport;
                    value.contentType = value.contentType || schema.contentType;
                    value.envelope = value.envelope || schema.envelope || "URL";
                    value.description = value.description || "";

                    if (value.returns) {
                        resolveExtensions(value.returns);
                    }

                    if (value.parameters) {
                        value.parameters.forEach(function (item) {
                            item.envelope = item.envelope || value.envelope;
                            item.description = item.description || "";
                        });
                    }

                    var ext = value["extends"];

                    if (ext) {

                        //resolution hasn't been completed or extends object isn't proper JSONSchema
                        if (!ext.id) {
                            throw new Error("Parent schema for method [" + key + "] in schema " + schema.id + " is invalid.");
                        }

                        //TODO: resolveExtensions for params object properties? not really needed yet (the name is fine for now...)
                        if (!value.parameters) {
                            value.parameters = ext.parameters;
                        } else {
                            value.parameters = value.parameters.concat(ext.parameters);
                        }
                    }
                });

            }

            //if a schema has already been resolved, don't do it again - we can get into endless recursion
            if (!schema.resolved) {
                resolveRef(schema, null, null);
                schema.resolved = true;
            }

            //only resolve these once, or else our concats will be a problem
            if (!schema.resolvedProperties) {
                resolveProperties(schema);
                schema.resolvedProperties = true;
            }

            var hash = {};

            //index params array by name for lookup
            hash.parameters = {};
            this.getMethodNames().forEach(function (methodName) {
                var service = this.smd.services[methodName];
                if (service.parameters) {
                    service.parameters.forEach(function (parameter) {
                        hash[methodName + "-" + parameter.name] = parameter;
                    });
                }
            }, this);

            this.findParameter = function (methodName, parameterName) {
                return hash[methodName + "-" + parameterName];
            };

        },

        /**
         * Returns the identifier of the schema this reader operates on.
         */
        getSchemaId: function () {
            return this.smd.id; //TODO: the property name here can be configurable, we may want to support that.
        },

        /**
         * Gets the root target property for the service.
         */
        getRootPath: function () {
            return this.smd.target;
        },

        /**
         * Gets the jsonp callback property for the service.
         */
        getJsonpCallbackParameter: function () {
            return this.smd.jsonpCallbackParameter;
        },

        /**
         * Gets the transport property for the service.
         */
        getTransport: function () {
            return this.smd.transport;
        },

        /**
         * Gets a list of the service method names defined by the SMD.
         */
        getMethodNames: function () {
            var names = [];

            Object.keys(this.smd.services || {}).forEach(function (serviceName) {
                names.push(serviceName);
            });

            return names;
        },

        /**
         * Gets list of service methods in the SMD. These are the actual schema objects.
         */
        getMethods: function () {
            var services = [], smdServices = this.smd.services;

            Object.keys(smdServices || []).forEach(function (serviceName) {
                services.push(smdServices[serviceName]);
            });

            return services;
        },

        /**
         * Gets a specific service method object by name.
         * TODO: exception if service doesn't exist
         */
        getMethod: function (methodName) {
            var method = this.smd.services[methodName];
            if (!method) {
                throw new Error("no such method");
            }
            return method;
        },

        /**
         * Gets a list of parameter names for a specified service.
         */
        getParameterNames: function (methodName) {
            var names = [], params = this.getParameters(methodName);

            params.forEach(function (param) {
                names.push(param.name);
            });

            return names;
        },

        /**
         * Gets a list of parameters for a specified service. These are the actual objects.
         */
        getParameters: function (methodName) {
            var parameters = this.smd.parameters || [];

            parameters = parameters.concat(this.smd.services[methodName].parameters || []);

            return parameters;
        },

        /**
         * Indicates whether the specified argument on a service method is required or not.
         */
        isArgumentRequired: function (methodName, argName) {
            var required = this.findParameter(methodName, argName).required;
            //default is false, so if "required" is undefined, return false anyway
            if (required) {
                return true;
            }
            return false;
        },

        /**
         * For the specified service, map the args object to the target + parameters to
         * get a full, functional URL.
         */
        getServiceUrl: function (methodName, args) {

            var service = this.smd.services[methodName],
                basePath = this.getRootPath(),
                url,
                parameters = this.enumerateParameters(service);

            //if no service target, it sits at the root
            url = basePath + (service.target ? "/" + service.target : "");

            //replace path params where required
            url = this.replacePathParamsInUrl(url, parameters.PATH, args);

            //add any query params
            url = this.addQueryParamsToUrl(url, parameters.URL, args);

            return url;

        },

        getMethodTransport: function (methodName) {
            return this.smd.services[methodName].transport;
        },

        getAndValidateArgument: function (param, args) {
            args = args || {};
            var arg = typeof args[param.name] !== "undefined" ? args[param.name] : param.default;

            if (typeof arg === "undefined" && (param.required === true || param.optional === false)) {
                throw new Error("Missing required param for service call: " + param.name);
            }

            return arg;
        },

        replacePathParamsInUrl: function (url, params, args) {

            var index, length, param, arg;

            for (index = 0, length = params.length; index < length; index += 1) {

                param = params[index];
                arg = this.getAndValidateArgument(param, args);

                if (typeof arg !== "undefined") {
                    url = url.replace("{" + param.name + "}", encodeURIComponent(arg));
                }
            }

            return url;

        },

        addQueryParamsToUrl: function (url, params, args) {

            var index, length, queryString = "", param, arg, substring, firstParam = true;

            for (index = 0, length = params.length; index < length; index += 1) {

                param = params[index];
                arg = this.getAndValidateArgument(param, args);

                if (typeof arg !== "undefined") {

                    substring = param.name + "=" + encodeURIComponent(arg);

                    if (firstParam) {
                        firstParam = false;
                        queryString += "?" + substring;
                    } else {
                        queryString += "&" + substring;
                    }

                }
            }

            url += queryString;

            return url;

        },

        /**
         * Returns the param list mapped by envelope (URL, PATH, ENTITY)
         */
        enumerateParameters: function (service) {

            var index, length, parameters = this.smd.parameters, param,
                svcParameters = service.parameters || [],
                params = {
                    PATH: [], //args in URL path
                    URL: [], //args in query string
                    JSON: [], //JSON in POST/PUT body
                    ENTITY: [] //custom POST/PUT entity body (e.g., multi-part)
                };

            parameters = parameters ? parameters.concat(svcParameters) : svcParameters;

            if (parameters) {
                for (index = 0, length = parameters.length; index < length; index += 1) {
                    param = parameters[index];
                    params[param.envelope].push(param);
                }
            }

            return params;

        },

        /**
         * Returns the schema associted with the service method's response.
         * @param methodName - the service method to return a schema for.
         * @return the response schema
         */
        getResponseSchema: function (methodName) {
            return this.smd.services[methodName].returns;
        },

        /**
         * Returns the parameter associated with the payload of a request if there is one.
         * @param methodName - the service method to return a payload schema for.
         * @return the payload parameter or undefined
         */
        getRequestPayloadParam: function (methodName) {
            var params = this.getParameters(methodName),
                ret;
            params.forEach(function (param) {
                if (param && (param.envelope === 'JSON' ||
                        param.envelope === 'ENTITY')) {
                    ret = param;
                }
            });
            return ret;
        },

        /**
         * Returns the schema associated with the payload of a request if there is one.
         * @param methodName - the service method to return a payload schema for.
         * @return a model schema or undefined if there is no payload.
         */
        getRequestSchema: function (methodName) {
            var param = this.getRequestPayloadParam(methodName),
                ret = param && param.type;
            return ret;
        },

        /**
         * Returns the name of the primary payload object.
         * @param methodName - the service method to return a payload schema for.
         * If the "payload" field is not defined on the method, check the service root.
         */
        getResponsePayloadName: function (methodName) {

            var smd = this.smd,
                method = smd.services[methodName],
                payloadName = (method && method.payload) || smd.payload;

            return payloadName;
        },

        /**
         * Returns the name of the primary payload object.
         * @param methodName - the service method to return a payload schema for.
         */
        getRequestPayloadName: function (methodName) {

            var param = this.getRequestPayloadParam(methodName),
                payloadName = param && param.payload;

            return payloadName;
        },

        /**
         * Returns whether the primary payload is a list, by checking for "array" type on the SMD.
         * Defaults to false if return type is JSONSchema "null" primitive type.
         */
        isListResponse: function (methodName) {
            var response = this.getResponseSchema(methodName),
                payloadName = this.getResponsePayloadName(methodName),
                isList = false;

            if (response.type !== "null") {
                if ((payloadName && response.properties[payloadName] && response.properties[payloadName].type === "array") ||
                        (response.type && response.type === "array")) {
                    isList = true;
                }
            }

            return isList;
        }

    });

    return module;
});<commit_msg>fixed use of reserved word "default"<commit_after>/**
 * Parses an SMD and provides methods to read information from it for working with RESTful services.
 * Uses the format defined by Kris Zyp and utilized by Dojo for RPC stores
 */
define([
    "./declare",
    "./ServiceDescriptorReader",
    "./log",
    "./util",
    "./AmdResolver"
], function (
    declare,
    ServiceDescriptorReader,
    logger,
    Util,
    AmdResolver
) {

    var util = new Util(),
        module = declare(ServiceDescriptorReader, {
            /**
             * Constructor requires a JSONSchema-compliant SMD file in Zyp format.
             */
            constructor: function (schema, refResolver) {

                logger.debug("Creating reader for schema", schema);

                if (!refResolver) {
                    refResolver = new AmdResolver({path: "", altSeparator: "\\.", synchronous: true}).resolver;
                }

                this.smd = schema;

                //finds all $ref instances and replaces with the actual object
                //similar to dojox.json.ref.resolveJson, but doesn't get hung up on circular references
                //TODO: should we assume all schemas have been resolved prior, and remove this step?
                function resolveRef(subobj, parent, parentKey) {
                    if (!subobj.resolved) {
                        Object.keys(subobj).forEach(function (key) {
                            var Ref, value = subobj[key];
                            if (key === "$ref") {
                                logger.debug("Resolving $ref: " + value);
                                Ref = refResolver(value);
                                value = typeof Ref === 'function' ? new Ref() : Ref;
                                if (!util.isUndefined(value) && !value.resolved) {
                                    subobj.resolved = true;
                                    resolveRef(value, subobj, key);
                                }
                                parent[parentKey] = value;
                            } else if (typeof value === "object") {
                                resolveRef(value, subobj, key);
                            }
                        });
                    }
                }

                function getExtendedProperties(obj, props) {
                    var parent = (obj && obj["extends"]), propsObj = [], items = [], itemProps;

                    if (typeof parent !== "undefined") {

                        items = util.isArray(parent) ? parent : [parent]; //can be multiple-inheritance

                        items.forEach(function (item) {
                            itemProps = item.properties || {};
                            Object.keys(itemProps).forEach(function (key) {
                                var value = item.properties[key];
                                if (key !== "__parent") {
                                    propsObj.push({
                                        parentId: item.id,
                                        key: key,
                                        value: value
                                    });
                                }
                            });

                        }, this);

                        props.push(propsObj);
                        props = getExtendedProperties(parent, props);
                    }

                    return props;

                }

                //looks in JSONSchema objects for "extends" and copies properties to children
            function resolveExtensions(schema) {

                var xprops, props;

                xprops = getExtendedProperties(schema, []);

                //unwind the property stack so that the earliest gets inheritance link
                schema.properties = schema.properties || {};
                function copyprop(item) { //util to get around jslint complaints about doing this directly in loop
                    schema.properties[item.key] = item.value;
                }

                while (xprops.length > 0) {
                    props = xprops.pop();
                    props.forEach(copyprop);
                }
            }

            // mix-in parameters for extended schemas
            function resolveExtendedParameters(obj) {

                // assume all references are resolved, just copy parameters down the
                // inheritence chain. If I am derived check base first.
                if (obj["extends"]) {
                    resolveExtendedParameters(obj["extends"]);
                    obj.parameters = obj.parameters || [];
                    obj.parameters = obj.parameters.concat(obj["extends"].parameters);
                }
            }

            //copies properties from parent as defaults, as well as extensions for params
            function resolveProperties(schema) {

                logger.debug("Resolving sub-properties for " + schema.id);

                // resolve inherited global parameters
                resolveExtendedParameters(schema);

                Object.keys(schema.services || {}).forEach(function (key) {
                    var value = schema.services[key];
                    //value.target = value.target ? schema.target + value.target : schema.target; //TODO: should this build concat paths? that is currently handled in getServiceUrl function
                    value.returns = value.returns || schema.returns;
                    value.transport = value.transport || schema.transport;
                    value.contentType = value.contentType || schema.contentType;
                    value.envelope = value.envelope || schema.envelope || "URL";
                    value.description = value.description || "";

                    if (value.returns) {
                        resolveExtensions(value.returns);
                    }

                    if (value.parameters) {
                        value.parameters.forEach(function (item) {
                            item.envelope = item.envelope || value.envelope;
                            item.description = item.description || "";
                        });
                    }

                    var ext = value["extends"];

                    if (ext) {

                        //resolution hasn't been completed or extends object isn't proper JSONSchema
                        if (!ext.id) {
                            throw new Error("Parent schema for method [" + key + "] in schema " + schema.id + " is invalid.");
                        }

                        //TODO: resolveExtensions for params object properties? not really needed yet (the name is fine for now...)
                        if (!value.parameters) {
                            value.parameters = ext.parameters;
                        } else {
                            value.parameters = value.parameters.concat(ext.parameters);
                        }
                    }
                });

            }

            //if a schema has already been resolved, don't do it again - we can get into endless recursion
            if (!schema.resolved) {
                resolveRef(schema, null, null);
                schema.resolved = true;
            }

            //only resolve these once, or else our concats will be a problem
            if (!schema.resolvedProperties) {
                resolveProperties(schema);
                schema.resolvedProperties = true;
            }

            var hash = {};

            //index params array by name for lookup
            hash.parameters = {};
            this.getMethodNames().forEach(function (methodName) {
                var service = this.smd.services[methodName];
                if (service.parameters) {
                    service.parameters.forEach(function (parameter) {
                        hash[methodName + "-" + parameter.name] = parameter;
                    });
                }
            }, this);

            this.findParameter = function (methodName, parameterName) {
                return hash[methodName + "-" + parameterName];
            };

        },

        /**
         * Returns the identifier of the schema this reader operates on.
         */
        getSchemaId: function () {
            return this.smd.id; //TODO: the property name here can be configurable, we may want to support that.
        },

        /**
         * Gets the root target property for the service.
         */
        getRootPath: function () {
            return this.smd.target;
        },

        /**
         * Gets the jsonp callback property for the service.
         */
        getJsonpCallbackParameter: function () {
            return this.smd.jsonpCallbackParameter;
        },

        /**
         * Gets the transport property for the service.
         */
        getTransport: function () {
            return this.smd.transport;
        },

        /**
         * Gets a list of the service method names defined by the SMD.
         */
        getMethodNames: function () {
            var names = [];

            Object.keys(this.smd.services || {}).forEach(function (serviceName) {
                names.push(serviceName);
            });

            return names;
        },

        /**
         * Gets list of service methods in the SMD. These are the actual schema objects.
         */
        getMethods: function () {
            var services = [], smdServices = this.smd.services;

            Object.keys(smdServices || []).forEach(function (serviceName) {
                services.push(smdServices[serviceName]);
            });

            return services;
        },

        /**
         * Gets a specific service method object by name.
         * TODO: exception if service doesn't exist
         */
        getMethod: function (methodName) {
            var method = this.smd.services[methodName];
            if (!method) {
                throw new Error("no such method");
            }
            return method;
        },

        /**
         * Gets a list of parameter names for a specified service.
         */
        getParameterNames: function (methodName) {
            var names = [], params = this.getParameters(methodName);

            params.forEach(function (param) {
                names.push(param.name);
            });

            return names;
        },

        /**
         * Gets a list of parameters for a specified service. These are the actual objects.
         */
        getParameters: function (methodName) {
            var parameters = this.smd.parameters || [];

            parameters = parameters.concat(this.smd.services[methodName].parameters || []);

            return parameters;
        },

        /**
         * Indicates whether the specified argument on a service method is required or not.
         */
        isArgumentRequired: function (methodName, argName) {
            var required = this.findParameter(methodName, argName).required;
            //default is false, so if "required" is undefined, return false anyway
            if (required) {
                return true;
            }
            return false;
        },

        /**
         * For the specified service, map the args object to the target + parameters to
         * get a full, functional URL.
         */
        getServiceUrl: function (methodName, args) {

            var service = this.smd.services[methodName],
                basePath = this.getRootPath(),
                url,
                parameters = this.enumerateParameters(service);

            //if no service target, it sits at the root
            url = basePath + (service.target ? "/" + service.target : "");

            //replace path params where required
            url = this.replacePathParamsInUrl(url, parameters.PATH, args);

            //add any query params
            url = this.addQueryParamsToUrl(url, parameters.URL, args);

            return url;

        },

        getMethodTransport: function (methodName) {
            return this.smd.services[methodName].transport;
        },

        getAndValidateArgument: function (param, args) {
            args = args || {};
            var arg = typeof args[param.name] !== "undefined" ? args[param.name] : param["default"];

            if (typeof arg === "undefined" && (param.required === true || param.optional === false)) {
                throw new Error("Missing required param for service call: " + param.name);
            }

            return arg;
        },

        replacePathParamsInUrl: function (url, params, args) {

            var index, length, param, arg;

            for (index = 0, length = params.length; index < length; index += 1) {

                param = params[index];
                arg = this.getAndValidateArgument(param, args);

                if (typeof arg !== "undefined") {
                    url = url.replace("{" + param.name + "}", encodeURIComponent(arg));
                }
            }

            return url;

        },

        addQueryParamsToUrl: function (url, params, args) {

            var index, length, queryString = "", param, arg, substring, firstParam = true;

            for (index = 0, length = params.length; index < length; index += 1) {

                param = params[index];
                arg = this.getAndValidateArgument(param, args);

                if (typeof arg !== "undefined") {

                    substring = param.name + "=" + encodeURIComponent(arg);

                    if (firstParam) {
                        firstParam = false;
                        queryString += "?" + substring;
                    } else {
                        queryString += "&" + substring;
                    }

                }
            }

            url += queryString;

            return url;

        },

        /**
         * Returns the param list mapped by envelope (URL, PATH, ENTITY)
         */
        enumerateParameters: function (service) {

            var index, length, parameters = this.smd.parameters, param,
                svcParameters = service.parameters || [],
                params = {
                    PATH: [], //args in URL path
                    URL: [], //args in query string
                    JSON: [], //JSON in POST/PUT body
                    ENTITY: [] //custom POST/PUT entity body (e.g., multi-part)
                };

            parameters = parameters ? parameters.concat(svcParameters) : svcParameters;

            if (parameters) {
                for (index = 0, length = parameters.length; index < length; index += 1) {
                    param = parameters[index];
                    params[param.envelope].push(param);
                }
            }

            return params;

        },

        /**
         * Returns the schema associted with the service method's response.
         * @param methodName - the service method to return a schema for.
         * @return the response schema
         */
        getResponseSchema: function (methodName) {
            return this.smd.services[methodName].returns;
        },

        /**
         * Returns the parameter associated with the payload of a request if there is one.
         * @param methodName - the service method to return a payload schema for.
         * @return the payload parameter or undefined
         */
        getRequestPayloadParam: function (methodName) {
            var params = this.getParameters(methodName),
                ret;
            params.forEach(function (param) {
                if (param && (param.envelope === 'JSON' ||
                        param.envelope === 'ENTITY')) {
                    ret = param;
                }
            });
            return ret;
        },

        /**
         * Returns the schema associated with the payload of a request if there is one.
         * @param methodName - the service method to return a payload schema for.
         * @return a model schema or undefined if there is no payload.
         */
        getRequestSchema: function (methodName) {
            var param = this.getRequestPayloadParam(methodName),
                ret = param && param.type;
            return ret;
        },

        /**
         * Returns the name of the primary payload object.
         * @param methodName - the service method to return a payload schema for.
         * If the "payload" field is not defined on the method, check the service root.
         */
        getResponsePayloadName: function (methodName) {

            var smd = this.smd,
                method = smd.services[methodName],
                payloadName = (method && method.payload) || smd.payload;

            return payloadName;
        },

        /**
         * Returns the name of the primary payload object.
         * @param methodName - the service method to return a payload schema for.
         */
        getRequestPayloadName: function (methodName) {

            var param = this.getRequestPayloadParam(methodName),
                payloadName = param && param.payload;

            return payloadName;
        },

        /**
         * Returns whether the primary payload is a list, by checking for "array" type on the SMD.
         * Defaults to false if return type is JSONSchema "null" primitive type.
         */
        isListResponse: function (methodName) {
            var response = this.getResponseSchema(methodName),
                payloadName = this.getResponsePayloadName(methodName),
                isList = false;

            if (response.type !== "null") {
                if ((payloadName && response.properties[payloadName] && response.properties[payloadName].type === "array") ||
                        (response.type && response.type === "array")) {
                    isList = true;
                }
            }

            return isList;
        }

    });

    return module;
});<|endoftext|>


<commit_before>var cradle = require('cradle')
  , root = this
  , couchDbStorage
  , Storage;

if (typeof exports !== 'undefined') {
    couchDbStorage = exports;
} else {
    couchDbStorage = root.couchDbStorage = {};
}

couchDbStorage.VERSION = '0.0.1';

// Create new instance of storage.
couchDbStorage.createStorage = function(options, callback) {
    new Storage(options, callback);
};

/*******************************************
* Storage
*/
Storage = function(options, callback) {
    if (typeof options === 'function')
        callback = options;

    var defaults = {
        host: 'localhost',
        port: 5984,
        dbName: 'eventstore',
        eventsCollectionName: 'events',
        snapshotsCollectionName: 'snapshots'
    };

    this.options = mergeOptions(options, defaults);

    this.store = new(cradle.Connection)();
    this.client = this.store.database(this.options.dbName);
    this.client.exists(function(err, res) {
    	if (err) {
			callback(err);
		}
		else if (res === false) {
            this.client.create(function(err) {
                if (err) {
                    callback(err);
                }
                else {
                    this.client.save('_design/'+this.options.dbName, {
                        byStreamId: {
                            map: function (evt) {
                                if (evt.snapshotId == null) {
                                    emit(evt.streamId, evt);
                                }
                            }
                        },
                        allUndispatched: {
                            map: function (evt) {
                                if (evt.snapshotId == null && evt.dispatched === false) {
                                    emit(evt._id, evt);
                                }
                            }
                        },
                        snapshotsByStreamId: {
                            map: function (snapshot) {
                                if (snapshot.snapshotId != null) {
                                    emit(snapshot.streamId, snapshot);
                                }
                            }
                        },
                        all: {
                            map: function (evt) {
                                emit(evt._id, evt);
                            }
                        }
                    });
                    callback(null, this);
                }
            }.bind(this));
        }
        else {
            callback(null, this);
        }
    }.bind(this));
};

Storage.prototype = {

    // This function saves an event in the storage.
    addEvents: function(events, callback) {
        for(var i in events) {
            events[i]._id = events[i].commitId;
        }
        this.client.save(events, callback);
    },

    // This function saves a snapshot in the storage.
    addSnapshot: function(snapshot, callback) {
        snapshot._id = snapshot.snapshotId;
        this.client.save(snapshot, callback);
    },

    // This function returns the wished events.
    getEvents: function(streamId, minRev, maxRev, callback) {
        this.client.view(this.options.dbName+'/byStreamId', { 'key': streamId },
            function(err, res) {
                if(!err) {
                    var result = [];
                    for (var i in res) {
        				result.push(res[i].value);
        			}
                    if (result.length === 0) {
                        callback(null, []);
                    } else {
                        if (maxRev === -1) {
                            callback(null, result.slice(minRev));
                        }
                        else {
                            callback(null, result.slice(minRev, maxRev));
                        }
                    }
                }
                else {
                    callback(err);
    			}
            }.bind(this));
    },

    // This function returns all events.
    getAllEvents: function(callback) {
        var logger = this.logger;
        this.client.view(this.options.dbName+'/all',
            function(err, res) {
                if(!err) {
                    var result = [];
                    for (var i in res) {
            			result.push(res[i].value);
        			}
                    if (result.length === 0) {
                        callback(null, []);
                    } else {
                        if (maxRev === -1) {
                            callback(null, result.slice(minRev));
                        }
                        else {
                            callback(null, result.slice(minRev, maxRev));
                        }
                    }
                }
                else {
    				callback(err);
    			}
            }.bind(this));
    },

    // This function returns the wished snapshot.
    // If revMax is -1 returns the latest snapshot.
    getSnapshot: function(streamId, maxRev, callback) {
        var logger = this.logger;
        this.client.view(this.options.dbName+'/snapshotsByStreamId', { 'key': streamId },
            function(err, res) {
                if(!err) {
                    var result = [];
                	for (var i in res) {
        				result.push(res[i].value);
        			}
                    if (result.length === 0) {
                        callback(null);
                    } else {
                        if (maxRev === -1) {
                            callback(null, result[result.length-1]);
                        }
                        else {
                            callback(null, result[maxRev]);
                        }
                    }
                }
                else {
        			callback(err);
    			}
            }.bind(this));
    },

    // This function returns all undispatched events.
    getUndispatchedEvents: function(callback) {
        var logger = this.logger;
        this.client.view(this.options.dbName+'/allUndispatched', function(err, res) {
        	if (err) {
    			callback(err);
    		}
    		else {
    			var result = [];
    			for (var i in res) {
    				result.push(res[i].value);
    			}
    			callback(null, result);
    		}
        });
    },

    // This function set an event to dispatched.
    setEventToDispatched: function(event, callback) {
        var logger = this.logger;
        this.client.merge(evt.commitId, {'dispatched': true}, function(err, res) {
            if (err) {
                callback(err);
            }
        });
    },

    // This function returns a new id.
    getId: function(callback) {
        var logger = this.logger;
        this.store.uuids(function(err, uuids) {
            if (err) {
        		callback(err);
    		}
    		else {
                if (typeof callback === 'function') {
                    callback(null, uuids.toString());
                }
            }
        });
    }
}

// helper
var mergeOptions = function(options, defaultOptions) {
    if (!options || typeof options === 'function') {
        return defaultOptions;
    }

    var merged = {};
    for (var attrname in defaultOptions) { merged[attrname] = defaultOptions[attrname]; }
    for (var attrname in options) { if (options[attrname]) merged[attrname] = options[attrname]; }
    return merged;
};
<commit_msg>no log in storage return error<commit_after>var cradle = require('cradle')
  , root = this
  , couchDbStorage
  , Storage;

if (typeof exports !== 'undefined') {
    couchDbStorage = exports;
} else {
    couchDbStorage = root.couchDbStorage = {};
}

couchDbStorage.VERSION = '0.0.1';

// Create new instance of storage.
couchDbStorage.createStorage = function(options, callback) {
    new Storage(options, callback);
};

/*******************************************
* Storage
*/
Storage = function(options, callback) {
    if (typeof options === 'function')
        callback = options;

    var defaults = {
        host: 'localhost',
        port: 5984,
        dbName: 'eventstore',
        eventsCollectionName: 'events',
        snapshotsCollectionName: 'snapshots'
    };

    this.options = mergeOptions(options, defaults);

    this.store = new(cradle.Connection)();
    this.client = this.store.database(this.options.dbName);
    this.client.exists(function(err, res) {
    	if (err) {
			callback(err);
		}
		else if (res === false) {
            this.client.create(function(err) {
                if (err) {
                    callback(err);
                }
                else {
                    this.client.save('_design/'+this.options.dbName, {
                        byStreamId: {
                            map: function (evt) {
                                if (evt.snapshotId == null) {
                                    emit(evt.streamId, evt);
                                }
                            }
                        },
                        allUndispatched: {
                            map: function (evt) {
                                if (evt.snapshotId == null && evt.dispatched === false) {
                                    emit(evt._id, evt);
                                }
                            }
                        },
                        snapshotsByStreamId: {
                            map: function (snapshot) {
                                if (snapshot.snapshotId != null) {
                                    emit(snapshot.streamId, snapshot);
                                }
                            }
                        },
                        all: {
                            map: function (evt) {
                                emit(evt._id, evt);
                            }
                        }
                    });
                    callback(null, this);
                }
            }.bind(this));
        }
        else {
            callback(null, this);
        }
    }.bind(this));
};

Storage.prototype = {

    // This function saves an event in the storage.
    addEvents: function(events, callback) {
        for(var i in events) {
            events[i]._id = events[i].commitId;
        }
        this.client.save(events, callback);
    },

    // This function saves a snapshot in the storage.
    addSnapshot: function(snapshot, callback) {
        snapshot._id = snapshot.snapshotId;
        this.client.save(snapshot, callback);
    },

    // This function returns the wished events.
    getEvents: function(streamId, minRev, maxRev, callback) {
        this.client.view(this.options.dbName+'/byStreamId', { 'key': streamId },
            function(err, res) {
                if(!err) {
                    var result = [];
                    for (var i in res) {
        				result.push(res[i].value);
        			}
                    if (result.length === 0) {
                        callback(null, []);
                    } else {
                        if (maxRev === -1) {
                            callback(null, result.slice(minRev));
                        }
                        else {
                            callback(null, result.slice(minRev, maxRev));
                        }
                    }
                }
                else {
                    callback(err);
    			}
            }.bind(this));
    },

    // This function returns all events.
    getAllEvents: function(callback) {
        this.client.view(this.options.dbName+'/all',
            function(err, res) {
                if(!err) {
                    var result = [];
                    for (var i in res) {
            			result.push(res[i].value);
        			}
                    if (result.length === 0) {
                        callback(null, []);
                    } else {
                        if (maxRev === -1) {
                            callback(null, result.slice(minRev));
                        }
                        else {
                            callback(null, result.slice(minRev, maxRev));
                        }
                    }
                }
                else {
    				callback(err);
    			}
            }.bind(this));
    },

    // This function returns the wished snapshot.
    // If revMax is -1 returns the latest snapshot.
    getSnapshot: function(streamId, maxRev, callback) {
        this.client.view(this.options.dbName+'/snapshotsByStreamId', { 'key': streamId },
            function(err, res) {
                if(!err) {
                    var result = [];
                	for (var i in res) {
        				result.push(res[i].value);
        			}
                    if (result.length === 0) {
                        callback(null);
                    } else {
                        if (maxRev === -1) {
                            callback(null, result[result.length-1]);
                        }
                        else {
                            callback(null, result[maxRev]);
                        }
                    }
                }
                else {
        			callback(err);
    			}
            }.bind(this));
    },

    // This function returns all undispatched events.
    getUndispatchedEvents: function(callback) {
        this.client.view(this.options.dbName+'/allUndispatched', function(err, res) {
        	if (err) {
    			callback(err);
    		}
    		else {
    			var result = [];
    			for (var i in res) {
    				result.push(res[i].value);
    			}
    			callback(null, result);
    		}
        });
    },

    // This function set an event to dispatched.
    setEventToDispatched: function(event, callback) {
        this.client.merge(evt.commitId, {'dispatched': true}, function(err, res) {
            if (err) {
                callback(err);
            }
        });
    },

    // This function returns a new id.
    getId: function(callback) {
        this.store.uuids(function(err, uuids) {
            if (err) {
        		callback(err);
    		}
    		else {
                if (typeof callback === 'function') {
                    callback(null, uuids.toString());
                }
            }
        });
    }
}

// helper
var mergeOptions = function(options, defaultOptions) {
    if (!options || typeof options === 'function') {
        return defaultOptions;
    }

    var merged = {};
    for (var attrname in defaultOptions) { merged[attrname] = defaultOptions[attrname]; }
    for (var attrname in options) { if (options[attrname]) merged[attrname] = options[attrname]; }
    return merged;
};
<|endoftext|>


<commit_before>import { Transition } from './automaton'
import NFAe from './nfa-e'
import { epsilon, stackConst } from '../constants'
import { UnknownCharError, UnknownStateError,
         DuplicateTransitionError, InvalidPDATransition,
         NoInitialStateError } from '../errors'

export default class PDA extends NFAe {
    addTransition(from, a, to) {
        const fs   = this.getState(from)
		const ts   = this.getState(to)
        const data = this.parseTransitionData(a)

		if (!fs)
			throw new UnknownStateError(from)
		if (!ts)
			throw new UnknownStateError(to)
		if (!this.charInAlphabet(data.input))
			throw new UnknownCharError(data.input)
        if (this.stateHasTransition(from, a, to))
            throw new DuplicateTransitionError({ from, a, to })
        if (data.push)
            data.pushValues.map(pv => {
                if (pv !== stackConst && !this.charInAlphabet(pv))
                    throw new UnknownCharError(pv)
            })

		this.states = this.states.map(e => {
			if (e.name === from)
				e.transitions = [ ...e.transitions, new Transition(from, a, to) ]
			return e
		})
    }
    parseTransitionData(str) {
        const [ first, last ] = str.split('/')
        const [ input, popValue ] = first.split(',')
        const pushValues = last.split(',').reverse()
        const push = pushValues.indexOf(epsilon) < 0

        if (!input || !popValue || !pushValues)
            throw new InvalidPDATransition(str)

        return { input, popValue, pushValues, push }
    }
    getInitRunSnaps(w) {
        const initSnap = { state: this.getInitialState(), w, stack: [ stackConst ] }
        const epsilonSnaps = this.getSnapsFor([initSnap], epsilon)
        return [ initSnap, ...epsilonSnaps ]
    }
    getSnapsFor(snaps, symbol) {
        let toSnaps = snaps.reduce((accum, snap) => {
            const newSnaps = snap.state.transitions
                .filter(t => this.transitionMatches(t.a, symbol, snap.stack))
                    .map(t => this.newSnap(t.to, snap, t.a))
            return [ ...accum, ...newSnaps ]
        }, [])

        toSnaps = toSnaps.reduce((accum, snap) =>
            [ ...accum, ...this.getESnapClosure(snap) ], toSnaps)

        return [ ...new Set(toSnaps) ]
    }
    modStack(stack, a) {
        let newStack = [ ...stack ]

        const { popValue, push, pushValues } = this.parseTransitionData(a)

        if (popValue !== epsilon)
            newStack.pop()

        if (push)
            pushValues.map(pv => newStack.push(pv))

        return newStack
    }
    transitionMatches(a, symbol, stack) {
        const data = this.parseTransitionData(a)
        return data.input === symbol && (data.popValue === epsilon || data.popValue === stack[stack.length - 1])
    }
    getETransitions(snap) {
        return snap.state.transitions
            .filter(t => this.transitionMatches(t.a, epsilon, snap.stack))
    }
    getESnaps(snap) {
        return this.getETransitions(snap).map(t => this.newSnap(t.to, snap, t.a))
    }
    getESnapClosure(snap) {
        return [ snap, ...this.getesnapclosure(snap) ]
    }
    getesnapclosure(snap) {
        let eSnaps = this.getESnaps(snap)

        for (const s of eSnaps)
            eSnaps = [ ...eSnaps, ...this.getesnapclosure(s) ]

        return eSnaps
    }
    newSnap(stateName, oldSnap, a) {
        return {
            state: this.getState(stateName),
            w: oldSnap.w.substr(1),
            stack: this.modStack(oldSnap.stack, a)
        }
    }
    run(w) {
        if (!this.initialState)
			throw new NoInitialStateError()

        let snaps = this.getInitRunSnaps(w)

        for (let a of w)
            if (!snaps.length)
                return false
            else
                snaps = this.getSnapsFor(snaps, a)

        return this.hasFinalState(snaps.map(s => s.state))
    }
    clone() {
        const a = new PDA([])
        a.setFromAutomaton(this)
        return a
    }
}<commit_msg>Override charInAlphabet validation for pda<commit_after>import { Transition } from './automaton'
import NFAe from './nfa-e'
import { epsilon, stackConst } from '../constants'
import { UnknownCharError, UnknownStateError,
         DuplicateTransitionError, InvalidPDATransition,
         NoInitialStateError } from '../errors'

export default class PDA extends NFAe {
    charInAlphabet(a) {
        const { input } = this.parseTransitionData(a)
        return input === epsilon ? true :
               this.alphabet.filter(e => e === input).length > 0
    }
    parseTransitionData(str) {
        const [ first, last ] = str.split('/')
        const [ input, popValue ] = first.split(',')
        const pushValues = last.split(',').reverse()
        const push = pushValues.indexOf(epsilon) < 0

        if (!input || !popValue || !pushValues)
            throw new InvalidPDATransition(str)

        return { input, popValue, pushValues, push }
    }
    getInitRunSnaps(w) {
        const initSnap = { state: this.getInitialState(), w, stack: [ stackConst ] }
        const epsilonSnaps = this.getSnapsFor([initSnap], epsilon)
        return [ initSnap, ...epsilonSnaps ]
    }
    getSnapsFor(snaps, symbol) {
        let toSnaps = snaps.reduce((accum, snap) => {
            const newSnaps = snap.state.transitions
                .filter(t => this.transitionMatches(t.a, symbol, snap.stack))
                    .map(t => this.newSnap(t.to, snap, t.a))
            return [ ...accum, ...newSnaps ]
        }, [])

        toSnaps = toSnaps.reduce((accum, snap) =>
            [ ...accum, ...this.getESnapClosure(snap) ], toSnaps)

        return [ ...new Set(toSnaps) ]
    }
    modStack(stack, a) {
        let newStack = [ ...stack ]

        const { popValue, push, pushValues } = this.parseTransitionData(a)

        if (popValue !== epsilon)
            newStack.pop()

        if (push)
            pushValues.map(pv => newStack.push(pv))

        return newStack
    }
    transitionMatches(a, symbol, stack) {
        const data = this.parseTransitionData(a)
        return data.input === symbol && (data.popValue === epsilon || data.popValue === stack[stack.length - 1])
    }
    getETransitions(snap) {
        return snap.state.transitions
            .filter(t => this.transitionMatches(t.a, epsilon, snap.stack))
    }
    getESnaps(snap) {
        return this.getETransitions(snap).map(t => this.newSnap(t.to, snap, t.a))
    }
    getESnapClosure(snap) {
        return [ snap, ...this.getesnapclosure(snap) ]
    }
    getesnapclosure(snap) {
        let eSnaps = this.getESnaps(snap)

        for (const s of eSnaps)
            eSnaps = [ ...eSnaps, ...this.getesnapclosure(s) ]

        return eSnaps
    }
    newSnap(stateName, oldSnap, a) {
        return {
            state: this.getState(stateName),
            w: oldSnap.w.substr(1),
            stack: this.modStack(oldSnap.stack, a)
        }
    }
    run(w) {
        if (!this.initialState)
			throw new NoInitialStateError()

        let snaps = this.getInitRunSnaps(w)

        for (let a of w)
            if (!snaps.length)
                return false
            else
                snaps = this.getSnapsFor(snaps, a)

        return this.hasFinalState(snaps.map(s => s.state))
    }
    clone() {
        const a = new PDA([])
        a.setFromAutomaton(this)
        return a
    }
}<|endoftext|>


<commit_before>import Historian from 'historian';

describe('historian', () => {
    let lastVisitTime, historian;

    beforeEach(() => {
        jasmine.clock().mockDate(new Date(1993, 9, 26));

        Historian.__set__({
            browser: {
                setToStorage: ({key, value}) => {
                    if (key === 'lastVisitTime')
                        lastVisitTime = value;
                },
                getFromStorage: (key) => {
                    if (key === 'lastVisitTime')
                        return lastVisitTime;
                },
                searchFromHistory: (query, lastVisitTime, callback) => {
                    if (query === 'http://southpark.cc.com/full-episodes/') {
                        callback([{
                            lastVisitTime: 743809800000,
                            url: 'http://southpark.cc.com/full-episodes/s01e01'
                        }, {
                            lastVisitTime: 743809900000,
                            url: 'http://southpark.cc.com/full-episodes/s01e02'
                        }]);
                    } else if (query === 'http://kisscartoon.me/Cartoon/South-Park-Season') {
                        callback([{
                            lastVisitTime: 703806800000,
                            url: 'http://kisscartoon.me/Cartoon/South-Park-Season-03/Episode-004'
                        }, {
                            lastVisitTime: 783806800000,
                            url: 'http://kisscartoon.me/Cartoon/South-Park-Season-04/Episode-005'
                        }]);
                    }
                }
            }
        });
        historian = new Historian();
    });

    it('sets last visit time to storage', () => {
        expect(lastVisitTime).toEqual(743806800000);
    });

    describe('getSeenEpisodes()', () => {
        it('collects all seen episodes', (done) => {
            historian.getSeenEpisodes().then((seenEpisodes) => {
                expect(seenEpisodes).toEqual([
                    {season: 1, episode: 1},
                    {season: 1, episode: 2},
                    {season: 4, episode: 5}
                ]);
                done();
            });
        });
    });
});
<commit_msg>#FIX Mock time in historian tests to make sure that timezones don't fck it up<commit_after>import Historian from 'historian';

describe('historian', () => {
    let lastVisitTime, historian;

    beforeEach(() => {
        jasmine.clock().mockDate(new Date(1993, 9, 26, 3, 25, 0));

        Historian.__set__({
            browser: {
                setToStorage: ({key, value}) => {
                    if (key === 'lastVisitTime')
                        lastVisitTime = value;
                },
                getFromStorage: (key) => {
                    if (key === 'lastVisitTime')
                        return lastVisitTime;
                },
                searchFromHistory: (query, lastVisitTime, callback) => {
                    if (query === 'http://southpark.cc.com/full-episodes/') {
                        callback([{
                            lastVisitTime: 743859800000,
                            url: 'http://southpark.cc.com/full-episodes/s01e01'
                        }, {
                            lastVisitTime: 743829100000,
                            url: 'http://southpark.cc.com/full-episodes/s01e02'
                        }]);
                    } else if (query === 'http://kisscartoon.me/Cartoon/South-Park-Season') {
                        callback([{
                            lastVisitTime: 703806800000,
                            url: 'http://kisscartoon.me/Cartoon/South-Park-Season-03/Episode-004'
                        }, {
                            lastVisitTime: 783806800000,
                            url: 'http://kisscartoon.me/Cartoon/South-Park-Season-04/Episode-005'
                        }]);
                    }
                }
            }
        });
        historian = new Historian();
    });

    it('sets last visit time to storage', () => {
        expect(lastVisitTime).toEqual(743819100000);
    });

    describe('getSeenEpisodes()', () => {
        it('collects all seen episodes', (done) => {
            historian.getSeenEpisodes().then((seenEpisodes) => {
                expect(seenEpisodes).toEqual([
                    {season: 1, episode: 1},
                    {season: 1, episode: 2},
                    {season: 4, episode: 5}
                ]);
                done();
            });
        });
    });
});
<|endoftext|>