<commit_before>'use strict';

require('css/log-feed.css');
var m = require('mithril'); // exposes mithril methods, useful for redraw etc.
var $ = require('jquery');
var $osf = require('js/osfHelpers');
var mHelpers = require('js/mithrilHelpers');
var Raven = require('raven-js');
var LogText = require('js/logTextParser');

var MAX_PAGES_ON_PAGINATOR = 7;
var MAX_PAGES_ON_PAGINATOR_SIDE = 5;
var LOG_PAGE_SIZE_LIMITED = 3;
var LOG_PAGE_SIZE = 6;
var PROFILE_IMAGE_SIZE = 16;

var _buildLogUrl = function(node, page, limitLogs) {
    var logPage = page || 1;
    var urlPrefix = (node.isRegistration || node.is_registration) ? 'registrations' : 'nodes';
    var size = limitLogs ? LOG_PAGE_SIZE_LIMITED : LOG_PAGE_SIZE;
    var query = { 'page[size]': size, 'page': logPage, 'embed': ['original_node', 'user', 'linked_node', 'template_node'], 'profile_image_size': PROFILE_IMAGE_SIZE};
    var viewOnly = $osf.urlParams().view_only;
    if (viewOnly) {
        query.view_only = viewOnly;
    }
    return $osf.apiV2Url(urlPrefix + '/' + node.id + '/logs/', { query: query});
};

var LogFeed = {

    controller: function(options) {
        var self = this;
        self.node = options.node;
        self.activityLogs = m.prop([]);
        self.logRequestPending = m.prop(false);
        self.limitLogs = options.limitLogs;
        self.failed = false;
        self.paginators = m.prop([]);
        self.nextPage = m.prop('');
        self.prevPage = m.prop('');
        self.totalPages = m.prop(0);
        self.currentPage = m.prop(0);
        self.pageToGet = m.prop(0);

        self.getLogs = function _getLogs (url) {
            self.activityLogs([]); // Empty logs from other projects while load is happening;
            function _processResults (result){
                result.data.map(function(log){
                    log.attributes.formattableDate = new $osf.FormattableDate(log.attributes.date);
                });

                self.activityLogs(result.data);  // Set activity log data
                self.nextPage(result.links.next);
                self.prevPage(result.links.prev);

                var params = $osf.urlParams(url);
                var page = params.page || 1;
                self.currentPage(parseInt(page));
                self.totalPages(Math.ceil(result.links.meta.total / result.links.meta.per_page));
                $('#linkProjects').toggleClass('disabled');
            }
            self.logRequestPending(true);
            var promise = m.request({method : 'GET', url : url, config: mHelpers.apiV2Config({withCredentials: window.contextVars.isOnRootDomain})});
            promise.then(
                function(result) {
                    _processResults(result);
                    self.logRequestPending(false);
                    return promise;
                }, function(xhr, textStatus, error) {
                    self.failed = true;
                    self.logRequestPending(false);
                    Raven.captureMessage('Error retrieving logs', {extra: {url: url, textStatus: textStatus, error: error}});
                }
            );
        };

        self.getCurrentLogs = function _getCurrentLogs (node, page){
            if(!self.logRequestPending()) {
                var url = _buildLogUrl(node, page, self.limitLogs);
                return self.getLogs(url);
            }
        };
        self.getCurrentLogs(self.node);
    },

    view : function (ctrl) {

        var i;
        ctrl.paginators([]);
        if (ctrl.totalPages() > 1 && !ctrl.limitLogs) {
            // previous page
            ctrl.paginators().push({
                url: function() { return ctrl.prevPage(); },
                text: '<'
            });
            // first page
            ctrl.paginators().push({
                text: 1,
                url: function() {
                    ctrl.pageToGet(1);
                    if(ctrl.pageToGet() !== ctrl.currentPage()) {
                        return _buildLogUrl(ctrl.node, ctrl.pageToGet());
                    }
                }
            });
            // no ellipses
            if (ctrl.totalPages() <= MAX_PAGES_ON_PAGINATOR) {
                for (i = 2; i < ctrl.totalPages(); i++) {
                    ctrl.paginators().push({
                        text: i,
                        url: function() {
                            ctrl.pageToGet(parseInt(this.text));
                            if (ctrl.pageToGet() !== ctrl.currentPage()) {
                                return _buildLogUrl(ctrl.node, ctrl.pageToGet());
                            }
                        }
                    });/* jshint ignore:line */
                    // function defined inside loop
                }
            }
            // one ellipse at the end
            else if (ctrl.currentPage() < MAX_PAGES_ON_PAGINATOR_SIDE - 1) {
                for (i = 2; i < MAX_PAGES_ON_PAGINATOR_SIDE; i++) {
                    ctrl.paginators().push({
                        text: i,
                        url: function() {
                            ctrl.pageToGet(parseInt(this.text));
                            if (ctrl.pageToGet() !== ctrl.currentPage()) {
                                return _buildLogUrl(ctrl.node, ctrl.pageToGet());
                            }
                        }
                    });/* jshint ignore:line */
                    // function defined inside loop
                }
                ctrl.paginators().push({
                    text: '...',
                    url: function() { }
                });
            }
            // one ellipse at the beginning
            else if (ctrl.currentPage() > ctrl.totalPages() - MAX_PAGES_ON_PAGINATOR_SIDE + 2) {
                ctrl.paginators().push({
                    text: '...',
                    url: function() { }
                });
                for (i = ctrl.totalPages() - MAX_PAGES_ON_PAGINATOR_SIDE + 2; i <= ctrl.totalPages() - 1; i++) {
                    ctrl.paginators().push({
                        text: i,
                        url: function() {
                            ctrl.pageToGet(parseInt(this.text));
                            if (ctrl.pageToGet() !== ctrl.currentPage()) {
                                return _buildLogUrl(ctrl.node, ctrl.pageToGet());
                            }
                        }
                    });/* jshint ignore:line */
                    // function defined inside loop
                }
            }
            // two ellipses
            else {
                ctrl.paginators().push({
                    text: '...',
                    url: function() { }
                });
                for (i = parseInt(ctrl.currentPage()) - 1; i <= parseInt(ctrl.currentPage()) + 1; i++) {
                    ctrl.paginators().push({
                        text: i,
                        url: function() {
                            ctrl.pageToGet(parseInt(this.text));
                            if (ctrl.pageToGet() !== ctrl.currentPage()) {
                                return _buildLogUrl(ctrl.node, ctrl.pageToGet());
                            }
                        }
                    });/* jshint ignore:line */
                    // function defined inside loop
                }
                ctrl.paginators().push({
                    text: '...',
                    url: function() { }
                });
            }
            // last page
            ctrl.paginators().push({
                text: ctrl.totalPages(),
                url: function() {
                    ctrl.pageToGet(ctrl.totalPages());
                    if (ctrl.pageToGet() !== ctrl.currentPage()) {
                        return _buildLogUrl(ctrl.node, ctrl.pageToGet());
                    }
                }
            });
            // next page
            ctrl.paginators().push({
                url: function() { return ctrl.nextPage(); },
                text: '>'
            });
        }

        return m('.db-activity-list.m-t-md', [
            // Error message if the log request fails
            ctrl.failed ? m('p', [
                'Unable to retrieve logs at this time. Please refresh the page or contact ',
                m('a', {'href': 'mailto:support@osf.io'}, 'support@osf.io'),
                ' if the problem persists.'
            ]) :
            // Show OSF spinner while there is a pending log request
            ctrl.logRequestPending() ?  m('.spinner-loading-wrapper', [
                m('.logo-spin.logo-lg'),
                m('p.m-t-sm.fg-load-message', 'Loading logs...')
            ]) :
            // Display each log item (text and user image)
            [ctrl.activityLogs() ? ctrl.activityLogs().map(function(item) {
                var image = m('i.fa.fa-desktop');
                if (ctrl.node.anonymous) item.anonymous = true;
                if (!ctrl.node.anonymous && item.embeds.user && item.embeds.user.data) {
                    image = m('img', { src : item.embeds.user.data.links.profile_image});
                } else if (!ctrl.node.anonymous && item.embeds.user && item.embeds.user.errors[0].meta){
                    image = m('img', { src : item.embeds.user.errors[0].meta.profile_image});
                }
                return m('.db-activity-item', [
                    m('', [m('.db-log-avatar.m-r-xs', image), m.component(LogText.LogText, item)]),
                    m('.text-right', m('span.text-muted.m-r-xs', item.attributes.formattableDate.local))
                ]);
            }) : '',
            // Log pagination
            m('.db-activity-nav.text-center', [
                ctrl.paginators() && !ctrl.limitLogs ? ctrl.paginators().map(function(page) {
                    return page.url() ? m('.btn.btn-sm.btn-link', { onclick : function() {
                        ctrl.getLogs(page.url());
                    }}, page.text) : m('.btn.btn-sm.btn-link.disabled', {style: 'color: black'}, page.text);
                }) : ''
            ])]
        ]);
    }
};

module.exports = {
    LogFeed: LogFeed
};
<commit_msg>Can still link projects, in case logs fail<commit_after>'use strict';

require('css/log-feed.css');
var m = require('mithril'); // exposes mithril methods, useful for redraw etc.
var $ = require('jquery');
var $osf = require('js/osfHelpers');
var mHelpers = require('js/mithrilHelpers');
var Raven = require('raven-js');
var LogText = require('js/logTextParser');

var MAX_PAGES_ON_PAGINATOR = 7;
var MAX_PAGES_ON_PAGINATOR_SIDE = 5;
var LOG_PAGE_SIZE_LIMITED = 3;
var LOG_PAGE_SIZE = 6;
var PROFILE_IMAGE_SIZE = 16;

var _buildLogUrl = function(node, page, limitLogs) {
    var logPage = page || 1;
    var urlPrefix = (node.isRegistration || node.is_registration) ? 'registrations' : 'nodes';
    var size = limitLogs ? LOG_PAGE_SIZE_LIMITED : LOG_PAGE_SIZE;
    var query = { 'page[size]': size, 'page': logPage, 'embed': ['original_node', 'user', 'linked_node', 'template_node'], 'profile_image_size': PROFILE_IMAGE_SIZE};
    var viewOnly = $osf.urlParams().view_only;
    if (viewOnly) {
        query.view_only = viewOnly;
    }
    return $osf.apiV2Url(urlPrefix + '/' + node.id + '/logs/', { query: query});
};

var LogFeed = {

    controller: function(options) {
        var self = this;
        self.node = options.node;
        self.activityLogs = m.prop([]);
        self.logRequestPending = m.prop(false);
        self.limitLogs = options.limitLogs;
        self.failed = false;
        self.paginators = m.prop([]);
        self.nextPage = m.prop('');
        self.prevPage = m.prop('');
        self.totalPages = m.prop(0);
        self.currentPage = m.prop(0);
        self.pageToGet = m.prop(0);

        self.getLogs = function _getLogs (url) {
            self.activityLogs([]); // Empty logs from other projects while load is happening;
            function _processResults (result){
                result.data.map(function(log){
                    log.attributes.formattableDate = new $osf.FormattableDate(log.attributes.date);
                });

                self.activityLogs(result.data);  // Set activity log data
                self.nextPage(result.links.next);
                self.prevPage(result.links.prev);

                var params = $osf.urlParams(url);
                var page = params.page || 1;
                self.currentPage(parseInt(page));
                self.totalPages(Math.ceil(result.links.meta.total / result.links.meta.per_page));
                $('#linkProjects').toggleClass('disabled');
            }
            self.logRequestPending(true);
            var promise = m.request({method : 'GET', url : url, config: mHelpers.apiV2Config({withCredentials: window.contextVars.isOnRootDomain})});
            promise.then(
                function(result) {
                    _processResults(result);
                    self.logRequestPending(false);
                    return promise;
                }, function(xhr, textStatus, error) {
                    self.failed = true;
                    $('#linkProjects').toggleClass('disabled');
                    self.logRequestPending(false);
                    Raven.captureMessage('Error retrieving logs', {extra: {url: url, textStatus: textStatus, error: error}});
                }
            );
        };

        self.getCurrentLogs = function _getCurrentLogs (node, page){
            if(!self.logRequestPending()) {
                var url = _buildLogUrl(node, page, self.limitLogs);
                return self.getLogs(url);
            }
        };
        self.getCurrentLogs(self.node);
    },

    view : function (ctrl) {

        var i;
        ctrl.paginators([]);
        if (ctrl.totalPages() > 1 && !ctrl.limitLogs) {
            // previous page
            ctrl.paginators().push({
                url: function() { return ctrl.prevPage(); },
                text: '<'
            });
            // first page
            ctrl.paginators().push({
                text: 1,
                url: function() {
                    ctrl.pageToGet(1);
                    if(ctrl.pageToGet() !== ctrl.currentPage()) {
                        return _buildLogUrl(ctrl.node, ctrl.pageToGet());
                    }
                }
            });
            // no ellipses
            if (ctrl.totalPages() <= MAX_PAGES_ON_PAGINATOR) {
                for (i = 2; i < ctrl.totalPages(); i++) {
                    ctrl.paginators().push({
                        text: i,
                        url: function() {
                            ctrl.pageToGet(parseInt(this.text));
                            if (ctrl.pageToGet() !== ctrl.currentPage()) {
                                return _buildLogUrl(ctrl.node, ctrl.pageToGet());
                            }
                        }
                    });/* jshint ignore:line */
                    // function defined inside loop
                }
            }
            // one ellipse at the end
            else if (ctrl.currentPage() < MAX_PAGES_ON_PAGINATOR_SIDE - 1) {
                for (i = 2; i < MAX_PAGES_ON_PAGINATOR_SIDE; i++) {
                    ctrl.paginators().push({
                        text: i,
                        url: function() {
                            ctrl.pageToGet(parseInt(this.text));
                            if (ctrl.pageToGet() !== ctrl.currentPage()) {
                                return _buildLogUrl(ctrl.node, ctrl.pageToGet());
                            }
                        }
                    });/* jshint ignore:line */
                    // function defined inside loop
                }
                ctrl.paginators().push({
                    text: '...',
                    url: function() { }
                });
            }
            // one ellipse at the beginning
            else if (ctrl.currentPage() > ctrl.totalPages() - MAX_PAGES_ON_PAGINATOR_SIDE + 2) {
                ctrl.paginators().push({
                    text: '...',
                    url: function() { }
                });
                for (i = ctrl.totalPages() - MAX_PAGES_ON_PAGINATOR_SIDE + 2; i <= ctrl.totalPages() - 1; i++) {
                    ctrl.paginators().push({
                        text: i,
                        url: function() {
                            ctrl.pageToGet(parseInt(this.text));
                            if (ctrl.pageToGet() !== ctrl.currentPage()) {
                                return _buildLogUrl(ctrl.node, ctrl.pageToGet());
                            }
                        }
                    });/* jshint ignore:line */
                    // function defined inside loop
                }
            }
            // two ellipses
            else {
                ctrl.paginators().push({
                    text: '...',
                    url: function() { }
                });
                for (i = parseInt(ctrl.currentPage()) - 1; i <= parseInt(ctrl.currentPage()) + 1; i++) {
                    ctrl.paginators().push({
                        text: i,
                        url: function() {
                            ctrl.pageToGet(parseInt(this.text));
                            if (ctrl.pageToGet() !== ctrl.currentPage()) {
                                return _buildLogUrl(ctrl.node, ctrl.pageToGet());
                            }
                        }
                    });/* jshint ignore:line */
                    // function defined inside loop
                }
                ctrl.paginators().push({
                    text: '...',
                    url: function() { }
                });
            }
            // last page
            ctrl.paginators().push({
                text: ctrl.totalPages(),
                url: function() {
                    ctrl.pageToGet(ctrl.totalPages());
                    if (ctrl.pageToGet() !== ctrl.currentPage()) {
                        return _buildLogUrl(ctrl.node, ctrl.pageToGet());
                    }
                }
            });
            // next page
            ctrl.paginators().push({
                url: function() { return ctrl.nextPage(); },
                text: '>'
            });
        }

        return m('.db-activity-list.m-t-md', [
            // Error message if the log request fails
            ctrl.failed ? m('p', [
                'Unable to retrieve logs at this time. Please refresh the page or contact ',
                m('a', {'href': 'mailto:support@osf.io'}, 'support@osf.io'),
                ' if the problem persists.'
            ]) :
            // Show OSF spinner while there is a pending log request
            ctrl.logRequestPending() ?  m('.spinner-loading-wrapper', [
                m('.logo-spin.logo-lg'),
                m('p.m-t-sm.fg-load-message', 'Loading logs...')
            ]) :
            // Display each log item (text and user image)
            [ctrl.activityLogs() ? ctrl.activityLogs().map(function(item) {
                var image = m('i.fa.fa-desktop');
                if (ctrl.node.anonymous) item.anonymous = true;
                if (!ctrl.node.anonymous && item.embeds.user && item.embeds.user.data) {
                    image = m('img', { src : item.embeds.user.data.links.profile_image});
                } else if (!ctrl.node.anonymous && item.embeds.user && item.embeds.user.errors[0].meta){
                    image = m('img', { src : item.embeds.user.errors[0].meta.profile_image});
                }
                return m('.db-activity-item', [
                    m('', [m('.db-log-avatar.m-r-xs', image), m.component(LogText.LogText, item)]),
                    m('.text-right', m('span.text-muted.m-r-xs', item.attributes.formattableDate.local))
                ]);
            }) : '',
            // Log pagination
            m('.db-activity-nav.text-center', [
                ctrl.paginators() && !ctrl.limitLogs ? ctrl.paginators().map(function(page) {
                    return page.url() ? m('.btn.btn-sm.btn-link', { onclick : function() {
                        ctrl.getLogs(page.url());
                    }}, page.text) : m('.btn.btn-sm.btn-link.disabled', {style: 'color: black'}, page.text);
                }) : ''
            ])]
        ]);
    }
};

module.exports = {
    LogFeed: LogFeed
};
<|endoftext|>


<commit_before>/*global describe, it, expect, example, before, after, beforeEach, afterEach, mocha, sinon*/
'use strict';

var assert = require('chai').assert;
var $ = require('jquery');
var m = require('mithril');
var URI = require('URIjs');
var Treebeard = require('treebeard');
var Fangorn = require('js/fangorn');

// Add sinon asserts to chai.assert, so we can do assert.calledWith instead of sinon.assert.calledWith
sinon.assert.expose(assert, {prefix: ''});

var smallSample = [ {kind : 'folder', name : 'test folder'}, { kind : 'file', name : 'test file'}];

describe('fangornToolbars', () => {
// Tests related to the toolbar
	describe('toolbarOptions', () => {
	// header template is defined

	});

});
<commit_msg>Add initial tests to fangorn.test [skip ci]<commit_after>/*global describe, it, expect, example, before, after, beforeEach, afterEach, mocha, sinon*/
'use strict';

var assert = require('chai').assert;
var $ = require('jquery');
var m = require('mithril');
var URI = require('URIjs');
var Treebeard = require('treebeard');
var Fangorn = require('js/fangorn');

// Add sinon asserts to chai.assert, so we can do assert.calledWith instead of sinon.assert.calledWith
sinon.assert.expose(assert, {prefix: ''});

var smallSample = [ {kind : 'folder', name : 'test folder'}, { kind : 'file', name : 'test file'}];

var fangornInstance = function() {
    var fan =  new Fangorn({
        divID: 'fangorn',
        filesData: smallSample
    });
    return fan.grid.tbController;
};

describe('fangornToolbars', () => {
// Tests related to the toolbar
	describe('toolbarOptions', () => {
	  var fangorn;
	  beforeEach(function() {
	    // runs before all tests in this block
	    $('body').append('

');
	    fangorn = fangornInstance();
	  });
	  afterEach(function(){
	    // runs after all tests in this block
	    $('#fangorn').remove();
	  });

	  it('Should have fangorn toolbar template', function() {
	  	assert.ok(fangorn.options.headerTemplate);
	  });
	  it('fangorn toolbar template should returns an object', function() {
	  	var template = fangorn.options.headerTemplate.call(fangorn);
	  	assert.equal(typeof template, 'object');
	  });

	});

});
  <|endoftext|>


<commit_before>angular.module('ngPrettyJson', [])
    .directive('prettyJson', ['ngPrettyJsonFunctions', function (ngPrettyJsonFunctions) {
        'use strict';

        var isDefined = angular.isDefined;

        return {
            restrict: 'AE',
            scope: {
                json: '=',
                prettyJson: '=',
                onEdit: '&'
            },
            replace: true,
            template: '
' +
                        '<button ng-click="edit()" ng-show="edition && !editActivated">Edit</button>' +
                        '<button ng-click="edit()" ng-show="edition && editActivated">Cancel</button>' +
                        '<button ng-click="update()" ng-show="editActivated && parsable">Update</button>' +
                        '

' +
                    '
',
            link: function (scope, elm, attrs) {
                var currentValue = {}, id = 'prettyjson', editor = null;

                scope.editActivated = false;
                scope.edition = attrs.edition;
                scope.aceEditor = window.ace !== undefined;

                // prefer the "json" attribute over the "prettyJson" one.
                // the value on the scope might not be defined yet, so look at the markup.
                var exp = isDefined(attrs.json) ? 'json' : 'prettyJson',
                    highlight = function highlight(value) {
                        var html = ngPrettyJsonFunctions.syntaxHighlight(value) || "";
                        html = html
                            .replace(/\{/g, "{")
                            .replace(/\}/g, "}")
                            .replace(/\[/g, "[")
                            .replace(/\]/g, "]")
                            .replace(/\,/g, ",");
                        return isDefined(value) ? elm.find('pre').html(html) : elm.empty();
                    },
                    objWatch;

                objWatch = scope.$watch(exp, function (newValue) {
                    // BACKWARDS COMPATIBILITY:
                    // if newValue is an object, and we find a `json` property,
                    // then stop watching on `exp`.
                    if (angular.isObject(newValue) && isDefined(newValue.json)) {
                        objWatch();
                        scope.$watch(exp + '.json', function (newValue) {
                            highlight(newValue);
                            currentValue = newValue;
                        }, true);
                    }
                    else {
                        highlight(newValue);
                        currentValue = newValue;
                    }
                }, true);

                var editChanges = function(e) {
                    try {
                        currentValue = JSON.parse(editor.getValue());
                        scope.parsable = true;
                    }
                    catch (error) {scope.parsable = false;}

                    // trigger update
                    scope.$apply(function () {});
                };

                scope.edit = function() {
                    if (!scope.aceEditor) {
                        if (console)
                            console.log('\'ace lib is missing\'');
                        return;
                    }

                    if (!scope.editActivated) {
                        editor = ace.edit(id);
                        editor.setOptions({maxLines: Infinity});
                        editor.on('change', editChanges);
                        editor.getSession().setMode("ace/mode/json");
                    }
                    else {
                        if (editor) { document.getElementById(id).env = null; }
                        highlight(currentValue);
                    }
                    scope.editActivated = !scope.editActivated;
                };

                scope.update = function() {
                    scope.$emit('json-updated', currentValue);
                    if (scope.onEdit)
                        scope.onEdit({newJson: currentValue});
                    this.edit();
                };
            }
        };
    }])

    // mostly we want to just expose this stuff for unit testing; if it's within the directive's
    // function scope, we can't get to it.
    .factory('ngPrettyJsonFunctions', function ngPrettyJsonFunctions() {

        // cache some regular expressions
        var rx = {
            entities: /((&)|(<)|(>))/g,
            json: /"(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|(null))\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g
        };

        // mapping of chars to entities
        var entities = [
            '&',
            '<',
            '>'
        ];

        // lookup of positional regex matches in rx.json to CSS classes
        var classes = [
            'number',
            'string',
            'key',
            'boolean',
            'null'
        ];

        /**
         * @description Used by {@link makeEntities} and {@link markup}.  Expects all arguments
         * to be nonempty strings.
         * @private
         * @returns {number} Index of last nonempty string argument in list of arguments.
         */
        var reverseCoalesce = function reverseCoalesce() {
            var i = arguments.length - 2;
            do {
                i--;
            } while (!arguments[i]);
            return i;
        };

        /**
         * @description Callback to String.prototype.replace(); marks up JSON string
         * @param {string|number} match Any one of the below, or if none of the below, it's a number
         * @returns {string} Marked-up JSON string
         */
        var markup = function markup(match) {
            var idx;
            // the final two arguments are the length, and the entire string itself;
            // we don't care about those.
            if (arguments.length < 7) {
                throw new Error('markup() must be called from String.prototype.replace()');
            }
            idx = reverseCoalesce.apply(null, arguments);
            return '' + match + '';
        };

        /**
         * @description Finds chars in string to turn into entities for HTML output.
         * @returns {string} Entity-ized string
         */
        var makeEntities = function makeEntities() {
            var idx;
            if (arguments.length < 5) {
                throw new Error('makeEntities() must be called from String.prototype.replace()');
            }
            idx = reverseCoalesce.apply(null, arguments);
            return entities[idx - 2];
        };

        /**
         * @description Does some regex matching to sanitize for HTML and finally returns a bunch of
         * syntax-highlighted markup.
         * @param {*} json Something to be output as pretty-printed JSON
         * @returns {string|undefined} If we could convert to JSON, you get markup as a string, otherwise
         * no return value for you.
         */
        var syntaxHighlight = function syntaxHighlight(json) {
            if (!angular.isString(json))
                json = JSON.stringify(json, null, 2);
            if (angular.isDefined(json)) {
                return json.replace(rx.entities, makeEntities)
                    .replace(rx.json, markup);
            }
        };

        return {
            syntaxHighlight: syntaxHighlight,
            makeEntities: makeEntities,
            markup: markup,
            rx: rx
        };
    });<commit_msg>resolved console error<commit_after>angular.module('ngPrettyJson', [])
    .directive('prettyJson', ['ngPrettyJsonFunctions', function (ngPrettyJsonFunctions) {
        'use strict';

        var isDefined = angular.isDefined;

        return {
            restrict: 'AE',
            scope: {
                json: '=',
                prettyJson: '=',
                onEdit: '&'
            },
            replace: true,
            template: '
' +
                        '<button ng-click="edit()" ng-show="edition && !editActivated">Edit</button>' +
                        '<button ng-click="edit()" ng-show="edition && editActivated">Cancel</button>' +
                        '<button ng-click="update()" ng-show="editActivated && parsable">Update</button>' +
                        '

' +
                    '
',
            link: function (scope, elm, attrs) {
                var currentValue = {}, id = 'prettyjson', editor = null;

                scope.editActivated = false;
                scope.edition = attrs.edition;
                scope.aceEditor = window.ace !== undefined;

                // prefer the "json" attribute over the "prettyJson" one.
                // the value on the scope might not be defined yet, so look at the markup.
                var exp = isDefined(attrs.json) ? 'json' : 'prettyJson',
                    highlight = function highlight(value) {
                        var html = ngPrettyJsonFunctions.syntaxHighlight(value) || "";
                        html = html
                            .replace(/\{/g, "{")
                            .replace(/\}/g, "}")
                            .replace(/\[/g, "[")
                            .replace(/\]/g, "]")
                            .replace(/\,/g, ",");
                        return isDefined(value) ? elm.find('pre').html(html) : elm = '';
                    },
                    objWatch;

                objWatch = scope.$watch(exp, function (newValue) {
                    // BACKWARDS COMPATIBILITY:
                    // if newValue is an object, and we find a `json` property,
                    // then stop watching on `exp`.
                    if (angular.isObject(newValue) && isDefined(newValue.json)) {
                        objWatch();
                        scope.$watch(exp + '.json', function (newValue) {
                            highlight(newValue);
                            currentValue = newValue;
                        }, true);
                    }
                    else {
                        highlight(newValue);
                        currentValue = newValue;
                    }
                }, true);

                var editChanges = function(e) {
                    try {
                        currentValue = JSON.parse(editor.getValue());
                        scope.parsable = true;
                    }
                    catch (error) {scope.parsable = false;}

                    // trigger update
                    scope.$apply(function () {});
                };

                scope.edit = function() {
                    if (!scope.aceEditor) {
                        if (console)
                            console.log('\'ace lib is missing\'');
                        return;
                    }

                    if (!scope.editActivated) {
                        editor = ace.edit(id);
                        editor.setOptions({maxLines: Infinity});
                        editor.on('change', editChanges);
                        editor.getSession().setMode("ace/mode/json");
                    }
                    else {
                        if (editor) { document.getElementById(id).env = null; }
                        highlight(currentValue);
                    }
                    scope.editActivated = !scope.editActivated;
                };

                scope.update = function() {
                    scope.$emit('json-updated', currentValue);
                    if (scope.onEdit)
                        scope.onEdit({newJson: currentValue});
                    this.edit();
                };
            }
        };
    }])

    // mostly we want to just expose this stuff for unit testing; if it's within the directive's
    // function scope, we can't get to it.
    .factory('ngPrettyJsonFunctions', function ngPrettyJsonFunctions() {

        // cache some regular expressions
        var rx = {
            entities: /((&)|(<)|(>))/g,
            json: /"(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|(null))\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g
        };

        // mapping of chars to entities
        var entities = [
            '&',
            '<',
            '>'
        ];

        // lookup of positional regex matches in rx.json to CSS classes
        var classes = [
            'number',
            'string',
            'key',
            'boolean',
            'null'
        ];

        /**
         * @description Used by {@link makeEntities} and {@link markup}.  Expects all arguments
         * to be nonempty strings.
         * @private
         * @returns {number} Index of last nonempty string argument in list of arguments.
         */
        var reverseCoalesce = function reverseCoalesce() {
            var i = arguments.length - 2;
            do {
                i--;
            } while (!arguments[i]);
            return i;
        };

        /**
         * @description Callback to String.prototype.replace(); marks up JSON string
         * @param {string|number} match Any one of the below, or if none of the below, it's a number
         * @returns {string} Marked-up JSON string
         */
        var markup = function markup(match) {
            var idx;
            // the final two arguments are the length, and the entire string itself;
            // we don't care about those.
            if (arguments.length < 7) {
                throw new Error('markup() must be called from String.prototype.replace()');
            }
            idx = reverseCoalesce.apply(null, arguments);
            return '' + match + '';
        };

        /**
         * @description Finds chars in string to turn into entities for HTML output.
         * @returns {string} Entity-ized string
         */
        var makeEntities = function makeEntities() {
            var idx;
            if (arguments.length < 5) {
                throw new Error('makeEntities() must be called from String.prototype.replace()');
            }
            idx = reverseCoalesce.apply(null, arguments);
            return entities[idx - 2];
        };

        /**
         * @description Does some regex matching to sanitize for HTML and finally returns a bunch of
         * syntax-highlighted markup.
         * @param {*} json Something to be output as pretty-printed JSON
         * @returns {string|undefined} If we could convert to JSON, you get markup as a string, otherwise
         * no return value for you.
         */
        var syntaxHighlight = function syntaxHighlight(json) {
            if (!angular.isString(json))
                json = JSON.stringify(json, null, 2);
            if (angular.isDefined(json)) {
                return json.replace(rx.entities, makeEntities)
                    .replace(rx.json, markup);
            }
        };

        return {
            syntaxHighlight: syntaxHighlight,
            makeEntities: makeEntities,
            markup: markup,
            rx: rx
        };
    });<|endoftext|>


<commit_before>var express = require('express');
var bodyParser = require('body-parser');
var cors = require('cors');

var configuration = require('./lib/configuration');
var bootstrap = require('./lib/bootstrap');

module.exports.create = function(callback) {
    var app = express();

    app.use(cors());
    app.use(bodyParser.json());

    bootstrap.bootstrap(app, configuration, function(error) {
        if (error) return callback(error);

        callback(null, app);
    });
};<commit_msg>boyscout<commit_after>var express = require('express');
var bodyParser = require('body-parser');
var cors = require('cors');

var configuration = require('./lib/configuration');
var bootstrap = require('./lib/bootstrap');

function createApp(callback) {
    var app = express();

    app.use(cors());
    app.use(bodyParser.json());

    bootstrap.bootstrap(app, configuration, function(error) {
        if (error) return callback(error);

        callback(null, app);
    });
}

module.exports = createApp;<|endoftext|>


<commit_before>/**
 * File: vni-manager.js
 */
var _ = require('underscore');

var inputStates = require('./input-states');

var DEFAULT_VNID = '';

/**
 * Manage the node's vni's by vnid.  If no vnid is provided the IIP VNID will be used.
 * If the vni for the specified vnid does not exist, a new one will be created.
 *
 * @this node unless otherwise specified on an API
 * @param componentFacade a component facade
 *
 * @return the component facade, extended to include the vni interface
 *
 * Usage examples:
 *     var vni = node.vni(); // retrieve the default VNI
 *     var vni = node.vni(vnid); // retrieve the vni associated with the vnid
 *
 *     node.deleteAllVnis();
 *     node.deleteVni( vnid );
 *     node.vni(vnid).delete();
 *
 *     node.vni().errorState( state );
 *     var state = node.vni().errorState();
 *
 *     node.vni().inputStates( {input: state} );
 *     var inputStates = node.vni().inputStates();
 *
 *     node.vni().outputState( state );
 *     var state = node.vni().outputState();
 */
module.exports = function( componentFacade ) {

    _.extend( componentFacade,
        {

          /**
           * Delete all vnis assiciated with the node instance.
           *
           * @this node instance
           * @return node instance node for easy chaining
           */
          deleteAllVnis: function() {
              // reassign vnis array to an empty array and let garbage collection clean up
              this.vnis = {};
              return this;
          },

          /**
           * Delete the vni associated with the specified VNID
           *
           * @param vnid vnid identifying which vni to delete
           *
           * @this node instance
           * @return node instance node for easy chaining
           */
          deleteVni: function( vnid ) {

              if ( vnid in this.vnis ) {
                  delete this.vnis[vnid];
              }

              return this;
          },

          /**
           * Getter for a vni facade specified by the vnid parameter.  If no VNID is specified,
           * the IIP VNID will be used.  If the VNI does not yet exist, a new VNI will be
           * created.
           *
           * @this node
           * @param vnid vnid identifying which vni to delete
           *
           * @return node for easy chaining
           */
          vni: function( vnid ) {

              vnid = vnid || DEFAULT_VNID;

              if ( _.isUndefined( this.vnis[vnid] )  ) {

                  // have no vni so create one
                  this.vnis[vnid] = {};

                  // TODO: Add parentVni setting here
                  // TODO: Add previousLms here
              }

              return {
                  delete: _.bind( this.deleteVni, this, vnid ),
                  inputStates: _.partial( inputStates, this, vnid ),
                  errorState: _.partial( errorState, this.vnis[vnid] ),
                  outputState: _.partial( outputState, this.vnis[vnid] )
              };
          },

          vnis: {}

    }); // extend
} // module export

/**
 * Get/Set error state on the vni
 *
 * @this vni context
 *
 * @param vni vni whose state should be set or retrieved
 * @param state error state to be set
 *
 * @return the requested state or the current VNI context
 */
function errorState( vni, state ) {

    // Do we have a state to be set ?
    if ( arguments.length > 1 ) {

        if ( _.isUndefined(state) ) {
            // Clear state
            delete vni.errorState;
        } else {
            // Set state
            vni.errorState = state;
        }

        return this;
    }

    // Get the state
    return vni.errorState;
}

/**
 * Get/Set output state on the vni
 *
 * @this vni context
 *
 * @param vni vni whose state should be set or retrieved
 * @param state output state to be set
 *
 * @return the requested state or the current VNI context
 */
function outputState( vni, state ) {

    // Do we have a state to be set ?
    if ( arguments.length > 1 ) {
        if ( _.isUndefined(state) ) {
            // Clear state
            delete vni.outputState;
        } else {
            // Set state
            vni.outputState = state;
        }

        return this;
    }

    // Get the state
    return vni.outputState;
}
<commit_msg>PreviousLms will be in states, not VNI -> removed TODO about it.<commit_after>/**
 * File: vni-manager.js
 */
var _ = require('underscore');

var inputStates = require('./input-states');

var DEFAULT_VNID = '';

/**
 * Manage the node's vni's by vnid.  If no vnid is provided the IIP VNID will be used.
 * If the vni for the specified vnid does not exist, a new one will be created.
 *
 * @this node unless otherwise specified on an API
 * @param componentFacade a component facade
 *
 * @return the component facade, extended to include the vni interface
 *
 * Usage examples:
 *     var vni = node.vni(); // retrieve the default VNI
 *     var vni = node.vni(vnid); // retrieve the vni associated with the vnid
 *
 *     node.deleteAllVnis();
 *     node.deleteVni( vnid );
 *     node.vni(vnid).delete();
 *
 *     node.vni().errorState( state );
 *     var state = node.vni().errorState();
 *
 *     node.vni().inputStates( {input: state} );
 *     var inputStates = node.vni().inputStates();
 *
 *     node.vni().outputState( state );
 *     var state = node.vni().outputState();
 */
module.exports = function( componentFacade ) {

    _.extend( componentFacade,
        {

          /**
           * Delete all vnis assiciated with the node instance.
           *
           * @this node instance
           * @return node instance node for easy chaining
           */
          deleteAllVnis: function() {
              // reassign vnis array to an empty array and let garbage collection clean up
              this.vnis = {};
              return this;
          },

          /**
           * Delete the vni associated with the specified VNID
           *
           * @param vnid vnid identifying which vni to delete
           *
           * @this node instance
           * @return node instance node for easy chaining
           */
          deleteVni: function( vnid ) {

              if ( vnid in this.vnis ) {
                  delete this.vnis[vnid];
              }

              return this;
          },

          /**
           * Getter for a vni facade specified by the vnid parameter.  If no VNID is specified,
           * the IIP VNID will be used.  If the VNI does not yet exist, a new VNI will be
           * created.
           *
           * @this node
           * @param vnid vnid identifying which vni to delete
           *
           * @return node for easy chaining
           */
          vni: function( vnid ) {

              vnid = vnid || DEFAULT_VNID;

              if ( _.isUndefined( this.vnis[vnid] )  ) {

                  // have no vni so create one
                  this.vnis[vnid] = {};

                  // TODO: Add parentVni setting here
              }

              return {
                  delete: _.bind( this.deleteVni, this, vnid ),
                  inputStates: _.partial( inputStates, this, vnid ),
                  errorState: _.partial( errorState, this.vnis[vnid] ),
                  outputState: _.partial( outputState, this.vnis[vnid] )
              };
          },

          vnis: {}

    }); // extend
} // module export

/**
 * Get/Set error state on the vni
 *
 * @this vni context
 *
 * @param vni vni whose state should be set or retrieved
 * @param state error state to be set
 *
 * @return the requested state or the current VNI context
 */
function errorState( vni, state ) {

    // Do we have a state to be set ?
    if ( arguments.length > 1 ) {

        if ( _.isUndefined(state) ) {
            // Clear state
            delete vni.errorState;
        } else {
            // Set state
            vni.errorState = state;
        }

        return this;
    }

    // Get the state
    return vni.errorState;
}

/**
 * Get/Set output state on the vni
 *
 * @this vni context
 *
 * @param vni vni whose state should be set or retrieved
 * @param state output state to be set
 *
 * @return the requested state or the current VNI context
 */
function outputState( vni, state ) {

    // Do we have a state to be set ?
    if ( arguments.length > 1 ) {
        if ( _.isUndefined(state) ) {
            // Clear state
            delete vni.outputState;
        } else {
            // Set state
            vni.outputState = state;
        }

        return this;
    }

    // Get the state
    return vni.outputState;
}
<|endoftext|>


<commit_before>const sh = require('shelljs'),
      path = require('path'),
      fs = require('fs-extra'),
      basePackagePath = path.resolve(__dirname, '..'),
      fixturePath = path.resolve(__dirname, 'fixtures'),
      resultFixturePath = path.resolve(__dirname, 'fixtures', 'result'),
      readJSON = fs.readJSONSync;

let prepareInput,
    identInputForTest,
    clearInputForTest,
    runApp;
/**
 * Идентификация входных данных
 * на основе кейса определяет имена json файлов с тестовыми данными
 * @param {string} testCase - кейс использования:
 * (equal|oneMoreError|oneMoreNewError|empty)
 * @typedef {Object} testDataJSONNames имена обозначающие JSON с тестовыми
 * данными
 * @property {String} masterInputName - мастер ветку
 * @property {String} currentInputName - текущую ветку
 * @return {testDataJSONNames}
 */
identInputForTest = (testCase) => {
  let current,
      master,
      error = 'error';

  switch (testCase) {
    case 'equal':
      master = error;
      current = error;
      break;
    case 'oneMoreErrorFile':
      master = error;
      current = testCase;
      break;
    case 'onesLessErrorFile':
      master = identInputForTest('oneMoreErrorFile').masterInputName;
      current = error;
      break;
    case 'oneMoreErrorInExistErrorFile':
      master = error;
      current = testCase;
      break;
    case 'onesLessErrorInExistErrorFile':
      master = identInputForTest('oneMoreErrorInExistErrorFile').masterInputName;
      current = testCase;
      break;
    case 'empty':
      master = testCase;
      current = testCase;
      break;
    default:
      break;
  }
  return {
    masterInputName: master,
    currentInputName: current
  };
};

/**
 * функия копирует входные json в корень
 * @param {string} testCase - кейс использования:
 * (equal|oneMoreError|oneMoreNewError|empty)
 */
prepareInput = (testCase) => {
  const testDataPath = identInputForTest(testCase);

  sh.cp(`${fixturePath}/${testDataPath.masterInputName}.json`, `${basePackagePath}/fromMaster.json`);
  sh.cp(`${fixturePath}/${testDataPath.currentInputName}.json`,
    `${basePackagePath}/fromCurrent.json`);
};

/**
 * Запуск приложения
 */
runApp = () => {
  sh.exec(`cd ${basePackagePath}; node index.js
       -master ${__dirname}/fromMaster.json
       -merge ${__dirname}/fromCurrent.json`);
};

/**
 * Очистить входные данные после теста
 */
clearInputForTest = () => {
  sh.rm(`${basePackagePath}/fromCurrent.json`);
  sh.rm(`${basePackagePath}/fromMaster.json`);
};

describe('Смок тест модуля работы с eslint', () => {
  describe('исключающий мерж', () => {
    beforeAll(() => {
      sh.chmod('+x', `${basePackagePath}/index.js`);
    });

    afterAll(() => {
      clearInputForTest();
    });

    it('создан результирующий файл', () => {
      runApp();

      expect(sh.test('-f', `${basePackagePath}/result.json`)).toBeTruthy();
    });

    describe('файлы идентичны', function () {
      let resultJSON,
          expectedJSON;

      afterEach(() => {
        resultJSON = undefined;
      });

      it('пусты', function () {
        prepareInput('empty');
        runApp();
        expectedJSON = readJSON(`${resultFixturePath}/empty.json`);
        resultJSON = readJSON(`${basePackagePath}/result.json`);
        expect(resultJSON).toEqual(0);
      });

      it('одинаковы', function () {
        prepareInput('equal');
        runApp();

        resultJSON = readJSON(`${basePackagePath}/result.json`);
        expect(resultJSON.length).toEqual(0);
      });

      describe('не одинаковы', function () {
        it('новый файл с ошибками', () => {
          prepareInput('oneMoreErrorFile');
          runApp();

          resultJSON = readJSON(`${basePackagePath}/result.json`);
        });

        it('новые ошибки в файле, в котором уже были ошибки', () => {
          prepareInput('oneMoreErrorInExistErrorFile');
          runApp();

          resultJSON = readJSON(`${basePackagePath}/result.json`);
        });

        it('уменьшение количества ошибок', () => {
          prepareInput('onesLessErrorInExistErrorFile');
          runApp();

          resultJSON = readJSON(`${basePackagePath}/result.json`);
        });

        it('уменьшение количества файлов с ошибками', () => {
          prepareInput('onesLessErrorFile');
          runApp();

          resultJSON = readJSON(`${basePackagePath}/result.json`);
        });
      });
    });
  });
});
<commit_msg>test(*): тесты для модуля получения уникальных ошибок eslint<commit_after>const sh = require('shelljs'),
      path = require('path'),
      fs = require('fs-extra'),
      basePackagePath = path.resolve(__dirname, '..'),
      fixturePath = path.resolve(__dirname, 'fixtures'),
      resultFixturePath = path.resolve(__dirname, 'fixtures', 'result'),
      readJSON = fs.readJSONSync;

let prepareInput,
    identInputForTest,
    clearInputForTest,
    runApp;
/**
 * Идентификация входных данных
 * на основе кейса определяет имена json файлов с тестовыми данными
 * @param {string} testCase - кейс использования:
 * (equal|oneMoreError|oneMoreNewError|empty)
 * @typedef {Object} testDataJSONNames имена обозначающие JSON с тестовыми
 * данными
 * @property {String} masterInputName - мастер ветку
 * @property {String} currentInputName - текущую ветку
 * @return {testDataJSONNames}
 */
identInputForTest = (testCase) => {
  let current,
      master,
      error = 'error';

  switch (testCase) {
    case 'equal':
      master = error;
      current = error;
      break;
    case 'newErrorsAndFiles':
      master = error;
      current = testCase;
      break;
    case 'onesLessErrorFile':
      master = identInputForTest('oneMoreErrorFile').masterInputName;
      current = error;
      break;
    case 'oneMoreErrorInExistErrorFile':
      master = error;
      current = testCase;
      break;
    case 'onesLessErrorInExistErrorFile':
      master = identInputForTest('oneMoreErrorInExistErrorFile').masterInputName;
      current = testCase;
      break;
    case 'empty':
      master = testCase;
      current = testCase;
      break;
    default:
      break;
  }

  console.log({
    masterInputName: master,
    currentInputName: current
  });

  return {
    masterInputName: master,
    currentInputName: current
  };
};

/**
 * функия копирует входные json в корень
 * @param {string} testCase - кейс использования:
 * (equal|oneMoreError|oneMoreNewError|empty)
 */
prepareInput = (testCase) => {
  const testDataPath = identInputForTest(testCase);

  sh.cp(`${fixturePath}/${testDataPath.masterInputName}.json`, `${basePackagePath}/fromMaster.json`);
  sh.cp(`${fixturePath}/${testDataPath.currentInputName}.json`,
    `${basePackagePath}/fromCurrent.json`);
};

/**
 * Запуск приложения
 */
runApp = () => {
  sh.exec(`cd ${basePackagePath}; node index.js -master ${basePackagePath}/fromMaster.json -current ${basePackagePath}/fromCurrent.json`);
  console.log(`cd ${basePackagePath}; node index.js -master ${basePackagePath}/fromMaster.json -current ${basePackagePath}/fromCurrent.json`)
};

/**
 * Очистить входные данные после теста
 */
clearInputForTest = () => {
  sh.rm(`${basePackagePath}/fromCurrent.json`);
  sh.rm(`${basePackagePath}/fromMaster.json`);
  sh.rm(`${basePackagePath}/result.json`);
};

describe('Смок тест модуля работы с eslint', () => {
  describe('исключающий мерж', () => {
    beforeAll(() => {
      sh.chmod('+x', `${basePackagePath}/index.js`);
    });

    afterEach(() => {
      clearInputForTest();
    });

    it('создан результирующий файл', () => {
      prepareInput('empty');
      runApp();

      expect(sh.test('-f', `${basePackagePath}/result.json`)).toBeTruthy();
    });

    describe('файлы идентичны', function () {
      let resultJSON,
          expectedJSON;

      afterEach(() => {
        resultJSON = undefined;
      });

      it('пусты', function () {
        prepareInput('empty');
        runApp();
        expectedJSON = readJSON(`${resultFixturePath}/empty.json`);
        resultJSON = readJSON(`${basePackagePath}/result.json`);
        expect(resultJSON).toEqual([]);
      });

      it('одинаковы', function () {
        let resultFixtureName = 'empty';
        prepareInput('equal');
        runApp();

        resultJSON = readJSON(`${basePackagePath}/result.json`);
        expectedJSON = readJSON(`${resultFixturePath}/${resultFixtureName}.json`);
        expect(resultJSON).toEqual(expectedJSON);
      });

      describe('не одинаковы', function () {
        it('новый файл с ошибками', () => {
          let resultFixtureName = 'newErrorsAndFiles';
          prepareInput(resultFixtureName);
          runApp();
          expectedJSON = readJSON(`${resultFixturePath}/${resultFixtureName}.json`);
          resultJSON = readJSON(`${basePackagePath}/result.json`);

          expect(resultJSON).toEqual(expectedJSON);
        });

        it('новые ошибки в файле, в котором уже были ошибки', () => {
          let resultFixtureName = 'oneMoreErrorInExistErrorFile';
          prepareInput(resultFixtureName);
          runApp();
          expectedJSON = readJSON(`${resultFixturePath}/${resultFixtureName}.json`);
          resultJSON = readJSON(`${basePackagePath}/result.json`);

          expect(resultJSON).toEqual(expectedJSON);
        });

        it('уменьшение количества ошибок', () => {
          let resultFixtureName = 'empty';
          prepareInput('onesLessErrorInExistErrorFile');
          runApp();

          expectedJSON = readJSON(`${resultFixturePath}/onesLessErrorInExistErrorFile.json`);
          resultJSON = readJSON(`${basePackagePath}/result.json`);
        });

        it('уменьшение количества файлов с ошибками', () => {
          let resultFixtureName = 'empty';
          prepareInput('onesLessErrorInExistErrorFile');
          runApp();

          expectedJSON = readJSON(`${resultFixturePath}/onesLessErrorInExistErrorFile.json`);
          resultJSON = readJSON(`${basePackagePath}/result.json`);
        });
      });
    });
  });
});
<|endoftext|>


<commit_before>$(window).load(function(){
	heightFix('.people-col');
    heightFix('.video-column');
});<commit_msg>Updated height fix to account for window resizing<commit_after>$(window).load(function(){
	heightFix('.people-col');
    heightFix('.video-column');
});

$(window).resize(function() {
	heightFix('.people-col');
    heightFix('.video-column');
});<|endoftext|>


<commit_before>/**
 * Step 5
 * Where you write the generator specific files (routes, controllers, etc)
 */

const FILES_MAP = {
  add: ['api/blueprints/add.js', 'test/unit/blueprints/add.test.js'],
  create: ['api/blueprints/create.js', 'test/unit/blueprints/create.test.js'],
  destroy: ['api/blueprints/destroy.js', 'test/unit/blueprints/destroy.test.js'],
  find: ['api/blueprints/find.js', 'test/unit/blueprints/find.test.js'],
  findOne: ['api/blueprints/findone.js', 'test/unit/blueprints/findone.test.js'],
  populate: ['api/blueprints/populate.js', 'test/unit/blueprints/populate.test.js'],
  remove: ['api/blueprints/remove.js', 'test/unit/blueprints/remove.test.js'],
  update: ['api/blueprints/update.js', 'test/unit/blueprints/update.test.js']
};

export default function () {
  if (this.options['use-default']) {
    this.copy('api/blueprints/.gitkeep', 'api/blueprints/.gitkeep');
    this.copy('test/unit/blueprints/.gitkeep', 'test/unit/blueprints/.gitkeep');
  } else {
    Object.keys(FILES_MAP).forEach(blueprint => FILES_MAP[blueprint].forEach(path => this.copy(path, path)));
  }
};
<commit_msg>Implement removing blueprints if you regenerate with --use-default<commit_after>/**
 * Step 5
 * Where you write the generator specific files (routes, controllers, etc)
 */

import fs from 'fs';
import path from 'path';

const GIT_KEEP_FILES = [
  'api/blueprints/.gitkeep',
  'test/unit/blueprints/.gitkeep'
];

const BLUEPRINTS_FILES = {
  add: ['api/blueprints/add.js', 'test/unit/blueprints/add.test.js'],
  create: ['api/blueprints/create.js', 'test/unit/blueprints/create.test.js'],
  destroy: ['api/blueprints/destroy.js', 'test/unit/blueprints/destroy.test.js'],
  find: ['api/blueprints/find.js', 'test/unit/blueprints/find.test.js'],
  findOne: ['api/blueprints/findone.js', 'test/unit/blueprints/findone.test.js'],
  populate: ['api/blueprints/populate.js', 'test/unit/blueprints/populate.test.js'],
  remove: ['api/blueprints/remove.js', 'test/unit/blueprints/remove.test.js'],
  update: ['api/blueprints/update.js', 'test/unit/blueprints/update.test.js']
};

const removeFile = file => fs.existsSync(file) ? fs.unlinkSync(path.resolve(process.cwd(), file)) : false;

export default function () {
  if (this.options['use-default']) {
    GIT_KEEP_FILES.forEach(file => this.copy(file, file));
    Object.keys(BLUEPRINTS_FILES).forEach(blueprint => BLUEPRINTS_FILES[blueprint].forEach(removeFile));
  } else {
    GIT_KEEP_FILES.forEach(removeFile);
    Object.keys(BLUEPRINTS_FILES).forEach(blueprint => BLUEPRINTS_FILES[blueprint].forEach(file => this.copy(file, file)));
  }
};
<|endoftext|>


<commit_before>const utils = require('../lib/utils');

describe('utils', () => {
  it('есть нужные функции', () => {
    expect(typeof utils.mergePathsFromAnyEnv === 'function').toBeTruthy();
  });

  describe('mergePathsFromAnyEnv', () => {
    it('env не задан', () => {
      expect(utils.mergePathsFromAnyEnv).toThrowError('Параметр env не задан');
    });

    it('env задан', function () {
      let path = utils.mergePathsFromAnyEnv('/home/alexey/IdeaProjects/sfa',
        '/opt/teamcity-agent/work/89d8f1306cb75ef7/devTools/js/grunt-config/clean.js', 'teamcity');

      expect(path.replace(/\\/g, '/')).toEqual('/home/alexey/IdeaProjects/sfa/devTools/js/grunt-config/clean.js');
    });

    describe('isVerboseMode', () => {
      it('true', () => {
        process.argv.push('--verbose');

        expect(utils.isVerboseMode()).toBeTruthy();
        process.argv.pop();
      });

      it('false', () => {
        expect(utils.isVerboseMode()).toBeFalsy();
      });
    });

    describe('filerArrayOfObjectsByPropertyValue', () => {
      let exampleArrayOfObjects;
      beforeAll(() => {
        exampleArrayOfObjects = [{a:'a'},{a:'b'},'c'];
      })

      it('success > value', () => {
        expect(utils.filerArrayOfObjectsByPropertyValue(exampleArrayOfObjects,
          'a','a')).toEqual(exampleArrayOfObjects[0]);
      })
      it('fail > undefined', () => {
        expect(utils.filerArrayOfObjectsByPropertyValue(exampleArrayOfObjects,
          'a','d')).toBeUndefined();
      })
    })
  });
});
<commit_msg>style: eslint<commit_after>const utils = require('../lib/utils');

describe('utils', () => {
  it('есть нужные функции', () => {
    expect(typeof utils.mergePathsFromAnyEnv === 'function').toBeTruthy();
  });

  describe('mergePathsFromAnyEnv', () => {
    it('env не задан', () => {
      expect(utils.mergePathsFromAnyEnv).toThrowError('Параметр env не задан');
    });

    it('env задан', function () {
      let path = utils.mergePathsFromAnyEnv('/home/alexey/IdeaProjects/sfa',
        '/opt/teamcity-agent/work/89d8f1306cb75ef7/devTools/js/grunt-config/clean.js', 'teamcity');

      expect(path.replace(/\\/g, '/')).toEqual('/home/alexey/IdeaProjects/sfa/devTools/js/grunt-config/clean.js');
    });

    describe('isVerboseMode', () => {
      it('true', () => {
        process.argv.push('--verbose');

        expect(utils.isVerboseMode()).toBeTruthy();
        process.argv.pop();
      });

      it('false', () => {
        expect(utils.isVerboseMode()).toBeFalsy();
      });
    });

    describe('filerArrayOfObjectsByPropertyValue', () => {
      let exampleArrayOfObjects;
      beforeAll(() => {
        exampleArrayOfObjects = [{a: 'a'}, {a: 'b'}, 'c'];
      });

      it('success > value', () => {
        expect(utils.filerArrayOfObjectsByPropertyValue(exampleArrayOfObjects,
          'a', 'a')).toEqual(exampleArrayOfObjects[0]);
      });

      it('fail > undefined', () => {
        expect(utils.filerArrayOfObjectsByPropertyValue(exampleArrayOfObjects,
          'a', 'd')).toBeUndefined();
      });
    });
  });
});
<|endoftext|>


<commit_before>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import HeadNext from 'next/head';
import { connect } from 'react-redux';

// constants
import { TRANSIFEX_BLACKLIST, USERREPORT_BLACKLIST } from 'constants/app';

class Head extends PureComponent {
  static propTypes = {
    // some pages don't have any title (think embed)
    title: PropTypes.string,
    description: PropTypes.string.isRequired,
    routes: PropTypes.object.isRequired,
    thumbnail: PropTypes.string,
    category: PropTypes.string
  };

  static defaultProps = {
    title: null,
    category: null,
    thumbnail: 'https://resourcewatch.org/static/images/social-big.jpg'
  }

  static getStyles() {
    return <link rel="stylesheet" type="text/css" href="/_next/static/style.css" />;
  }

  getCrazyEgg() {
    if (process.env.NODE_ENV === 'production' && typeof window !== 'undefined') {
      return (
        <script
          type="text/javascript"
          src="//script.crazyegg.com/pages/scripts/0069/4623.js"
          async="async"
        />
      );
    }
    return null;
  }

  getUserReport() {
    const { routes } = this.props;
    const { pathname } = routes;

    if (USERREPORT_BLACKLIST.includes(pathname)) return null;

    if (process.env.NODE_ENV === 'production' && typeof window !== 'undefined') {
      return (
        <script
          type="text/javascript"
          // eslint-disable-next-line react/no-danger
          dangerouslySetInnerHTML={{
            __html: `
              window._urq = window._urq || [];
              _urq.push(['setGACode', 'UA-67196006-1']);
              _urq.push(['initSite', '085d5a65-977b-4c3d-af9f-d0a3624e276f']);
              (function() {
              var ur = document.createElement('script');
              ur.type = 'text/javascript';
              ur.async = true;
              ur.src = ('https:' == document.location.protocol ? 'https://cdn.userreport.com/userreport.js' : 'http://cdn.userreport.com/userreport.js');
              var s = document.getElementsByTagName('script')[0];
              s.parentNode.insertBefore(ur, s);
              })();
            `
          }}
        />
      );
    }

    return null;
  }

  getTransifexSettings() {
    const { pathname } = this.props.routes;

    if (TRANSIFEX_BLACKLIST.includes(pathname)) {
      return null;
    }

    return (
      <script
        type="text/javascript"
        // eslint-disable-next-line react/no-danger
        dangerouslySetInnerHTML={{
          __html: `
            window.liveSettings = { api_key: '${process.env.TRANSIFEX_LIVE_API}' }
          `
        }}
      />
    );
  }

  getTransifex() {
    const { pathname } = this.props.routes;

    if (TRANSIFEX_BLACKLIST.includes(pathname)) {
      return null;
    }

    return <script type="text/javascript" src="//cdn.transifex.com/live.js" />;
  }

  getCesium() {
    const { pathname } = this.props.routes;
    if (pathname === '/app/pulse' || pathname === '/app/Splash') {
      return (
        <fragment>
          <script src="/static/cesium/cesium.js" />
          <script src="/static/cesium/cesium-navigation.js" />
        </fragment>
      );
    }
    return null;
  }

  getCesiumStyles() {
    const { pathname } = this.props.routes;
    if (pathname === '/app/pulse' || pathname === '/app/Splash') {
      return <link rel="stylesheet" href="/static/cesium/Widgets/widgets.css" />;
    }
    return null;
  }

  getAFrame() {
    const { pathname } = this.props.routes;
    if (pathname === '/app/SplashDetail') {
      return <script src="/static/aframe/aframe.min.js" />;
    }
    return null;
  }

  render() {
    const {
      title,
      description,
      category,
      thumbnail
    } = this.props;

    return (
      <HeadNext>
        <title>{title ? `${title} | Resource Watch` : 'Resource Watch'}</title>
        <meta name="description" content={description} />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <meta name="author" content="Vizzuality" />

        {category && <meta name="addsearch-category" content={category} />}

        <link rel="icon" href="/static/favicon.ico" />
        <link
          rel="stylesheet"
          media="screen"
          href="https://fonts.googleapis.com/css?family=Lato:400,300,700"
        />
        <link rel="stylesheet" media="screen" href="/static/styles/add-search-results.css" />

        {/* Mobile Adress background */}
        {/* Chrome, Firefox OS and Opera */}
        <meta name="theme-color" content="#c32d7b" />
        {/* Windows Phone */}
        <meta name="msapplication-navbutton-color" content="#c32d7b" />
        {/* iOS Safari */}
        <meta name="apple-mobile-web-app-capable" content="yes" />
        <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />

        {/* Social metadata */}
        <meta property="og:title" content={title} />
        <meta property="og:description" content={description} />
        <meta
          property="og:image"
          content={thumbnail}
        />
        <meta property="og:url" content="https://resourcewatch.org" />
        <meta property="og:type" content="website" />
        <meta name="twitter:card" content="summary" />
        <meta name="twitter:site" content="@resource_watch" />

        {/* Leaflet CDN */}
        <link
          rel="stylesheet"
          href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css"
          integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ=="
          crossOrigin=""
        />
        <link
          rel="stylesheet"
          href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.2/leaflet.draw.css"
          crossOrigin=""
        />
        <script
          src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js"
          integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw=="
          crossOrigin=""
        />
        <script
          src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.2/leaflet.draw.js"
          crossOrigin=""
        />
        <script
          src="https://unpkg.com/esri-leaflet@2.1.3/dist/esri-leaflet.js"
          integrity="sha512-pijLQd2FbV/7+Jwa86Mk3ACxnasfIMzJRrIlVQsuPKPCfUBCDMDUoLiBQRg7dAQY6D1rkmCcR8286hVTn/wlIg=="
          crossOrigin=""
        />
        <script src="https://unpkg.com/leaflet-utfgrid/L.UTFGrid-min.js" crossOrigin="" />

        {this.getCesiumStyles()}
        {this.getCrazyEgg()}
        {this.getUserReport()}
        {/* {this.getTransifexSettings()}
        {this.getTransifex()} */}
        {this.getCesium()}
        {this.getAFrame()}

        <script
          src={`https://maps.googleapis.com/maps/api/js?v=3.35&key=${
            process.env.RW_GOGGLE_API_TOKEN_SHORTENER
          }&libraries=places`}
        />
        <script src="https://cdn.polyfill.io/v2/polyfill.min.js" />
      </HeadNext>
    );
  }
}

export default connect(
  state => ({ routes: state.routes }),
  null
)(Head);
<commit_msg>Updates og:url<commit_after>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import HeadNext from 'next/head';
import { connect } from 'react-redux';

// constants
import { TRANSIFEX_BLACKLIST, USERREPORT_BLACKLIST } from 'constants/app';

class Head extends PureComponent {
  static propTypes = {
    // some pages don't have any title (think embed)
    title: PropTypes.string,
    description: PropTypes.string.isRequired,
    routes: PropTypes.object.isRequired,
    thumbnail: PropTypes.string,
    category: PropTypes.string
  };

  static defaultProps = {
    title: null,
    category: null,
    thumbnail: 'https://resourcewatch.org/static/images/social-big.jpg'
  }

  static getStyles() {
    return <link rel="stylesheet" type="text/css" href="/_next/static/style.css" />;
  }

  getCrazyEgg() {
    if (process.env.NODE_ENV === 'production' && typeof window !== 'undefined') {
      return (
        <script
          type="text/javascript"
          src="//script.crazyegg.com/pages/scripts/0069/4623.js"
          async="async"
        />
      );
    }
    return null;
  }

  getUserReport() {
    const { routes } = this.props;
    const { pathname } = routes;

    if (USERREPORT_BLACKLIST.includes(pathname)) return null;

    if (process.env.NODE_ENV === 'production' && typeof window !== 'undefined') {
      return (
        <script
          type="text/javascript"
          // eslint-disable-next-line react/no-danger
          dangerouslySetInnerHTML={{
            __html: `
              window._urq = window._urq || [];
              _urq.push(['setGACode', 'UA-67196006-1']);
              _urq.push(['initSite', '085d5a65-977b-4c3d-af9f-d0a3624e276f']);
              (function() {
              var ur = document.createElement('script');
              ur.type = 'text/javascript';
              ur.async = true;
              ur.src = ('https:' == document.location.protocol ? 'https://cdn.userreport.com/userreport.js' : 'http://cdn.userreport.com/userreport.js');
              var s = document.getElementsByTagName('script')[0];
              s.parentNode.insertBefore(ur, s);
              })();
            `
          }}
        />
      );
    }

    return null;
  }

  getTransifexSettings() {
    const { pathname } = this.props.routes;

    if (TRANSIFEX_BLACKLIST.includes(pathname)) {
      return null;
    }

    return (
      <script
        type="text/javascript"
        // eslint-disable-next-line react/no-danger
        dangerouslySetInnerHTML={{
          __html: `
            window.liveSettings = { api_key: '${process.env.TRANSIFEX_LIVE_API}' }
          `
        }}
      />
    );
  }

  getTransifex() {
    const { pathname } = this.props.routes;

    if (TRANSIFEX_BLACKLIST.includes(pathname)) {
      return null;
    }

    return <script type="text/javascript" src="//cdn.transifex.com/live.js" />;
  }

  getCesium() {
    const { pathname } = this.props.routes;
    if (pathname === '/app/pulse' || pathname === '/app/Splash') {
      return (
        <fragment>
          <script src="/static/cesium/cesium.js" />
          <script src="/static/cesium/cesium-navigation.js" />
        </fragment>
      );
    }
    return null;
  }

  getCesiumStyles() {
    const { pathname } = this.props.routes;
    if (pathname === '/app/pulse' || pathname === '/app/Splash') {
      return <link rel="stylesheet" href="/static/cesium/Widgets/widgets.css" />;
    }
    return null;
  }

  getAFrame() {
    const { pathname } = this.props.routes;
    if (pathname === '/app/SplashDetail') {
      return <script src="/static/aframe/aframe.min.js" />;
    }
    return null;
  }

  render() {
    const {
      title,
      description,
      category,
      thumbnail
    } = this.props;
    const url = (typeof window !== 'undefined') ?
      window.location.href : 'https://resourcewatch.org';

    return (
      <HeadNext>
        <title>{title ? `${title} | Resource Watch` : 'Resource Watch'}</title>
        <meta name="description" content={description} />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <meta name="author" content="Vizzuality" />

        {category && <meta name="addsearch-category" content={category} />}

        <link rel="icon" href="/static/favicon.ico" />
        <link
          rel="stylesheet"
          media="screen"
          href="https://fonts.googleapis.com/css?family=Lato:400,300,700"
        />
        <link rel="stylesheet" media="screen" href="/static/styles/add-search-results.css" />

        {/* Mobile Adress background */}
        {/* Chrome, Firefox OS and Opera */}
        <meta name="theme-color" content="#c32d7b" />
        {/* Windows Phone */}
        <meta name="msapplication-navbutton-color" content="#c32d7b" />
        {/* iOS Safari */}
        <meta name="apple-mobile-web-app-capable" content="yes" />
        <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />

        {/* Social metadata */}
        <meta property="og:title" content={title} />
        <meta property="og:description" content={description} />
        <meta
          property="og:image"
          content={thumbnail}
        />
        <meta property="og:url" content={url} />
        <meta property="og:type" content="website" />
        <meta name="twitter:card" content="summary" />
        <meta name="twitter:site" content="@resource_watch" />

        {/* Leaflet CDN */}
        <link
          rel="stylesheet"
          href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css"
          integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ=="
          crossOrigin=""
        />
        <link
          rel="stylesheet"
          href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.2/leaflet.draw.css"
          crossOrigin=""
        />
        <script
          src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js"
          integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw=="
          crossOrigin=""
        />
        <script
          src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.2/leaflet.draw.js"
          crossOrigin=""
        />
        <script
          src="https://unpkg.com/esri-leaflet@2.1.3/dist/esri-leaflet.js"
          integrity="sha512-pijLQd2FbV/7+Jwa86Mk3ACxnasfIMzJRrIlVQsuPKPCfUBCDMDUoLiBQRg7dAQY6D1rkmCcR8286hVTn/wlIg=="
          crossOrigin=""
        />
        <script src="https://unpkg.com/leaflet-utfgrid/L.UTFGrid-min.js" crossOrigin="" />

        {this.getCesiumStyles()}
        {this.getCrazyEgg()}
        {this.getUserReport()}
        {/* {this.getTransifexSettings()}
        {this.getTransifex()} */}
        {this.getCesium()}
        {this.getAFrame()}

        <script
          src={`https://maps.googleapis.com/maps/api/js?v=3.35&key=${
            process.env.RW_GOGGLE_API_TOKEN_SHORTENER
          }&libraries=places`}
        />
        <script src="https://cdn.polyfill.io/v2/polyfill.min.js" />
      </HeadNext>
    );
  }
}

export default connect(
  state => ({ routes: state.routes }),
  null
)(Head);
<|endoftext|>