UNPKG

6.49 kBMarkdownView Raw
1
2babel-plugin-\_\_coverage\_\_
3=============================
4
5[![Build Status](https://travis-ci.org/dtinth/babel-plugin-__coverage__.svg?branch=master)](https://travis-ci.org/dtinth/babel-plugin-__coverage__)
6[![codecov.io](https://codecov.io/github/dtinth/babel-plugin-__coverage__/coverage.svg?branch=master)](https://codecov.io/github/dtinth/babel-plugin-__coverage__?branch=master)
7
8A Babel plugin that instruments your code with `__coverage__` variable.
9The resulting `__coverage__` object is compatible with Istanbul.
10
11__Note:__ This plugin does not generate any report or save any data to any file;
12it only adds instrumenting code to your JavaScript source code.
13To integrate with testing tools, please see the [Integrations](#integrations) section.
14
15
16## Usage
17
18Install it:
19
20```
21npm install --save-dev babel-plugin-__coverage__
22```
23
24Add it to `.babelrc` in test mode:
25
26```js
27{
28 "env": {
29 "test": {
30 "plugins": [ "__coverage__" ]
31 }
32 }
33}
34```
35
36
37## Integrations
38
39### karma
40
41It _just works_ with Karma. First, make sure that the code is already transpiled by Babel (either using `karma-babel-preprocessor`, `karma-webpack`, or `karma-browserify`). Then, simply set up [karma-coverage](https://github.com/karma-runner/karma-coverage) according to the docs, but __don’t add the `coverage` preprocessor.__ This plugin has already instrumented your code, and Karma should pick it up automatically.
42
43It has been tested with [bemusic/bemuse](https://codecov.io/github/bemusic/bemuse) project, which contains ~2400 statements.
44
45
46### node.js (using nyc)
47
48Configure Mocha to transpile JavaScript code using Babel, then you can run your tests with [`nyc`](https://github.com/bcoe/nyc), which will collect all the coverage report. You need to __configure NYC not to instrument your code__ by adding setting this in your `package.json`:
49
50```js
51 "nyc": {
52 "include": [ "/" ]
53 },
54```
55
56
57## Canned Answers
58
59### There’s already Isparta. Why another coverage tool?
60
61Isparta is the de-facto tool for measuring coverage against ES6 code, which extends Istanbul with ES6 support. But it did not go that smoothly.
62
63So I’ve been trying to get webpack 2 to work with Istanbul/Isparta.
64To benefit from [webpack 2’s with tree shaking](http://www.2ality.com/2015/12/webpack-tree-shaking.html), I need to keep `import` and `export` statements in JavaScript file intact. I can’t get code coverage to work. Inspecting Isparta’s [source code](https://github.com/douglasduteil/isparta/blob/749862a7d1810dd25b8c62c9e613720b57d36da1/src/instrumenter.js), here’s what it does:
65
661. It uses Babel to transpile ES6 back into ES5, saving the source map.
672. It uses Istanbul to instrument the transpiled source code. This produces some initial metadata (in a global variable called `__coverage__`) which contains the location of each statement, branch, and function. Unfortunately, the location is mapped to the transpiled code. Therefore,
683. The metadata is processed using source map obtained from step 1 to map the location in transpiled code back to the location in the original source code.
694. The final instrumented code in ES5 is generated. This code shouldn’t be processed through Babel again, or it will be redundant and leads to slower builds.
70
71Since transforming `import`/`export` statements has now been disabled, instrumentation now dies at step 2.
72
73So I looked for something else, and I found [babel-plugin-transform-adana](https://github.com/adana-coverage/babel-plugin-transform-adana). I tried it out immediately.
74It turns out that although adana also generates the `__coverage__` variable, it is in its own format. This means that most tools that works with Istanbul-format coverage data (including `karma-coverage` and `nyc`) will not work with this. Tools need to be reinvented for each test harness.
75
76Now, with lots of tools to help developers author Babel 6 plugins,
77such as [the Babel Handbook](https://github.com/thejameskyle/babel-handbook) and [the AST Explorer](https://astexplorer.net/), it’s not that hard to create Babel plugins today. So I gave it a shot. This is my first Babel plugin.
78
79It turns out that I can create a rudimentary instrumenter with Babel 6 in roughly 300 lines of code (compare to 1,000 in Istanbul). Babel has A LOT of cool stuff to make transpilation easy, from [babel-template](https://github.com/babel/babel/tree/master/packages/babel-template) to [babel-traverse](https://github.com/babel/babel/tree/master/packages/babel-traverse) to [babel-helper-function-name](https://github.com/babel/babel/tree/master/packages/babel-helper-function-name). Babel’s convenient API also handles a lot of edge cases automatically. For example, if a function begins with `'use strict'` statement, prepending a statement into its body will insert it _after_ the `'use strict'` statement. It also automatically convert `if`/`while`/`for` body into a `BlockStatement` when a statement is inserted before the body.
80
81
82### Is it stable?
83
84Well, I wrote most of it in two nights and have only tested some basic stuffs.
85So speaking in terms of maturity, this one is very new.
86
87However, I tried using them in some bigger projects, such as [bemusic/bemuse](https://github.com/bemusic/bemuse) (contains around 2400 statements) without much problem, and it works fine.
88
89
90### How do I ignore branches/statements?
91
92I haven’t implemented it. I once [posted an issue on Isparta](https://github.com/douglasduteil/isparta/issues/24) asking about ignoring statements in Isparta (which is now fixed). But later, I just think that “coverage is just a number.” Also, I don’t have time to implement it.
93
94Pull requests are welcome!
95
96
97### How do I ignore certain files?
98
99Well, [Codecov](https://codecov.io/) allows you to ignore files from their web interface, so if you’re using that, then that’s the easiest way!
100
101Oh yeah if you use webpack, you can set up two loaders.
102One for your production code (with this plugin enabled), and another for your test code (without this plugin).
103
104And if you’re using Babel, you can precompile your production code with coverage enabled into another directory like `babel src --plugins __coverage__ -d lib-cov` and tell your tests to redirect to that instead.
105
106But if you’re using something like `browserify` or `babel-register` where you can only enable or disable this plugin for every source file, then sorry, I haven’t implemented it yet, because I don’t need it now. If you want it, pull requests are welcome!