gotwarlost / istanbul

Yet another JS code coverage tool that computes statement, line, function and branch coverage with module loader hooks to transparently add coverage when running tests. Supports all JS coverage use cases including unit tests, server side functional tests and browser tests. Built for scale.
Other
8.7k stars 786 forks source link

How to ignore default value branch for ES6 #665

Open mspoulsen opened 8 years ago

mspoulsen commented 8 years ago

I have same problem as Sabrina describes here:

http://stackoverflow.com/questions/36929320/istanbul-how-to-ignore-default-value-branch-for-es6-babel-compiles-to-es5

Anybody know the answer?

Thanks!

arjunu commented 8 years ago

You can cover the default value branch by writing a test case where in you don't pass the value.

Chaoste commented 8 years ago

I have the same issue. My coverage report for a file looks like this:

JSFiddle with HTML Cov Report

I added the report and my spec file to the fiddle. The report says "29/32" branches. But I'm calling my functions with any combination of parameters.

mrchief commented 7 years ago

Per https://github.com/gotwarlost/istanbul/blob/master/ignoring-code-for-coverage.md#ignore-default-assignments

var object = parameter || /* istanbul ignore next: tired of writing tests */ {};

joelnet commented 7 years ago

@arjunu, In the case when the default opens a socket or writes to a file or mutates a database or performs some other side effect, not passing an argument is not always an option.

dcharbonnier commented 7 years ago

@mrchief this does not work for es6 assignments constructor(private queryClass: typeof RedisQuery /* istanbul ignore next: tired of writing tests */ = RedisQuery, private redisClass: typeof RedisClient = RedisClient) { has no effect

mrchief commented 7 years ago

@dcharbonnier This issue is specifically about ignoring a default branch. Your use case is different. Also, seems like you're using typescript? If so, then you're further away from ES6 and transpiler might be screwing things up during transpilation. I don't know for a fact, just guessing.

The point is, I know that trick works for default branches, arrow functions, try/catch blocks as I'm using it in various pieces of code in several projects.

That said, would love the contributors to chime in here. It may help to have this feature but then again, its a call that they have to make.

felixfbecker commented 6 years ago

I've been wrapping my head around how to ignore these. None of the following work (inside a list of params or object destructuring):

/* istanbul ignore next */ sourcesArchivePath = DEFAULT_SOURCES_ARCHIVE_PATH

sourcesArchivePath = /* istanbul ignore next */ DEFAULT_SOURCES_ARCHIVE_PATH

/* istanbul ignore next */ 
sourcesArchivePath = DEFAULT_SOURCES_ARCHIVE_PATH
elialgranti commented 6 years ago

For those using typescript: make sure tsc is not set to remove comments ("removeComments": true in tsconfig.json), else istanbul won't find them (duh).

jeremymoritz commented 6 years ago

This is the best i can do to avoid the "If path not taken" message. This feels like a defeat because i have tested this with all variety of parameters including leaving it out, but nothing causes the message to go away except ignoring it. I would love to be proven wrong on this:

private myPrivateFunction(
  /* istanbul ignore next: because TypeScript default assignments are untestable i guess? */
  myVar: boolean = false
) {
  return doStuff(myVar);
}

myPublicFunction(anotherVar: boolean = false) {
  return myPrivateFunction(anotherVar);
}
jeremymoritz commented 6 years ago

I'm answering my own question. As it turns out, the problem is that the function i was trying to test was a private function, and the only way i was reaching it was through other public functions. These public functions set the default value of myVar to false, but then they were always passing the value to my private method (i.e. never ignoring it for the private method to set its default. I'm so happy to say that Istanbul was right all along! Thank you, @gotwarlost for all the help your docs and comments have provided!

msafi commented 4 years ago

As stated in one of the answers on Stack Overflow, this might work

function(
  /* istanbul ignore next */
  a = 123
){

}
pete-otaqui-sky commented 3 years ago

This may be happening to you if you are transpiling to ES5, because even if you preserve your comments they may end up in a different place.

One option, if possible for you, may be to target ES6 or higher.

If you are using Typescript, then update your tsconfig.json to have { "compilerOptions": { "target": "ES6" } }, etc.

Once done, you should find that the following works as expected:

function myFunc(
  requiredProp: string,
  /* istanbul ignore next */
  optionalProp = 'defaultValue',
) {
  /* ... */
}

NB - I took the hint from this post https://github.com/microsoft/TypeScript/issues/13029#issuecomment-287901266