Skip to content

Commit

Permalink
Merge branch 'start-end'
Browse files Browse the repository at this point in the history
  • Loading branch information
kpdecker committed Nov 13, 2015
2 parents c98feeb + 2a55a14 commit dd1228d
Show file tree
Hide file tree
Showing 3 changed files with 427 additions and 18 deletions.
9 changes: 9 additions & 0 deletions ignoring-code-for-coverage.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ the source code
* A part of a logical expression in which case that part of the expression is ignored for branch coverage
6. It is up to the caller to scope this as narrowly as possible. For example, if you have a source file that is wrapped
in a function expression, adding `/* istanbul ignore next */` at the top of the file will ignore the whole file!
7. Ranges of code may be skipped using `/* istanbul ignore start */` and `/* istanbul ignore end */`. When defined, these only ignore locations that they completely cover. Ex:

```
/* istanbul ignore start */
if (foo || bar /* istanbul ignore end */) {
}
```

Will only ignore the `foo || bar` portions of the code and the `if` will continue to be covered.

### How it works

Expand Down
73 changes: 55 additions & 18 deletions lib/instrumenter.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
SourceMapConsumer = isNode ? require('source-map').SourceMapConsumer : null,
LEADER_WRAP = '(function () { ',
TRAILER_WRAP = '\n}());',
COMMENT_RE = /^\s*istanbul\s+ignore\s+(if|else|next)(?=\W|$)/,
COMMENT_RE = /^\s*istanbul\s+ignore\s+(if|else|next|start|end)(?=\W|$)/,
astgen,
preconditions,
cond,
Expand Down Expand Up @@ -470,11 +470,12 @@
}
return this.instrumentASTSync(program, filename, code);
},
filterHints: function (comments) {
filterHints: function (comments, program) {
var ret = [],
i,
comment,
groups;
groups,
lastHint;
if (!(comments && isArray(comments))) {
return ret;
}
Expand All @@ -484,18 +485,54 @@
if (comment && comment.value && comment.range && isArray(comment.range)) {
groups = String(comment.value).match(COMMENT_RE);
if (groups) {
ret.push({ type: groups[1], start: comment.range[0], end: comment.range[1] });
if (lastHint && lastHint.type === 'start') {
// If we have the end flag then finalize the range
if (groups[1] === 'end') {
lastHint.type = 'range';
lastHint.rangeEnd = comment.range[1];
}
// Otherwise ignore the nested ignore
} else {
lastHint = { type: groups[1], start: comment.range[0], end: comment.range[1] };
ret.push(lastHint);
}
}
}
}

// If there is a start without an end, then expand the range to cover the remainder of the file
if (lastHint && lastHint.type === 'start') {
lastHint.type = 'range';
var programEnd = program.body[program.body.length - 1];
lastHint.rangeEnd = programEnd.range[1] + 1;
}

return ret;
},
extractCurrentHint: function (node) {
if (!node.range) { return; }
var i = this.currentState.lastHintPosition + 1,
hints = this.currentState.hints,
nodeStart = node.range[0],
hint;
hint = this.currentState.currentHint;

// If we are still in a range, keep it running
if (hint) {
if (hint.type === 'range' && hint.rangeEnd > node.range[1]) {
return;
}
}

// Check if we are part of a partial range overlap that didn't
// cover our parents completely
hint = hints[i - 1];
if (hint && hint.type === 'range' && hint.rangeEnd > node.range[1]) {
this.currentState.currentHint = hint;
this.currentState.lastHintPosition = i - 1;
return;
}

// Otherwise check for the next range
this.currentState.currentHint = null;
while (i < hints.length) {
hint = hints[i];
Expand Down Expand Up @@ -543,7 +580,7 @@
branch: 0,
variable: 0,
statement: 0,
hints: this.filterHints(program.comments),
hints: this.filterHints(program.comments, program),
currentHint: null,
lastHintPosition: -1,
ignoring: 0
Expand All @@ -563,7 +600,6 @@
codegenOptions.sourceMapWithCode = true;
}
codegenOptions.comment = this.opts.preserveComments;
//console.log(JSON.stringify(program, undefined, 2));

generated = ESPGEN.generate(program, codegenOptions);
preamble = this.getPreamble(originalCode || '', usingStrict);
Expand Down Expand Up @@ -793,17 +829,21 @@
},

maybeSkipNode: function (node, type) {
var alreadyIgnoring = !!this.currentState.ignoring,
hint = this.currentState.currentHint,
ignoreThis = !alreadyIgnoring && hint && hint.type === type;

if (ignoreThis) {
if (this.shouldSkip(node, type)) {
this.startIgnore();
node.postprocessor = this.endIgnore;
return true;
}
return false;
},
shouldSkip: function(node, type) {
var alreadyIgnoring = !!this.currentState.ignoring,
hint = this.currentState.currentHint;

return !alreadyIgnoring && hint &&
(hint.type === type ||
(hint.type === 'range' && hint.rangeEnd > node.range[1]));
},

coverStatement: function (node, walker) {
var sName,
Expand Down Expand Up @@ -939,10 +979,8 @@
},

ifBranchInjector: function (node, walker) {
var alreadyIgnoring = !!this.currentState.ignoring,
hint = this.currentState.currentHint,
ignoreThen = !alreadyIgnoring && hint && hint.type === 'if',
ignoreElse = !alreadyIgnoring && hint && hint.type === 'else',
var ignoreThen = this.shouldSkip(node, 'if'),
ignoreElse = this.shouldSkip(node, 'else'),
line = node.loc.start.line,
col = node.loc.start.column,
makeLoc = function () { return { line: line, column: col }; },
Expand Down Expand Up @@ -1000,8 +1038,7 @@
maybeAddSkip: function (branchLocation) {
return function (node) {
var alreadyIgnoring = !!this.currentState.ignoring,
hint = this.currentState.currentHint,
ignoreThis = !alreadyIgnoring && hint && hint.type === 'next';
ignoreThis = this.shouldSkip(node, 'next');
if (ignoreThis) {
this.startIgnore();
node.postprocessor = this.endIgnore;
Expand Down
Loading

0 comments on commit dd1228d

Please sign in to comment.