[gjs] Write function line number before unique key in FN entries.
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs] Write function line number before unique key in FN entries.
- Date: Sat, 17 Jan 2015 01:00:09 +0000 (UTC)
commit 96628cb56d3822ee4138179c5c7981b85438088a
Author: Sam Spilsbury <smspillaz gmail com>
Date: Mon Jan 5 09:25:35 2015 +0800
Write function line number before unique key in FN entries.
Before we were not writing the line number before the unique key
but instead as part of the unique key. This is technically not
compliant with the lcov specification, which requires th
following:
FN:<line number>,<function name>
For some reason, genhtml never complained about this and silently
just accepted the function names. Other tools that work with lcov
data, like lcov_cobertura and lcov-result-merge are far less
forgiving.
Fixes BGO #742362
gjs/coverage.cpp | 18 +++++++++++--
modules/coverage.js | 3 ++
test/gjs-test-coverage.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 77 insertions(+), 5 deletions(-)
---
diff --git a/gjs/coverage.cpp b/gjs/coverage.cpp
index 2f4d843..73ed9e8 100644
--- a/gjs/coverage.cpp
+++ b/gjs/coverage.cpp
@@ -70,6 +70,7 @@ typedef struct _GjsCoverageBranch {
typedef struct _GjsCoverageFunction {
char *key;
+ unsigned int line_number;
unsigned int hit_count;
} GjsCoverageFunction;
@@ -126,7 +127,7 @@ write_function_foreach_func(gpointer value,
GOutputStream *stream = (GOutputStream *) user_data;
GjsCoverageFunction *function = (GjsCoverageFunction *) value;
- g_output_stream_printf(stream, NULL, NULL, NULL, "FN:%s\n", function->key);
+ g_output_stream_printf(stream, NULL, NULL, NULL, "FN:%d,%s\n", function->line_number, function->key);
}
static void
@@ -503,9 +504,11 @@ get_executed_lines_for(GjsCoverage *coverage,
static void
init_covered_function(GjsCoverageFunction *function,
char *key,
+ unsigned int line_number,
unsigned int hit_count)
{
function->key = key;
+ function->line_number = line_number;
function->hit_count = hit_count;
}
@@ -558,12 +561,21 @@ convert_and_insert_function_decl(GArray *array,
return FALSE;
}
- unsigned int line_number = JSVAL_TO_INT(hit_count_property_value);
+ jsval line_number_property_value;
+ if (!JS_GetProperty(context, object, "line", &line_number_property_value) ||
+ !JSVAL_IS_INT(line_number_property_value)) {
+ gjs_throw(context, "Failed to get line property for function object");
+ return FALSE;
+ }
+
+ unsigned int line_number = JSVAL_TO_INT(line_number_property_value);
+ unsigned int hit_count = JSVAL_TO_INT(hit_count_property_value);
GjsCoverageFunction info;
init_covered_function(&info,
utf8_string,
- line_number);
+ line_number,
+ hit_count);
g_array_append_val(array, info);
diff --git a/modules/coverage.js b/modules/coverage.js
index e2b98bc..1c29992 100644
--- a/modules/coverage.js
+++ b/modules/coverage.js
@@ -591,7 +591,10 @@ function _convertFunctionCountersToArray(functionCounters) {
* of that object */
for (let key in functionCounters) {
let func = functionCounters[key];
+ /* The name of the function contains its line, after the first
+ * colon. Split the name and retrieve it here */
arrayReturn.push({ name: key,
+ line: Number(key.split(':')[1]),
hitCount: func.hitCount });
}
diff --git a/test/gjs-test-coverage.cpp b/test/gjs-test-coverage.cpp
index 462c001..28929a7 100644
--- a/test/gjs-test-coverage.cpp
+++ b/test/gjs-test-coverage.cpp
@@ -802,6 +802,10 @@ has_function_name(const char *line,
/* Advance past "FN:" */
line += 3;
+ /* Advance past the first comma */
+ while (*(line - 1) != ',')
+ ++line;
+
return strncmp(line,
expected_function_name,
strlen(expected_function_name)) == 0;
@@ -835,8 +839,7 @@ test_function_names_written_to_coverage_data(gpointer fixture_data,
};
const gsize expected_function_names_len = G_N_ELEMENTS(expected_function_names);
- /* There are two possible branches here, the second should be taken
- * and the first should not have been */
+ /* Just expect that we've got an FN matching out expected function names */
g_assert(coverage_data_matches_values_for_key(coverage_data_contents,
"FN:",
expected_function_names_len,
@@ -846,6 +849,56 @@ test_function_names_written_to_coverage_data(gpointer fixture_data,
g_free(coverage_data_contents);
}
+static gboolean
+has_function_line(const char *line,
+ gpointer user_data)
+{
+ /* User data is const char ** */
+ const char *expected_function_line = *((const char **) user_data);
+
+ /* Advance past "FN:" */
+ line += 3;
+
+ return strncmp(line,
+ expected_function_line,
+ strlen(expected_function_line)) == 0;
+}
+
+static void
+test_function_lines_written_to_coverage_data(gpointer fixture_data,
+ gconstpointer user_data)
+{
+ GjsCoverageToSingleOutputFileFixture *fixture = (GjsCoverageToSingleOutputFileFixture *) fixture_data;
+
+ const char *script_with_functions =
+ "function f(){}\n"
+ "\n"
+ "function g(){}\n";
+
+ write_to_file_at_beginning(fixture->base_fixture.temporary_js_script_open_handle,
+ script_with_functions);
+
+ char *coverage_data_contents =
+ eval_script_and_get_coverage_data(fixture->base_fixture.context,
+ fixture->base_fixture.coverage,
+ fixture->base_fixture.temporary_js_script_filename,
+ fixture->output_file_directory,
+ NULL);
+ const char * expected_function_lines[] = {
+ "1",
+ "3"
+ };
+ const gsize expected_function_lines_len = G_N_ELEMENTS(expected_function_lines);
+
+ g_assert(coverage_data_matches_values_for_key(coverage_data_contents,
+ "FN:",
+ expected_function_lines_len,
+ has_function_line,
+ (gpointer) expected_function_lines,
+ sizeof(const char *)));
+ g_free(coverage_data_contents);
+}
+
typedef struct _FunctionHitCountData {
const char *function;
unsigned int hit_count_minimum;
@@ -1435,6 +1488,10 @@ void gjs_test_add_tests_for_coverage()
&coverage_to_single_output_fixture,
test_function_names_written_to_coverage_data,
NULL);
+ add_test_for_fixture("/gjs/coverage/function_lines_written_to_coverage_data",
+ &coverage_to_single_output_fixture,
+ test_function_lines_written_to_coverage_data,
+ NULL);
add_test_for_fixture("/gjs/coverage/function_hit_counts_written_to_coverage_data",
&coverage_to_single_output_fixture,
test_function_hit_counts_written_to_coverage_data,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]