Created
June 9, 2016 04:39
-
-
Save maddijoyce/5002eee18138b682aa84c601c2b40197 to your computer and use it in GitHub Desktop.
Istanbul hook loader to be used programatically
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
import { hook, Instrumenter } from 'babel-istanbul'; | |
import { clone } from 'lodash'; | |
let instrumenter = null; | |
const baselineCoverage = {}; | |
export function getCoverageObject() { | |
global.coverage = global.coverage || {}; | |
return global.coverage; | |
} | |
export function getRootMatcher(root) { | |
return function rootMatcher(path) { | |
if (path.indexOf(root) !== 0) { return false; } | |
const file = path.substring(root.length); | |
if (file.indexOf('test') >= 0) { return false; } | |
if (file.indexOf('node_modules') >= 0) { return false; } | |
return true; | |
}; | |
} | |
export function saveBaseline(file) { | |
const coverageObject = getCoverageObject(); | |
if (coverageObject && coverageObject[file]) { | |
const fileCoverage = coverageObject[file]; | |
if (!baselineCoverage[file]) { | |
baselineCoverage[file] = { | |
s: clone(fileCoverage.s), | |
f: clone(fileCoverage.f), | |
b: clone(fileCoverage.b), | |
}; | |
} | |
} | |
} | |
export function restoreBaseline() { | |
const coverageObject = getCoverageObject(); | |
let fileCoverage; | |
let fileBaseline; | |
Object.keys(baselineCoverage).forEach((file) => { | |
fileBaseline = baselineCoverage[file]; | |
if (coverageObject[file]) { | |
fileCoverage = coverageObject[file]; | |
fileCoverage.s = clone(fileBaseline.s); | |
fileCoverage.f = clone(fileBaseline.f); | |
fileCoverage.b = clone(fileBaseline.b); | |
} | |
}); | |
Object.keys(coverageObject).forEach((file) => { | |
if (!baselineCoverage[file]) { | |
delete coverageObject[file]; | |
} | |
}); | |
} | |
export function hookLoader(matcherOrRoot, customOpts) { | |
let matcherFn; | |
let postLoadHook; | |
const opts = customOpts || {}; | |
opts.coverageVariable = 'coverage'; | |
postLoadHook = opts.postLoadHook; | |
if (!(postLoadHook && typeof postLoadHook === 'function')) { | |
postLoadHook = (/* matcher, transformer, verbose */) => ((/* file */) => {}); | |
} | |
delete opts.postLoadHook; | |
if (typeof matcherOrRoot === 'function') { | |
matcherFn = matcherOrRoot; | |
} else if (typeof matcherOrRoot === 'string') { | |
matcherFn = getRootMatcher(matcherOrRoot); | |
} else { | |
throw new Error('Argument was not a function or string'); | |
} | |
if (instrumenter) { return; } | |
instrumenter = new Instrumenter(opts); | |
const transformer = instrumenter.instrumentSync.bind(instrumenter); | |
const postLoadHookFn = postLoadHook(matcherFn, transformer, opts.verbose); | |
hook.hookRequire(matcherFn, transformer, { | |
extensions: opts.extensions, | |
verbose: opts.verbose, | |
postLoadHook(file) { | |
postLoadHookFn(file); | |
saveBaseline(file); | |
}, | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment