diff options
Diffstat (limited to 'vnfmarket/src/main/webapp/vnfmarket/node_modules/istanbul/lib/object-utils.js')
-rw-r--r-- | vnfmarket/src/main/webapp/vnfmarket/node_modules/istanbul/lib/object-utils.js | 425 |
1 files changed, 425 insertions, 0 deletions
diff --git a/vnfmarket/src/main/webapp/vnfmarket/node_modules/istanbul/lib/object-utils.js b/vnfmarket/src/main/webapp/vnfmarket/node_modules/istanbul/lib/object-utils.js new file mode 100644 index 00000000..ab88ae0b --- /dev/null +++ b/vnfmarket/src/main/webapp/vnfmarket/node_modules/istanbul/lib/object-utils.js @@ -0,0 +1,425 @@ +/* + Copyright (c) 2012, Yahoo! Inc. All rights reserved. + Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. + */ + +/** + * utility methods to process coverage objects. A coverage object has the following + * format. + * + * { + * "/path/to/file1.js": { file1 coverage }, + * "/path/to/file2.js": { file2 coverage } + * } + * + * The internals of the file coverage object are intentionally not documented since + * it is not a public interface. + * + * *Note:* When a method of this module has the word `File` in it, it will accept + * one of the sub-objects of the main coverage object as an argument. Other + * methods accept the higher level coverage object with multiple keys. + * + * Works on `node` as well as the browser. + * + * Usage on nodejs + * --------------- + * + * var objectUtils = require('istanbul').utils; + * + * Usage in a browser + * ------------------ + * + * Load this file using a `script` tag or other means. This will set `window.coverageUtils` + * to this module's exports. + * + * @class ObjectUtils + * @module main + * @static + */ +(function (isNode) { + /** + * adds line coverage information to a file coverage object, reverse-engineering + * it from statement coverage. The object passed in is updated in place. + * + * Note that if line coverage information is already present in the object, + * it is not recomputed. + * + * @method addDerivedInfoForFile + * @static + * @param {Object} fileCoverage the coverage object for a single file + */ + function addDerivedInfoForFile(fileCoverage) { + var statementMap = fileCoverage.statementMap, + statements = fileCoverage.s, + lineMap; + + if (!fileCoverage.l) { + fileCoverage.l = lineMap = {}; + Object.keys(statements).forEach(function (st) { + var line = statementMap[st].start.line, + count = statements[st], + prevVal = lineMap[line]; + if (count === 0 && statementMap[st].skip) { count = 1; } + if (typeof prevVal === 'undefined' || prevVal < count) { + lineMap[line] = count; + } + }); + } + } + /** + * adds line coverage information to all file coverage objects. + * + * @method addDerivedInfo + * @static + * @param {Object} coverage the coverage object + */ + function addDerivedInfo(coverage) { + Object.keys(coverage).forEach(function (k) { + addDerivedInfoForFile(coverage[k]); + }); + } + /** + * removes line coverage information from all file coverage objects + * @method removeDerivedInfo + * @static + * @param {Object} coverage the coverage object + */ + function removeDerivedInfo(coverage) { + Object.keys(coverage).forEach(function (k) { + delete coverage[k].l; + }); + } + + function percent(covered, total) { + var tmp; + if (total > 0) { + tmp = 1000 * 100 * covered / total + 5; + return Math.floor(tmp / 10) / 100; + } else { + return 100.00; + } + } + + function computeSimpleTotals(fileCoverage, property, mapProperty) { + var stats = fileCoverage[property], + map = mapProperty ? fileCoverage[mapProperty] : null, + ret = { total: 0, covered: 0, skipped: 0 }; + + Object.keys(stats).forEach(function (key) { + var covered = !!stats[key], + skipped = map && map[key].skip; + ret.total += 1; + if (covered || skipped) { + ret.covered += 1; + } + if (!covered && skipped) { + ret.skipped += 1; + } + }); + ret.pct = percent(ret.covered, ret.total); + return ret; + } + + function computeBranchTotals(fileCoverage) { + var stats = fileCoverage.b, + branchMap = fileCoverage.branchMap, + ret = { total: 0, covered: 0, skipped: 0 }; + + Object.keys(stats).forEach(function (key) { + var branches = stats[key], + map = branchMap[key], + covered, + skipped, + i; + for (i = 0; i < branches.length; i += 1) { + covered = branches[i] > 0; + skipped = map.locations && map.locations[i] && map.locations[i].skip; + if (covered || skipped) { + ret.covered += 1; + } + if (!covered && skipped) { + ret.skipped += 1; + } + } + ret.total += branches.length; + }); + ret.pct = percent(ret.covered, ret.total); + return ret; + } + /** + * returns a blank summary metrics object. A metrics object has the following + * format. + * + * { + * lines: lineMetrics, + * statements: statementMetrics, + * functions: functionMetrics, + * branches: branchMetrics + * linesCovered: lineCoveredCount + * } + * + * Each individual metric object looks as follows: + * + * { + * total: n, + * covered: m, + * pct: percent + * } + * + * @method blankSummary + * @static + * @return {Object} a blank metrics object + */ + function blankSummary() { + return { + lines: { + total: 0, + covered: 0, + skipped: 0, + pct: 'Unknown' + }, + statements: { + total: 0, + covered: 0, + skipped: 0, + pct: 'Unknown' + }, + functions: { + total: 0, + covered: 0, + skipped: 0, + pct: 'Unknown' + }, + branches: { + total: 0, + covered: 0, + skipped: 0, + pct: 'Unknown' + }, + linesCovered: {} + }; + } + /** + * returns the summary metrics given the coverage object for a single file. See `blankSummary()` + * to understand the format of the returned object. + * + * @method summarizeFileCoverage + * @static + * @param {Object} fileCoverage the coverage object for a single file. + * @return {Object} the summary metrics for the file + */ + function summarizeFileCoverage(fileCoverage) { + var ret = blankSummary(); + addDerivedInfoForFile(fileCoverage); + ret.lines = computeSimpleTotals(fileCoverage, 'l'); + ret.functions = computeSimpleTotals(fileCoverage, 'f', 'fnMap'); + ret.statements = computeSimpleTotals(fileCoverage, 's', 'statementMap'); + ret.branches = computeBranchTotals(fileCoverage); + ret.linesCovered = fileCoverage.l; + return ret; + } + /** + * merges two instances of file coverage objects *for the same file* + * such that the execution counts are correct. + * + * @method mergeFileCoverage + * @static + * @param {Object} first the first file coverage object for a given file + * @param {Object} second the second file coverage object for the same file + * @return {Object} an object that is a result of merging the two. Note that + * the input objects are not changed in any way. + */ + function mergeFileCoverage(first, second) { + var ret = JSON.parse(JSON.stringify(first)), + i; + + delete ret.l; //remove derived info + + Object.keys(second.s).forEach(function (k) { + ret.s[k] += second.s[k]; + }); + Object.keys(second.f).forEach(function (k) { + ret.f[k] += second.f[k]; + }); + Object.keys(second.b).forEach(function (k) { + var retArray = ret.b[k], + secondArray = second.b[k]; + for (i = 0; i < retArray.length; i += 1) { + retArray[i] += secondArray[i]; + } + }); + + return ret; + } + /** + * merges multiple summary metrics objects by summing up the `totals` and + * `covered` fields and recomputing the percentages. This function is generic + * and can accept any number of arguments. + * + * @method mergeSummaryObjects + * @static + * @param {Object} summary... multiple summary metrics objects + * @return {Object} the merged summary metrics + */ + function mergeSummaryObjects() { + var ret = blankSummary(), + args = Array.prototype.slice.call(arguments), + keys = ['lines', 'statements', 'branches', 'functions'], + increment = function (obj) { + if (obj) { + keys.forEach(function (key) { + ret[key].total += obj[key].total; + ret[key].covered += obj[key].covered; + ret[key].skipped += obj[key].skipped; + }); + + // keep track of all lines we have coverage for. + Object.keys(obj.linesCovered).forEach(function (key) { + if (!ret.linesCovered[key]) { + ret.linesCovered[key] = obj.linesCovered[key]; + } else { + ret.linesCovered[key] += obj.linesCovered[key]; + } + }); + } + }; + args.forEach(function (arg) { + increment(arg); + }); + keys.forEach(function (key) { + ret[key].pct = percent(ret[key].covered, ret[key].total); + }); + + return ret; + } + /** + * returns the coverage summary for a single coverage object. This is + * wrapper over `summarizeFileCoverage` and `mergeSummaryObjects` for + * the common case of a single coverage object + * @method summarizeCoverage + * @static + * @param {Object} coverage the coverage object + * @return {Object} summary coverage metrics across all files in the coverage object + */ + function summarizeCoverage(coverage) { + var fileSummary = []; + Object.keys(coverage).forEach(function (key) { + fileSummary.push(summarizeFileCoverage(coverage[key])); + }); + return mergeSummaryObjects.apply(null, fileSummary); + } + + /** + * makes the coverage object generated by this library yuitest_coverage compatible. + * Note that this transformation is lossy since the returned object will not have + * statement and branch coverage. + * + * @method toYUICoverage + * @static + * @param {Object} coverage The `istanbul` coverage object + * @return {Object} a coverage object in `yuitest_coverage` format. + */ + function toYUICoverage(coverage) { + var ret = {}; + + addDerivedInfo(coverage); + + Object.keys(coverage).forEach(function (k) { + var fileCoverage = coverage[k], + lines = fileCoverage.l, + functions = fileCoverage.f, + fnMap = fileCoverage.fnMap, + o; + + o = ret[k] = { + lines: {}, + calledLines: 0, + coveredLines: 0, + functions: {}, + calledFunctions: 0, + coveredFunctions: 0 + }; + Object.keys(lines).forEach(function (k) { + o.lines[k] = lines[k]; + o.coveredLines += 1; + if (lines[k] > 0) { + o.calledLines += 1; + } + }); + Object.keys(functions).forEach(function (k) { + var name = fnMap[k].name + ':' + fnMap[k].line; + o.functions[name] = functions[k]; + o.coveredFunctions += 1; + if (functions[k] > 0) { + o.calledFunctions += 1; + } + }); + }); + return ret; + } + + /** + * Creates new file coverage object with incremented hits count + * on skipped statements, branches and functions + * + * @method incrementIgnoredTotals + * @static + * @param {Object} cov File coverage object + * @return {Object} New file coverage object + */ + function incrementIgnoredTotals(cov) { + //TODO: This may be slow in the browser and may break in older browsers + // Look into using a library that works in Node and the browser + var fileCoverage = JSON.parse(JSON.stringify(cov)); + + [ + {mapKey: 'statementMap', hitsKey: 's'}, + {mapKey: 'branchMap', hitsKey: 'b'}, + {mapKey: 'fnMap', hitsKey: 'f'} + ].forEach(function (keys) { + Object.keys(fileCoverage[keys.mapKey]) + .forEach(function (key) { + var map = fileCoverage[keys.mapKey][key]; + var hits = fileCoverage[keys.hitsKey]; + + if (keys.mapKey === 'branchMap') { + var locations = map.locations; + + locations.forEach(function (location, index) { + if (hits[key][index] === 0 && location.skip) { + hits[key][index] = 1; + } + }); + + return; + } + + if (hits[key] === 0 && map.skip) { + hits[key] = 1; + } + }); + }); + + return fileCoverage; + } + + var exportables = { + addDerivedInfo: addDerivedInfo, + addDerivedInfoForFile: addDerivedInfoForFile, + removeDerivedInfo: removeDerivedInfo, + blankSummary: blankSummary, + summarizeFileCoverage: summarizeFileCoverage, + summarizeCoverage: summarizeCoverage, + mergeFileCoverage: mergeFileCoverage, + mergeSummaryObjects: mergeSummaryObjects, + toYUICoverage: toYUICoverage, + incrementIgnoredTotals: incrementIgnoredTotals + }; + + /* istanbul ignore else: windows */ + if (isNode) { + module.exports = exportables; + } else { + window.coverageUtils = exportables; + } +}(typeof module !== 'undefined' && typeof module.exports !== 'undefined' && typeof exports !== 'undefined')); |