Specs
Beautiful C++ Test Framework
Loading...
Searching...
No Matches
SpecsCpp::SpecCodeBlock Class Reference

#include <SpecCodeBlock.h>

Inheritance diagram for SpecsCpp::SpecCodeBlock:
SpecsCpp::ISpecCodeBlock

Public Member Functions

 SpecCodeBlock (std::unique_ptr< IFunctionPointer< void(ISpecComponent *, ISpec *, SpecCodeBlockAsyncDoneFn *)> > managedBody)
 
 SpecCodeBlock (FunctionPointer< void()> body)
 
 SpecCodeBlock (FunctionPointer< void(SpecDone)> body)
 
 SpecCodeBlock (FunctionPointer< void(ISpec *)> body)
 
 SpecCodeBlock (FunctionPointer< void(ISpecGroup *)> body)
 
 SpecCodeBlock (FunctionPointer< void(ISpecGroup *, SpecDone)> body)
 
 SpecCodeBlock (FunctionPointer< void(ISpec *, SpecDone)> body)
 
 SpecCodeBlock (FunctionPointer< void(ISpecComponent *, ISpec *)> body)
 
 SpecCodeBlock (FunctionPointer< void(ISpecGroup *, ISpec *)> body)
 
 SpecCodeBlock (FunctionPointer< void(ISpecGroup *, ISpecComponent *, ISpec *)> body)
 
 SpecCodeBlock (FunctionPointer< void(ISpecGroup *, ISpec *, SpecDone)> body)
 
 SpecCodeBlock (FunctionPointer< void(ISpecComponent *, ISpec *, SpecDone)> body)
 
 SpecCodeBlock (FunctionPointer< void(ISpecGroup *, ISpecComponent *, ISpec *, SpecDone)> body)
 
bool is_async () const override
 
void mark_async (bool async=true) override
 
std::uint32_t get_timeout_ms () const override
 
void set_timeout_ms (std::uint32_t timeout_ms) override
 
SpecCodeBlockBodyFnbody () const override
 
void set_body (SpecCodeBlockBodyFn *body) override
 
void run (ISpecComponent *self, ISpecGroup *group, ISpec *spec, ISpecRunResultCallbackFn *resultCallback) override
 
- Public Member Functions inherited from SpecsCpp::ISpecCodeBlock
virtual ~ISpecCodeBlock ()=default
 
virtual bool is_async () const =0
 
virtual void mark_async (bool async=true)=0
 
virtual std::uint32_t get_timeout_ms () const =0
 
virtual void set_timeout_ms (std::uint32_t timeout_ms)=0
 
virtual SpecCodeBlockBodyFnbody () const =0
 
virtual void set_body (SpecCodeBlockBodyFn *)=0
 
virtual void run (ISpecComponent *, ISpecGroup *, ISpec *, ISpecRunResultCallbackFn *)=0
 

Additional Inherited Members

- Public Types inherited from SpecsCpp::ISpecCodeBlock
using SpecCodeBlockAsyncDoneFn = IFunctionPointer< void()>
 
using SpecCodeBlockBodyFn = IFunctionPointer< void(ISpecComponent *, ISpec *, SpecCodeBlockAsyncDoneFn *)>
 

Detailed Description

Definition at line 16 of file SpecCodeBlock.h.

Constructor & Destructor Documentation

◆ SpecCodeBlock() [1/13]

SpecsCpp::SpecCodeBlock::SpecCodeBlock ( std::unique_ptr< IFunctionPointer< void(ISpecComponent *, ISpec *, SpecCodeBlockAsyncDoneFn *)> >  managedBody)
inline

Definition at line 64 of file SpecCodeBlock.h.

67 : _managedBody(std::move(managedBody)) {}

◆ SpecCodeBlock() [2/13]

SpecsCpp::SpecCodeBlock::SpecCodeBlock ( FunctionPointer< void()>  body)
inline

Definition at line 69 of file SpecCodeBlock.h.

70 : _managedBody(
71 std::make_unique<
72 FunctionPointer<void(ISpecComponent*, ISpec*, SpecCodeBlockAsyncDoneFn*)>>(
73 [body](
74 ISpecComponent* self, ISpec* spec, SpecCodeBlockAsyncDoneFn* asyncDone
75 ) { body.invoke(); }
76 )
77 ) {}
SpecCodeBlockBodyFn * body() const override
IFunctionPointer< void()> SpecCodeBlockAsyncDoneFn
Definition API.h:201

◆ SpecCodeBlock() [3/13]

SpecsCpp::SpecCodeBlock::SpecCodeBlock ( FunctionPointer< void(SpecDone)>  body)
inline

Definition at line 79 of file SpecCodeBlock.h.

80 : _managedBody(
81 std::make_unique<
82 FunctionPointer<void(ISpecComponent*, ISpec*, SpecCodeBlockAsyncDoneFn*)>>(
83 [body](
84 ISpecComponent* self, ISpec* spec, SpecCodeBlockAsyncDoneFn* asyncDone
85 ) { body.invoke(SpecDone{asyncDone}); }
86 )
87 ) {
88 mark_async();
89 }
void mark_async(bool async=true) override

◆ SpecCodeBlock() [4/13]

SpecsCpp::SpecCodeBlock::SpecCodeBlock ( FunctionPointer< void(ISpec *)>  body)
inline

Definition at line 91 of file SpecCodeBlock.h.

92 : _managedBody(
93 std::make_unique<
94 FunctionPointer<void(ISpecComponent*, ISpec*, SpecCodeBlockAsyncDoneFn*)>>(
95 [body](
96 ISpecComponent* self, ISpec* spec, SpecCodeBlockAsyncDoneFn* asyncDone
97 ) { body.invoke(spec); }
98 )
99 ) {}

◆ SpecCodeBlock() [5/13]

SpecsCpp::SpecCodeBlock::SpecCodeBlock ( FunctionPointer< void(ISpecGroup *)>  body)
inline

Definition at line 101 of file SpecCodeBlock.h.

102 : _managedBody(std::make_unique<FunctionPointer<
103 void(ISpecComponent*, ISpec*, SpecCodeBlockAsyncDoneFn*)>>(
104 [body](ISpecComponent* self, ISpec* spec, SpecCodeBlockAsyncDoneFn* asyncDone) {
105 // If 'self' is a group, invoke the body with it, otherwise invoke with the
106 // group() of self, if any
107 if (auto* group = dynamic_cast<ISpecGroup*>(self)) body.invoke(group);
108 else if (auto* group = self->group()) _Log_("AFTER");
109 ;
110 }
111 )) {}

◆ SpecCodeBlock() [6/13]

SpecsCpp::SpecCodeBlock::SpecCodeBlock ( FunctionPointer< void(ISpecGroup *, SpecDone)>  body)
inline

Definition at line 113 of file SpecCodeBlock.h.

114 : _managedBody(
115 std::make_unique<
116 FunctionPointer<void(ISpecComponent*, ISpec*, SpecCodeBlockAsyncDoneFn*)>>(
117 [body](
118 ISpecComponent* self, ISpec* spec, SpecCodeBlockAsyncDoneFn* asyncDone
119 ) { body.invoke(self->group(), SpecDone{asyncDone}); }
120 )
121 ) {
122 mark_async();
123 }

◆ SpecCodeBlock() [7/13]

SpecsCpp::SpecCodeBlock::SpecCodeBlock ( FunctionPointer< void(ISpec *, SpecDone)>  body)
inline

Definition at line 125 of file SpecCodeBlock.h.

126 : _managedBody(
127 std::make_unique<
128 FunctionPointer<void(ISpecComponent*, ISpec*, SpecCodeBlockAsyncDoneFn*)>>(
129 [body](
130 ISpecComponent* self, ISpec* spec, SpecCodeBlockAsyncDoneFn* asyncDone
131 ) { body.invoke(spec, SpecDone{asyncDone}); }
132 )
133 ) {
134 mark_async();
135 }

◆ SpecCodeBlock() [8/13]

SpecsCpp::SpecCodeBlock::SpecCodeBlock ( FunctionPointer< void(ISpecComponent *, ISpec *)>  body)
inline

Definition at line 137 of file SpecCodeBlock.h.

138 : _managedBody(
139 std::make_unique<
140 FunctionPointer<void(ISpecComponent*, ISpec*, SpecCodeBlockAsyncDoneFn*)>>(
141 [body](
142 ISpecComponent* self, ISpec* spec, SpecCodeBlockAsyncDoneFn* asyncDone
143 ) { body.invoke(self, spec); }
144 )
145 ) {}

◆ SpecCodeBlock() [9/13]

SpecsCpp::SpecCodeBlock::SpecCodeBlock ( FunctionPointer< void(ISpecGroup *, ISpec *)>  body)
inline

Definition at line 147 of file SpecCodeBlock.h.

148 : _managedBody(
149 std::make_unique<
150 FunctionPointer<void(ISpecComponent*, ISpec*, SpecCodeBlockAsyncDoneFn*)>>(
151 [body](
152 ISpecComponent* self, ISpec* spec, SpecCodeBlockAsyncDoneFn* asyncDone
153 ) { body.invoke(self->group(), spec); }
154 )
155 ) {}

◆ SpecCodeBlock() [10/13]

SpecsCpp::SpecCodeBlock::SpecCodeBlock ( FunctionPointer< void(ISpecGroup *, ISpecComponent *, ISpec *)>  body)
inline

Definition at line 157 of file SpecCodeBlock.h.

158 : _managedBody(
159 std::make_unique<
160 FunctionPointer<void(ISpecComponent*, ISpec*, SpecCodeBlockAsyncDoneFn*)>>(
161 [body](
162 ISpecComponent* self, ISpec* spec, SpecCodeBlockAsyncDoneFn* asyncDone
163 ) { body.invoke(self->group(), self, spec); }
164 )
165 ) {}

◆ SpecCodeBlock() [11/13]

SpecsCpp::SpecCodeBlock::SpecCodeBlock ( FunctionPointer< void(ISpecGroup *, ISpec *, SpecDone)>  body)
inline

Definition at line 167 of file SpecCodeBlock.h.

168 : _managedBody(
169 std::make_unique<
170 FunctionPointer<void(ISpecComponent*, ISpec*, SpecCodeBlockAsyncDoneFn*)>>(
171 [body](
172 ISpecComponent* self, ISpec* spec, SpecCodeBlockAsyncDoneFn* asyncDone
173 ) { body.invoke(self->group(), spec, SpecDone{asyncDone}); }
174 )
175 ) {
176 mark_async();
177 }

◆ SpecCodeBlock() [12/13]

SpecsCpp::SpecCodeBlock::SpecCodeBlock ( FunctionPointer< void(ISpecComponent *, ISpec *, SpecDone)>  body)
inline

Definition at line 179 of file SpecCodeBlock.h.

180 : _managedBody(
181 std::make_unique<
182 FunctionPointer<void(ISpecComponent*, ISpec*, SpecCodeBlockAsyncDoneFn*)>>(
183 [body](
184 ISpecComponent* self, ISpec* spec, SpecCodeBlockAsyncDoneFn* asyncDone
185 ) { body.invoke(self, spec, SpecDone{asyncDone}); }
186 )
187 ) {
188 mark_async();
189 }

◆ SpecCodeBlock() [13/13]

SpecsCpp::SpecCodeBlock::SpecCodeBlock ( FunctionPointer< void(ISpecGroup *, ISpecComponent *, ISpec *, SpecDone)>  body)
inline

Definition at line 191 of file SpecCodeBlock.h.

192 : _managedBody(
193 std::make_unique<
194 FunctionPointer<void(ISpecComponent*, ISpec*, SpecCodeBlockAsyncDoneFn*)>>(
195 [body](
196 ISpecComponent* self, ISpec* spec, SpecCodeBlockAsyncDoneFn* asyncDone
197 ) { body.invoke(self->group(), self, spec, SpecDone{asyncDone}); }
198 )
199 ) {
200 mark_async();
201 }

Member Function Documentation

◆ body()

SpecCodeBlockBodyFn * SpecsCpp::SpecCodeBlock::body ( ) const
inlineoverridevirtual

Implements SpecsCpp::ISpecCodeBlock.

Definition at line 209 of file SpecCodeBlock.h.

209 {
210 return _unmanagedBody ? _unmanagedBody : _managedBody.get();
211 }

Referenced by run(), set_body(), SpecCodeBlock(), SpecCodeBlock(), SpecCodeBlock(), SpecCodeBlock(), SpecCodeBlock(), SpecCodeBlock(), SpecCodeBlock(), SpecCodeBlock(), SpecCodeBlock(), SpecCodeBlock(), SpecCodeBlock(), and SpecCodeBlock().

◆ get_timeout_ms()

std::uint32_t SpecsCpp::SpecCodeBlock::get_timeout_ms ( ) const
inlineoverridevirtual

Implements SpecsCpp::ISpecCodeBlock.

Definition at line 206 of file SpecCodeBlock.h.

206{ return _timeout_ms; }

Referenced by run().

◆ is_async()

bool SpecsCpp::SpecCodeBlock::is_async ( ) const
inlineoverridevirtual

Implements SpecsCpp::ISpecCodeBlock.

Definition at line 203 of file SpecCodeBlock.h.

203{ return _async; }

Referenced by run().

◆ mark_async()

void SpecsCpp::SpecCodeBlock::mark_async ( bool  async = true)
inlineoverridevirtual

Implements SpecsCpp::ISpecCodeBlock.

Definition at line 204 of file SpecCodeBlock.h.

204{ _async = async; }

◆ run()

void SpecsCpp::SpecCodeBlock::run ( ISpecComponent self,
ISpecGroup group,
ISpec spec,
ISpecRunResultCallbackFn resultCallback 
)
inlineoverridevirtual

Implements SpecsCpp::ISpecCodeBlock.

Definition at line 215 of file SpecCodeBlock.h.

218 {
219 try {
220 if (is_async()) {
221 _asyncDonePromise = std::make_unique<std::promise<void>>();
222 body()->invoke(self, spec, &_markAsyncPromiseDoneFn);
223
224 auto asyncDoneFuture = _asyncDonePromise->get_future();
225 if (get_timeout_ms() > 0) {
226 if (asyncDoneFuture.wait_for(std::chrono::milliseconds(get_timeout_ms())) ==
227 std::future_status::timeout) {
228 if (resultCallback) {
229 auto result = SpecRunResult::timeout(self, group, spec);
230 resultCallback->invoke(result.get());
231 return;
232 } else {
233 _Log_("Code block timed out");
234 }
235 }
236 }
237
238 asyncDoneFuture.get();
239
240 } else {
241 body()->invoke(self, spec, nullptr);
242 }
243
244 if (!resultCallback) return;
245 auto result = SpecRunResult::passed(self, group, spec);
246 resultCallback->invoke(result.get());
247 } catch (...) {
248 _exceptionHandled = false;
249
250 // ...
251 if (_asyncDonePromise) _asyncDonePromise->set_exception(std::current_exception());
252
253 if (auto* currentlyRunningSpecEnvironment = global_spec_environment().get()) {
254 if (auto* exceptionHandlers =
255 currentlyRunningSpecEnvironment->local_exception_handlers()) {
256 _currentExceptionMessage.clear();
257 _currentExceptionPtr =
258 std::make_unique<std::exception_ptr>(std::current_exception());
259 exceptionHandlers->foreach_exception_handler(&_forEachExceptionHandlerFn);
260 if (_exceptionHandled) {
261 if (resultCallback) {
262 auto result = SpecRunResult::failed(
263 self, group, spec, _currentExceptionMessage.c_str()
264 );
265 resultCallback->invoke(result.get());
266 } else {
267 _Log_("Code block error: {}", _currentExceptionMessage);
268 }
269 } else {
270 if (resultCallback) {
271 auto result =
272 SpecRunResult::failed(self, group, spec, "Unknown exception");
273 resultCallback->invoke(result.get());
274
275 } else {
276 _Log_("Code block error: Unhandled exception");
277 }
278 }
279 } else {
280 _Log_("No exception handlers registered");
281 }
282 } else {
283 _Log_("No currently running spec environment");
284 }
285 }
286 }
std::uint32_t get_timeout_ms() const override
bool is_async() const override
static std::unique_ptr< SpecRunResult > timeout(ISpecComponent *component, ISpecGroup *group, ISpec *spec)
static std::unique_ptr< SpecRunResult > passed(ISpecComponent *component, ISpecGroup *group, ISpec *spec)
static std::unique_ptr< SpecRunResult > failed(ISpecComponent *component, ISpecGroup *group, ISpec *spec, std::string_view message="")
GlobalSpecEnvironment & global_spec_environment()

◆ set_body()

void SpecsCpp::SpecCodeBlock::set_body ( SpecCodeBlockBodyFn body)
inlineoverridevirtual

Implements SpecsCpp::ISpecCodeBlock.

Definition at line 213 of file SpecCodeBlock.h.

213{ _unmanagedBody = body; }

◆ set_timeout_ms()

void SpecsCpp::SpecCodeBlock::set_timeout_ms ( std::uint32_t  timeout_ms)
inlineoverridevirtual

Implements SpecsCpp::ISpecCodeBlock.

Definition at line 207 of file SpecCodeBlock.h.

207{ _timeout_ms = timeout_ms; }

The documentation for this class was generated from the following file: