Skip to content

Commit

Permalink
fix: do not overwrite coverage after each test suite (#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
joe223 authored Apr 14, 2020
1 parent 0ff95c8 commit 848aa76
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 25 deletions.
35 changes: 23 additions & 12 deletions lib/output-files.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ const pathLib = require('path')
const url = require('url')

const storagePath = './.nyc_output/js'
let iterator = {}

class OutputFiles {
constructor (coverageInfo) {
// Clone coverageInfo to prevent mutating the passed in data
this.coverageInfo = clone(coverageInfo)
this.iterator = 0
this._parseAndIsolate()
}

Expand Down Expand Up @@ -49,18 +49,22 @@ class OutputFiles {

let str = ``
let parsedPath = this.parsePath(path)

let isInline = false
// Special case: when html present, strip and return specialized string
if (parsedPath.includes('.html')) {
parsedPath = pathLib.resolve(storagePath, parsedPath) + 'puppeteerTemp-inline'
if (pathLib.extname(parsedPath) === '.html') {
isInline = true
parsedPath = pathLib.resolve(storagePath, parsedPath + 'puppeteerTemp-inline')
} else {
parsedPath = parsedPath.split('.js')[0]
parsedPath = pathLib.resolve(storagePath, parsedPath)
parsedPath = pathLib.resolve(storagePath, pathLib.dirname(parsedPath), pathLib.basename(parsedPath, '.js'))
}
mkdirp.sync(storagePath)
if (fs.existsSync(parsedPath + '.js')) {
this.iterator++
str = `${parsedPath}-${this.iterator}.js`
if (fs.existsSync(parsedPath + '.js') && isInline) {
if (!Number.isInteger(iterator[parsedPath])) {
iterator[parsedPath] = 1
} else {
iterator[parsedPath]++
}
str = `${parsedPath}-${iterator[parsedPath]}.js`
return str
} else {
str = `${parsedPath}.js`
Expand All @@ -69,8 +73,9 @@ class OutputFiles {
}

_parseAndIsolate () {
for (var i = 0; i < this.coverageInfo.length; i++) {
var path = this.rewritePath(this.coverageInfo[i].url)
for (let i = 0; i < this.coverageInfo.length; i++) {
let path = this.rewritePath(this.coverageInfo[i].url)

this.coverageInfo[i].originalUrl = this.coverageInfo[i].url
this.coverageInfo[i].url = path

Expand All @@ -85,6 +90,12 @@ class OutputFiles {
}
}

module.exports = function (coverageInfo) {
function genOutputFiles (coverageInfo) {
return new OutputFiles(coverageInfo)
}

genOutputFiles.resetIterator = function () {
iterator = {}
}

module.exports = genOutputFiles
44 changes: 34 additions & 10 deletions lib/puppeteer-to-istanbul.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ const mkdirp = require('mkdirp')
const PuppeteerToV8 = require('./puppeteer-to-v8')
const v8toIstanbul = require('v8-to-istanbul')

let jsonPart = {}

class PuppeteerToIstanbul {
constructor (coverageInfo) {
this.coverageInfo = coverageInfo
Expand All @@ -23,7 +25,6 @@ class PuppeteerToIstanbul {
fs.writeFileSync(outFilePath, '')

const fd = fs.openSync(outFilePath, 'a')
fs.writeSync(fd, '{')

this.puppeteerToV8Info.forEach((jsFile, index) => {
const script = v8toIstanbul(jsFile.url)
Expand All @@ -32,23 +33,46 @@ class PuppeteerToIstanbul {
let istanbulCoverage = script.toIstanbul()
let keys = Object.keys(istanbulCoverage)

let jsonPart = {}
jsonPart[keys[0]] = istanbulCoverage[keys[0]]
if (jsonPart[keys[0]]) {
// Merge coverage records
mergeCoverageData(jsonPart[keys[0]].s, istanbulCoverage[keys[0]].s)
} else {
jsonPart[keys[0]] = istanbulCoverage[keys[0]]
}
jsonPart[keys[0]].originalUrl = jsFile.originalUrl
})

let jsonStr = JSON.stringify(jsonPart)
.replace(/^{/, '')
.replace(/}$/, '')
fs.writeSync(fd, '{')
Object.keys(jsonPart).forEach((url, index, keys) => {
const data = jsonPart[url]
const isLastIteration = index === (keys.length - 1)

const isLastIteration = index === (this.puppeteerToV8Info.length - 1)
fs.writeSync(fd, jsonStr + (isLastIteration ? '' : ','))
fs.writeSync(fd, `"${url}": ${JSON.stringify(data)}${(isLastIteration ? '' : ',')}`)
})

fs.writeSync(fd, '}')
fs.closeSync(fd)
}
}

module.exports = function (coverageInfo) {
function mergeCoverageData (obja, objb) {
Object.keys(obja).forEach(key => {
obja[key] = (obja[key] || objb[key]) ? 1 : 0
})
return obja
}

function genPuppeteerToIstanbul (coverageInfo) {
return new PuppeteerToIstanbul(coverageInfo)
}

genPuppeteerToIstanbul.resetJSONPart = function () {
jsonPart = {}
}

genPuppeteerToIstanbul.getJSONPart = function () {
return JSON.parse(JSON.stringify(jsonPart))
}

genPuppeteerToIstanbul.mergeCoverageData = mergeCoverageData

module.exports = genPuppeteerToIstanbul
20 changes: 19 additions & 1 deletion test/fixtures/inline-script-coverage.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
[
{
"url": "file:///tmp/puppeteerTemp.html",
"ranges": [
{
"start": 0,
"end": 59
},
{
"start": 66,
"end": 74
},
{
"start": 121,
"end": 140
}
],
"text": "\n function c(num1, num2) {\n return num2 * num1;\n }\n function d(num3) {\n return num3;\n }\n c(4,3);\n "
},
{
"url": "file:///tmp/puppeteerTemp.html",
"ranges": [
Expand All @@ -17,4 +35,4 @@
],
"text": "\n function c(num1, num2) {\n return num2 * num1;\n }\n function d(num3) {\n return num3;\n }\n c(4,3);\n "
}
]
]
26 changes: 26 additions & 0 deletions test/fixtures/merge-coverage/non-inline-script-a.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[
{
"url": "http://localhost:9000/js/index.js",
"ranges": [
{
"start": 0,
"end": 55
}
],
"text": "\n function c(num1, num2) {\n return num2 * num1;\n }\n function d(num3) {\n return num3;\n }\n c(4,3);\n "
},
{
"url": "file:///tmp/puppeteerTemp.html",
"ranges": [
{
"start": 0,
"end": 68
},
{
"start": 73,
"end": 93
}
],
"text": "\n function e(num4, num5, num6) {\n return num4 * num5 - num6;\n }\n e(3,5,6);\n "
}
]
30 changes: 30 additions & 0 deletions test/fixtures/merge-coverage/non-inline-script-b.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[
{
"url": "http://localhost:9000/js/index.js",
"ranges": [
{
"start": 60,
"end": 66
},
{
"start": 109,
"end": 126
}
],
"text": "\n function c(num1, num2) {\n return num2 * num1;\n }\n function d(num3) {\n return num3;\n }\n c(4,3);\n "
},
{
"url": "file:///tmp/puppeteerTemp.html",
"ranges": [
{
"start": 0,
"end": 68
},
{
"start": 73,
"end": 93
}
],
"text": "\n function e(num4, num5, num6) {\n return num4 * num5 - num6;\n }\n e(3,5,6);\n "
}
]
2 changes: 1 addition & 1 deletion test/fixtures/two-inline.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@
],
"text": "\n function e(num4, num5, num6) {\n return num4 * num5 - num6;\n }\n e(3,5,6);\n "
}
]
]
10 changes: 9 additions & 1 deletion test/output-files.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,21 @@ describe('output-files', () => {
coverageInfo[1].url.should.not.eql(fixture[1].url)

coverageInfo[0].url.should.eql(movedUrl(fixture[0].url))
coverageInfo[1].url.should.eql(movedUrl(fixture[0].url.replace('.js', '-1.js')))
// It's not inline script and has the same url, so we could know both of them are same file.
// There is no need to create `-1.js` file.
// In case multiple page instance load the same js file.
coverageInfo[1].url.should.eql(movedUrl(fixture[0].url))
})

// call it something like indexHTML-inline-1.js
it('appropriately handles only inline JavaScript', () => {
const fixture = require('./fixtures/inline-script-coverage.json')
// Reset iterator
OutputFiles.resetIterator()
const coverageInfo = OutputFiles(fixture).getTransformedCoverage()

coverageInfo[0].url.should.include('puppeteerTemp-inline.js')
coverageInfo[1].url.should.include('puppeteerTemp-inline-1.js')
})

it('appropriately handles inline and external JavaScript', () => {
Expand All @@ -54,6 +60,8 @@ describe('output-files', () => {

it('appropriately handles two cases of inline JavaScript', () => {
const fixture = require('./fixtures/two-inline.json')
// Reset iterator
OutputFiles.resetIterator()
const coverageInfo = OutputFiles(fixture).getTransformedCoverage()

coverageInfo[0].url.should.include('puppeteerTemp-inline.js')
Expand Down
33 changes: 33 additions & 0 deletions test/puppeteer-to-istanbul.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

const should = require('chai').should()
const fs = require('fs')
const OutputFiles = require('../lib/output-files')

var PuppeteerToIstanbul = require('../lib/puppeteer-to-istanbul')

Expand All @@ -22,4 +23,36 @@ describe('puppeteer-to-istanbul', () => {
pti.setCoverageInfo(fixture)
pti.coverageInfo.should.eql(fixture)
})

it('merge non-inline script coverage records', () => {
OutputFiles.resetIterator()
PuppeteerToIstanbul.resetJSONPart()

const fixtureNonInlineScriptA = require('./fixtures/merge-coverage/non-inline-script-a.json')
const fixtureNonInlineScriptB = require('./fixtures/merge-coverage/non-inline-script-b.json')
const ptiA = PuppeteerToIstanbul(fixtureNonInlineScriptA)
ptiA.writeIstanbulFormat()
const jsonPartA = PuppeteerToIstanbul.getJSONPart()
PuppeteerToIstanbul.resetJSONPart()
const ptiB = PuppeteerToIstanbul(fixtureNonInlineScriptB)
ptiB.writeIstanbulFormat()
const jsonPartB = PuppeteerToIstanbul.getJSONPart()
PuppeteerToIstanbul.resetJSONPart()
OutputFiles.resetIterator()
PuppeteerToIstanbul.resetJSONPart()
const pti = PuppeteerToIstanbul(fixtureNonInlineScriptA.concat(fixtureNonInlineScriptB))
pti.writeIstanbulFormat()
const jsonPart = PuppeteerToIstanbul.getJSONPart()
const keys = Object.keys(jsonPart)

// Non-inline script data should be merged.
jsonPart[keys[0]].s.should.deep.equal(PuppeteerToIstanbul.mergeCoverageData(jsonPartA[keys[0]].s, jsonPartB[keys[0]].s))
// Inline script data should not be merged. So, there would be two inline files. Just likes:
// [
// "/Users/puppeteer-to-istanbul/.nyc_output/js/localhost_9000/js/index.js"
// "/Users/puppeteer-to-istanbul/.nyc_output/js/tmp/puppeteerTemp.htmlpuppeteerTemp-inline-1.js"
// "/Users/puppeteer-to-istanbul/.nyc_output/js/tmp/puppeteerTemp.htmlpuppeteerTemp-inline-2.js"
// ]
Object.keys(jsonPart).should.deep.equal(Array.from(new Set(Object.keys(jsonPartA).concat(Object.keys(jsonPartB)))))
})
})

0 comments on commit 848aa76

Please sign in to comment.