Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
Add --cov code coverage option
Browse files Browse the repository at this point in the history
  • Loading branch information
ry committed Apr 15, 2011
1 parent 80711b0 commit b4ff36a
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 0 deletions.
16 changes: 16 additions & 0 deletions lib/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,22 @@ Module.prototype._compile = function(content, filename) {
// remove shebang
content = content.replace(/^\#\!.*/, '');

// add coverage
if (process.cov) {
var lines = content.split('\n');

if (lines.length > 0) {
lines[0] = '__cov[__filename] = { 0: true}; ' + lines[0];
}

for (var i = 0; i < lines.length; i++) {
lines[i] =
lines[i].replace(/;$/, '; __cov[__filename][' + i + '] = true;');

This comment has been minimized.

Copy link
@felixge

felixge Apr 15, 2011

Interesting, is this how we'll get @isaacs back on the righteous path of using semicolons : )?

This comment has been minimized.

Copy link
@ry

ry Apr 15, 2011

Author

breaks for loops. need something slightly better...

This comment has been minimized.

Copy link
@anatoliychakkaev

anatoliychakkaev Apr 15, 2011

Also break code in if-else statements without curly brackets :(
Just have added --cov support to nodeunit, but it breaks itself. too mane else-if statements without { }

I suggest to do not add coverage stuff to files, that not pass jslint test.

UPD

I have implemented this: when code did'n pass jslint, it just ignored, it is fine for me. If you found this solution acceptable, I will submit pull request. Only wanted to figure out correct way to use third-party modules in node (Douglas Crockford's fulljslint). Now I just place inside /lib folder.

This comment has been minimized.

Copy link
@isaacs

isaacs Apr 15, 2011

It also breaks on:

foo;(space)
expr; // line comment
expr; /* block comment */
if (true) { expr; }
    for (x;
      y; z) {}

I think you need a proper AST to do this in a proper way. Mangling JavaScript with a regex is failsome.

This comment has been minimized.

Copy link
@ry

ry Apr 15, 2011

Author

it doesn't have to be perfect, but something slightly better would be preferable.

This comment has been minimized.

Copy link
@anatoliychakkaev

anatoliychakkaev Apr 21, 2011

I susggest another replace to cover more lines:

    lines[i] = lines[i]
    .replace(/;$/, ';' + covLine)
    .replace(/^\s*(return|throw|break|continue)/, covLine + ' $1');

this is working fine for my coverage tool and allows to cover lines like that:

return true;
throw new Error;

This comment has been minimized.

Copy link
@anatoliychakkaev

anatoliychakkaev Apr 21, 2011

Not only regexes. It will provide false-negative reports on lines

x = x || 9;

when x is set, this line will be reported as uncovered.

}

content = lines.join('\n');
}

function require(path) {
return Module._load(path, self);
}
Expand Down
6 changes: 6 additions & 0 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ static char *eval_string = NULL;
static int option_end_index = 0;
static bool use_debug_agent = false;
static bool debug_wait_connect = false;
static bool cov = false;
static int debug_port=5858;
static int max_stack_size = 0;

Expand Down Expand Up @@ -2029,6 +2030,7 @@ Handle<Object> SetupProcessObject(int argc, char *argv[]) {
process->Set(String::NewSymbol("ENV"), ENV);

process->Set(String::NewSymbol("pid"), Integer::New(getpid()));
process->Set(String::NewSymbol("cov"), cov ? True() : False());

// -e, --eval
if (eval_string) {
Expand Down Expand Up @@ -2171,6 +2173,7 @@ static void PrintHelp() {
" --v8-options print v8 command line options\n"
" --vars print various compiled-in variables\n"
" --max-stack-size=val set max v8 stack size (bytes)\n"
" --cov code coverage; writes node-cov.json \n"
"\n"
"Enviromental variables:\n"
"NODE_PATH ':'-separated list of directories\n"
Expand All @@ -2193,6 +2196,9 @@ static void ParseArgs(int argc, char **argv) {
if (strstr(arg, "--debug") == arg) {
ParseDebugOpt(arg);
argv[i] = const_cast<char*>("");
} else if (!strcmp(arg, "--cov")) {
cov = true;
argv[i] = const_cast<char*>("");
} else if (strcmp(arg, "--version") == 0 || strcmp(arg, "-v") == 0) {
printf("%s\n", NODE_VERSION);
exit(0);
Expand Down
17 changes: 17 additions & 0 deletions src/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@
global.GLOBAL = global;
global.root = global;
global.Buffer = NativeModule.require('buffer').Buffer;
if (process.cov) {
global.__cov = {};
}
};

startup.globalTimeouts = function() {
Expand Down Expand Up @@ -343,6 +346,20 @@
var path = NativeModule.require('path');
process.argv[0] = path.join(cwd, process.argv[0]);
}

if (process.cov) {
process.on('exit', function() {

This comment has been minimized.

Copy link
@ry

ry Apr 15, 2011

Author

misses the user-defined 'exit' handlers. maybe call back in from node.cc:2454

var coverage = JSON.stringify(__cov);
var path = NativeModule.require('path');
var fs = NativeModule.require('fs');
var filename = path.join(cwd, 'node-cov.json');
try {
fs.unlinkSync(filename);
} catch(e) {
}
fs.writeFileSync(filename, coverage);
});
}
};

// Below you find a minimal module system, which is used to load the node
Expand Down
4 changes: 4 additions & 0 deletions test/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ process.on('exit', function() {
knownGlobals.push(gc);
}

if (global.__cov) {
knownGlobals.push(__cov);
}

if (global.DTRACE_HTTP_SERVER_RESPONSE) {
knownGlobals.push(DTRACE_HTTP_SERVER_RESPONSE);
knownGlobals.push(DTRACE_HTTP_SERVER_REQUEST);
Expand Down

0 comments on commit b4ff36a

Please sign in to comment.