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

    var Taxi = function(element, options) {
        this.$element = $(element);
        this.options = options;
        this.sectionData = [];  // populated on draw with objects of section metadata
        this.preventTransform = false;  // when true, calls to transform are ignored
        this.expandedScrollingMode = false;  // when true, prevents calls to transform through the movement handler
        this.scrollLock = new ScrollLock();

        $('body').css('margin', 0);
        this.$element.css('position', 'relative');

        this.draw();
        $(window).resize(this.draw.bind(this));

        if (this.options.guidedScrolling) {
            this.scrollLock.go('lock');
            $(document).on('movement', this._movementHandler.bind(this));
            this.$element.on('sectionchange.taxi', this._expandedScrollHandler.bind(this));
        } else {
            $(document).on('scroll', this._sectionChangeHandler.bind(this));
        }

        if (this.options.hideScrollbar) {
            $("<style type='text/css'>::-webkit-scrollbar { display: none; }</style>").appendTo('head');
        }
    };

    /** Fire events when the section changes.
        Called after transforms complete and on scroll events when
        guidedScrolling is false
    */
    Taxi.prototype._sectionChangeHandler = function() {
        var currentSection = this._currentSection();
        if (this._cur != currentSection) {
            this.$element.trigger('sectionchange.taxi', [currentSection, this._cur])
        }
        this._cur = currentSection;
    };

    /** Called when guidedScrolling is true and expandedScrollingMode is false.
        Drives transform events based on swipe-like events from user input.
    */
    Taxi.prototype._movementHandler = function(e, direction) {
        if (!this.expandedScrollingMode && !this.preventTransform) {
            if (direction == 'up') { this.previous(true); }
            else if (direction == 'down') { this.next(); }
        }
    };

    /** Called when guidedScrolling is true and the section changes.
        If the current section is an expanded section, it binds expanded
        scroll handlers which give control of scrolling to the user.
        When the user scrolls past the defined boundaries, the handlers
        are unbound, the user is moved to the next section
        and locked scrolling is turned back on.
    */
    Taxi.prototype._expandedScrollHandler = function(e, index) {
        if (this.sectionData[index].expanded) {

            var checkOnScroll = (function() {
                var viewportHeight = $(window).height();
                var viewportTop = $(document).scrollTop();
                var height = this.sectionData[index].height;
                var top = this.sectionData[index].top;

                var lowerLimit = viewportHeight + viewportTop > top + height + this.options.expandedScrollOffThreshold;
                var upperLimit = viewportTop < top - this.options.expandedScrollOffThreshold;

                if (upperLimit || lowerLimit) {
                    this.expandedScrollingMode = false;
                    this.scrollLock.go('lock');
                    $(document).off('scroll', checkOnScroll);

                }
            }).bind(this);

            this.expandedScrollingMode = true;
            this.scrollLock.go('unlock');
            $(document).on('scroll', checkOnScroll);
        }

    };

    /** Returns the index of the section currently in view.
    */
    Taxi.prototype._currentSection = function() {
        var scrollTop = $(document).scrollTop();

        var i = this.sectionData.length;
        while(i--) {
            if (scrollTop >= this.sectionData[i].top) {
                return i;
            }
        }
        return 0;  // catch negative scrolling browser behaviour
    };

    /** Sizes and positions the sections.
        Called on init and when a section is expanded or contracted.
        Can be manually called if a section is added, updated or removed
    */
    Taxi.prototype.draw = function() {

        var that = this;
        var sectionData = [];
        var viewportHeight = $(window).height();
        var sections = this.$element.children(this.options.sectionSelector);
        var currentPosition = 0;

        sections.each(function(index, el){
            var $el = $(el);
            var section = {
                element: $el,
                top: currentPosition,
                expanded: $el.hasClass(that.options.expandedSectionClass)
            };

            $el.css('height', 'auto');  // ensure appropriate measurement when redrawing
            var height = (section.expanded) ? section.element.outerHeight() : viewportHeight;
            section.height = height;

            sectionData.push(section);

            section.element.css({
                position: 'absolute',
                top: section.top,
                width: '100%',
                height: height,
                overflow: 'hidden',
            });

            currentPosition += height;

        });

        // If a descendent element of a section has a taxi-full-height data attribute,
        // it will be assigned the height of the viewport.
        sections.find('[data-taxi-full-height]').css('height', viewportHeight);

        this.sectionData = sectionData;

        return this;
    };

    /* Aligns the top of the current section to the top of the viewport
    */
    Taxi.prototype.snap = function() {
        var scrollTop = $(document).scrollTop();
        var currentSection = this._currentSection();
        var currentSectionData = this.sectionData[currentSection];

        if (scrollTop != currentSectionData.top) {
            this.transform(currentSectionData.top);
        }

        return this;
    };

    /* Transforms the top of the current section to the top of the viewport.
       If scrollToBottom is true, the bottom of the current section is aligned to the
       bottom of the viewport. (This only makes a difference for expanded sections.
       For sections where the height matches the viewport height, )
    */
    Taxi.prototype.to = function(index, scrollToBottom) {
        var that = this;

        if (index >= this.sectionData.length) {
            $.error('Out of range: this instance only has ' + this.sectionData.length + ' sections');
        }

        var cur = this._currentSection();
        var section = this.sectionData[index];
        scrollToBottom = (typeof scrollToBottom === 'boolean') ? scrollToBottom : false;

        if (scrollToBottom) {
            var destination = section.top + section.height - $(window).height();
        } else {
            var destination = section.top;
        }

        this.$element.trigger('moveto.start.taxi', [index, cur]);
        this.transform(destination).done(function(){
            that.$element.trigger('moveto.end.taxi', [index, cur]);
        });
        return this;
    };

    Taxi.prototype.previous = function(scrollToBottom) {
        var cur = this._currentSection();
        var index = (cur > 0) ? cur - 1 : cur;
        return this.to(index, scrollToBottom);
    };

    Taxi.prototype.next = function(scrollToBottom) {
        var cur = this._currentSection();
        var index = (cur < this.sectionData.length - 1) ? cur + 1 : cur;
        return this.to(index, scrollToBottom);
    };

    /** The main driver for simulated page scrolls. Accepts a pixel value
     *  which is scrolled to the top of the page. Calls to transform fail
     *  when preventTransform is true. The engine that drives animations is
     *  $.fn.taxi.transform. Returns a jQuery promise object.
     */
    Taxi.prototype.transform = function(x) {
        var that = this;
        var dfd = $.Deferred();

        // The transform fails if it is out of bounds or
        // if preventTransform is true
        if (this.preventTransform ||
            x < 0 ||
            x > $(document).height()) {
            dfd.reject();
        }

        // If the transform delta is 0, resolve immediately
        else if ($(document).scrollTop() == x) {
            dfd.resolve();
        }

        // Do the transform
        else {

            this.$element.trigger('transform.start.taxi');
            this.preventTransform = true;
            if (!this.options.guidedScrolling) this.scrollLock.go('lock');

            $.fn.taxi.transform(this.$element, x, this.options).done(function(){
                that.preventTransform = false;
                that._sectionChangeHandler();
                if (!that.options.guidedScrolling) that.scrollLock.go('unlock');
                dfd.resolve();
                that.$element.trigger('transform.end.taxi');
            });

        }

        return dfd.promise();
    };

    /** Sections with overflowing content can be turned into
     *  expanded or non-expanded sections on the fly
     *  Pass a method as 'expand', 'collapse' or 'toggle'
     *  and an index which is either the numeric index of the section
     *  within $element, or the element itself
     */
    Taxi.prototype.expand = function(method, indexOrElement) {
        var that = this;

        var index = (typeof indexOrElement === "number") ?
            indexOrElement :
            this.$element.children().index(indexOrElement);

        var section = this.sectionData[index];
        var currentSection = this._currentSection();
        var delta = section.element[0].scrollHeight - $(window).height();
        var currentScroll = $(document).scrollTop();

        var _expand = function() {
            section.element.addClass('expanded');
            that.draw();

            if (currentSection == index) {
                that._expandedScrollHandler(null, index);
            } else if (currentSection > index) {
                $(document).scrollTop(currentScroll + delta);
            }

            this.$element.trigger('sectionexpand.taxi', [index]);
        };

        var _collapse = function() {
            if (currentSection == index) {
                // Scroll the window back to the top of the section before
                // closing it
                that.transform(section.top).done(function(){
                    section.element.removeClass('expanded');
                    that.draw();
                    that.expandedScrollingMode = false;
                    this.$element.trigger('sectioncollapse.taxi', [index]);
                });
            } else if (currentSection > index) {
                // Offset the scroll value by the amount the window size
                // changes to keep the window in the same place

                $(document).scrollTop(currentScroll - delta);
                section.element.removeClass('expanded');
                that.draw();
                this.$element.trigger('sectioncollapse.taxi', [index]);

            } else {
                section.element.removeClass('expanded');
                that.draw();
                this.$element.trigger('sectioncollapse.taxi', [index]);
            }
        };

        if (!section.expanded &&
            (method == 'expand' || method == 'toggle')) {
            _expand();
        } else if (section.expanded &&
            (method == 'collapse' || method == 'toggle')) {
            _collapse();
        }

        return this;
    }

    /** ScrollLock toggle's the user's ability to scroll manually,
     *  by scroll wheels, touch events and key presses.
     *  Call ScrollLock.go('lock') to disable scrolling
     *  and ScrollLock.go('unlock') to reenable.
     */
    var ScrollLock = function(){
        this.isLocked = false;
        this.evtString = 'mousewheel.scrolllock DOMMouseScroll.scrolllock \
            MozMousePixelScroll.scrolllock touchstart.scrolllock \
            touchmove.scrolllock keydown.scrolllock'; // keydown.scrolllock';
        this.lockHandler = function(e) {
            var keycodes = [33, 32, 34, 37, 38, 39, 40, 65, 68, 83, 87];
            if (e.type !== 'keydown' || keycodes.indexOf(e.keyCode) > -1) {
                e.preventDefault();
            }
        }
    };

    ScrollLock.prototype.go = function(action) {
        if (!action) return this.isLocked;

        if (action == 'lock' && !this.isLocked) {
            $(document).on(this.evtString, this.lockHandler);
            this.isLocked = true;
        } else if (action == 'unlock' && this.isLocked) {
            $(document).off(this.evtString, this.lockHandler);
            this.isLocked = false;
        }
    };

    // Plugin definition
    // =================

    $.fn.taxi = function(option) {
        var nargs = Array.prototype.slice.call(arguments, 1);
        return this.each(function(){
            var $this = $(this);
            var data = $this.data('jquery.taxi');
            var options = $.extend({}, $.fn.taxi.defaults, typeof option == 'object' && option);

            if (!data) {
                $this.data('jquery.taxi', (data = new Taxi(this, options)));
            } else {
                if (option) {
                    if (typeof option == 'string' && option in data) {
                        return data[option].apply(data, nargs);
                    } else {
                        $.error('Method ' +  option + ' does not exist on jQuery.taxi');
                    }
                }
            }
        });
    };

    // Extendable methods and objects
    // =================

    $.fn.taxi.constructor = Taxi;

    /*
    The built in transform function uses CSS3 transitions for better
    performance. You can override this method with your own implementation.
    The transform method takes three arguments:
        element — the parent element that contains the sections
        x — the pixel position being scrolled to
        options — an object containing user-specified options
    The method should return a jQuery promise object that is resolved upon
    completion of the animations.
    */
    $.fn.taxi.transform = function(element, x, options) {
        var dfd = $.Deferred();

        var currentPos = $(document).scrollTop();
        var delta = x - currentPos;
        var transitionString = options.scrollSpeed + 'ms ease';
        var transformString = 'translate(0, ' + delta + 'px)';

        $(window).scrollTop(x);
        element.css({
            '-webkit-transform': transformString,
            'transform': transformString
        })
        element[0].offsetHeight; // trigger reflow, flush CSS
        element.css({
            'transform': 'translate(0, 0)',
            '-webkit-transform': 'translate(0, 0)',
            'transition': transitionString,
            '-webkit-transition': transitionString
        });
        element[0].offsetHeight; // trigger reflow, flush CSS
        element.css({
            '-webkit-transition': '0ms ease',
            'transition': '0ms ease',
        });

        element.one('transitionend webkitTransitionEnd', dfd.resolve);
        return dfd.promise();
    };

    $.fn.taxi.defaults = {
        sectionSelector: 'section',
        expandedSectionClass: 'expanded',
        guidedScrolling: true,
        scrollSpeed: 1000,
        expandedScrollOffThreshold: 200,
        hideScrollbar: true
    };

})(jQuery);
<commit_msg>scope<commit_after>;(function($){
    'use strict';

    var Taxi = function(element, options) {
        this.$element = $(element);
        this.options = options;
        this.sectionData = [];  // populated on draw with objects of section metadata
        this.preventTransform = false;  // when true, calls to transform are ignored
        this.expandedScrollingMode = false;  // when true, prevents calls to transform through the movement handler
        this.scrollLock = new ScrollLock();

        $('body').css('margin', 0);
        this.$element.css('position', 'relative');

        this.draw();
        $(window).resize(this.draw.bind(this));

        if (this.options.guidedScrolling) {
            this.scrollLock.go('lock');
            $(document).on('movement', this._movementHandler.bind(this));
            this.$element.on('sectionchange.taxi', this._expandedScrollHandler.bind(this));
        } else {
            $(document).on('scroll', this._sectionChangeHandler.bind(this));
        }

        if (this.options.hideScrollbar) {
            $("<style type='text/css'>::-webkit-scrollbar { display: none; }</style>").appendTo('head');
        }
    };

    /** Fire events when the section changes.
        Called after transforms complete and on scroll events when
        guidedScrolling is false
    */
    Taxi.prototype._sectionChangeHandler = function() {
        var currentSection = this._currentSection();
        if (this._cur != currentSection) {
            this.$element.trigger('sectionchange.taxi', [currentSection, this._cur])
        }
        this._cur = currentSection;
    };

    /** Called when guidedScrolling is true and expandedScrollingMode is false.
        Drives transform events based on swipe-like events from user input.
    */
    Taxi.prototype._movementHandler = function(e, direction) {
        if (!this.expandedScrollingMode && !this.preventTransform) {
            if (direction == 'up') { this.previous(true); }
            else if (direction == 'down') { this.next(); }
        }
    };

    /** Called when guidedScrolling is true and the section changes.
        If the current section is an expanded section, it binds expanded
        scroll handlers which give control of scrolling to the user.
        When the user scrolls past the defined boundaries, the handlers
        are unbound, the user is moved to the next section
        and locked scrolling is turned back on.
    */
    Taxi.prototype._expandedScrollHandler = function(e, index) {
        if (this.sectionData[index].expanded) {

            var checkOnScroll = (function() {
                var viewportHeight = $(window).height();
                var viewportTop = $(document).scrollTop();
                var height = this.sectionData[index].height;
                var top = this.sectionData[index].top;

                var lowerLimit = viewportHeight + viewportTop > top + height + this.options.expandedScrollOffThreshold;
                var upperLimit = viewportTop < top - this.options.expandedScrollOffThreshold;

                if (upperLimit || lowerLimit) {
                    this.expandedScrollingMode = false;
                    this.scrollLock.go('lock');
                    $(document).off('scroll', checkOnScroll);

                }
            }).bind(this);

            this.expandedScrollingMode = true;
            this.scrollLock.go('unlock');
            $(document).on('scroll', checkOnScroll);
        }

    };

    /** Returns the index of the section currently in view.
    */
    Taxi.prototype._currentSection = function() {
        var scrollTop = $(document).scrollTop();

        var i = this.sectionData.length;
        while(i--) {
            if (scrollTop >= this.sectionData[i].top) {
                return i;
            }
        }
        return 0;  // catch negative scrolling browser behaviour
    };

    /** Sizes and positions the sections.
        Called on init and when a section is expanded or contracted.
        Can be manually called if a section is added, updated or removed
    */
    Taxi.prototype.draw = function() {

        var that = this;
        var sectionData = [];
        var viewportHeight = $(window).height();
        var sections = this.$element.children(this.options.sectionSelector);
        var currentPosition = 0;

        sections.each(function(index, el){
            var $el = $(el);
            var section = {
                element: $el,
                top: currentPosition,
                expanded: $el.hasClass(that.options.expandedSectionClass)
            };

            $el.css('height', 'auto');  // ensure appropriate measurement when redrawing
            var height = (section.expanded) ? section.element.outerHeight() : viewportHeight;
            section.height = height;

            sectionData.push(section);

            section.element.css({
                position: 'absolute',
                top: section.top,
                width: '100%',
                height: height,
                overflow: 'hidden',
            });

            currentPosition += height;

        });

        // If a descendent element of a section has a taxi-full-height data attribute,
        // it will be assigned the height of the viewport.
        sections.find('[data-taxi-full-height]').css('height', viewportHeight);

        this.sectionData = sectionData;

        return this;
    };

    /* Aligns the top of the current section to the top of the viewport
    */
    Taxi.prototype.snap = function() {
        var scrollTop = $(document).scrollTop();
        var currentSection = this._currentSection();
        var currentSectionData = this.sectionData[currentSection];

        if (scrollTop != currentSectionData.top) {
            this.transform(currentSectionData.top);
        }

        return this;
    };

    /* Transforms the top of the current section to the top of the viewport.
       If scrollToBottom is true, the bottom of the current section is aligned to the
       bottom of the viewport. (This only makes a difference for expanded sections.
       For sections where the height matches the viewport height, )
    */
    Taxi.prototype.to = function(index, scrollToBottom) {
        var that = this;

        if (index >= this.sectionData.length) {
            $.error('Out of range: this instance only has ' + this.sectionData.length + ' sections');
        }

        var cur = this._currentSection();
        var section = this.sectionData[index];
        scrollToBottom = (typeof scrollToBottom === 'boolean') ? scrollToBottom : false;

        if (scrollToBottom) {
            var destination = section.top + section.height - $(window).height();
        } else {
            var destination = section.top;
        }

        this.$element.trigger('moveto.start.taxi', [index, cur]);
        this.transform(destination).done(function(){
            that.$element.trigger('moveto.end.taxi', [index, cur]);
        });
        return this;
    };

    Taxi.prototype.previous = function(scrollToBottom) {
        var cur = this._currentSection();
        var index = (cur > 0) ? cur - 1 : cur;
        return this.to(index, scrollToBottom);
    };

    Taxi.prototype.next = function(scrollToBottom) {
        var cur = this._currentSection();
        var index = (cur < this.sectionData.length - 1) ? cur + 1 : cur;
        return this.to(index, scrollToBottom);
    };

    /** The main driver for simulated page scrolls. Accepts a pixel value
     *  which is scrolled to the top of the page. Calls to transform fail
     *  when preventTransform is true. The engine that drives animations is
     *  $.fn.taxi.transform. Returns a jQuery promise object.
     */
    Taxi.prototype.transform = function(x) {
        var that = this;
        var dfd = $.Deferred();

        // The transform fails if it is out of bounds or
        // if preventTransform is true
        if (this.preventTransform ||
            x < 0 ||
            x > $(document).height()) {
            dfd.reject();
        }

        // If the transform delta is 0, resolve immediately
        else if ($(document).scrollTop() == x) {
            dfd.resolve();
        }

        // Do the transform
        else {

            this.$element.trigger('transform.start.taxi');
            this.preventTransform = true;
            if (!this.options.guidedScrolling) this.scrollLock.go('lock');

            $.fn.taxi.transform(this.$element, x, this.options).done(function(){
                that.preventTransform = false;
                that._sectionChangeHandler();
                if (!that.options.guidedScrolling) that.scrollLock.go('unlock');
                dfd.resolve();
                that.$element.trigger('transform.end.taxi');
            });

        }

        return dfd.promise();
    };

    /** Sections with overflowing content can be turned into
     *  expanded or non-expanded sections on the fly
     *  Pass a method as 'expand', 'collapse' or 'toggle'
     *  and an index which is either the numeric index of the section
     *  within $element, or the element itself
     */
    Taxi.prototype.expand = function(method, indexOrElement) {
        var that = this;

        var index = (typeof indexOrElement === "number") ?
            indexOrElement :
            this.$element.children().index(indexOrElement);

        var section = this.sectionData[index];
        var currentSection = this._currentSection();
        var delta = section.element[0].scrollHeight - $(window).height();
        var currentScroll = $(document).scrollTop();

        var _expand = function() {
            section.element.addClass('expanded');
            that.draw();

            if (currentSection == index) {
                that._expandedScrollHandler(null, index);
            } else if (currentSection > index) {
                $(document).scrollTop(currentScroll + delta);
            }

            that.$element.trigger('sectionexpand.taxi', [index]);
        };

        var _collapse = function() {
            if (currentSection == index) {
                // Scroll the window back to the top of the section before
                // closing it
                that.transform(section.top).done(function(){
                    section.element.removeClass('expanded');
                    that.draw();
                    that.expandedScrollingMode = false;
                    that.$element.trigger('sectioncollapse.taxi', [index]);
                });
            } else if (currentSection > index) {
                // Offset the scroll value by the amount the window size
                // changes to keep the window in the same place

                $(document).scrollTop(currentScroll - delta);
                section.element.removeClass('expanded');
                that.draw();
                that.$element.trigger('sectioncollapse.taxi', [index]);

            } else {
                section.element.removeClass('expanded');
                that.draw();
                that.$element.trigger('sectioncollapse.taxi', [index]);
            }
        };

        if (!section.expanded &&
            (method == 'expand' || method == 'toggle')) {
            _expand();
        } else if (section.expanded &&
            (method == 'collapse' || method == 'toggle')) {
            _collapse();
        }

        return this;
    }

    /** ScrollLock toggle's the user's ability to scroll manually,
     *  by scroll wheels, touch events and key presses.
     *  Call ScrollLock.go('lock') to disable scrolling
     *  and ScrollLock.go('unlock') to reenable.
     */
    var ScrollLock = function(){
        this.isLocked = false;
        this.evtString = 'mousewheel.scrolllock DOMMouseScroll.scrolllock \
            MozMousePixelScroll.scrolllock touchstart.scrolllock \
            touchmove.scrolllock keydown.scrolllock'; // keydown.scrolllock';
        this.lockHandler = function(e) {
            var keycodes = [33, 32, 34, 37, 38, 39, 40, 65, 68, 83, 87];
            if (e.type !== 'keydown' || keycodes.indexOf(e.keyCode) > -1) {
                e.preventDefault();
            }
        }
    };

    ScrollLock.prototype.go = function(action) {
        if (!action) return this.isLocked;

        if (action == 'lock' && !this.isLocked) {
            $(document).on(this.evtString, this.lockHandler);
            this.isLocked = true;
        } else if (action == 'unlock' && this.isLocked) {
            $(document).off(this.evtString, this.lockHandler);
            this.isLocked = false;
        }
    };

    // Plugin definition
    // =================

    $.fn.taxi = function(option) {
        var nargs = Array.prototype.slice.call(arguments, 1);
        return this.each(function(){
            var $this = $(this);
            var data = $this.data('jquery.taxi');
            var options = $.extend({}, $.fn.taxi.defaults, typeof option == 'object' && option);

            if (!data) {
                $this.data('jquery.taxi', (data = new Taxi(this, options)));
            } else {
                if (option) {
                    if (typeof option == 'string' && option in data) {
                        return data[option].apply(data, nargs);
                    } else {
                        $.error('Method ' +  option + ' does not exist on jQuery.taxi');
                    }
                }
            }
        });
    };

    // Extendable methods and objects
    // =================

    $.fn.taxi.constructor = Taxi;

    /*
    The built in transform function uses CSS3 transitions for better
    performance. You can override this method with your own implementation.
    The transform method takes three arguments:
        element — the parent element that contains the sections
        x — the pixel position being scrolled to
        options — an object containing user-specified options
    The method should return a jQuery promise object that is resolved upon
    completion of the animations.
    */
    $.fn.taxi.transform = function(element, x, options) {
        var dfd = $.Deferred();

        var currentPos = $(document).scrollTop();
        var delta = x - currentPos;
        var transitionString = options.scrollSpeed + 'ms ease';
        var transformString = 'translate(0, ' + delta + 'px)';

        $(window).scrollTop(x);
        element.css({
            '-webkit-transform': transformString,
            'transform': transformString
        })
        element[0].offsetHeight; // trigger reflow, flush CSS
        element.css({
            'transform': 'translate(0, 0)',
            '-webkit-transform': 'translate(0, 0)',
            'transition': transitionString,
            '-webkit-transition': transitionString
        });
        element[0].offsetHeight; // trigger reflow, flush CSS
        element.css({
            '-webkit-transition': '0ms ease',
            'transition': '0ms ease',
        });

        element.one('transitionend webkitTransitionEnd', dfd.resolve);
        return dfd.promise();
    };

    $.fn.taxi.defaults = {
        sectionSelector: 'section',
        expandedSectionClass: 'expanded',
        guidedScrolling: true,
        scrollSpeed: 1000,
        expandedScrollOffThreshold: 200,
        hideScrollbar: true
    };

})(jQuery);
<|endoftext|>


<commit_before>'use strict';

require('should');
var request = require('supertest');
var async = require('async');

var AnyFetchProvider = require('../../lib/');
var Token = require('../../lib/models/token.js');
var helpers = require('./helpers');

var connectFunctions = helpers.connectFunctions;
var workersFile = helpers.workersFile;
var updateFile = helpers.updateFile;
var config = helpers.config;

describe("POST /update endpoint", function() {
  var updateServer = function(server, identifier, done) {
    if(!done) {
      done = function(err) {
        if(err) {
          throw err;
        }
      };
    }

    request(server).post('/update' + (identifier ? '/' + identifier : ''))
      .send({
        access_token: server.token,
        api_url: 'http://api.anyfetch.com',
        documents_per_update: 100,
        force: server.force
      })
      .expect(202)
      .end(done);
  };

  var token;

  beforeEach(AnyFetchProvider.debug.cleanTokens);

  beforeEach(function createToken1(done) {
    // Create a token, as-if /init/ workflow was properly done
    token = new Token({
      anyfetchToken: 'thetoken',
      data: {
        foo: 'bar'
      },
      accountName: 'test@anyfetch.com'
    });

    token.save(done);
  });

  beforeEach(function createToken2(done) {
    // Create a token, as-if /init/ workflow was properly done
    token = new Token({
      anyfetchToken: 'thetoken2',
      data: {
        foo: 'bar'
      },
      accountName: 'test@anyfetch.com',
      isUpdating: true,
      lastUpdate: new Date()
    });

    token.save(done);
  });

  beforeEach(function createToken3(done) {
    // Create a token, as-if /init/ workflow was properly done
    token = new Token({
      anyfetchToken: 'thetoken3',
      data: {
        foo: 'bar'
      },
      accountName: 'test@anyfetch.com',
      isUpdating: true,
      lastUpdate: new Date(Date.now() - 5 * 3600 * 1000 - 1)
    });

    token.save(done);
  });

  beforeEach(function createToken4(done) {
    // Create a token, as-if /init/ workflow was properly done
    token = new Token({
      anyfetchToken: 'thetoken4',
      data: {
        foo: 'bar'
      },
      accountName: 'test@anyfetch.com',
      isUpdating: true,
      lastUpdate: new Date(Date.now() - 5 * 3600 * 1000 - 1),
      requireRefresh: true
    });

    token.save(done);
  });

  it("should require access_token to update", function(done) {
    var server = AnyFetchProvider.createServer(connectFunctions, workersFile, updateFile, config);

    request(server)
      .post('/update')
      .send({
        api_url: 'http://api.anyfetch.com',
        documents_per_update: 100
      })
      .expect(409)
      .expect(/access_token/)
      .end(done);
  });

  it("should require documents_per_update to update", function(done) {
    var server = AnyFetchProvider.createServer(connectFunctions, workersFile, updateFile, config);

    request(server)
      .post('/update')
      .send({
        access_token: 'thetoken',
        api_url: 'http://api.anyfetch.com',
      })
      .expect(409)
      .expect(/documents_per_update/)
      .end(done);
  });

  it("should require valid access_token to update", function(done) {
    var server = AnyFetchProvider.createServer(connectFunctions, workersFile, updateFile, config);

    request(server)
      .post('/update')
      .send({
        access_token: 'dummy_access_token',
        api_url: 'http://api.anyfetch.com',
        documents_per_update: 100
      })
      .expect(404)
      .end(done);
  });

  it("should require isUpdating to false to update", function(done) {
    var server = AnyFetchProvider.createServer(connectFunctions, workersFile, updateFile, config);

    request(server)
      .post('/update')
      .send({
        access_token: 'thetoken2',
        api_url: 'http://api.anyfetch.com',
        documents_per_update: 100
      })
      .expect(429)
      .end(done);
  });

  it("should fail with a token which need a refresh", function(done) {
    var server = AnyFetchProvider.createServer(connectFunctions, workersFile, updateFile, config);

    request(server)
      .post('/update')
      .send({
        access_token: 'thetoken4',
        api_url: 'http://api.anyfetch.com',
        documents_per_update: 100
      })
      .expect(428)
      .end(done);
  });

  it("should update with isUpdating to true and force", function(done) {
    var server = AnyFetchProvider.createServer(connectFunctions, __dirname + '/../helpers/workers-test.js', __dirname + '/../helpers/update-test.js', config);

    server.token = 'thetoken2';
    server.force = true;

    updateServer(server, null, function(err) {
      if(err) {
        return done(err);
      }

      server.usersQueue.once('empty', function() {
        done();
      });
    });
  });

  it("should update with isUpdating to true and a good lastUpdate", function(done) {
    var server = AnyFetchProvider.createServer(connectFunctions, __dirname + '/../helpers/workers-test.js', __dirname + '/../helpers/update-test.js', config);

    server.token = 'thetoken3';

    updateServer(server, null, function(err) {
      if(err) {
        return done(err);
      }

      server.usersQueue.once('empty', function() {
        done();
      });
    });
  });

  it("should retrieve tasks and upload them", function(done) {
    this.timeout(10000);

    var counter = 0;
    var server = AnyFetchProvider.createServer(connectFunctions, __dirname + '/../helpers/workers-test-1.js', __dirname + '/../helpers/update-test.js', config);

    server.token = 'thetoken';
    server.force = false;

    server.usersQueue.on('job.task.completed', function() {
      counter += 1;
    });

    server.usersQueue.on('job.task.failed', function(job, err) {
      done(err);
    });

    server.usersQueue.on('job.update.failed', function(job, err) {
      done(err);
    });

    updateServer(server, null, function(err) {
      if(err) {
        return done(err);
      }

      server.usersQueue.once('empty', function() {
        server.usersQueue.removeAllListeners();
        counter.should.eql(3);

        Token.findOne({anyfetchToken: 'thetoken'}, function(err, token) {
          if(err) {
            return done(err);
          }

          token.isUpdating.should.eql(false);
          done();
        });
      });
    });
  });

  it("should retrieve tasks and upload just one task", function(done) {
    var counter = 0;
    var server = AnyFetchProvider.createServer(connectFunctions, __dirname + '/../helpers/workers-test-2.js', __dirname + '/../helpers/update-test.js', config);

    server.token = 'thetoken';
    server.force = false;

    server.usersQueue.on('job.task.completed', function() {
      counter += 1;
    });

    server.usersQueue.on('job.task.failed', function(job, err) {
      done(err);
    });

    server.usersQueue.on('job.update.failed', function(job, err) {
      done(err);
    });

    updateServer(server, 'b', function(err) {
      if(err) {
        return done(err);
      }

      server.usersQueue.once('empty', function() {
        server.usersQueue.removeAllListeners();
        counter.should.eql(1);
        done();
      });
    });
  });

  it("should allow to update token data", function(done) {
    var counter = 0;
    var server = AnyFetchProvider.createServer(connectFunctions, __dirname + '/../helpers/workers-test-3.js', __dirname + '/../helpers/update-test.js', config);

    server.token = 'thetoken';
    server.force = false;

    server.usersQueue.on('job.task.completed', function() {
      counter += 1;
    });

    server.usersQueue.on('job.task.failed', function(job, err) {
      done(err);
    });

    server.usersQueue.on('job.update.failed', function(job, err) {
      done(err);
    });

    updateServer(server, null, function(err) {
      if(err) {
        return done(err);
      }

      server.usersQueue.once('empty', function() {
        server.usersQueue.removeAllListeners();
        counter.should.eql(3);
        done();
      });
    });
  });

  it("should set requireRefresh to true when we send a TokenError", function(done) {
    var server = AnyFetchProvider.createServer(connectFunctions, __dirname + '/../helpers/workers-token-error.js', __dirname + '/../helpers/update-test.js', config);

    server.token = 'thetoken';
    server.force = false;

    async.waterfall([
      function update(cb) {
        server.usersQueue.on('job.task.failed', function(job, err) {
          cb(err);
        });

        server.usersQueue.on('job.update.failed', function(job, err) {
          cb(err);
        });

        updateServer(server, null, function(err) {
          if(err) {
            return cb(err);
          }

          server.usersQueue.once('empty', function() {
            server.usersQueue.removeAllListeners();
            cb();
          });
        });
      },
      function retrieveToken(cb) {
        Token.findOne({anyfetchToken: 'thetoken'}, cb);
      },
      function checkToken(token, cb) {
        if(!token) {
          return cb(new Error("Can't retrieve token"));
        }

        token.requireRefresh.should.be.true;
        cb();
      }
    ], done);
  });
});
<commit_msg>Fix lint<commit_after>'use strict';

require('should');
var request = require('supertest');
var async = require('async');

var AnyFetchProvider = require('../../lib/');
var Token = require('../../lib/models/token.js');
var helpers = require('./helpers');

var connectFunctions = helpers.connectFunctions;
var workersFile = helpers.workersFile;
var updateFile = helpers.updateFile;
var config = helpers.config;

describe("POST /update endpoint", function() {
  var updateServer = function(server, identifier, done) {
    if(!done) {
      done = function(err) {
        if(err) {
          throw err;
        }
      };
    }

    request(server).post('/update' + (identifier ? '/' + identifier : ''))
      .send({
        access_token: server.token,
        api_url: 'http://api.anyfetch.com',
        documents_per_update: 100,
        force: server.force
      })
      .expect(202)
      .end(done);
  };

  var token;

  beforeEach(AnyFetchProvider.debug.cleanTokens);

  beforeEach(function createToken1(done) {
    // Create a token, as-if /init/ workflow was properly done
    token = new Token({
      anyfetchToken: 'thetoken',
      data: {
        foo: 'bar'
      },
      accountName: 'test@anyfetch.com'
    });

    token.save(done);
  });

  beforeEach(function createToken2(done) {
    // Create a token, as-if /init/ workflow was properly done
    token = new Token({
      anyfetchToken: 'thetoken2',
      data: {
        foo: 'bar'
      },
      accountName: 'test@anyfetch.com',
      isUpdating: true,
      lastUpdate: new Date()
    });

    token.save(done);
  });

  beforeEach(function createToken3(done) {
    // Create a token, as-if /init/ workflow was properly done
    token = new Token({
      anyfetchToken: 'thetoken3',
      data: {
        foo: 'bar'
      },
      accountName: 'test@anyfetch.com',
      isUpdating: true,
      lastUpdate: new Date(Date.now() - 5 * 3600 * 1000 - 1)
    });

    token.save(done);
  });

  beforeEach(function createToken4(done) {
    // Create a token, as-if /init/ workflow was properly done
    token = new Token({
      anyfetchToken: 'thetoken4',
      data: {
        foo: 'bar'
      },
      accountName: 'test@anyfetch.com',
      isUpdating: true,
      lastUpdate: new Date(Date.now() - 5 * 3600 * 1000 - 1),
      requireRefresh: true
    });

    token.save(done);
  });

  it("should require access_token to update", function(done) {
    var server = AnyFetchProvider.createServer(connectFunctions, workersFile, updateFile, config);

    request(server)
      .post('/update')
      .send({
        api_url: 'http://api.anyfetch.com',
        documents_per_update: 100
      })
      .expect(409)
      .expect(/access_token/)
      .end(done);
  });

  it("should require documents_per_update to update", function(done) {
    var server = AnyFetchProvider.createServer(connectFunctions, workersFile, updateFile, config);

    request(server)
      .post('/update')
      .send({
        access_token: 'thetoken',
        api_url: 'http://api.anyfetch.com',
      })
      .expect(409)
      .expect(/documents_per_update/)
      .end(done);
  });

  it("should require valid access_token to update", function(done) {
    var server = AnyFetchProvider.createServer(connectFunctions, workersFile, updateFile, config);

    request(server)
      .post('/update')
      .send({
        access_token: 'dummy_access_token',
        api_url: 'http://api.anyfetch.com',
        documents_per_update: 100
      })
      .expect(404)
      .end(done);
  });

  it("should require isUpdating to false to update", function(done) {
    var server = AnyFetchProvider.createServer(connectFunctions, workersFile, updateFile, config);

    request(server)
      .post('/update')
      .send({
        access_token: 'thetoken2',
        api_url: 'http://api.anyfetch.com',
        documents_per_update: 100
      })
      .expect(429)
      .end(done);
  });

  it("should fail with a token which need a refresh", function(done) {
    var server = AnyFetchProvider.createServer(connectFunctions, workersFile, updateFile, config);

    request(server)
      .post('/update')
      .send({
        access_token: 'thetoken4',
        api_url: 'http://api.anyfetch.com',
        documents_per_update: 100
      })
      .expect(428)
      .end(done);
  });

  it("should update with isUpdating to true and force", function(done) {
    var server = AnyFetchProvider.createServer(connectFunctions, __dirname + '/../helpers/workers-test.js', __dirname + '/../helpers/update-test.js', config);

    server.token = 'thetoken2';
    server.force = true;

    updateServer(server, null, function(err) {
      if(err) {
        return done(err);
      }

      server.usersQueue.once('empty', function() {
        done();
      });
    });
  });

  it("should update with isUpdating to true and a good lastUpdate", function(done) {
    var server = AnyFetchProvider.createServer(connectFunctions, __dirname + '/../helpers/workers-test.js', __dirname + '/../helpers/update-test.js', config);

    server.token = 'thetoken3';

    updateServer(server, null, function(err) {
      if(err) {
        return done(err);
      }

      server.usersQueue.once('empty', function() {
        done();
      });
    });
  });

  it("should retrieve tasks and upload them", function(done) {
    this.timeout(10000);

    var counter = 0;
    var server = AnyFetchProvider.createServer(connectFunctions, __dirname + '/../helpers/workers-test-1.js', __dirname + '/../helpers/update-test.js', config);

    server.token = 'thetoken';
    server.force = false;

    server.usersQueue.on('job.task.completed', function() {
      counter += 1;
    });

    server.usersQueue.on('job.task.failed', function(job, err) {
      done(err);
    });

    server.usersQueue.on('job.update.failed', function(job, err) {
      done(err);
    });

    updateServer(server, null, function(err) {
      if(err) {
        return done(err);
      }

      server.usersQueue.once('empty', function() {
        server.usersQueue.removeAllListeners();
        counter.should.eql(3);

        Token.findOne({anyfetchToken: 'thetoken'}, function(err, token) {
          if(err) {
            return done(err);
          }

          token.isUpdating.should.eql(false);
          done();
        });
      });
    });
  });

  it("should retrieve tasks and upload just one task", function(done) {
    var counter = 0;
    var server = AnyFetchProvider.createServer(connectFunctions, __dirname + '/../helpers/workers-test-2.js', __dirname + '/../helpers/update-test.js', config);

    server.token = 'thetoken';
    server.force = false;

    server.usersQueue.on('job.task.completed', function() {
      counter += 1;
    });

    server.usersQueue.on('job.task.failed', function(job, err) {
      done(err);
    });

    server.usersQueue.on('job.update.failed', function(job, err) {
      done(err);
    });

    updateServer(server, 'b', function(err) {
      if(err) {
        return done(err);
      }

      server.usersQueue.once('empty', function() {
        server.usersQueue.removeAllListeners();
        counter.should.eql(1);
        done();
      });
    });
  });

  it("should allow to update token data", function(done) {
    var counter = 0;
    var server = AnyFetchProvider.createServer(connectFunctions, __dirname + '/../helpers/workers-test-3.js', __dirname + '/../helpers/update-test.js', config);

    server.token = 'thetoken';
    server.force = false;

    server.usersQueue.on('job.task.completed', function() {
      counter += 1;
    });

    server.usersQueue.on('job.task.failed', function(job, err) {
      done(err);
    });

    server.usersQueue.on('job.update.failed', function(job, err) {
      done(err);
    });

    updateServer(server, null, function(err) {
      if(err) {
        return done(err);
      }

      server.usersQueue.once('empty', function() {
        server.usersQueue.removeAllListeners();
        counter.should.eql(3);
        done();
      });
    });
  });

  it("should set requireRefresh to true when we send a TokenError", function(done) {
    var server = AnyFetchProvider.createServer(connectFunctions, __dirname + '/../helpers/workers-token-error.js', __dirname + '/../helpers/update-test.js', config);

    server.token = 'thetoken';
    server.force = false;

    async.waterfall([
      function update(cb) {
        server.usersQueue.on('job.task.failed', function(job, err) {
          cb(err);
        });

        server.usersQueue.on('job.update.failed', function(job, err) {
          cb(err);
        });

        updateServer(server, null, function(err) {
          if(err) {
            return cb(err);
          }

          server.usersQueue.once('empty', function() {
            server.usersQueue.removeAllListeners();
            cb();
          });
        });
      },
      function retrieveToken(cb) {
        Token.findOne({anyfetchToken: 'thetoken'}, cb);
      },
      function checkToken(token, cb) {
        if(!token) {
          return cb(new Error("Can't retrieve token"));
        }

        token.requireRefresh.should.eql(true);
        cb();
      }
    ], done);
  });
});
<|endoftext|>


<commit_before>'use strict';

const assert = require('chai').assert;
const Harray = require('../lib/harray');

describe('Some Method', () => {
    it('Iterates through elements of a Harray until the callback returns true', () => {
        let h = new Harray(0, 2);
        let expected = [0, 2, 4, 6, 8, 10];
        let actual = [];

        h.some(function(el) {
            if (el > 10) {
                return true;
            } else {
                actual.push(el);
            }
        });

        assert.strictEqual(JSON.stringify(actual), JSON.stringify(expected));
    });

    it('Accepts an starting index', () => {
        let h = new Harray(0, 2);
        let expected = [4, 6, 8, 10];
        let actual = [];

        h.some(function(el) {
            if (el > 10) {
                return false;
            } else {
                actual.push(el);
                return true;
            }
        }, 2);

        assert.strictEqual(JSON.stringify(actual), JSON.stringify(expected));
    });

    it('Throws a TypeError if the argument is not an array', () => {
        let h = new Harray(0, 2);
        assert.throws(() => {
            h.some('hue');
        }, TypeError);
    });
});
<commit_msg>Fix some method tests<commit_after>'use strict';

const assert = require('chai').assert;
const Harray = require('../lib/harray');

describe('Some Method', () => {
    it('Iterates through elements of a Harray until the callback returns true', () => {
        let h = new Harray(0, 2);
        let expected = [0, 2, 4, 6, 8, 10];
        let actual = [];

        h.some(function(el) {
            if (el > 10) {
                return true;
            } else {
                actual.push(el);
            }
        });

        assert.strictEqual(JSON.stringify(actual), JSON.stringify(expected));
    });

    it('Accepts an starting index', () => {
        let h = new Harray(0, 2);
        let expected = [4, 6, 8, 10];
        let actual = [];

        h.some(function(el) {
            if (el > 10) {
                return true;
            } else {
                actual.push(el);
                return false;
            }
        }, 2);

        assert.strictEqual(JSON.stringify(actual), JSON.stringify(expected));
    });

    it('Throws a TypeError if the argument is not an array', () => {
        let h = new Harray(0, 2);
        assert.throws(() => {
            h.some('hue');
        }, TypeError);
    });
});
<|endoftext|>


<commit_before>/**
 * hermes-bus <https://github.com/jahnestacado/hermes-bus>
 * Copyright (c) 2014 Ioannis Tzanellis
 * Licensed under the MIT License (MIT).
 */

var assert = require("assert");
var bus = require("./..");
var sinon = require("sinon");

describe('#################### Start integration tests for hermes-bus module \n', function() {

    describe("emit events", function() {

        var firstEventCallback = sinon.spy();
        var secondEventCallback = sinon.spy();

        bus.onEvent("firstEvent", firstEventCallback);
        bus.onEvent("secondEvent", secondEventCallback);

        describe('invocation of bus.emitFirstEvent', function() {
            var firstEventArg1 = {isDummy: true};
            var firstEventArg2 = "frrrrr";
            var firstEventArg3 = 639;

            before(function() {
                bus.emitFirstEvent(firstEventArg1, firstEventArg2, firstEventArg3);
            });

            it('should invoke firstCallback once', function() {
                assert(firstEventCallback.calledOnce);
            });

            it("should invoke firstCallback with the right argument", function() {
                assert(firstEventCallback.calledWith(firstEventArg1, firstEventArg2, firstEventArg3));
            });

            it('should not invoke secondCallback', function() {
                assert(firstEventCallback.calledOnce, false);
            });

            describe('invocation of bus.emitSecondEvent', function() {
                var secondEventArg1 = {isDummy: true};
                var secondEventArg2 = [3, 5, 6, ["4"]];

                before(function() {
                    bus.emitSecondEvent(firstEventArg1, secondEventArg2);
                });

                it('should invoke secondCallback once', function() {
                    assert(secondEventCallback.calledOnce);
                });

                it("should invoke secondCallback with the right argument", function() {
                    assert(secondEventCallback.calledWith(secondEventArg1, secondEventArg2));
                });

                it('should not invoke firstCallback again', function() {
                    assert(firstEventCallback.calledOnce);
                });

                describe('create "red busline" ', function() {
                    var thirdEventCallback = sinon.spy();

                    before(function() {
                        bus.onEvent("red", "firstEvent", thirdEventCallback);
                    });

                    describe('invocation of bus.red.emitFirstEvent', function() {
                        var thirdEventArg1 = {isDummy: true};

                        before(function() {
                            bus.red.emitFirstEvent(thirdEventArg1);
                        });

                        it('should invoke thirdCallback once', function() {
                            assert(thirdEventCallback.calledOnce);
                        });

                        it("should invoke thirdCallback with the right argument", function() {
                            assert(thirdEventCallback.calledWith(thirdEventArg1));
                        });

                        it('should not invoke firstCallback again', function() {
                            assert(firstEventCallback.calledOnce);
                        });

                        it('should not invoke secondCallback again', function() {
                            assert(secondEventCallback.calledOnce);
                        });

                        describe('disable and emit thirdEvent of "red" busline', function() {

                            before(function() {
                                bus.red.deactivateEvent("firstEvent");
                                bus.red.emitFirstEvent();
                            });

                            it('should not invoke thirdCallback again', function() {
                                assert(thirdEventCallback.calledOnce);
                            });

                            it('should not invoke firstCallback again', function() {
                                assert(firstEventCallback.calledOnce);
                            });

                            it('should not invoke secondCallback again', function() {
                                assert(secondEventCallback.calledOnce);
                            });

                            describe('re-enable and emit thirdEvent of "red" busline', function() {

                                before(function() {
                                    bus.red.activateEvent("firstEvent");
                                    bus.red.emitFirstEvent();
                                });

                                it('should invoke thirdCallback for second time', function() {
                                    assert(thirdEventCallback.calledTwice);
                                });

                                it('should not invoke firstCallback again', function() {
                                    assert(firstEventCallback.calledOnce);
                                });

                                it('should not invoke secondCallback again', function() {
                                    assert(secondEventCallback.calledOnce);
                                });

                            });

                            describe('create "green" and "black" and "white" buslines ', function() {

                                before(function() {
                                    bus.onEvent("green", "dummyEvent", function() {});
                                    bus.onEvent("black", "dummyEvent", function() {});
                                });

                                it('should have "green" busline ', function() {
                                    assert(bus.green);
                                });

                                it('should have "black" busline ', function() {
                                    assert(bus.black);
                                });

                                describe('invoke reset on "main" busline', function() {

                                    before(function() {
                                        bus.reset();
                                    });

                                    it('should not have emitFirstEvent function on "main" busline ', function() {
                                        assert.equal(bus.emitFirstEvent, undefined);
                                    });

                                    it('should not have emitSecondEvent function on "main" busline', function() {
                                        assert.equal(bus.emitSecondEvent, undefined);
                                    });

                                    it('should maintain "red" busline ', function() {
                                        assert(bus.red);
                                    });

                                    it('should maintain "green" busline ', function() {
                                        assert(bus.green);
                                    });

                                    describe('invoke destroy on "red" busline', function() {

                                        before(function() {
                                            bus.red.destroy();
                                        });

                                        it('should destroy "red" busline ', function() {
                                            assert.equal(bus.red, undefined);
                                        });

                                        describe('invoke hardReset on "main" busline', function() {

                                            before(function() {
                                                bus.hardReset();
                                            });

                                            it('should destroy "green" busline ', function() {
                                                assert.equal(bus.green, undefined);
                                            });

                                            it('should destroy "white" busline ', function() {
                                                assert.equal(bus.green, undefined);
                                            });

                                        });
                                    });

                                });
                            });

                        });

                    });
                });

            });

        });

        describe('resolve events', function() {
            function getRandomInt(min, max) {
                return Math.floor(Math.random() * (max - min + 1)) + min;
            }

            function addCb(a, b) {
                return a + b;
            }
            function mulCb(a, b) {
                return a * b;
            }

            function divCb(a, b) {
                return a / b;
            }

            function getDelayedAsyncFunc(cb, delay) {
                return    function asyncFunc(a, b, resolve) {
                    setTimeout(function() {
                        resolve(cb(a, b));
                    }, delay);
                }
            }

            var firstEventCallback = sinon.spy(getDelayedAsyncFunc(addCb, getRandomInt(500)));
            var secondEventCallback = sinon.spy(getDelayedAsyncFunc(mulCb, getRandomInt(500)));
            var thirdEventCallback = sinon.spy(getDelayedAsyncFunc(divCb, getRandomInt(500)));

            describe('register events', function() {

                before(function() {
                    bus.onEvent("syncLine", "forthEvent", firstEventCallback);
                    bus.onEvent("syncLine", "forthEvent", secondEventCallback);
                    bus.onEvent("syncLine", "forthEvent", thirdEventCallback);
                });

                describe('invocation of bus.syncLine.resolveForthEvent with use of .then()', function() {
                    var a = 566;
                    var b = 5;
                    var results;
                    before(function(done) {
                        bus.syncLine.resolveForthEvent(a, b)
                                .then(function(output) {
                                    results = output;
                                    done();
                                });
                    });

                    it('should invoke firstEventCallback once', function() {
                        assert(firstEventCallback.calledOnce);
                    });

                    it('should invoke firstEventCallback once', function() {
                        assert(secondEventCallback.calledOnce);
                    });

                    it('should invoke firstEventCallback once', function() {
                        assert(thirdEventCallback.calledOnce);
                    });

                    it("should invoke firstEventCallback with the right arguments", function() {
                        assert(firstEventCallback.calledWith(a, b));
                    });

                    it("should invoke secondEventCallback with the right arguments", function() {
                        assert(secondEventCallback.calledWith(a, b));
                    });

                    it("should invoke thirdEventCallback with the right arguments", function() {
                        assert(thirdEventCallback.calledWith(a, b));
                    });

                    it('first element of "results" should be equal to 571', function() {
                        assert.equal(results[0], 571);
                    });

                    it('second element of "results" should be equal to 2830', function() {
                        assert.equal(results[1], 2830);
                    });

                    it('first element of "results" should be equal to 113.2', function() {
                        assert.equal(results[2], 113.2);
                    });

                });

            });

        });

        after(function() {
            console.log("\n  #################### End of integration tests for hermes-bus module");
        });
    });
});<commit_msg>test/hermes-bus.test.js: Improved tests for 'hardRest' function and uniformly used double-quotes for string declaration<commit_after>/**
 * hermes-bus <https://github.com/jahnestacado/hermes-bus>
 * Copyright (c) 2014 Ioannis Tzanellis
 * Licensed under the MIT License (MIT).
 */

var assert = require("assert");
var bus = require("./..");
var sinon = require("sinon");

describe('#################### Start integration tests for hermes-bus module \n', function() {

    describe("emit events", function() {

        var firstEventCallback = sinon.spy();
        var secondEventCallback = sinon.spy();

        bus.onEvent("firstEvent", firstEventCallback);
        bus.onEvent("secondEvent", secondEventCallback);

        describe("when invoking bus.emitFirstEvent", function() {
            var firstEventArg1 = {isDummy: true};
            var firstEventArg2 = "frrrrr";
            var firstEventArg3 = 639;

            before(function() {
                bus.emitFirstEvent(firstEventArg1, firstEventArg2, firstEventArg3);
            });

            it("should invoke firstCallback once", function() {
                assert(firstEventCallback.calledOnce);
            });

            it("should invoke firstCallback with the right argument", function() {
                assert(firstEventCallback.calledWith(firstEventArg1, firstEventArg2, firstEventArg3));
            });

            it("should not invoke secondCallback", function() {
                assert(firstEventCallback.calledOnce, false);
            });

            describe("when invoking bus.emitSecondEvent", function() {
                var secondEventArg1 = {isDummy: true};
                var secondEventArg2 = [3, 5, 6, ["4"]];

                before(function() {
                    bus.emitSecondEvent(firstEventArg1, secondEventArg2);
                });

                it("should invoke secondCallback once", function() {
                    assert(secondEventCallback.calledOnce);
                });

                it("should invoke secondCallback with the right argument", function() {
                    assert(secondEventCallback.calledWith(secondEventArg1, secondEventArg2));
                });

                it("should not invoke firstCallback again", function() {
                    assert(firstEventCallback.calledOnce);
                });

                describe("creating 'red busline' ", function() {
                    var thirdEventCallback = sinon.spy();

                    before(function() {
                        bus.onEvent("red", "firstEvent", thirdEventCallback);
                    });

                    describe("when invoking bus.red.emitFirstEvent", function() {
                        var thirdEventArg1 = {isDummy: true};

                        before(function() {
                            bus.red.emitFirstEvent(thirdEventArg1);
                        });

                        it("should invoke thirdCallback once", function() {
                            assert(thirdEventCallback.calledOnce);
                        });

                        it("should invoke thirdCallback with the right argument", function() {
                            assert(thirdEventCallback.calledWith(thirdEventArg1));
                        });

                        it("should not invoke firstCallback again", function() {
                            assert(firstEventCallback.calledOnce);
                        });

                        it("should not invoke secondCallback again", function() {
                            assert(secondEventCallback.calledOnce);
                        });

                        describe("when disabling and emitting thirdEvent of 'red' busline", function() {

                            before(function() {
                                bus.red.deactivateEvent("firstEvent");
                                bus.red.emitFirstEvent();
                            });

                            it("should not invoke thirdCallback again", function() {
                                assert(thirdEventCallback.calledOnce);
                            });

                            it("should not invoke firstCallback again", function() {
                                assert(firstEventCallback.calledOnce);
                            });

                            it("should not invoke secondCallback again", function() {
                                assert(secondEventCallback.calledOnce);
                            });

                            describe("when re-enabling and emitting thirdEvent of 'red' busline", function() {

                                before(function() {
                                    bus.red.activateEvent("firstEvent");
                                    bus.red.emitFirstEvent();
                                });

                                it("should invoke thirdCallback for second time", function() {
                                    assert(thirdEventCallback.calledTwice);
                                });

                                it("should not invoke firstCallback again", function() {
                                    assert(firstEventCallback.calledOnce);
                                });

                                it("should not invoke secondCallback again", function() {
                                    assert(secondEventCallback.calledOnce);
                                });

                            });

                            describe("when creating 'green' and 'black' and 'white' buslines", function() {

                                var dummyEventCallback = sinon.spy();

                                before(function() {
                                    bus.onEvent("green", "dummyEvent", dummyEventCallback);
                                    bus.onEvent("black", "dummyEvent", dummyEventCallback);
                                });

                                it("should have 'green' busline", function() {
                                    assert(bus.green);
                                });

                                it("should have 'black' busline", function() {
                                    assert(bus.black);
                                });

                                describe("when invoking reset on 'main' busline", function() {

                                    before(function() {
                                        bus.reset();
                                    });

                                    it("should not have emitFirstEvent function on 'main' busline", function() {
                                        assert.equal(bus.emitFirstEvent, undefined);
                                    });

                                    it("should not have emitSecondEvent function on 'main' busline", function() {
                                        assert.equal(bus.emitSecondEvent, undefined);
                                    });

                                    it("should maintain 'red' busline", function() {
                                        assert(bus.red);
                                    });

                                    it("should maintain 'green' busline", function() {
                                        assert(bus.green);
                                    });

                                    describe("when invoking destroy on 'red' busline", function() {

                                        before(function() {
                                            bus.red.destroy();
                                        });

                                        it("should destroy 'red' busline", function() {
                                            assert.equal(bus.red, undefined);
                                        });

                                        describe("when invoking hardReset on 'main' busline", function() {

                                            before(function() {
                                                bus.hardReset();
                                            });

                                            it("should destroy 'green' busline", function() {
                                                assert.equal(bus.green, undefined);
                                            });

                                            it("should destroy 'white' busline", function() {
                                                assert.equal(bus.green, undefined);
                                            });

                                            describe("when creating again 'dummyEvent' message on 'green' busline ", function() {

                                                before(function() {
                                                    bus.onEvent("green", "dummyEvent", dummyEventCallback);
                                                });

                                                it("should not have invoked 'dummyEventCallback' until this point", function() {
                                                    assert.equal(dummyEventCallback.called, false);
                                                });

                                                describe("when emitting 'dummyEvent' message on 'green' busline ", function() {

                                                    before(function() {
                                                        bus.green.emitDummyEvent();
                                                    });

                                                    it("should invoke 'dummyEventCallback' only once", function() {
                                                        assert(dummyEventCallback.calledOnce);
                                                    });

                                                });

                                            });

                                        });

                                    });

                                });

                            });

                        });

                    });

                });

            });

        });

        describe("when resolving events", function() {

            function getRandomInt(min, max) {
                return Math.floor(Math.random() * (max - min + 1)) + min;
            }

            function addCb(a, b) {
                return a + b;
            }
            function mulCb(a, b) {
                return a * b;
            }

            function divCb(a, b) {
                return a / b;
            }

            function getDelayedAsyncFunc(cb, delay) {
                return    function asyncFunc(a, b, resolve) {
                    setTimeout(function() {
                        resolve(cb(a, b));
                    }, delay);
                }
            }

            var firstEventCallback = sinon.spy(getDelayedAsyncFunc(addCb, getRandomInt(500)));
            var secondEventCallback = sinon.spy(getDelayedAsyncFunc(mulCb, getRandomInt(500)));
            var thirdEventCallback = sinon.spy(getDelayedAsyncFunc(divCb, getRandomInt(500)));

            describe("when registering events", function() {

                before(function() {
                    bus.onEvent("syncLine", "forthEvent", firstEventCallback);
                    bus.onEvent("syncLine", "forthEvent", secondEventCallback);
                    bus.onEvent("syncLine", "forthEvent", thirdEventCallback);
                });

                describe("when invoking  bus.syncLine.resolveForthEvent with use of .then()", function() {
                    var a = 566;
                    var b = 5;
                    var results;
                    before(function(done) {
                        bus.syncLine.resolveForthEvent(a, b)
                                .then(function(output) {
                                    results = output;
                                    done();
                                });
                    });

                    it("should invoke firstEventCallback once", function() {
                        assert(firstEventCallback.calledOnce);
                    });

                    it("should invoke firstEventCallback once", function() {
                        assert(secondEventCallback.calledOnce);
                    });

                    it("should invoke firstEventCallback once", function() {
                        assert(thirdEventCallback.calledOnce);
                    });

                    it("should invoke firstEventCallback with the right arguments", function() {
                        assert(firstEventCallback.calledWith(a, b));
                    });

                    it("should invoke secondEventCallback with the right arguments", function() {
                        assert(secondEventCallback.calledWith(a, b));
                    });

                    it("should invoke thirdEventCallback with the right arguments", function() {
                        assert(thirdEventCallback.calledWith(a, b));
                    });

                    it("first element of 'results' should be equal to 571", function() {
                        assert.equal(results[0], 571);
                    });

                    it("second element of 'results' should be equal to 2830", function() {
                        assert.equal(results[1], 2830);
                    });

                    it("first element of 'results' should be equal to 113.2", function() {
                        assert.equal(results[2], 113.2);
                    });

                });

            });

        });

        after(function() {
            console.log("\n  #################### End of integration tests for hermes-bus module");
        });
    });
});<|endoftext|>


<commit_before>/* global describe, before, beforeEach, it */

const path = require('path');
const assert = require('yeoman-assert');
const helpers = require('yeoman-test');
const fse = require('fs-extra');
const constants = require('../generators/generator-constants');

const SERVER_MAIN_SRC_DIR = constants.SERVER_MAIN_SRC_DIR;
const SERVER_TEST_SRC_DIR = constants.SERVER_TEST_SRC_DIR;

const entityFiles = [
    `${SERVER_MAIN_SRC_DIR}com/mycompany/myapp/domain/Job.java`,
    `${SERVER_MAIN_SRC_DIR}com/mycompany/myapp/repository/JobRepository.java`,
    `${SERVER_MAIN_SRC_DIR}com/mycompany/myapp/web/rest/JobResource.java`,
    `${SERVER_TEST_SRC_DIR}com/mycompany/myapp/web/rest/JobResourceIntTest.java`,
];

describe.only('JHipster generator import jdl', () => {
    describe('imports a JDL model from single file with --json-only flag', () => {
        beforeEach((done) => {
            helpers.run(require.resolve('../generators/import-jdl'))
                .inTmpDir((dir) => {
                    fse.copySync(path.join(__dirname, '../test/templates/import-jdl'), dir);
                })
                .withArguments(['jdl.jdl'])
                .withOptions({ 'json-only': true })
                .on('end', done);
        });

        it('creates entity json files', () => {
            assert.file([
                '.jhipster/Department.json',
                '.jhipster/JobHistory.json',
                '.jhipster/Job.json',
                '.jhipster/Employee.json',
                '.jhipster/Location.json',
                '.jhipster/Task.json',
                '.jhipster/Country.json',
                '.jhipster/Region.json'
            ]);
        });
        it('does not create actual entity files', () => {
            assert.noFile(entityFiles);
        });
    });
    describe('imports a JDL model from single file', () => {
        beforeEach((done) => {
            helpers.run(require.resolve('../generators/import-jdl'))
                .inTmpDir((dir) => {
                    fse.copySync(path.join(__dirname, '../test/templates/import-jdl'), dir);
                })
                .withArguments(['jdl.jdl'])
                .on('end', done);
        });

        it('creates entity json files', () => {
            assert.file([
                '.jhipster/Department.json',
                '.jhipster/JobHistory.json',
                '.jhipster/Job.json',
                '.jhipster/Employee.json',
                '.jhipster/Location.json',
                '.jhipster/Task.json',
                '.jhipster/Country.json',
                '.jhipster/Region.json'
            ]);
        });
        it('creates actual entity files', () => {
            assert.file(entityFiles);
        });
    });
    describe('imports JDL apps and entities', () => {
        before((done) => {
            helpers.run(require.resolve('../generators/import-jdl'))
                .inTmpDir((dir) => {
                    fse.copySync(path.join(__dirname, '../test/templates/import-jdl'), dir);
                })
                .withArguments(['apps-and-entities.jdl'])
                .on('end', done);
        });

        it('creates the applications', () => {
            assert.file([
                path.join('myFirstApp', '.yo-rc.json'),
                path.join('mySecondApp', '.yo-rc.json'),
                path.join('myThirdApp', '.yo-rc.json')
            ]);
        });
        it('creates the entities', () => {
            assert.file([
                path.join('myFirstApp', '.jhipster', 'A.json'),
                path.join('myFirstApp', '.jhipster', 'B.json'),
                path.join('myFirstApp', '.jhipster', 'E.json'),
                path.join('myFirstApp', '.jhipster', 'F.json'),
                path.join('mySecondApp', '.jhipster', 'E.json'),
                path.join('myThirdApp', '.jhipster', 'F.json')
            ]);
        });
    });
    describe.only('imports single app and entities', () => {
        before((done) => {
            helpers.run(require.resolve('../generators/import-jdl'))
                .inTmpDir((dir) => {
                    fse.copySync(path.join(__dirname, '../test/templates/import-jdl'), dir);
                })
                .withOptions({ skipInstall: true })
                .withArguments(['single-app-and-entities.jdl'])
                .on('end', done);
        });

        it('creates the application', () => {
            assert.file(['.yo-rc.json']);
        });
        it('creates the entities', () => {
            assert.file([
                path.join('.jhipster', 'A.json'),
                path.join('.jhipster', 'B.json'),
            ]);
        });
    });
    describe('imports a JDL model from multiple files', () => {
        beforeEach((done) => {
            helpers.run(require.resolve('../generators/import-jdl'))
                .inTmpDir((dir) => {
                    fse.copySync(path.join(__dirname, '../test/templates/import-jdl'), dir);
                })
                .withArguments(['jdl.jdl', 'jdl2.jdl', 'jdl-ambiguous.jdl'])
                .on('end', done);
        });

        it('creates entity json files', () => {
            assert.file([
                '.jhipster/Department.json',
                '.jhipster/JobHistory.json',
                '.jhipster/Job.json',
                '.jhipster/Employee.json',
                '.jhipster/Location.json',
                '.jhipster/Task.json',
                '.jhipster/Country.json',
                '.jhipster/Region.json',
                '.jhipster/DepartmentAlt.json',
                '.jhipster/JobHistoryAlt.json',
                '.jhipster/Listing.json',
                '.jhipster/Profile.json',
                '.jhipster/WishList.json'
            ]);
        });
        it('creates actual entity files', () => {
            assert.file(entityFiles);
        });
    });
    describe('imports a JDL model which excludes Elasticsearch for a class', () => {
        beforeEach((done) => {
            helpers.run(require.resolve('../generators/import-jdl'))
                .inTmpDir((dir) => {
                    fse.copySync(path.join(__dirname, '../test/templates/import-jdl'), dir);
                })
                .withArguments(['search.jdl'])
                .on('end', done);
        });

        it('creates entity json files', () => {
            assert.file([
                '.jhipster/WithSearch.json',
                '.jhipster/WithoutSearch.json'
            ]);
            assert.fileContent('.jhipster/WithoutSearch.json', /"searchEngine": false/);
            assert.file(`${SERVER_MAIN_SRC_DIR}com/mycompany/myapp/repository/search/WithSearchSearchRepository.java`);
            assert.noFile(`${SERVER_MAIN_SRC_DIR}com/mycompany/myapp/repository/search/WithoutSearchSearchRepository.java`);
        });
    });
});
<commit_msg>Enabled all the tests<commit_after>/* global describe, before, beforeEach, it */

const path = require('path');
const assert = require('yeoman-assert');
const helpers = require('yeoman-test');
const fse = require('fs-extra');
const constants = require('../generators/generator-constants');

const SERVER_MAIN_SRC_DIR = constants.SERVER_MAIN_SRC_DIR;
const SERVER_TEST_SRC_DIR = constants.SERVER_TEST_SRC_DIR;

const entityFiles = [
    `${SERVER_MAIN_SRC_DIR}com/mycompany/myapp/domain/Job.java`,
    `${SERVER_MAIN_SRC_DIR}com/mycompany/myapp/repository/JobRepository.java`,
    `${SERVER_MAIN_SRC_DIR}com/mycompany/myapp/web/rest/JobResource.java`,
    `${SERVER_TEST_SRC_DIR}com/mycompany/myapp/web/rest/JobResourceIntTest.java`,
];

describe('JHipster generator import jdl', () => {
    describe('imports a JDL model from single file with --json-only flag', () => {
        beforeEach((done) => {
            helpers.run(require.resolve('../generators/import-jdl'))
                .inTmpDir((dir) => {
                    fse.copySync(path.join(__dirname, '../test/templates/import-jdl'), dir);
                })
                .withArguments(['jdl.jdl'])
                .withOptions({ 'json-only': true })
                .on('end', done);
        });

        it('creates entity json files', () => {
            assert.file([
                '.jhipster/Department.json',
                '.jhipster/JobHistory.json',
                '.jhipster/Job.json',
                '.jhipster/Employee.json',
                '.jhipster/Location.json',
                '.jhipster/Task.json',
                '.jhipster/Country.json',
                '.jhipster/Region.json'
            ]);
        });
        it('does not create actual entity files', () => {
            assert.noFile(entityFiles);
        });
    });
    describe('imports a JDL model from single file', () => {
        beforeEach((done) => {
            helpers.run(require.resolve('../generators/import-jdl'))
                .inTmpDir((dir) => {
                    fse.copySync(path.join(__dirname, '../test/templates/import-jdl'), dir);
                })
                .withArguments(['jdl.jdl'])
                .on('end', done);
        });

        it('creates entity json files', () => {
            assert.file([
                '.jhipster/Department.json',
                '.jhipster/JobHistory.json',
                '.jhipster/Job.json',
                '.jhipster/Employee.json',
                '.jhipster/Location.json',
                '.jhipster/Task.json',
                '.jhipster/Country.json',
                '.jhipster/Region.json'
            ]);
        });
        it('creates actual entity files', () => {
            assert.file(entityFiles);
        });
    });
    describe('imports JDL apps and entities', () => {
        before((done) => {
            helpers.run(require.resolve('../generators/import-jdl'))
                .inTmpDir((dir) => {
                    fse.copySync(path.join(__dirname, '../test/templates/import-jdl'), dir);
                })
                .withArguments(['apps-and-entities.jdl'])
                .on('end', done);
        });

        it('creates the applications', () => {
            assert.file([
                path.join('myFirstApp', '.yo-rc.json'),
                path.join('mySecondApp', '.yo-rc.json'),
                path.join('myThirdApp', '.yo-rc.json')
            ]);
        });
        it('creates the entities', () => {
            assert.file([
                path.join('myFirstApp', '.jhipster', 'A.json'),
                path.join('myFirstApp', '.jhipster', 'B.json'),
                path.join('myFirstApp', '.jhipster', 'E.json'),
                path.join('myFirstApp', '.jhipster', 'F.json'),
                path.join('mySecondApp', '.jhipster', 'E.json'),
                path.join('myThirdApp', '.jhipster', 'F.json')
            ]);
        });
    });
    describe('imports single app and entities', () => {
        before((done) => {
            helpers.run(require.resolve('../generators/import-jdl'))
                .inTmpDir((dir) => {
                    fse.copySync(path.join(__dirname, '../test/templates/import-jdl'), dir);
                })
                .withOptions({ skipInstall: true })
                .withArguments(['single-app-and-entities.jdl'])
                .on('end', done);
        });

        it('creates the application', () => {
            assert.file(['.yo-rc.json']);
        });
        it('creates the entities', () => {
            assert.file([
                path.join('.jhipster', 'A.json'),
                path.join('.jhipster', 'B.json'),
            ]);
        });
    });
    describe('imports a JDL model from multiple files', () => {
        beforeEach((done) => {
            helpers.run(require.resolve('../generators/import-jdl'))
                .inTmpDir((dir) => {
                    fse.copySync(path.join(__dirname, '../test/templates/import-jdl'), dir);
                })
                .withArguments(['jdl.jdl', 'jdl2.jdl', 'jdl-ambiguous.jdl'])
                .on('end', done);
        });

        it('creates entity json files', () => {
            assert.file([
                '.jhipster/Department.json',
                '.jhipster/JobHistory.json',
                '.jhipster/Job.json',
                '.jhipster/Employee.json',
                '.jhipster/Location.json',
                '.jhipster/Task.json',
                '.jhipster/Country.json',
                '.jhipster/Region.json',
                '.jhipster/DepartmentAlt.json',
                '.jhipster/JobHistoryAlt.json',
                '.jhipster/Listing.json',
                '.jhipster/Profile.json',
                '.jhipster/WishList.json'
            ]);
        });
        it('creates actual entity files', () => {
            assert.file(entityFiles);
        });
    });
    describe('imports a JDL model which excludes Elasticsearch for a class', () => {
        beforeEach((done) => {
            helpers.run(require.resolve('../generators/import-jdl'))
                .inTmpDir((dir) => {
                    fse.copySync(path.join(__dirname, '../test/templates/import-jdl'), dir);
                })
                .withArguments(['search.jdl'])
                .on('end', done);
        });

        it('creates entity json files', () => {
            assert.file([
                '.jhipster/WithSearch.json',
                '.jhipster/WithoutSearch.json'
            ]);
            assert.fileContent('.jhipster/WithoutSearch.json', /"searchEngine": false/);
            assert.file(`${SERVER_MAIN_SRC_DIR}com/mycompany/myapp/repository/search/WithSearchSearchRepository.java`);
            assert.noFile(`${SERVER_MAIN_SRC_DIR}com/mycompany/myapp/repository/search/WithoutSearchSearchRepository.java`);
        });
    });
});
<|endoftext|>