UNPKG

coffee-coverage

Version:

Istanbul and JSCoverage-style instrumentation for CoffeeScript files.

201 lines (185 loc) 5.96 kB
// Generated by CoffeeScript 2.3.2 (function() { // Visitor which looks for pragma directives for skipping coverage, and marks coffeescript nodes // to be skipped. var NodeWrapper, PRAGMAS, PRAGMA_PREFIX, SkipVisitor, _; _ = require('lodash'); NodeWrapper = require('./NodeWrapper'); PRAGMA_PREFIX = '!pragma'; PRAGMAS = [ { // '!pragma coverage-skip-next', 'istanbul ignore next' // Mark the next node and all descendants as `skip`. regex: /^!pragma\s+coverage-skip-next$/, istanbulRegex: /^istanbul\s+ignore\s+next$/, fn: function(self, node, match, options = {}) { var origNode; origNode = node; if (node.type === "Value") { if (node.parent.type === "Assign" || node.parent.type === "Switch" || node.parent.type === "Class") { node = node.parent; } else { node = node.parent.parent; } } else if (node.type !== "If") { node = node.parent; } if (!node) { throw new Error(`Pragma '${match[0]}' at ${self._toLocString(origNode)} has no next statement`); } return node.markAll('skip', true); } }, { // '!pragma coverage-skip-block' regex: /^!pragma\s+coverage-skip-block$/, fn: function(self, node, match, options = {}) { var ifBody, ifNode, parent; parent = node.parent.parent.parent; parent.markAll('skip', true); if (parent.parent.type === 'If') { ifBody = parent; ifNode = parent.parent; if (ifBody.childName === 'body') { return ifNode.mark('skipIf', true); } else { return ifNode.mark('skipElse', true); } } } }, { // '!pragma no-coverage-next' // Mark the next node and all descendants as `noCoverage`. regex: /^!pragma\s+no-coverage-next$/, fn: function(self, node, match, options = {}) { if (node.type === "Value") { if (node.parent.type === "Assign" || node.parent.type === "Switch" || node.parent.type === "Class") { node = node.parent; } else { node = node.parent.parent; } } else if (node.type !== "If") { node = node.parent; } return node.markAll('noCoverage', true); } }, { // 'istanbul ignore if' // Must be before an `If` statement. Mark the `If` as `skipIf`, and mark all children in // the `body` as `skip`. istanbulRegex: /^istanbul\s+ignore\s+if$/, fn: function(self, node, match, options = {}) { var ifNode, ref, ref1; if (node.type === "IdentifierLiteral") { return; } if (node.type === "Value" && ((ref = node.node.base.constructor) != null ? ref.name : void 0) === "PassthroughLiteral") { throw new Error(`Pragma '${match[0]}' at ${self._toLocString(node)} has no next statement`); } ifNode = self.getIfNode(node, match); ifNode.mark('skipIf', true); return (ref1 = ifNode.child('body')) != null ? ref1.markAll('skip', true) : void 0; } }, { // 'istanbul ignore next' // Must be before an `If` statement. Mark the `If` as `skipElse`, and mark all children in // the `elseBody` as `skip`. istanbulRegex: /^istanbul\s+ignore\s+else$/, fn: function(self, node, match, options = {}) { var ifNode, ref, ref1; if (node.type === "IdentifierLiteral") { return; } if (node.type === "Value" && ((ref = node.node.base.constructor) != null ? ref.name : void 0) === "PassthroughLiteral") { throw new Error(`Pragma '${match[0]}' at ${self._toLocString(node)} has no next statement`); } ifNode = self.getIfNode(node, match); ifNode.mark('skipElse', true); return (ref1 = ifNode.child('elseBody')) != null ? ref1.markAll('skip', true) : void 0; } } ]; module.exports = SkipVisitor = class SkipVisitor { constructor(fileName) { this.fileName = fileName; } visitComment(node) { var comment, ref; if (node.node.comments.visited) { return; } comment = (ref = node.node.comments[0].content.trim().toLowerCase()) != null ? ref : ''; if (_.startsWith(comment, PRAGMA_PREFIX)) { PRAGMAS.filter(function(pragma) { return pragma.regex != null; }).forEach((pragma) => { var match; if (match = comment.match(pragma.regex)) { return pragma.fn(this, node, match, this.options); } }); } else if (_.startsWith(comment, 'istanbul')) { PRAGMAS.filter(function(pragma) { return pragma.istanbulRegex != null; }).forEach((pragma) => { var match; if (match = comment.match(pragma.istanbulRegex)) { return pragma.fn(this, node, match, this.options); } }); } return node.node.comments.visited = true; } _toLocString(node) { return `${this.fileName} (${node.locationData.first_line + 1}:${node.locationData.first_column + 1})`; } getIfNode(node, match) { var ref, ref1, ref2, ref3, ref4; if (node.type === "If") { return node; } if (((ref = node.parent) != null ? (ref1 = ref.parent) != null ? ref1.type : void 0 : void 0) === "If") { return node.parent.parent; } if (((ref2 = node.parent) != null ? (ref3 = ref2.parent) != null ? (ref4 = ref3.parent) != null ? ref4.type : void 0 : void 0 : void 0) === "If") { return node.parent.parent.parent; } throw new Error(`Statement after pragma '${match[0]}' at ${this._toLocString(node)} is not of type If`); } }; }).call(this);