jeffrifwald / babel-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
144 stars 23 forks source link

Weird stuff, semicolon at end of statement treated as branch #46

Closed silkentrance closed 8 years ago

silkentrance commented 8 years ago

In my project, I have a weird problem that will treat semicolons at the end of the statement as separate branches.

I am using babel 6.3.19 and babel-istanbul 0.5.9.

Here is an excerpt from the generated coverage report

1            let target = args[0];

            // we do not support constructor injection
            if (args.length == 1)
            {
                util.log(
                    messages.MSG_USE_PROPERTY_INJECTION_INSTEAD,
                    target, null, ifaces, logger.error
                );

                throw new InjectionError(
                    messages.MSG_USE_PROPERTY_INJECTION_INSTEAD
                );
            }

2            const attr = args[1];
3            const descriptor = args[2];

Where (1) to (3) will cause missing coverage due to the ; not being covered.

You can check this out yourself: https://github.com/coldrye-es/inxs.git

Simply run (on preferably a new VM running debian/stretch)

make deps-global
make deps
make cover

The coverage report will be available under ./build/cover/index.html. Navigating to src/inxs.es will give you that information.

silkentrance commented 8 years ago

Even more weird is, that when I remove the trailing semicolons, the coverage report will still be the same, yet in the rendered HTML, one cannot see what is reported for being not covered.

jeffrifwald commented 8 years ago

You'll want to look at the transpiled code to see what babel might be sticking in there to make your coverage fail. This doesn't have anything to do with the semicolons, as there is probably just a branch of code hidden in the transpiled version.

If you are messing around with the arguments object in this method above, babel is likely injecting a branch of code to check something for compatibility. If you can show me the source and then the compiled code next to each other, I might be able to help you out more. Every now and then babel produces some code that just has to be skipped in coverage for one reason or another.

silkentrance commented 8 years ago

Yes, you are right. I've made istanbul ignore the specific statements for the time being. Thanks!

To clear this up a bit, the function being called was defined like this

return function injectionDecorator(...args) {...}

and the generated code will look like this

      /* istanbul ignore next */
      var target = arguments.length <= 0 || arguments[0] === undefined ? undefined : arguments[0];

whatever the reason is for asserting that the arrays length is <= 0...