Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
6b59bb87
Commit
6b59bb87
authored
Aug 06, 2023
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add should_fail_with_exception and improve output
parent
641ab130
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
103 additions
and
12 deletions
+103
-12
libcaf_test/caf/test/runnable.cpp
libcaf_test/caf/test/runnable.cpp
+17
-0
libcaf_test/caf/test/runnable.hpp
libcaf_test/caf/test/runnable.hpp
+86
-12
No files found.
libcaf_test/caf/test/runnable.cpp
View file @
6b59bb87
...
...
@@ -10,13 +10,23 @@
#include "caf/test/scope.hpp"
#include "caf/test/test.hpp"
#include "caf/detail/scope_guard.hpp"
namespace
caf
::
test
{
namespace
{
thread_local
runnable
*
current_runnable
;
}
// namespace
runnable
::~
runnable
()
{
// nop
}
void
runnable
::
run
()
{
current_runnable
=
this
;
auto
guard
=
detail
::
make_scope_guard
([]
{
current_runnable
=
nullptr
;
});
switch
(
root_type_
)
{
case
block_type
:
:
scenario
:
if
(
auto
guard
=
ctx_
->
get
<
scenario
>
(
0
,
description_
,
loc_
)
->
commit
())
{
...
...
@@ -48,6 +58,13 @@ bool runnable::check(bool value, const detail::source_location& location) {
return
value
;
}
runnable
&
runnable
::
current
()
{
auto
ptr
=
current_runnable
;
if
(
!
ptr
)
CAF_RAISE_ERROR
(
std
::
logic_error
,
"no current runnable"
);
return
*
ptr
;
}
block
&
runnable
::
current_block
()
{
if
(
ctx_
->
call_stack
.
empty
())
CAF_RAISE_ERROR
(
std
::
logic_error
,
"no current block"
);
...
...
libcaf_test/caf/test/runnable.hpp
View file @
6b59bb87
...
...
@@ -12,8 +12,10 @@
#include "caf/config.hpp"
#include "caf/deep_to_string.hpp"
#include "caf/detail/format.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/detail/source_location.hpp"
#include "caf/detail/test_export.hpp"
#include "caf/raise_error.hpp"
#include <string_view>
...
...
@@ -42,6 +44,18 @@ public:
/// Runs the next branch of the test.
void
run
();
/// Generates a message with the INFO severity level.
template
<
class
...
Ts
>
[[
noreturn
]]
void
fail
(
detail
::
format_string_with_location
fwl
,
Ts
&&
...
xs
)
{
if
constexpr
(
sizeof
...(
Ts
)
>
0
)
{
auto
msg
=
detail
::
format
(
fwl
.
value
,
std
::
forward
<
Ts
>
(
xs
)...);
reporter
::
instance
->
fail
(
msg
,
fwl
.
location
);
}
else
{
reporter
::
instance
->
fail
(
fwl
.
value
,
fwl
.
location
);
}
CAF_RAISE_ERROR
(
std
::
logic_error
,
"requirement failed: abort test"
);
}
/// Generates a message with the INFO severity level.
template
<
class
...
Ts
>
void
info
(
detail
::
format_string_with_location
fwl
,
Ts
&&
...
xs
)
{
...
...
@@ -143,18 +157,46 @@ public:
return
false
;
}
/// Checks whether `value` is `true`.
bool
check
(
bool
value
,
const
detail
::
source_location
&
location
=
detail
::
source_location
::
current
());
/// Returns the `runnable` instance that is currently running.
static
runnable
&
current
();
block
&
current_block
();
template
<
class
Expr
>
void
should_fail
(
Expr
&&
expr
,
const
caf
::
detail
::
source_location
&
location
=
caf
::
detail
::
source_location
::
current
())
{
auto
*
rep
=
reporter
::
instance
;
auto
lvl
=
rep
->
verbosity
(
CAF_LOG_LEVEL_QUIET
);
auto
before
=
rep
->
test_stats
();
{
auto
lvl_guard
=
detail
::
make_scope_guard
([
&
]
{
rep
->
verbosity
(
lvl
);
});
expr
();
}
auto
after
=
rep
->
test_stats
();
auto
passed_count_ok
=
before
.
passed
==
after
.
passed
;
auto
failed_count_ok
=
before
.
failed
+
1
==
after
.
failed
;
if
(
passed_count_ok
&&
failed_count_ok
)
{
reporter
::
instance
->
pass
(
location
);
rep
->
test_stats
({
before
.
passed
+
1
,
before
.
failed
});
}
else
{
reporter
::
instance
->
fail
(
"nested check should fail"
,
location
);
rep
->
test_stats
({
before
.
passed
,
before
.
failed
+
1
});
}
}
#ifdef CAF_ENABLE_EXCEPTIONS
template
<
class
Exception
=
void
,
class
CodeBlock
>
void
check_throws
(
CodeBlock
&&
fn
,
const
detail
::
source_location
&
location
/// Checks whether `expr()` throws an exception of type `Exception`.
template
<
class
Exception
=
void
,
class
Expr
>
void
check_throws
(
Expr
&&
expr
,
const
detail
::
source_location
&
location
=
detail
::
source_location
::
current
())
{
if
constexpr
(
std
::
is_same_v
<
Exception
,
void
>
)
{
try
{
fn
();
expr
();
}
catch
(...)
{
reporter
::
instance
->
pass
(
location
);
return
;
...
...
@@ -162,7 +204,7 @@ public:
reporter
::
instance
->
fail
(
"throws"
,
location
);
}
else
{
try
{
fn
();
expr
();
}
catch
(
const
Exception
&
)
{
reporter
::
instance
->
pass
(
location
);
return
;
...
...
@@ -173,20 +215,52 @@ public:
reporter
::
instance
->
fail
(
"throws Exception"
,
location
);
}
}
#endif
template
<
class
Expr
>
void
should_fail
(
Expr
&&
expr
,
const
caf
::
detail
::
source_location
&
location
/// Checks whether `expr()` throws an exception of type `Exception` and
/// increases the failure count.
template
<
class
Exception
=
void
,
class
Expr
>
void
should_fail_with_exception
(
Expr
&&
expr
,
const
caf
::
detail
::
source_location
&
location
=
caf
::
detail
::
source_location
::
current
())
{
auto
*
rep
=
reporter
::
instance
;
auto
before
=
rep
->
test_stats
();
auto
lvl
=
rep
->
verbosity
(
CAF_LOG_LEVEL_QUIET
);
auto
caught
=
false
;
if
constexpr
(
std
::
is_same_v
<
Exception
,
void
>
)
{
try
{
expr
();
}
catch
(...)
{
caught
=
true
;
}
}
else
{
try
{
expr
();
}
catch
(
const
Exception
&
)
{
caught
=
true
;
}
catch
(...)
{
// TODO: print error message
}
}
rep
->
verbosity
(
lvl
);
auto
after
=
rep
->
test_stats
();
check_eq
(
before
.
passed
,
after
.
passed
,
location
);
if
(
check_eq
(
before
.
failed
+
1
,
after
.
failed
,
location
))
auto
passed_count_ok
=
before
.
passed
==
after
.
passed
;
auto
failed_count_ok
=
before
.
failed
+
1
==
after
.
failed
;
if
(
caught
&&
passed_count_ok
&&
failed_count_ok
)
{
reporter
::
instance
->
pass
(
location
);
rep
->
test_stats
({
before
.
passed
+
1
,
before
.
failed
});
}
else
{
if
(
!
caught
)
{
reporter
::
instance
->
fail
(
"nested check should throw an Exception"
,
location
);
}
else
if
(
!
passed_count_ok
||
!
failed_count_ok
)
{
reporter
::
instance
->
fail
(
"nested check should fail"
,
location
);
}
rep
->
test_stats
({
before
.
passed
,
before
.
failed
+
1
});
}
}
#endif
protected:
context_ptr
ctx_
;
std
::
string_view
description_
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment