From 7d0259c45eca706e112c5c294534b5ffd6a2877c Mon Sep 17 00:00:00 2001 From: cenfun Date: Mon, 18 Dec 2023 12:30:02 +0800 Subject: [PATCH] fix covered lines --- lib/converter/converter.js | 116 ++++++++++++++---------------- lib/converter/info-line.js | 3 + lib/platform/share.js | 45 ++++++++---- packages/v8/src/utils/coverage.js | 7 +- 4 files changed, 93 insertions(+), 78 deletions(-) diff --git a/lib/converter/converter.js b/lib/converter/converter.js index 10b2eccd..5741f01b 100644 --- a/lib/converter/converter.js +++ b/lib/converter/converter.js @@ -78,8 +78,11 @@ const updateLineComment = (positionMapping, range) => { const lines = Util.getRangeLines(sLoc, eLoc, block); - lines.forEach((i) => { - const line = positionMapping.getLine(i); + lines.forEach((it) => { + if (!it.entire) { + return; + } + const line = positionMapping.getLine(it.line); if (line) { line.comment = true; } @@ -129,12 +132,11 @@ const calculateV8Lines = (lines, blankCount, commentCount) => { }; lines.forEach((ln) => { - v8Lines.total += 1; - if (ln.count > 0) { + // full line covered + if (ln.covered) { v8Lines.covered += 1; } - }); return v8Lines; @@ -149,9 +151,11 @@ const createEmptyCoverage = () => { // functions ranges from ast const functions = []; + // line 1 based const functionMap = new Map(); const lines = []; + // line 1 based const lineMap = new Map(); const blankCount = 0; @@ -251,54 +255,6 @@ const getFileCoverage = (coverage, sourcePath) => { // ======================================================================================================== -const setLineCount = (lineMap, line, count) => { - const lineInfo = lineMap.get(line); - if (lineInfo) { - lineInfo.count = count; - } -}; - -const setSingleLineCount = (lineMap, sLoc, eLoc, count) => { - // nothing between - if (sLoc.column >= eLoc.column) { - return; - } - - // sometimes column > length - if (sLoc.column <= sLoc.indent && eLoc.column >= eLoc.length) { - // console.log('single', sLoc.line); - setLineCount(lineMap, sLoc.line, count); - } - -}; - -const updateLinesCount = (lineMap, sLoc, eLoc, count) => { - - // single line - if (sLoc.line === eLoc.line) { - setSingleLineCount(lineMap, sLoc, eLoc, count); - return; - } - - const firstELoc = { - ... sLoc, - column: sLoc.length - }; - setSingleLineCount(lineMap, sLoc, firstELoc, count); - - for (let i = sLoc.line + 1; i < eLoc.line; i++) { - setLineCount(lineMap, i, count); - } - - const lastSLoc = { - ... eLoc, - column: eLoc.indent - }; - setSingleLineCount(lineMap, lastSLoc, eLoc, count); - -}; - - const updateFunctionsCount = (coverage, sLoc, eLoc, count, functionName) => { if (!count) { return; @@ -401,8 +357,27 @@ const addJsCoverage = (coverage, block, range, index, positionMapping) => { const eLoc = positionMapping.offsetToLocation(endOffset); // line, column - updateLinesCount(lineMap, sLoc, eLoc, count); + const lines = Util.getRangeLines(sLoc, eLoc); + lines.forEach((it) => { + const line = lineMap.get(it.line); + if (!line) { + return; + } + + // from outside into inside, uncovered is certain + // default is covered + if (line.covered) { + line.covered = count > 0; + } + + line.count = count; + // if (!line.history) { + // line.history = []; + // } + // line.history.push(`${it.entire}-${count}`); + + }); if (isBlockCoverage) { // the ranges form a tree of blocks representing how many times each statement or expression inside was executed. @@ -434,8 +409,20 @@ const addCssCoverage = (coverage, range, positionMapping) => { const sLoc = positionMapping.offsetToLocation(start); const eLoc = positionMapping.offsetToLocation(end); - // line, column - updateLinesCount(lineMap, sLoc, eLoc, 1); + // covered css lines + const lines = Util.getRangeLines(sLoc, eLoc); + lines.forEach((it) => { + if (!it.entire) { + return; + } + const line = lineMap.get(it.line); + if (line) { + // default is uncovered + // count always 1, covered is certain + line.covered = true; + } + }); + }; @@ -486,11 +473,6 @@ const handleDistLinesCoverage = (item, state, coverage) => { let blankCount = 0; let commentCount = 0; - // baseLineCount: - // js: 1 (functions include all uncovered) - // css: 0 (ranges include all covered) - const baseLineCount = item.type === 'js' ? 1 : 0; - // handle comment before collect lines const comments = astInfo.comments; @@ -503,6 +485,11 @@ const handleDistLinesCoverage = (item, state, coverage) => { updateLineComment(positionMapping, range); }); + + // js: 1 (functions include all uncovered) + // css: 0 (ranges include all covered) + const baseLineCount = item.type === 'js' ? 1 : 0; + positionMapping.lines.forEach((it) => { // exclude blank and comment if (it.blank) { @@ -539,6 +526,13 @@ const handleDistRangesCoverage = (item, state, coverage) => { addCssCoverage(coverage, range, positionMapping); }); } + + + // if (item.sourcePath.indexOf('demo.js') !== -1) { + // console.log(coverage.lines); + // } + + }; const generateCoverageForDist = (item, state) => { diff --git a/lib/converter/info-line.js b/lib/converter/info-line.js index 31981fc3..62b5e7dc 100644 --- a/lib/converter/info-line.js +++ b/lib/converter/info-line.js @@ -1,8 +1,11 @@ module.exports = class InfoLine { constructor(line, column, count = 1) { + // 1 based this.line = line; this.column = column; this.count = count; + // covered full line, could be false even count > 0 + this.covered = count > 0; } generate() { diff --git a/lib/platform/share.js b/lib/platform/share.js index 31ab9e7d..0a4f1e7e 100644 --- a/lib/platform/share.js +++ b/lib/platform/share.js @@ -234,20 +234,33 @@ const Util = { getRangeLines: (sLoc, eLoc, block = true) => { - // line index, 0 based const lines = []; const addStart = () => { - if (sLoc.column === sLoc.indent) { - lines.push(sLoc.line); - } + const entire = sLoc.column === sLoc.indent; + lines.push({ + line: sLoc.line, + entire + }); + }; + + const addMiddle = () => { + const start = sLoc.column === sLoc.indent; + const end = Util.isBlank(eLoc.text.slice(eLoc.column)); + const entire = start && end; + // same line + lines.push({ + line: sLoc.line, + entire + }); }; const addEnd = () => { - const rightText = eLoc.text.slice(eLoc.column); - if (Util.isBlank(rightText)) { - lines.push(eLoc.line); - } + const entire = Util.isBlank(eLoc.text.slice(eLoc.column)); + lines.push({ + line: eLoc.line, + entire + }); }; // block @@ -255,23 +268,25 @@ const Util = { // same line, single line if (sLoc.line === eLoc.line) { - // check start - if (sLoc.column === sLoc.indent) { - // check end is blank - addEnd(); - } + + addMiddle(); } else { // multiple lines addStart(); - // mids + // always entire for middle lines const lineStart = sLoc.line + 1; const lineEnd = eLoc.line; if (lineEnd > lineStart) { for (let i = lineStart; i < lineEnd; i++) { - lines.push(i); + lines.push({ + line: i, + // for js nested functions + middle: true, + entire: true + }); } } diff --git a/packages/v8/src/utils/coverage.js b/packages/v8/src/utils/coverage.js index 436bf5fd..3d49bc8e 100644 --- a/packages/v8/src/utils/coverage.js +++ b/packages/v8/src/utils/coverage.js @@ -32,8 +32,11 @@ class CoverageParser { const lines = Util.getRangeLines(sLoc, eLoc, block); - lines.forEach((i) => { - const line = formattedLines[i]; + lines.forEach((it) => { + if (!it.entire) { + return; + } + const line = formattedLines[it.line]; if (line) { line.comment = true; }