C++Spec 1.0.0
BDD testing for C++
Loading...
Searching...
No Matches
tap.hpp
Go to the documentation of this file.
1
2#pragma once
3
4#include <sstream>
5#include <string>
6
7#include "formatters_base.hpp"
8#include "term_colors.hpp"
9
10namespace CppSpec::Formatters {
11struct TAP final : public BaseFormatter {
12 bool first = true;
13 std::ostringstream buffer;
14
15 ~TAP() { flush(); }
16
17 std::string result_to_yaml(const Result& result);
18 void format(const Description& description) override;
19 void format(const ItBase& it) override;
20 void flush();
21};
22
23inline std::string TAP::result_to_yaml(const Result& result) {
24 if (result.is_success()) {
25 return {};
26 }
27
28 auto message = result.get_message();
29
30 std::ostringstream oss;
31 oss << " " << "---" << std::endl;
32 if (message.contains("\n")) {
33 oss << " " << "message: |" << std::endl;
34 std::string indented_message = message; // split on newlines and indent
35 std::string::size_type pos = 0;
36 while ((pos = indented_message.find('\n', pos)) != std::string::npos) {
37 indented_message.replace(pos, 1, "\n ");
38 pos += 2; // Skip over the newline and the space we just added
39 }
40 oss << " " << " " << indented_message << std::endl;
41 } else {
42 oss << " " << "message: " << '"' << result.get_message() << '"' << std::endl;
43 }
44
45 oss << " " << "severity: failure" << std::endl;
46 oss << " " << "at:" << std::endl;
47 oss << " " << " " << "file: " << result.get_location().file_name() << std::endl;
48 oss << " " << " " << "line: " << result.get_location().line() << std::endl;
49 // oss << " " << "data:" << std::endl;
50 // oss << " " << " " << "expected: " << result.get_expected() << std::endl;
51 // oss << " " << " " << "got: " << result.get_actual() << std::endl;
52 oss << " " << "..." << std::endl;
53 return oss.str();
54}
55
56inline void TAP::flush() {
57 std::string str = buffer.str();
58 std::ostringstream oss;
59 if (str[0] == '\n') {
60 oss << str[0];
61 }
62
63 if (test_counter != 1) {
64 if (color_output) {
65 oss << GREEN;
66 }
67 oss << "1.." << test_counter - 1;
68 if (color_output) {
69 oss << RESET;
70 }
71 oss << std::endl;
72 }
73
74 oss << ((str[0] == '\n') ? str.substr(1) : str);
75
76 std::cout << oss.str() << std::flush;
77 first = false;
78 reset_test_counter();
79 buffer = std::ostringstream();
80}
81
82inline void TAP::format(const Description& description) {
83 if (!first && !description.has_parent()) {
84 flush();
85 }
86
87 if (first) {
88 first = false;
89 }
90}
91
92inline void TAP::format(const ItBase& it) {
93 // Build up the description for the test by ascending the
94 // execution tree and chaining the individual descriptions together
95 std::forward_list<std::string> descriptions;
96
97 descriptions.push_front(it.get_description());
98 for (const auto* parent = it.get_parent_as<Description>(); parent->has_parent();
99 parent = parent->get_parent_as<Description>()) {
100 descriptions.push_front(parent->get_description());
101 }
102
103 std::string description = Util::join(descriptions, " ");
104
105 buffer << status_color(it.get_result().status());
106 buffer << (it.get_result().is_success() ? "ok" : "not ok");
107 buffer << reset_color();
108 buffer << " " << get_and_increment_test_counter() << " - " << description << std::endl;
109 buffer << result_to_yaml(it.get_result());
110}
111
112static TAP tap;
113
114} // namespace CppSpec::Formatters
Definition description.hpp:20
Base class for it expressions.
Definition it_base.hpp:32
Definition result.hpp:13
Definition tap.hpp:11