make[1]: Entering directory `/home/eran/code/hoek' Coverage

Coverage

54%
175
95
80

hoek.js

54%
175
95
80
LineHitsSource
1// Load modules
2
31var Fs = require('fs');
41var Async = require('async');
5
6
7// Declare internals
8
91var internals = {};
10
11
12// Clone object or array
13
141exports.clone = function (obj) {
15
161 if (obj === null ||
17 obj === undefined) {
18
190 return null;
20 }
21
221 var newObj = (obj instanceof Array) ? [] : {};
23
241 for (var i in obj) {
253 if (obj.hasOwnProperty(i)) {
263 if (obj[i] instanceof Date) {
271 newObj[i] = new Date(obj[i].getTime());
28 }
292 else if (obj[i] instanceof RegExp) {
300 var flags = '' + (obj[i].global ? 'g' : '') + (obj[i].ignoreCase ? 'i' : '') + (obj[i].multiline ? 'm' : '') + (obj[i].sticky ? 'y' : '');
310 newObj[i] = new RegExp(obj[i].source, flags);
32 }
332 else if (typeof obj[i] === 'object') {
340 newObj[i] = exports.clone(obj[i]);
35 }
36 else {
372 newObj[i] = obj[i];
38 }
39 }
40 }
41
421 return newObj;
43};
44
45
46// Merge all the properties of source into target, source wins in conflic, and by default null and undefined from source are applied
47
481exports.merge = function (target, source, isNullOverride /* = true */, isMergeArrays /* = true */) {
49
501 if (source) {
511 if (source instanceof Array) {
520 target = (isMergeArrays !== false ? (target || []).concat(source) : source);
53 }
54 else {
551 target = target || {};
56
571 for (var key in source) {
583 if (source.hasOwnProperty(key)) {
593 var value = source[key];
60
613 if (value &&
62 typeof value === 'object') {
63
641 if (value instanceof Date) {
651 target[key] = new Date(value.getTime());
66 }
670 else if (value instanceof RegExp) {
680 var flags = '' + (value.global ? 'g' : '') + (value.ignoreCase ? 'i' : '') + (value.multiline ? 'm' : '') + (value.sticky ? 'y' : '');
690 target[key] = new RegExp(value.source, flags);
70 }
71 else {
720 target[key] = exports.merge(target[key], source[key], isNullOverride, isMergeArrays);
73 }
74 }
75 else {
762 if ((value !== null && value !== undefined) || // Explicit to preserve empty strings
77 isNullOverride !== false) {
78
792 target[key] = value;
80 }
81 }
82 }
83 }
84 }
85 }
86
871 return target;
88};
89
90
91// Apply options to a copy of the defaults
92
931exports.applyToDefaults = function (defaults, options) {
94
950 if (options === false) { // If options is set to false, return null
960 return null;
97 }
98
990 var copy = exports.clone(defaults);
100
1010 if (options === true) { // If options is set to true, use defaults
1020 return copy;
103 }
104
1050 return exports.merge(copy, options, false, false);
106};
107
108
109// Remove duplicate items from array
110
1111exports.unique = function (array, key) {
112
1131 var index = {};
1141 var result = [];
115
1161 for (var i = 0, il = array.length; i < il; ++i) {
1173 if (index[array[i][key]] !== true) {
118
1192 result.push(array[i]);
1202 index[array[i][key]] = true;
121 }
122 }
123
1241 return result;
125};
126
127
128// Convert array into object
129
1301exports.mapToObject = function (array, key) {
131
1323 if (!array) {
1330 return null;
134 }
135
1363 var obj = {};
1373 for (var i = 0, il = array.length; i < il; ++i) {
13814 if (key) {
1393 if (array[i][key]) {
1403 obj[array[i][key]] = true;
141 }
142 }
143 else {
14411 obj[array[i]] = true;
145 }
146 }
147
1483 return obj;
149};
150
151
152// Find the common unique items in two arrays
153
1541exports.intersect = function (array1, array2) {
155
1561 if (!array1 || !array2) {
1570 return [];
158 }
159
1601 var common = [];
1611 var hash = exports.mapToObject(array1);
1621 var found = {};
1631 for (var i = 0, il = array2.length; i < il; ++i) {
1645 if (hash[array2[i]] && !found[array2[i]]) {
1652 common.push(array2[i]);
1662 found[array2[i]] = true;
167 }
168 }
169
1701 return common;
171};
172
173
174// Flatten array
175
1761exports.flatten = function (array, target) {
177
1780 var result = target || [];
179
1800 for (var i = 0, il = array.length; i < il; ++i) {
1810 if (Array.isArray(array[i])) {
1820 exports.flatten(array[i], result);
183 }
184 else {
1850 result.push(array[i]);
186 }
187 }
188
1890 return result;
190};
191
192
193// Remove keys
194
1951exports.removeKeys = function (object, keys) {
196
1971 for (var i = 0, il = keys.length; i < il; i++) {
1981 delete object[keys[i]];
199 }
200};
201
202
203// Inherits a selected set of methods from an object, converting synchronous functions
204// to asynchronous and properly handling errors
205
2061exports.inheritAsync = function (self, obj, keys) {
207
2080 keys = keys || null;
209
2100 for (var i in obj) {
2110 if (obj.hasOwnProperty(i)) {
2120 if (keys instanceof Array &&
213 keys.indexOf(i) < 0) {
214
2150 continue;
216 }
217
2180 self.prototype[i] = (function (fn) {
219
2200 return function (callback) {
221
2220 var err = null;
2230 result = null;
224
2250 try {
2260 result = fn();
227 }
228 catch (err) {
229 // Do nothing
2300 result = null;
231 }
232
2330 callback(err, result);
234 };
235 })(obj[i]);
236 }
237 }
238};
239
240
2411exports.callStack = function (slice) {
242
2430 var v8 = Error.prepareStackTrace;
2440 Error.prepareStackTrace = function (err, stack) {
245
2460 return stack;
247 };
248
2490 var capture = {};
2500 Error.captureStackTrace(capture, arguments.callee);
2510 var stack = capture.stack;
252
2530 Error.prepareStackTrace = v8;
254
2550 var trace = [];
2560 stack.forEach(function (item) {
257
2580 trace.push([item.getFileName(), item.getLineNumber(), item.getColumnNumber(), item.getFunctionName(), item.isConstructor()]);
259 });
260
2610 return trace.slice(1 + (slice || 0));
262};
263
264
2651exports.abort = function (message) {
266
2671 if (process.env.NODE_ENV === 'test') {
2681 throw new Error(message || 'Unknown error');
269 }
270 else {
2710 console.log('ABORT: ' + message + '\n\t' + exports.callStack(1).join('\n\t'));
2720 process.exit(1);
273 }
274};
275
276
2771exports.assert = function (condition, message) {
278
2791 if (!condition) {
2801 exports.abort(message);
281 }
282};
283
284
2851exports.executeRequestHandlers = function (handlers, request, callback) {
286
2870 callback = callback || function () {};
288
2890 if (handlers) {
2900 var list = (handlers instanceof Array ? handlers : [handlers]);
2910 Async.forEachSeries(list, function (func, next) {
292
2930 func(request, next);
294 },
295 function (err) {
296
2970 callback(err);
298 });
299 }
300 else {
3010 callback();
302 }
303};
304
305
3061exports.loadDirModules = function (path, excludeFiles, target) { // target(filename, name, capName)
307
3080 var exclude = {};
3090 for (var i = 0, il = excludeFiles.length; i < il; ++i) {
3100 exclude[excludeFiles[i] + '.js'] = true;
311 }
312
3130 Fs.readdirSync(path).forEach(function (filename) {
314
3150 if (/\.js$/.test(filename) &&
316 !exclude[filename]) {
317
3180 var name = filename.substr(0, filename.lastIndexOf('.'));
3190 var capName = name.charAt(0).toUpperCase() + name.substr(1).toLowerCase();
320
3210 if (typeof target !== 'function') {
3220 target[capName] = require(path + '/' + name);
323 }
324 else {
3250 target(path + '/' + name, name, capName);
326 }
327 }
328 });
329};
330
331
3321exports.rename = function (obj, from, to) {
333
3340 obj[to] = obj[from];
3350 delete obj[from];
336};
337
338
3391exports.Timer = function () {
340
3410 this.reset();
342};
343
344
3451exports.Timer.prototype.reset = function () {
346
3470 this.ts = Date.now();
348};
349
350
3511exports.Timer.prototype.elapsed = function () {
352
3530 return Date.now() - this.ts;
354};
355
356
357// Load and parse package.json process root or given directory
358
3591exports.loadPackage = function (dir) {
360
3610 var result = {};
3620 var filepath = (dir || process.env.PWD) + '/package.json';
3630 if (Fs.existsSync(filepath)) {
3640 try {
3650 result = JSON.parse(Fs.readFileSync(filepath));
366 }
367 catch (e) {}
368 }
369
3700 return result;
371};
372
373
374// Escape string for Regex construction
375
3761exports.escapeRegex = function (string) {
377
378 // Escape ^$.*+-?=!:|\/()[]{},
3791 return string.replace(/[\^\$\.\*\+\-\?\=\!\:\|\\\/\(\)\[\]\{\}\,]/g, '\\$&');
380};
381
382
383// Return an error as first argument of a callback
384
3851exports.toss = function (condition /*, [message], callback */) {
386
3876 var message = (arguments.length === 3 ? arguments[1] : '');
3886 var callback = (arguments.length === 3 ? arguments[2] : arguments[1]);
389
3906 var err = (message instanceof Error ? message : (message ? new Error(message) : (condition instanceof Error ? condition : new Error())));
391
3926 if (condition instanceof Error ||
393 !condition) {
394
3955 return callback(err);
396 }
397};
398
399
400// Base64url (RFC 4648) encode
401
4021exports.base64urlEncode = function (value) {
403
4041 return (new Buffer(value, 'binary')).toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');
405};
406
407
408// Base64url (RFC 4648) decode
409
4101exports.base64urlDecode = function (encoded) {
411
4121 try {
4131 return (new Buffer(encoded.replace(/-/g, '+').replace(/:/g, '/'), 'base64')).toString('binary');
414 }
415 catch (err) {
4160 return err;
417 }
418};
419
420
421// Escape attribute value for use in HTTP header
422
4231exports.escapeHeaderAttribute = function (attribute) {
424
4251 return attribute.replace(/\\/g, '\\\\').replace(/\"/g, '\\"');
426};
427
428
429// Escape string for inclusion in HTML
430
4311internals.htmlEscaped = {
432 '&': '&amp;',
433 '<': '&lt;',
434 '>': '&gt;',
435 '"': '&quot;',
436 "'": '&#x27;',
437 '`': '&#x60;'
438};
439
4401exports.escapeHtml = function (string) {
441
4421 if (!string) {
4430 return '';
444 }
445
4461 if (/[&<>"'`]/.test(string) === false) {
4470 return string;
448 }
449
4501 return string.replace(/[&<>"'`]/g, function (chr) {
451
4526 return internals.htmlEscaped[chr];
453 });
454};
make[1]: Leaving directory `/home/eran/code/hoek'