nano 6 and the Coverage Contract


Coming with version 6 nano enforces 100% test coverage. It does so by including the pre-commit node module. This module automatically installs a pre-commit hook. The hook then runs all npm
scripts defined in the pre-commit section of package.json:

package.json:

"pre-commit": \[    
  "jshint",  
  "codestyle",  
  "mocked",  
  "test",  
  "checkcoverage"  
\]

We see that besides test coverage the hook also ensures that the code passes the linter, the code style guidelines and, of course, the tests.

Lets see how it works by committing something:

\[jo@localhost nano\]$ echo "I have changed the README!" >> README.md   
\[jo@localhost nano\]$ git commit -am"README changes"
\> nano@6.0.0 jshint /home/jo/nano  
\> jshint tests/\*/\*/\*.js lib/\*.js  

\> nano@6.0.0 codestyle /home/jo/nano  
\> jscs -p google tests/\*/\*/\*.js lib/\*.js
No code style errors found.
\> nano@6.0.0 mocked /home/jo/nano  
\> tape tests/\*/\*/\*.js
TAP version 13    
\# nano/tests/unit/attachment/destroy:1  
ok 1 object    
...
1..556    
\# tests 556  
\# pass  556
\# ok  

\> nano@6.0.0 test /home/jo/nano  
\> DEBUG=\* NOCK\_OFF=true istanbul cover tape tests/\*/\*/\*.js
  nock.intercept Overriding ClientRequest +0ms  
...
\=============================== Coverage summary ===============================  
Statements   : 100% ( 293/293 )    
Branches     : 100% ( 157/157 )    
Functions    : 100% ( 52/52 )    
Lines        : 100% ( 290/290 )    
\================================================================================
1..535    
\# tests 535  
\# pass  535
\# ok  

\> nano@6.0.0 checkcoverage /home/jo/nano  
\> istanbul check-coverage --statements 100 --functions 100 --lines 100  
\> --branches 100
\[playground 259e275\] README changes  
 1 file changed, 1 insertion(+)

Yeah! We see that before the commit was saved all tests were run and code coverage was determined. Ony if all of the scripts pass, the commit gets saved.

OK, lets try break nano:

\[jo@localhost nano\]$ sed -i -e 's/\_db\_updates/\_dbupdates/g' lib/nano.js  
\[jo@localhost nano\]$ git commit -am"I break you :P"
...
pre-commit: You've failed to pass all the hooks.    
pre-commit:    
pre-commit: The "npm run mocked" script failed.    
pre-commit:    
pre-commit: You can skip the git pre-commit hook by running:    
pre-commit:    
pre-commit:   git commit -n (--no-verify)    
pre-commit:    
pre-commit: But this is not adviced as your tests are obviously failing.

Booom. The commit was rejected.
Of course we could enforce our bad commit with git commit --no-verify but thats not the point. The point is that we set up a toolchain which ensures that nanos code matches the guidelines defined inside the project. If they will change in the future, they must be changed explicitely.

I think this project serves as a good example for other projects in the Node world. I will embrace this setup by myself and I am looking forward to my next project.

Written by: Johannes Jörg Schmidt

Originally published at blog.yld.io on November 12, 2014.


Written by YLDNovember 3rd, 2014


Share this article