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

// Declare app level module which depends on views, and components
angular.module('slicebox', [
    'ngRoute',
    'ngCookies',
    'ngAnimate',
    'ngMaterial',
    'slicebox.utils',
    'slicebox.directives',
    'slicebox.login',
    'slicebox.import',
    'slicebox.home',
    'slicebox.anonymization',
    'slicebox.transactions',
    'slicebox.log',
    'slicebox.adminPacs',
    'slicebox.adminWatchDirectories',
    'slicebox.adminBoxes',
    'slicebox.adminUsers',
    'slicebox.adminSeriesTypes'
])

.config(function($locationProvider, $routeProvider, $mdThemingProvider, $animateProvider, $filterProvider) {
    $locationProvider.html5Mode(true);
    $routeProvider.otherwise({redirectTo: '/'});

    $mdThemingProvider.theme('default')
        .primaryPalette('blue-grey', {
            'default': '600',
        })
        .accentPalette('pink')
        .warnPalette('red');

    $mdThemingProvider.theme('redTheme')
        .primaryPalette('red');

    // prevent ng-animate on spinners, causes weird behaviour with ng-if/ng-show
    $animateProvider.classNameFilter(/^((?!(fa-spinner)).)*$/);

    // Register filters
    $filterProvider.register('hexvalue', function() {
        return function(intValue, length) {
            var returnValue = intValue;

            if (!length) {
                length = 4;
            }

            if (angular.isDefined(intValue) && angular.isNumber(intValue) && intValue !== 0) {
                returnValue = intValue.toString(16);

                while (returnValue.length < length) {
                    returnValue = '0' + returnValue;
                }
            }

            return returnValue;
        };
    });
})

.filter('prettyPatientName', function () {
    return function (text) {
        return text ? text.replace(new RegExp('\\^', 'g'), ' ') : '';
    };
})

.controller('SliceboxCtrl', function($scope, $http, $q, $location, $mdSidenav, $mdToast, $mdDialog, authenticationService, openConfirmActionModal) {

    $scope.uiState = {
        showMenu: true,
        addEntityInProgress: false
    };

    $scope.toggleLeftNav = function() {
        $mdSidenav('leftNav').toggle();
    };

    $scope.logout = function() {
        authenticationService.clearCredentials();
        $scope.uiState.showMenu = false;
        $location.url("/login");
    };

    $scope.userSignedIn = function() {
        return authenticationService.userSignedIn();
    };

    $scope.isCurrentPath = function(path) {
        return $location.path() === path;
    };

    $scope.currentPathStartsWith = function(path) {
        return $location.path().indexOf(path) === 0;
    };

    $scope.showErrorMessage = function(errorMessage) {
        var toast = $mdToast.simple()
            .content(errorMessage)
            .action('Dismiss')
            .highlightAction(true)
            .hideDelay(30000)
            .theme('redTheme')
            .position("bottom right");
        $mdToast.show(toast);
    };

    $scope.showInfoMessage = function(infoMessage) {
        var toast = {
            parent: angular.element(document.getElementById("content")),
            template: '<md-toast>' + infoMessage + '</md-toast>',
            position: 'top right'
        };
        $mdToast.show(toast);
    };

    $scope.addEntityButtonClicked = function(modalContentName, controllerName, url, entityName, table) {
        var dialogPromise = $mdDialog.show({
            templateUrl: '/assets/partials/' + modalContentName,
            controller: controllerName
        });

        dialogPromise.then(function (entity) {
            $scope.uiState.addEntityInProgress = true;

            var addPromise = $http.post(url, entity);
            addPromise.error(function(data) {
                $scope.showErrorMessage(data);
            });

            addPromise.success(function() {
                $scope.showInfoMessage(entityName + " added");
            });

            addPromise.finally(function() {
                $scope.uiState.addEntityInProgress = false;
                table.reloadPage();
            });
        });
    };

    $scope.confirmDeleteEntitiesFunction = function(url, entitiesText) {

        return function(entities) {
            var deleteConfirmationText = 'Permanently delete ' + entities.length + ' ' + entitiesText + '?';

            return openConfirmActionModal('Delete ' + entitiesText, deleteConfirmationText, 'Delete', function() {
                return deleteEntities(url, entities, entitiesText);
            });
        };
    };

    // private functions
    function deleteEntities(url, entities, entitiesText) {

        var removePromises = [];
        var removePromise;
        var deleteAllPromises;

        angular.forEach(entities, function(entity) {
            removePromise = $http.delete(url + entity.id);
            removePromises.push(removePromise);
        });

        deleteAllPromises = $q.all(removePromises);

        deleteAllPromises.then(function() {
            $scope.showInfoMessage(entities.length + " " + entitiesText + " deleted");
        }, function(response) {
            $scope.showErrorMessage(response.data);
        });

        return deleteAllPromises;
    }
})

.run(function ($rootScope, $location, $cookieStore, $http) {
    // keep user logged in after page refresh
    $rootScope.globals = $cookieStore.get('globals') || {};
    if ($rootScope.globals.currentUser) {
        $http.defaults.headers.common['Authorization'] = 'Basic ' + $rootScope.globals.currentUser.authdata; // jshint ignore:line
    }

    $rootScope.$on('$locationChangeStart', function (event, next, current) {
        // redirect to login page if not logged in
        if ($location.path() !== '/login' && !$rootScope.globals.currentUser) {
            $location.path('/login');
        }
    });
});
<commit_msg>Updated hexvalue filter to display hex value as upper case.<commit_after>(function () {
    'use strict';
}());

// Declare app level module which depends on views, and components
angular.module('slicebox', [
    'ngRoute',
    'ngCookies',
    'ngAnimate',
    'ngMaterial',
    'slicebox.utils',
    'slicebox.directives',
    'slicebox.login',
    'slicebox.import',
    'slicebox.home',
    'slicebox.anonymization',
    'slicebox.transactions',
    'slicebox.log',
    'slicebox.adminPacs',
    'slicebox.adminWatchDirectories',
    'slicebox.adminBoxes',
    'slicebox.adminUsers',
    'slicebox.adminSeriesTypes'
])

.config(function($locationProvider, $routeProvider, $mdThemingProvider, $animateProvider, $filterProvider) {
    $locationProvider.html5Mode(true);
    $routeProvider.otherwise({redirectTo: '/'});

    $mdThemingProvider.theme('default')
        .primaryPalette('blue-grey', {
            'default': '600',
        })
        .accentPalette('pink')
        .warnPalette('red');

    $mdThemingProvider.theme('redTheme')
        .primaryPalette('red');

    // prevent ng-animate on spinners, causes weird behaviour with ng-if/ng-show
    $animateProvider.classNameFilter(/^((?!(fa-spinner)).)*$/);

    // Register filters
    $filterProvider.register('hexvalue', function() {
        return function(intValue, length) {
            var returnValue = intValue;

            if (!length) {
                length = 4;
            }

            if (angular.isDefined(intValue) && angular.isNumber(intValue) && intValue !== 0) {
                returnValue = intValue.toString(16);

                while (returnValue.length < length) {
                    returnValue = '0' + returnValue;
                }

                returnValue = returnValue.toUpperCase();
            }

            return returnValue;
        };
    });
})

.filter('prettyPatientName', function () {
    return function (text) {
        return text ? text.replace(new RegExp('\\^', 'g'), ' ') : '';
    };
})

.controller('SliceboxCtrl', function($scope, $http, $q, $location, $mdSidenav, $mdToast, $mdDialog, authenticationService, openConfirmActionModal) {

    $scope.uiState = {
        showMenu: true,
        addEntityInProgress: false
    };

    $scope.toggleLeftNav = function() {
        $mdSidenav('leftNav').toggle();
    };

    $scope.logout = function() {
        authenticationService.clearCredentials();
        $scope.uiState.showMenu = false;
        $location.url("/login");
    };

    $scope.userSignedIn = function() {
        return authenticationService.userSignedIn();
    };

    $scope.isCurrentPath = function(path) {
        return $location.path() === path;
    };

    $scope.currentPathStartsWith = function(path) {
        return $location.path().indexOf(path) === 0;
    };

    $scope.showErrorMessage = function(errorMessage) {
        var toast = $mdToast.simple()
            .content(errorMessage)
            .action('Dismiss')
            .highlightAction(true)
            .hideDelay(30000)
            .theme('redTheme')
            .position("bottom right");
        $mdToast.show(toast);
    };

    $scope.showInfoMessage = function(infoMessage) {
        var toast = {
            parent: angular.element(document.getElementById("content")),
            template: '<md-toast>' + infoMessage + '</md-toast>',
            position: 'top right'
        };
        $mdToast.show(toast);
    };

    $scope.addEntityButtonClicked = function(modalContentName, controllerName, url, entityName, table) {
        var dialogPromise = $mdDialog.show({
            templateUrl: '/assets/partials/' + modalContentName,
            controller: controllerName
        });

        dialogPromise.then(function (entity) {
            $scope.uiState.addEntityInProgress = true;

            var addPromise = $http.post(url, entity);
            addPromise.error(function(data) {
                $scope.showErrorMessage(data);
            });

            addPromise.success(function() {
                $scope.showInfoMessage(entityName + " added");
            });

            addPromise.finally(function() {
                $scope.uiState.addEntityInProgress = false;
                table.reloadPage();
            });
        });
    };

    $scope.confirmDeleteEntitiesFunction = function(url, entitiesText) {

        return function(entities) {
            var deleteConfirmationText = 'Permanently delete ' + entities.length + ' ' + entitiesText + '?';

            return openConfirmActionModal('Delete ' + entitiesText, deleteConfirmationText, 'Delete', function() {
                return deleteEntities(url, entities, entitiesText);
            });
        };
    };

    // private functions
    function deleteEntities(url, entities, entitiesText) {

        var removePromises = [];
        var removePromise;
        var deleteAllPromises;

        angular.forEach(entities, function(entity) {
            removePromise = $http.delete(url + entity.id);
            removePromises.push(removePromise);
        });

        deleteAllPromises = $q.all(removePromises);

        deleteAllPromises.then(function() {
            $scope.showInfoMessage(entities.length + " " + entitiesText + " deleted");
        }, function(response) {
            $scope.showErrorMessage(response.data);
        });

        return deleteAllPromises;
    }
})

.run(function ($rootScope, $location, $cookieStore, $http) {
    // keep user logged in after page refresh
    $rootScope.globals = $cookieStore.get('globals') || {};
    if ($rootScope.globals.currentUser) {
        $http.defaults.headers.common['Authorization'] = 'Basic ' + $rootScope.globals.currentUser.authdata; // jshint ignore:line
    }

    $rootScope.$on('$locationChangeStart', function (event, next, current) {
        // redirect to login page if not logged in
        if ($location.path() !== '/login' && !$rootScope.globals.currentUser) {
            $location.path('/login');
        }
    });
});
<|endoftext|>


<commit_before>/**
 * JBZoo Helper
 *
 * This file is part of the JBZoo CCK package.
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @package   Utils
 * @license   MIT
 * @copyright Copyright (C) JBZoo.com,  All rights reserved.
 * @link      https://github.com/JBZoo/Utils
 * @author    Denis Smetannikov <denis@jbzoo.com>
 */

/**
 * JBZoo Helper with custom js functions
 */
(function (window, document, undefined) {

    'use strict';

    var class2type = {},
        types      = ['Boolean', 'Number', 'String', 'Function', 'Array',
            'Date', 'RegExp', 'Object', 'Error', 'Symbol'];

    (function() {
        for (var index in types) {
            class2type['[object ' + types[index] + ']'] = types[index].toLowerCase();
        }
    }());

    window.JBZoo = {

        DEBUG: false,

        /**
         * @link http://phpjs.org/functions/number_format/
         * @param number
         * @param decimals
         * @param decPoint
         * @param thousandsSep
         * @returns {string}
         */
        numFormat: function (number, decimals, decPoint, thousandsSep) {

            number = ('' + number).replace(/[^0-9+\-Ee.]/g, '');

            var num        = !isFinite(+number) ? 0 : +number,
                prec       = !isFinite(+decimals) ? 0 : Math.abs(decimals),
                separator  = (typeof thousandsSep === 'undefined') ? ',' : thousandsSep,
                decimal    = (typeof decPoint === 'undefined') ? '.' : decPoint,
                toFixedFix = function (n, prec) {
                    var k = Math.pow(10, prec);
                    return '' + (Math.round(n * k) / k).toFixed(prec);
                };

            // Fix for IE parseFloat(0.55).toFixed(0) = 0;
            var result = (prec ? toFixedFix(num, prec) : '' + Math.round(num)).split('.');

            if (result[0].length > 3) {
                result[0] = result[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, separator);
            }

            return result.join(decimal);
        },

        /**
         * Check is variable empty
         * @link http://phpjs.org/functions/empty:392
         * @param mixedVar
         * @return {Boolean}
         */
        empty: function (mixedVar) {
            var $this       = this,
                undefined, i, length,
                emptyValues = [undefined, null, false, 0, '', '0'];

            for (i = 0, length = emptyValues.length; i < length; i++) {
                if (mixedVar === emptyValues[i]) {
                    return true;
                }
            }

            if (typeof mixedVar === 'object') {
                if ($this.count(mixedVar) === 0) {
                    return true;
                }
            }

            return false;
        },

        /**
         * Check and get variable
         *
         * @returns {*}
         */
        get: function () {

            var args = arguments,
                argc = arguments.length;

            if (argc === 1) {
                if (args[0] === undefined || args[0] === null) {
                    return undefined;
                }

                return args[0];

            } else if (argc === 2) {

                if (args[0] === undefined || args[0] === null) {
                    return args[1];
                }

                return args[0];

            } else if (argc === 3) {

                if (args[0][args[1]] === undefined || args[0][args[1]] === null) {
                    return args[2];
                }

                return args[0][args[1]];
            }
        },

        /**
         * Check is variable function
         *
         * @param functionToCheck
         * @returns {boolean}
         */
        isFunc: function (functionToCheck) {
            return this.type(functionToCheck) === 'function';
        },

        /**
         * Get variable type
         *
         * @param mixedVar
         * @returns {*}
         */
        type: function (mixedVar) {

            if (mixedVar == null) {
                return mixedVar + '';
            }

            // Support: Android<4.0 (functionish RegExp)
            return typeof mixedVar === 'object' ||
            typeof mixedVar === 'function' ? (class2type[toString.call(mixedVar)] || 'object') : typeof mixedVar;
        },

        /**
         * Count all elements in an array, or something in an object
         *
         * @link http://php.net/manual/en/function.count.php
         * @link http://phpjs.org/functions/count/
         *
         * @param variable
         * @param isRecursive bool
         * @returns {number}
         */
        count: function (variable, isRecursive) {

            var $this = this, property, result = 0;

            isRecursive = (typeof isRecursive !== 'undefined' && isRecursive) ? true : false;

            if (variable === false ||
                variable === null ||
                typeof variable === 'undefined'
            ) {
                return 0;

            } else if (variable.constructor !== Array && variable.constructor !== Object) {
                return 1;
            }

            for (property in variable) {

                if (variable.hasOwnProperty(property) && !$this.isFunc(variable[property])) {
                    result++;

                    if (isRecursive && variable[property] &&
                        (
                            variable[property].constructor === Array ||
                            variable[property].constructor === Object
                        )
                    ) {
                        result += this.count(variable[property], true);
                    }
                }
            }

            return result;
        },

        /**
         * Finds whether a variable is a number or a numeric string
         *
         * @link http://php.net/manual/ru/function.in-array.php
         * @link http://phpjs.org/functions/in_array/
         *
         * @param needle
         * @param haystack
         * @param strict
         * @return {Boolean}
         */
        inArray: function (needle, haystack, strict) {

            var found = false, key;

            strict = !!strict;

            for (key in haystack) {
                if ((strict && haystack[key] === needle) || (!strict && haystack[key] == needle)) {
                    found = true;
                    break;
                }
            }

            return found;
        },

        /**
         * Finds whether a variable is a number or a numeric string
         *
         * @link http://php.net/manual/ru/function.is-numeric.php
         * @link http://phpjs.org/functions/is_numeric/
         *
         * @param mixed
         * @returns {boolean}
         */
        isNumeric: function (mixed) {
            return (typeof(mixed) === 'number' || typeof(mixed) === 'string') && mixed !== '' && !isNaN(mixed);
        },

        /**
         * Parse integer from string
         *
         * @link http://phpjs.org/functions/intval/
         *
         * @param mixed
         * @returns {Number}
         */
        toInt: function (mixed, base) {
            var type = typeof mixed;

            base = base || 10;

            if (type === 'boolean') {
                return +mixed;

            } else if (type === 'string') {
                mixed   = mixed.replace(/\s/g, '');
                var tmp = parseInt(mixed, base);
                return (isNaN(tmp) || !isFinite(tmp)) ? 0 : tmp;

            } else if (type === 'number' && isFinite(mixed)) {
                return mixed | 0;

            } else {
                return 0;
            }
        },

        /**
         * Check is variable integer
         *
         * @link http://phpjs.org/functions/is_int/
         *
         * @param mixed
         * @returns {boolean}
         */
        isInt: function (mixed) {
            return mixed === +mixed && isFinite(mixed) && !(mixed % 1);
        },

        /**
         * Parse integer from string
         *
         * @param mixed
         * @returns {Number}
         */
        toFloat: function (mixed) {

            var type = typeof mixed;

            if (type === 'boolean') {
                return +mixed;
            }

            mixed = '' + mixed;
            mixed = mixed.replace(/\s/g, '');
            mixed = mixed.replace(',', '.');
            mixed = (parseFloat(mixed) || 0);
            mixed = this.round(mixed, 9); // hack for numbers like '0.30000000000000004'

            return mixed;
        },

        /**
         * Rounds a float
         *
         * @link http://php.net/manual/en/function.round.php
         * @link http://phpjs.org/functions/round/
         *
         * @param value
         * @param precision
         * @param mode
         * @returns {number}
         */
        round: function (value, precision, mode) {
            // helper variables
            var base, floorNum, isHalf, sign;

            // making sure precision is integer
            precision |= 0;
            base = Math.pow(10, precision);
            value *= base;

            // sign of the number
            sign     = (value > 0) | -(value < 0);
            isHalf   = value % 1 === 0.5 * sign;
            floorNum = Math.floor(value);

            if (isHalf) {
                mode = mode ? mode.toUpperCase() : 'DEFAULT';
                switch (mode) {
                    case 'DOWN':
                        // rounds .5 toward zero
                        value = floorNum + (sign < 0);
                        break;
                    case 'EVEN':
                        // rouds .5 towards the next even integer
                        value = floorNum + (floorNum % 2 * sign);
                        break;
                    case 'ODD':
                        // rounds .5 towards the next odd integer
                        value = floorNum + !(floorNum % 2);
                        break;
                    default:
                        // rounds .5 away from zero
                        value = floorNum + (sign > 0);
                }
            }

            return (isHalf ? value : Math.round(value)) / base;
        },

        /**
         * Generate a random integer
         *
         * @link http://php.net/manual/en/function.rand.php
         * @link http://phpjs.org/functions/rand/
         *
         * @param min
         * @param max
         * @returns {*}
         */
        rand: function (min, max) {
            var $this = this,
                argc  = arguments.length;

            if (argc === 0) {
                min = 0;
                max = 2147483647;

            } else if (argc === 1) {
                throw new Error('Warning: rand() expects exactly 2 parameters, 1 given');

            } else {
                min = $this.toInt(min);
                max = $this.toInt(max);
            }

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

        /**
         * Join array elements with a string
         *
         * @link http://php.net/manual/en/function.implode.php
         * @link http://phpjs.org/functions/implode/
         *
         * @param glue
         * @param pieces
         * @returns {*}
         */
        implode: function (glue, pieces) {

            var i      = '',
                $this  = this,
                retVal = '',
                tGlue  = '';

            if (arguments.length === 1) {
                pieces = glue;
                glue   = '';
            }

            if (typeof pieces === 'object') {
                if ($this.type(pieces) === 'array') {
                    return pieces.join(glue);
                }

                for (i in pieces) {
                    retVal += tGlue + pieces[i];
                    tGlue = glue;
                }

                return retVal;
            }
        },

        /**
         * Split a string by string
         *
         * @link http://phpjs.org/functions/explode/
         * @link http://php.net/manual/en/function.explode.php
         *
         * @param delimiter
         * @param string
         * @param limit
         * @returns {*}
         */
        explode: function (delimiter, string, limit) {

            if (arguments.length < 2 ||
                typeof delimiter === 'undefined' ||
                typeof string === 'undefined'
            ) {
                return null;
            }

            if (delimiter === '' ||
                delimiter === false ||
                delimiter === null
            ) {
                return false;
            }

            if (delimiter === true) {
                delimiter = '1';
            }

            // Here we go...
            delimiter += '';
            string += '';

            var splited = string.split(delimiter);

            if (typeof limit === 'undefined') {
                return splited;
            }

            // Support for limit
            if (limit === 0) {
                limit = 1;
            }

            // Positive limit
            if (limit > 0) {
                if (limit >= splited.length) return splited;
                return splited.slice(0, limit - 1)
                    .concat([splited.slice(limit - 1)
                        .join(delimiter)
                    ]);
            }

            // Negative limit
            if (-limit >= splited.length) return [];

            splited.splice(splited.length + limit);

            return splited;
        },

        /**
         * Strip HTML and PHP tags from a string
         *
         * @link http://php.net/manual/en/function.strip-tags.php
         * @link http://phpjs.org/functions/strip_tags/
         *
         * @param input
         * @param allowed
         * @returns {string}
         */
        stripTags: function (input, allowed) {

            allowed = (((allowed || '') + '')
                .toLowerCase()
                .match(/<[a-z][a-z0-9]*>/g) || [])
                .join('');

            var tags               = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
                commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;

            return input
                .replace(commentsAndPhpTags, '')
                .replace(tags, function ($0, $1) {
                    return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
                });
        },

        /**
         * Alias for console log + backtrace. For debug only. Works only if environment is 'development' (DEBUG = true)
         *
         * @param vars mixed
         * @param name String
         * @param showTrace Boolean
         * @return {Boolean}
         */
        dump: function (vars, name, showTrace) {

            var $this = this;

            if (!this.DEBUG) {
                return false;
            }

            // Get type
            var type    = '',
                varType = $this.type(vars);

            if (varType === 'string' || varType === 'array') {
                type = ' (' + varType + ', ' + $this.count(vars) + ')';
            } else {
                type = ' (' + varType + ')';
            }

            // Wrap in vars quote if string
            if (varType === 'string') {
                vars = '\'' + vars + '\'';
            }

            // Get var name
            if (!name) {
                name = '...' + type + ' = ';
            } else {
                name += type + ' = ';
            }

            // Dump var
            if (window.parent && window.parent.console && window.parent.console.log) {
                window.parent.console.log(name, vars);
            }

            // Show backtrace
            if (showTrace && typeof console.trace !== 'undefined') {
                console.trace();
                return false;
            }

            return false;
        }
    };

})(window, document);
<commit_msg>undefined var<commit_after>/**
 * JBZoo Helper
 *
 * This file is part of the JBZoo CCK package.
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @package   Utils
 * @license   MIT
 * @copyright Copyright (C) JBZoo.com,  All rights reserved.
 * @link      https://github.com/JBZoo/Utils
 * @author    Denis Smetannikov <denis@jbzoo.com>
 */

/**
 * JBZoo Helper with custom js functions
 */
(function (window, document, undefined) {

    'use strict';

    var class2type = {},
        types      = ['Boolean', 'Number', 'String', 'Function', 'Array',
            'Date', 'RegExp', 'Object', 'Error', 'Symbol'];

    (function() {
        for (var index in types) {
            class2type['[object ' + types[index] + ']'] = types[index].toLowerCase();
        }
    }());

    window.JBZoo = {

        DEBUG: false,

        /**
         * @link http://phpjs.org/functions/number_format/
         * @param number
         * @param decimals
         * @param decPoint
         * @param thousandsSep
         * @returns {string}
         */
        numFormat: function (number, decimals, decPoint, thousandsSep) {

            number = ('' + number).replace(/[^0-9+\-Ee.]/g, '');

            var num        = !isFinite(+number) ? 0 : +number,
                prec       = !isFinite(+decimals) ? 0 : Math.abs(decimals),
                separator  = (typeof thousandsSep === 'undefined') ? ',' : thousandsSep,
                decimal    = (typeof decPoint === 'undefined') ? '.' : decPoint,
                toFixedFix = function (n, prec) {
                    var k = Math.pow(10, prec);
                    return '' + (Math.round(n * k) / k).toFixed(prec);
                };

            // Fix for IE parseFloat(0.55).toFixed(0) = 0;
            var result = (prec ? toFixedFix(num, prec) : '' + Math.round(num)).split('.');

            if (result[0].length > 3) {
                result[0] = result[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, separator);
            }

            return result.join(decimal);
        },

        /**
         * Check is variable empty
         * @link http://phpjs.org/functions/empty:392
         * @param mixedVar
         * @return {Boolean}
         */
        empty: function (mixedVar) {
            var $this       = this,
                emptyValues = [undefined, null, false, 0, '', '0'],
                i, length;

            for (i = 0, length = emptyValues.length; i < length; i++) {
                if (mixedVar === emptyValues[i]) {
                    return true;
                }
            }

            if (typeof mixedVar === 'object') {
                if ($this.count(mixedVar) === 0) {
                    return true;
                }
            }

            return false;
        },

        /**
         * Check and get variable
         *
         * @returns {*}
         */
        get: function () {

            var args = arguments,
                argc = arguments.length;

            if (argc === 1) {
                if (args[0] === undefined || args[0] === null) {
                    return undefined;
                }

                return args[0];

            } else if (argc === 2) {

                if (args[0] === undefined || args[0] === null) {
                    return args[1];
                }

                return args[0];

            } else if (argc === 3) {

                if (args[0][args[1]] === undefined || args[0][args[1]] === null) {
                    return args[2];
                }

                return args[0][args[1]];
            }
        },

        /**
         * Check is variable function
         *
         * @param functionToCheck
         * @returns {boolean}
         */
        isFunc: function (functionToCheck) {
            return this.type(functionToCheck) === 'function';
        },

        /**
         * Get variable type
         *
         * @param mixedVar
         * @returns {*}
         */
        type: function (mixedVar) {

            if (mixedVar == null) {
                return mixedVar + '';
            }

            // Support: Android<4.0 (functionish RegExp)
            return typeof mixedVar === 'object' ||
            typeof mixedVar === 'function' ? (class2type[toString.call(mixedVar)] || 'object') : typeof mixedVar;
        },

        /**
         * Count all elements in an array, or something in an object
         *
         * @link http://php.net/manual/en/function.count.php
         * @link http://phpjs.org/functions/count/
         *
         * @param variable
         * @param isRecursive bool
         * @returns {number}
         */
        count: function (variable, isRecursive) {

            var $this = this, property, result = 0;

            isRecursive = (typeof isRecursive !== 'undefined' && isRecursive) ? true : false;

            if (variable === false ||
                variable === null ||
                typeof variable === 'undefined'
            ) {
                return 0;

            } else if (variable.constructor !== Array && variable.constructor !== Object) {
                return 1;
            }

            for (property in variable) {

                if (variable.hasOwnProperty(property) && !$this.isFunc(variable[property])) {
                    result++;

                    if (isRecursive && variable[property] &&
                        (
                            variable[property].constructor === Array ||
                            variable[property].constructor === Object
                        )
                    ) {
                        result += this.count(variable[property], true);
                    }
                }
            }

            return result;
        },

        /**
         * Finds whether a variable is a number or a numeric string
         *
         * @link http://php.net/manual/ru/function.in-array.php
         * @link http://phpjs.org/functions/in_array/
         *
         * @param needle
         * @param haystack
         * @param strict
         * @return {Boolean}
         */
        inArray: function (needle, haystack, strict) {

            var found = false, key;

            strict = !!strict;

            for (key in haystack) {
                if ((strict && haystack[key] === needle) || (!strict && haystack[key] == needle)) {
                    found = true;
                    break;
                }
            }

            return found;
        },

        /**
         * Finds whether a variable is a number or a numeric string
         *
         * @link http://php.net/manual/ru/function.is-numeric.php
         * @link http://phpjs.org/functions/is_numeric/
         *
         * @param mixed
         * @returns {boolean}
         */
        isNumeric: function (mixed) {
            return (typeof(mixed) === 'number' || typeof(mixed) === 'string') && mixed !== '' && !isNaN(mixed);
        },

        /**
         * Parse integer from string
         *
         * @link http://phpjs.org/functions/intval/
         *
         * @param mixed
         * @returns {Number}
         */
        toInt: function (mixed, base) {
            var type = typeof mixed;

            base = base || 10;

            if (type === 'boolean') {
                return +mixed;

            } else if (type === 'string') {
                mixed   = mixed.replace(/\s/g, '');
                var tmp = parseInt(mixed, base);
                return (isNaN(tmp) || !isFinite(tmp)) ? 0 : tmp;

            } else if (type === 'number' && isFinite(mixed)) {
                return mixed | 0;

            } else {
                return 0;
            }
        },

        /**
         * Check is variable integer
         *
         * @link http://phpjs.org/functions/is_int/
         *
         * @param mixed
         * @returns {boolean}
         */
        isInt: function (mixed) {
            return mixed === +mixed && isFinite(mixed) && !(mixed % 1);
        },

        /**
         * Parse integer from string
         *
         * @param mixed
         * @returns {Number}
         */
        toFloat: function (mixed) {

            var type = typeof mixed;

            if (type === 'boolean') {
                return +mixed;
            }

            mixed = '' + mixed;
            mixed = mixed.replace(/\s/g, '');
            mixed = mixed.replace(',', '.');
            mixed = (parseFloat(mixed) || 0);
            mixed = this.round(mixed, 9); // hack for numbers like '0.30000000000000004'

            return mixed;
        },

        /**
         * Rounds a float
         *
         * @link http://php.net/manual/en/function.round.php
         * @link http://phpjs.org/functions/round/
         *
         * @param value
         * @param precision
         * @param mode
         * @returns {number}
         */
        round: function (value, precision, mode) {
            // helper variables
            var base, floorNum, isHalf, sign;

            // making sure precision is integer
            precision |= 0;
            base = Math.pow(10, precision);
            value *= base;

            // sign of the number
            sign     = (value > 0) | -(value < 0);
            isHalf   = value % 1 === 0.5 * sign;
            floorNum = Math.floor(value);

            if (isHalf) {
                mode = mode ? mode.toUpperCase() : 'DEFAULT';
                switch (mode) {
                    case 'DOWN':
                        // rounds .5 toward zero
                        value = floorNum + (sign < 0);
                        break;
                    case 'EVEN':
                        // rouds .5 towards the next even integer
                        value = floorNum + (floorNum % 2 * sign);
                        break;
                    case 'ODD':
                        // rounds .5 towards the next odd integer
                        value = floorNum + !(floorNum % 2);
                        break;
                    default:
                        // rounds .5 away from zero
                        value = floorNum + (sign > 0);
                }
            }

            return (isHalf ? value : Math.round(value)) / base;
        },

        /**
         * Generate a random integer
         *
         * @link http://php.net/manual/en/function.rand.php
         * @link http://phpjs.org/functions/rand/
         *
         * @param min
         * @param max
         * @returns {*}
         */
        rand: function (min, max) {
            var $this = this,
                argc  = arguments.length;

            if (argc === 0) {
                min = 0;
                max = 2147483647;

            } else if (argc === 1) {
                throw new Error('Warning: rand() expects exactly 2 parameters, 1 given');

            } else {
                min = $this.toInt(min);
                max = $this.toInt(max);
            }

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

        /**
         * Join array elements with a string
         *
         * @link http://php.net/manual/en/function.implode.php
         * @link http://phpjs.org/functions/implode/
         *
         * @param glue
         * @param pieces
         * @returns {*}
         */
        implode: function (glue, pieces) {

            var i      = '',
                $this  = this,
                retVal = '',
                tGlue  = '';

            if (arguments.length === 1) {
                pieces = glue;
                glue   = '';
            }

            if (typeof pieces === 'object') {
                if ($this.type(pieces) === 'array') {
                    return pieces.join(glue);
                }

                for (i in pieces) {
                    retVal += tGlue + pieces[i];
                    tGlue = glue;
                }

                return retVal;
            }
        },

        /**
         * Split a string by string
         *
         * @link http://phpjs.org/functions/explode/
         * @link http://php.net/manual/en/function.explode.php
         *
         * @param delimiter
         * @param string
         * @param limit
         * @returns {*}
         */
        explode: function (delimiter, string, limit) {

            if (arguments.length < 2 ||
                typeof delimiter === 'undefined' ||
                typeof string === 'undefined'
            ) {
                return null;
            }

            if (delimiter === '' ||
                delimiter === false ||
                delimiter === null
            ) {
                return false;
            }

            if (delimiter === true) {
                delimiter = '1';
            }

            // Here we go...
            delimiter += '';
            string += '';

            var splited = string.split(delimiter);

            if (typeof limit === 'undefined') {
                return splited;
            }

            // Support for limit
            if (limit === 0) {
                limit = 1;
            }

            // Positive limit
            if (limit > 0) {
                if (limit >= splited.length) return splited;
                return splited.slice(0, limit - 1)
                    .concat([splited.slice(limit - 1)
                        .join(delimiter)
                    ]);
            }

            // Negative limit
            if (-limit >= splited.length) return [];

            splited.splice(splited.length + limit);

            return splited;
        },

        /**
         * Strip HTML and PHP tags from a string
         *
         * @link http://php.net/manual/en/function.strip-tags.php
         * @link http://phpjs.org/functions/strip_tags/
         *
         * @param input
         * @param allowed
         * @returns {string}
         */
        stripTags: function (input, allowed) {

            allowed = (((allowed || '') + '')
                .toLowerCase()
                .match(/<[a-z][a-z0-9]*>/g) || [])
                .join('');

            var tags               = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
                commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;

            return input
                .replace(commentsAndPhpTags, '')
                .replace(tags, function ($0, $1) {
                    return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
                });
        },

        /**
         * Alias for console log + backtrace. For debug only. Works only if environment is 'development' (DEBUG = true)
         *
         * @param vars mixed
         * @param name String
         * @param showTrace Boolean
         * @return {Boolean}
         */
        dump: function (vars, name, showTrace) {

            var $this = this;

            if (!this.DEBUG) {
                return false;
            }

            // Get type
            var type    = '',
                varType = $this.type(vars);

            if (varType === 'string' || varType === 'array') {
                type = ' (' + varType + ', ' + $this.count(vars) + ')';
            } else {
                type = ' (' + varType + ')';
            }

            // Wrap in vars quote if string
            if (varType === 'string') {
                vars = '\'' + vars + '\'';
            }

            // Get var name
            if (!name) {
                name = '...' + type + ' = ';
            } else {
                name += type + ' = ';
            }

            // Dump var
            if (window.parent && window.parent.console && window.parent.console.log) {
                window.parent.console.log(name, vars);
            }

            // Show backtrace
            if (showTrace && typeof console.trace !== 'undefined') {
                console.trace();
                return false;
            }

            return false;
        }
    };

})(window, document);
<|endoftext|>


<commit_before>import Utils from './utils';

export default class Color {
  constructor(space, components) {
    this.space      = space;
    this.components = new Map(components);
    this.components.forEach((value, key) => {
      let name = Symbol.keyFor(key);
      Object.defineProperty(this, name, {
        get: () => {
          return function(value = null) {
            if (value === null) {
              return this.get(key);
            }
            this.set(key, value);
            return this;
          }.bind(this);
        }
      });
    });
  }

  has(key) {
    return this.components.has(key);
  }

  get(key) {
    if (!this.has(key)) {
      throw new TypeError();
    }
    return this.components.get(key);
  }

  set(key, value) {
    if (!this.has(key)) {
      throw new TypeError();
    }
    this.components.set(key, value);
    return this;
  }

  keys() {
    return Array.from(this.components.keys());
  }

  values() {
    return Array.from(this.components.values());
  }

  entries() {
    return Array.from(this.components.entries());
  }

  cmy() {
  }

  cmyk() {
  }

  hsl() {
  }

  hsv() {
  }

  rgb() {
  }

  xyz() {
  }

  static from(value) {
    return null;
  }
}
<commit_msg>Added a method that clones instance<commit_after>import Utils from './utils';

export default class Color {
  constructor(space, components) {
    this.space      = space;
    this.components = new Map(components);
    this.components.forEach((value, key) => {
      let name = Symbol.keyFor(key);
      Object.defineProperty(this, name, {
        get: () => {
          return function(value = null) {
            if (value === null) {
              return this.get(key);
            }
            this.set(key, value);
            return this;
          }.bind(this);
        }
      });
    });
  }

  clone() {
  }

  has(key) {
    return this.components.has(key);
  }

  get(key) {
    if (!this.has(key)) {
      throw new TypeError();
    }
    return this.components.get(key);
  }

  set(key, value) {
    if (!this.has(key)) {
      throw new TypeError();
    }
    this.components.set(key, value);
    return this;
  }

  keys() {
    return Array.from(this.components.keys());
  }

  values() {
    return Array.from(this.components.values());
  }

  entries() {
    return Array.from(this.components.entries());
  }

  cmy() {
  }

  cmyk() {
  }

  hsl() {
  }

  hsv() {
  }

  rgb() {
  }

  xyz() {
  }

  static from(value) {
    return null;
  }
}
<|endoftext|>


<commit_before>describe("chorus.pages.SearchIndexPage", function() {
    beforeEach(function() {
        this.query = "50/50";
    });

    it("has a helpId", function() {
        this.page = new chorus.pages.SearchIndexPage(this.query);
        expect(this.page.helpId).toBe("search");
    });

    context("when the search returns with unprocessableEntity", function() {
        beforeEach(function() {
            this.page = new chorus.pages.SearchIndexPage(this.query);
            spyOn(Backbone.history, 'loadUrl');
            this.server.lastFetchFor(this.page.model).failUnprocessableEntity();
        });

        it("shows a nice error popup", function() {
            expect(Backbone.history.loadUrl).toHaveBeenCalledWith('/unprocessableEntity');
            expect(chorus.pageOptions.title).toMatchTranslation('search.bad_entity_type.title');
            expect(chorus.pageOptions.text).toMatchTranslation('search.bad_entity_type.text');
        });
    });

    describe("when searching for all items, across all of chorus", function() {
        beforeEach(function() {
            this.page = new chorus.pages.SearchIndexPage(this.query);
        });

        it("fetches the search results for the given query", function() {
            expect(this.page.search.entityType()).toBe("all");
            expect(this.page.search.searchIn()).toBe("all");
            expect(this.page.search).toHaveBeenFetched();
        });

        describe("when the search result fetch completes", function() {
            beforeEach(function() {
                this.server.completeFetchFor(this.page.search, rspecFixtures.searchResult());
            });

            it("doesn't display the list content details", function() {
                expect(this.page.mainContent.contentDetails).toBeUndefined();
            });

            it("has breadcrumbs", function() {
                expect(this.page.$(".breadcrumbs li:eq(0)")).toContainTranslation('breadcrumbs.home');
                expect((this.page.$(".breadcrumbs li:eq(0) a")).attr("href")).toBe("#/");

                expect(this.page.$(".breadcrumbs li:eq(1) .slug")).toContainTranslation('breadcrumbs.search_results');
            });

            it("has the right title", function() {
                expect(this.page.$(".default_content_header h1")).toContainTranslation("search.index.title", {query: "50/50"});
            });

            it("has a 'Show All Results' link", function() {
                expect(this.page.$('.default_content_header .type .title')).toContainTranslation("search.show");
                expect(this.page.$('.default_content_header .type a')).toContainTranslation("search.type.all");
            });

            it("has filtered result links", function() {
                expect(this.page.$('.default_content_header .type a')).toContainTranslation("search.type.workfile");
                expect(this.page.$('.default_content_header .type a')).toContainTranslation("search.type.hdfs_entry");
                expect(this.page.$('.default_content_header .type a')).toContainTranslation("search.type.dataset");
                expect(this.page.$('.default_content_header .type a')).toContainTranslation("search.type.workspace");
                expect(this.page.$('.default_content_header .type a')).toContainTranslation("search.type.user");
                expect(this.page.$('.default_content_header .type a')).toContainTranslation("search.type.instance");
            });

            describe("filtering by result type", function() {
                beforeEach(function() {
                    spyOn(chorus.router, "navigate");
                    this.page.$('.default_content_header li[data-type="workspace"] a').click();
                });

                it("should navigate to the filtered result type page", function() {
                    expect(this.page.search.entityType()).toBe("workspace");
                    expect(this.page.search.searchIn()).toBe("all");
                    expect(chorus.router.navigate).toHaveBeenCalledWith(this.page.search.showUrl());
                });
            });

            it("has a 'Search in' filter link", function() {
                var searchInMenu = this.page.$(".default_content_header .search_in");
                var searchInOptions = searchInMenu.find(".menu a");
                expect(searchInMenu.find(".chosen")).toContainTranslation("search.in.all");
                expect(searchInMenu.find(".title")).toContainTranslation("search.search_in");
                expect(searchInOptions.length).toBe(2);
                expect(searchInOptions).toContainTranslation("search.in.all");
                expect(searchInOptions).toContainTranslation("search.in.my_workspaces");
            });

            it("navigates to the right page when 'my workspaces' is selected from the 'search in' menu", function() {
                spyOn(chorus.router, "navigate");
                chorus.PageEvents.broadcast("choice:search_in", "my_workspaces");
                expect(this.page.search.entityType()).toBe("all");
                expect(this.page.search.searchIn()).toBe("my_workspaces");
                expect(chorus.router.navigate).toHaveBeenCalledWith(this.page.search.showUrl());
            });

            describe("the workfile section", function() {
                beforeEach(function() {
                    this.workfileLIs = this.page.$(".workfile_list li");
                });

                it("shows a list of search results", function() {
                    expect(this.workfileLIs.length).toBeGreaterThan(0);
                });

                it("selects the first workfile by default", function() {
                    expect(this.workfileLIs.eq(0)).toHaveClass("selected");
                });

                describe("clicking on a workfile search result", function() {
                    beforeEach(function() {
                        this.workfileLIs.eq(3).trigger("click");
                    });

                    it("selects that workfile", function() {
                        expect(this.workfileLIs.eq(3)).toHaveClass("selected");
                    });

                    it("shows that workfile in the sidebar", function() {
                        expect(this.page.sidebar.$(".fileName")).toHaveText("Public");
                    });

                    it("sets the workfile as the selectedItem on the search result", function() {
                        expect(this.page.search.selectedItem).toBe(this.page.search.workfiles().at(3));
                    });
                });
            });

            describe("the workspace section", function() {
                beforeEach(function() {
                    this.workspaceLIs = this.page.$(".workspace_list li");
                });

                it("shows a list of search results", function() {
                    expect(this.workspaceLIs.length).toBeGreaterThan(0);
                });

                describe("clicking on a workspace search result", function() {
                    beforeEach(function() {
                        this.workspaceLIs.eq(1).trigger("click");
                    });

                    it("selects that workspace", function() {
                        expect(this.workspaceLIs.eq(1)).toHaveClass("selected");
                    });

                    it("shows that workspace in the sidebar", function() {
                        expect(this.page.sidebar.$(".info .name")).toHaveText("Private");
                    });

                    it("show the 'add a note' link in the sidebar", function() {
                        expect(this.page.sidebar.$("a[data-dialog='NotesNew']")).toExist();
                    });

                    it("show the 'add an insight' link in the sidebar", function() {
                        expect(this.page.sidebar.$("a[data-dialog='InsightsNew']")).toExist();
                    });
                });
            });

            describe("the dataset section", function() {
                beforeEach(function() {
                    this.datasetLIs = this.page.$(".dataset_list li");
                });

                it("shows a list of search results", function() {
                    expect(this.datasetLIs.length).toBeGreaterThan(0);
                });

                describe("clicking on a tabular data search result", function() {
                    beforeEach(function() {
                        this.datasetLIs.eq(2).trigger("click");
                    });

                    it("selects that tabular data item", function() {
                        expect(this.datasetLIs.eq(2)).toHaveClass("selected");
                    });

                    it("shows the tabular data item in the sidebar", function() {
                        expect(this.page.sidebar.$(".info .name")).toHaveText("typeahead");
                    });

                    it("shows the associate-with-workspace link in the sidebar", function() {
                        expect(this.page.sidebar.$('a.associate')).toExist();
                    });
                });
            });

            describe("the instance section", function() {
                beforeEach(function() {
                    this.instanceLIs = this.page.$(".instance_list li");
                });

                it("shows a list of search results", function() {
                    expect(this.instanceLIs.length).toBe(3);
                });

                describe("clicking on an instance search result", function() {
                    beforeEach(function() {
                        spyOn(this.page.sidebars.instance, "setInstance");
                        this.instanceLIs.eq(0).trigger("click");
                    });

                    it("selects that instance", function() {
                        expect(this.instanceLIs.eq(0)).toHaveClass("selected");
                    });

                    it("shows the instance in the sidebar", function() {
                        expect($(this.page.sidebar.el)).toHaveClass("instance_list_sidebar");
                        expect(this.page.sidebars.instance.setInstance).toHaveBeenCalledWith(this.page.search.instances().at(0));
                    });
                });
            });

            describe("the user section", function() {
                beforeEach(function() {
                    this.users = this.page.search.users();
                    this.userLis = this.page.$(".user_list li");
                });

                it("shows a list of search results", function() {
                    expect(this.userLis.length).toBeGreaterThan(0);
                });

                describe("clicking on a user search result", function() {
                    beforeEach(function() {
                        this.clickedUser = this.users.at(0);
                        this.userLis.eq(0).trigger("click");
                    });

                    it("selects that user", function() {
                        expect(this.userLis.eq(0)).toHaveClass("selected");
                    });

                    it("fetches the user's activities'", function() {
                        expect(this.clickedUser.activities()).toHaveBeenFetched();
                    });

                    describe("when all of the sidebar's fetches complete", function() {
                        beforeEach(function() {
                            this.server.completeFetchFor(this.clickedUser.activities(), []);
                            this.server.completeFetchFor(chorus.models.Config.instance());
                        });

                        it("shows that user in the sidebar", function() {
                            expect(this.page.sidebar.$(".info .full_name")).toHaveText(this.users.at(0).displayName());
                        });
                    });
                });
            });

            describe("the hdfs section", function() {
                beforeEach(function() {
                    this.files = this.page.search.hdfs_entries();
                    this.fileLis = this.page.$(".hdfs_list li");
                });

                it("shows a list of search results", function() {
                    expect(this.fileLis.length).toBe(1);
                });

                describe("clicking on a file search result", function() {
                    beforeEach(function() {
                        this.clickedFile = this.files.at(0);
                        this.fileLis.eq(0).trigger("click");
                    });

                    it("selects that file", function() {
                        expect(this.fileLis.eq(0)).toHaveClass("selected");
                    });

                    it("fetches the file's activities'", function() {
                        expect(this.clickedFile.activities()).toHaveBeenFetched();
                    });

                    describe("when all of the sidebar's fetches complete", function() {
                        beforeEach(function() {
                            this.server.completeFetchFor(this.clickedFile.activities(), []);
                        });

                        it("shows that file in the sidebar", function() {
                            expect(this.page.sidebar.$(".info .name")).toHaveText(this.clickedFile.get('name'));
                        });
                    });
                });
            });

            describe("the other files section", function() {
                beforeEach(function() {
                    this.attachments = this.page.search.attachments();
                    this.attachmentLis = this.page.$(".attachment_list li");
                });

                it("shows a list of search results", function() {
                    expect(this.attachmentLis.length).toBe(7);
                });

                describe("clicking on a search result", function() {
                    beforeEach(function() {
                        this.clickedFile = this.attachments.at(0);
                        this.attachmentLis.eq(0).trigger("click");
                    });

                    it("selects that file", function() {
                        expect(this.attachmentLis.eq(0)).toHaveClass("selected");
                    });

                    it("shows that file in the sidebar", function() {
                        expect(this.page.sidebar.$(".info .name")).toHaveText(this.clickedFile.get("name"));
                    });
                });
            });
        });
    });

    describe("when searching for only workspaces, across all of chorus", function() {
        beforeEach(function() {
            this.page = new chorus.pages.SearchIndexPage("all", "workspace", this.query);
        });

        it("fetches from the right search url", function() {
            expect(this.page.search.entityType()).toBe("workspace");
            expect(this.page.search.searchIn()).toBe("all");
            expect(this.page.search).toHaveBeenFetched();
        });

        describe("when the search result is fetched", function() {
            beforeEach(function() {
                this.server.completeFetchFor(this.page.search, rspecFixtures.searchResult());
            });

            it("selects the 'all of chorus' option in the 'search in' menu", function() {
                expect(this.page.$(".default_content_header .search_in .chosen")).toContainTranslation("search.in.all");
            });

            it("selects the search result type in the menu", function() {
                expect(this.page.$(".default_content_header .type .chosen")).toContainTranslation("search.type.workspace");
            });

            it("has a content details and footer with pagination controls", function() {
                expect(this.page.mainContent.contentDetails).toBeA(chorus.views.ListContentDetails);
                expect(this.page.mainContent.contentDetails.collection).toBe(this.page.search.workspaces());
                expect(this.page.mainContent.contentDetails.options.modelClass).toBe("SearchResult");

                expect(this.page.mainContent.contentFooter).toBeA(chorus.views.ListContentDetails);
                expect(this.page.mainContent.contentFooter.collection).toBe(this.page.search.workspaces());
                expect(this.page.mainContent.contentFooter.options.hideCounts).toBeTruthy();
                expect(this.page.mainContent.contentFooter.options.hideIfNoPagination).toBeTruthy();
                expect(this.page.mainContent.contentFooter.options.modelClass).toBe("SearchResult");
            });
        });
    });

    describe("when searching for all items in the current user's workspaces", function() {
        beforeEach(function() {
            this.page = new chorus.pages.SearchIndexPage("my_workspaces", "all", this.query);
            this.search = this.page.search;
        });

        it("fetches the right search result", function() {
            expect(this.search.searchIn()).toBe("my_workspaces");
            expect(this.search.entityType()).toBe('all');
            expect(this.search).toHaveBeenFetched();
        });

        describe("when the search result is fetched", function() {
            beforeEach(function() {
                this.server.completeFetchFor(this.page.search, rspecFixtures.searchResult());
            });

            it("selects the 'my workspaces' option in the 'search in' menu", function() {
                expect(this.page.$(".default_content_header .search_in .chosen")).toContainTranslation("search.in.my_workspaces");
            });

            it("selects the search result type in the menu", function() {
                expect(this.page.$(".default_content_header .type .chosen")).toContainTranslation("search.type.all");
            });
        });
    });

    describe("when searching only for workfiles in the current user's workspaces", function() {
        beforeEach(function() {
            this.page = new chorus.pages.SearchIndexPage("my_workspaces", "workfile", this.query);
            this.search = this.page.search;
            spyOn(this.search, "workspace").andReturn(rspecFixtures.workspace());
        });

        it("fetches the right search result", function() {
            expect(this.search.searchIn()).toBe("my_workspaces");
            expect(this.search.entityType()).toBe("workfile");
            expect(this.search).toHaveBeenFetched();
        });

        describe("when the search result is fetched", function() {
            beforeEach(function() {
                this.server.completeFetchFor(this.page.search, rspecFixtures.searchResult());
            });

            it("selects the 'my workspaces' option in the 'search in' menu", function() {
                expect(this.page.$(".default_content_header .search_in .chosen")).toContainTranslation("search.in.my_workspaces");
            });

            it("selects the search result type in the menu", function() {
                expect(this.page.$(".default_content_header .type .chosen")).toContainTranslation("search.type.workfile");
            });

            it("doesn't display the list content details", function() {
                expect(this.page.mainContent.contentDetails).toBeUndefined();
            });
        });
    });
});
<commit_msg>Update jasmine fixture reference<commit_after>describe("chorus.pages.SearchIndexPage", function() {
    beforeEach(function() {
        this.query = "50/50";
    });

    it("has a helpId", function() {
        this.page = new chorus.pages.SearchIndexPage(this.query);
        expect(this.page.helpId).toBe("search");
    });

    context("when the search returns with unprocessableEntity", function() {
        beforeEach(function() {
            this.page = new chorus.pages.SearchIndexPage(this.query);
            spyOn(Backbone.history, 'loadUrl');
            this.server.lastFetchFor(this.page.model).failUnprocessableEntity();
        });

        it("shows a nice error popup", function() {
            expect(Backbone.history.loadUrl).toHaveBeenCalledWith('/unprocessableEntity');
            expect(chorus.pageOptions.title).toMatchTranslation('search.bad_entity_type.title');
            expect(chorus.pageOptions.text).toMatchTranslation('search.bad_entity_type.text');
        });
    });

    describe("when searching for all items, across all of chorus", function() {
        beforeEach(function() {
            this.page = new chorus.pages.SearchIndexPage(this.query);
        });

        it("fetches the search results for the given query", function() {
            expect(this.page.search.entityType()).toBe("all");
            expect(this.page.search.searchIn()).toBe("all");
            expect(this.page.search).toHaveBeenFetched();
        });

        describe("when the search result fetch completes", function() {
            beforeEach(function() {
                this.server.completeFetchFor(this.page.search, rspecFixtures.searchResult());
            });

            it("doesn't display the list content details", function() {
                expect(this.page.mainContent.contentDetails).toBeUndefined();
            });

            it("has breadcrumbs", function() {
                expect(this.page.$(".breadcrumbs li:eq(0)")).toContainTranslation('breadcrumbs.home');
                expect((this.page.$(".breadcrumbs li:eq(0) a")).attr("href")).toBe("#/");

                expect(this.page.$(".breadcrumbs li:eq(1) .slug")).toContainTranslation('breadcrumbs.search_results');
            });

            it("has the right title", function() {
                expect(this.page.$(".default_content_header h1")).toContainTranslation("search.index.title", {query: "50/50"});
            });

            it("has a 'Show All Results' link", function() {
                expect(this.page.$('.default_content_header .type .title')).toContainTranslation("search.show");
                expect(this.page.$('.default_content_header .type a')).toContainTranslation("search.type.all");
            });

            it("has filtered result links", function() {
                expect(this.page.$('.default_content_header .type a')).toContainTranslation("search.type.workfile");
                expect(this.page.$('.default_content_header .type a')).toContainTranslation("search.type.hdfs_entry");
                expect(this.page.$('.default_content_header .type a')).toContainTranslation("search.type.dataset");
                expect(this.page.$('.default_content_header .type a')).toContainTranslation("search.type.workspace");
                expect(this.page.$('.default_content_header .type a')).toContainTranslation("search.type.user");
                expect(this.page.$('.default_content_header .type a')).toContainTranslation("search.type.instance");
            });

            describe("filtering by result type", function() {
                beforeEach(function() {
                    spyOn(chorus.router, "navigate");
                    this.page.$('.default_content_header li[data-type="workspace"] a').click();
                });

                it("should navigate to the filtered result type page", function() {
                    expect(this.page.search.entityType()).toBe("workspace");
                    expect(this.page.search.searchIn()).toBe("all");
                    expect(chorus.router.navigate).toHaveBeenCalledWith(this.page.search.showUrl());
                });
            });

            it("has a 'Search in' filter link", function() {
                var searchInMenu = this.page.$(".default_content_header .search_in");
                var searchInOptions = searchInMenu.find(".menu a");
                expect(searchInMenu.find(".chosen")).toContainTranslation("search.in.all");
                expect(searchInMenu.find(".title")).toContainTranslation("search.search_in");
                expect(searchInOptions.length).toBe(2);
                expect(searchInOptions).toContainTranslation("search.in.all");
                expect(searchInOptions).toContainTranslation("search.in.my_workspaces");
            });

            it("navigates to the right page when 'my workspaces' is selected from the 'search in' menu", function() {
                spyOn(chorus.router, "navigate");
                chorus.PageEvents.broadcast("choice:search_in", "my_workspaces");
                expect(this.page.search.entityType()).toBe("all");
                expect(this.page.search.searchIn()).toBe("my_workspaces");
                expect(chorus.router.navigate).toHaveBeenCalledWith(this.page.search.showUrl());
            });

            describe("the workfile section", function() {
                beforeEach(function() {
                    this.workfileLIs = this.page.$(".workfile_list li");
                });

                it("shows a list of search results", function() {
                    expect(this.workfileLIs.length).toBeGreaterThan(0);
                });

                it("selects the first workfile by default", function() {
                    expect(this.workfileLIs.eq(0)).toHaveClass("selected");
                });

                describe("clicking on a workfile search result", function() {
                    beforeEach(function() {
                        this.workfileLIs.eq(3).trigger("click");
                    });

                    it("selects that workfile", function() {
                        expect(this.workfileLIs.eq(3)).toHaveClass("selected");
                    });

                    it("shows that workfile in the sidebar", function() {
                        expect(this.page.sidebar.$(".fileName")).toHaveText("Public");
                    });

                    it("sets the workfile as the selectedItem on the search result", function() {
                        expect(this.page.search.selectedItem).toBe(this.page.search.workfiles().at(3));
                    });
                });
            });

            describe("the workspace section", function() {
                beforeEach(function() {
                    this.workspaceLIs = this.page.$(".workspace_list li");
                });

                it("shows a list of search results", function() {
                    expect(this.workspaceLIs.length).toBeGreaterThan(0);
                });

                describe("clicking on a workspace search result", function() {
                    beforeEach(function() {
                        this.workspaceLIs.eq(1).trigger("click");
                    });

                    it("selects that workspace", function() {
                        expect(this.workspaceLIs.eq(1)).toHaveClass("selected");
                    });

                    it("shows that workspace in the sidebar", function() {
                        expect(this.page.sidebar.$(".info .name")).toHaveText("Private");
                    });

                    it("show the 'add a note' link in the sidebar", function() {
                        expect(this.page.sidebar.$("a[data-dialog='NotesNew']")).toExist();
                    });

                    it("show the 'add an insight' link in the sidebar", function() {
                        expect(this.page.sidebar.$("a[data-dialog='InsightsNew']")).toExist();
                    });
                });
            });

            describe("the dataset section", function() {
                beforeEach(function() {
                    this.datasetLIs = this.page.$(".dataset_list li");
                });

                it("shows a list of search results", function() {
                    expect(this.datasetLIs.length).toBeGreaterThan(0);
                });

                describe("clicking on a tabular data search result", function() {
                    beforeEach(function() {
                        this.datasetLIs.eq(2).trigger("click");
                    });

                    it("selects that tabular data item", function() {
                        expect(this.datasetLIs.eq(2)).toHaveClass("selected");
                    });

                    it("shows the tabular data item in the sidebar", function() {
                        expect(this.page.sidebar.$(".info .name")).toHaveText("typeahead_gpdb_table");
                    });

                    it("shows the associate-with-workspace link in the sidebar", function() {
                        expect(this.page.sidebar.$('a.associate')).toExist();
                    });
                });
            });

            describe("the instance section", function() {
                beforeEach(function() {
                    this.instanceLIs = this.page.$(".instance_list li");
                });

                it("shows a list of search results", function() {
                    expect(this.instanceLIs.length).toBe(3);
                });

                describe("clicking on an instance search result", function() {
                    beforeEach(function() {
                        spyOn(this.page.sidebars.instance, "setInstance");
                        this.instanceLIs.eq(0).trigger("click");
                    });

                    it("selects that instance", function() {
                        expect(this.instanceLIs.eq(0)).toHaveClass("selected");
                    });

                    it("shows the instance in the sidebar", function() {
                        expect($(this.page.sidebar.el)).toHaveClass("instance_list_sidebar");
                        expect(this.page.sidebars.instance.setInstance).toHaveBeenCalledWith(this.page.search.instances().at(0));
                    });
                });
            });

            describe("the user section", function() {
                beforeEach(function() {
                    this.users = this.page.search.users();
                    this.userLis = this.page.$(".user_list li");
                });

                it("shows a list of search results", function() {
                    expect(this.userLis.length).toBeGreaterThan(0);
                });

                describe("clicking on a user search result", function() {
                    beforeEach(function() {
                        this.clickedUser = this.users.at(0);
                        this.userLis.eq(0).trigger("click");
                    });

                    it("selects that user", function() {
                        expect(this.userLis.eq(0)).toHaveClass("selected");
                    });

                    it("fetches the user's activities'", function() {
                        expect(this.clickedUser.activities()).toHaveBeenFetched();
                    });

                    describe("when all of the sidebar's fetches complete", function() {
                        beforeEach(function() {
                            this.server.completeFetchFor(this.clickedUser.activities(), []);
                            this.server.completeFetchFor(chorus.models.Config.instance());
                        });

                        it("shows that user in the sidebar", function() {
                            expect(this.page.sidebar.$(".info .full_name")).toHaveText(this.users.at(0).displayName());
                        });
                    });
                });
            });

            describe("the hdfs section", function() {
                beforeEach(function() {
                    this.files = this.page.search.hdfs_entries();
                    this.fileLis = this.page.$(".hdfs_list li");
                });

                it("shows a list of search results", function() {
                    expect(this.fileLis.length).toBe(1);
                });

                describe("clicking on a file search result", function() {
                    beforeEach(function() {
                        this.clickedFile = this.files.at(0);
                        this.fileLis.eq(0).trigger("click");
                    });

                    it("selects that file", function() {
                        expect(this.fileLis.eq(0)).toHaveClass("selected");
                    });

                    it("fetches the file's activities'", function() {
                        expect(this.clickedFile.activities()).toHaveBeenFetched();
                    });

                    describe("when all of the sidebar's fetches complete", function() {
                        beforeEach(function() {
                            this.server.completeFetchFor(this.clickedFile.activities(), []);
                        });

                        it("shows that file in the sidebar", function() {
                            expect(this.page.sidebar.$(".info .name")).toHaveText(this.clickedFile.get('name'));
                        });
                    });
                });
            });

            describe("the other files section", function() {
                beforeEach(function() {
                    this.attachments = this.page.search.attachments();
                    this.attachmentLis = this.page.$(".attachment_list li");
                });

                it("shows a list of search results", function() {
                    expect(this.attachmentLis.length).toBe(7);
                });

                describe("clicking on a search result", function() {
                    beforeEach(function() {
                        this.clickedFile = this.attachments.at(0);
                        this.attachmentLis.eq(0).trigger("click");
                    });

                    it("selects that file", function() {
                        expect(this.attachmentLis.eq(0)).toHaveClass("selected");
                    });

                    it("shows that file in the sidebar", function() {
                        expect(this.page.sidebar.$(".info .name")).toHaveText(this.clickedFile.get("name"));
                    });
                });
            });
        });
    });

    describe("when searching for only workspaces, across all of chorus", function() {
        beforeEach(function() {
            this.page = new chorus.pages.SearchIndexPage("all", "workspace", this.query);
        });

        it("fetches from the right search url", function() {
            expect(this.page.search.entityType()).toBe("workspace");
            expect(this.page.search.searchIn()).toBe("all");
            expect(this.page.search).toHaveBeenFetched();
        });

        describe("when the search result is fetched", function() {
            beforeEach(function() {
                this.server.completeFetchFor(this.page.search, rspecFixtures.searchResult());
            });

            it("selects the 'all of chorus' option in the 'search in' menu", function() {
                expect(this.page.$(".default_content_header .search_in .chosen")).toContainTranslation("search.in.all");
            });

            it("selects the search result type in the menu", function() {
                expect(this.page.$(".default_content_header .type .chosen")).toContainTranslation("search.type.workspace");
            });

            it("has a content details and footer with pagination controls", function() {
                expect(this.page.mainContent.contentDetails).toBeA(chorus.views.ListContentDetails);
                expect(this.page.mainContent.contentDetails.collection).toBe(this.page.search.workspaces());
                expect(this.page.mainContent.contentDetails.options.modelClass).toBe("SearchResult");

                expect(this.page.mainContent.contentFooter).toBeA(chorus.views.ListContentDetails);
                expect(this.page.mainContent.contentFooter.collection).toBe(this.page.search.workspaces());
                expect(this.page.mainContent.contentFooter.options.hideCounts).toBeTruthy();
                expect(this.page.mainContent.contentFooter.options.hideIfNoPagination).toBeTruthy();
                expect(this.page.mainContent.contentFooter.options.modelClass).toBe("SearchResult");
            });
        });
    });

    describe("when searching for all items in the current user's workspaces", function() {
        beforeEach(function() {
            this.page = new chorus.pages.SearchIndexPage("my_workspaces", "all", this.query);
            this.search = this.page.search;
        });

        it("fetches the right search result", function() {
            expect(this.search.searchIn()).toBe("my_workspaces");
            expect(this.search.entityType()).toBe('all');
            expect(this.search).toHaveBeenFetched();
        });

        describe("when the search result is fetched", function() {
            beforeEach(function() {
                this.server.completeFetchFor(this.page.search, rspecFixtures.searchResult());
            });

            it("selects the 'my workspaces' option in the 'search in' menu", function() {
                expect(this.page.$(".default_content_header .search_in .chosen")).toContainTranslation("search.in.my_workspaces");
            });

            it("selects the search result type in the menu", function() {
                expect(this.page.$(".default_content_header .type .chosen")).toContainTranslation("search.type.all");
            });
        });
    });

    describe("when searching only for workfiles in the current user's workspaces", function() {
        beforeEach(function() {
            this.page = new chorus.pages.SearchIndexPage("my_workspaces", "workfile", this.query);
            this.search = this.page.search;
            spyOn(this.search, "workspace").andReturn(rspecFixtures.workspace());
        });

        it("fetches the right search result", function() {
            expect(this.search.searchIn()).toBe("my_workspaces");
            expect(this.search.entityType()).toBe("workfile");
            expect(this.search).toHaveBeenFetched();
        });

        describe("when the search result is fetched", function() {
            beforeEach(function() {
                this.server.completeFetchFor(this.page.search, rspecFixtures.searchResult());
            });

            it("selects the 'my workspaces' option in the 'search in' menu", function() {
                expect(this.page.$(".default_content_header .search_in .chosen")).toContainTranslation("search.in.my_workspaces");
            });

            it("selects the search result type in the menu", function() {
                expect(this.page.$(".default_content_header .type .chosen")).toContainTranslation("search.type.workfile");
            });

            it("doesn't display the list content details", function() {
                expect(this.page.mainContent.contentDetails).toBeUndefined();
            });
        });
    });
});
<|endoftext|>


<commit_before>'use strict';

var through = require('through2');
var fs = require('fs-extra');
var Gemini = require('gemini/api');
var spawn = require('child_process').spawn;
var path = require('path');
var gutil = require('gulp-util');
var _ = require('lodash');

let removeDuplicates = (arr, newArr = []) => {
  arr.forEach(item => newArr.indexOf(item) < 0 && newArr.push(item));
  return newArr;
};

var phantomProcess;
var runPhantom = function() {
    phantomProcess = spawn('phantomjs',  ['--webdriver', '4444', '--disk-cache', 'false'],  {setsid:true});
    phantomProcess.stdout.pipe(process.stdout);
};

var getGemini = function(options) {

    var geminiOptions = {
      rootUrl: options.rootUrl,
      projectRoot: './',
      gridUrl: 'http://127.0.0.1:4444/wd/hub',
      screenshotsDir: options.gridScreenshotsDir,
      browsers: {
        chrome: {
          browserName: 'chrome',
          version: '37.0'
        }
      },
      windowSize: '1024x768'
    }
    geminiOptions = _.merge(geminiOptions, options.geminiOptions);

    return new Gemini(geminiOptions);
}

var normalize = function (options) {
  if (options.sections && Object.prototype.toString.call(options.sections) !== '[object Array]') {
    options.sections = [options.sections];
  }
  return options;
}

var getTestPaths  = function (options, allTests) {
  if (!allTests) {
    var allTests = require(path.resolve(process.cwd(), options.configDir, './pages-list.js'));
  }

  if (options.sections) {
    // For the given sections
    var tests = options.sections;
    allTests.forEach((section) => {
      options.sections.forEach((sectionToInclude) => {
        if (section.startsWith(sectionToInclude)) {
          tests.push(section);
        }
      });
      tests.sort();
      tests = removeDuplicates(tests);
    });
  } else {
    // For all the sections
    var tests = allTests;
  }

  var testPaths = tests.map((sec) => {
    return path.resolve(options.configDir, './test_' + sec + '.js');
  });
  return testPaths;
}

module.exports.test = function(options) {

  // Gemini does not configurate report dir
  options.reportDir = 'gemini-report';

  options = normalize(options);

  var test = function(file, enc, callback) {

    var gemini = getGemini(options);

    // Run PhantomJs
    runPhantom();

    // Clean report
    fs.removeSync(options.reportDir);

    // Run tests and create reports
    var runTests = function() {

      var testPaths = getTestPaths(options);

      var runTestsPromise = gemini.test(testPaths, {
        reporters: ['html', 'flat'],
        tempDir: options.reportDir
      });
      runTestsPromise.done(result => {
        phantomProcess.kill('SIGTERM');
        spawn('open', [`${options.reportDir}/index.html`])
      });
    };
    // TODO: remake with promises
    setTimeout(runTests, 2000);

  }

  return through.obj(test);

}

module.exports.gather = function(options) {

  options = normalize(options);

  var gather = function(file, enc, callback) {

    // Provide configuration
    var getPages = function(path) {
      var styleguideData = JSON.parse(fs.readFileSync(`${path}/styleguide.json`));
      var examples = [];
      if (options.sections !== false) {
        // If section is in parameters, take only it and its children
        var res = [];
        styleguideData.sections.forEach(section => {
          options.sections.forEach(sectionToInclude => {
            if (section.reference.startsWith(sectionToInclude)) {
              res.push(section)
            }
          });
        });
        styleguideData.sections = res;
      }
      styleguideData.sections.forEach(section => {
        if (!section.markup) { // For sections with markup only
          return;
        }
        if (section.modifiers.length === 0) {
          // Only for the pages with markup
          // Exclude pages
          if (options.excludePages.indexOf(section.reference) !== -1) {
            return;
          }
          examples.push(section.reference);
        } else {
          for(var m = 1;m<=section.modifiers.length;m++) {
            // Exclude pages
            if (options.excludePages.indexOf(`${section.reference}-${m}`) !== -1) {
              continue;
            }
            examples.push(`${section.reference}-${m}`);
          }
        }
      });
      return examples;
    };

    var styleguidePath = file.path;

    var pages = getPages(styleguidePath);

    var currentSections = (function(options) {
      var pagesListPath = path.join(process.cwd(), options.configDir, './pages-list.js');
      if (fs.existsSync(pagesListPath)) {
        return require(pagesListPath);
      } else {
        return [];
      }
    })(options);

    // If sections are define, ADD them into existing file
    if (options.sections) {
      pages = currentSections.concat(pages);
      pages = removeDuplicates(pages);
      pages.sort();
    } else {
      // If sections are not defined, rewrite whole file
    }

    var testSource = fs.readFileSync(path.join(__dirname, './_basic-test.js'), "utf8");
    [
      './_core-test.js',
      './_build-page-obj.js'
    ].forEach((fileName) => {
      var source = fs.readFileSync(path.join(__dirname, fileName), "utf8");
      var file = new gutil.File({
        base: path.join(__dirname),
        cwd: __dirname,
        path: path.join(__dirname, fileName),
        contents: new Buffer(source)
      });
      this.push(file);
    });

    var pagesJsonString = JSON.stringify(pages, null, 4);

    // list of pages
    var file = new gutil.File({
      base: path.join(__dirname),
      cwd: __dirname,
      path: path.join(__dirname, './pages-list.js'),
      contents: new Buffer(`module.exports = ${pagesJsonString}`)
    });
    this.push(file);

    pages.forEach((page) => {
        var coreTestPath = options.customTests && options.customTests[page] ? options.customTests[page] : "./_core-test";
        var content = testSource.replace('"<% EXAMPLES %>"', `["${page}"]`);
        content = content.replace('<% TEST_PATH %>', coreTestPath);

        var file = new gutil.File({
        base: path.join(__dirname),
        cwd: __dirname,
        path: path.join(__dirname, `./test_${page}.js`),
        contents: new Buffer(content)
        });
        this.push(file);
    });

    var gemini = getGemini(options);

    // Run PhantomJs
    runPhantom();

    // Clean screenshot
    if (!options.sections) { // only for full replacement
      fs.removeSync(options.gridScreenshotsDir);
    }

    var runGather = function() {

      var testPaths = getTestPaths(options, pages);

      gemini.gather(testPaths, {
        reporters: ['flat'],
      })
      .done(result => {
        phantomProcess.kill('SIGTERM');
      });
    }
    // TODO: remake with promises
    setTimeout(runGather, 2000);

  };

  return through.obj(gather);

};
<commit_msg>Ignore ssl errors (make it work with https)<commit_after>'use strict';

var through = require('through2');
var fs = require('fs-extra');
var Gemini = require('gemini/api');
var spawn = require('child_process').spawn;
var path = require('path');
var gutil = require('gulp-util');
var _ = require('lodash');

let removeDuplicates = (arr, newArr = []) => {
  arr.forEach(item => newArr.indexOf(item) < 0 && newArr.push(item));
  return newArr;
};

var phantomProcess;
var runPhantom = function() {
    phantomProcess = spawn('phantomjs',  ['--webdriver', '4444', '--disk-cache', 'false', '--ignore-ssl-errors', 'true'],  {setsid:true});
    phantomProcess.stdout.pipe(process.stdout);
};

var getGemini = function(options) {

    var geminiOptions = {
      rootUrl: options.rootUrl,
      projectRoot: './',
      gridUrl: 'http://127.0.0.1:4444/wd/hub',
      screenshotsDir: options.gridScreenshotsDir,
      browsers: {
        chrome: {
          browserName: 'chrome',
          version: '37.0'
        }
      },
      windowSize: '1024x768'
    }
    geminiOptions = _.merge(geminiOptions, options.geminiOptions);

    return new Gemini(geminiOptions);
}

var normalize = function (options) {
  if (options.sections && Object.prototype.toString.call(options.sections) !== '[object Array]') {
    options.sections = [options.sections];
  }
  return options;
}

var getTestPaths  = function (options, allTests) {
  if (!allTests) {
    var allTests = require(path.resolve(process.cwd(), options.configDir, './pages-list.js'));
  }

  if (options.sections) {
    // For the given sections
    var tests = options.sections;
    allTests.forEach((section) => {
      options.sections.forEach((sectionToInclude) => {
        if (section.startsWith(sectionToInclude)) {
          tests.push(section);
        }
      });
      tests.sort();
      tests = removeDuplicates(tests);
    });
  } else {
    // For all the sections
    var tests = allTests;
  }

  var testPaths = tests.map((sec) => {
    return path.resolve(options.configDir, './test_' + sec + '.js');
  });
  return testPaths;
}

module.exports.test = function(options) {

  // Gemini does not configurate report dir
  options.reportDir = 'gemini-report';

  options = normalize(options);

  var test = function(file, enc, callback) {

    var gemini = getGemini(options);

    // Run PhantomJs
    runPhantom();

    // Clean report
    fs.removeSync(options.reportDir);

    // Run tests and create reports
    var runTests = function() {

      var testPaths = getTestPaths(options);

      var runTestsPromise = gemini.test(testPaths, {
        reporters: ['html', 'flat'],
        tempDir: options.reportDir
      });
      runTestsPromise.done(result => {
        phantomProcess.kill('SIGTERM');
        spawn('open', [`${options.reportDir}/index.html`])
      });
    };
    // TODO: remake with promises
    setTimeout(runTests, 2000);

  }

  return through.obj(test);

}

module.exports.gather = function(options) {

  options = normalize(options);

  var gather = function(file, enc, callback) {

    // Provide configuration
    var getPages = function(path) {
      var styleguideData = JSON.parse(fs.readFileSync(`${path}/styleguide.json`));
      var examples = [];
      if (options.sections !== false) {
        // If section is in parameters, take only it and its children
        var res = [];
        styleguideData.sections.forEach(section => {
          options.sections.forEach(sectionToInclude => {
            if (section.reference.startsWith(sectionToInclude)) {
              res.push(section)
            }
          });
        });
        styleguideData.sections = res;
      }
      styleguideData.sections.forEach(section => {
        if (!section.markup) { // For sections with markup only
          return;
        }
        if (section.modifiers.length === 0) {
          // Only for the pages with markup
          // Exclude pages
          if (options.excludePages.indexOf(section.reference) !== -1) {
            return;
          }
          examples.push(section.reference);
        } else {
          for(var m = 1;m<=section.modifiers.length;m++) {
            // Exclude pages
            if (options.excludePages.indexOf(`${section.reference}-${m}`) !== -1) {
              continue;
            }
            examples.push(`${section.reference}-${m}`);
          }
        }
      });
      return examples;
    };

    var styleguidePath = file.path;

    var pages = getPages(styleguidePath);

    var currentSections = (function(options) {
      var pagesListPath = path.join(process.cwd(), options.configDir, './pages-list.js');
      if (fs.existsSync(pagesListPath)) {
        return require(pagesListPath);
      } else {
        return [];
      }
    })(options);

    // If sections are define, ADD them into existing file
    if (options.sections) {
      pages = currentSections.concat(pages);
      pages = removeDuplicates(pages);
      pages.sort();
    } else {
      // If sections are not defined, rewrite whole file
    }

    var testSource = fs.readFileSync(path.join(__dirname, './_basic-test.js'), "utf8");
    [
      './_core-test.js',
      './_build-page-obj.js'
    ].forEach((fileName) => {
      var source = fs.readFileSync(path.join(__dirname, fileName), "utf8");
      var file = new gutil.File({
        base: path.join(__dirname),
        cwd: __dirname,
        path: path.join(__dirname, fileName),
        contents: new Buffer(source)
      });
      this.push(file);
    });

    var pagesJsonString = JSON.stringify(pages, null, 4);

    // list of pages
    var file = new gutil.File({
      base: path.join(__dirname),
      cwd: __dirname,
      path: path.join(__dirname, './pages-list.js'),
      contents: new Buffer(`module.exports = ${pagesJsonString}`)
    });
    this.push(file);

    pages.forEach((page) => {
        var coreTestPath = options.customTests && options.customTests[page] ? options.customTests[page] : "./_core-test";
        var content = testSource.replace('"<% EXAMPLES %>"', `["${page}"]`);
        content = content.replace('<% TEST_PATH %>', coreTestPath);

        var file = new gutil.File({
        base: path.join(__dirname),
        cwd: __dirname,
        path: path.join(__dirname, `./test_${page}.js`),
        contents: new Buffer(content)
        });
        this.push(file);
    });

    var gemini = getGemini(options);

    // Run PhantomJs
    runPhantom();

    // Clean screenshot
    if (!options.sections) { // only for full replacement
      fs.removeSync(options.gridScreenshotsDir);
    }

    var runGather = function() {

      var testPaths = getTestPaths(options, pages);

      gemini.gather(testPaths, {
        reporters: ['flat'],
      })
      .done(result => {
        phantomProcess.kill('SIGTERM');
      });
    }
    // TODO: remake with promises
    setTimeout(runGather, 2000);

  };

  return through.obj(gather);

};
<|endoftext|>