aboutsummaryrefslogtreecommitdiff
path: root/build2/test/script/runner.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'build2/test/script/runner.cxx')
-rw-r--r--build2/test/script/runner.cxx102
1 files changed, 101 insertions, 1 deletions
diff --git a/build2/test/script/runner.cxx b/build2/test/script/runner.cxx
index a17b9bf..c4778bf 100644
--- a/build2/test/script/runner.cxx
+++ b/build2/test/script/runner.cxx
@@ -12,11 +12,111 @@ namespace build2
{
namespace script
{
+ static ostream&
+ operator<< (ostream& o, const test& t)
+ {
+ auto print_string = [&o] (const string& s)
+ {
+ // Quote if empty or contains spaces.
+ //
+ if (s.empty () || s.find (' ') != string::npos)
+ o << '"' << s << '"';
+ else
+ o << s;
+ };
+
+ auto print_redirect = [&o, &print_string] (const redirect& r,
+ const char* prefix)
+ {
+ o << ' ' << prefix;
+
+ size_t n (string::traits_type::length (prefix));
+ assert (n > 0);
+
+ switch (r.type)
+ {
+ case redirect_type::null: o << '!'; break;
+ case redirect_type::here_string: print_string (r.value); break;
+ case redirect_type::here_document:
+ {
+ o << prefix[n - 1]; // Add another '>' or '<'.
+ print_string (r.end_marker);
+ break;
+ }
+ default: assert (false);
+ }
+ };
+
+ auto print_heredoc = [&o] (const redirect& r)
+ {
+ // Here-document value always ends with a newline.
+ //
+ o << endl << r.value << r.end_marker;
+ };
+
+ print_string (t.program.string ());
+
+ for (const auto& a: t.arguments)
+ {
+ o << ' ';
+ print_string (a);
+ }
+
+ if (t.in.type != redirect_type::none)
+ print_redirect (t.in, "<");
+
+ if (t.out.type != redirect_type::none)
+ print_redirect (t.out, ">");
+
+ if (t.err.type != redirect_type::none)
+ print_redirect (t.err, "2>");
+
+ if (t.exit.comparison != exit_comparison::eq || t.exit.status != 0)
+ o << (t.exit.comparison == exit_comparison::eq ? " == " : " != ")
+ << (int)t.exit.status;
+
+ if (t.in.type == redirect_type::here_document)
+ print_heredoc (t.in);
+
+ if (t.out.type == redirect_type::here_document)
+ print_heredoc (t.out);
+
+ if (t.err.type == redirect_type::here_document)
+ print_heredoc (t.err);
+
+ return o;
+ }
+
+ static void
+ print_test (diag_record& r, const test& t)
+ {
+ // @@ No indentation performed for here-documents. If to fix then
+ // probably need to do on diag_record level in a way similar to
+ // butl::pager approach.
+ //
+ r << t;
+ }
+
+ static void
+ print_test (const test& t)
+ {
+ diag_record r (text);
+ print_test (r, t);
+ }
+
void concurrent_runner::
run (const test& t)
{
// @@ TODO
- text << "run " << t.program.string ();
+
+ // @@ When running multiple threads will need to synchronize printing
+ // the diagnostics so it don't overlap for concurrent tests.
+ // Alternatively we can not bother with that and expect a user to
+ // re-run test operation in the single-thread mode.
+ //
+
+ if (verb >= 3)
+ print_test (t);
}
}
}