All files small.js

100% Statements 52/52
100% Branches 20/20
100% Functions 9/9
100% Lines 45/45

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192              1x 1x   1x 1x                       1x 1x   1x                   1x                                 1x 4x 4x 2x 2x                                 1x 3x                                         6x 2x 2x 4x 4x 6x 12x 12x 12x     4x   2x                             7x                           1x 6x 5x   4x 4x   4x                                 1x   11x 4x 1x   3x       7x 7x 14x 4x 2x   5x     1x                    
/**
 * Functions & classes, which content is trivial or|and doesn't require
 * complex implementation (<10 SLOC mostly).
 *
 * @module
 */
 
const os = require("os");
const util = require("util");
 
const _ = require("lodash");
const BaseError = require("es6-error");
 
/**
 * Creates a new instance of `glacejs` error.
 *
 * @memberOf module:glace-utils
 * @class
 * @classdesc A base class for exceptions and errors, which are raised by
 * `glacejs` framework or its plugins. Any `glacejs` exception should be
 * inherited from this class for good style.
 * @arg {string} message - Error message.
 */
const GlaceError = function (message) {
    BaseError.call(this, message);
};
util.inherits(GlaceError, BaseError);
 
/**
 * @memberOf module:glace-utils
 * @property {string} hostname - Host name of machine where `glacejs` framework is
 * launched. Despite of machine hostname can be changed during script execution
 * the probability that hostname will be changed during tests execution is low.
 * That's why it's kept as property and in low case, because hostname is case
 * insensitive.
 */
const hostname = os.hostname().toLowerCase();
 
/**
 * Pick default value for variable among listed values.
 *
 * @memberOf module:glace-utils
 * @function
 * @arg {...*} values - Sequence of variable values.
 * @return {*} First defined value or `null` if no one is defined.
 *
 * @example
 * U.coalesce(); // null
 * U.coalesce(undefined); // null
 * U.coalesce(undefined, 1); // 1
 * U.coalesce(undefined, 1, 2); // 1
 * U.coalesce(null, 1); // null
 */
const coalesce = function () {
    for (const arg of arguments)
        if (typeof arg !== "undefined")
            return arg;
    return null;
};
 
/**
 * Capitalizes the first letter of a string. It doesn't influence to case
 * of other letters.
 *
 * @memberOf module:glace-utils
 * @function
 * @arg {string} string - String to capitalize.
 * @return {string} Capitalized string.
 *
 * @example
 * U.capitalize('hello'); // 'Hello'
 * U.capitalize('Hello'); // 'Hello'
 * U.capitalize('hEllo'); // 'HEllo'
 */
const capitalize = string => {
    return string.charAt(0).toUpperCase() + string.slice(1);
};
 
/**
 * Creates each to each combinations of sets.
 *
 * @memberOf module:glace-utils
 * @function
 * @arg {Array<Array>} l - Array of arrays to combine.
 * @arg {?function} [p] - Function to process element before adding to combination.
 * It passes two arguments:
 * `e` - a new element to add;
 * `c` - assembling combination;
 * By default it just pushes `e` to `c`.
 * @return {Array<Array>} List of combinations.
 *
 * @example
 * each2each([[1, 2], [3, 4]]); // [[1, 3], [1, 4], [2, 3], [2, 4]]
 * each2each([[1, 2], [3, 4]], e => e + 1); // [[2, 4], [2, 5], [3, 4], [3, 5]]
 * each2each([[1, 2], [3, 4]], (e, c) => e + _.sum(c)); // [[1, 4], [1, 5], [2, 5], [2, 6]]
 */
const each2each = (l, p = e => e) => {
    let r = [[]];
    for (const i of l) {
        const t = [];
        for (const j of r) {
            for (const e of i) {
                const c = _.clone(j);
                c.push(p(e, c));
                t.push(c);
            }
        }
        r = t;
    }
    return r;
};
 
/**
 * Splits string to array by delimiter.
 *
 * @memberOf module:glace-utils
 * @function
 * @arg {string} s - String to split.
 * @arg {char} d - String delimiter.
 * @return {array<string>}
 *
 * @example
 * U.splitBy("a, b, c", ","); // ['a', 'b', 'c']
 */
const splitBy = (s, d) => _.filter(_.map(s.split(d), e => e.trim()));
 
/**
 * Checks if text contains words or no.
 *
 * @memberOf module:glace-utils
 * @function
 * @arg {string} string - Original text.
 * @arg {string} words - Checking words.
 * @return {boolean} - `true` if text contains words, `false` otherwise.
 *
 * @example
 * U.textContains("hello world", "hello world"); // true
 */
const textContains = (text, words) => {
    if (!text) return false;
    if (!words) return true;
 
    text = text.toLowerCase();
    words = words.toLowerCase().split(/ +/g);
 
    return _.isEmpty(missedWords(text, words, true));
};
 
/**
 * Detects words if they are missed in text (case-sensitive).
 *
 * @memberOf module:glace-utils
 * @function
 * @arg {string} text - Text where words are looked for. 
 * @arg {string[]} words - Filtered words.
 * @arg {boolean} [firstMissedOnly=false] - Flag to return first missed word only.
 * It reduces searching time and recommended to use if not need to get all missed words.
 * @returns {string[]} - Array of missed words.
 *
 * @example
 * U.missedWords("hello world", ["hello", "man"]); // ["man"]
 */
const missedWords = (text, words, firstMissedOnly = false) => {
 
    if (!text || _.isEmpty(words)) {
        if (firstMissedOnly && !_.isEmpty(words)) {
            return words.slice(0, 1);
        } else {
            return words;
        }
    }
 
    const missed = [];
    for (const word of words) {
        if (text.includes(word)) continue;
        if (firstMissedOnly) return [word];
        missed.push(word);
    }
    return missed;
};
 
module.exports = {
    GlaceError,
    hostname,
    coalesce,
    capitalize,
    each2each,
    splitBy,
    textContains,
    missedWords,
};