Permalink
Browse files

Added support for extracting jscoverage info.

Credit to Anthony Baxter for most of the implementation.
  • Loading branch information...
jacobsa committed Feb 5, 2012
1 parent 8853bd8 commit 315a999194b4828324b0aa4e10c8e2f14252a3c4
Showing with 57 additions and 3 deletions.
  1. +20 −1 gjstest/internal/cpp/gjstest.cc
  2. +30 −1 gjstest/internal/cpp/run_tests.cc
  3. +7 −1 gjstest/internal/cpp/run_tests.h
@@ -46,6 +46,12 @@ DEFINE_string(js_files, "",
"The list of JS files to execute, comma separated.");
DEFINE_string(xml_output_file, "", "An XML file to write results to.");
+
+DEFINE_string(coverage_output_file, "",
+ "A file to which coverage info should be written. If this is "
+ "specified, it is assumed that the input JS files are "
+ "instrumented using jscoverage.");
+
DEFINE_string(filter, "", "Regular expression for test names to run.");
// Browser support
@@ -158,7 +164,15 @@ static bool Run() {
// Run any tests registered.
string output;
string xml;
- const bool success = RunTests(scripts, FLAGS_filter, &output, &xml);
+ string coverage_info;
+
+ const bool success =
+ RunTests(
+ scripts,
+ FLAGS_filter,
+ &output,
+ &xml,
+ FLAGS_coverage_output_file.empty() ? NULL : &coverage_info);
// Log the output.
std::cout << output;
@@ -168,6 +182,11 @@ static bool Run() {
WriteStringToFileOrDie(xml, FLAGS_xml_output_file);
}
+ // Write out coverage info to the appropriate place.
+ if (!FLAGS_coverage_output_file.empty()) {
+ WriteStringToFileOrDie(coverage_info, FLAGS_coverage_output_file);
+ }
+
return success;
}
@@ -54,6 +54,26 @@ using v8::Value;
namespace gjstest {
+// JS code that can be executed to extract the information generated by
+// jscoverage.
+static const char kCoverageExtractionJs[] =
+ "var _$coverageout = '';"
+ "for (file in _$jscoverage) {"
+ " _$coverageout += 'SF:' + file + '\\n';"
+ " for (lineno in _$jscoverage[file]) {"
+ " if (lineno != undefined && lineno != 'source') {"
+ " var count = _$jscoverage[file][lineno];"
+ " if (count > 0) {"
+ " _$coverageout += 'DA:' + lineno + ',1\\n';"
+ " } else {"
+ " _$coverageout += 'DA:' + lineno + ',0\\n';"
+ " }"
+ " }"
+ " }"
+ " _$coverageout += 'end_of_record\\n';"
+ "}"
+ "_$coverageout;";
+
// Create XML output given an overall duration in seconds, a list of test names
// in the order of execution, a map from test names to durations, and a map from
// failed test names to failure messages.
@@ -186,7 +206,8 @@ bool RunTests(
const NamedScripts& scripts,
const string& test_filter_string,
string* output,
- string* xml) {
+ string* xml,
+ string* coverage_info) {
const RE2 test_filter(test_filter_string.empty() ? ".*" : test_filter_string);
// Take ownership of all handles created.
@@ -281,6 +302,14 @@ bool RunTests(
test_durations,
test_failure_messages);
+ // Extract coverage info if requested.
+ if (coverage_info) {
+ const Local<Value> coverage_result = ExecuteJs(kCoverageExtractionJs, "");
+ CHECK(coverage_result->IsString());
+
+ *coverage_info += ConvertToString(coverage_result);
+ }
+
return success;
}
@@ -31,12 +31,18 @@ class NamedScripts;
// If test_filter is non-empty, it is interpreted to be a regular expression
// specifying which test names should be run. Others will be excluded.
//
+// If coverage_info is non-NULL, the JS scripts are assumed to be instrumented
+// with jscoverage (that is, they are the output of the jscoverage tool). The
+// coverage information generated by the code will be extracted after the tests
+// are run and returned LCOV format in *coverage_info.
+//
// This function is not safe to be called multiple times concurrently.
bool RunTests(
const NamedScripts& scripts,
const string& test_filter,
string* output,
- string* xml);
+ string* xml,
+ string* coverage_info);
} // namespace gjstest

0 comments on commit 315a999

Please sign in to comment.