Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / istanbul / lib / config.js
1 /*
2  Copyright (c) 2013, Yahoo! Inc.  All rights reserved.
3  Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
4  */
5 var path = require('path'),
6     fs = require('fs'),
7     existsSync = fs.existsSync || path.existsSync,
8     CAMEL_PATTERN = /([a-z])([A-Z])/g,
9     YML_PATTERN = /\.ya?ml$/,
10     yaml = require('js-yaml'),
11     defaults = require('./report/common/defaults');
12
13 function defaultConfig(includeBackCompatAttrs) {
14     var ret = {
15         verbose: false,
16         instrumentation: {
17             root: '.',
18             extensions: ['.js'],
19             'default-excludes': true,
20             excludes: [],
21             'embed-source': false,
22             variable: '__coverage__',
23             compact: true,
24             'preserve-comments': false,
25             'complete-copy': false,
26             'save-baseline': false,
27             'baseline-file': './coverage/coverage-baseline.json',
28             'include-all-sources': false,
29             'include-pid': false
30         },
31         reporting: {
32             print: 'summary',
33             reports: [ 'lcov' ],
34             dir: './coverage'
35         },
36         hooks: {
37             'hook-run-in-context': false,
38             'post-require-hook': null,
39             'handle-sigint': false
40         },
41         check: {
42             global: {
43                 statements: 0,
44                 lines: 0,
45                 branches: 0,
46                 functions: 0,
47                 excludes: [] // Currently list of files (root + path). For future, extend to patterns.
48             },
49             each: {
50                 statements: 0,
51                 lines: 0,
52                 branches: 0,
53                 functions: 0,
54                 excludes: []
55             }
56         }
57     };
58     ret.reporting.watermarks = defaults.watermarks();
59     ret.reporting['report-config'] = defaults.defaultReportConfig();
60
61     if (includeBackCompatAttrs) {
62         ret.instrumentation['preload-sources'] = false;
63     }
64
65     return ret;
66 }
67
68 function dasherize(word) {
69     return word.replace(CAMEL_PATTERN, function (match, lch, uch) {
70         return lch + '-' + uch.toLowerCase();
71     });
72 }
73 function isScalar(v) {
74     if (v === null) { return true; }
75     return v !== undefined && !Array.isArray(v) && typeof v !== 'object';
76 }
77
78 function isObject(v) {
79     return typeof v === 'object' && v !== null && !Array.isArray(v);
80 }
81
82 function mergeObjects(explicit, template) {
83
84     var ret = {};
85
86     Object.keys(template).forEach(function (k) {
87         var v1 = template[k],
88             v2 = explicit[k];
89
90         if (Array.isArray(v1)) {
91             ret[k] = Array.isArray(v2) && v2.length > 0 ? v2 : v1;
92         } else if (isObject(v1)) {
93             v2 = isObject(v2) ? v2 : {};
94             ret[k] = mergeObjects(v2, v1);
95         } else {
96             ret[k] = isScalar(v2) ? v2 : v1;
97         }
98     });
99     return ret;
100 }
101
102 function mergeDefaults(explicit, implicit) {
103     return mergeObjects(explicit || {}, implicit);
104 }
105
106 function addMethods() {
107     var args = Array.prototype.slice.call(arguments),
108         cons = args.shift();
109
110     args.forEach(function (arg) {
111         var method = arg,
112             property = dasherize(arg);
113         cons.prototype[method] = function () {
114             return this.config[property];
115         };
116     });
117 }
118
119 /**
120  * Object that returns instrumentation options
121  * @class InstrumentOptions
122  * @module config
123  * @constructor
124  * @param config the instrumentation part of the config object
125  */
126 function InstrumentOptions(config) {
127     if (config['preload-sources']) {
128         console.error('The preload-sources option is deprecated, please use include-all-sources instead.');
129         config['include-all-sources'] = config['preload-sources'];
130     }
131     this.config = config;
132 }
133
134 /**
135  * returns if default excludes should be turned on. Used by the `cover` command.
136  * @method defaultExcludes
137  * @return {Boolean} true if default excludes should be turned on
138  */
139 /**
140  * returns if non-JS files should be copied during instrumentation. Used by the
141  * `instrument` command.
142  * @method completeCopy
143  * @return {Boolean} true if non-JS files should be copied
144  */
145 /**
146  * returns if the source should be embedded in the instrumented code. Used by the
147  * `instrument` command.
148  * @method embedSource
149  * @return {Boolean} true if the source should be embedded in the instrumented code
150  */
151 /**
152  * the coverage variable name to use. Used by the `instrument` command.
153  * @method variable
154  * @return {String} the coverage variable name to use
155  */
156 /**
157  * returns if the output should be compact JS. Used by the `instrument` command.
158  * @method compact
159  * @return {Boolean} true if the output should be compact
160  */
161 /**
162  * returns if comments should be preserved in the generated JS. Used by the
163  * `cover` and `instrument` commands.
164  * @method preserveComments
165  * @return {Boolean} true if comments should be preserved in the generated JS
166  */
167 /**
168  * returns if a zero-coverage baseline file should be written as part of
169  * instrumentation. This allows reporting to display numbers for files that have
170  * no tests. Used by the  `instrument` command.
171  * @method saveBaseline
172  * @return {Boolean} true if a baseline coverage file should be written.
173  */
174 /**
175  * Sets the baseline coverage filename. Used by the  `instrument` command.
176  * @method baselineFile
177  * @return {String} the name of the baseline coverage file.
178  */
179 /**
180  * returns if the coverage filename should include the PID. Used by the  `instrument` command.
181  * @method includePid
182  * @return {Boolean} true to include pid in coverage filename.
183  */
184
185
186 addMethods(InstrumentOptions,
187     'extensions', 'defaultExcludes', 'completeCopy',
188     'embedSource', 'variable', 'compact', 'preserveComments',
189     'saveBaseline', 'baselineFile',
190     'includeAllSources', 'includePid');
191
192 /**
193  * returns the root directory used by istanbul which is typically the root of the
194  * source tree. Used by the `cover` and `report` commands.
195  * @method root
196  * @return {String} the root directory used by istanbul.
197  */
198 InstrumentOptions.prototype.root = function () { return path.resolve(this.config.root); };
199 /**
200  * returns an array of fileset patterns that should be excluded for instrumentation.
201  * Used by the `instrument` and `cover` commands.
202  * @method excludes
203  * @return {Array} an array of fileset patterns that should be excluded for
204  *  instrumentation.
205  */
206 InstrumentOptions.prototype.excludes = function (excludeTests) {
207     var defs;
208     if (this.defaultExcludes()) {
209         defs = [ '**/node_modules/**' ];
210         if (excludeTests) {
211             defs = defs.concat(['**/test/**', '**/tests/**']);
212         }
213         return defs.concat(this.config.excludes);
214     }
215     return this.config.excludes;
216 };
217
218 /**
219  * Object that returns reporting options
220  * @class ReportingOptions
221  * @module config
222  * @constructor
223  * @param config the reporting part of the config object
224  */
225 function ReportingOptions(config) {
226     this.config = config;
227 }
228
229 /**
230  * returns the kind of information to be printed on the console. May be one
231  * of `summary`, `detail`, `both` or `none`. Used by the
232  * `cover` command.
233  * @method print
234  * @return {String} the kind of information to print to the console at the end
235  * of the `cover` command execution.
236  */
237 /**
238  * returns a list of reports that should be generated at the end of a run. Used
239  * by the `cover` and `report` commands.
240  * @method reports
241  * @return {Array} an array of reports that should be produced
242  */
243 /**
244  * returns the directory under which reports should be generated. Used by the
245  * `cover` and `report` commands.
246  *
247  * @method dir
248  * @return {String} the directory under which reports should be generated.
249  */
250 /**
251  * returns an object that has keys that are report format names and values that are objects
252  * containing detailed configuration for each format. Running `istanbul help config`
253  * will give you all the keys per report format that can be overridden.
254  * Used by the `cover` and `report` commands.
255  * @method reportConfig
256  * @return {Object} detailed report configuration per report format.
257  */
258 addMethods(ReportingOptions, 'print', 'reports', 'dir', 'reportConfig');
259
260 function isInvalidMark(v, key) {
261     var prefix = 'Watermark for [' + key + '] :';
262
263     if (v.length !== 2) {
264         return prefix + 'must be an array of length 2';
265     }
266     v[0] = Number(v[0]);
267     v[1] = Number(v[1]);
268
269     if (isNaN(v[0]) || isNaN(v[1])) {
270         return prefix + 'must have valid numbers';
271     }
272     if (v[0] < 0 || v[1] < 0) {
273         return prefix + 'must be positive numbers';
274     }
275     if (v[1] > 100) {
276         return prefix + 'cannot exceed 100';
277     }
278     if (v[1] <= v[0]) {
279         return prefix + 'low must be less than high';
280     }
281     return null;
282 }
283
284 /**
285  * returns the low and high watermarks to be used to designate whether coverage
286  * is `low`, `medium` or `high`. Statements, functions, branches and lines can
287  * have independent watermarks. These are respected by all reports
288  * that color for low, medium and high coverage. See the default configuration for exact syntax
289  * using `istanbul help config`. Used by the `cover` and `report` commands.
290  *
291  * @method watermarks
292  * @return {Object} an object containing low and high watermarks for statements,
293  *  branches, functions and lines.
294  */
295 ReportingOptions.prototype.watermarks = function () {
296     var v = this.config.watermarks,
297         defs = defaults.watermarks(),
298         ret = {};
299
300     Object.keys(defs).forEach(function (k) {
301         var mark = v[k], //it will already be a non-zero length array because of the way the merge works
302             message = isInvalidMark(mark, k);
303         if (message) {
304             console.error(message);
305             ret[k] = defs[k];
306         } else {
307             ret[k] = mark;
308         }
309     });
310     return ret;
311 };
312
313 /**
314  * Object that returns hook options. Note that istanbul does not provide an
315  * option to hook `require`. This is always done by the `cover` command.
316  * @class HookOptions
317  * @module config
318  * @constructor
319  * @param config the hooks part of the config object
320  */
321 function HookOptions(config) {
322     this.config = config;
323 }
324
325 /**
326  * returns if `vm.runInThisContext` needs to be hooked, in addition to the standard
327  * `require` hooks added by istanbul. This should be true for code that uses
328  * RequireJS for example. Used by the `cover` command.
329  * @method hookRunInContext
330  * @return {Boolean} true if `vm.runInThisContext` needs to be hooked for coverage
331  */
332 /**
333  * returns a path to JS file or a dependent module that should be used for
334  * post-processing files after they have been required. See the `yui-istanbul` module for
335  * an example of a post-require hook. This particular hook modifies the yui loader when
336  * that file is required to add istanbul interceptors. Use by the `cover` command
337  *
338  * @method postRequireHook
339  * @return {String} a path to a JS file or the name of a node module that needs
340  * to be used as a `require` post-processor
341  */
342 /**
343  * returns if istanbul needs to add a SIGINT (control-c, usually) handler to
344  * save coverage information. Useful for getting code coverage out of processes
345  * that run forever and need a SIGINT to terminate.
346  * @method handleSigint
347  * @return {Boolean} true if SIGINT needs to be hooked to write coverage information
348  */
349
350 addMethods(HookOptions, 'hookRunInContext', 'postRequireHook', 'handleSigint');
351
352 /**
353  * represents the istanbul configuration and provides sub-objects that can
354  * return instrumentation, reporting and hook options respectively.
355  * Usage
356  * -----
357  *
358  *      var configObj = require('istanbul').config.loadFile();
359  *
360  *      console.log(configObj.reporting.reports());
361  *
362  * @class Configuration
363  * @module config
364  * @param {Object} obj  the base object to use as the configuration
365  * @param {Object} overrides optional - override attributes that are merged into
366  *  the base config
367  * @constructor
368  */
369 function Configuration(obj, overrides) {
370
371     var config = mergeDefaults(obj, defaultConfig(true));
372     if (isObject(overrides)) {
373         config = mergeDefaults(overrides, config);
374     }
375     if (config.verbose) {
376         console.error('Using configuration');
377         console.error('-------------------');
378         console.error(yaml.safeDump(config, { indent: 4, flowLevel: 3 }));
379         console.error('-------------------\n');
380     }
381     this.verbose = config.verbose;
382     this.instrumentation = new InstrumentOptions(config.instrumentation);
383     this.reporting = new ReportingOptions(config.reporting);
384     this.hooks = new HookOptions(config.hooks);
385     this.check = config.check; // Pass raw config sub-object.
386 }
387
388 /**
389  * true if verbose logging is required
390  * @property verbose
391  * @type Boolean
392  */
393 /**
394  * instrumentation options
395  * @property instrumentation
396  * @type InstrumentOptions
397  */
398 /**
399  * reporting options
400  * @property reporting
401  * @type ReportingOptions
402  */
403 /**
404  * hook options
405  * @property hooks
406  * @type HookOptions
407  */
408
409
410 function loadFile(file, overrides) {
411     var defaultConfigFile = path.resolve('.istanbul.yml'),
412         configObject;
413
414     if (file) {
415         if (!existsSync(file)) {
416             throw new Error('Invalid configuration file specified:' + file);
417         }
418     } else {
419         if (existsSync(defaultConfigFile)) {
420             file = defaultConfigFile;
421         }
422     }
423
424     if (file) {
425         console.error('Loading config: ' + file);
426         configObject = file.match(YML_PATTERN) ?
427             yaml.safeLoad(fs.readFileSync(file, 'utf8'), { filename: file }) :
428             require(path.resolve(file));
429     }
430
431     return new Configuration(configObject, overrides);
432 }
433
434 function loadObject(obj, overrides) {
435     return new Configuration(obj, overrides);
436 }
437
438 /**
439  * methods to load the configuration object.
440  * Usage
441  * -----
442  *
443  *      var config = require('istanbul').config,
444  *          configObj = config.loadFile();
445  *
446  *      console.log(configObj.reporting.reports());
447  *
448  * @class Config
449  * @module main
450  * @static
451  */
452 module.exports = {
453     /**
454      * loads the specified configuration file with optional overrides. Throws
455      * when a file is specified and it is not found.
456      * @method loadFile
457      * @static
458      * @param {String} file the file to load. If falsy, the default config file, if present, is loaded.
459      *  If not a default config is used.
460      * @param {Object} overrides - an object with override keys that are merged into the
461      *  config object loaded
462      * @return {Configuration} the config object with overrides applied
463      */
464     loadFile: loadFile,
465     /**
466      * loads the specified configuration object with optional overrides.
467      * @method loadObject
468      * @static
469      * @param {Object} obj the object to use as the base configuration.
470      * @param {Object} overrides - an object with override keys that are merged into the
471      *  config object
472      * @return {Configuration} the config object with overrides applied
473      */
474     loadObject: loadObject,
475     /**
476      * returns the default configuration object. Note that this is a plain object
477      * and not a `Configuration` instance.
478      * @method defaultConfig
479      * @static
480      * @return {Object} an object that represents the default config
481      */
482     defaultConfig: defaultConfig
483 };