forked from cypress-io/code-coverage
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtask.js
118 lines (105 loc) · 3.71 KB
/
task.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
const istanbul = require('istanbul-lib-coverage')
const { join } = require('path')
const { existsSync, mkdirSync, readFileSync, writeFileSync } = require('fs')
const execa = require('execa')
const fs = require('fs')
const { fixSourcePathes } = require('./utils')
const debug = require('debug')('code-coverage')
// these are standard folder and file names used by NYC tools
const processWorkingDirectory = process.cwd()
const outputFolder = '.nyc_output'
const coverageFolder = join(processWorkingDirectory, outputFolder)
const nycFilename = join(coverageFolder, 'out.json')
// there might be custom "nyc" options in the user package.json
// see https://github.com/istanbuljs/nyc#configuring-nyc
// potentially there might be "nyc" options in other configuration files
// it allows, but for now ignore those options
const pkgFilename = join(processWorkingDirectory, 'package.json')
const pkg = fs.existsSync(pkgFilename)
? JSON.parse(fs.readFileSync(pkgFilename, 'utf8'))
: {}
const nycOptions = pkg.nyc || {}
function saveCoverage(coverage) {
if (!existsSync(coverageFolder)) {
mkdirSync(coverageFolder)
debug('created folder %s for output coverage', coverageFolder)
}
writeFileSync(nycFilename, JSON.stringify(coverage, null, 2))
}
module.exports = {
/**
* Clears accumulated code coverage information.
*
* Interactive mode with "cypress open"
* - running a single spec or "Run all specs" needs to reset coverage
* Headless mode with "cypress run"
* - runs EACH spec separately, so we cannot reset the coverage
* or we will lose the coverage from previous specs.
*/
resetCoverage({ isInteractive }) {
if (isInteractive) {
debug('reset code coverage in interactive mode')
const coverageMap = istanbul.createCoverageMap({})
saveCoverage(coverageMap)
}
/*
Else:
in headless mode, assume the coverage file was deleted
before the `cypress run` command was called
example: rm -rf .nyc_output || true
*/
return null
},
/**
* Combines coverage information from single test
* with previously collected coverage.
*
* @param {string} sentCoverage Stringified coverage object sent by the test runner
* @returns {null} Nothing is returned from this task
*/
combineCoverage(sentCoverage) {
const coverage = JSON.parse(sentCoverage)
debug('parsed sent coverage')
fixSourcePathes(coverage)
const previous = existsSync(nycFilename)
? JSON.parse(readFileSync(nycFilename))
: istanbul.createCoverageMap({})
const coverageMap = istanbul.createCoverageMap(previous)
coverageMap.merge(coverage)
saveCoverage(coverageMap)
debug('wrote coverage file %s', nycFilename)
return null
},
/**
* Saves coverage information as a JSON file and calls
* NPM script to generate HTML report
*/
coverageReport() {
if (!existsSync(nycFilename)) {
console.warn('Cannot find coverage file %s', nycFilename)
console.warn('Skipping coverage report')
return null
}
const reportDir = nycOptions['report-dir'] || './coverage'
const reporter = nycOptions['reporter'] || ['lcov', 'clover', 'json']
const reporters = Array.isArray(reporter)
? reporter.map(name => `--reporter=${name}`)
: `--reporter=${reporter}`
// should we generate report via NYC module API?
const command = 'nyc'
const args = [
'report',
'--report-dir',
reportDir,
'--temp-dir',
coverageFolder
].concat(reporters)
debug(
'saving coverage report using command: "%s %s"',
command,
args.join(' ')
)
debug('current working directory is %s', process.cwd())
return execa(command, args, { stdio: 'inherit' })
}
}