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
1ed9a0b4
Unverified
Commit
1ed9a0b4
authored
Mar 03, 2021
by
Noir
Committed by
GitHub
Mar 03, 2021
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1225
Allow setter to return bool, error or void
parents
2c696667
f62b9932
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
353 additions
and
29 deletions
+353
-29
CHANGELOG.md
CHANGELOG.md
+9
-1
libcaf_core/caf/inspector_access.hpp
libcaf_core/caf/inspector_access.hpp
+35
-8
libcaf_core/caf/inspector_access_base.hpp
libcaf_core/caf/inspector_access_base.hpp
+6
-4
libcaf_core/caf/load_inspector.hpp
libcaf_core/caf/load_inspector.hpp
+36
-7
libcaf_core/caf/load_inspector_base.hpp
libcaf_core/caf/load_inspector_base.hpp
+22
-7
libcaf_core/test/load_inspector.cpp
libcaf_core/test/load_inspector.cpp
+180
-1
libcaf_core/test/save_inspector.cpp
libcaf_core/test/save_inspector.cpp
+65
-1
No files found.
CHANGELOG.md
View file @
1ed9a0b4
...
...
@@ -5,11 +5,19 @@ is based on [Keep a Changelog](https://keepachangelog.com).
## [Unreleased]
### Changed
-
Setter functions for fields may now return either
`bool`
,
`caf::error`
or
`void`
. Previously, CAF only allowed
`bool`
.
### Fixed
-
Passing a getter and setter pair to an inspector via
`apply`
produced a
compiler error for non-builtin types. The inspection API now recursively
inspects user-defined types instead, as was the original intend (#1216).
-
The handle type
`typed_actor`
now can construct from a
`typed_actor_pointer`
.
This resolves a compiler error when trying to initialize a handle for
`my_handle`
from a self pointer of type
`my_handle::pointer_view`
.
`my_handle`
from a self pointer of type
`my_handle::pointer_view`
(#1218)
.
## [0.18.0] - 2021-01-25
...
...
libcaf_core/caf/inspector_access.hpp
View file @
1ed9a0b4
...
...
@@ -78,6 +78,32 @@ constexpr bool has_static_apply_v = has_static_apply<T, Inspector, Obj>::value;
// -- loading ------------------------------------------------------------------
// Converts a setter that returns void, error or bool to a sync function object
// taking no arguments that always returns a bool.
template
<
class
Inspector
,
class
Set
,
class
ValueType
>
auto
bind_setter
(
Inspector
&
f
,
Set
&
set
,
ValueType
&
tmp
)
{
using
set_result_type
=
decltype
(
set
(
std
::
move
(
tmp
)));
if
constexpr
(
std
::
is_same
<
set_result_type
,
bool
>::
value
)
{
return
[
&
]
{
return
set
(
std
::
move
(
tmp
));
};
}
else
if
constexpr
(
std
::
is_same
<
set_result_type
,
error
>::
value
)
{
return
[
&
]
{
if
(
auto
err
=
set
(
std
::
move
(
tmp
));
!
err
)
{
return
true
;
}
else
{
f
.
set_error
(
std
::
move
(
err
));
return
false
;
}
};
}
else
{
static_assert
(
std
::
is_same
<
set_result_type
,
void
>::
value
,
"a setter must return caf::error, bool or void"
);
return
[
&
]
{
set
(
std
::
move
(
tmp
));
return
true
;
};
}
}
// TODO: remove with CAF 0.19
template
<
class
Inspector
,
class
T
>
[[
deprecated
(
"please provide apply instead of apply_object/apply_value"
)]]
//
...
...
@@ -390,9 +416,8 @@ struct optional_inspector_access {
container_type
&
x
,
IsValid
&
is_valid
,
SyncValue
&
sync_value
)
{
traits
::
emplace
(
x
);
auto
set_x
=
[
&
]
{
return
sync_value
();
};
auto
reset
=
[
&
x
]
{
x
.
reset
();
};
return
detail
::
load_field
(
f
,
field_name
,
*
x
,
is_valid
,
s
et_x
,
reset
);
return
detail
::
load_field
(
f
,
field_name
,
*
x
,
is_valid
,
s
ync_value
,
reset
);
}
template
<
class
Inspector
,
class
IsValid
,
class
SyncValue
,
class
SetFallback
>
...
...
@@ -400,8 +425,8 @@ struct optional_inspector_access {
container_type
&
x
,
IsValid
&
is_valid
,
SyncValue
&
sync_value
,
SetFallback
&
set_fallback
)
{
traits
::
emplace
(
x
);
auto
set_x
=
[
&
]
{
return
sync_value
();
};
return
detail
::
load_field
(
f
,
field_name
,
*
x
,
is_valid
,
set_x
,
set_fallback
);
return
detail
::
load_field
(
f
,
field_name
,
*
x
,
is_valid
,
sync_value
,
set_fallback
);
}
};
...
...
@@ -575,8 +600,9 @@ struct variant_inspector_access {
return
false
;
}
if
(
!
sync_value
())
{
f
.
emplace_error
(
sec
::
field_value_synchronization_failed
,
to_string
(
field_name
));
if
(
!
f
.
get_error
())
f
.
emplace_error
(
sec
::
field_value_synchronization_failed
,
to_string
(
field_name
));
return
false
;
}
return
f
.
end_field
();
...
...
@@ -605,8 +631,9 @@ struct variant_inspector_access {
return
false
;
}
if
(
!
sync_value
())
{
f
.
emplace_error
(
sec
::
field_value_synchronization_failed
,
to_string
(
field_name
));
if
(
!
f
.
get_error
())
f
.
emplace_error
(
sec
::
field_value_synchronization_failed
,
to_string
(
field_name
));
return
false
;
}
}
else
{
...
...
libcaf_core/caf/inspector_access_base.hpp
View file @
1ed9a0b4
...
...
@@ -25,8 +25,9 @@ struct inspector_access_base {
return
false
;
}
if
(
!
sync_value
())
{
f
.
emplace_error
(
sec
::
field_value_synchronization_failed
,
to_string
(
field_name
));
if
(
!
f
.
get_error
())
f
.
emplace_error
(
sec
::
field_value_synchronization_failed
,
to_string
(
field_name
));
return
false
;
}
return
f
.
end_field
();
...
...
@@ -52,8 +53,9 @@ struct inspector_access_base {
return
false
;
}
if
(
!
sync_value
())
{
f
.
emplace_error
(
sec
::
field_value_synchronization_failed
,
to_string
(
field_name
));
if
(
!
f
.
get_error
())
f
.
emplace_error
(
sec
::
field_value_synchronization_failed
,
to_string
(
field_name
));
return
false
;
}
return
f
.
end_field
();
...
...
libcaf_core/caf/load_inspector.hpp
View file @
1ed9a0b4
...
...
@@ -155,7 +155,7 @@ public:
template
<
class
Inspector
>
bool
operator
()(
Inspector
&
f
)
{
auto
tmp
=
T
{};
auto
sync
=
[
this
,
&
tmp
]
{
return
set
(
std
::
move
(
tmp
));
}
;
auto
sync
=
detail
::
bind_setter
(
f
,
set
,
tmp
)
;
auto
reset
=
[
this
]
{
set
(
std
::
move
(
fallback
));
};
return
detail
::
load_field
(
f
,
field_name
,
tmp
,
predicate
,
sync
,
reset
);
}
...
...
@@ -170,7 +170,7 @@ public:
template
<
class
Inspector
>
bool
operator
()(
Inspector
&
f
)
{
auto
tmp
=
T
{};
auto
sync
=
[
this
,
&
tmp
]
{
return
set
(
std
::
move
(
tmp
));
}
;
auto
sync
=
detail
::
bind_setter
(
f
,
set
,
tmp
)
;
auto
reset
=
[
this
]
{
set
(
std
::
move
(
fallback
));
};
return
detail
::
load_field
(
f
,
field_name
,
tmp
,
detail
::
always_true
,
sync
,
reset
);
...
...
@@ -196,7 +196,7 @@ public:
template
<
class
Inspector
>
bool
operator
()(
Inspector
&
f
)
{
auto
tmp
=
T
{};
auto
sync
=
[
this
,
&
tmp
]
{
return
set
(
std
::
move
(
tmp
));
}
;
auto
sync
=
detail
::
bind_setter
(
f
,
set
,
tmp
)
;
return
detail
::
load_field
(
f
,
field_name
,
tmp
,
predicate
,
sync
);
}
...
...
@@ -219,7 +219,7 @@ public:
template
<
class
Inspector
>
bool
operator
()(
Inspector
&
f
)
{
auto
tmp
=
T
{};
auto
sync
=
[
this
,
&
tmp
]
{
return
set
(
std
::
move
(
tmp
));
}
;
auto
sync
=
detail
::
bind_setter
(
f
,
set
,
tmp
)
;
return
detail
::
load_field
(
f
,
field_name
,
tmp
,
detail
::
always_true
,
sync
);
}
...
...
@@ -251,7 +251,7 @@ public:
template
<
class
Inspector
>
bool
operator
()(
Inspector
&
f
)
{
auto
tmp
=
T
{};
auto
sync
=
[
this
,
&
tmp
]
{
return
set
(
std
::
move
(
tmp
));
}
;
auto
sync
=
detail
::
bind_setter
(
f
,
set
,
tmp
)
;
return
detail
::
load_field
(
f
,
field_name
,
tmp
,
detail
::
always_true
,
sync
,
reset
);
}
...
...
@@ -339,14 +339,43 @@ public:
template
<
class
Get
,
class
Set
>
static
auto
field
(
string_view
name
,
Get
get
,
Set
set
)
{
using
field_type
=
std
::
decay_t
<
decltype
(
get
())
>
;
return
virt_field_t
<
field_type
,
Set
>
{
name
,
set
};
using
setter_result
=
decltype
(
set
(
std
::
declval
<
field_type
&&>
()));
if
constexpr
(
std
::
is_same
<
setter_result
,
error
>::
value
||
std
::
is_same
<
setter_result
,
bool
>::
value
)
{
return
virt_field_t
<
field_type
,
Set
>
{
name
,
std
::
move
(
set
)};
}
else
{
static_assert
(
std
::
is_same
<
setter_result
,
void
>::
value
,
"a setter must return caf::error, bool or void"
);
auto
set_fun
=
[
f
{
std
::
move
(
set
)}](
field_type
&&
val
)
{
f
(
std
::
move
(
val
));
return
true
;
};
return
virt_field_t
<
field_type
,
decltype
(
set_fun
)
>
{
name
,
std
::
move
(
set_fun
)};
}
}
template
<
class
IsPresent
,
class
Get
,
class
Reset
,
class
Set
>
static
auto
field
(
string_view
name
,
IsPresent
&&
,
Get
&&
get
,
Reset
reset
,
Set
set
)
{
using
field_type
=
std
::
decay_t
<
decltype
(
get
())
>
;
return
optional_virt_field_t
<
field_type
,
Reset
,
Set
>
{
name
,
reset
,
set
};
using
setter_result
=
decltype
(
set
(
std
::
declval
<
field_type
&&>
()));
if
constexpr
(
std
::
is_same
<
setter_result
,
error
>::
value
||
std
::
is_same
<
setter_result
,
bool
>::
value
)
{
return
optional_virt_field_t
<
field_type
,
Reset
,
Set
>
{
name
,
std
::
move
(
reset
),
std
::
move
(
set
)};
}
else
{
static_assert
(
std
::
is_same
<
setter_result
,
void
>::
value
,
"a setter must return caf::error, bool or void"
);
auto
set_fun
=
[
f
{
std
::
move
(
set
)}](
field_type
&&
val
)
{
f
(
std
::
move
(
val
));
return
true
;
};
return
optional_virt_field_t
<
field_type
,
Reset
,
Set
>
{
name
,
std
::
move
(
reset
),
std
::
move
(
set_fun
)};
}
}
protected:
...
...
libcaf_core/caf/load_inspector_base.hpp
View file @
1ed9a0b4
...
...
@@ -10,6 +10,7 @@
#include "caf/inspector_access.hpp"
#include "caf/load_inspector.hpp"
#include "caf/sec.hpp"
namespace
caf
{
...
...
@@ -61,7 +62,7 @@ public:
auto
emplace_result
=
xs
.
emplace
(
std
::
move
(
key
),
std
::
move
(
val
));
if
constexpr
(
detail
::
is_pair
<
decltype
(
emplace_result
)
>::
value
)
{
if
(
!
emplace_result
.
second
)
{
dref
().
emplace_error
(
sec
::
runtime_error
,
"multiple key definitions"
);
super
::
emplace_error
(
sec
::
runtime_error
,
"multiple key definitions"
);
return
false
;
}
}
...
...
@@ -106,17 +107,31 @@ public:
auto
tmp
=
value_type
{};
using
setter_result
=
decltype
(
set
(
std
::
move
(
tmp
)));
if
constexpr
(
std
::
is_same
<
setter_result
,
bool
>::
value
)
{
if
(
dref
().
value
(
tmp
))
return
set
(
std
::
move
(
tmp
));
else
if
(
dref
().
apply
(
tmp
))
{
if
(
set
(
std
::
move
(
tmp
)))
{
return
true
;
}
else
{
super
::
emplace_error
(
sec
::
save_callback_failed
);
return
false
;
}
}
else
{
return
false
;
}
}
else
if
constexpr
(
std
::
is_same
<
setter_result
,
void
>::
value
)
{
if
(
dref
().
apply
(
tmp
))
{
set
(
std
::
move
(
tmp
));
return
true
;
}
else
{
return
false
;
}
}
else
{
static_assert
(
std
::
is_convertible
<
setter_result
,
error
>::
value
);
if
(
dref
().
value
(
tmp
))
{
static_assert
(
std
::
is_convertible
<
setter_result
,
error
>::
value
,
"a setter must return caf::error, bool or void"
);
if
(
dref
().
apply
(
tmp
))
{
if
(
auto
err
=
set
(
std
::
move
(
tmp
));
!
err
)
{
return
true
;
}
else
{
this
->
emplace
_error
(
std
::
move
(
err
));
super
::
set
_error
(
std
::
move
(
err
));
return
false
;
}
}
else
{
...
...
libcaf_core/test/load_inspector.cpp
View file @
1ed9a0b4
...
...
@@ -6,7 +6,7 @@
#include "caf/load_inspector.hpp"
#include "c
af/test/dsl
.hpp"
#include "c
ore-test
.hpp"
#include <array>
#include <cstdint>
...
...
@@ -35,6 +35,12 @@ struct testee : deserializer {
size_t
indent
=
0
;
void
reset
()
{
log
.
clear
();
indent
=
0
;
set_error
(
error
{});
}
void
new_line
()
{
log
+=
'\n'
;
log
.
insert
(
log
.
end
(),
indent
,
' '
);
...
...
@@ -567,4 +573,177 @@ CAF_TEST(load inspectors support messages) {
auto
msg
=
make_message
(
1
,
"two"
,
3.0
);
}
SCENARIO
(
"load inspectors support apply with a getter and setter"
)
{
std
::
string
baseline
=
R"_(
begin object line
begin field p1
begin object point_3d
begin field x
int32_t value
end field
begin field y
int32_t value
end field
begin field z
int32_t value
end field
end object
end field
begin field p2
begin object point_3d
begin field x
int32_t value
end field
begin field y
int32_t value
end field
begin field z
int32_t value
end field
end object
end field
end object)_"
;
GIVEN
(
"a line object"
)
{
WHEN
(
"passing a void setter"
)
{
f
.
reset
();
auto
x
=
line
{{
10
,
10
,
10
},
{
20
,
20
,
20
}};
auto
get
=
[
&
x
]
{
return
x
;
};
auto
set
=
[
&
x
](
line
val
)
{
x
=
val
;
};
THEN
(
"the inspector overrides the state using the setter"
)
{
CHECK
(
f
.
apply
(
get
,
set
));
CHECK_EQ
(
f
.
log
,
baseline
);
line
default_line
{{
0
,
0
,
0
},
{
0
,
0
,
0
}};
CHECK_EQ
(
x
,
default_line
);
}
}
WHEN
(
"passing a setter returning true"
)
{
f
.
reset
();
auto
x
=
line
{{
10
,
10
,
10
},
{
20
,
20
,
20
}};
auto
get
=
[
&
x
]
{
return
x
;
};
auto
set
=
[
&
x
](
line
val
)
{
x
=
val
;
return
true
;
};
THEN
(
"the inspector overrides the state using the setter"
)
{
CHECK
(
f
.
apply
(
get
,
set
));
CHECK_EQ
(
f
.
log
,
baseline
);
line
default_line
{{
0
,
0
,
0
},
{
0
,
0
,
0
}};
CHECK_EQ
(
x
,
default_line
);
}
}
WHEN
(
"passing a setter returning false"
)
{
f
.
reset
();
auto
x
=
line
{{
10
,
10
,
10
},
{
20
,
20
,
20
}};
auto
get
=
[
&
x
]
{
return
x
;
};
auto
set
=
[](
line
)
{
return
false
;
};
THEN
(
"the inspection fails"
)
{
CHECK
(
!
f
.
apply
(
get
,
set
));
CHECK_EQ
(
f
.
get_error
(),
sec
::
save_callback_failed
);
}
}
WHEN
(
"passing a setter returning a default-constructed error"
)
{
f
.
reset
();
auto
x
=
line
{{
10
,
10
,
10
},
{
20
,
20
,
20
}};
auto
get
=
[
&
x
]
{
return
x
;
};
auto
set
=
[
&
x
](
line
val
)
{
x
=
val
;
return
error
{};
};
THEN
(
"the inspector overrides the state using the setter"
)
{
CHECK
(
f
.
apply
(
get
,
set
));
CHECK_EQ
(
f
.
log
,
baseline
);
line
default_line
{{
0
,
0
,
0
},
{
0
,
0
,
0
}};
CHECK_EQ
(
x
,
default_line
);
}
}
WHEN
(
"passing a setter returning an error"
)
{
f
.
reset
();
auto
x
=
line
{{
10
,
10
,
10
},
{
20
,
20
,
20
}};
auto
get
=
[
&
x
]
{
return
x
;
};
auto
set
=
[](
line
)
{
return
error
{
sec
::
runtime_error
};
};
THEN
(
"the inspection fails"
)
{
CHECK
(
!
f
.
apply
(
get
,
set
));
CHECK_EQ
(
f
.
get_error
(),
sec
::
runtime_error
);
}
}
}
}
SCENARIO
(
"load inspectors support fields with a getter and setter"
)
{
std
::
string
baseline
=
R"_(
begin object person
begin field name
std::string value
end field
begin optional field phone
end field
end object)_"
;
GIVEN
(
"a person object"
)
{
WHEN
(
"passing a name setter returning void"
)
{
f
.
reset
();
auto
x
=
person
{
"John Doe"
,
{}};
auto
get_name
=
[
&
x
]
{
return
x
.
name
;
};
auto
set_name
=
[
&
x
](
std
::
string
val
)
{
x
.
name
=
std
::
move
(
val
);
};
THEN
(
"the inspector overrides the state using the setter"
)
{
CHECK
(
f
.
object
(
x
).
fields
(
f
.
field
(
"name"
,
get_name
,
set_name
),
f
.
field
(
"phone"
,
x
.
phone
)));
CHECK_EQ
(
f
.
log
,
baseline
);
CHECK_EQ
(
x
.
name
,
""
);
}
}
WHEN
(
"passing a name setter returning true"
)
{
f
.
reset
();
auto
x
=
person
{
"John Doe"
,
{}};
auto
get_name
=
[
&
x
]
{
return
x
.
name
;
};
auto
set_name
=
[
&
x
](
std
::
string
val
)
{
x
.
name
=
std
::
move
(
val
);
return
true
;
};
THEN
(
"the inspector overrides the state using the setter"
)
{
CHECK
(
f
.
object
(
x
).
fields
(
f
.
field
(
"name"
,
get_name
,
set_name
),
f
.
field
(
"phone"
,
x
.
phone
)));
CHECK_EQ
(
f
.
log
,
baseline
);
CHECK_EQ
(
x
.
name
,
""
);
}
}
WHEN
(
"passing a name setter returning false"
)
{
f
.
reset
();
auto
x
=
person
{
"John Doe"
,
{}};
auto
get_name
=
[
&
x
]
{
return
x
.
name
;
};
auto
set_name
=
[](
std
::
string
&&
)
{
return
false
;
};
THEN
(
"the inspection fails"
)
{
CHECK
(
!
f
.
object
(
x
).
fields
(
f
.
field
(
"name"
,
get_name
,
set_name
),
f
.
field
(
"phone"
,
x
.
phone
)));
CHECK_EQ
(
f
.
get_error
(),
sec
::
field_value_synchronization_failed
);
}
}
WHEN
(
"passing a name setter returning a default-constructed error"
)
{
f
.
reset
();
auto
x
=
person
{
"John Doe"
,
{}};
auto
get_name
=
[
&
x
]
{
return
x
.
name
;
};
auto
set_name
=
[
&
x
](
std
::
string
val
)
{
x
.
name
=
std
::
move
(
val
);
return
error
{};
};
THEN
(
"the inspector overrides the state using the setter"
)
{
CHECK
(
f
.
object
(
x
).
fields
(
f
.
field
(
"name"
,
get_name
,
set_name
),
f
.
field
(
"phone"
,
x
.
phone
)));
CHECK_EQ
(
f
.
log
,
baseline
);
CHECK_EQ
(
x
.
name
,
""
);
}
}
WHEN
(
"passing a name setter returning an error"
)
{
f
.
reset
();
auto
x
=
person
{
"John Doe"
,
{}};
auto
get_name
=
[
&
x
]
{
return
x
.
name
;
};
auto
set_name
=
[](
std
::
string
&&
)
{
return
error
{
sec
::
runtime_error
};
};
THEN
(
"the inspection fails"
)
{
CHECK
(
!
f
.
object
(
x
).
fields
(
f
.
field
(
"name"
,
get_name
,
set_name
),
f
.
field
(
"phone"
,
x
.
phone
)));
CHECK_EQ
(
f
.
get_error
(),
sec
::
runtime_error
);
}
}
}
}
CAF_TEST_FIXTURE_SCOPE_END
()
libcaf_core/test/save_inspector.cpp
View file @
1ed9a0b4
...
...
@@ -6,7 +6,7 @@
#include "caf/save_inspector.hpp"
#include "c
af/test/dsl
.hpp"
#include "c
ore-test
.hpp"
#include <cstdint>
#include <string>
...
...
@@ -719,4 +719,68 @@ begin sequence of size 3
end sequence)_"
);
}
SCENARIO
(
"save inspectors support apply with a getter and setter"
)
{
GIVEN
(
"a line object"
)
{
line
x
{{
10
,
10
,
10
},
{
20
,
20
,
20
}};
WHEN
(
"passing the line to a save inspector with a getter and setter pair"
)
{
auto
get
=
[
&
x
]
{
return
x
;
};
auto
set
=
[
&
x
](
line
val
)
{
x
=
val
;
};
THEN
(
"the inspector reads the state from the getter"
)
{
CHECK
(
f
.
apply
(
get
,
set
));
CHECK_EQ
(
f
.
log
,
R"_(
begin object line
begin field p1
begin object point_3d
begin field x
int32_t value
end field
begin field y
int32_t value
end field
begin field z
int32_t value
end field
end object
end field
begin field p2
begin object point_3d
begin field x
int32_t value
end field
begin field y
int32_t value
end field
begin field z
int32_t value
end field
end object
end field
end object)_"
);
}
}
}
}
SCENARIO
(
"load inspectors support fields with a getter and setter"
)
{
GIVEN
(
"a person object"
)
{
auto
x
=
person
{
"John Doe"
,
{}};
WHEN
(
"passing a setter and setter pair for the member name"
)
{
auto
get_name
=
[
&
x
]
{
return
x
.
name
;
};
auto
set_name
=
[
&
x
](
std
::
string
val
)
{
x
.
name
=
std
::
move
(
val
);
};
THEN
(
"the inspector reads the state from the getter"
)
{
CHECK
(
f
.
object
(
x
).
fields
(
f
.
field
(
"name"
,
get_name
,
set_name
),
f
.
field
(
"phone"
,
x
.
phone
)));
CHECK_EQ
(
f
.
log
,
R"_(
begin object person
begin field name
std::string value
end field
begin optional field phone
end field
end object)_"
);
}
}
}
}
CAF_TEST_FIXTURE_SCOPE_END
()
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