istanbul-lib-instrument
Advanced tools
Comparing version 5.0.4 to 5.1.0
@@ -6,2 +6,9 @@ # Change Log | ||
## [5.1.0](https://www.github.com/istanbuljs/istanbuljs/compare/istanbul-lib-instrument-v5.0.4...istanbul-lib-instrument-v5.1.0) (2021-10-27) | ||
### Features | ||
* option to evaluate logical truthiness, for applications such as fuzzing ([#629](https://www.github.com/istanbuljs/istanbuljs/issues/629)) ([a743b84](https://www.github.com/istanbuljs/istanbuljs/commit/a743b8442e977f0c77ffa282eed7ac84ca200d1f)) | ||
### [5.0.4](https://www.github.com/istanbuljs/istanbuljs/compare/istanbul-lib-instrument-v5.0.3...istanbul-lib-instrument-v5.0.4) (2021-10-16) | ||
@@ -8,0 +15,0 @@ |
{ | ||
"name": "istanbul-lib-instrument", | ||
"version": "5.0.4", | ||
"version": "5.1.0", | ||
"description": "Core istanbul API for JS code coverage", | ||
@@ -17,3 +17,3 @@ "author": "Krishnan Anantheswaran <kananthmail-github@yahoo.com>", | ||
"@istanbuljs/schema": "^0.1.2", | ||
"istanbul-lib-coverage": "^3.0.0", | ||
"istanbul-lib-coverage": "^3.2.0", | ||
"semver": "^6.3.0" | ||
@@ -20,0 +20,0 @@ }, |
@@ -17,3 +17,4 @@ /* | ||
* @param {string} [opts.coverageVariable=__coverage__] name of global coverage variable. | ||
* @param {boolean} [opts.preserveComments=false] preserve comments in output | ||
* @param {boolean} [opts.reportLogic=false] report boolean value of logical expressions. | ||
* @param {boolean} [opts.preserveComments=false] preserve comments in output. | ||
* @param {boolean} [opts.compact=true] generate compact code. | ||
@@ -26,3 +27,3 @@ * @param {boolean} [opts.esModules=false] set to true to instrument ES6 modules. | ||
* is found in the original code. This function is called with the source file name and the source map URL. | ||
* @param {boolean} [opts.debug=false] - turn debugging on | ||
* @param {boolean} [opts.debug=false] - turn debugging on. | ||
* @param {array} [opts.parserPlugins] - set babel parser plugins, see @istanbuljs/schema for defaults. | ||
@@ -78,2 +79,3 @@ */ | ||
coverageVariable: opts.coverageVariable, | ||
reportLogic: opts.reportLogic, | ||
coverageGlobalScope: opts.coverageGlobalScope, | ||
@@ -80,0 +82,0 @@ coverageGlobalScopeFunc: |
@@ -20,2 +20,3 @@ const { parseSync, traverse } = require('@babel/core'); | ||
parserOpts: { | ||
allowAwaitOutsideFunction: true, | ||
allowImportExportEverywhere: true, | ||
@@ -22,0 +23,0 @@ allowReturnOutsideFunction: true, |
@@ -60,3 +60,3 @@ const { classes } = require('istanbul-lib-coverage'); | ||
newBranch(type, loc) { | ||
newBranch(type, loc, isReportLogic = false) { | ||
const b = this.meta.last.b; | ||
@@ -72,5 +72,17 @@ this.data.b[b] = []; | ||
this.meta.last.b += 1; | ||
this.maybeNewBranchTrue(type, b, isReportLogic); | ||
return b; | ||
} | ||
maybeNewBranchTrue(type, name, isReportLogic) { | ||
if (!isReportLogic) { | ||
return; | ||
} | ||
if (type !== 'binary-expr') { | ||
return; | ||
} | ||
this.data.bT = this.data.bT || {}; | ||
this.data.bT[name] = []; | ||
} | ||
addBranchPath(name, location) { | ||
@@ -86,5 +98,17 @@ const bMeta = this.data.branchMap[name]; | ||
counts.push(0); | ||
this.maybeAddBranchTrue(name); | ||
return counts.length - 1; | ||
} | ||
maybeAddBranchTrue(name) { | ||
if (!this.data.bT) { | ||
return; | ||
} | ||
const countsTrue = this.data.bT[name]; | ||
if (!countsTrue) { | ||
return; | ||
} | ||
countsTrue.push(0); | ||
} | ||
/** | ||
@@ -103,2 +127,3 @@ * Assigns an input source map to the coverage that can be used | ||
const branches = this.data.b; | ||
const branchesT = this.data.bT || {}; | ||
Object.keys(map).forEach(b => { | ||
@@ -108,2 +133,3 @@ if (map[b].locations.length === 0) { | ||
delete branches[b]; | ||
delete branchesT[b]; | ||
} | ||
@@ -110,0 +136,0 @@ }); |
@@ -28,3 +28,4 @@ const { createHash } = require('crypto'); | ||
inputSourceMap, | ||
ignoreClassMethods = [] | ||
ignoreClassMethods = [], | ||
reportLogic = false | ||
) { | ||
@@ -42,2 +43,3 @@ this.varName = genVar(sourceFilePath); | ||
this.sourceMappingURL = null; | ||
this.reportLogic = reportLogic; | ||
} | ||
@@ -187,2 +189,33 @@ | ||
// Reads the logic expression conditions and conditionally increments truthy counter. | ||
increaseTrue(type, id, index, node) { | ||
const T = this.types; | ||
const tempName = `${this.varName}_temp`; | ||
return T.sequenceExpression([ | ||
T.assignmentExpression( | ||
'=', | ||
T.memberExpression( | ||
T.callExpression(T.identifier(this.varName), []), | ||
T.identifier(tempName) | ||
), | ||
node // Only evaluates once. | ||
), | ||
T.parenthesizedExpression( | ||
T.conditionalExpression( | ||
T.memberExpression( | ||
T.callExpression(T.identifier(this.varName), []), | ||
T.identifier(tempName) | ||
), | ||
this.increase(type, id, index), | ||
T.nullLiteral() | ||
) | ||
), | ||
T.memberExpression( | ||
T.callExpression(T.identifier(this.varName), []), | ||
T.identifier(tempName) | ||
) | ||
]); | ||
} | ||
insertCounter(path, increment) { | ||
@@ -282,2 +315,10 @@ const T = this.types; | ||
getBranchLogicIncrement(path, branchName, loc) { | ||
const index = this.cov.addBranchPath(branchName, loc); | ||
return [ | ||
this.increase('b', branchName, index), | ||
this.increaseTrue('bT', branchName, index, path.node) | ||
]; | ||
} | ||
insertBranchCounter(path, branchName, loc) { | ||
@@ -468,3 +509,7 @@ const increment = this.getBranchIncrement( | ||
this.findLeaves(path.node, leaves); | ||
const b = this.cov.newBranch('binary-expr', path.node.loc); | ||
const b = this.cov.newBranch( | ||
'binary-expr', | ||
path.node.loc, | ||
this.reportLogic | ||
); | ||
for (let i = 0; i < leaves.length; i += 1) { | ||
@@ -476,2 +521,19 @@ const leaf = leaves[i]; | ||
} | ||
if (this.reportLogic) { | ||
const increment = this.getBranchLogicIncrement( | ||
leaf, | ||
b, | ||
leaf.node.loc | ||
); | ||
if (!increment[0]) { | ||
continue; | ||
} | ||
leaf.parent[leaf.property] = T.sequenceExpression([ | ||
increment[0], | ||
increment[1] | ||
]); | ||
continue; | ||
} | ||
const increment = this.getBranchIncrement(b, leaf.node.loc); | ||
@@ -593,6 +655,7 @@ if (!increment) { | ||
* | ||
* @param {Object} types - an instance of babel-types | ||
* @param {string} sourceFilePath - the path to source file | ||
* @param {Object} opts - additional options | ||
* @param {Object} types - an instance of babel-types. | ||
* @param {string} sourceFilePath - the path to source file. | ||
* @param {Object} opts - additional options. | ||
* @param {string} [opts.coverageVariable=__coverage__] the global coverage variable name. | ||
* @param {boolean} [opts.reportLogic=false] report boolean value of logical expressions. | ||
* @param {string} [opts.coverageGlobalScope=this] the global coverage variable scope. | ||
@@ -614,3 +677,4 @@ * @param {boolean} [opts.coverageGlobalScopeFunc=true] use an evaluated function to find coverageGlobalScope. | ||
opts.inputSourceMap, | ||
opts.ignoreClassMethods | ||
opts.ignoreClassMethods, | ||
opts.reportLogic | ||
); | ||
@@ -617,0 +681,0 @@ return { |
65251
1070
Updatedistanbul-lib-coverage@^3.2.0