<commit_before>"use strict";

define(['jquery',
        'logManager'], function (__jquery,
                                 logManager) {

    var DragScroll;

    DragScroll = function (containerNode) {
        this._logger = logManager.create("DragScroll");

        this._containerNode = containerNode;
    };

    DragScroll._SCROLL_STEP = 25;

    DragScroll._INTERVAL = 50;

    DragScroll.prototype.start = function () {
        var self = this;

        this._getContainerBoundaries();

        //hook up MouseMove and MouseUp
        this._onMouseMoveCallBack = function (event) {
            self._onMouseMove(event);
        };

        this._onMouseUpCallBack = function (/*event*/) {
            self._onMouseUp(/*event*/);
        };

        $(document).on('mousemove.DragScroll', this._onMouseMoveCallBack);
        $(document).on('mouseup.DragScroll', this._onMouseUpCallBack);
    };

    DragScroll.prototype._onMouseUp = function (/*event*/) {
        //unbind mousemove and mouseup handlers
        $(document).off('mousemove.DragScroll', this._onMouseMoveCallBack);
        $(document).off('mouseup.DragScroll', this._onMouseUpCallBack);

        //delete unnecessary instance members
        delete this._onMouseMoveCallBack;
        delete this._onMouseUpCallBack;

        this._stopScroll();
    };

    DragScroll.prototype._onMouseMove = function (event) {
        if (!this._isInContainerBounds(event.pageX, event.pageY)) {
            this._logger.debug("onMouseMove - outside ContainerBounds");
            //start scrolling
            this._scrollDelta = this._calculateScrollDelta(event.pageX, event.pageY);
            this._startScroll();
        } else {
            this._logger.debug("onMouseMove - INSIDE ContainerBounds");
            //stop scrolling
            this._stopScroll();
        }
    };

    DragScroll.prototype._startScroll = function () {
        var self = this;

        if (this._timer === undefined) {
            this._timer = window.setTimeout(function () {
                self._doScroll();
            }, DragScroll._INTERVAL);
        }
    };

    DragScroll.prototype._stopScroll = function () {
        if (this._timer) {
            window.clearTimeout(this._timer);
            this._timer = undefined;
        }
    };

    DragScroll.prototype._getContainerBoundaries = function () {
        var offset = this._containerNode.offset();

        this._containerBoundaries = {"left" : offset.left,
                                    "top" : offset.top,
                                    "width": this._containerNode.width(),
                                    "height": this._containerNode.height() };

        this._logger.debug("_containerBoundaries: " + JSON.stringify(this._containerBoundaries));
    };

    DragScroll.prototype._isInContainerBounds = function(x, y) {
        return this._containerBoundaries.left <= x &&
            this._containerBoundaries.left + this._containerBoundaries.width >= x &&
            this._containerBoundaries.top <= y &&
            this._containerBoundaries.top + this._containerBoundaries.height >= y;
    };

    DragScroll.prototype._calculateScrollDelta = function(x, y) {
        var dx = 0,
            dy = 0;

        if (x < this._containerBoundaries.left) {
            dx = -DragScroll._SCROLL_STEP;
        } else if (x > this._containerBoundaries.left + this._containerBoundaries.width) {
            dx = DragScroll._SCROLL_STEP;
        }

        if (y < this._containerBoundaries.top) {
            dy = -DragScroll._SCROLL_STEP;
        } else if (y > this._containerBoundaries.top + this._containerBoundaries.height) {
            dy = DragScroll._SCROLL_STEP;
        }

        return { "x": dx, "y": dy };
    };

    DragScroll.prototype._doScroll = function () {
        var sTop, sLeft;

        this._logger.debug("doScroll - " + JSON.stringify(this._scrollDelta));
        this._timer = undefined;
        if (this._scrollDelta) {
            if (this._scrollDelta.x !== 0 ||
                this._scrollDelta.y !== 0) {
                sTop = this._containerNode[0].scrollTop;
                sLeft = this._containerNode[0].scrollLeft;

                this._containerNode[0].scrollTop += this._scrollDelta.y;
                this._containerNode[0].scrollLeft += this._scrollDelta.x;

                if (this._containerNode[0].scrollTop === 0 ||
                    this._containerNode[0].scrollTop < sTop + this._scrollDelta.y) {
                    this._scrollDelta.y = 0;
                }

                if (this._containerNode[0].scrollLeft === 0 ||
                    this._containerNode[0].scrollLeft < sLeft + this._scrollDelta.x) {
                    this._scrollDelta.x = 0;
                }

                this._startScroll();
            } else {
                this._scrollDelta = undefined;
                this._stopScroll();
            }
        }
    };

    return DragScroll;
});<commit_msg>minor syntax fixes<commit_after>"use strict";

define(['jquery',
        'logManager'], function (__jquery,
                                 logManager) {

    var DragScroll;

    DragScroll = function (containerNode) {
        this._logger = logManager.create("DragScroll");

        this._containerNode = containerNode;
    };

    DragScroll._SCROLL_STEP = 25;

    DragScroll._INTERVAL = 50;

    DragScroll.prototype.start = function () {
        var self = this;

        this._getContainerBoundaries();

        //hook up MouseMove and MouseUp
        this._onMouseMoveCallBack = function (event) {
            self._onMouseMove(event);
        };

        this._onMouseUpCallBack = function (/*event*/) {
            self._onMouseUp(/*event*/);
        };

        $(document).on('mousemove.DragScroll', this._onMouseMoveCallBack);
        $(document).on('mouseup.DragScroll', this._onMouseUpCallBack);
    };

    DragScroll.prototype._onMouseUp = function (/*event*/) {
        //unbind mousemove and mouseup handlers
        $(document).off('mousemove.DragScroll', this._onMouseMoveCallBack);
        $(document).off('mouseup.DragScroll', this._onMouseUpCallBack);

        //delete unnecessary instance members
        delete this._onMouseMoveCallBack;
        delete this._onMouseUpCallBack;

        this._stopScroll();
    };

    DragScroll.prototype._onMouseMove = function (event) {
        if (!this._isInContainerBounds(event.pageX, event.pageY)) {
            this._logger.debug("onMouseMove - outside ContainerBounds");
            //start scrolling
            this._scrollDelta = this._calculateScrollDelta(event.pageX, event.pageY);
            this._startScroll();
        } else {
            this._logger.debug("onMouseMove - INSIDE ContainerBounds");
            //stop scrolling
            this._stopScroll();
        }
    };

    DragScroll.prototype._startScroll = function () {
        var self = this;

        if (this._timer === undefined) {
            this._timer = window.setTimeout(function () {
                self._doScroll();
            }, DragScroll._INTERVAL);
        }
    };

    DragScroll.prototype._stopScroll = function () {
        if (this._timer) {
            window.clearTimeout(this._timer);
            this._timer = undefined;
        }
    };

    DragScroll.prototype._getContainerBoundaries = function () {
        var offset = this._containerNode.offset();

        this._containerBoundaries = {"left" : offset.left,
                                    "top" : offset.top,
                                    "width": this._containerNode.width(),
                                    "height": this._containerNode.height() };

        this._logger.debug("_containerBoundaries: " + JSON.stringify(this._containerBoundaries));
    };

    DragScroll.prototype._isInContainerBounds = function (x, y) {
        return this._containerBoundaries.left <= x &&
            this._containerBoundaries.left + this._containerBoundaries.width >= x &&
            this._containerBoundaries.top <= y &&
            this._containerBoundaries.top + this._containerBoundaries.height >= y;
    };

    DragScroll.prototype._calculateScrollDelta = function (x, y) {
        var dx = 0,
            dy = 0;

        if (x < this._containerBoundaries.left) {
            dx = -DragScroll._SCROLL_STEP;
        } else if (x > this._containerBoundaries.left + this._containerBoundaries.width) {
            dx = DragScroll._SCROLL_STEP;
        }

        if (y < this._containerBoundaries.top) {
            dy = -DragScroll._SCROLL_STEP;
        } else if (y > this._containerBoundaries.top + this._containerBoundaries.height) {
            dy = DragScroll._SCROLL_STEP;
        }

        return { "x": dx, "y": dy };
    };

    DragScroll.prototype._doScroll = function () {
        var sTop, sLeft;

        this._logger.debug("doScroll - " + JSON.stringify(this._scrollDelta));
        this._timer = undefined;
        if (this._scrollDelta) {
            if (this._scrollDelta.x !== 0 || this._scrollDelta.y !== 0) {
                sTop = this._containerNode[0].scrollTop;
                sLeft = this._containerNode[0].scrollLeft;

                this._containerNode[0].scrollTop += this._scrollDelta.y;
                this._containerNode[0].scrollLeft += this._scrollDelta.x;

                if (this._containerNode[0].scrollTop === 0 ||
                        this._containerNode[0].scrollTop < sTop + this._scrollDelta.y) {
                    this._scrollDelta.y = 0;
                }

                if (this._containerNode[0].scrollLeft === 0 ||
                        this._containerNode[0].scrollLeft < sLeft + this._scrollDelta.x) {
                    this._scrollDelta.x = 0;
                }

                this._startScroll();
            } else {
                this._scrollDelta = undefined;
                this._stopScroll();
            }
        }
    };

    return DragScroll;
});<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var integration = require('analytics.js-integration');
var includes = require('includes');
var foldl = require('foldl');
var each = require('each');
var fbq;

/**
 * Expose `Facebook Pixel`.
 */

var FacebookPixel = module.exports = integration('Facebook Pixel')
  .global('fbq')
  .option('pixelId', '')
  .mapping('standardEvents')
  .mapping('legacyEvents')
  .tag('<script src="//connect.facebook.net/en_US/fbevents.js">');

/**
 * Initialize Facebook Pixel.
 *
 * @param {Facade} page
 */

FacebookPixel.prototype.initialize = function(){
  fbq = window.fbq = window._fbq = function() {
    fbq.callMethod
      ? fbq.callMethod.apply(fbq, arguments)
      : fbq.queue.push(arguments)
  };
  fbq.push = fbq;
  fbq.loaded = true;
  fbq.version='2.0';
  fbq.queue=[];
  this.load(this.ready);
  fbq('init', this.options.pixelId);
};

/**
 * Has the Facebook Pixel library been loaded yet?
 *
 * @return {Boolean}
 */

FacebookPixel.prototype.loaded = function(){
  return !!(fbq && fbq.callMethod);
};

/**
 * Trigger a page view.
 *
 * @param {Facade} identify
 */

FacebookPixel.prototype.page = function(page){
  window.fbq('track', 'PageView');
};

/**
 * Track an event.
 *
 * @param {Facade} track
 */

FacebookPixel.prototype.track = function(track){
  var event = track.event();
  var revenue = formatRevenue(track.revenue());

  var payload = foldl(function(acc, val, key) {
    if (key === 'revenue') {
      acc.value = revenue;
      return acc;
    }

    acc[key] = val;
    return acc;
  }, {}, track.properties())

  var standard = this.standardEvents(event);
  var legacy = this.legacyEvents(event);

  // non-mapped events get sent as "custom events" with full
  // tranformed payload
  if (![].concat(standard, legacy).length) {
    window.fbq('trackCustom', event, payload);
    return;
  }

  // standard conversion events, mapped to one of 9 standard events
  // send full transformed payload
  each(function(event) {
    window.fbq('track', event, payload);
  }, standard);

  // legacy conversion events — mapped to specific "pixelId"s
  // send only currency and value
  each(function(event) {
    window.fbq('track', event, {
      currency: track.currency(),
      value: revenue
    });
  }, legacy);

};

/**
 * Viewed product category.
 *
 * @api private
 * @param {Track} track category
 */

FacebookPixel.prototype.viewedProductCategory = function(track) {
  window.fbq('track', 'ViewContent', {
    content_ids: [track.category() || ''],
    content_type: 'product_group'
  });
};

/**
 * Viewed product.
 *
 * @api private
 * @param {Track} track
 */

FacebookPixel.prototype.viewedProduct = function(track) {
  window.fbq('track', 'ViewContent', {
    content_ids: [track.id() || track.sku() || ''],
    content_type: 'product',
    content_name: track.name() || '',
    content_category: track.category() || '',
    currency: track.currency(),
    value: formatRevenue(track.price())
  });
};

/**
 * Added product.
 *
 * @api private
 * @param {Track} track
 */

FacebookPixel.prototype.addedProduct = function(track) {
  window.fbq('track', 'AddToCart', {
    content_ids: [track.id() || track.sku() || ''],
    content_type: 'product',
    content_name: track.name() || '',
    content_category: track.category() || '',
    currency: track.currency(),
    value: formatRevenue(track.price())
  });
};

/**
 * Completed Order.
 *
 * @api private
 * @param {Track} track
 */

FacebookPixel.prototype.completedOrder = function(track) {
  var key;
  var content_ids = foldl(function(acc, product) {
    key = product.id || product.sku;
    if (key) acc.push(key);
    return acc;
  }, [], track.products() || []);

  var revenue = formatRevenue(track.revenue());

  window.fbq('track', 'Purchase', {
    content_ids: content_ids,
    content_type: 'product',
    currency: track.currency(),
    value: revenue
  });
};

/**
 * Get Revenue Formatted Correctly for FB.
 *
 * @api private
 * @param {Track} track
 */

function formatRevenue(revenue) {
  return Number(revenue || 0).toFixed(2);
}
<commit_msg>whitespace edits<commit_after>
/**
 * Module dependencies.
 */

var integration = require('analytics.js-integration');
var includes = require('includes');
var foldl = require('foldl');
var each = require('each');
var fbq;

/**
 * Expose `Facebook Pixel`.
 */

var FacebookPixel = module.exports = integration('Facebook Pixel')
  .global('fbq')
  .option('pixelId', '')
  .mapping('standardEvents')
  .mapping('legacyEvents')
  .tag('<script src="//connect.facebook.net/en_US/fbevents.js">');

/**
 * Initialize Facebook Pixel.
 *
 * @param {Facade} page
 */

FacebookPixel.prototype.initialize = function(){
  fbq = window.fbq = window._fbq = function() {
    fbq.callMethod
      ? fbq.callMethod.apply(fbq, arguments)
      : fbq.queue.push(arguments)
  };
  fbq.push = fbq;
  fbq.loaded = true;
  fbq.version='2.0';
  fbq.queue=[];
  this.load(this.ready);
  fbq('init', this.options.pixelId);
};

/**
 * Has the Facebook Pixel library been loaded yet?
 *
 * @return {Boolean}
 */

FacebookPixel.prototype.loaded = function(){
  return !!(fbq && fbq.callMethod);
};

/**
 * Trigger a page view.
 *
 * @param {Facade} identify
 */

FacebookPixel.prototype.page = function(page){
  window.fbq('track', 'PageView');
};

/**
 * Track an event.
 *
 * @param {Facade} track
 */

FacebookPixel.prototype.track = function(track){
  var event = track.event();
  var revenue = formatRevenue(track.revenue());

  var payload = foldl(function(acc, val, key) {
    if (key === 'revenue') {
      acc.value = revenue;
      return acc;
    }

    acc[key] = val;
    return acc;
  }, {}, track.properties())

  var standard = this.standardEvents(event);
  var legacy = this.legacyEvents(event);

  // non-mapped events get sent as "custom events" with full
  // tranformed payload
  if (![].concat(standard, legacy).length) {
    window.fbq('trackCustom', event, payload);
    return;
  }

  // standard conversion events, mapped to one of 9 standard events
  // send full transformed payload
  each(function(event) {
    window.fbq('track', event, payload);
  }, standard);

  // legacy conversion events — mapped to specific "pixelId"s
  // send only currency and value
  each(function(event) {
    window.fbq('track', event, {
      currency: track.currency(),
      value: revenue
    });
  }, legacy);

};

/**
 * Viewed product category.
 *
 * @api private
 * @param {Track} track category
 */

FacebookPixel.prototype.viewedProductCategory = function(track) {
  window.fbq('track', 'ViewContent', {
    content_ids: [track.category() || ''],
    content_type: 'product_group'
  });
};

/**
 * Viewed product.
 *
 * @api private
 * @param {Track} track
 */

FacebookPixel.prototype.viewedProduct = function(track) {
  window.fbq('track', 'ViewContent', {
    content_ids: [track.id() || track.sku() || ''],
    content_type: 'product',
    content_name: track.name() || '',
    content_category: track.category() || '',
    currency: track.currency(),
    value: formatRevenue(track.price())
  });
};

/**
 * Added product.
 *
 * @api private
 * @param {Track} track
 */

FacebookPixel.prototype.addedProduct = function(track) {
  window.fbq('track', 'AddToCart', {
    content_ids: [track.id() || track.sku() || ''],
    content_type: 'product',
    content_name: track.name() || '',
    content_category: track.category() || '',
    currency: track.currency(),
    value: formatRevenue(track.price())
  });
};

/**
 * Completed Order.
 *
 * @api private
 * @param {Track} track
 */

FacebookPixel.prototype.completedOrder = function(track) {
  var key;
  var content_ids = foldl(function(acc, product) {
    key = product.id || product.sku;
    if (key) acc.push(key);
    return acc;
  }, [], track.products() || []);

  var revenue = formatRevenue(track.revenue());

  window.fbq('track', 'Purchase', {
    content_ids: content_ids,
    content_type: 'product',
    currency: track.currency(),
    value: revenue
  });
};

/**
 * Get Revenue Formatted Correctly for FB.
 *
 * @api private
 * @param {Track} track
 */

function formatRevenue(revenue) {
  return Number(revenue || 0).toFixed(2);
}
<|endoftext|>


<commit_before>'use strict';

const Lab = require('lab');
const {expect} = require('code');
const path = require('path');

const lab = exports.lab = Lab.script();
const {describe, it} = lab;

const Configue = require('../');

const JSON_CONF_FILE = path.join(__dirname, 'data/config.json');
const JSON_CONF_FILE_BIS = path.join(__dirname, 'data/config-bis.json');
const YAML_CONF_FILE = path.join(__dirname, 'data/config.yaml');

describe('Configue Core', () => {

    describe('Resolving', () => {

        it('resolve is automatic', (done) => {
            const configue = Configue();
            expect(configue.resolved).to.be.true();
            done();
        });
        it('resolve is automatic unless defer', (done) => {
            const configue = Configue({defer: true});
            expect(configue.resolved).to.be.false();
            configue.resolve();

            expect(configue.resolved).to.be.true();
            done();
        });

        it('resolve is executed once', (done) => {
            const configue = Configue({defer: true, defaults: {A: 1}});
            expect(configue.resolved).to.be.false();
            configue.resolve();
            configue.resolve(); // coverage ensure that we don't have ran a second times

            expect(configue.resolved).to.be.true();
            // can't test a resolve with change value since dynamic access to argv and env
            done();
        });
    });

    describe('Options Schema', () => {
        it('detect wrong option item', (done) => {
            try {
                const configue = Configue({'this': 'is-junk'});
                done(new Error('Exception not triggered'));
            } catch (err) {
                done();
            }
        });
        // TODO maybe add some valid schema
    });

    describe('Files', () => {

        it('can load data from a json file given as string', (done) => {
            const configue = Configue({files: JSON_CONF_FILE});
            expect(configue.get('key')).to.equal('json-config');
            done();
        });

        it('can load data from a json files given as string array', (done) => {
            const configue = Configue({files: [JSON_CONF_FILE, JSON_CONF_FILE_BIS]});
            expect(configue.get('key')).to.equal('json-config');
            expect(configue.get('key-bis')).to.equal('json-config-bis');
            done();
        });

        it('can load data from a json file', (done) => {
            const configue = Configue({files: [{file: JSON_CONF_FILE}]});
            expect(configue.get('key')).to.equal('json-config');
            done();
        });

        it('can load data from a yaml file', (done) => {
            const configueOptions = {
                files: [{
                    file: YAML_CONF_FILE,
                    format: require('nconf-yaml')
                }]
            };
            const configue = Configue(configueOptions);
            expect(configue.get('key')).to.equal('yaml-config');
            done();
        });

        it('files are loaded in order', (done) => {
            const configueOptions = {
                files: [{file: JSON_CONF_FILE},
                    {
                        file: YAML_CONF_FILE,
                        format: require('nconf-yaml')
                    }]
            };
            const configue = Configue(configueOptions);
            expect(configue.get('key')).to.equal('json-config');
            done();
        });
    });

    describe('Defaults', () => {
        it('can load a default object', (done) => {
            const configue = Configue({defaults: {one: 1}});
            expect(configue.get('one')).to.equal(1);
            done();
        });

        it('defaults are loaded in order', (done) => {
            const configue = Configue({
                defaults: [{one: 1}, {one: 2, two: 2}]
            });
            expect(configue.get('one')).to.equal(1);
            expect(configue.get('two')).to.equal(2);
            done();
        });

    });
    describe('Overrides', () => {
        it('can be defined', (done) => {
            const configue = Configue({overrides: {one: 1}});
            expect(configue.get('one')).to.equal(1);
            done();
        });
        it('can be defined', (done) => {
            const configue = Configue({overrides: {one: 1}});
            expect(configue.get('one')).to.equal(1);
            done();
        });

        it('are not overidden', (done) => {
            process.argv.push('--one=2');
            const configue = Configue({overrides: {one: 1}});
            process.argv.pop();
            expect(configue.get('one')).to.equal(1);
            done();
        });

    });

    describe('Options', () => {
        it('argv are forwarded to nconf', (done) => {
            const configue = Configue({argv: {'key': {default: 'some-value'}}});
            expect(configue.get('key')).to.equal('some-value');
            done();
        });

        it('env config are forwarded to nconf', (done) => {
            const configue = Configue({env: ['PWD']});
            const allEnv = configue.nconf.load(); //FIXME
            expect(configue.get('HOME')).to.be.undefined();
            done();

        });
        it('required keys are enforced by nconf', (done) => {
            try {
                const configue = Configue.defaults({A: 1}).required(['A', 'B']).get();
                done(new Error('Error should be triggered'));
            } catch (err) {
                expect(err.message).to.equal('Missing required keys: B');
                done();
            }
        });
        it('required keys are enforced by nconf does not false alarm', (done) => {
            try {
                const configue = Configue.defaults({A: 1, B: 2, C: 3}).required(['A', 'B']).get();
                done();
            } catch (err) {
                done(new Error('Error should not be triggered'));
            }
        });
    });

    describe('Disable', () => {

        it('enable to disable argv', (done) => {
            process.argv.push('--who=YO');
            process.env.who = 'NO';
            // RISKY!!!!

            const configue = Configue({disable: {argv: true}});
            expect(configue.get('who')).to.equal('NO');

            process.argv.pop();
            process.env.who = undefined;

            done();
        });

        it('enable to disable env', (done) => {
            process.env.who = 'NONO';
            // RISKY!!!!

            const configue = Configue({disable: {env: true}, defaults: {who: 'YES YES'}});
            expect(configue.get('who')).to.equal('YES YES');

            process.env.who = undefined;

            done();
        });

    });

    describe('Post Hooks', () => {

        it('enable to insert hook', (done) => {
            const configueOptions = {
                postHooks: {
                    overrides: function postOverrides(nconf) {
                        nconf.set('who', 'ME FIRST!');
                    },
                    argv: function postArgv(nconf) {
                        nconf.set('when', 'NOW');
                    },
                    defaults: function last(nconf) {
                        nconf.set('when', 'RIGHT ' + nconf.get('when'));
                    }
                }
            };
            process.argv.push('--when=later');
            process.env.who = 'me';

            const configue = Configue(configueOptions);
            expect(configue.get('who')).to.equal('ME FIRST!');
            expect(configue.get('when')).to.equal('RIGHT NOW');
            done();
        });
        it('first hook is runned to insert hook', (done) => {
            const configueOptions = {
                overrides: {who: 'ME second!'},
                postHooks: {
                    first: function first(nconf) {
                        nconf.set('who', 'ME FIRST!');
                        nconf.set('when', 'RIGHT NOW!');
                    }
                }
            };
            process.env.who = 'me';

            const configue = Configue(configueOptions);
            process.env.who = undefined;
            expect(configue.get('who')).to.equal('ME FIRST!');
            expect(configue.get('when')).to.equal('RIGHT NOW!');
            done();
        });

        it('handle error in loading process', (done) => {
            try {
                const configue = Configue({
                    postHooks: {
                        argv: function postArgv(nconf) {
                            throw new Error('This is an error');
                        }
                    }
                });
            } catch (err) {
                expect(err).to.exist();
            }
            done();
        });
    });

    describe('CustomWorkflow', () => {

        it('accept a custom workflow', (done) => {
            const configueOptions = {
                customWorkflow: nconf => nconf.set('workflow', 'custom')
            };
            process.argv.push('--workflow=default');
            process.env.key = 'value';

            const configue = Configue(configueOptions);
            expect(configue.get('workflow')).to.equal('custom');
            expect(configue.get('key')).to.not.exist();
            done();
        });

    });

});
<commit_msg>test: remove useless statement load<commit_after>'use strict';

const Lab = require('lab');
const {expect} = require('code');
const path = require('path');

const lab = exports.lab = Lab.script();
const {describe, it} = lab;

const Configue = require('../');

const JSON_CONF_FILE = path.join(__dirname, 'data/config.json');
const JSON_CONF_FILE_BIS = path.join(__dirname, 'data/config-bis.json');
const YAML_CONF_FILE = path.join(__dirname, 'data/config.yaml');

describe('Configue Core', () => {

    describe('Resolving', () => {

        it('resolve is automatic', (done) => {
            const configue = Configue();
            expect(configue.resolved).to.be.true();
            done();
        });
        it('resolve is automatic unless defer', (done) => {
            const configue = Configue({defer: true});
            expect(configue.resolved).to.be.false();
            configue.resolve();

            expect(configue.resolved).to.be.true();
            done();
        });

        it('resolve is executed once', (done) => {
            const configue = Configue({defer: true, defaults: {A: 1}});
            expect(configue.resolved).to.be.false();
            configue.resolve();
            configue.resolve(); // coverage ensure that we don't have ran a second times

            expect(configue.resolved).to.be.true();
            // can't test a resolve with change value since dynamic access to argv and env
            done();
        });
    });

    describe('Options Schema', () => {
        it('detect wrong option item', (done) => {
            try {
                const configue = Configue({'this': 'is-junk'});
                done(new Error('Exception not triggered'));
            } catch (err) {
                done();
            }
        });
        // TODO maybe add some valid schema
    });

    describe('Files', () => {

        it('can load data from a json file given as string', (done) => {
            const configue = Configue({files: JSON_CONF_FILE});
            expect(configue.get('key')).to.equal('json-config');
            done();
        });

        it('can load data from a json files given as string array', (done) => {
            const configue = Configue({files: [JSON_CONF_FILE, JSON_CONF_FILE_BIS]});
            expect(configue.get('key')).to.equal('json-config');
            expect(configue.get('key-bis')).to.equal('json-config-bis');
            done();
        });

        it('can load data from a json file', (done) => {
            const configue = Configue({files: [{file: JSON_CONF_FILE}]});
            expect(configue.get('key')).to.equal('json-config');
            done();
        });

        it('can load data from a yaml file', (done) => {
            const configueOptions = {
                files: [{
                    file: YAML_CONF_FILE,
                    format: require('nconf-yaml')
                }]
            };
            const configue = Configue(configueOptions);
            expect(configue.get('key')).to.equal('yaml-config');
            done();
        });

        it('files are loaded in order', (done) => {
            const configueOptions = {
                files: [{file: JSON_CONF_FILE},
                    {
                        file: YAML_CONF_FILE,
                        format: require('nconf-yaml')
                    }]
            };
            const configue = Configue(configueOptions);
            expect(configue.get('key')).to.equal('json-config');
            done();
        });
    });

    describe('Defaults', () => {
        it('can load a default object', (done) => {
            const configue = Configue({defaults: {one: 1}});
            expect(configue.get('one')).to.equal(1);
            done();
        });

        it('defaults are loaded in order', (done) => {
            const configue = Configue({
                defaults: [{one: 1}, {one: 2, two: 2}]
            });
            expect(configue.get('one')).to.equal(1);
            expect(configue.get('two')).to.equal(2);
            done();
        });

    });
    describe('Overrides', () => {
        it('can be defined', (done) => {
            const configue = Configue({overrides: {one: 1}});
            expect(configue.get('one')).to.equal(1);
            done();
        });
        it('can be defined', (done) => {
            const configue = Configue({overrides: {one: 1}});
            expect(configue.get('one')).to.equal(1);
            done();
        });

        it('are not overidden', (done) => {
            process.argv.push('--one=2');
            const configue = Configue({overrides: {one: 1}});
            process.argv.pop();
            expect(configue.get('one')).to.equal(1);
            done();
        });

    });

    describe('Options', () => {
        it('argv are forwarded to nconf', (done) => {
            const configue = Configue({argv: {'key': {default: 'some-value'}}});
            expect(configue.get('key')).to.equal('some-value');
            done();
        });

        it('env config are forwarded to nconf', (done) => {
            const configue = Configue({env: ['PWD']});
            expect(configue.get('HOME')).to.be.undefined();
            done();
        });
        it('required keys are enforced by nconf', (done) => {
            try {
                const configue = Configue.defaults({A: 1}).required(['A', 'B']).get();
                done(new Error('Error should be triggered'));
            } catch (err) {
                expect(err.message).to.equal('Missing required keys: B');
                done();
            }
        });
        it('required keys are enforced by nconf does not false alarm', (done) => {
            try {
                const configue = Configue.defaults({A: 1, B: 2, C: 3}).required(['A', 'B']).get();
                done();
            } catch (err) {
                done(new Error('Error should not be triggered'));
            }
        });
    });

    describe('Disable', () => {

        it('enable to disable argv', (done) => {
            process.argv.push('--who=YO');
            process.env.who = 'NO';
            // RISKY!!!!

            const configue = Configue({disable: {argv: true}});
            expect(configue.get('who')).to.equal('NO');

            process.argv.pop();
            process.env.who = undefined;

            done();
        });

        it('enable to disable env', (done) => {
            process.env.who = 'NONO';
            // RISKY!!!!

            const configue = Configue({disable: {env: true}, defaults: {who: 'YES YES'}});
            expect(configue.get('who')).to.equal('YES YES');

            process.env.who = undefined;

            done();
        });

    });

    describe('Post Hooks', () => {

        it('enable to insert hook', (done) => {
            const configueOptions = {
                postHooks: {
                    overrides: function postOverrides(nconf) {
                        nconf.set('who', 'ME FIRST!');
                    },
                    argv: function postArgv(nconf) {
                        nconf.set('when', 'NOW');
                    },
                    defaults: function last(nconf) {
                        nconf.set('when', 'RIGHT ' + nconf.get('when'));
                    }
                }
            };
            process.argv.push('--when=later');
            process.env.who = 'me';

            const configue = Configue(configueOptions);
            expect(configue.get('who')).to.equal('ME FIRST!');
            expect(configue.get('when')).to.equal('RIGHT NOW');
            done();
        });
        it('first hook is runned to insert hook', (done) => {
            const configueOptions = {
                overrides: {who: 'ME second!'},
                postHooks: {
                    first: function first(nconf) {
                        nconf.set('who', 'ME FIRST!');
                        nconf.set('when', 'RIGHT NOW!');
                    }
                }
            };
            process.env.who = 'me';

            const configue = Configue(configueOptions);
            process.env.who = undefined;
            expect(configue.get('who')).to.equal('ME FIRST!');
            expect(configue.get('when')).to.equal('RIGHT NOW!');
            done();
        });

        it('handle error in loading process', (done) => {
            try {
                const configue = Configue({
                    postHooks: {
                        argv: function postArgv(nconf) {
                            throw new Error('This is an error');
                        }
                    }
                });
            } catch (err) {
                expect(err).to.exist();
            }
            done();
        });
    });

    describe('CustomWorkflow', () => {

        it('accept a custom workflow', (done) => {
            const configueOptions = {
                customWorkflow: nconf => nconf.set('workflow', 'custom')
            };
            process.argv.push('--workflow=default');
            process.env.key = 'value';

            const configue = Configue(configueOptions);
            expect(configue.get('workflow')).to.equal('custom');
            expect(configue.get('key')).to.not.exist();
            done();
        });

    });

});
<|endoftext|>


<commit_before>// Treehouse Project-04: Tic-Tac-Toe Game
'use strict';
(function (module) {

// Global Variables -----------------------------------------------------
  // Get the start screen div
  const $start = $('#start');
  // Get the button that hides the start screen
  const $button = $('.button');
  const $finish1 = $('#finish1');
  const $finish2 = $('#finish2');
  const $tie = $('#tie');

  const $player1 = $('#player1');
  const $player2 = $('#player2');
  const $board = $('#board');
  const $boxes = $('.boxes');
  const twoDimArr = [];
  const game = document.querySelectorAll('.boxes');
  let count = 0;

  const player1 = {
    name: 'player1',
    bgColor: '#FFA000',
    svg: 'img/o.svg',
    boxFill: 'box-filled-1',
    isWinner: false
  };

  const player2 = {
    name: 'player2',
    bgColor: '#3688C3',
    svg: 'img/x.svg',
    boxFill: 'box-filled-2',
    isWinner: false
  };

// Main Function ------------------------------

  // On page load, show the start screen.
  $(document).ready(function() {
    $start.css('display', 'block');
  });
  // On button click, start the game.
  $button.on('click', function() {
    $start.css('display', 'none');
    $player1.toggleClass('active');
    play(player1);
    pickSquare(player1);
  });

  function play(player) {
    $('.box').hover(
      function() {
        $(this).toggleClass(player.boxFill);
      });
  }

  function pickSquare(player) {
    $('.box').click(
      function() {
        $(this).css({'background-image': 'url(' + player.svg + ')'});
        $(this).css({'background-color': player.bgColor});
        count++;
        console.log(count);
        increaseCount();
      }
    )
  }

  $finish1.css('display', 'none');
  $finish2.css('display', 'none');
  $tie.css('display', 'none');

  function increaseCount() {
    if (count < 9) {
      togglePlayer();
    } else if (count > 9) {
      $finish1.css('display', 'block');
    }
  }

  function togglePlayer() {
    $player1.toggleClass('active');
    $player2.toggleClass('active');
  }

}) (window);
<commit_msg>Worked on getting player turn to change when game tile is clicked.<commit_after>// Treehouse Project-04: Tic-Tac-Toe Game
'use strict';
(function (module) {

// Global Variables -----------------------------------------------------
  // Get the start screen div
  const $start = $('#start');
  // Get the button that hides the start screen
  const $button = $('.button');
  const $finish1 = $('#finish1');
  const $finish2 = $('#finish2');
  const $tie = $('#tie');

  const $player1 = $('#player1');
  const $player2 = $('#player2');
  const $board = $('#board');
  const $boxes = $('.boxes');
  const twoDimArr = [];
  const game = document.querySelectorAll('.boxes');
  let count = 0;

  const player1 = {
    name: 'player1',
    bgColor: '#FFA000',
    svg: 'img/o.svg',
    boxFill: 'box-filled-1',
    isWinner: false
  };

  const player2 = {
    name: 'player2',
    bgColor: '#3688C3',
    svg: 'img/x.svg',
    boxFill: 'box-filled-2',
    isWinner: false
  };

  // Hide the various winning screens.
  $finish1.css('display', 'none');
  $finish2.css('display', 'none');
  $tie.css('display', 'none');

// Main Function ------------------------------

  // On page load, show the start screen.
  $(document).ready(function() {
    $start.css('display', 'block');
  });
  // On button click, start the game.
  $button.on('click', function() {
    $start.css('display', 'none');
    $finish1.css('display', 'none');
    $finish2.css('display', 'none');
    $player1.toggleClass('active');
    togglePlayer();
  });

  function play(player) {
    $('.box').hover(
      function() {
        $(this).toggleClass(player.boxFill);
      });
  }

  function pickSquare(player) {
    $('.box').click(
      function() {
        $(this).css({'background-image': 'url(' + player.svg + ')'});
        $(this).css({'background-color': player.bgColor});
        count++;
        console.log(count);
        increaseCount();
      }
    )
  }

  function increaseCount() {
    if (count < 9) {
      togglePlayer();
    } else if (count === 9) {
      $finish1.css('display', 'block');
      count = 0;
    }
  }

  function togglePlayer() {
    // Changes the active O or X on game board.
    if (count === 0) {
      $player1.toggleClass('active');
      $player2.toggleClass('active');
      play(player1);
      pickSquare(player1);
    } else if (count != 0 && $player1.hasClass('active')) {
      $player1.toggleClass('active');
      $player2.toggleClass('active');
      play(player1);
      pickSquare(player1);
    } else if ($player2.hasClass('active')) {
      $player1.toggleClass('active');
      $player2.toggleClass('active');
      play(player2);
      pickSquare(player2);
    }
  }

}) (window);
<|endoftext|>


<commit_before>// Gravity Scrolling jQuery Plugin by Ryan Stock
// www.github.com/ryanstockau/gravity-scrolling

/*

LICENSE

The MIT License (MIT)

Copyright (c) 2015 Ryan Stock

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

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

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

*/

(function($) {

    $.fn.gravityScroll = function(method) {

		var settings;

		// The original container that gravityScroll() is attached to.
		var $original_container;

		// We sometimes have to change the container to something that works better than what the user provided. i.e. $('body')
		var $container;

		// The container that works better for scroll events. i.e. $original_container or ('html,body')
		var $scroll_container;

		// The container that works better for animating scrolling. i.e. $original_container or $(document)
		var $animation_container;

		// All the children elements
		var $children = $();

        var methods = {
            init : function(options) {
                settings = $.extend({}, this.gravityScroll.defaults, options);
				if ( ! settings.children.length ) {
					return;
				}
				$original_container = $container = this;

				// If the container is not able to handle scroll events, use the the best alternatives instead.
				if ( $container.is($('html,body')) || $container.is($(settings.window)) ) {
					$container = $('body');
					$scroll_container = $(document);
					$animation_container = $('body,html');
				} else {
					$scroll_container = $container;
				}

				helpers.addChildren( settings.children );
				helpers.attachScrollHandler();

				helpers.log( 'Children:', $children );
            }
        };

        var helpers = {

			// Register children with the plugin while setting their data attributes
			addChild: function( child ) {
				var info = $.extend({}, $original_container.gravityScroll.child_defaults, child);
				var $child = $(info.selector);
				helpers.log( 'Adding child', $child );
				$child.data('gravityscroll-pause', info.pause);
				$child.data('gravityscroll-range', info.range);
				$child.data('gravityscroll-easing', info.easing);
				$children = $children.add( $child );
			},

			// Go through children and register them
			addChildren: function( children ) {
				helpers.log( 'Adding children', children );
				for( var i = 0; i < children.length; i++ ) {
					helpers.addChild( children[i] );
				}
			},

			// Attach the gravity scroll handler to an element. (The container that scrolls)
			attachScrollHandler: function() {
				if ( $container.data( 'gravityscroll-hashandler' ) === '1' ) {
					return;
				}
				$scroll_container.scroll(function(e) {
					// Ensure scroll events don't take up too much CPU by calling only before animation frame change.
					window.requestAnimationFrame( helpers.scrollHandler );
				});
				$container.data( 'gravityscroll-hashandler', '1' );
				$scroll_container.scroll();
			},

			// Return all children who we might potentially scroll to
			getChildrenInDangerZone: function() {
				var $matches = $();
				$children.each(function() {
					$child = $(this);
					if ( helpers.isInDangerZone( $child ) ) {
						$matches = $matches.add( $child );
						helpers.log( 'Matched:', $child, $matches );
					}
				});
				return $matches;
			},

			// Get the current scroll position of an object (or the window if object not provided)
			getScrollPosition: function( object ) {
				if ( ! object ) {
					object = window;
				}
				return [
					$(object).scrollLeft(),
					$(object).scrollTop()
			 	];
			},

			// Get relative position between two elements.
			getRelativePosition: function( of, to ) {
				helpers.log( 'getRelativePosition', of, to );
				helpers.log( settings.document, settings.window );
				var of_offset, to_offset;
				if ( of.is(settings.document) ) {
					of_offset = { 'left': settings.window.scrollLeft(), 'top': settings.window.scrollTop() };
				} else {
					of_offset = of.offset();
				}
				if ( to.is(settings.document) ) {
					to_offset = { 'left': settings.window.scrollLeft(), 'top': settings.window.scrollTop() };
				} else {
					to_offset = to.offset();
				}
				return [
					of_offset.left - to_offset.left,
					of_offset.top - to_offset.top
				];
			},

			// Is the element in a position that will be effected by gravity?
			isInDangerZone: function( element ) {
				var $element = element;
				var position = -helpers.positionFromContainer( $element );
				helpers.log( 'Position from danger zone:', position, $element, $element.data('gravityscroll-range') );
				return (
					( $element.data('gravityscroll-range')[0] < position ) && ( position < $element.data('gravityscroll-range')[1] )
				);
			},

			// Pixel distance that $element is away from $container
			positionFromContainer: function( element ) {
				var $element = element;
				return helpers.getRelativePosition( $element, $scroll_container )[1];
			},

			// Called on the container when the user scrolls.
            scrollHandler: function() {
				helpers.log( 'Handling scroll' );
				$container.data('gravityscroll-moving','1');
				clearTimeout( $container.data('gravityscroll-scrollingtimeout') );
				$container.data('gravityscroll-scrollingtimeout',
					setTimeout( function() {
						helpers.log( 'Slowed' );
						$container.data('gravityscroll-scrolling','0');
					}, 150 )
				);
				helpers.log( 'Scrolling' );
				if ( $container.data('gravityscroll-hasdone') === '1' ) {
					return;
				}
				// When the continer has finished scrolling...
				helpers.whenFinishedScrollMovement( $scroll_container ).done( function() {
					helpers.log( 'Stopped' );
					$container.data('gravityscroll-scrolling','0');
					$container.data('gravityscroll-moving','0');
					var $closest_match = null;
					var closest_distance_from_danger = null;
					var $matches = helpers.getChildrenInDangerZone();
					helpers.log( 'Children found in danger zone: ', $matches.length );
					$matches.each(function() {
						$element = $(this);
						var distance_from_danger = Math.abs(helpers.positionFromContainer( $element ));
						if ( closest_distance_from_danger !== null ) {
							if ( distance_from_danger < closest_distance_from_danger ) {
								$closest_match = $element;
								closest_distance_from_danger = distance_from_danger;
							}
						} else {
							$closest_match = $element;
							closest_distance_from_danger = distance_from_danger;
						}
					});
					if ( $closest_match !== null ) {
						helpers.scrollContainerToElement( $closest_match );
					}
					$container.data('gravityscroll-hasdone','0');
				});
				$container.data('gravityscroll-hasdone','1');
			},

			// a Promise that is .done() when the scrolling movement of the element has stopped.
			whenFinishedScrollMovement: function( element ) {
				$element = element;
				// If we already have a Deferred, return that.
				if ( typeof element.data( 'gravityscroll-movementdeferred' ) !== 'undefined' ) {
					return element.data( 'gravityscroll-movementdeferred' );
				}
				$df = $.Deferred();
				$element.data( 'gravityscroll-movementdeferred', $df );
				var previous_distance = $element.scrollTop();

				// Check if the container has finished moving every 100ms.
				$element.data( 'gravityscroll-movementtimeout', setInterval( function() {
					var current_distance = $element.scrollTop();
					var distance_diff = current_distance - previous_distance;
					// If it hasn't moved since the last check, resolve Deferred.
					if ( distance_diff == 0 ) {
						clearTimeout( element.data( 'gravityscroll-movementtimeout' ) );
						$element.removeData( 'gravityscroll-movementdeferred' );
						$element.removeData( 'gravityscroll-movementtimeout' );
						$df.resolve();
					}
					previous_distance = current_distance;
				}, 200 ));
				return $df.promise();
			},

			// Scroll container so element is at the top.
			scrollContainerToElement: function( element ) {
				var $element = element;
				var pause = $element.data('gravityscroll-pause');
				if ( $container.data('gravityscroll-animating') === '1' ) {
					helpers.log( 'Already scrolling - ignore.' );
					return;
				}
				$container.data('gravityscroll-currentpause', pause);
				var relative_position = helpers.getRelativePosition( $element, $scroll_container );
				var position = $animation_container.scrollTop() + parseInt(relative_position[1]);
				helpers.log( 'Scrolling container to ', position );
				$container.data('gravityscroll-animating', '1');
				helpers.log('$animation_container.stop()');
				$animation_container.stop('gravityscroll-animation-queue');
				helpers.log('$animation_container.animate()');
				$animation_container.animate({scrollTop:position},{
					speed: settings.speed,
					easing: $element.data('gravityscroll-easing'),
					queue: 'gravityscroll-animation-queue'
				}).promise().done(function() {
					helpers.log( 'Completed animation' );
					$element.data('gravityscroll-indanger', '0' );
					$container.data('gravityscroll-animating', '0');
					$container.data('gravityscroll-currentpause', '0');
				});
				$animation_container.dequeue( 'gravityscroll-animation-queue' );
			},

			log: function() {
				if ( settings.developer ) {
					if(typeof(console) !== 'undefined'){
						console.log.apply(console, arguments);
					}
				}
			}
        }
		// Depending on args sent to gravityScroll()...
        if (methods[method]) {
			// ...if method exists for it, return that.
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
			// ...if not, call the init.
            return methods.init.apply(this, arguments);
        } else {
			// ...or throw an error.
            $.error( 'Method "' +  method + '" does not exist in gravityScroll plugin!');
        }

    }

    $.fn.gravityScroll.defaults = {
		debug: false,
		window: $(window),
		document: $(document)
    }

    $.fn.gravityScroll.child_defaults = {
        range: [-20, 20],
		updateDistance: 2,
		pause: 250,
		speed: 400,
		easing: 'swing'
    }

    $.fn.gravityScroll.settings = {}

})(jQuery);
<commit_msg>Fix for non-document containers<commit_after>// Gravity Scrolling jQuery Plugin by Ryan Stock
// www.github.com/ryanstockau/gravity-scrolling

/*

LICENSE

The MIT License (MIT)

Copyright (c) 2015 Ryan Stock

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

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

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

*/

(function($) {

    $.fn.gravityScroll = function(method) {

		var settings;

		// The original container that gravityScroll() is attached to.
		var $original_container;

		// We sometimes have to change the container to something that works better than what the user provided. i.e. $('body')
		var $container;

		// The container that works better for scroll events. i.e. $original_container or ('html,body')
		var $scroll_container;

		// The container that works better for animating scrolling. i.e. $original_container or $(document)
		var $animation_container;

		// All the children elements
		var $children = $();

        var methods = {
            init : function(options) {
                settings = $.extend({}, this.gravityScroll.defaults, options);
				if ( ! settings.children.length ) {
					return;
				}
				$original_container = this;

				// If the container is not able to handle scroll events, use the the best alternatives instead.
				if ( $container.is($('html,body')) || $container.is($(settings.window)) ) {
					$container = $('body');
					$scroll_container = $(document);
					$animation_container = $('body,html');
				} else {
					$container = $original_container;
					$scroll_container = $original_container;
					$animation_container = $original_container;
				}

				helpers.addChildren( settings.children );
				helpers.attachScrollHandler();

				helpers.log( 'Children:', $children );
            }
        };

        var helpers = {

			// Register children with the plugin while setting their data attributes
			addChild: function( child ) {
				var info = $.extend({}, $original_container.gravityScroll.child_defaults, child);
				var $child = $(info.selector);
				helpers.log( 'Adding child', $child );
				$child.data('gravityscroll-pause', info.pause);
				$child.data('gravityscroll-range', info.range);
				$child.data('gravityscroll-easing', info.easing);
				$children = $children.add( $child );
			},

			// Go through children and register them
			addChildren: function( children ) {
				helpers.log( 'Adding children', children );
				for( var i = 0; i < children.length; i++ ) {
					helpers.addChild( children[i] );
				}
			},

			// Attach the gravity scroll handler to an element. (The container that scrolls)
			attachScrollHandler: function() {
				if ( $container.data( 'gravityscroll-hashandler' ) === '1' ) {
					return;
				}
				$scroll_container.scroll(function(e) {
					// Ensure scroll events don't take up too much CPU by calling only before animation frame change.
					window.requestAnimationFrame( helpers.scrollHandler );
				});
				$container.data( 'gravityscroll-hashandler', '1' );
				$scroll_container.scroll();
			},

			// Return all children who we might potentially scroll to
			getChildrenInDangerZone: function() {
				var $matches = $();
				$children.each(function() {
					$child = $(this);
					if ( helpers.isInDangerZone( $child ) ) {
						$matches = $matches.add( $child );
						helpers.log( 'Matched:', $child, $matches );
					}
				});
				return $matches;
			},

			// Get the current scroll position of an object (or the window if object not provided)
			getScrollPosition: function( object ) {
				if ( ! object ) {
					object = window;
				}
				return [
					$(object).scrollLeft(),
					$(object).scrollTop()
			 	];
			},

			// Get relative position between two elements.
			getRelativePosition: function( of, to ) {
				helpers.log( 'getRelativePosition', of, to );
				helpers.log( settings.document, settings.window );
				var of_offset, to_offset;
				if ( of.is(settings.document) ) {
					of_offset = { 'left': settings.window.scrollLeft(), 'top': settings.window.scrollTop() };
				} else {
					of_offset = of.offset();
				}
				if ( to.is(settings.document) ) {
					to_offset = { 'left': settings.window.scrollLeft(), 'top': settings.window.scrollTop() };
				} else {
					to_offset = to.offset();
				}
				return [
					of_offset.left - to_offset.left,
					of_offset.top - to_offset.top
				];
			},

			// Is the element in a position that will be effected by gravity?
			isInDangerZone: function( element ) {
				var $element = element;
				var position = -helpers.positionFromContainer( $element );
				helpers.log( 'Position from danger zone:', position, $element, $element.data('gravityscroll-range') );
				return (
					( $element.data('gravityscroll-range')[0] < position ) && ( position < $element.data('gravityscroll-range')[1] )
				);
			},

			// Pixel distance that $element is away from $container
			positionFromContainer: function( element ) {
				var $element = element;
				return helpers.getRelativePosition( $element, $scroll_container )[1];
			},

			// Called on the container when the user scrolls.
            scrollHandler: function() {
				helpers.log( 'Handling scroll' );
				$container.data('gravityscroll-moving','1');
				clearTimeout( $container.data('gravityscroll-scrollingtimeout') );
				$container.data('gravityscroll-scrollingtimeout',
					setTimeout( function() {
						helpers.log( 'Slowed' );
						$container.data('gravityscroll-scrolling','0');
					}, 150 )
				);
				helpers.log( 'Scrolling' );
				if ( $container.data('gravityscroll-hasdone') === '1' ) {
					return;
				}
				// When the continer has finished scrolling...
				helpers.whenFinishedScrollMovement( $scroll_container ).done( function() {
					helpers.log( 'Stopped' );
					$container.data('gravityscroll-scrolling','0');
					$container.data('gravityscroll-moving','0');
					var $closest_match = null;
					var closest_distance_from_danger = null;
					var $matches = helpers.getChildrenInDangerZone();
					helpers.log( 'Children found in danger zone: ', $matches.length );
					$matches.each(function() {
						$element = $(this);
						var distance_from_danger = Math.abs(helpers.positionFromContainer( $element ));
						if ( closest_distance_from_danger !== null ) {
							if ( distance_from_danger < closest_distance_from_danger ) {
								$closest_match = $element;
								closest_distance_from_danger = distance_from_danger;
							}
						} else {
							$closest_match = $element;
							closest_distance_from_danger = distance_from_danger;
						}
					});
					if ( $closest_match !== null ) {
						helpers.scrollContainerToElement( $closest_match );
					}
					$container.data('gravityscroll-hasdone','0');
				});
				$container.data('gravityscroll-hasdone','1');
			},

			// a Promise that is .done() when the scrolling movement of the element has stopped.
			whenFinishedScrollMovement: function( element ) {
				$element = element;
				// If we already have a Deferred, return that.
				if ( typeof element.data( 'gravityscroll-movementdeferred' ) !== 'undefined' ) {
					return element.data( 'gravityscroll-movementdeferred' );
				}
				$df = $.Deferred();
				$element.data( 'gravityscroll-movementdeferred', $df );
				var previous_distance = $element.scrollTop();

				// Check if the container has finished moving every 100ms.
				$element.data( 'gravityscroll-movementtimeout', setInterval( function() {
					var current_distance = $element.scrollTop();
					var distance_diff = current_distance - previous_distance;
					// If it hasn't moved since the last check, resolve Deferred.
					if ( distance_diff == 0 ) {
						clearTimeout( element.data( 'gravityscroll-movementtimeout' ) );
						$element.removeData( 'gravityscroll-movementdeferred' );
						$element.removeData( 'gravityscroll-movementtimeout' );
						$df.resolve();
					}
					previous_distance = current_distance;
				}, 200 ));
				return $df.promise();
			},

			// Scroll container so element is at the top.
			scrollContainerToElement: function( element ) {
				var $element = element;
				var pause = $element.data('gravityscroll-pause');
				if ( $container.data('gravityscroll-animating') === '1' ) {
					helpers.log( 'Already scrolling - ignore.' );
					return;
				}
				$container.data('gravityscroll-currentpause', pause);
				var relative_position = helpers.getRelativePosition( $element, $scroll_container );
				var position = $animation_container.scrollTop() + parseInt(relative_position[1]);
				helpers.log( 'Scrolling container to ', position );
				$container.data('gravityscroll-animating', '1');
				helpers.log('$animation_container.stop()');
				$animation_container.stop('gravityscroll-animation-queue');
				helpers.log('$animation_container.animate()');
				$animation_container.animate({scrollTop:position},{
					speed: settings.speed,
					easing: $element.data('gravityscroll-easing'),
					queue: 'gravityscroll-animation-queue'
				}).promise().done(function() {
					helpers.log( 'Completed animation' );
					$element.data('gravityscroll-indanger', '0' );
					$container.data('gravityscroll-animating', '0');
					$container.data('gravityscroll-currentpause', '0');
				});
				$animation_container.dequeue( 'gravityscroll-animation-queue' );
			},

			log: function() {
				if ( settings.developer ) {
					if(typeof(console) !== 'undefined'){
						console.log.apply(console, arguments);
					}
				}
			}
        }
		// Depending on args sent to gravityScroll()...
        if (methods[method]) {
			// ...if method exists for it, return that.
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
			// ...if not, call the init.
            return methods.init.apply(this, arguments);
        } else {
			// ...or throw an error.
            $.error( 'Method "' +  method + '" does not exist in gravityScroll plugin!');
        }

    }

    $.fn.gravityScroll.defaults = {
		debug: false,
		window: $(window),
		document: $(document)
    }

    $.fn.gravityScroll.child_defaults = {
        range: [-20, 20],
		updateDistance: 2,
		pause: 250,
		speed: 400,
		easing: 'swing'
    }

    $.fn.gravityScroll.settings = {}

})(jQuery);
<|endoftext|>


<commit_before>var myTools = {
  readTSV: function (str, head) { // str is a string, head is true or false
    var result = {};
    var strArr = str.split('\n');
    if (head) {
      result.th = strArr[0];
      result.td = strArr.slice(1);
      return result;
    }
    result.td = strArr;
    return result;
  },
  prepTable: function (data) { // data = {th: str, td: [str, str, ...]}
    var html = '
';
    if (data.th) {
      var vals = data.th.split('\t');
      html += '
';
      for (var i = 0, len = vals.length; i < len; i++) {
        html += `<th>${vals[i]}</th>`;
      }
      html += '
';
    }
    for (i = 0, len = data.td.length; i < len; i++) {
      if (data.td[i]) {
        var row = '
';
        var line = data.td[i].split('\t');
        for (var j = 0; j < line.length; j++) {
          row += `<td>${line[j]}</td>`;
        }
        row += '
';
        html += row;
      }
    }
    return html + '
';
  }
};
<commit_msg>replace var with let<commit_after>let myTools = {
  readTSV: function (str, head) { // str is a string, head is true or false
    let result = {};
    let strArr = str.split('\n');
    if (head) {
      result.th = strArr[0];
      result.td = strArr.slice(1);
      return result;
    }
    result.td = strArr;
    return result;
  },
  prepTable: function (data) { // data = {th: str, td: [str, str, ...]}
    let html = '
';
    if (data.th) {
      let vals = data.th.split('\t');
      html += '
';
      for (let i = 0, len = vals.length; i < len; i++) {
        html += `<th>${vals[i]}</th>`;
      }
      html += '
';
    }
    for (i = 0, len = data.td.length; i < len; i++) {
      if (data.td[i]) {
        let row = '
';
        let line = data.td[i].split('\t');
        for (let j = 0; j < line.length; j++) {
          row += `<td>${line[j]}</td>`;
        }
        row += '
';
        html += row;
      }
    }
    return html + '
';
  }
};
<|endoftext|>


<commit_before><commit_msg>Do not validate if the component is not an input.<commit_after><|endoftext|>


<commit_before><commit_msg>move code runner to core modules<commit_after><|endoftext|>


<commit_before>/**
 * Created by Olav on 10/9/2015.
 */
import React from "react";
import ExperimentHistory from './libs/ExperimentHistory.js';
import ExperimentList from './libs/ExperimentList.js';
import moment from "moment";

class List extends React.Component {

    constructor() {
        super();
        this.state = {active: {}}
    }

    _handleListClick(experiment) {
        this.setState({active: experiment});
        this.props.onListChange(experiment);
    }
    render() {

        var list = this.props.experiments.map((experiment) => {
            let handler = this._handleListClick.bind(this, experiment);
            let isActive = this.state.active._id === experiment._id? "active": "";
            return (

                    {moment(experiment.date_start).format("HH:mm:ss DD-MM-YYYY")}

)
        });
        return (

{list}

        );
    }
}

class Experiments extends React.Component {

    constructor() {
        super();
        this.state = {experiments: [], display: {}};
        this._listChange = this._handleListChange.bind(this);
    }

    componentWillMount() {
        var jobs = JSON.parse(this.props.data);
        this.setState({experiments: jobs})
    }

    _handleListChange(experiment) {
        this.setState({display: experiment});
    }
    render() {

        var emptyMessage = !this.state.display._id? (

No experiment has been selected

): null;
        return (

                    <List ref="list" experiments={this.state.experiments} onListChange={this._listChange}/>

Experiment history

                    <ExperimentHistory experiment={this.state.display} />
                    {emptyMessage}

        );
    }
}

Experiments.title = "Experiments";
Experiments.description =  "";

module.exports = Experiments;<commit_msg>More stuff<commit_after>/**
 * Created by Olav on 10/9/2015.
 */
import React from "react";
import ExperimentHistory from './libs/ExperimentHistory.js';
import ExperimentList from './libs/ExperimentList.js';
import moment from "moment";

class List extends React.Component {

    constructor() {
        super();
        this.state = {active: {}}
    }

    _handleListClick(experiment) {
        this.setState({active: experiment});
        this.props.onListChange(experiment);
    }
    render() {

        var list = this.props.experiments.map((experiment) => {
            let handler = this._handleListClick.bind(this, experiment);
            let isActive = this.state.active._id === experiment._id? "active": "";
            return (

                    {moment(experiment.date_start).format("HH:mm:ss DD-MM-YYYY")}

)
        });
        return (

{list}

        );
    }
}

class Experiments extends React.Component {

    constructor() {
        super();
        this.state = {experiments: [], display: {}};
        this._listChange = this._handleListChange.bind(this);
    }

    componentWillMount() {
        var jobs = JSON.parse(this.props.data);
        this.setState({experiments: jobs})
    }

    _handleListChange(experiment) {
        this.setState({display: experiment});
    }
    render() {

        var emptyMessage = !this.state.display._id? (

No experiment has been selected

): null;
        return (

Experiment history

                    <List ref="list" experiments={this.state.experiments} onListChange={this._listChange}/>

                    <ExperimentHistory experiment={this.state.display} />
                    {emptyMessage}

        );
    }
}

Experiments.title = "Experiments";
Experiments.description =  "";

module.exports = Experiments;<|endoftext|>


<commit_before>// transpile:mocha

import _ from 'lodash';
import B from 'bluebird';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import wd from 'wd';
import axios from 'axios';
import { main as appiumServer } from '../lib/main';
import { TEST_FAKE_APP, TEST_HOST, TEST_PORT } from './helpers';
import { BaseDriver } from 'appium-base-driver';
import { FakeDriver } from 'appium-fake-driver';
import sinon from 'sinon';

chai.use(chaiAsPromised);

const should = chai.should();
const shouldStartServer = process.env.USE_RUNNING_SERVER !== '0';
const caps = {
  automationName: 'Fake',
  platformName: 'Fake',
  deviceName: 'Fake',
  app: TEST_FAKE_APP
};

describe('FakeDriver - via HTTP', function () {
  let server = null;
  const baseUrl = `http://${TEST_HOST}:${TEST_PORT}/wd/hub/session`;
  before(async function () {
    if (shouldStartServer) {
      let args = {port: TEST_PORT, host: TEST_HOST};
      server = await appiumServer(args);
    }
  });
  after(async function () {
    if (server) {
      await server.close();
    }
  });

  describe('session handling', function () {
    it('should start and stop a session', async function () {
      let driver = wd.promiseChainRemote(TEST_HOST, TEST_PORT);
      let [sessionId] = await driver.init(caps);
      should.exist(sessionId);
      sessionId.should.be.a('string');
      await driver.quit();
      await driver.title().should.eventually.be.rejectedWith(/terminated/);
    });

    it('should be able to run two FakeDriver sessions simultaneously', async function () {
      let driver1 = wd.promiseChainRemote(TEST_HOST, TEST_PORT);
      let [sessionId1] = await driver1.init(caps);
      should.exist(sessionId1);
      sessionId1.should.be.a('string');
      let driver2 = wd.promiseChainRemote(TEST_HOST, TEST_PORT);
      let [sessionId2] = await driver2.init(caps);
      should.exist(sessionId2);
      sessionId2.should.be.a('string');
      sessionId1.should.not.equal(sessionId2);
      await driver1.quit();
      await driver2.quit();
    });

    it('should not be able to run two FakeDriver sessions simultaneously when one is unique', async function () {
      let uniqueCaps = _.clone(caps);
      uniqueCaps.uniqueApp = true;
      let driver1 = wd.promiseChainRemote(TEST_HOST, TEST_PORT);
      let [sessionId1] = await driver1.init(uniqueCaps);
      should.exist(sessionId1);
      sessionId1.should.be.a('string');
      let driver2 = wd.promiseChainRemote(TEST_HOST, TEST_PORT);
      await driver2.init(caps).should.eventually.be.rejected;
      await driver1.quit();
    });

    it('should use the newCommandTimeout of the inner Driver on session creation', async function () {
      let driver = wd.promiseChainRemote(TEST_HOST, TEST_PORT);

      let localCaps = Object.assign({
        newCommandTimeout: 0.25,
      }, caps);

      let [sessionId] = await driver.init(localCaps);
      should.exist(sessionId);

      await B.delay(250);
      await driver.source().should.eventually.be.rejectedWith(/terminated/);
    });

    it('should accept valid W3C capabilities and start a W3C session', async function () {
      // Try with valid capabilities and check that it returns a session ID
      const w3cCaps = {
        capabilities: {
          alwaysMatch: {automationName: 'Fake', platformName: 'Fake'},
          firstMatch: [{'appium:deviceName': 'Fake', 'appium:app': TEST_FAKE_APP}],
        }
      };

      // Create the session
      const {status, value, sessionId} = (await axios.post(baseUrl, w3cCaps)).data;
      should.not.exist(status); // Test that it's a W3C session by checking that 'status' is not in the response
      should.not.exist(sessionId);
      value.sessionId.should.be.a.string;
      value.should.exist;
      value.capabilities.should.deep.equal({
        automationName: 'Fake',
        platformName: 'Fake',
        deviceName: 'Fake',
        app: TEST_FAKE_APP,
      });

      // Now use that sessionId to call /screenshot
      const {status: screenshotStatus, value: screenshotValue} = (await axios({url: `${baseUrl}/${value.sessionId}/screenshot`})).data;
      should.not.exist(screenshotStatus);
      screenshotValue.should.equal('hahahanotreallyascreenshot');

      // Now use that sessionID to call an arbitrary W3C-only endpoint that isn't implemented to see if it responds with correct error
      await axios.post(
        `${baseUrl}/${value.sessionId}/execute/async`,
        {script: '', args: ['a']}).should.eventually.be.rejectedWith(/405/);

      // End session
      await axios.delete(`${baseUrl}/${value.sessionId}`);
    });

    it('should reject invalid W3C capabilities and respond with a 400 Bad Parameters error', async function () {
      const badW3Ccaps = {
        capabilities: {
          alwaysMatch: {},
          firstMatch: [{'appium:deviceName': 'Fake', 'appium:app': TEST_FAKE_APP}],
        }
      };

      await axios.post(baseUrl, badW3Ccaps).should.eventually.be.rejectedWith(/400/);
    });

    it('should accept a combo of W3C and JSONWP capabilities but default to W3C', async function () {
      const combinedCaps = {
        'desiredCapabilities': {
          ...caps,
        },
        'capabilities': {
          'alwaysMatch': {...caps},
          'firstMatch': [{
            w3cParam: 'w3cParam',
          }],
        }
      };

      const {status, value, sessionId} = (await axios.post(baseUrl, combinedCaps)).data;
      should.not.exist(status); // If it's a W3C session, should not respond with 'status'
      should.not.exist(sessionId);
      value.sessionId.should.exist;
      value.capabilities.should.deep.equal({
        ...caps,
        w3cParam: 'w3cParam',
      });

      // End session
      await axios.delete(`${baseUrl}/${value.sessionId}`);
    });

    it('should accept a combo of W3C and JSONWP and if JSONWP has extraneous keys, they should be merged into W3C capabilities', async function () {
      const combinedCaps = {
        'desiredCapabilities': {
          ...caps,
          automationName: 'Fake',
          anotherParam: 'Hello',
        },
        'capabilities': {
          'alwaysMatch': {...caps},
          'firstMatch': [{
            w3cParam: 'w3cParam',
          }],
        }
      };

      const {sessionId, status, value} = (await axios.post(baseUrl, combinedCaps)).data;
      should.not.exist(sessionId);
      should.not.exist(status);
      value.sessionId.should.exist;
      value.capabilities.should.deep.equal({
        ...caps,
        automationName: 'Fake',
        anotherParam: 'Hello',
        w3cParam: 'w3cParam',
      });

      // End session
      await axios.delete(`${baseUrl}/${value.sessionId}`);
    });

    it('should reject bad automation name with an appropriate error', async function () {
      const w3cCaps = {
        capabilities: {
          alwaysMatch: {
            ...caps,
            automationName: 'BadAutomationName',
          },
        },
      };
      await axios.post(baseUrl, w3cCaps).should.eventually.be.rejectedWith(/Could not find a driver for/);
    });

    it('should accept capabilities that are provided in the firstMatch array', async function () {
      const w3cCaps = {
        capabilities: {
          alwaysMatch: {},
          firstMatch: [{}, {
            ...caps
          }],
        },
      };
      const {value, sessionId, status} = (await axios.post(baseUrl, w3cCaps)).data;
      should.not.exist(status);
      should.not.exist(sessionId);
      value.capabilities.should.deep.equal(caps);

      // End session
      await axios.delete(`${baseUrl}/${value.sessionId}`);
    });

    it('should fall back to MJSONWP if w3c caps are invalid', async function () {
      const combinedCaps = {
        desiredCapabilities: {
          ...caps,
        },
        capabilities: {
          alwaysMatch: {},
          firstMatch: [{}, {
            ...caps,
            platformName: null,
            automationName: null,
            deviceName: null,
          }],
        },
      };
      const {value, sessionId, status} = (await axios.post(baseUrl, combinedCaps)).data;
      status.should.exist;
      sessionId.should.exist;
      value.should.deep.equal(caps);

      // End session
      await axios.delete(`${baseUrl}/${sessionId}`);
    });

    it('should fall back to MJSONWP if Inner Driver is not ready for W3C', async function () {
      const combinedCaps = {
        desiredCapabilities: {
          ...caps,
        },
        capabilities: {
          alwaysMatch: {
            ...caps,
            deviceName: null,
          },
        },
      };
      const createSessionStub = sinon.stub(FakeDriver.prototype, 'createSession').callsFake(async function (jsonwpCaps) {
        const res = await BaseDriver.prototype.createSession.call(this, jsonwpCaps);
        this.protocol.should.equal('MJSONWP');
        return res;
      });

      const {value, sessionId, status} = (await axios.post(baseUrl, combinedCaps)).data;
      status.should.exist;
      sessionId.should.exist;
      value.should.deep.equal(caps);

      createSessionStub.restore();

      // End session
      await axios.delete(`${baseUrl}/${sessionId}`);
    });

    it('should handle concurrent MJSONWP and W3C sessions', async function () {
      const combinedCaps = {
        desiredCapabilities: {
          ...caps,
        },
        capabilities: {
          alwaysMatch: {
            ...caps,
          },
          firstMatch: [],
        },
      };

      // Have an MJSONWP and W3C session running concurrently
      const {sessionId: mjsonwpSessId, value: mjsonwpValue, status} = (await axios.post(baseUrl, _.omit(combinedCaps, 'capabilities'))).data;
      status.should.exist;
      mjsonwpValue.should.eql(caps);
      mjsonwpSessId.should.exist;

      const {value} = (await axios.post(baseUrl, _.omit(combinedCaps, 'desiredCapabilities'))).data;
      const w3cSessId = value.sessionId;
      w3cSessId.should.exist;
      value.capabilities.should.eql(caps);

      // Test that both return the proper payload based on their protocol
      const mjsonwpPayload = (await axios.get(`${baseUrl}/${mjsonwpSessId}`)).data;
      mjsonwpPayload.sessionId.should.exist;
      mjsonwpPayload.status.should.exist;
      mjsonwpPayload.value.should.eql(caps);

      const w3cPayload = (await axios.get(`${baseUrl}/${w3cSessId}`)).data;
      should.not.exist(w3cPayload.sessionId);
      should.not.exist(w3cPayload.status);
      w3cPayload.value.should.eql(caps);

      // End sessions
      await axios.delete(`${baseUrl}/${mjsonwpSessId}`);
      await axios.delete(`${baseUrl}/${w3cSessId}`);
    });
  });
});

describe('Logsink', function () {
  let server = null;
  let logs = [];
  let logHandler = function (level, message) {
    logs.push([level, message]);
  };
  let args = {
    port: TEST_PORT,
    host: TEST_HOST,
    logHandler,
  };

  before(async function () {
    server = await appiumServer(args);
  });

  after(async function () {
    await server.close();
  });

  it('should send logs to a logHandler passed in by a parent package', function () {
    logs.length.should.be.above(1);
    let welcomeIndex = logs[0][1].includes('versions of node') ? 1 : 0;
    logs[welcomeIndex].length.should.equal(2);
    logs[welcomeIndex][1].should.include('Welcome to Appium');
  });
});
<commit_msg>fix: fix broken e2e tests<commit_after>// transpile:mocha

import _ from 'lodash';
import B from 'bluebird';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import wd from 'wd';
import axios from 'axios';
import { main as appiumServer } from '../lib/main';
import { DEFAULT_APPIUM_HOME } from '../lib/parser';
import { TEST_FAKE_APP, TEST_HOST, TEST_PORT } from './helpers';
import { BaseDriver } from 'appium-base-driver';
import { FakeDriver } from 'appium-fake-driver';
import sinon from 'sinon';

chai.use(chaiAsPromised);

const should = chai.should();
const shouldStartServer = process.env.USE_RUNNING_SERVER !== '0';
const caps = {
  automationName: 'Fake',
  platformName: 'Fake',
  deviceName: 'Fake',
  app: TEST_FAKE_APP
};

describe('FakeDriver - via HTTP', function () {
  let server = null;
  const baseUrl = `http://${TEST_HOST}:${TEST_PORT}/wd/hub/session`;
  before(async function () {
    if (shouldStartServer) {
      let args = {port: TEST_PORT, host: TEST_HOST, appiumHome: DEFAULT_APPIUM_HOME};
      server = await appiumServer(args);
    }
  });
  after(async function () {
    if (server) {
      await server.close();
    }
  });

  describe('session handling', function () {
    it('should start and stop a session', async function () {
      let driver = wd.promiseChainRemote(TEST_HOST, TEST_PORT);
      let [sessionId] = await driver.init(caps);
      should.exist(sessionId);
      sessionId.should.be.a('string');
      await driver.quit();
      await driver.title().should.eventually.be.rejectedWith(/terminated/);
    });

    it('should be able to run two FakeDriver sessions simultaneously', async function () {
      let driver1 = wd.promiseChainRemote(TEST_HOST, TEST_PORT);
      let [sessionId1] = await driver1.init(caps);
      should.exist(sessionId1);
      sessionId1.should.be.a('string');
      let driver2 = wd.promiseChainRemote(TEST_HOST, TEST_PORT);
      let [sessionId2] = await driver2.init(caps);
      should.exist(sessionId2);
      sessionId2.should.be.a('string');
      sessionId1.should.not.equal(sessionId2);
      await driver1.quit();
      await driver2.quit();
    });

    it('should not be able to run two FakeDriver sessions simultaneously when one is unique', async function () {
      let uniqueCaps = _.clone(caps);
      uniqueCaps.uniqueApp = true;
      let driver1 = wd.promiseChainRemote(TEST_HOST, TEST_PORT);
      let [sessionId1] = await driver1.init(uniqueCaps);
      should.exist(sessionId1);
      sessionId1.should.be.a('string');
      let driver2 = wd.promiseChainRemote(TEST_HOST, TEST_PORT);
      await driver2.init(caps).should.eventually.be.rejected;
      await driver1.quit();
    });

    it('should use the newCommandTimeout of the inner Driver on session creation', async function () {
      let driver = wd.promiseChainRemote(TEST_HOST, TEST_PORT);

      let localCaps = Object.assign({
        newCommandTimeout: 0.25,
      }, caps);

      let [sessionId] = await driver.init(localCaps);
      should.exist(sessionId);

      await B.delay(250);
      await driver.source().should.eventually.be.rejectedWith(/terminated/);
    });

    it('should accept valid W3C capabilities and start a W3C session', async function () {
      // Try with valid capabilities and check that it returns a session ID
      const w3cCaps = {
        capabilities: {
          alwaysMatch: {automationName: 'Fake', platformName: 'Fake'},
          firstMatch: [{'appium:deviceName': 'Fake', 'appium:app': TEST_FAKE_APP}],
        }
      };

      // Create the session
      const {status, value, sessionId} = (await axios.post(baseUrl, w3cCaps)).data;
      should.not.exist(status); // Test that it's a W3C session by checking that 'status' is not in the response
      should.not.exist(sessionId);
      value.sessionId.should.be.a.string;
      value.should.exist;
      value.capabilities.should.deep.equal({
        automationName: 'Fake',
        platformName: 'Fake',
        deviceName: 'Fake',
        app: TEST_FAKE_APP,
      });

      // Now use that sessionId to call /screenshot
      const {status: screenshotStatus, value: screenshotValue} = (await axios({url: `${baseUrl}/${value.sessionId}/screenshot`})).data;
      should.not.exist(screenshotStatus);
      screenshotValue.should.equal('hahahanotreallyascreenshot');

      // Now use that sessionID to call an arbitrary W3C-only endpoint that isn't implemented to see if it responds with correct error
      await axios.post(
        `${baseUrl}/${value.sessionId}/execute/async`,
        {script: '', args: ['a']}).should.eventually.be.rejectedWith(/405/);

      // End session
      await axios.delete(`${baseUrl}/${value.sessionId}`);
    });

    it('should reject invalid W3C capabilities and respond with a 400 Bad Parameters error', async function () {
      const badW3Ccaps = {
        capabilities: {
          alwaysMatch: {},
          firstMatch: [{'appium:deviceName': 'Fake', 'appium:app': TEST_FAKE_APP}],
        }
      };

      await axios.post(baseUrl, badW3Ccaps).should.eventually.be.rejectedWith(/400/);
    });

    it('should accept a combo of W3C and JSONWP capabilities but default to W3C', async function () {
      const combinedCaps = {
        'desiredCapabilities': {
          ...caps,
        },
        'capabilities': {
          'alwaysMatch': {...caps},
          'firstMatch': [{
            w3cParam: 'w3cParam',
          }],
        }
      };

      const {status, value, sessionId} = (await axios.post(baseUrl, combinedCaps)).data;
      should.not.exist(status); // If it's a W3C session, should not respond with 'status'
      should.not.exist(sessionId);
      value.sessionId.should.exist;
      value.capabilities.should.deep.equal({
        ...caps,
        w3cParam: 'w3cParam',
      });

      // End session
      await axios.delete(`${baseUrl}/${value.sessionId}`);
    });

    it('should accept a combo of W3C and JSONWP and if JSONWP has extraneous keys, they should be merged into W3C capabilities', async function () {
      const combinedCaps = {
        'desiredCapabilities': {
          ...caps,
          automationName: 'Fake',
          anotherParam: 'Hello',
        },
        'capabilities': {
          'alwaysMatch': {...caps},
          'firstMatch': [{
            w3cParam: 'w3cParam',
          }],
        }
      };

      const {sessionId, status, value} = (await axios.post(baseUrl, combinedCaps)).data;
      should.not.exist(sessionId);
      should.not.exist(status);
      value.sessionId.should.exist;
      value.capabilities.should.deep.equal({
        ...caps,
        automationName: 'Fake',
        anotherParam: 'Hello',
        w3cParam: 'w3cParam',
      });

      // End session
      await axios.delete(`${baseUrl}/${value.sessionId}`);
    });

    it('should reject bad automation name with an appropriate error', async function () {
      const w3cCaps = {
        capabilities: {
          alwaysMatch: {
            ...caps,
            automationName: 'BadAutomationName',
          },
        },
      };
      await axios.post(baseUrl, w3cCaps).should.eventually.be.rejectedWith(/500/);
    });

    it('should accept capabilities that are provided in the firstMatch array', async function () {
      const w3cCaps = {
        capabilities: {
          alwaysMatch: {},
          firstMatch: [{}, {
            ...caps
          }],
        },
      };
      const {value, sessionId, status} = (await axios.post(baseUrl, w3cCaps)).data;
      should.not.exist(status);
      should.not.exist(sessionId);
      value.capabilities.should.deep.equal(caps);

      // End session
      await axios.delete(`${baseUrl}/${value.sessionId}`);
    });

    it('should fall back to MJSONWP if w3c caps are invalid', async function () {
      const combinedCaps = {
        desiredCapabilities: {
          ...caps,
        },
        capabilities: {
          alwaysMatch: {},
          firstMatch: [{}, {
            ...caps,
            platformName: null,
            automationName: null,
            deviceName: null,
          }],
        },
      };
      const {value, sessionId, status} = (await axios.post(baseUrl, combinedCaps)).data;
      status.should.exist;
      sessionId.should.exist;
      value.should.deep.equal(caps);

      // End session
      await axios.delete(`${baseUrl}/${sessionId}`);
    });

    it('should fall back to MJSONWP if Inner Driver is not ready for W3C', async function () {
      const combinedCaps = {
        desiredCapabilities: {
          ...caps,
        },
        capabilities: {
          alwaysMatch: {
            ...caps,
            deviceName: 'Fake',
          },
        },
      };
      const createSessionStub = sinon.stub(FakeDriver.prototype, 'createSession').callsFake(async function (jsonwpCaps) {
        const res = await BaseDriver.prototype.createSession.call(this, jsonwpCaps);
        this.protocol.should.equal('MJSONWP');
        return res;
      });

      const {value} = (await axios.post(baseUrl, combinedCaps)).data;
      const {capabilities, sessionId} = value;
      sessionId.should.exist;
      capabilities.should.deep.equal(caps);

      createSessionStub.restore();

      // End session
      await axios.delete(`${baseUrl}/${sessionId}`);
    });

    it('should handle concurrent MJSONWP and W3C sessions', async function () {
      const combinedCaps = {
        desiredCapabilities: {
          ...caps,
        },
        capabilities: {
          alwaysMatch: {
            ...caps,
          },
          firstMatch: [],
        },
      };

      // Have an MJSONWP and W3C session running concurrently
      const {sessionId: mjsonwpSessId, value: mjsonwpValue, status} = (await axios.post(baseUrl, _.omit(combinedCaps, 'capabilities'))).data;
      status.should.exist;
      mjsonwpValue.should.eql(caps);
      mjsonwpSessId.should.exist;

      const {value} = (await axios.post(baseUrl, _.omit(combinedCaps, 'desiredCapabilities'))).data;
      const w3cSessId = value.sessionId;
      w3cSessId.should.exist;
      value.capabilities.should.eql(caps);

      // Test that both return the proper payload based on their protocol
      const mjsonwpPayload = (await axios.get(`${baseUrl}/${mjsonwpSessId}`)).data;
      mjsonwpPayload.sessionId.should.exist;
      mjsonwpPayload.status.should.exist;
      mjsonwpPayload.value.should.eql(caps);

      const w3cPayload = (await axios.get(`${baseUrl}/${w3cSessId}`)).data;
      should.not.exist(w3cPayload.sessionId);
      should.not.exist(w3cPayload.status);
      w3cPayload.value.should.eql(caps);

      // End sessions
      await axios.delete(`${baseUrl}/${mjsonwpSessId}`);
      await axios.delete(`${baseUrl}/${w3cSessId}`);
    });
  });
});

describe('Logsink', function () {
  let server = null;
  let logs = [];
  let logHandler = function (level, message) {
    logs.push([level, message]);
  };
  let args = {
    port: TEST_PORT,
    host: TEST_HOST,
    appiumHome: DEFAULT_APPIUM_HOME,
    logHandler,
  };

  before(async function () {
    server = await appiumServer(args);
  });

  after(async function () {
    await server.close();
  });

  it('should send logs to a logHandler passed in by a parent package', function () {
    logs.length.should.be.above(1);
    let welcomeIndex = logs[0][1].includes('versions of node') ? 1 : 0;
    logs[welcomeIndex].length.should.equal(2);
    logs[welcomeIndex][1].should.include('Welcome to Appium');
  });
});
<|endoftext|>


<commit_before>document.getElementById("id_logic_version").innerHTML = "Logic version: 2018.11.06.0";

window.addEventListener("deviceorientation", la_schimbare_gyro);

function la_schimbare_gyro(e)
{
  document.getElementById("id_x").innerHTML = e.beta;
  document.getElementById("id_y").innerHTML = e.gamma;
  document.getElementById("id_z").innerHTML = e.alpha;

  var canvas = document.getElementById("id_canvas");
  var context = canvas.getContext("2d");

  var R = 10;

  context.beginPath();
  context.arc(canvas.width / 2 + e.gamma / 90 * (canvas.width / 2 - R),
              canvas.height / 2 + e.beta / 90 * (canvas.height / 2 - R),
              R, 0, 2 * Math.PI);
  context.stroke();
}
<commit_msg>Update orientation.js<commit_after>document.getElementById("id_logic_version").innerHTML = "Logic version: 2018.11.06.1";

window.addEventListener("deviceorientation", la_schimbare_gyro);

function la_schimbare_gyro(e)
{
  document.getElementById("id_x").innerHTML = e.beta;
  document.getElementById("id_y").innerHTML = e.gamma;
  document.getElementById("id_z").innerHTML = e.alpha;

  var canvas = document.getElementById("id_canvas");
  var context = canvas.getContext("2d");

  var R = 10;

  context.clearRect(0, 0, canvas.width, canvas.height);

  context.beginPath();
  context.arc(canvas.width / 2 + e.gamma / 90 * (canvas.width / 2 - R),
              canvas.height / 2 + e.beta / 90 * (canvas.height / 2 - R),
              R, 0, 2 * Math.PI);
  context.stroke();
}
<|endoftext|>


<commit_before>import EventEmitter from 'events';
import remote from 'remote';

const nativeNotifier = remote.require('../browser/bridges/native-notifier').default;

// Extend the default notification API
window.Notification = (function(Html5Notification) {
  log('extending HTML5 Notification');

  const Notification = function(title, options) {
    if (!nativeNotifier.isImplemented) {
      log('showing html5 notification', title, options);
      return new Html5Notification(title, options);
    }

    log('showing native notification');
    const nativeOptions = Object.assign({}, options, {
      canReply: true,
      title: title
    });

    // HTML5-like event emitter to be returned
    const result = Object.assign(new EventEmitter(), nativeOptions);

    // Set the click handler
    nativeOptions.onClick = function(payload) {
      log('notification clicked', payload);
      result.emit('click');

      // Call additional handlers
      if (result.onclick) {
        result.onclick();
      }

      // Send the reply
      if (payload.response) {
        log('sending reply', payload.response);
        setTimeout(function() {
          if (typeReply(payload.response)) {
            sendReply();
          }
        }, 50);
      }
    };

    // Fire the notification
    nativeNotifier.fireNotification(nativeOptions);
    return result;
  };

  return Object.assign(Notification, Html5Notification);
})(window.Notification);

function typeReply(replyText) {
  const event = document.createEvent('TextEvent');
  event.initTextEvent('textInput', true, true, window, replyText, 0, 'en-US');
  const inputField = document.querySelector('div.input');
  if (inputField) {
    inputField.focus();
    return inputField.dispatchEvent(event);
  }
  return false;
}

function sendReply() {
  const event = new MouseEvent('click', {
    view: window,
    bubbles: true,
    cancelable: true
  });
  const sendButton = document.querySelector('.icon.btn-icon.icon-send');
  if (sendButton) {
    sendButton.dispatchEvent(event);
  }
}
<commit_msg>Adds dummy Notification.close instance callback<commit_after>import EventEmitter from 'events';
import remote from 'remote';

const nativeNotifier = remote.require('../browser/bridges/native-notifier').default;

// Extend the default notification API
window.Notification = (function(Html5Notification) {
  log('extending HTML5 Notification');

  const Notification = function(title, options) {
    if (!nativeNotifier.isImplemented) {
      log('showing html5 notification', title, options);
      return new Html5Notification(title, options);
    }

    log('showing native notification');
    const nativeOptions = Object.assign({}, options, {
      canReply: true,
      title: title
    });

    // HTML5-like event emitter to be returned
    const result = Object.assign(new EventEmitter(), nativeOptions);

    // Add a dummy close callback
    result.close = function() {
      log('notification.close() not implemented');
    };

    // Set the click handler
    nativeOptions.onClick = function(payload) {
      log('notification clicked', payload);
      result.emit('click');

      // Call additional handlers
      if (result.onclick) {
        result.onclick();
      }

      // Send the reply
      if (payload.response) {
        log('sending reply', payload.response);
        setTimeout(function() {
          if (typeReply(payload.response)) {
            sendReply();
          }
        }, 50);
      }
    };

    // Fire the notification
    nativeNotifier.fireNotification(nativeOptions);
    return result;
  };

  return Object.assign(Notification, Html5Notification);
})(window.Notification);

function typeReply(replyText) {
  const event = document.createEvent('TextEvent');
  event.initTextEvent('textInput', true, true, window, replyText, 0, 'en-US');
  const inputField = document.querySelector('div.input');
  if (inputField) {
    inputField.focus();
    return inputField.dispatchEvent(event);
  }
  return false;
}

function sendReply() {
  const event = new MouseEvent('click', {
    view: window,
    bubbles: true,
    cancelable: true
  });
  const sendButton = document.querySelector('.icon.btn-icon.icon-send');
  if (sendButton) {
    sendButton.dispatchEvent(event);
  }
}
<|endoftext|>