const asar = require('asar') const fs = require('fs') const glob = require('glob') const mkdirp = require('mkdirp') const path = require('path') const {Collector, Instrumenter, Reporter} = require('istanbul') const outputPath = path.join(__dirname, '..', '..', 'out', 'coverage') const libPath = path.join(__dirname, '..', '..', 'lib') // Add unrequired files to the coverage report so all files are present there const addUnrequiredFiles = (coverage) => { const instrumenter = new Instrumenter() const libPath = path.join(__dirname, '..', '..', 'lib') glob.sync('**/*.js', {cwd: libPath}).map(function (relativePath) { return path.join(libPath, relativePath) }).filter(function (filePath) { return coverage[filePath] == null }).forEach(function (filePath) { instrumenter.instrumentSync(fs.readFileSync(filePath, 'utf8'), filePath) // When instrumenting the code, istanbul will give each FunctionDeclaration // a value of 1 in coverState.s,presumably to compensate for function // hoisting. We need to reset this, as the function was not hoisted, as it // was never loaded. Object.keys(instrumenter.coverState.s).forEach(function (key) { instrumenter.coverState.s[key] = 0 }); coverage[filePath] = instrumenter.coverState }) } // Generate a code coverage report in out/coverage/lcov-report exports.generate = () => { const coverage = window.__coverage__ if (coverage == null) return addUnrequiredFiles(coverage) const collector = new Collector() collector.add(coverage) const {ipcRenderer} = require('electron') collector.add(ipcRenderer.sendSync('get-coverage')) const reporter = new Reporter(null, outputPath) reporter.addAll(['text', 'lcov']) reporter.write(collector, true, function () {}) } // Generate an instrumented .asar file for all the files in lib/ and save it // to out/coverage/electron-instrumented.asar exports.instrument = () => { const instrumenter = new Instrumenter() glob.sync('**/*.js', {cwd: libPath}).forEach(function (relativePath) { const rawPath = path.join(libPath, relativePath) const raw = fs.readFileSync(rawPath, 'utf8') const generatedPath = path.join(outputPath, 'lib', relativePath) const generated = instrumenter.instrumentSync(raw, rawPath) mkdirp.sync(path.dirname(generatedPath)) fs.writeFileSync(generatedPath, generated) }) const asarPath = path.join(outputPath, 'electron-instrumented.asar') asar.createPackageWithOptions(path.join(outputPath, 'lib'), asarPath, {}, function (error) { if (error) { console.error(error.stack || error) process.exit(1) } }) }