<commit_before>define([
	"dojo",
	".",
	"./popup",
	"dojo/window",
	"./_WidgetBase",
	"./_FocusMixin",
	"./_KeyNavContainer",
	"./_FocusMixin",
	"./_TemplatedMixin"], function(dojo, dijit, pm){

	// module:
	//		dijit/_MenuBase
	// summary:
	//		Base class for Menu and MenuBar

dojo.declare("dijit._MenuBase",
	[dijit._WidgetBase, dijit._FocusMixin, dijit._TemplatedMixin, dijit._KeyNavContainer, dijit._FocusMixin],
{
	// summary:
	//		Base class for Menu and MenuBar

	// parentMenu: [readonly] Widget
	//		pointer to menu that displayed me
	parentMenu: null,

	// popupDelay: Integer
	//		number of milliseconds before hovering (without clicking) causes the popup to automatically open.
	popupDelay: 500,

	onExecute: function(){
		// summary:
		//		Attach point for notification about when a menu item has been executed.
		//		This is an internal mechanism used for Menus to signal to their parent to
		//		close them, because they are about to execute the onClick handler.  In
		//		general developers should not attach to or override this method.
		// tags:
		//		protected
	},

	onCancel: function(/*Boolean*/ closeAll){
		// summary:
		//		Attach point for notification about when the user cancels the current menu
		//		This is an internal mechanism used for Menus to signal to their parent to
		//		close them.  In general developers should not attach to or override this method.
		// tags:
		//		protected
	},

	_moveToPopup: function(/*Event*/ evt){
		// summary:
		//		This handles the right arrow key (left arrow key on RTL systems),
		//		which will either open a submenu, or move to the next item in the
		//		ancestor MenuBar
		// tags:
		//		private

		if(this.focusedChild && this.focusedChild.popup && !this.focusedChild.disabled){
			this.focusedChild._onClick(evt);
		}else{
			var topMenu = this._getTopMenu();
			if(topMenu && topMenu._isMenuBar){
				topMenu.focusNext();
			}
		}
	},

	_onPopupHover: function(/*Event*/ evt){
		// summary:
		//		This handler is called when the mouse moves over the popup.
		// tags:
		//		private

		// if the mouse hovers over a menu popup that is in pending-close state,
		// then stop the close operation.
		// This can't be done in onItemHover since some popup targets don't have MenuItems (e.g. ColorPicker)
		if(this.currentPopup && this.currentPopup._pendingClose_timer){
			var parentMenu = this.currentPopup.parentMenu;
			// highlight the parent menu item pointing to this popup
			if(parentMenu.focusedChild){
				parentMenu.focusedChild._setSelected(false);
			}
			parentMenu.focusedChild = this.currentPopup.from_item;
			parentMenu.focusedChild._setSelected(true);
			// cancel the pending close
			this._stopPendingCloseTimer(this.currentPopup);
		}
	},

	onItemHover: function(/*MenuItem*/ item){
		// summary:
		//		Called when cursor is over a MenuItem.
		// tags:
		//		protected

		// Don't do anything unless user has "activated" the menu by:
		//		1) clicking it
		//		2) opening it from a parent menu (which automatically focuses it)
		if(this.isActive){
			this.focusChild(item);
			if(this.focusedChild.popup && !this.focusedChild.disabled && !this.hover_timer){
				this.hover_timer = setTimeout(dojo.hitch(this, "_openPopup"), this.popupDelay);
			}
		}
		// if the user is mixing mouse and keyboard navigation,
		// then the menu may not be active but a menu item has focus,
		// but it's not the item that the mouse just hovered over.
		// To avoid both keyboard and mouse selections, use the latest.
		if(this.focusedChild){
			this.focusChild(item);
		}
		this._hoveredChild = item;
	},

	_onChildBlur: function(item){
		// summary:
		//		Called when a child MenuItem becomes inactive because focus
		//		has been removed from the MenuItem *and* it's descendant menus.
		// tags:
		//		private
		this._stopPopupTimer();
		item._setSelected(false);
		// Close all popups that are open and descendants of this menu
		var itemPopup = item.popup;
		if(itemPopup){
			this._stopPendingCloseTimer(itemPopup);
			itemPopup._pendingClose_timer = setTimeout(function(){
				itemPopup._pendingClose_timer = null;
				if(itemPopup.parentMenu){
					itemPopup.parentMenu.currentPopup = null;
				}
				pm.close(itemPopup); // this calls onClose
			}, this.popupDelay);
		}
	},

	onItemUnhover: function(/*MenuItem*/ item){
		// summary:
		//		Callback fires when mouse exits a MenuItem
		// tags:
		//		protected

		if(this.isActive){
			this._stopPopupTimer();
		}
		if(this._hoveredChild == item){ this._hoveredChild = null; }
	},

	_stopPopupTimer: function(){
		// summary:
		//		Cancels the popup timer because the user has stop hovering
		//		on the MenuItem, etc.
		// tags:
		//		private
		if(this.hover_timer){
			clearTimeout(this.hover_timer);
			this.hover_timer = null;
		}
	},

	_stopPendingCloseTimer: function(/*dijit._Widget*/ popup){
		// summary:
		//		Cancels the pending-close timer because the close has been preempted
		// tags:
		//		private
		if(popup._pendingClose_timer){
			clearTimeout(popup._pendingClose_timer);
			popup._pendingClose_timer = null;
		}
	},

	_stopFocusTimer: function(){
		// summary:
		//		Cancels the pending-focus timer because the menu was closed before focus occured
		// tags:
		//		private
		if(this._focus_timer){
			clearTimeout(this._focus_timer);
			this._focus_timer = null;
		}
	},

	_getTopMenu: function(){
		// summary:
		//		Returns the top menu in this chain of Menus
		// tags:
		//		private
		for(var top=this; top.parentMenu; top=top.parentMenu);
		return top;
	},

	onItemClick: function(/*dijit._Widget*/ item, /*Event*/ evt){
		// summary:
		//		Handle clicks on an item.
		// tags:
		//		private

		// this can't be done in _onFocus since the _onFocus events occurs asynchronously
		if(typeof this.isShowingNow == 'undefined'){ // non-popup menu
			this._markActive();
		}

		this.focusChild(item);

		if(item.disabled){ return false; }

		if(item.popup){
			this._openPopup();
		}else{
			// before calling user defined handler, close hierarchy of menus
			// and restore focus to place it was when menu was opened
			this.onExecute();

			// user defined handler for click
			item.onClick(evt);
		}
	},

	_openPopup: function(){
		// summary:
		//		Open the popup to the side of/underneath the current menu item
		// tags:
		//		protected

		this._stopPopupTimer();
		var from_item = this.focusedChild;
		if(!from_item){ return; } // the focused child lost focus since the timer was started
		var popup = from_item.popup;
		if(popup.isShowingNow){ return; }
		if(this.currentPopup){
			this._stopPendingCloseTimer(this.currentPopup);
			pm.close(this.currentPopup);
		}
		popup.parentMenu = this;
		popup.from_item = from_item; // helps finding the parent item that should be focused for this popup
		var self = this;
		pm.open({
			parent: this,
			popup: popup,
			around: from_item.domNode,
			orient: this._orient || ["after", "before"],
			onCancel: function(){ // called when the child menu is canceled
				// set isActive=false (_closeChild vs _cleanUp) so that subsequent hovering will NOT open child menus
				// which seems aligned with the UX of most applications (e.g. notepad, wordpad, paint shop pro)
				self.focusChild(from_item);	// put focus back on my node
				self._cleanUp();			// close the submenu (be sure this is done _after_ focus is moved)
				from_item._setSelected(true); // oops, _cleanUp() deselected the item
				self.focusedChild = from_item;	// and unset focusedChild
			},
			onExecute: dojo.hitch(this, "_cleanUp")
		});

		this.currentPopup = popup;
		// detect mouseovers to handle lazy mouse movements that temporarily focus other menu items
		popup.connect(popup.domNode, "onmouseenter", dojo.hitch(self, "_onPopupHover")); // cleaned up when the popped-up widget is destroyed on close

		if(popup.focus){
			// If user is opening the popup via keyboard (right arrow, or down arrow for MenuBar),
			// if the cursor happens to collide with the popup, it will generate an onmouseover event
			// even though the mouse wasn't moved.  Use a setTimeout() to call popup.focus so that
			// our focus() call overrides the onmouseover event, rather than vice-versa.  (#8742)
			popup._focus_timer = setTimeout(dojo.hitch(popup, function(){
				this._focus_timer = null;
				this.focus();
			}), 0);
		}
	},

	_markActive: function(){
		// summary:
		//		Mark this menu's state as active.
		//		Called when this Menu gets focus from:
		//			1) clicking it (mouse or via space/arrow key)
		//			2) being opened by a parent menu.
		//		This is not called just from mouse hover.
		//		Focusing a menu via TAB does NOT automatically set isActive
		//		since TAB is a navigation operation and not a selection one.
		//		For Windows apps, pressing the ALT key focuses the menubar
		//		menus (similar to TAB navigation) but the menu is not active
		//		(ie no dropdown) until an item is clicked.
		this.isActive = true;
		dojo.replaceClass(this.domNode, "dijitMenuActive", "dijitMenuPassive");
	},

	onOpen: function(/*Event*/ e){
		// summary:
		//		Callback when this menu is opened.
		//		This is called by the popup manager as notification that the menu
		//		was opened.
		// tags:
		//		private

		this.isShowingNow = true;
		this._markActive();
	},

	_markInactive: function(){
		// summary:
		//		Mark this menu's state as inactive.
		this.isActive = false; // don't do this in _onBlur since the state is pending-close until we get here
		dojo.replaceClass(this.domNode, "dijitMenuPassive", "dijitMenuActive");
	},

	onClose: function(){
		// summary:
		//		Callback when this menu is closed.
		//		This is called by the popup manager as notification that the menu
		//		was closed.
		// tags:
		//		private

		this._stopFocusTimer();
		this._markInactive();
		this.isShowingNow = false;
		this.parentMenu = null;
	},

	_closeChild: function(){
		// summary:
		//		Called when submenu is clicked or focus is lost.  Close hierarchy of menus.
		// tags:
		//		private
		this._stopPopupTimer();

		var fromItem = this.focusedChild && this.focusedChild.from_item;

		if(this.currentPopup){
			// If focus is on my child menu then move focus to me,
			// because IE doesn't like it when you display:none a node with focus
			var curFocusNode = this._focusManager.get("curNode");
			if(curFocusNode && dojo.isDescendant(curFocusNode, this.currentPopup.domNode)){
				this.focusedChild.focusNode.focus();
			}
			// Close all popups that are open and descendants of this menu
			pm.close(this.currentPopup);
			this.currentPopup = null;
		}

		if(this.focusedChild){ // unhighlight the focused item
			this.focusedChild._setSelected(false);
			this.focusedChild._onUnhover();
			this.focusedChild = null;
		}
	},

	_onItemFocus: function(/*MenuItem*/ item){
		// summary:
		//		Called when child of this Menu gets focus from:
		//			1) clicking it
		//			2) tabbing into it
		//			3) being opened by a parent menu.
		//		This is not called just from mouse hover.
		if(this._hoveredChild && this._hoveredChild != item){
			this._hoveredChild._onUnhover(); // any previous mouse movement is trumped by focus selection
		}
	},

	_onBlur: function(){
		// summary:
		//		Called when focus is moved away from this Menu and it's submenus.
		// tags:
		//		protected
		this._cleanUp();
		this.inherited(arguments);
	},

	_cleanUp: function(){
		// summary:
		//		Called when the user is done with this menu.  Closes hierarchy of menus.
		// tags:
		//		private

		this._closeChild(); // don't call this.onClose since that's incorrect for MenuBar's that never close
		if(typeof this.isShowingNow == 'undefined'){ // non-popup menu doesn't call onClose
			this._markInactive();
		}
	}
});

return dijit._MenuBase;
});
<commit_msg>indentation fix, refs #12672 !strict<commit_after>define([
	"dojo",
	".",
	"./popup",
	"dojo/window",
	"./_WidgetBase",
	"./_FocusMixin",
	"./_KeyNavContainer",
	"./_FocusMixin",
	"./_TemplatedMixin"], function(dojo, dijit, pm){

// module:
//		dijit/_MenuBase
// summary:
//		Base class for Menu and MenuBar

dojo.declare("dijit._MenuBase",
	[dijit._WidgetBase, dijit._FocusMixin, dijit._TemplatedMixin, dijit._KeyNavContainer, dijit._FocusMixin],
{
	// summary:
	//		Base class for Menu and MenuBar

	// parentMenu: [readonly] Widget
	//		pointer to menu that displayed me
	parentMenu: null,

	// popupDelay: Integer
	//		number of milliseconds before hovering (without clicking) causes the popup to automatically open.
	popupDelay: 500,

	onExecute: function(){
		// summary:
		//		Attach point for notification about when a menu item has been executed.
		//		This is an internal mechanism used for Menus to signal to their parent to
		//		close them, because they are about to execute the onClick handler.  In
		//		general developers should not attach to or override this method.
		// tags:
		//		protected
	},

	onCancel: function(/*Boolean*/ closeAll){
		// summary:
		//		Attach point for notification about when the user cancels the current menu
		//		This is an internal mechanism used for Menus to signal to their parent to
		//		close them.  In general developers should not attach to or override this method.
		// tags:
		//		protected
	},

	_moveToPopup: function(/*Event*/ evt){
		// summary:
		//		This handles the right arrow key (left arrow key on RTL systems),
		//		which will either open a submenu, or move to the next item in the
		//		ancestor MenuBar
		// tags:
		//		private

		if(this.focusedChild && this.focusedChild.popup && !this.focusedChild.disabled){
			this.focusedChild._onClick(evt);
		}else{
			var topMenu = this._getTopMenu();
			if(topMenu && topMenu._isMenuBar){
				topMenu.focusNext();
			}
		}
	},

	_onPopupHover: function(/*Event*/ evt){
		// summary:
		//		This handler is called when the mouse moves over the popup.
		// tags:
		//		private

		// if the mouse hovers over a menu popup that is in pending-close state,
		// then stop the close operation.
		// This can't be done in onItemHover since some popup targets don't have MenuItems (e.g. ColorPicker)
		if(this.currentPopup && this.currentPopup._pendingClose_timer){
			var parentMenu = this.currentPopup.parentMenu;
			// highlight the parent menu item pointing to this popup
			if(parentMenu.focusedChild){
				parentMenu.focusedChild._setSelected(false);
			}
			parentMenu.focusedChild = this.currentPopup.from_item;
			parentMenu.focusedChild._setSelected(true);
			// cancel the pending close
			this._stopPendingCloseTimer(this.currentPopup);
		}
	},

	onItemHover: function(/*MenuItem*/ item){
		// summary:
		//		Called when cursor is over a MenuItem.
		// tags:
		//		protected

		// Don't do anything unless user has "activated" the menu by:
		//		1) clicking it
		//		2) opening it from a parent menu (which automatically focuses it)
		if(this.isActive){
			this.focusChild(item);
			if(this.focusedChild.popup && !this.focusedChild.disabled && !this.hover_timer){
				this.hover_timer = setTimeout(dojo.hitch(this, "_openPopup"), this.popupDelay);
			}
		}
		// if the user is mixing mouse and keyboard navigation,
		// then the menu may not be active but a menu item has focus,
		// but it's not the item that the mouse just hovered over.
		// To avoid both keyboard and mouse selections, use the latest.
		if(this.focusedChild){
			this.focusChild(item);
		}
		this._hoveredChild = item;
	},

	_onChildBlur: function(item){
		// summary:
		//		Called when a child MenuItem becomes inactive because focus
		//		has been removed from the MenuItem *and* it's descendant menus.
		// tags:
		//		private
		this._stopPopupTimer();
		item._setSelected(false);
		// Close all popups that are open and descendants of this menu
		var itemPopup = item.popup;
		if(itemPopup){
			this._stopPendingCloseTimer(itemPopup);
			itemPopup._pendingClose_timer = setTimeout(function(){
				itemPopup._pendingClose_timer = null;
				if(itemPopup.parentMenu){
					itemPopup.parentMenu.currentPopup = null;
				}
				pm.close(itemPopup); // this calls onClose
			}, this.popupDelay);
		}
	},

	onItemUnhover: function(/*MenuItem*/ item){
		// summary:
		//		Callback fires when mouse exits a MenuItem
		// tags:
		//		protected

		if(this.isActive){
			this._stopPopupTimer();
		}
		if(this._hoveredChild == item){ this._hoveredChild = null; }
	},

	_stopPopupTimer: function(){
		// summary:
		//		Cancels the popup timer because the user has stop hovering
		//		on the MenuItem, etc.
		// tags:
		//		private
		if(this.hover_timer){
			clearTimeout(this.hover_timer);
			this.hover_timer = null;
		}
	},

	_stopPendingCloseTimer: function(/*dijit._Widget*/ popup){
		// summary:
		//		Cancels the pending-close timer because the close has been preempted
		// tags:
		//		private
		if(popup._pendingClose_timer){
			clearTimeout(popup._pendingClose_timer);
			popup._pendingClose_timer = null;
		}
	},

	_stopFocusTimer: function(){
		// summary:
		//		Cancels the pending-focus timer because the menu was closed before focus occured
		// tags:
		//		private
		if(this._focus_timer){
			clearTimeout(this._focus_timer);
			this._focus_timer = null;
		}
	},

	_getTopMenu: function(){
		// summary:
		//		Returns the top menu in this chain of Menus
		// tags:
		//		private
		for(var top=this; top.parentMenu; top=top.parentMenu);
		return top;
	},

	onItemClick: function(/*dijit._Widget*/ item, /*Event*/ evt){
		// summary:
		//		Handle clicks on an item.
		// tags:
		//		private

		// this can't be done in _onFocus since the _onFocus events occurs asynchronously
		if(typeof this.isShowingNow == 'undefined'){ // non-popup menu
			this._markActive();
		}

		this.focusChild(item);

		if(item.disabled){ return false; }

		if(item.popup){
			this._openPopup();
		}else{
			// before calling user defined handler, close hierarchy of menus
			// and restore focus to place it was when menu was opened
			this.onExecute();

			// user defined handler for click
			item.onClick(evt);
		}
	},

	_openPopup: function(){
		// summary:
		//		Open the popup to the side of/underneath the current menu item
		// tags:
		//		protected

		this._stopPopupTimer();
		var from_item = this.focusedChild;
		if(!from_item){ return; } // the focused child lost focus since the timer was started
		var popup = from_item.popup;
		if(popup.isShowingNow){ return; }
		if(this.currentPopup){
			this._stopPendingCloseTimer(this.currentPopup);
			pm.close(this.currentPopup);
		}
		popup.parentMenu = this;
		popup.from_item = from_item; // helps finding the parent item that should be focused for this popup
		var self = this;
		pm.open({
			parent: this,
			popup: popup,
			around: from_item.domNode,
			orient: this._orient || ["after", "before"],
			onCancel: function(){ // called when the child menu is canceled
				// set isActive=false (_closeChild vs _cleanUp) so that subsequent hovering will NOT open child menus
				// which seems aligned with the UX of most applications (e.g. notepad, wordpad, paint shop pro)
				self.focusChild(from_item);	// put focus back on my node
				self._cleanUp();			// close the submenu (be sure this is done _after_ focus is moved)
				from_item._setSelected(true); // oops, _cleanUp() deselected the item
				self.focusedChild = from_item;	// and unset focusedChild
			},
			onExecute: dojo.hitch(this, "_cleanUp")
		});

		this.currentPopup = popup;
		// detect mouseovers to handle lazy mouse movements that temporarily focus other menu items
		popup.connect(popup.domNode, "onmouseenter", dojo.hitch(self, "_onPopupHover")); // cleaned up when the popped-up widget is destroyed on close

		if(popup.focus){
			// If user is opening the popup via keyboard (right arrow, or down arrow for MenuBar),
			// if the cursor happens to collide with the popup, it will generate an onmouseover event
			// even though the mouse wasn't moved.  Use a setTimeout() to call popup.focus so that
			// our focus() call overrides the onmouseover event, rather than vice-versa.  (#8742)
			popup._focus_timer = setTimeout(dojo.hitch(popup, function(){
				this._focus_timer = null;
				this.focus();
			}), 0);
		}
	},

	_markActive: function(){
		// summary:
		//		Mark this menu's state as active.
		//		Called when this Menu gets focus from:
		//			1) clicking it (mouse or via space/arrow key)
		//			2) being opened by a parent menu.
		//		This is not called just from mouse hover.
		//		Focusing a menu via TAB does NOT automatically set isActive
		//		since TAB is a navigation operation and not a selection one.
		//		For Windows apps, pressing the ALT key focuses the menubar
		//		menus (similar to TAB navigation) but the menu is not active
		//		(ie no dropdown) until an item is clicked.
		this.isActive = true;
		dojo.replaceClass(this.domNode, "dijitMenuActive", "dijitMenuPassive");
	},

	onOpen: function(/*Event*/ e){
		// summary:
		//		Callback when this menu is opened.
		//		This is called by the popup manager as notification that the menu
		//		was opened.
		// tags:
		//		private

		this.isShowingNow = true;
		this._markActive();
	},

	_markInactive: function(){
		// summary:
		//		Mark this menu's state as inactive.
		this.isActive = false; // don't do this in _onBlur since the state is pending-close until we get here
		dojo.replaceClass(this.domNode, "dijitMenuPassive", "dijitMenuActive");
	},

	onClose: function(){
		// summary:
		//		Callback when this menu is closed.
		//		This is called by the popup manager as notification that the menu
		//		was closed.
		// tags:
		//		private

		this._stopFocusTimer();
		this._markInactive();
		this.isShowingNow = false;
		this.parentMenu = null;
	},

	_closeChild: function(){
		// summary:
		//		Called when submenu is clicked or focus is lost.  Close hierarchy of menus.
		// tags:
		//		private
		this._stopPopupTimer();

		var fromItem = this.focusedChild && this.focusedChild.from_item;

		if(this.currentPopup){
			// If focus is on my child menu then move focus to me,
			// because IE doesn't like it when you display:none a node with focus
			var curFocusNode = this._focusManager.get("curNode");
			if(curFocusNode && dojo.isDescendant(curFocusNode, this.currentPopup.domNode)){
				this.focusedChild.focusNode.focus();
			}
			// Close all popups that are open and descendants of this menu
			pm.close(this.currentPopup);
			this.currentPopup = null;
		}

		if(this.focusedChild){ // unhighlight the focused item
			this.focusedChild._setSelected(false);
			this.focusedChild._onUnhover();
			this.focusedChild = null;
		}
	},

	_onItemFocus: function(/*MenuItem*/ item){
		// summary:
		//		Called when child of this Menu gets focus from:
		//			1) clicking it
		//			2) tabbing into it
		//			3) being opened by a parent menu.
		//		This is not called just from mouse hover.
		if(this._hoveredChild && this._hoveredChild != item){
			this._hoveredChild._onUnhover(); // any previous mouse movement is trumped by focus selection
		}
	},

	_onBlur: function(){
		// summary:
		//		Called when focus is moved away from this Menu and it's submenus.
		// tags:
		//		protected
		this._cleanUp();
		this.inherited(arguments);
	},

	_cleanUp: function(){
		// summary:
		//		Called when the user is done with this menu.  Closes hierarchy of menus.
		// tags:
		//		private

		this._closeChild(); // don't call this.onClose since that's incorrect for MenuBar's that never close
		if(typeof this.isShowingNow == 'undefined'){ // non-popup menu doesn't call onClose
			this._markInactive();
		}
	}
});

return dijit._MenuBase;
});
<|endoftext|>


<commit_before>var
    SearchContext,
    Search;

(function ($) {
    "use strict";

    try {
        Object.defineProperties($, {
            flatten: {
                value: function(linkedList) {
                    var
                        iterator,
                        flattened = [],
                        allowedPattern = /^(Array|Arguments)$/,
                        className = Object.className(linkedList);

                    if (className == "Arguments") {
                        linkedList = $.from(linkedList);
                    } else if (!allowedPattern.test(className)) {
                        return linkedList;
                    }

                    // this way will treate all as String after run .join
                    // linkedList = linkedList.join().split(",");
                    iterator = SearchContext.Proxy
                        .new(Search.Graphs.BFS.Object.new(linkedList));

                    iterator.research(function(item) {
                        if (!allowedPattern.test(Object.className(item))) {
                            flattened.push(item);
                        }
                    });

                    return flattened;
                }
            }
        });

        Object.defineProperties($.prototype, {

            clone: {
                value: function () {
                    var
                        clone = [];

                    Object.assign(clone, this);

                    return clone;
                }
            },

            indexOfEquivalence: {
                // value: function(comparator, startWithIndex = 0) {
                value: function(comparator, startWithIndex) {
                    if(typeof startWithIndex != "number") {startWithIndex = 0;}

                    var
                        found,
                        item,
                        i = startWithIndex,
                        index = i;

                    if (typeof comparator != "number" && !comparator) {
                        return -1;
                    }

                    for(i = startWithIndex; i < this.length; i++) {
                        item = this[i];
                        if (typeof item == "function") {
                            if (item == comparator) {
                                found = true;
                                break;
                            }
                        } else {
                            if (item === undefined) {
                                console.warn("Item for compare is " +
                                                "undefined!");
                            }

                            // change to overridable equals method. Maybe using valueOf
                            if (Object.areEquivalents(item, comparator)) {
                                found = true;
                                break;
                            }
                        }

                        index += 1;
                    }

                    if (found) {
                        return index;
                    }

                    return -1;
                }
            },

            uniq: {
                value: function() {
                    return this.reduce(function (init, v) {
                        if (init.indexOfEquivalence(v) == -1) {
                            init.push(v);
                        }
                        return init;
                    }, []);
                }
            },

            includes: {
                value: function(items) {
                    var
                        args = Array.from(arguments).uniq(),
                        mainReference = this,
                        count = 0;

                    args.forEach(function (arg) {
                        if (mainReference.indexOfEquivalence(arg) > -1) {
                            count += 1;
                        }
                    });

                    return count == args.length;
                }
            },

            delete: {
                value: function(index) {
                    return this.splice(index, 1);
                }
            },

            deleteValue: {
                value: function(amount) {
                    var
                        counter,
                        index,
                        mainReference = this,
                        deleted = [],
                        partsToDelete = Array.from(arguments);

                    partsToDelete.shift();
                    partsToDelete.forEach(function (i) {
                        counter = amount;
                        while(counter-- > 0 && mainReference.count(i)) {
                            index = mainReference.indexOfEquivalence(i);
                            if (index > -1) {
                                deleted.push(mainReference.splice(index, 1)[0]);
                            }
                        }
                    });

                    return deleted;
                }
            },

            without: {
                value: function () {
                    var
                        parts = $.flatten(arguments),
                        clone = [];

                    clone = this.clone();

                    parts.forEach(function (i) {
                        clone.deleteValue(clone.count(i), i);
                    });

                    return clone;
                }
            },

            count: {
                value: function (item) {
                    var
                        clone = this.asc(),
                        index = -1,
                        count = 0;

                    while(true) {
                        index = clone.indexOfEquivalence(item, index + 1);
                        if(index > -1) {
                            count++;
                        } else {
                            break;
                        }
                    }

                    return count;
                }
            },

            countSlice: {
                value: function (slice) {
                    var
                        arr = this.asc(),
                        count = 0,
                        i = parseInt(arr.firstFromASlice(slice));

                    if (i > -1) {
                        while (i < this.length) {
                            if (arr[i].trim().search(slice.trim()) > -1) {
                                count += 1;
                                i += 1;
                            } else {
                                break;
                            }
                        }
                    }

                    return count;
                }
            },

            differences: {
                value: function (sets) {
                    var
                        clone = this.clone();

                    sets = Array.from(arguments);

                    if (sets.length <= 0) {
                        return this;
                    }

                    clone.uniq().forEach(function(item) {
                        sets.forEach(function(set) {
                            clone.deleteValue(set.count(item), item);
                        });
                    });

                    return clone;
                }
            },

            flatten: {
                value: function () {
                    return $.flatten(this);
                }
            },

            capitalize: {
                value: function () {
                    var
                        clone = [];

                    this.forEach(function (value) {
                        if (typeof value == "string") {
                            clone.push(value.capitalize());
                        }
                    });

                    return clone;
                }
            },

            spaceOut: {
                value: function () {
                    var
                        i = 0,
                        clone = this.clone();

                    while(i < clone.lastIndex()) {
                        clone[i++] += " ";
                    }

                    return clone;
                }
            },

            compact: {
                value: function () {
                    var
                        newArr = [];

                    this.forEach(function (v) {
                        if (typeof v == "string") {
                            if (v !== "") {
                                newArr.push(v);
                            }
                        } else {
                            if (v !== undefined && v !== null) {
                                newArr.push(v);
                            }
                        }
                    });

                    return newArr;
                }
            },

            asc: {
                value: function () {
                    var
                        clone = this.clone(),
                        compareFunction = function (a, b) {
                            return a > b;
                        };

                    clone.sort(compareFunction);

                    return clone;
                }
            },

            desc: {
                value: function () {
                    var
                        clone = this.clone(),
                        compareFunction = function (a, b) {
                            return a < b;
                        };

                    clone.sort(compareFunction);

                    return clone;
                }
            },

            min: {
                value: function () {
                    return Math.min.apply(null, this);
                }
            },

            max: {
                value: function () {
                    return Math.max.apply(null, this);
                }
            },

            first: {
                value: function () {
                    return this[0];
                }
            },

            firstIndexOf: {
                value: function(item) {
                    return this.indexOfEquivalence(item);
                }
            },

            lastIndex: {
                value: function () {
                    return this.length - 1;
                }
            },

            lastIndexOf: {
                value: function (item) {
                    return this.lastIndex() - this.clone().reverse()
                        .indexOfEquivalence(item);
                }
            },

            last: {
                value: function () {
                    return this[this.lastIndex()];
                }
            },

            firstFromASlice: {
                value: function (slice) {
                    var
                        i,
                        value,
                        index = 0;

                    for(i in this) {
                        if (this.hasOwnProperty(i)) {
                            value = this[i];
                            if (value.search(slice) > -1) {
                                return index;
                            }
                            index += 1;
                        }
                    }

                    return -1;
                }
            },

            lastFromASlice: {
                value: function (slice) {
                    var
                        i, key,
                        object = Object.keys(this).desc();

                    for(i in object) {
                        if (object.hasOwnProperty(i)) {
                            key = object[i];
                            if (this[key].search(slice) > -1) {
                                return key;
                            }
                        }
                    }

                    return undefined;
                }
            }

        });
    } catch(e) {}

})(Array);
<commit_msg>rename uniq method vars<commit_after>var
    SearchContext,
    Search;

(function ($) {
    "use strict";

    try {
        Object.defineProperties($, {
            flatten: {
                value: function(linkedList) {
                    var
                        iterator,
                        flattened = [],
                        allowedPattern = /^(Array|Arguments)$/,
                        className = Object.className(linkedList);

                    if (className == "Arguments") {
                        linkedList = $.from(linkedList);
                    } else if (!allowedPattern.test(className)) {
                        return linkedList;
                    }

                    // this way will treate all as String after run .join
                    // linkedList = linkedList.join().split(",");
                    iterator = SearchContext.Proxy
                        .new(Search.Graphs.BFS.Object.new(linkedList));

                    iterator.research(function(item) {
                        if (!allowedPattern.test(Object.className(item))) {
                            flattened.push(item);
                        }
                    });

                    return flattened;
                }
            }
        });

        Object.defineProperties($.prototype, {

            clone: {
                value: function () {
                    var
                        clone = [];

                    Object.assign(clone, this);

                    return clone;
                }
            },

            indexOfEquivalence: {
                // value: function(comparator, startWithIndex = 0) {
                value: function(comparator, startWithIndex) {
                    if(typeof startWithIndex != "number") {startWithIndex = 0;}

                    var
                        found,
                        item,
                        i = startWithIndex,
                        index = i;

                    if (typeof comparator != "number" && !comparator) {
                        return -1;
                    }

                    for(i = startWithIndex; i < this.length; i++) {
                        item = this[i];
                        if (typeof item == "function") {
                            if (item == comparator) {
                                found = true;
                                break;
                            }
                        } else {
                            if (item === undefined) {
                                console.warn("Item for compare is " +
                                                "undefined!");
                            }

                            // change to overridable equals method. Maybe using valueOf
                            if (Object.areEquivalents(item, comparator)) {
                                found = true;
                                break;
                            }
                        }

                        index += 1;
                    }

                    if (found) {
                        return index;
                    }

                    return -1;
                }
            },

            uniq: {
                value: function() {
                    return this.reduce(function (aux, value) {
                        if (aux.indexOfEquivalence(value) == -1) {
                            aux.push(value);
                        }
                        return aux;
                    }, []);
                }
            },

            includes: {
                value: function(items) {
                    var
                        args = Array.from(arguments).uniq(),
                        mainReference = this,
                        count = 0;

                    args.forEach(function (arg) {
                        if (mainReference.indexOfEquivalence(arg) > -1) {
                            count += 1;
                        }
                    });

                    return count == args.length;
                }
            },

            delete: {
                value: function(index) {
                    return this.splice(index, 1);
                }
            },

            deleteValue: {
                value: function(amount) {
                    var
                        counter,
                        index,
                        mainReference = this,
                        deleted = [],
                        partsToDelete = Array.from(arguments);

                    partsToDelete.shift();
                    partsToDelete.forEach(function (i) {
                        counter = amount;
                        while(counter-- > 0 && mainReference.count(i)) {
                            index = mainReference.indexOfEquivalence(i);
                            if (index > -1) {
                                deleted.push(mainReference.splice(index, 1)[0]);
                            }
                        }
                    });

                    return deleted;
                }
            },

            without: {
                value: function () {
                    var
                        parts = $.flatten(arguments),
                        clone = [];

                    clone = this.clone();

                    parts.forEach(function (i) {
                        clone.deleteValue(clone.count(i), i);
                    });

                    return clone;
                }
            },

            count: {
                value: function (item) {
                    var
                        clone = this.asc(),
                        index = -1,
                        count = 0;

                    while(true) {
                        index = clone.indexOfEquivalence(item, index + 1);
                        if(index > -1) {
                            count++;
                        } else {
                            break;
                        }
                    }

                    return count;
                }
            },

            countSlice: {
                value: function (slice) {
                    var
                        arr = this.asc(),
                        count = 0,
                        i = parseInt(arr.firstFromASlice(slice));

                    if (i > -1) {
                        while (i < this.length) {
                            if (arr[i].trim().search(slice.trim()) > -1) {
                                count += 1;
                                i += 1;
                            } else {
                                break;
                            }
                        }
                    }

                    return count;
                }
            },

            differences: {
                value: function (sets) {
                    var
                        clone = this.clone();

                    sets = Array.from(arguments);

                    if (sets.length <= 0) {
                        return this;
                    }

                    clone.uniq().forEach(function(item) {
                        sets.forEach(function(set) {
                            clone.deleteValue(set.count(item), item);
                        });
                    });

                    return clone;
                }
            },

            flatten: {
                value: function () {
                    return $.flatten(this);
                }
            },

            capitalize: {
                value: function () {
                    var
                        clone = [];

                    this.forEach(function (value) {
                        if (typeof value == "string") {
                            clone.push(value.capitalize());
                        }
                    });

                    return clone;
                }
            },

            spaceOut: {
                value: function () {
                    var
                        i = 0,
                        clone = this.clone();

                    while(i < clone.lastIndex()) {
                        clone[i++] += " ";
                    }

                    return clone;
                }
            },

            compact: {
                value: function () {
                    var
                        newArr = [];

                    this.forEach(function (v) {
                        if (typeof v == "string") {
                            if (v !== "") {
                                newArr.push(v);
                            }
                        } else {
                            if (v !== undefined && v !== null) {
                                newArr.push(v);
                            }
                        }
                    });

                    return newArr;
                }
            },

            asc: {
                value: function () {
                    var
                        clone = this.clone(),
                        compareFunction = function (a, b) {
                            return a > b;
                        };

                    clone.sort(compareFunction);

                    return clone;
                }
            },

            desc: {
                value: function () {
                    var
                        clone = this.clone(),
                        compareFunction = function (a, b) {
                            return a < b;
                        };

                    clone.sort(compareFunction);

                    return clone;
                }
            },

            min: {
                value: function () {
                    return Math.min.apply(null, this);
                }
            },

            max: {
                value: function () {
                    return Math.max.apply(null, this);
                }
            },

            first: {
                value: function () {
                    return this[0];
                }
            },

            firstIndexOf: {
                value: function(item) {
                    return this.indexOfEquivalence(item);
                }
            },

            lastIndex: {
                value: function () {
                    return this.length - 1;
                }
            },

            lastIndexOf: {
                value: function (item) {
                    return this.lastIndex() - this.clone().reverse()
                        .indexOfEquivalence(item);
                }
            },

            last: {
                value: function () {
                    return this[this.lastIndex()];
                }
            },

            firstFromASlice: {
                value: function (slice) {
                    var
                        i,
                        value,
                        index = 0;

                    for(i in this) {
                        if (this.hasOwnProperty(i)) {
                            value = this[i];
                            if (value.search(slice) > -1) {
                                return index;
                            }
                            index += 1;
                        }
                    }

                    return -1;
                }
            },

            lastFromASlice: {
                value: function (slice) {
                    var
                        i, key,
                        object = Object.keys(this).desc();

                    for(i in object) {
                        if (object.hasOwnProperty(i)) {
                            key = object[i];
                            if (this[key].search(slice) > -1) {
                                return key;
                            }
                        }
                    }

                    return undefined;
                }
            }

        });
    } catch(e) {}

})(Array);
<|endoftext|>


<commit_before>//
// Extra Logging for Debugging
//
// To customize logging - create a file in the root called
// user-logging.js, with the following contents:
//
//    module.exports = function() {
//      logging = {
//         headers:      true,
//         queryParams:  true,
//         bodyParams:   true,
//         bodyData:     true,
//         content:      true
//      };
//      return logging;
//    }();

var logging;

try {
  logging = require('../user-logging.js');
} catch (e) {
  logging = {
    headers:      false,
    queryParams:  false,
    bodyParams:   false,
    bodyData:     false,
    content:      false
  };
}

exports.middleware = function(req, res, next) {

  if (logging.headers) {
    console.log("== HEADERS ========= " + req.url);
    console.log(req.headers);
  }

  if (logging.queryParams) {
    console.log("== QUERY PARAMS ========= " + req.url);
    console.log(req.query);
  }

  if (logging.bodyParams) {
    console.log("==  BODY PARAMS ========= " + req.url);
    console.log(req.tcapi_body_params);
  }

  if (logging.bodyData) {
    console.log("== RAW BODY ========= " + req.url);
    console.log(req.rawBody);
  }

  if (logging.contnt) {
    console.log("== BODY CONTENT ========= " + req.url);
    console.log(req.tcapi_body_params.content);
  }

  next();
};

<commit_msg>Add some extra logging<commit_after>//
// Extra Logging for Debugging
//
// To customize logging - create a file in the root called
// user-logging.js, with the following contents:
//
//    module.exports = function() {
//      logging = {
//         headers:      true,
//         queryParams:  true,
//         bodyParams:   true,
//         bodyData:     true,
//         content:      true
//      };
//      return logging;
//    }();

var logging;

try {
  logging = require('../user-logging.js');
} catch (e) {
  logging = {
    headers:      true,
    queryParams:  true,
    bodyParams:   true,
    bodyData:     true,
    content:      true
  };
}

exports.middleware = function(req, res, next) {

  if (logging.headers) {
    console.log("== HEADERS ========= " + req.url);
    console.log(req.headers);
  }

  if (logging.queryParams) {
    console.log("== QUERY PARAMS ========= " + req.url);
    console.log(req.query);
  }

  if (logging.bodyParams) {
    console.log("==  BODY PARAMS ========= " + req.url);
    console.log(req.tcapi_body_params);
  }

  if (logging.bodyData) {
    console.log("== RAW BODY ========= " + req.url);
    console.log(req.rawBody);
  }

  if (logging.contnt) {
    console.log("== BODY CONTENT ========= " + req.url);
    console.log(req.tcapi_body_params.content);
  }

  next();
};

<|endoftext|>


<commit_before>/*
* freelog-widgetscripts
* https://github.com/miushock/freelog-widgetscripts
*
* Copyright (c) 2015 Miushock
* Licensed under the MIT license.
*/

'use strict';

var grunt = require('grunt');
var jquery = grunt.file.read('./node_modules/jquery/dist/jquery.min.js');
var jsdom = require('jsdom');
var request = require('request');

module.exports = function(grunt) {

  grunt.registerTask('build-index-page', 'create index page for testing the widget', function(){
    var config = grunt.config('build_index_page');
    var widget_html = grunt.file.read(config.widget_html);
    var container = grunt.file.read(config.container_file);
    var dest = config.dest;

    jsdom.env({
      html:container,
      src:[jquery],
      done: function (err, window) {
        if (err) {
          grunt.fail.warn(err);
        }
        var $ = window.$;
        var widget= $(widget_html);
        $('body').append(widget);
        var html_export = "<!DOCTYPE html>\n\n" + $("html").html() + "\n";
        grunt.file.write(dest, html_export);
      }
    });

  });

  grunt.registerTask('submit-widget', 'submit-widget to freelog.co', function(){
  //make async
    var done = this.async();

    var config = grunt.config('submit_widget');
    var widget_html = grunt.file.read(config.widget_html);
    var widget_style = grunt.file.read(config.widget_style);
    var widget_script = grunt.file.read(config.widget_script);

    var author_email = config.author_email;

    var widget_object = JSON.stringify({html:widget_html, css:widget_style, javascript:widget_script});

    var resource = {
      resource: {
        resource_type: 'widget',
        meta: JSON.stringify({shim_dependencies: config.shim_dependencies}),
        name: config.name,
        mime_type: 'application/json',
        sharing_policy: '{}',
        content: widget_object
      }
    }

    request(
      {
        method:'post',
        uri:'http://freelog.co:3000/resources.json',
        json:true,
        body:resource
      } ,
      function (err, response, body) {
        if (err) {
          console.error('upload failed:', err);
          done();
        }
        done();
      })
      .auth(config.auth_email,config.auth_pw);
  });

};
<commit_msg>submit task for page build<commit_after>/*
* freelog-widgetscripts
* https://github.com/miushock/freelog-widgetscripts
*
* Copyright (c) 2015 Miushock
* Licensed under the MIT license.
*/

'use strict';

var grunt = require('grunt');
var jquery = grunt.file.read('./node_modules/jquery/dist/jquery.min.js');
var jsdom = require('jsdom');
var request = require('request');

module.exports = function(grunt) {

  grunt.registerTask('build-index-page', 'create index page for testing the widget', function(){
    var config = grunt.config('build_index_page');
    var widget_html = grunt.file.read(config.widget_html);
    var container = grunt.file.read(config.container_file);
    var dest = config.dest;

    jsdom.env({
      html:container,
      src:[jquery],
      done: function (err, window) {
        if (err) {
          grunt.fail.warn(err);
        }
        var $ = window.$;
        var widget= $(widget_html);
        $('body').append(widget);
        var html_export = "<!DOCTYPE html>\n\n" + $("html").html() + "\n";
        grunt.file.write(dest, html_export);
      }
    });

  });

  grunt.registerTask('submit-widget', 'submit-widget to freelog.co', function(){
  //make async
    var done = this.async();

    var config = grunt.config('submit_widget');
    var widget_html = grunt.file.read(config.widget_html);
    var widget_style = grunt.file.read(config.widget_style);
    var widget_script = grunt.file.read(config.widget_script);

    var author_email = config.author_email;

    var widget_object = JSON.stringify({html:widget_html, css:widget_style, javascript:widget_script});

    var resource = {
      resource: {
        resource_type: 'widget',
        meta: JSON.stringify({shim_dependencies: config.shim_dependencies}),
        name: config.name,
        mime_type: 'application/json',
        sharing_policy: '{}',
        content: widget_object
      }
    }

    request(
      {
        method:'post',
        uri:'http://freelog.co:3000/resources.json',
        json:true,
        body:resource
      } ,
      function (err, response, body) {
        if (err) {
          console.error('upload failed:', err);
          done();
        }
        done();
      })
      .auth(config.auth_email,config.auth_pw);
  });

  grunt.registerTask('submit-pagebuild', 'submit a page build to freelog.co', function(){
    var done = this.async();

    var config = grunt.config('submit_widget');
    var pb_html = grunt.file.read(config.widget_html);
    var pb_style = grunt.file.read(config.widget_style);
    var pb_script = grunt.file.read(config.widget_script);
    var pb_widgets = config.widgets;
    var author_email = config.author_email;

    var pb_object = JSON.stringify({widgets:pb_widgets, html:widget_html, css:widget_style, javascript:widget_script});

    var resource = {
      resource: {
        resource_type: 'page_build',
        meta: {},
        name: config.name,
        mime_type: 'application/json',
        sharing_policy: '{}',
        content: pb_object
      }
    }

    request(
      {
        method:'post',
        uri:'http://freelog.co:3000/resources.json',
        json:true,
        body:resource
      } ,
      function (err, response, body) {
        if (err) {
          console.error('upload failed:', err);
          done();
        }
        done();
      })
      .auth(config.auth_email,config.auth_pw);
  });
};
<|endoftext|>


<commit_before>var
	DEFAULTS = require('./constants/defaults'),
	MESSAGES = require('./constants/messages'),
	PATTERNS = require('./constants/ignorePatterns'),
	MAPPINGS = require('./constants/editorconfigMappings'),

	editorconfig = require('editorconfig'),
	merge = require('merge'),

	eol = '\\r?\\n',
	eolRegExp = new RegExp(eol)
;

module.exports = (function() {
	var Validator = function(grunt, options, logger) {
		this._grunt = grunt;
		this._options = options(DEFAULTS);
		this._logger = logger;
		this._processedFiles = 0;
	};

	// Extend Validator's prototype with specific properties:
	Validator.prototype = merge(Validator.prototype, {

		validate: function(path) {
			var self = this;
			if (this._grunt.file.isFile(path)) {
				// Load file, settings & ignores:
				this._path = path;
				this._loadSettings();
				this._loadFile();
				this._loadIgnores();

				// Validate total file:
				this._validateNewlineMaximum();
				this._validateNewlinesEOF();

				// Validate single lines:
				this._lines.forEach(function(line, index) {
					self._validateIndentation(line, index);
					self._validateTrailingspaces(line, index);
				});

				// Validation is done:
				this._done();
			}
		},

		getProssessedFiles: function() {
			return this._processedFiles;
		},

		_done: function() {
			this._processedFiles++;

			// Cleanup references:
			this._settings = null;
			this._data = undefined;
			this._lines = null;
			this._ignoredLines = null;
		},

		/*
		 * Loading functions
		 * ------------------------------------------------------------------ */

		_loadFile: function() {
			this._data = this._grunt.file.read(this._path, this._settings.encoding),
			this._lines = this._data.split(eolRegExp);
		},

		_loadSettings: function() {
			var config, key;

			// Initially the users options are the current settings:
			this._settings = merge({}, this._options);

			// Overwrite settings by .editorconfig file's settings:
			if (typeof this._settings.editorconfig === 'string') {
				if (this._grunt.file.isFile(this._settings.editorconfig)) {

					// Load config for current path
					config = editorconfig.parse(
						this._path, {
							config: this._settings.editorconfig
						}
					);

					if (typeof config === 'object') {
						// Merge editorconfig values into the correct settings names:
						for (key in config) {
							if (typeof MAPPINGS[key] === 'string') {
								switch (key) {
									case 'indent_style':
										// The 'indent_style' property value isn't
										// equal to the expected setting value:
										this._settings[MAPPINGS[key]] = config[key] + 's';
										break;
									default:
										this._settings[MAPPINGS[key]] = config[key];
										break;
								}
							}
						}
					}
				} else {
					this._logFail(
						MESSAGES.EDITORCONFIG_NOTFOUND.replace(
							'{a}',
							this._settings.editorconfig
						)
					);
				}
			}
		},

		_loadIgnores: function() {
			var
				self = this,
				ignores = []
			;

			this._ignoredLines = {};

			// Load ignore patterns:
			if (Array.isArray(this._settings.ignores)) {
				this._settings.ignores.forEach(function(ignore) {
					if (typeof ignore === 'string' && typeof PATTERNS[ignore] === 'object') {
						ignores.push(PATTERNS[ignore]);
					} else if (typeof ignore === 'object' && typeof ignore.test === 'function') {
						ignores.push(ignore);
					}
				});
			}

			// When no patterns are defined, disable the following search for lines:
			if (ignores.length === 0) {
				ignores = false;
			}

			// Index lines which match patterns, when available:
			if (Array.isArray(ignores)) {

				// Loop all given regular expressions:
				ignores.forEach(function(expression) {

					var matches = self._data.match(expression) || [];

					matches.forEach(function(match) {

						// Only perform an action when match has more
						// than one line:
						if (eolRegExp.test(match)) {

							// Use fake replace cycle to find indices of all
							// lines to be ignored. Return unchanged match:
							self._data = self._data.replace(match, function(matched) {
								var
									index = 1,
									args,
									indexOfMatch,
									indexOfSecondLine,
									totalLines
								;

								// last argument is whole string, remove it:
								args = Array.prototype.slice.call(arguments);
								args.pop();

								// matched string start index:
								indexOfMatch = args.pop();

								// slice source data from beginning to matched
								// string start index to find index of second
								// line to be ignored:
								indexOfSecondLine = self._data.slice(0, indexOfMatch).split(eolRegExp).length;
								totalLines = matched.split(eolRegExp).length;

								//Count and store lines:
								while (index < totalLines) {
									self._ignoredLines[indexOfSecondLine + index - 1] = true;
									index++;
								}

								// Fillup result with linebreaks and overwrite
								// data string in case that the data string contains
								// the current 'matched' more than once:
								return Array(totalLines).join('\n');
							});

						}
					});
				});
			}
		},

		/*
		 * Validation functions
		 * ------------------------------------------------------------------ */

		_validateNewlineMaximum: function() {
			if (typeof this._settings.newlineMaximum === 'number') {
				if (this._settings.newlineMaximum > 0) {
					var
						self = this;

						// To grep all all blocks at the begin of a file
						// which have at least 1 more new line than the defined
						// criteria the expression for one or more newlines is
						// appended:
						newlinesAtBeginn = '^[' + eol + ']{'+ this._settings.newlineMaximum + '}' + eol + '+'

						// Each block inside a file has an extra leading newline
						// from the previous line above (+1). To grep all all blocks
						// which have at least 1 more new line than the defined
						// criteria the expression for one or more newlines is
						// appended:
						newlinesInFile = '[' + eol + ']{'+ (this._settings.newlineMaximum + 1) + '}' + eol + '+',

						// Define function which is used as fake replace cycle to
						// validate matches:
						validate = function(match, offset, original) {
							var
								substring = original.substr(0, offset),
								newlines = substring.match(new RegExp(eol, 'g')),
								amount = match.match(new RegExp(eol, 'g')).length,
								atLine = 0
							;

							// When current match is not at the beginning of a file,
							// newlines is defined. In this case update variables:
							if (newlines) {
								atLine = newlines.length + 1;
								amount = amount - 1;
							}

							self._logLine(
								atLine + 1,
								MESSAGES.NEWLINE_MAXIMUM
									.replace('{a}', amount)
									.replace('{b}', self._settings.newlineMaximum)
							);

							return original;
						}
					;

					this._data.replace(new RegExp(newlinesAtBeginn, 'g'), validate);
					this._data.replace(new RegExp(newlinesInFile, 'g'), validate);
				} else {
					this._logFail(
						MESSAGES.NEWLINE_MAXIMUM_INVALIDVALUE.replace('{a}', this._settings.newlineMaximum)
					);
				}
			}
		},

		_validateNewlinesEOF: function() {
			if (this._settings.newline && this._lines.length > 1) {
				var
					index = this._lines.length - 1
				;

				// check last line:
				if (this._lines[index].length > 0) {
					this._logLine(index + 1, MESSAGES.NEWLINE);
				}

				// check line before last line:
				if (this._lines[index - 1].length === 0) {
					this._logLine(index, MESSAGES.NEWLINE_AMOUNT);
				}
			}
		},

		_validateTrailingspaces: function(line, index) {
			if (this._settings.trailingspaces && typeof line === 'string') {
				var matchSpaces = line.match(/\s*$/);
				if (matchSpaces.length > 0 && matchSpaces[0].length > 0) {
					this._logLine(index + 1, MESSAGES.TRAILINGSPACES);
				}
			}
		},

		_validateIndentation: function(line, index) {
			if (!this._ignoredLines[index] &&
				typeof this._settings.indentation === 'string' &&
				typeof line === 'string') {

				var
					tabsRegExp = /^\t*(?!\s).*$/, // leading tabs without leading spaces
					spacesRegExp = /^ *(?!\s).*$/, // leading spaces without leading tabs
					spacesLeadingRegExp = /^( *).*$/,
					spacesExpected,
					indent,
					message
				;

				switch (this._settings.indentation) {
					case 'tabs':
						if (!tabsRegExp.test(line)) {
							// indentation failed...
							return this._logLine(index + 1, MESSAGES.INDENTATION_TABS);
						}
						break;

					case 'spaces':
						if (!spacesRegExp.test(line)) {
							// Indentation failed...
							this._logLine(index + 1, MESSAGES.INDENTATION_SPACES);
						} else {
							// Indentation correct, is amount of spaces correct?
							if (typeof this._settings.spaces === 'number') {
								indent = line.match(spacesLeadingRegExp)[1].length;
								if (indent % this._settings.spaces !== 0) {
									// Indentation incorrect, create message:
									spacesExpected = Math.round(indent / this._settings.spaces) * this._settings.spaces;
									message = MESSAGES.INDENTATION_SPACES_AMOUNT
										.replace('{a}', spacesExpected)
										.replace('{b}', indent);

									this._logLine(index + 1, message);
								}
							}
						}
						break;
				}
			}
		},

		/*
		 * Logging functions
		 * ------------------------------------------------------------------ */

		_logFail: function(message) {
			this._logger.fail(message);
		},

		_logLine: function(linenumber, message) {
			this._logger.logLine(this._path, linenumber, message);
		}
	});

	return Validator;
})();
<commit_msg>Fix issue when ignored lines are not used to detect maximum amount of newlines<commit_after>var
	DEFAULTS = require('./constants/defaults'),
	MESSAGES = require('./constants/messages'),
	PATTERNS = require('./constants/ignorePatterns'),
	MAPPINGS = require('./constants/editorconfigMappings'),

	editorconfig = require('editorconfig'),
	merge = require('merge'),

	eol = '\\r?\\n',
	eolRegExp = new RegExp(eol)
;

module.exports = (function() {
	var Validator = function(grunt, options, logger) {
		this._grunt = grunt;
		this._options = options(DEFAULTS);
		this._logger = logger;
		this._processedFiles = 0;
	};

	// Extend Validator's prototype with specific properties:
	Validator.prototype = merge(Validator.prototype, {

		validate: function(path) {
			var self = this;
			if (this._grunt.file.isFile(path)) {
				// Load file, settings & ignores:
				this._path = path;
				this._loadSettings();
				this._loadFile();
				this._loadIgnores();

				// Validate total file:
				this._validateNewlineMaximum();
				this._validateNewlinesEOF();

				// Validate single lines:
				this._lines.forEach(function(line, index) {
					self._validateIndentation(line, index);
					self._validateTrailingspaces(line, index);
				});

				// Validation is done:
				this._done();
			}
		},

		getProssessedFiles: function() {
			return this._processedFiles;
		},

		_done: function() {
			this._processedFiles++;

			// Cleanup references:
			this._settings = null;
			this._data = undefined;
			this._lines = null;
			this._ignoredLines = null;
		},

		/*
		 * Loading functions
		 * ------------------------------------------------------------------ */

		_loadFile: function() {
			this._data = this._grunt.file.read(this._path, this._settings.encoding),
			this._lines = this._data.split(eolRegExp);
		},

		_loadSettings: function() {
			var config, key;

			// Initially the users options are the current settings:
			this._settings = merge({}, this._options);

			// Overwrite settings by .editorconfig file's settings:
			if (typeof this._settings.editorconfig === 'string') {
				if (this._grunt.file.isFile(this._settings.editorconfig)) {

					// Load config for current path
					config = editorconfig.parse(
						this._path, {
							config: this._settings.editorconfig
						}
					);

					if (typeof config === 'object') {
						// Merge editorconfig values into the correct settings names:
						for (key in config) {
							if (typeof MAPPINGS[key] === 'string') {
								switch (key) {
									case 'indent_style':
										// The 'indent_style' property value isn't
										// equal to the expected setting value:
										this._settings[MAPPINGS[key]] = config[key] + 's';
										break;
									default:
										this._settings[MAPPINGS[key]] = config[key];
										break;
								}
							}
						}
					}
				} else {
					this._logFail(
						MESSAGES.EDITORCONFIG_NOTFOUND.replace(
							'{a}',
							this._settings.editorconfig
						)
					);
				}
			}
		},

		_loadIgnores: function() {
			var
				self = this,
				ignores = []
			;

			this._ignoredLines = {};

			// Load ignore patterns:
			if (Array.isArray(this._settings.ignores)) {
				this._settings.ignores.forEach(function(ignore) {
					if (typeof ignore === 'string' && typeof PATTERNS[ignore] === 'object') {
						ignores.push(PATTERNS[ignore]);
					} else if (typeof ignore === 'object' && typeof ignore.test === 'function') {
						ignores.push(ignore);
					}
				});
			}

			// When no patterns are defined, disable the following search for lines:
			if (ignores.length === 0) {
				ignores = false;
			}

			// Index lines which match patterns, when available:
			if (Array.isArray(ignores)) {

				// Loop all given regular expressions:
				ignores.forEach(function(expression) {

					var matches = self._data.match(expression) || [];

					matches.forEach(function(match) {

						// Only perform an action when match has more
						// than one line:
						if (eolRegExp.test(match)) {

							// Use fake replace cycle to find indices of all
							// lines to be ignored. Return unchanged match:
							self._data = self._data.replace(match, function(matched) {
								var
									index = 1,
									args,
									indexOfMatch,
									indexOfSecondLine,
									totalLines
								;

								// last argument is whole string, remove it:
								args = Array.prototype.slice.call(arguments);
								args.pop();

								// matched string start index:
								indexOfMatch = args.pop();

								// slice source data from beginning to matched
								// string start index to find index of second
								// line to be ignored:
								indexOfSecondLine = self._data.slice(0, indexOfMatch).split(eolRegExp).length;
								totalLines = matched.split(eolRegExp).length;

								//Count and store lines:
								while (index < totalLines) {
									self._ignoredLines[indexOfSecondLine + index - 1] = true;
									index++;
								}

								// Fillup result with linebreaks and overwrite
								// data string in case that the data string contains
								// the current 'matched' more than once:
								return Array(totalLines).join('\n');
							});

						}
					});
				});
			}
		},

		/*
		 * Validation functions
		 * ------------------------------------------------------------------ */

		_validateNewlineMaximum: function() {
			if (typeof this._settings.newlineMaximum === 'number') {
				if (this._settings.newlineMaximum > 0) {
					var
						self = this;

						// To grep all all blocks at the begin of a file
						// which have at least 1 more new line than the defined
						// criteria the expression for one or more newlines is
						// appended:
						newlinesAtBeginn = '^[' + eol + ']{'+ this._settings.newlineMaximum + '}' + eol + '+'

						// Each block inside a file has an extra leading newline
						// from the previous line above (+1). To grep all all blocks
						// which have at least 1 more new line than the defined
						// criteria the expression for one or more newlines is
						// appended:
						newlinesInFile = '[' + eol + ']{'+ (this._settings.newlineMaximum + 1) + '}' + eol + '+',

						// Define function which is used as fake replace cycle to
						// validate matches:
						validate = function(match, offset, original) {
							var
								substring = original.substr(0, offset),
								newlines = substring.match(new RegExp(eol, 'g')),
								amount = match.match(new RegExp(eol, 'g')).length,
								atLine = 0
							;

							// When current match is not at the beginning of a file,
							// newlines is defined. In this case update variables:
							if (newlines) {
								atLine = newlines.length + 1;
								amount = amount - 1;
							}

							// Test if found lines are not in ignored lines:
							if (!self._ignoredLines[atLine + 1]) {
								self._logLine(
									atLine + 1,
									MESSAGES.NEWLINE_MAXIMUM
										.replace('{a}', amount)
										.replace('{b}', self._settings.newlineMaximum)
								);
							}

							return original;
						}
					;

					this._data.replace(new RegExp(newlinesAtBeginn, 'g'), validate);
					this._data.replace(new RegExp(newlinesInFile, 'g'), validate);
				} else {
					this._logFail(
						MESSAGES.NEWLINE_MAXIMUM_INVALIDVALUE.replace('{a}', this._settings.newlineMaximum)
					);
				}
			}
		},

		_validateNewlinesEOF: function() {
			if (this._settings.newline && this._lines.length > 1) {
				var
					index = this._lines.length - 1
				;

				// check last line:
				if (this._lines[index].length > 0) {
					this._logLine(index + 1, MESSAGES.NEWLINE);
				}

				// check line before last line:
				if (this._lines[index - 1].length === 0) {
					this._logLine(index, MESSAGES.NEWLINE_AMOUNT);
				}
			}
		},

		_validateTrailingspaces: function(line, index) {
			if (this._settings.trailingspaces && typeof line === 'string') {
				var matchSpaces = line.match(/\s*$/);
				if (matchSpaces.length > 0 && matchSpaces[0].length > 0) {
					this._logLine(index + 1, MESSAGES.TRAILINGSPACES);
				}
			}
		},

		_validateIndentation: function(line, index) {
			if (!this._ignoredLines[index] &&
				typeof this._settings.indentation === 'string' &&
				typeof line === 'string') {

				var
					tabsRegExp = /^\t*(?!\s).*$/, // leading tabs without leading spaces
					spacesRegExp = /^ *(?!\s).*$/, // leading spaces without leading tabs
					spacesLeadingRegExp = /^( *).*$/,
					spacesExpected,
					indent,
					message
				;

				switch (this._settings.indentation) {
					case 'tabs':
						if (!tabsRegExp.test(line)) {
							// indentation failed...
							return this._logLine(index + 1, MESSAGES.INDENTATION_TABS);
						}
						break;

					case 'spaces':
						if (!spacesRegExp.test(line)) {
							// Indentation failed...
							this._logLine(index + 1, MESSAGES.INDENTATION_SPACES);
						} else {
							// Indentation correct, is amount of spaces correct?
							if (typeof this._settings.spaces === 'number') {
								indent = line.match(spacesLeadingRegExp)[1].length;
								if (indent % this._settings.spaces !== 0) {
									// Indentation incorrect, create message:
									spacesExpected = Math.round(indent / this._settings.spaces) * this._settings.spaces;
									message = MESSAGES.INDENTATION_SPACES_AMOUNT
										.replace('{a}', spacesExpected)
										.replace('{b}', indent);

									this._logLine(index + 1, message);
								}
							}
						}
						break;
				}
			}
		},

		/*
		 * Logging functions
		 * ------------------------------------------------------------------ */

		_logFail: function(message) {
			this._logger.fail(message);
		},

		_logLine: function(linenumber, message) {
			this._logger.logLine(this._path, linenumber, message);
		}
	});

	return Validator;
})();
<|endoftext|>


<commit_before>/*
 Copyright 2015 - 2017 by Jan Dockx

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

/* eslint-env mocha */

'use strict'

const stack = require('../../lib/_private/stack')
const is = require('../../lib/_private/is')
const testUtil = require('../_util/testUtil')
const os = require('os')

describe('_private/stack', function () {
  describe('#location', function () {
    it('returns the expected line without arguments', function () {
      function aFirstFunction () {
        function aSecondFunction () {
          return stack.location()
        }

        return aSecondFunction()
      }

      const result = aFirstFunction()
      testUtil.log(result)
      result.must.be.a.string()
      result.split(os.EOL).length.must.equal(1)
      if (testUtil.environment !== 'safari') {
        result.must.contain('aSecondFunction')
      }
      is.stackLocation(result).must.be.true()
    })
    it('returns the expected line 2 deep', function () {
      function aFirstFunction () {
        function aSecondFunction () {
          function aThirdFunction () {
            function aFourthFunction () {
              return stack.location(2)
            }

            return aFourthFunction()
          }

          return aThirdFunction()
        }

        return aSecondFunction()
      }

      const result = aFirstFunction()
      testUtil.log(result)
      result.must.be.a.string()
      result.split(os.EOL).length.must.equal(1)
      if (testUtil.environment !== 'safari') {
        result.must.contain('aSecondFunction')
      }
      is.stackLocation(result).must.be.true()
    })
  })

  describe('#raw', function () {
    it('returns the expected stack without arguments', function () {
      function aFourthFunction () {
        function aFifthFunction () {
          return stack.raw()
        }

        return aFifthFunction()
      }

      function aSecondFunction () {
        function aThirdFunction () {
          return aFourthFunction()
        }

        return aThirdFunction()
      }

      function aFirstFunction () {
        return aSecondFunction()
      }

      const result = aFirstFunction()
      testUtil.log(result)
      result.must.be.a.string()
      const lines = result.split(os.EOL)
      lines.length.must.be.at.least(1)
      if (testUtil.environment !== 'safari') {
        lines.length.must.be.at.least(5)
        lines[0].must.contain('aFifthFunction')
        lines[1].must.contain('aFourthFunction')
        lines[2].must.contain('aThirdFunction')
        lines[3].must.contain('aSecondFunction')
        lines[4].must.contain('aFirstFunction')
      }
      is.stack(result).must.be.true()
    })
    it('returns the expected stack. 2 deep', function () {
      function skipTwo (skip) {
        function skipOne (skip) {
          return stack.raw(skip + 1)
        }

        return skipOne(skip + 1)
      }

      function skipThree (skip) {
        return skipTwo(skip + 1)
      }

      function aFourthFunction () {
        function aFifthFunction () {
          return skipThree(0)
        }

        return aFifthFunction()
      }

      function aSecondFunction () {
        function aThirdFunction () {
          return aFourthFunction()
        }

        return aThirdFunction()
      }

      function aFirstFunction () {
        return aSecondFunction()
      }

      const result = aFirstFunction()
      testUtil.log(result)
      result.must.be.a.string()
      const lines = result.split(os.EOL)
      lines.length.must.be.at.least(1)
      if (testUtil.environment !== 'safari') {
        lines.length.must.be.at.least(5)
        lines[0].must.contain('aFifthFunction')
        lines[1].must.contain('aFourthFunction')
        lines[2].must.contain('aThirdFunction')
        lines[3].must.contain('aSecondFunction')
        lines[4].must.contain('aFirstFunction')
      }
      is.stack(result).must.be.true()
    })
  })

  describe('skipsForEach', function () {
    it('return the expected value for this platform', function () {
      testUtil.log('stack.skipsForEach:', stack.skipsForEach)
      stack.skipsForEach.must.equal(testUtil.environment === 'firefox')
    })
  })
})
<commit_msg>a location must be a single line, whatever the EOL<commit_after>/*
 Copyright 2015 - 2017 by Jan Dockx

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

/* eslint-env mocha */

'use strict'

const stack = require('../../lib/_private/stack')
const is = require('../../lib/_private/is')
const testUtil = require('../_util/testUtil')
const os = require('os')

const rnEOL = '\r\n'
const nEOL = '\n'

describe('_private/stack', function () {
  describe('#location', function () {
    it('returns the expected line without arguments', function () {
      function aFirstFunction () {
        function aSecondFunction () {
          return stack.location()
        }

        return aSecondFunction()
      }

      const result = aFirstFunction()
      testUtil.log(result)
      result.must.be.a.string()
      // must be a single line with any EOL
      result.split(rnEOL).length.must.equal(1)
      result.split(nEOL).length.must.equal(1)
      if (testUtil.environment !== 'safari') {
        result.must.contain('aSecondFunction')
      }
      is.stackLocation(result).must.be.true()
    })
    it('returns the expected line 2 deep', function () {
      function aFirstFunction () {
        function aSecondFunction () {
          function aThirdFunction () {
            function aFourthFunction () {
              return stack.location(2)
            }

            return aFourthFunction()
          }

          return aThirdFunction()
        }

        return aSecondFunction()
      }

      const result = aFirstFunction()
      testUtil.log(result)
      result.must.be.a.string()
      // must be a single line with any EOL
      result.split(rnEOL).length.must.equal(1)
      result.split(nEOL).length.must.equal(1)
      if (testUtil.environment !== 'safari') {
        result.must.contain('aSecondFunction')
      }
      is.stackLocation(result).must.be.true()
    })
  })

  describe('#raw', function () {
    it('returns the expected stack without arguments', function () {
      function aFourthFunction () {
        function aFifthFunction () {
          return stack.raw()
        }

        return aFifthFunction()
      }

      function aSecondFunction () {
        function aThirdFunction () {
          return aFourthFunction()
        }

        return aThirdFunction()
      }

      function aFirstFunction () {
        return aSecondFunction()
      }

      const result = aFirstFunction()
      testUtil.log(result)
      result.must.be.a.string()
      const lines = result.split(os.EOL)
      lines.length.must.be.at.least(1)
      if (testUtil.environment !== 'safari') {
        lines.length.must.be.at.least(5)
        lines[0].must.contain('aFifthFunction')
        lines[1].must.contain('aFourthFunction')
        lines[2].must.contain('aThirdFunction')
        lines[3].must.contain('aSecondFunction')
        lines[4].must.contain('aFirstFunction')
      }
      is.stack(result).must.be.true()
    })
    it('returns the expected stack. 2 deep', function () {
      function skipTwo (skip) {
        function skipOne (skip) {
          return stack.raw(skip + 1)
        }

        return skipOne(skip + 1)
      }

      function skipThree (skip) {
        return skipTwo(skip + 1)
      }

      function aFourthFunction () {
        function aFifthFunction () {
          return skipThree(0)
        }

        return aFifthFunction()
      }

      function aSecondFunction () {
        function aThirdFunction () {
          return aFourthFunction()
        }

        return aThirdFunction()
      }

      function aFirstFunction () {
        return aSecondFunction()
      }

      const result = aFirstFunction()
      testUtil.log(result)
      result.must.be.a.string()
      const lines = result.split(os.EOL)
      lines.length.must.be.at.least(1)
      if (testUtil.environment !== 'safari') {
        lines.length.must.be.at.least(5)
        lines[0].must.contain('aFifthFunction')
        lines[1].must.contain('aFourthFunction')
        lines[2].must.contain('aThirdFunction')
        lines[3].must.contain('aSecondFunction')
        lines[4].must.contain('aFirstFunction')
      }
      is.stack(result).must.be.true()
    })
  })

  describe('skipsForEach', function () {
    it('return the expected value for this platform', function () {
      testUtil.log('stack.skipsForEach:', stack.skipsForEach)
      stack.skipsForEach.must.equal(testUtil.environment === 'firefox')
    })
  })
})
<|endoftext|>


<commit_before>'use strict';

module.exports = function (t, a) {
	var args, x;

	a.h1("2 args");
	x = [1, 2, 3, 4, 5];
	t.call(x, 0, 3);
	a.deep(x, [4, 5, 3, 4, 5]);
	a.deep(t.call([1, 2, 3, 4, 5], 1, 3), [1, 4, 5, 4, 5]);
	a.deep(t.call([1, 2, 3, 4, 5], 1, 2), [1, 3, 4, 5, 5]);
	a.deep(t.call([1, 2, 3, 4, 5], 2, 2), [1, 2, 3, 4, 5]);

	a.h1("3 args");
	a.deep(t.call([1, 2, 3, 4, 5], 0, 3, 4), [4, 2, 3, 4, 5]);
	a.deep(t.call([1, 2, 3, 4, 5], 1, 3, 4), [1, 4, 3, 4, 5]);
	a.deep(t.call([1, 2, 3, 4, 5], 1, 2, 4), [1, 3, 4, 4, 5]);

	a.h1("Negative args");
	a.deep(t.call([1, 2, 3, 4, 5], 0, -2), [4, 5, 3, 4, 5]);
	a.deep(t.call([1, 2, 3, 4, 5], 0, -2, -1), [4, 2, 3, 4, 5]);
	a.deep(t.call([1, 2, 3, 4, 5], -4, -3, -2), [1, 3, 3, 4, 5]);
	a.deep(t.call([1, 2, 3, 4, 5], -4, -3, -1), [1, 3, 4, 4, 5]);
	a.deep(t.call([1, 2, 3, 4, 5], -4, -3), [1, 3, 4, 5, 5]);

	a.h1("Array-likes");
	args = (function () { return arguments; }(1, 2, 3));
	a.deep(t.call(args, -2, 0), [1, 1, 2]);
};
<commit_msg>Fix Array#copyWithin test<commit_after>'use strict';

module.exports = function (t, a) {
	var args, x;

	a.h1("2 args");
	x = [1, 2, 3, 4, 5];
	t.call(x, 0, 3);
	a.deep(x, [4, 5, 3, 4, 5]);
	a.deep(t.call([1, 2, 3, 4, 5], 1, 3), [1, 4, 5, 4, 5]);
	a.deep(t.call([1, 2, 3, 4, 5], 1, 2), [1, 3, 4, 5, 5]);
	a.deep(t.call([1, 2, 3, 4, 5], 2, 2), [1, 2, 3, 4, 5]);

	a.h1("3 args");
	a.deep(t.call([1, 2, 3, 4, 5], 0, 3, 4), [4, 2, 3, 4, 5]);
	a.deep(t.call([1, 2, 3, 4, 5], 1, 3, 4), [1, 4, 3, 4, 5]);
	a.deep(t.call([1, 2, 3, 4, 5], 1, 2, 4), [1, 3, 4, 4, 5]);

	a.h1("Negative args");
	a.deep(t.call([1, 2, 3, 4, 5], 0, -2), [4, 5, 3, 4, 5]);
	a.deep(t.call([1, 2, 3, 4, 5], 0, -2, -1), [4, 2, 3, 4, 5]);
	a.deep(t.call([1, 2, 3, 4, 5], -4, -3, -2), [1, 3, 3, 4, 5]);
	a.deep(t.call([1, 2, 3, 4, 5], -4, -3, -1), [1, 3, 4, 4, 5]);
	a.deep(t.call([1, 2, 3, 4, 5], -4, -3), [1, 3, 4, 5, 5]);

	a.h1("Array-likes");
	args = (function () { return arguments; }(1, 2, 3));
	a.deep(t.call(args, -2, 0), { '0': 1, '1': 1, '2':  2 });
};
<|endoftext|>


<commit_before>"use strict";

module.exports = function testAssertions(code, stdout, stderr) {
	code.should.be.exactly(0);

	stdout.should.be.ok();
	stdout[0].should.containEql("Hash: ");
	stdout[1].should.containEql("Version: ");
	stdout[2].should.containEql("Time: ");
	stdout[3].should.containEql("Environment (--env): ");
	stdout[5].should.containEql("null.js");

	stderr.should.be.empty();
};
<commit_msg>[lint] remove trailing space<commit_after>"use strict";

module.exports = function testAssertions(code, stdout, stderr) {
	code.should.be.exactly(0);

	stdout.should.be.ok();
	stdout[0].should.containEql("Hash: ");
	stdout[1].should.containEql("Version: ");
	stdout[2].should.containEql("Time: ");
	stdout[3].should.containEql("Environment (--env): ");
	stdout[5].should.containEql("null.js");

	stderr.should.be.empty();
};
<|endoftext|>


<commit_before>//@TODO Catch errors on hooks
(function (window) {
    "use strict";

    var nof5 = window.nof5,
        mocha = window.mocha;

    jQuery(function onReady() {

        nof5.connect(function onConnect(socket) {

            jQuery("#mocha").empty();

            mocha.setup({
                ui:"bdd",
                globals: [
                    "io",
                    "getInterface", //getInterface seems to be a global function from mocha ^^
                    "stats",
                    "report"
                ]
            });

            mocha.Runner.prototype.on("suite", function (suite) {
                if(suite.root) {
                    socket.emit("start", new Date());
                }
            });

            mocha.Runner.prototype.on("fail", function onFail(test) {

                mocha.Runner.prototype.once("test end", function onTestEnd() {

                    var error = {
                        "suite": test.parent.title,
                        "test": test.title,
                        "type": test.err.toString()
                    };

                    socket.emit("fail", error);
                });
            });

            mocha.Runner.prototype.on("suite end", function onSuiteEnd(suite) {
                if (suite.root) {
                    socket.emit("end", new Date());
                    mocha.Runner.prototype.removeAllListeners("test end");
                }
            });

            socket.on("disconnect", function onDisconnect() {
                mocha.Runner.prototype.removeAllListeners();
            });

            socket.once("f5", function onf5() {
                location.reload();
            });

            nof5.enableTests();
            mocha.run();
        });
    });

})(window);<commit_msg>- refactoring of testRunner according to changes of mocha 1.4.2<commit_after>//@TODO Catch errors on hooks
(function (window) {
    "use strict";

    var nof5 = window.nof5,
        mocha = window.mocha;

    jQuery(function onReady() {

        nof5.connect(function onConnect(socket) {

            var runner;

            mocha.setup({
                ui:"bdd",
                globals: [
                    "io",
                    //"getInterface", //getInterface seems to be a global function from mocha ^^
                    "stats",
                    "report"
                ]
            });

            nof5.enableTests();

            runner = mocha.run();

            runner.on("suite", function (suite) {
                if(suite.root) {
                    socket.emit("start", new Date());
                }
            });

            runner.on("fail", function onFail(test) {

                runner.once("test end", function onTestEnd() {

                    var error = {
                        "suite": test.parent.title,
                        "test": test.title,
                        "type": test.err.toString()
                    };

                    socket.emit("fail", error);
                });
            });

            runner.on("suite end", function onSuiteEnd(suite) {
                if (suite.root) {
                    socket.emit("end", new Date());
                    mocha.Runner.prototype.removeAllListeners("test end");
                }
            });

            socket.on("disconnect", function onDisconnect() {
                runner.removeAllListeners();
            });

            socket.once("f5", function onf5() {
                location.reload();
            });

        });
    });

})(window);<|endoftext|>


<commit_before><commit_msg>modified cms/actions/authors_test.js<commit_after>import { expect, sinon } from '../../helpers/utility';
import { fetchAuthor, updateAuthor } from 'cms/actions/authors';
import {
  CMS_ROOT_URL,
  AUTHOR_PATH,
  TEST_DOMAIN
} from 'shared/constants/apis';
import {
  FETCH_AUTHOR,
  FETCH_SOCIAL_ACCOUNTS,
  UPDATE_AUTHOR,
  CREATE_ALERT
} from 'shared/constants/actions';
import { trimAuthor } from 'cms/utilities';
import nock from 'nock'
import configureMockStore from 'redux-mock-store'
import browserHistory  from 'react-router/lib/browserHistory'
import thunk from 'redux-thunk'
const middleWares = [thunk];
const mockStore = configureMockStore(middleWares);

const authorUrl = `${CMS_ROOT_URL}${AUTHOR_PATH}`;
describe('cms author actions', () => {

  beforeEach(() => {
    // TODO: figure out how to test browserHistory
    sinon.stub(browserHistory,'push');
  });

  afterEach(() => {
    nock.cleanAll();
    browserHistory.push.restore();
  });

  describe('fetchAuthor', () => {

    it("creates FETCH_AUTHOR_SUCCESS when fetchAuthor has been done",  () => {
      const responseParams = {
        id: 1,
        email: 'sample@gmail.com',
        name: 'hoge',
        image: 'image',
        description: 'description',
        introduction: 'introduction',
        socialAccounts: [
          {
            accountType: 'twitter',
            url: 'http://twitter.com'
          }
        ]
      };

      nock(TEST_DOMAIN)
        .get(`${authorUrl}/`)
        .reply(200, responseParams);

      const store = mockStore({});
      const expectedResponse = [
        {
          type: FETCH_AUTHOR.SUCCESS,
          payload: { author: {
            id: 1,
            email: 'sample@gmail.com',
            name: 'hoge',
            image: 'image',
            description: 'description',
            introduction: 'introduction'
          }}
        },
        {
          type: FETCH_SOCIAL_ACCOUNTS,
          payload: {
            socialAccounts: [
              {
                accountType: 'twitter',
                url: 'http://twitter.com'
              }
            ]
          }
        }
      ];

      return store.dispatch(fetchAuthor()).then(()=> {
        expect(store.getActions()).to.eql(expectedResponse);
      })

    });

    it('created FETCH_AUTHOR_FAILURE when fetchAuthor has failed', () => {
      nock(TEST_DOMAIN)
        .get(`${authorUrl}/`)
        .reply(400, { errorMessage: 'errorMessage' });

      const store = mockStore({});

      const expectedResponse = [{
        payload: {
          hasAlert: true,
          kind: "error",
          message: 'errorMessage'
        },
        type: CREATE_ALERT
      }];

      return store.dispatch(fetchAuthor()).then(()=> {
        expect(store.getActions()).to.eql(expectedResponse);
      })

    })
  });

  describe('updateAuthor', () => {

    let props;
    beforeEach(() => {
      props = {
        author: {
          id: 1,
          name: 'hoge',
          image: 'image',
          description: 'description',
          introduction: 'introduction',
          socialAccountsAttributes: [{
            authorId: 1,
            accountType: 'twitter',
            url: 'http://twitter.com'
          }]
        }
      };
    });

    it("creates UPDATE_AUTHOR_SUCCESS when updateAuthor has been done",  () => {
      nock(TEST_DOMAIN)
        .patch(`${authorUrl}`, { author: trimAuthor(props.author) })
        .reply(200);

      const store = mockStore({});

      const expectedResponse = [{
        type: UPDATE_AUTHOR.SUCCESS
      }];

      return store.dispatch(updateAuthor(props)).then(()=> {
        expect(store.getActions()).to.eql(expectedResponse);
      })

    });

    it('created UPDATE_AUTHOR_FAILURE when updateAuthor has failed', () => {
      nock(TEST_DOMAIN)
        .patch(`${authorUrl}`, { author: trimAuthor(props.author) })
        .reply(400, { errorMessage: 'errorMessage' });

      const store = mockStore({});

      const expectedResponse = [{
        type: UPDATE_AUTHOR.FAILURE,
        payload: {
          errorMessage: 'errorMessage'
        }
      }];

      return store.dispatch(updateAuthor(props)).then(()=> {
        expect(store.getActions()).to.eql(expectedResponse);
      })

    })
  });

});<|endoftext|>