| | |
| | | types, |
| | | sourceFilePath, |
| | | inputSourceMap, |
| | | ignoreClassMethods = [] |
| | | ignoreClassMethods = [], |
| | | reportLogic = false |
| | | ) { |
| | | this.varName = genVar(sourceFilePath); |
| | | this.attrs = {}; |
| | |
| | | this.ignoreClassMethods = ignoreClassMethods; |
| | | this.types = types; |
| | | this.sourceMappingURL = null; |
| | | this.reportLogic = reportLogic; |
| | | } |
| | | |
| | | // should we ignore the node? Yes, if specifically ignoring |
| | |
| | | ); |
| | | } |
| | | |
| | | // 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( |
| | | this.validateTrueNonTrivial(T, tempName), |
| | | this.increase(type, id, index), |
| | | T.nullLiteral() |
| | | ) |
| | | ), |
| | | T.memberExpression( |
| | | T.callExpression(T.identifier(this.varName), []), |
| | | T.identifier(tempName) |
| | | ) |
| | | ]); |
| | | } |
| | | |
| | | validateTrueNonTrivial(T, tempName) { |
| | | return T.logicalExpression( |
| | | '&&', |
| | | T.memberExpression( |
| | | T.callExpression(T.identifier(this.varName), []), |
| | | T.identifier(tempName) |
| | | ), |
| | | T.logicalExpression( |
| | | '&&', |
| | | T.parenthesizedExpression( |
| | | T.logicalExpression( |
| | | '||', |
| | | T.unaryExpression( |
| | | '!', |
| | | T.callExpression( |
| | | T.memberExpression( |
| | | T.identifier('Array'), |
| | | T.identifier('isArray') |
| | | ), |
| | | [ |
| | | T.memberExpression( |
| | | T.callExpression( |
| | | T.identifier(this.varName), |
| | | [] |
| | | ), |
| | | T.identifier(tempName) |
| | | ) |
| | | ] |
| | | ) |
| | | ), |
| | | T.memberExpression( |
| | | T.memberExpression( |
| | | T.callExpression( |
| | | T.identifier(this.varName), |
| | | [] |
| | | ), |
| | | T.identifier(tempName) |
| | | ), |
| | | T.identifier('length') |
| | | ) |
| | | ) |
| | | ), |
| | | T.parenthesizedExpression( |
| | | T.logicalExpression( |
| | | '||', |
| | | T.binaryExpression( |
| | | '!==', |
| | | T.callExpression( |
| | | T.memberExpression( |
| | | T.identifier('Object'), |
| | | T.identifier('getPrototypeOf') |
| | | ), |
| | | [ |
| | | T.memberExpression( |
| | | T.callExpression( |
| | | T.identifier(this.varName), |
| | | [] |
| | | ), |
| | | T.identifier(tempName) |
| | | ) |
| | | ] |
| | | ), |
| | | T.memberExpression( |
| | | T.identifier('Object'), |
| | | T.identifier('prototype') |
| | | ) |
| | | ), |
| | | T.memberExpression( |
| | | T.callExpression( |
| | | T.memberExpression( |
| | | T.identifier('Object'), |
| | | T.identifier('values') |
| | | ), |
| | | [ |
| | | T.memberExpression( |
| | | T.callExpression( |
| | | T.identifier(this.varName), |
| | | [] |
| | | ), |
| | | T.identifier(tempName) |
| | | ) |
| | | ] |
| | | ), |
| | | T.identifier('length') |
| | | ) |
| | | ) |
| | | ) |
| | | ) |
| | | ); |
| | | } |
| | | |
| | | insertCounter(path, increment) { |
| | | const T = this.types; |
| | | if (path.isBlockStatement()) { |
| | |
| | | getBranchIncrement(branchName, loc) { |
| | | const index = this.cov.addBranchPath(branchName, loc); |
| | | return this.increase('b', branchName, index); |
| | | } |
| | | |
| | | 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) { |
| | |
| | | } |
| | | const leaves = []; |
| | | 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) { |
| | | const leaf = leaves[i]; |
| | | const hint = this.hintFor(leaf.node); |
| | | if (hint === 'next') { |
| | | continue; |
| | | } |
| | | |
| | | 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); |
| | | if (!increment) { |
| | | continue; |
| | |
| | | * `fileCoverage` - the file coverage object created for the source file. |
| | | * `sourceMappingURL` - any source mapping URL found when processing the file. |
| | | * |
| | | * @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. |
| | | * @param {boolean} [opts.coverageGlobalScopeFunc=true] use an evaluated function to find coverageGlobalScope. |
| | | * @param {Array} [opts.ignoreClassMethods=[]] names of methods to ignore by default on classes. |
| | |
| | | types, |
| | | sourceFilePath, |
| | | opts.inputSourceMap, |
| | | opts.ignoreClassMethods |
| | | opts.ignoreClassMethods, |
| | | opts.reportLogic |
| | | ); |
| | | return { |
| | | enter(path) { |