Skip to content

Commit a7b1bf5

Browse files
committed
Super fancy printer formats
1 parent 23d497c commit a7b1bf5

20 files changed

+372
-192
lines changed

examples/sample/example_spec.cpp

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ describe bool_spec("Some Tests", $ {
1313
it("true", _ {
1414
expect(true).to_equal(true);
1515
});
16-
1716
});
1817

1918
int i = 4;
@@ -192,18 +191,12 @@ describe list_spec("A list spec", $ {
192191
/* Here is the declaration of fabs description defined in an other file (fabs_spec.c in this sample)*/
193192
int main(){
194193
bool r = true;
195-
r &= bool_spec.run();
196-
r &= abs_spec.run();
197-
r &= strcmp_spec.run();
198-
r &= vector_spec.run();
199-
r &= let_spec.run();
200-
// #undef expect
201-
// #undef it
202-
// Description d("halp", _ {});
203-
// It i = d.it("me", _ {});
204-
// auto expectation = i.expect(2);
205-
// auto be_between = expectation.to_be_between(1,3);
206-
// be_between();
207-
//strcmp_spec.run();
194+
PrettyPrinter printer = Printer::verbose;
195+
r &= bool_spec.run(printer);
196+
r &= abs_spec.run(printer);
197+
r &= strcmp_spec.run(printer);
198+
r &= vector_spec.run(printer);
199+
r &= let_spec.run(printer);
200+
r &= list_spec.run(printer);
208201
return r ? EXIT_SUCCESS : EXIT_FAILURE;
209202
}

include/class_description.hpp

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,40 +18,49 @@ class ClassDescription : public Description {
1818
typedef std::function<void(ClassDescription<T>&)> block_t;
1919
block_t body;
2020
bool first;
21+
std::string type = "";
2122

2223
public:
2324
T subject; // subject field public for usage in `expect([self.]subject)`
2425

2526
// Constructor
2627
// if there's no explicit subject given, then use
2728
// the default constructor of the given type as the implicit subject.
28-
ClassDescription<T>(block_t body) : Description(), body(body), subject(T()) {
29-
this->descr = Pretty::to_word_type(subject);
29+
ClassDescription<T>(block_t body)
30+
: Description(),
31+
body(body),
32+
type(" : " + Util::demangle(typeid(T).name())),
33+
subject(T()) {
34+
this->descr = Pretty::to_word(subject);
3035
};
3136

3237
ClassDescription<T>(std::string descr, block_t body)
3338
: Description(descr), body(body), subject(T()){};
3439

3540
ClassDescription(T subject, block_t body)
36-
: Description(Pretty::to_word_type(subject)),
41+
: Description(Pretty::to_word(subject)),
3742
body(body),
43+
type(" : " + Util::demangle(typeid(T).name())),
3844
subject(subject){};
3945

4046
ClassDescription(std::string descr, T subject, block_t body)
4147
: Description(descr), body(body), subject(subject){};
4248

4349
ClassDescription(T& subject, block_t body)
44-
: Description(Pretty::to_word_type(subject)),
50+
: Description(Pretty::to_word(subject)),
4551
body(body),
52+
type(" : " + Util::demangle(typeid(T).name())),
4653
subject(subject){};
4754

4855
ClassDescription(std::string descr, T& subject, block_t body)
4956
: Description(descr), body(body), subject(subject){};
5057

5158
template <typename U>
5259
ClassDescription(std::initializer_list<U> init_list, block_t body)
53-
: body(body), subject(T(init_list)) {
54-
this->descr = Pretty::to_word_type(subject);
60+
: body(body),
61+
type(" : " + Util::demangle(typeid(T).name())),
62+
subject(T(init_list)) {
63+
this->descr = Pretty::to_word(subject);
5564
};
5665

5766
template <typename U>
@@ -68,7 +77,9 @@ class ClassDescription : public Description {
6877
Result context(T subject, block_t body);
6978
Result context(T& subject, block_t body);
7079
Result context(block_t body);
71-
Result run() override;
80+
Result run(BasePrinter& printer) override;
81+
virtual std::string get_descr() override;
82+
virtual const std::string get_descr() const override;
7283
};
7384

7485
template <class T>
@@ -81,7 +92,7 @@ Result ClassDescription<T>::context(
8192
context.set_parent(this);
8293
context.before_eaches = this->before_eaches;
8394
context.after_eaches = this->after_eaches;
84-
return context.run();
95+
return context.run(this->get_printer());
8596
}
8697

8798
template <class T>
@@ -97,7 +108,7 @@ Result ClassDescription<T>::context(
97108
context.set_parent(this);
98109
context.before_eaches = this->before_eaches;
99110
context.after_eaches = this->after_eaches;
100-
return context.run();
111+
return context.run(this->get_printer());
101112
}
102113

103114
template <class T>
@@ -108,7 +119,7 @@ Result Description::context(T subject,
108119
context.set_parent(this);
109120
context.before_eaches = this->before_eaches;
110121
context.after_eaches = this->after_eaches;
111-
return context.run();
122+
return context.run(this->get_printer());
112123
}
113124

114125
// template <class T>
@@ -124,7 +135,7 @@ Result Description::context(std::initializer_list<U> init_list,
124135
context.set_parent(this);
125136
context.before_eaches = this->before_eaches;
126137
context.after_eaches = this->after_eaches;
127-
return context.run();
138+
return context.run(this->get_printer());
128139
}
129140

130141
/**
@@ -152,7 +163,7 @@ template <class T>
152163
Result ClassDescription<T>::it(std::string name,
153164
std::function<void(ItCd<T>&)> body) {
154165
ItCd<T> it(*this, this->subject, name, body);
155-
Result result = it.run();
166+
Result result = it.run(this->get_printer());
156167
exec_after_eaches();
157168
exec_before_eaches();
158169
return result;
@@ -182,19 +193,39 @@ Result ClassDescription<T>::it(std::string name,
182193
template <class T>
183194
Result ClassDescription<T>::it(std::function<void(ItCd<T>&)> body) {
184195
ItCd<T> it(*this, this->subject, body);
185-
Result result = it.run();
196+
Result result = it.run(this->get_printer());
186197
exec_after_eaches();
187198
exec_before_eaches();
188199
return result;
189200
}
190201

191202
template <class T>
192-
Result ClassDescription<T>::run() {
193-
std::cout << padding() << descr << std::endl;
203+
Result ClassDescription<T>::run(BasePrinter& printer) {
204+
if (not this->has_printer()) this->set_printer(printer);
205+
printer.print(*this);
194206
body(*this);
195-
std::cout << std::endl;
207+
for (auto a : after_alls) a();
208+
if (this->get_parent() == nullptr) printer.flush();
196209
return this->get_status() ? Result::success : Result::failure;
197210
}
211+
template <class T>
212+
std::string ClassDescription<T>::get_descr() {
213+
if (this->get_printer().mode == BasePrinter::Mode::TAP) {
214+
return descr;
215+
} else {
216+
return descr + type;
217+
}
218+
}
219+
220+
template <class T>
221+
const std::string ClassDescription<T>::get_descr() const {
222+
if (const_cast<ClassDescription<T>*>(this)->get_printer().mode ==
223+
BasePrinter::Mode::TAP) {
224+
return descr;
225+
} else {
226+
return descr + type;
227+
}
228+
}
198229

199230
template <class T>
200231
Expectations::Expectation<T> ItCd<T>::is_expected() {
@@ -204,11 +235,18 @@ Expectations::Expectation<T> ItCd<T>::is_expected() {
204235
}
205236

206237
template <class T>
207-
Result ItCd<T>::run() {
208-
if (!this->needs_descr()) {
209-
std::cout << padding() << get_descr() << std::endl;
238+
Result ItCd<T>::run(BasePrinter& printer) {
239+
if (!this->needs_descr() && printer.mode == BasePrinter::Mode::verbose) {
240+
printer.print(*this);
210241
}
242+
211243
body(*this);
244+
245+
if (printer.mode == BasePrinter::Mode::TAP ||
246+
printer.mode == BasePrinter::Mode::terse) {
247+
printer.print(*this);
248+
}
249+
212250
auto cd = static_cast<ClassDescription<T>*>(this->get_parent());
213251
cd->reset_lets();
214252
return this->get_status() ? Result::success : Result::failure;

include/cppspec.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @file
33
* @brief The core header file for Cppspec
44
*/
5-
#include "class_description.hpp"
5+
#include "printer.hpp"
66

77
#define _ [=](auto &self) mutable
88
#define $ [](auto &self)
@@ -18,7 +18,7 @@
1818
#define after_all self.after_all
1919
#define after_each self.after_each
2020
#define let(name, body) \
21-
auto name = make_let(#name, body); \
21+
auto name = self.make_let(#name, body); \
2222
self.let(#name, name);
2323

2424
typedef Description describe;

include/description.hpp

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,14 @@ class Description : public Runnable {
6666
void exec_before_eaches();
6767
void exec_after_eaches();
6868

69-
void let(std::string, Runnable &body);
70-
Result run() override;
69+
template <typename T>
70+
auto make_let(std::string name, T body) -> Let<decltype(body())>;
71+
void let(std::string name, Runnable &body);
72+
virtual Result run(BasePrinter &printer) override;
7173
void reset_lets();
7274
Runnable *find_let(std::string);
75+
virtual std::string get_descr() { return descr; }
76+
virtual const std::string get_descr() const { return descr; }
7377
};
7478

7579
typedef Description Context;
@@ -79,20 +83,20 @@ Result Description::context(std::string name,
7983
Context context(*this, name, body);
8084
context.before_eaches = this->before_eaches;
8185
context.after_eaches = this->after_eaches;
82-
return context.run();
86+
return context.run(this->get_printer());
8387
}
8488

8589
Result Description::it(std::string name, std::function<void(ItD &)> body) {
8690
ItD it(*this, name, body);
87-
Result result = it.run();
91+
Result result = it.run(this->get_printer());
8892
exec_after_eaches();
8993
exec_before_eaches();
9094
return result;
9195
}
9296

9397
Result Description::it(std::function<void(ItD &)> body) {
9498
ItD it(*this, body);
95-
Result result = it.run();
99+
Result result = it.run(this->get_printer());
96100
exec_after_eaches();
97101
exec_before_eaches();
98102
return result;
@@ -140,15 +144,21 @@ void Description::exec_after_eaches() {
140144
for (rule_block_t b : after_eaches) b();
141145
}
142146

147+
template <typename T>
148+
auto Description::make_let(std::string name, T body) -> Let<decltype(body())> {
149+
return Let<decltype(body())>(*this, name, body);
150+
}
151+
143152
void Description::let(std::string name, Runnable &body) {
144153
lets.insert({name, &body});
145154
}
146155

147-
Result Description::run() {
148-
std::cout << padding() << descr << std::endl;
156+
Result Description::run(BasePrinter &printer) {
157+
if (not this->has_printer()) this->set_printer(printer);
158+
printer.print(*this);
149159
body(*this);
150160
for (auto a : after_alls) a();
151-
std::cout << std::endl;
161+
if (this->get_parent() == nullptr) printer.flush();
152162
return this->get_status() ? Result::success : Result::failure;
153163
}
154164

@@ -188,12 +198,18 @@ Expectations::Expectation<T> ItExpBase::expect(Let<T> let) {
188198
return expectation;
189199
}
190200

191-
Result ItD::run() {
192-
if (!this->needs_descr()) {
193-
std::cout << padding() << get_descr() << std::endl;
201+
Result ItD::run(BasePrinter &printer) {
202+
if (!this->needs_descr() && printer.mode == BasePrinter::Mode::verbose) {
203+
printer.print(*this);
194204
}
205+
195206
body(*this);
196207

208+
if (printer.mode == BasePrinter::Mode::TAP ||
209+
printer.mode == BasePrinter::Mode::terse) {
210+
printer.print(*this);
211+
}
212+
197213
auto parent = static_cast<Description *>(this->get_parent());
198214
parent->reset_lets();
199215

0 commit comments

Comments
 (0)