-
Notifications
You must be signed in to change notification settings - Fork 223
Support value-dependent hyperlinks in table generator #1246
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -426,7 +426,14 @@ def prepare_value(column, value, run_result): | |
| formatted_value = column.format_value(value, "html_cell") | ||
| result = {} | ||
| if column.href: | ||
| result["href"] = _create_link(column.href, base_dir, run_result, href_base) | ||
| # We use raw_value for the ${value} placeholder. | ||
| # If the cell is empty, we fall back to the column pattern if it exists. | ||
| subst_value = raw_value | ||
| if not subst_value and not formatted_value: | ||
| subst_value = column.pattern | ||
| result["href"] = _create_link( | ||
| column.href, base_dir, run_result, href_base, value=subst_value | ||
| ) | ||
| if not raw_value and not formatted_value: | ||
| raw_value = column.pattern | ||
| if raw_value is not None and not raw_value == "": | ||
|
|
@@ -450,7 +457,9 @@ def clean_up_results(res): | |
| if getattr(res, k) is not None | ||
| } | ||
| if toolHref: | ||
| result["href"] = _create_link(toolHref, base_dir, res, href_base) | ||
| result["href"] = _create_link( | ||
| toolHref, base_dir, res, href_base, value=res.status | ||
| ) | ||
| result["values"] = values | ||
| return result | ||
|
|
||
|
|
@@ -474,31 +483,35 @@ def clean_up_row(row): | |
| return [clean_up_row(row) for row in rows] | ||
|
|
||
|
|
||
| def _create_link(href, base_dir, runResult=None, href_base=None): | ||
| def _create_link(href, base_dir, runResult=None, href_base=None, value=None): | ||
| def get_replacements(task_file): | ||
| var_prefix = "taskdef_" if task_file.endswith(".yml") else "inputfile_" | ||
| return ( | ||
| replacements = [ | ||
| (var_prefix + "name", os.path.basename(task_file)), | ||
| (var_prefix + "path", os.path.dirname(task_file) or "."), | ||
| (var_prefix + "path_abs", os.path.dirname(os.path.abspath(task_file))), | ||
| ) + ( | ||
| ( | ||
| ("logfile_name", os.path.basename(runResult.log_file)), | ||
| ( | ||
| "logfile_path", | ||
| os.path.dirname( | ||
| os.path.relpath(runResult.log_file, href_base or ".") | ||
| ) | ||
| or ".", | ||
| ), | ||
| ( | ||
| "logfile_path_abs", | ||
| os.path.dirname(os.path.abspath(runResult.log_file)), | ||
| ), | ||
| ] | ||
| if value is not None: | ||
| replacements.append(("value", str(value))) | ||
|
|
||
| if runResult and runResult.log_file: | ||
| replacements.extend( | ||
| [ | ||
| ("logfile_name", os.path.basename(runResult.log_file)), | ||
| ( | ||
| "logfile_path", | ||
| os.path.dirname( | ||
| os.path.relpath(runResult.log_file, href_base or ".") | ||
| ) | ||
| or ".", | ||
| ), | ||
| ( | ||
| "logfile_path_abs", | ||
| os.path.dirname(os.path.abspath(runResult.log_file)), | ||
| ), | ||
| ] | ||
| ) | ||
| if runResult.log_file | ||
| else () | ||
| ) | ||
| return tuple(replacements) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can just return |
||
|
|
||
| source_file = ( | ||
| # os.path.relpath creates os-dependant paths, so standardize the output between OSs | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| # This file is part of BenchExec, a framework for reliable benchmarking: | ||
| # https://github.com/sosy-lab/benchexec | ||
| # | ||
| # SPDX-FileCopyrightText: 2007-2026 Dirk Beyer <https://www.sosy-lab.org> | ||
| # | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| import unittest | ||
| from benchexec.tablegenerator import htmltable | ||
|
|
||
|
|
||
| class TestHrefSubstitution(unittest.TestCase): | ||
| def test_create_link_with_value_substitution(self): | ||
| href = "http://example.com/${value}" | ||
| base_dir = "." | ||
| value = "test-value" | ||
|
|
||
| # We need a dummy runResult for _create_link to work if it tries to get source_file | ||
| # or we can pass None if we handle it. | ||
| # Looking at _create_link, it uses runResult to get source_file. | ||
|
|
||
| class DummyTaskId: | ||
| def __init__(self, name): | ||
| self.name = name | ||
|
|
||
| class DummyRunResult: | ||
| def __init__(self, task_name, log_file=None): | ||
| self.task_id = DummyTaskId(task_name) | ||
| self.log_file = log_file | ||
|
|
||
| def __getitem__(self, key): | ||
| return getattr(self, key) | ||
|
Comment on lines
+22
to
+32
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's just define this once instead of twice in two tests. |
||
|
|
||
| run_result = DummyRunResult("task1") | ||
|
|
||
| # Test basic substitution | ||
| link = htmltable._create_link(href, base_dir, runResult=run_result, value=value) | ||
| self.assertEqual(link, "http://example.com/test-value") | ||
|
|
||
| def test_create_link_with_value_substitution_and_other_vars(self): | ||
| href = "http://example.com/${inputfile_name}?v=${value}" | ||
| base_dir = "." | ||
| value = "123" | ||
|
|
||
| class DummyTaskId: | ||
| def __init__(self, name): | ||
| self.name = name | ||
|
|
||
| class DummyRunResult: | ||
| def __init__(self, task_name, log_file=None): | ||
| self.task_id = DummyTaskId(task_name) | ||
| self.log_file = log_file | ||
|
|
||
| run_result = DummyRunResult("dir/task1.c") | ||
|
|
||
| link = htmltable._create_link(href, base_dir, runResult=run_result, value=value) | ||
| self.assertEqual(link, "http://example.com/task1.c?v=123") | ||
|
|
||
| def test_create_link_backward_compatibility(self): | ||
| href = "http://example.com/static" | ||
| base_dir = "." | ||
|
|
||
| link = htmltable._create_link(href, base_dir) | ||
| self.assertEqual(link, "http://example.com/static") | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| unittest.main() | ||
|
Comment on lines
+65
to
+68
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can remove this, we use pytest to actually run the tests and with it it is quite convenient to run a single test file ( |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we use
replacements += [...]here the code becomes better readable because there is on indentation less.