This app provides monitoring and information features for the common freifunk user and the technical stuff of a freifunk community.
Code base is taken from a TUM Practical Course project and added here to see if Freifunk Altdorf can use it.
https://www.freifunk-altdorf.de
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
148 lines
5.0 KiB
148 lines
5.0 KiB
/* |
|
Copyright 2012-2015, Yahoo Inc. |
|
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. |
|
*/ |
|
var path = require('path'), |
|
fs = require('fs'), |
|
filesFor = require('./file-matcher').filesFor, |
|
libCoverage = require('istanbul-lib-coverage'), |
|
inputError = require('./input-error'), |
|
isAbsolute = path.isAbsolute || function (file) { |
|
return path.resolve(file) === path.normalize(file); |
|
}; |
|
|
|
function removeFiles(origMap, root, files) { |
|
var filesObj = {}, |
|
ret = libCoverage.createCoverageMap(); |
|
|
|
// Create lookup table. |
|
files.forEach(function (file) { |
|
filesObj[file] = true; |
|
}); |
|
|
|
origMap.files().forEach(function (key) { |
|
// Exclude keys will always be relative, but covObj keys can be absolute or relative |
|
var excludeKey = isAbsolute(key) ? path.relative(root, key) : key; |
|
// Also normalize for files that start with `./`, etc. |
|
excludeKey = path.normalize(excludeKey); |
|
if (filesObj[excludeKey] !== true) { |
|
ret.addFileCoverage(origMap.fileCoverageFor(key)); |
|
} |
|
}); |
|
|
|
return ret; |
|
} |
|
|
|
function run(config, opts, callback) { |
|
|
|
if (!callback && typeof(opts) === 'function') { |
|
callback = opts; |
|
opts = {}; |
|
} |
|
|
|
opts = opts || {}; |
|
|
|
var root = opts.root || config.instrumentation.root() || process.cwd(), |
|
includePattern = opts.include || '**/coverage*.json', |
|
errors = [], |
|
check, |
|
makeMap, |
|
processFiles; |
|
|
|
check = function (name, thresholds, actuals) { |
|
[ |
|
"statements", |
|
"branches", |
|
"lines", |
|
"functions" |
|
].forEach(function (key) { |
|
var actual = actuals[key].pct, |
|
actualUncovered = actuals[key].total - actuals[key].covered, |
|
threshold = thresholds[key]; |
|
|
|
if (threshold < 0) { |
|
if (threshold * -1 < actualUncovered) { |
|
errors.push('ERROR: Uncovered count for ' + key + ' (' + actualUncovered + |
|
') exceeds ' + name + ' threshold (' + -1 * threshold + ')'); |
|
} |
|
} else { |
|
if (actual < threshold) { |
|
errors.push('ERROR: Coverage for ' + key + ' (' + actual + |
|
'%) does not meet ' + name + ' threshold (' + threshold + '%)'); |
|
} |
|
} |
|
}); |
|
}; |
|
|
|
makeMap = function (files, callback) { |
|
var coverageMap = libCoverage.createCoverageMap(); |
|
if (files.length === 0) { |
|
return callback(inputError.create('ERROR: No coverage files found.')); |
|
} |
|
files.forEach(function (file) { |
|
var coverageObject = JSON.parse(fs.readFileSync(file, 'utf8')); |
|
coverageMap.merge(coverageObject); |
|
}); |
|
return callback(null, coverageMap); |
|
}; |
|
|
|
processFiles = function (coverageMap, callback) { |
|
var thresholds = { |
|
global: { |
|
statements: config.check.global.statements || 0, |
|
branches: config.check.global.branches || 0, |
|
lines: config.check.global.lines || 0, |
|
functions: config.check.global.functions || 0, |
|
excludes: config.check.global.excludes || [] |
|
}, |
|
each: { |
|
statements: config.check.each.statements || 0, |
|
branches: config.check.each.branches || 0, |
|
lines: config.check.each.lines || 0, |
|
functions: config.check.each.functions || 0, |
|
excludes: config.check.each.excludes || [] |
|
} |
|
}, |
|
globalResults = removeFiles(coverageMap, root, thresholds.global.excludes), |
|
eachResults = removeFiles(coverageMap, root, thresholds.each.excludes), |
|
finalError; |
|
|
|
if (config.verbose) { |
|
console.error('Compare actuals against thresholds'); |
|
console.error(JSON.stringify({ |
|
global: globalResults, |
|
each: eachResults, |
|
thresholds: thresholds |
|
}, undefined, 4)); |
|
} |
|
|
|
check("global", thresholds.global, globalResults.getCoverageSummary()); |
|
eachResults.files().forEach(function (key) { |
|
var summary = eachResults.fileCoverageFor(key).toSummary(); |
|
check("per-file" + " (" + key + ") ", thresholds.each, summary); |
|
}); |
|
finalError = errors.length === 0 ? null : errors.join("\n"); |
|
return callback(finalError); |
|
}; |
|
|
|
filesFor({ |
|
root: root, |
|
includes: [includePattern] |
|
}, function (err, files) { |
|
if (err) { |
|
return callback(err); |
|
} |
|
makeMap(files, function (err, map) { |
|
if (err) { |
|
return callback(err); |
|
} |
|
return processFiles(map, callback); |
|
}); |
|
}); |
|
} |
|
|
|
module.exports = { |
|
run: run |
|
}; |
|
|
|
|
|
|