-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Release candidate for sustainable coverage approach
- Loading branch information
1 parent
b4faa9e
commit d0fa726
Showing
5 changed files
with
159 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
var fs = require('fs') | ||
var jspm = require('jspm') | ||
var istanbul = require('istanbul') | ||
var rimraf = require('rimraf') | ||
var inlineSourceMap = require('inline-source-map-comment') | ||
|
||
function getFileKey(filename, basePath) { | ||
if(!basePath) throw new Error('Please supply a base path!') | ||
return filename.replace(basePath + '/', '') | ||
} | ||
|
||
function getOSFilePath(filename) { | ||
return filename.replace('file://', '') | ||
} | ||
|
||
function CoveragePreprocessor(basePath, client, reporters, helper) { | ||
// if coverage reporter is not used, do not preprocess the files | ||
if (!helper._.includes(reporters, 'jspm')) { | ||
return function (content, _, done) { | ||
done(content) | ||
} | ||
} | ||
|
||
// create a jspm namespace to pass data to the browsers | ||
if (!client.jspm) client.jspm = {} | ||
// store instrumented sources to be executed by browser | ||
client.jspm.coverageFiles = {} | ||
// store basePath used to generate the key for each source in the obj above | ||
client.jspm.basePath = basePath | ||
// temp folder to store instrumented files for sourcemap remapping | ||
client.jspm.tempDirectory = basePath + '/__karma-jspm-tmp__/' | ||
|
||
// make temp directory | ||
var tempDirectory = client.jspm.tempDirectory | ||
if (!fs.existsSync(tempDirectory)) fs.mkdirSync(tempDirectory) | ||
|
||
// create systemjs hook to allow Istanbul to instrument transpiled sources | ||
var instrument = new istanbul.Instrumenter() | ||
var systemJS = new jspm.Loader() | ||
var systemInstantiate = systemJS.instantiate | ||
// "instantiate" is the hook that provides the transpiled source | ||
systemJS.instantiate = function(load) { | ||
try { | ||
// create a unique key to store the sources of modules for the browser | ||
var fileKey = getFileKey(getOSFilePath(load.address), basePath) | ||
// exclude the dependency modules (i.e. libraries) from instrumentation | ||
if (client.jspm.coverageFiles[fileKey]) { | ||
var filename | ||
// arrange sourcemaps | ||
if (load.metadata.sourceMap) { | ||
// put file's transpiled counterpart in temp folder | ||
filename = tempDirectory + encodeURIComponent(fileKey) | ||
// keeping sourcesContent causes duplicate reports | ||
delete load.metadata.sourceMap.sourcesContent | ||
// this is the file being "instrumented" | ||
load.metadata.sourceMap.file = tempDirectory + encodeURIComponent(fileKey) | ||
// removing "file://" from paths | ||
load.metadata.sourceMap.sources = load.metadata.sourceMap.sources.map( | ||
filename => getOSFilePath(filename) | ||
) | ||
// write transpiled file with an inlined-sourceMap to temp directory | ||
fs.writeFileSync( | ||
filename, | ||
load.source + '\n' + inlineSourceMap(load.metadata.sourceMap) | ||
) | ||
} else { | ||
// keep file as is since it doesn't have a sourcemap to be remaped | ||
filename = getOSFilePath(load.address) | ||
} | ||
// instrument with istanbul | ||
client.jspm.coverageFiles[fileKey] = instrument.instrumentSync( | ||
load.source, | ||
// make the path-like file key into something that can be used as a name | ||
filename | ||
) | ||
} | ||
} catch (err) { | ||
console.log(err) | ||
// remove temp directory since something went wrong | ||
rimraf.sync(tempDirectory) | ||
} | ||
// call the original "instantiate" hook function | ||
return systemInstantiate.call(systemJS, load) | ||
} | ||
|
||
return function (content, file, done) { | ||
// only files to be instrumented pass through here | ||
// store this information to allow "instantiate" to exclude | ||
// dependency modules (i.e. libraries) | ||
client.jspm.coverageFiles[getFileKey(file.path, basePath)] = true | ||
// import modules | ||
systemJS.import(file.path).then(function () { | ||
done(content) | ||
}).catch(function(err) { | ||
console.log(err) | ||
// remove temp directory since something went wrong | ||
rimraf.sync(tempDirectory) | ||
}) | ||
} | ||
} | ||
|
||
CoveragePreprocessor.$inject = ['config.basePath','config.client','config.reporters','helper'] | ||
|
||
// PUBLISH | ||
module.exports = CoveragePreprocessor |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
var fs = require('fs') | ||
var jspm = require('jspm') | ||
var istanbul = require('istanbul') | ||
var rimraf = require('rimraf') | ||
var remapIstanbul = require('remap-istanbul') | ||
var karmaCoverageReport = require('karma-coverage/lib/reporter') | ||
|
||
function CoverageReporter(rootConfig, helper, logger, emitter) { | ||
var config = rootConfig.coverageReporter = rootConfig.coverageReporter || {} | ||
config._onWriteReport = function (collector) { | ||
try { | ||
collector = remapIstanbul.remap(collector.getFinalCoverage()) | ||
} catch(e) { | ||
log.error(e) | ||
} | ||
return collector | ||
} | ||
config._onExit = function (done) { | ||
try { | ||
rimraf.sync(rootConfig.client.jspm.tempDirectory) | ||
} catch(e) { | ||
log.error(e) | ||
} | ||
done() | ||
} | ||
karmaCoverageReport.call(this, rootConfig, helper, logger, emitter) | ||
} | ||
|
||
CoverageReporter.$inject = karmaCoverageReport.$inject | ||
|
||
// PUBLISH | ||
module.exports = CoverageReporter |