Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
bcoe committed Apr 23, 2019
1 parent 27d9304 commit 48ee422
Show file tree
Hide file tree
Showing 4 changed files with 216 additions and 151 deletions.
8 changes: 4 additions & 4 deletions lib/branch.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ module.exports = class CovBranch {
toIstanbul () {
const location = {
start: {
line: this.startLine.line,
column: this.startCol - this.startLine.startCol
line: this.startLine,
column: this.startCol
},
end: {
line: this.endLine.line,
column: this.endCol - this.endLine.startCol
line: this.endLine,
column: this.endCol
}
}
return {
Expand Down
10 changes: 5 additions & 5 deletions lib/function.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ module.exports = class CovFunction {
toIstanbul () {
const loc = {
start: {
line: this.startLine.line,
column: this.startCol - this.startLine.startCol
line: this.startLine,
column: this.startCol
},
end: {
line: this.endLine.line,
column: this.endCol - this.endLine.startCol
line: this.endLine,
column: this.endCol
}
}
return {
name: this.name,
decl: loc,
loc: loc,
line: this.startLine.line
line: this.startLine
}
}
}
132 changes: 100 additions & 32 deletions lib/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const CovFunction = require('./function')
const { dirname } = require('path')
const { readFileSync } = require('fs')
const { SourceMapConsumer } = require('source-map')
const { GREATEST_LOWER_BOUND, LOWEST_UPPER_BOUND } = SourceMapConsumer

const isNode10 = !!process.version.match(/^v10/)

Expand All @@ -19,31 +20,40 @@ module.exports = class CovScript {
this.path = parsePath(scriptPath)
this.wrapperLength = wrapperLength === undefined ? cjsWrapperLength : wrapperLength
this.lines = []
this.generatedLines = []
this.branches = []
this.functions = []
this.eof = -1
this.sourceMap = undefined
}
async load () {
this.source = readFileSync(this.path, 'utf8')
const source = readFileSync(this.path, 'utf8')
const shebangLength = getShebangLength(source)
this.wrapperLength -= shebangLength

const rawSourceMap = convertSourceMap.fromSource(this.source) || convertSourceMap.fromMapFileSource(this.source, dirname(this.path))
// handle both inline and file-based SourceMaps.
const rawSourceMap = convertSourceMap.fromSource(source) || convertSourceMap.fromMapFileSource(source, dirname(this.path))
if (rawSourceMap) {
this.path = rawSourceMap.sourcemap.sources[0]

const originalSource = readFileSync(this.path, 'utf8')
this.sourceMap = await new SourceMapConsumer(rawSourceMap.sourcemap)
console.info(this.sourceMap)
}

const shebangLength = getShebangLength(this.source)
this.wrapperLength -= shebangLength
this._buildLines(this.lines, shebangLength)
this.eof = originalSource.trim().length
this._buildLines(source, this.generatedLines, shebangLength)
this._buildLines(originalSource, this.lines, shebangLength)
} else {
this.eof = source.trim().length
this._buildLines(source, this.lines, shebangLength)
}
}
_buildLines (lines, shebangLength) {
_buildLines (source, lines, shebangLength) {
let position = 0
for (const [i, lineStr] of this.source.trim().split(/(?<=\r?\n)/u).entries()) {
for (const [i, lineStr] of source.trim().split(/(?<=\r?\n)/u).entries()) {
const matchedNewLineChar = lineStr.match(/\r?\n$/u)
const newLineLength = matchedNewLineChar ? matchedNewLineChar[0].length : 0
this.eof = position + lineStr.length - newLineLength
const line = new CovLine(i + 1, position, this.eof)
const eol = position + lineStr.length - newLineLength
const line = new CovLine(i + 1, position, eol)
if (i === 0 && shebangLength !== 0) line.count = 1
lines.push(line)
position += lineStr.length
Expand All @@ -52,18 +62,20 @@ module.exports = class CovScript {
applyCoverage (blocks) {
blocks.forEach(block => {
block.ranges.forEach((range, i) => {
const startCol = Math.max(0, range.startOffset - this.wrapperLength)
const endCol = Math.min(this.eof, range.endOffset - this.wrapperLength)
const lines = this.lines.filter(line => {
return startCol <= line.endCol && endCol >= line.startCol
})
const {
startLine,
startCol,
endLine,
endCol
} = this._toLineColumn(range)

if (block.isBlockCoverage && lines.length) {
if (block.isBlockCoverage && startLine !== undefined) {
// record branches.
console.info(startLine, startCol, endLine, endCol, range.count)
this.branches.push(new CovBranch(
lines[0],
startLine,
startCol,
lines[lines.length - 1],
endLine,
endCol,
range.count
))
Expand All @@ -72,39 +84,95 @@ module.exports = class CovScript {
// CovFunction tracking object for each set of ranges.
if (block.functionName && i === 0) {
this.functions.push(new CovFunction(
block.functionName,
lines[0],
startLine,
startCol,
lines[lines.length - 1],
endLine,
endCol,
range.count
))
}
} else if (block.functionName && lines.length) {
} else if (block.functionName && startLine !== undefined) {
// record functions.
this.functions.push(new CovFunction(
block.functionName,
lines[0],
startLine,
startCol,
lines[lines.length - 1],
endLine,
endCol,
range.count
))
}

// record the lines (we record these as statements, such that we're
// compatible with Istanbul 2.0).
lines.forEach(line => {

this.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.
if (startCol <= line.startCol && endCol >= line.endCol) {
line.count = range.count
if (line.line >= startLine && line.line <= endLine) {
if (line.line === startLine) {
if (line.startCol > startCol) {
line.count = range.count
}
} else if (line.line === endLine) {

} else {
line.count = range.count
}
}
})
})
})
}
_toLineColumn (range) {
let startCol = Math.max(0, range.startOffset - this.wrapperLength)
let startLine
let endCol = Math.min(this.eof, range.endOffset - this.wrapperLength)
let endLine
const empty = {startLine: undefined, startCol: undefined, endLine: undefined, endCol: undefined}

if (this.sourceMap) {
const lines = this.generatedLines.filter(line => {
return startCol <= line.endCol && endCol >= line.startCol
})

if (!lines.length) return empty

startLine = lines[0].line
startCol = startCol - lines[0].startCol
endLine = lines[lines.length - 1].line
endCol = endCol - lines[lines.length - 1].startCol

const originalStart = this._originalPosition(startLine, startCol)
startLine = originalStart.line
startCol = originalStart.column

const originalEnd = this._originalPosition(endLine, endCol)
endLine = originalEnd.line
endCol = originalEnd.column
} else {
const lines = this.lines.filter(line => {
return startCol <= line.endCol && endCol >= line.startCol
})
if (!lines.length) return empty

startLine = lines[0].line
startCol = startCol - lines[0].startCol
endLine = lines[lines.length - 1].line
endCol = endCol - lines[lines.length - 1].startCol
}

return {
startLine,
startCol,
endLine,
endCol
}
}
_originalPosition (line, column) {
return this.sourceMap.originalPositionFor({
line,
column,
bias: LOWEST_UPPER_BOUND
})
}
toIstanbul () {
const istanbulInner = Object.assign(
{ path: this.path },
Expand Down
Loading

0 comments on commit 48ee422

Please sign in to comment.