yeet
This commit is contained in:
28
node_modules/v8-to-istanbul/lib/branch.js
generated
vendored
Normal file
28
node_modules/v8-to-istanbul/lib/branch.js
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
module.exports = class CovBranch {
|
||||
constructor (startLine, startCol, endLine, endCol, count) {
|
||||
this.startLine = startLine
|
||||
this.startCol = startCol
|
||||
this.endLine = endLine
|
||||
this.endCol = endCol
|
||||
this.count = count
|
||||
}
|
||||
|
||||
toIstanbul () {
|
||||
const location = {
|
||||
start: {
|
||||
line: this.startLine,
|
||||
column: this.startCol
|
||||
},
|
||||
end: {
|
||||
line: this.endLine,
|
||||
column: this.endCol
|
||||
}
|
||||
}
|
||||
return {
|
||||
type: 'branch',
|
||||
line: this.startLine,
|
||||
loc: location,
|
||||
locations: [Object.assign({}, location)]
|
||||
}
|
||||
}
|
||||
}
|
29
node_modules/v8-to-istanbul/lib/function.js
generated
vendored
Normal file
29
node_modules/v8-to-istanbul/lib/function.js
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
module.exports = class CovFunction {
|
||||
constructor (name, startLine, startCol, endLine, endCol, count) {
|
||||
this.name = name
|
||||
this.startLine = startLine
|
||||
this.startCol = startCol
|
||||
this.endLine = endLine
|
||||
this.endCol = endCol
|
||||
this.count = count
|
||||
}
|
||||
|
||||
toIstanbul () {
|
||||
const loc = {
|
||||
start: {
|
||||
line: this.startLine,
|
||||
column: this.startCol
|
||||
},
|
||||
end: {
|
||||
line: this.endLine,
|
||||
column: this.endCol
|
||||
}
|
||||
}
|
||||
return {
|
||||
name: this.name,
|
||||
decl: loc,
|
||||
loc: loc,
|
||||
line: this.startLine
|
||||
}
|
||||
}
|
||||
}
|
34
node_modules/v8-to-istanbul/lib/line.js
generated
vendored
Normal file
34
node_modules/v8-to-istanbul/lib/line.js
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
module.exports = class CovLine {
|
||||
constructor (line, startCol, lineStr) {
|
||||
this.line = line
|
||||
// note that startCol and endCol are absolute positions
|
||||
// within a file, not relative to the line.
|
||||
this.startCol = startCol
|
||||
|
||||
// the line length itself does not include the newline characters,
|
||||
// these are however taken into account when enumerating absolute offset.
|
||||
const matchedNewLineChar = lineStr.match(/\r?\n$/u)
|
||||
const newLineLength = matchedNewLineChar ? matchedNewLineChar[0].length : 0
|
||||
this.endCol = startCol + lineStr.length - newLineLength
|
||||
|
||||
// we start with all lines having been executed, and work
|
||||
// backwards zeroing out lines based on V8 output.
|
||||
this.count = 1
|
||||
|
||||
// set by source.js during parsing, if /* c8 ignore next */ is found.
|
||||
this.ignore = false
|
||||
}
|
||||
|
||||
toIstanbul () {
|
||||
return {
|
||||
start: {
|
||||
line: this.line,
|
||||
column: 0
|
||||
},
|
||||
end: {
|
||||
line: this.line,
|
||||
column: this.endCol - this.startCol
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
198
node_modules/v8-to-istanbul/lib/source.js
generated
vendored
Normal file
198
node_modules/v8-to-istanbul/lib/source.js
generated
vendored
Normal file
@ -0,0 +1,198 @@
|
||||
const CovLine = require('./line')
|
||||
const { GREATEST_LOWER_BOUND, LEAST_UPPER_BOUND } = require('source-map').SourceMapConsumer
|
||||
|
||||
module.exports = class CovSource {
|
||||
constructor (sourceRaw, wrapperLength) {
|
||||
sourceRaw = sourceRaw.trimEnd()
|
||||
this.lines = []
|
||||
this.eof = sourceRaw.length
|
||||
this.shebangLength = getShebangLength(sourceRaw)
|
||||
this.wrapperLength = wrapperLength - this.shebangLength
|
||||
this._buildLines(sourceRaw)
|
||||
}
|
||||
|
||||
_buildLines (source) {
|
||||
let position = 0
|
||||
let ignoreCount = 0
|
||||
for (const [i, lineStr] of source.split(/(?<=\r?\n)/u).entries()) {
|
||||
const line = new CovLine(i + 1, position, lineStr)
|
||||
if (ignoreCount > 0) {
|
||||
line.ignore = true
|
||||
ignoreCount--
|
||||
} else {
|
||||
ignoreCount = this._parseIgnoreNext(lineStr, line)
|
||||
}
|
||||
this.lines.push(line)
|
||||
position += lineStr.length
|
||||
}
|
||||
}
|
||||
|
||||
_parseIgnoreNext (lineStr, line) {
|
||||
const testIgnoreNextLines = lineStr.match(/^\W*\/\* c8 ignore next (?<count>[0-9]+)? *\*\/\W*$/)
|
||||
if (testIgnoreNextLines) {
|
||||
line.ignore = true
|
||||
if (testIgnoreNextLines.groups.count) {
|
||||
return Number(testIgnoreNextLines.groups.count)
|
||||
} else {
|
||||
return 1
|
||||
}
|
||||
} else {
|
||||
if (lineStr.match(/\/\* c8 ignore next \*\//)) {
|
||||
line.ignore = true
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// given a start column and end column in absolute offsets within
|
||||
// a source file (0 - EOF), returns the relative line column positions.
|
||||
offsetToOriginalRelative (sourceMap, startCol, endCol) {
|
||||
const lines = this.lines.filter((line, i) => {
|
||||
return startCol <= line.endCol && endCol >= line.startCol
|
||||
})
|
||||
if (!lines.length) return {}
|
||||
|
||||
const start = originalPositionTryBoth(
|
||||
sourceMap,
|
||||
lines[0].line,
|
||||
Math.max(0, startCol - lines[0].startCol)
|
||||
)
|
||||
let end = originalEndPositionFor(
|
||||
sourceMap,
|
||||
lines[lines.length - 1].line,
|
||||
endCol - lines[lines.length - 1].startCol
|
||||
)
|
||||
|
||||
if (!(start && end)) {
|
||||
return {}
|
||||
}
|
||||
|
||||
if (!(start.source && end.source)) {
|
||||
return {}
|
||||
}
|
||||
|
||||
if (start.source !== end.source) {
|
||||
return {}
|
||||
}
|
||||
|
||||
if (start.line === end.line && start.column === end.column) {
|
||||
end = sourceMap.originalPositionFor({
|
||||
line: lines[lines.length - 1].line,
|
||||
column: endCol - lines[lines.length - 1].startCol,
|
||||
bias: LEAST_UPPER_BOUND
|
||||
})
|
||||
end.column -= 1
|
||||
}
|
||||
|
||||
return {
|
||||
startLine: start.line,
|
||||
relStartCol: start.column,
|
||||
endLine: end.line,
|
||||
relEndCol: end.column
|
||||
}
|
||||
}
|
||||
|
||||
relativeToOffset (line, relCol) {
|
||||
line = Math.max(line, 1)
|
||||
if (this.lines[line - 1] === undefined) return this.eof
|
||||
return Math.min(this.lines[line - 1].startCol + relCol, this.lines[line - 1].endCol)
|
||||
}
|
||||
}
|
||||
|
||||
// this implementation is pulled over from istanbul-lib-sourcemap:
|
||||
// https://github.com/istanbuljs/istanbuljs/blob/master/packages/istanbul-lib-source-maps/lib/get-mapping.js
|
||||
//
|
||||
/**
|
||||
* AST ranges are inclusive for start positions and exclusive for end positions.
|
||||
* Source maps are also logically ranges over text, though interacting with
|
||||
* them is generally achieved by working with explicit positions.
|
||||
*
|
||||
* When finding the _end_ location of an AST item, the range behavior is
|
||||
* important because what we're asking for is the _end_ of whatever range
|
||||
* corresponds to the end location we seek.
|
||||
*
|
||||
* This boils down to the following steps, conceptually, though the source-map
|
||||
* library doesn't expose primitives to do this nicely:
|
||||
*
|
||||
* 1. Find the range on the generated file that ends at, or exclusively
|
||||
* contains the end position of the AST node.
|
||||
* 2. Find the range on the original file that corresponds to
|
||||
* that generated range.
|
||||
* 3. Find the _end_ location of that original range.
|
||||
*/
|
||||
function originalEndPositionFor (sourceMap, line, column) {
|
||||
// Given the generated location, find the original location of the mapping
|
||||
// that corresponds to a range on the generated file that overlaps the
|
||||
// generated file end location. Note however that this position on its
|
||||
// own is not useful because it is the position of the _start_ of the range
|
||||
// on the original file, and we want the _end_ of the range.
|
||||
const beforeEndMapping = originalPositionTryBoth(
|
||||
sourceMap,
|
||||
line,
|
||||
Math.max(column - 1, 1)
|
||||
)
|
||||
|
||||
if (beforeEndMapping.source === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Convert that original position back to a generated one, with a bump
|
||||
// to the right, and a rightward bias. Since 'generatedPositionFor' searches
|
||||
// for mappings in the original-order sorted list, this will find the
|
||||
// mapping that corresponds to the one immediately after the
|
||||
// beforeEndMapping mapping.
|
||||
const afterEndMapping = sourceMap.generatedPositionFor({
|
||||
source: beforeEndMapping.source,
|
||||
line: beforeEndMapping.line,
|
||||
column: beforeEndMapping.column + 1,
|
||||
bias: LEAST_UPPER_BOUND
|
||||
})
|
||||
if (
|
||||
// If this is null, it means that we've hit the end of the file,
|
||||
// so we can use Infinity as the end column.
|
||||
afterEndMapping.line === null ||
|
||||
// If these don't match, it means that the call to
|
||||
// 'generatedPositionFor' didn't find any other original mappings on
|
||||
// the line we gave, so consider the binding to extend to infinity.
|
||||
sourceMap.originalPositionFor(afterEndMapping).line !==
|
||||
beforeEndMapping.line
|
||||
) {
|
||||
return {
|
||||
source: beforeEndMapping.source,
|
||||
line: beforeEndMapping.line,
|
||||
column: Infinity
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the end mapping into the real original position.
|
||||
return sourceMap.originalPositionFor(afterEndMapping)
|
||||
}
|
||||
|
||||
function originalPositionTryBoth (sourceMap, line, column) {
|
||||
const original = sourceMap.originalPositionFor({
|
||||
line,
|
||||
column,
|
||||
bias: GREATEST_LOWER_BOUND
|
||||
})
|
||||
if (original.line === null) {
|
||||
return sourceMap.originalPositionFor({
|
||||
line,
|
||||
column,
|
||||
bias: LEAST_UPPER_BOUND
|
||||
})
|
||||
} else {
|
||||
return original
|
||||
}
|
||||
}
|
||||
|
||||
function getShebangLength (source) {
|
||||
if (source.indexOf('#!') === 0) {
|
||||
const match = source.match(/(?<shebang>#!.*)/)
|
||||
if (match) {
|
||||
return match.groups.shebang.length
|
||||
}
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
238
node_modules/v8-to-istanbul/lib/v8-to-istanbul.js
generated
vendored
Normal file
238
node_modules/v8-to-istanbul/lib/v8-to-istanbul.js
generated
vendored
Normal file
@ -0,0 +1,238 @@
|
||||
const assert = require('assert')
|
||||
const convertSourceMap = require('convert-source-map')
|
||||
const { dirname, isAbsolute, join, resolve } = require('path')
|
||||
const CovBranch = require('./branch')
|
||||
const CovFunction = require('./function')
|
||||
const CovSource = require('./source')
|
||||
const compatError = Error(`requires Node.js ${require('../package.json').engines.node}`)
|
||||
let readFile = () => { throw compatError }
|
||||
try {
|
||||
readFile = require('fs').promises.readFile
|
||||
} catch (_err) {
|
||||
// most likely we're on an older version of Node.js.
|
||||
}
|
||||
const { SourceMapConsumer } = require('source-map')
|
||||
const isOlderNode10 = /^v10\.(([0-9]\.)|(1[0-5]\.))/u.test(process.version)
|
||||
const isNode8 = /^v8\./.test(process.version)
|
||||
|
||||
// Injected when Node.js is loading script into isolate pre Node 10.16.x.
|
||||
// see: https://github.com/nodejs/node/pull/21573.
|
||||
const cjsWrapperLength = isOlderNode10 ? require('module').wrapper[0].length : 0
|
||||
|
||||
module.exports = class V8ToIstanbul {
|
||||
constructor (scriptPath, wrapperLength, sources) {
|
||||
assert(typeof scriptPath === 'string', 'scriptPath must be a string')
|
||||
assert(!isNode8, 'This module does not support node 8 or lower, please upgrade to node 10')
|
||||
this.path = parsePath(scriptPath)
|
||||
this.wrapperLength = wrapperLength === undefined ? cjsWrapperLength : wrapperLength
|
||||
this.sources = sources || {}
|
||||
this.generatedLines = []
|
||||
this.branches = []
|
||||
this.functions = []
|
||||
this.sourceMap = undefined
|
||||
this.source = undefined
|
||||
this.sourceTranspiled = undefined
|
||||
}
|
||||
|
||||
async load () {
|
||||
const rawSource = this.sources.source || await readFile(this.path, 'utf8')
|
||||
const rawSourceMap = this.sources.sourceMap ||
|
||||
// if we find a source-map (either inline, or a .map file) we load
|
||||
// both the transpiled and original source, both of which are used during
|
||||
// the backflips we perform to remap absolute to relative positions.
|
||||
convertSourceMap.fromSource(rawSource) || convertSourceMap.fromMapFileSource(rawSource, dirname(this.path))
|
||||
|
||||
if (rawSourceMap) {
|
||||
if (rawSourceMap.sourcemap.sources.length > 1) {
|
||||
console.warn('v8-to-istanbul: source-mappings from one to many files not yet supported')
|
||||
this.source = new CovSource(rawSource, this.wrapperLength)
|
||||
} else {
|
||||
this._rewritePath(rawSourceMap)
|
||||
this.sourceMap = await new SourceMapConsumer(rawSourceMap.sourcemap)
|
||||
|
||||
let originalRawSource
|
||||
// If the source map has inline source content then it should be here
|
||||
// so use this inline one instead of trying to read the file off disk
|
||||
// Not sure what it means to have an array of more than 1 here so just ignore it
|
||||
// since we wouldn't know how to handle it
|
||||
if (this.sources.sourceMap && this.sources.sourceMap.sourcemap && this.sources.sourceMap.sourcemap.sourcesContent && this.sources.sourceMap.sourcemap.sourcesContent.length === 1) {
|
||||
originalRawSource = this.sources.sourceMap.sourcemap.sourcesContent[0]
|
||||
} else if (this.sources.originalSource) {
|
||||
originalRawSource = this.sources.originalSource
|
||||
} else {
|
||||
originalRawSource = await readFile(this.path, 'utf8')
|
||||
}
|
||||
|
||||
this.source = new CovSource(originalRawSource, this.wrapperLength)
|
||||
this.sourceTranspiled = new CovSource(rawSource, this.wrapperLength)
|
||||
}
|
||||
} else {
|
||||
this.source = new CovSource(rawSource, this.wrapperLength)
|
||||
}
|
||||
}
|
||||
|
||||
_rewritePath (rawSourceMap) {
|
||||
const sourceRoot = rawSourceMap.sourcemap.sourceRoot ? rawSourceMap.sourcemap.sourceRoot.replace('file://', '') : ''
|
||||
const sourcePath = rawSourceMap.sourcemap.sources.length >= 1 ? rawSourceMap.sourcemap.sources[0].replace('file://', '') : rawSourceMap.sourcemap.file
|
||||
const candidatePath = join(sourceRoot, sourcePath)
|
||||
|
||||
if (isAbsolute(candidatePath)) {
|
||||
this.path = candidatePath
|
||||
} else {
|
||||
this.path = resolve(dirname(this.path), candidatePath)
|
||||
}
|
||||
}
|
||||
|
||||
applyCoverage (blocks) {
|
||||
blocks.forEach(block => {
|
||||
block.ranges.forEach((range, i) => {
|
||||
const {
|
||||
startCol,
|
||||
endCol
|
||||
} = this._maybeRemapStartColEndCol(range)
|
||||
const lines = this.source.lines.filter(line => {
|
||||
// Upstream tooling can provide a block with the functionName
|
||||
// (empty-report), this will result in a report that has all
|
||||
// lines zeroed out.
|
||||
if (block.functionName === '(empty-report)') {
|
||||
line.count = 0
|
||||
return true
|
||||
}
|
||||
return startCol <= line.endCol && endCol >= line.startCol
|
||||
})
|
||||
const startLineInstance = lines[0]
|
||||
const endLineInstance = lines[lines.length - 1]
|
||||
|
||||
if (block.isBlockCoverage && lines.length) {
|
||||
// record branches.
|
||||
this.branches.push(new CovBranch(
|
||||
startLineInstance.line,
|
||||
startCol - startLineInstance.startCol,
|
||||
endLineInstance.line,
|
||||
endCol - endLineInstance.startCol,
|
||||
range.count
|
||||
))
|
||||
|
||||
// if block-level granularity is enabled, we we still create a single
|
||||
// CovFunction tracking object for each set of ranges.
|
||||
if (block.functionName && i === 0) {
|
||||
this.functions.push(new CovFunction(
|
||||
block.functionName,
|
||||
startLineInstance.line,
|
||||
startCol - startLineInstance.startCol,
|
||||
endLineInstance.line,
|
||||
endCol - endLineInstance.startCol,
|
||||
range.count
|
||||
))
|
||||
}
|
||||
} else if (block.functionName && lines.length) {
|
||||
// record functions.
|
||||
this.functions.push(new CovFunction(
|
||||
block.functionName,
|
||||
startLineInstance.line,
|
||||
startCol - startLineInstance.startCol,
|
||||
endLineInstance.line,
|
||||
endCol - endLineInstance.startCol,
|
||||
range.count
|
||||
))
|
||||
}
|
||||
|
||||
// record the lines (we record these as statements, such that we're
|
||||
// compatible with Istanbul 2.0).
|
||||
lines.forEach(line => {
|
||||
// make sure branch spans entire line; don't record 'goodbye'
|
||||
// branch in `const foo = true ? 'hello' : 'goodbye'` as a
|
||||
// 0 for line coverage.
|
||||
//
|
||||
// All lines start out with coverage of 1, and are later set to 0
|
||||
// if they are not invoked; line.ignore prevents a line from being
|
||||
// set to 0, and is set if the special comment /* c8 ignore next */
|
||||
// is used.
|
||||
if (startCol <= line.startCol && endCol >= line.endCol && !line.ignore) {
|
||||
line.count = range.count
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
_maybeRemapStartColEndCol (range) {
|
||||
let startCol = Math.max(0, range.startOffset - this.source.wrapperLength)
|
||||
let endCol = Math.min(this.source.eof, range.endOffset - this.source.wrapperLength)
|
||||
|
||||
if (this.sourceMap) {
|
||||
startCol = Math.max(0, range.startOffset - this.sourceTranspiled.wrapperLength)
|
||||
endCol = Math.min(this.sourceTranspiled.eof, range.endOffset - this.sourceTranspiled.wrapperLength)
|
||||
|
||||
const { startLine, relStartCol, endLine, relEndCol } = this.sourceTranspiled.offsetToOriginalRelative(
|
||||
this.sourceMap,
|
||||
startCol,
|
||||
endCol
|
||||
)
|
||||
|
||||
// next we convert these relative positions back to absolute positions
|
||||
// in the original source (which is the format expected in the next step).
|
||||
startCol = this.source.relativeToOffset(startLine, relStartCol)
|
||||
endCol = this.source.relativeToOffset(endLine, relEndCol)
|
||||
}
|
||||
|
||||
return {
|
||||
startCol,
|
||||
endCol
|
||||
}
|
||||
}
|
||||
|
||||
toIstanbul () {
|
||||
const istanbulInner = Object.assign(
|
||||
{ path: this.path },
|
||||
this._statementsToIstanbul(),
|
||||
this._branchesToIstanbul(),
|
||||
this._functionsToIstanbul()
|
||||
)
|
||||
const istanbulOuter = {}
|
||||
istanbulOuter[this.path] = istanbulInner
|
||||
return istanbulOuter
|
||||
}
|
||||
|
||||
_statementsToIstanbul () {
|
||||
const statements = {
|
||||
statementMap: {},
|
||||
s: {}
|
||||
}
|
||||
this.source.lines.forEach((line, index) => {
|
||||
statements.statementMap[`${index}`] = line.toIstanbul()
|
||||
statements.s[`${index}`] = line.count
|
||||
})
|
||||
return statements
|
||||
}
|
||||
|
||||
_branchesToIstanbul () {
|
||||
const branches = {
|
||||
branchMap: {},
|
||||
b: {}
|
||||
}
|
||||
this.branches.forEach((branch, index) => {
|
||||
const ignore = this.source.lines[branch.startLine - 1].ignore
|
||||
branches.branchMap[`${index}`] = branch.toIstanbul()
|
||||
branches.b[`${index}`] = [ignore ? 1 : branch.count]
|
||||
})
|
||||
return branches
|
||||
}
|
||||
|
||||
_functionsToIstanbul () {
|
||||
const functions = {
|
||||
fnMap: {},
|
||||
f: {}
|
||||
}
|
||||
this.functions.forEach((fn, index) => {
|
||||
const ignore = this.source.lines[fn.startLine - 1].ignore
|
||||
functions.fnMap[`${index}`] = fn.toIstanbul()
|
||||
functions.f[`${index}`] = ignore ? 1 : fn.count
|
||||
})
|
||||
return functions
|
||||
}
|
||||
}
|
||||
|
||||
function parsePath (scriptPath) {
|
||||
return scriptPath.replace('file://', '')
|
||||
}
|
Reference in New Issue
Block a user