forked from cypress-io/code-coverage
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtask.js
133 lines (119 loc) · 4.25 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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
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 || {}
const scripts = pkg.scripts || {}
const DEFAULT_CUSTOM_COVERAGE_SCRIPT_NAME = 'coverage:report'
const customNycReportScript = scripts[DEFAULT_CUSTOM_COVERAGE_SCRIPT_NAME]
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
}
if (customNycReportScript) {
debug(
'saving coverage report using script "%s" from package.json, command: %s',
DEFAULT_CUSTOM_COVERAGE_SCRIPT_NAME,
customNycReportScript
)
debug('current working directory is %s', process.cwd())
return execa('npm', ['run', DEFAULT_CUSTOM_COVERAGE_SCRIPT_NAME], {
stdio: 'inherit'
})
}
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' })
}
}