Skip to content

Commit bd2af3b

Browse files
committed
Add configurable mismatch template path
1 parent dcd6183 commit bd2af3b

3 files changed

Lines changed: 99 additions & 18 deletions

File tree

NEWS.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ every change, see the Git log.
66

77
Latest
88
------
9-
* tbd
9+
* Minor: Added ``set_mismatch_template()`` to configure the mismatch HTML template path.
10+
* Minor: Custom mismatch template paths now fail if they cannot be resolved.
11+
* Minor: Added template format validation for ``oldText`` and ``newText`` markers.
1012

1113
2.0.0
1214
-----

README.rst

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,48 @@ Overview
88
datarecorder is a simple C++ library that is meant to provide simple helper
99
functions to ease sometimes tedious testing tasks.
1010

11+
Build and test
12+
==============
13+
14+
Configure::
15+
16+
./waf configure
17+
18+
Build::
19+
20+
./waf build
21+
22+
Run tests::
23+
24+
./waf build --run_tests
25+
26+
Mismatch template
27+
=================
28+
29+
By default, datarecorder will try to find this template:
30+
31+
- ``visualizer/recording_diff.html``
32+
33+
You can override this with::
34+
35+
recorder.set_mismatch_template("path/to/recording_diff.html");
36+
37+
If the provided path is relative, datarecorder resolves it by searching
38+
backwards from the current working directory.
39+
40+
If you provide a custom mismatch template path and it cannot be found,
41+
recording will fail.
42+
43+
Template requirements
44+
---------------------
45+
46+
The template must contain both of these JavaScript markers (using backticks)::
47+
48+
const oldText = `...`;
49+
const newText = `...`;
50+
51+
These placeholders are replaced with recording data and mismatch data.
52+
1153
License
1254
-------
1355
The stub library is released under the BSD license, see the LICENSE.rst file.

src/datarecorder/datarecorder.hpp

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,20 @@ class datarecorder
119119
m_recording_filename = filename;
120120
}
121121

122+
/// Set the mismatch template used for mismatch HTML output.
123+
///
124+
/// If this path is relative, it will be resolved by searching backwards
125+
/// from the current working directory.
126+
///
127+
/// If this path is provided and cannot be found, recording will fail.
128+
void set_mismatch_template(std::filesystem::path mismatch_template)
129+
{
130+
VERIFY(!mismatch_template.empty(),
131+
"Mismatch template path must not be empty", mismatch_template);
132+
133+
m_mismatch_template = mismatch_template;
134+
}
135+
122136
/// Set the callback that will be called when a mismatch is found.
123137
///
124138
/// If no mismatch handler is set, a default mismatch handler will be used.
@@ -237,33 +251,43 @@ class datarecorder
237251

238252
void determine_mismatch_handler()
239253
{
240-
auto visualizer = find_relative_path("visualizer/recording_diff.html");
254+
tl::expected<std::filesystem::path, poke::error> mismatch_template =
255+
find_relative_path(
256+
m_mismatch_template.value_or("visualizer/recording_diff.html"));
241257

242-
if (visualizer)
258+
if (mismatch_template)
243259
{
244260
m_monitor.log(poke::log_level::debug,
245-
poke::log::str{"message", "Using diff visualizer"},
246-
poke::log::str{"path", visualizer->string()});
261+
poke::log::str{"message", "Using mismatch template"},
262+
poke::log::str{"path", mismatch_template->string()});
247263

248-
m_on_mismatch = [this, visualizer](mismatch_info mismatch)
264+
m_on_mismatch = [this, mismatch_template = *mismatch_template](
265+
mismatch_info mismatch)
249266
{
250267
// Call the diff handler
251-
return diff_mismatch_handler(*visualizer, mismatch);
268+
return diff_mismatch_handler(mismatch_template, mismatch);
252269
};
270+
return;
253271
}
254-
else
255-
{
256-
m_monitor.log(
257-
poke::log_level::debug,
258-
poke::log::str{"message", "Using default mismatch handler"},
259-
poke::log::str{"path", visualizer.error().message()});
260272

261-
m_on_mismatch = [this](mismatch_info mismatch)
262-
{
263-
// Call the default handler
264-
return default_mismatch_handler(mismatch);
265-
};
273+
if (m_mismatch_template)
274+
{
275+
VERIFY(mismatch_template,
276+
"Could not find configured mismatch template",
277+
m_mismatch_template.value(),
278+
mismatch_template.error().message());
266279
}
280+
281+
m_monitor.log(
282+
poke::log_level::debug,
283+
poke::log::str{"message", "Using default mismatch handler"},
284+
poke::log::str{"path", mismatch_template.error().message()});
285+
286+
m_on_mismatch = [this](mismatch_info mismatch)
287+
{
288+
// Call the default handler
289+
return default_mismatch_handler(mismatch);
290+
};
267291
}
268292

269293
auto determine_mismatch_path() -> std::filesystem::path
@@ -435,6 +459,18 @@ class datarecorder
435459
std::regex oldTextPattern(R"((const\s+oldText\s*=\s*`)([^`]*)(`;))");
436460
std::regex newTextPattern(R"((const\s+newText\s*=\s*`)([^`]*)(`;))");
437461

462+
if (!std::regex_search(file_content, oldTextPattern) ||
463+
!std::regex_search(file_content, newTextPattern))
464+
{
465+
return poke::make_error(
466+
std::make_error_code(std::errc::invalid_argument),
467+
poke::log::str{"message",
468+
"Mismatch template must contain both `const "
469+
"oldText = `...`;` "
470+
"and `const newText = `...`;` markers"},
471+
poke::log::str{"template_path", recording_diff_html.string()});
472+
}
473+
438474
file_content = std::regex_replace(file_content, oldTextPattern,
439475
"$1" + escaped_recording_data + "$3");
440476
file_content = std::regex_replace(file_content, newTextPattern,
@@ -479,6 +515,7 @@ class datarecorder
479515

480516
std::optional<std::string> m_recording_filename;
481517
std::optional<std::filesystem::path> m_recording_dir;
518+
std::optional<std::filesystem::path> m_mismatch_template;
482519
std::optional<std::function<poke::error(mismatch_info)>> m_on_mismatch;
483520
};
484521

0 commit comments

Comments
 (0)