properties-cpp 0.0.3
A very simple convenience library for handling properties and signals in C++11.
properties_test.cpp
Go to the documentation of this file.
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 */
18
19#include <core/property.h>
20
21#include <gtest/gtest.h>
22
23TEST(Property, default_construction_yields_default_value)
24{
26 EXPECT_EQ(int{}, p1.get());
27
28 static const int new_default_value = 42;
29 core::Property<int> p2{new_default_value};
30
31 EXPECT_EQ(new_default_value, p2.get());
32}
33
34TEST(Property, copy_construction_yields_correct_value)
35{
36 static const int default_value = 42;
37 core::Property<int> p1{default_value};
39
40 EXPECT_EQ(default_value, p2.get());
41}
42
43TEST(Property, assignment_operator_for_properties_works)
44{
45 static const int default_value = 42;
46 core::Property<int> p1{default_value};
48 p2 = p1;
49
50 EXPECT_EQ(default_value, p2.get());
51}
52
53TEST(Property, assignment_operator_for_raw_values_works)
54{
55 static const int default_value = 42;
57 p1 = default_value;
58
59 EXPECT_EQ(default_value, p1.get());
60}
61
62TEST(Property, equality_operator_for_properties_works)
63{
64 static const int default_value = 42;
65 core::Property<int> p1{default_value};
67 p2 = p1;
68
69 EXPECT_EQ(p1, p2);
70}
71
72TEST(Property, equality_operator_for_raw_values_works)
73{
74 static const int default_value = 42;
75 core::Property<int> p1{default_value};
76
77 EXPECT_EQ(default_value, p1);
78}
79
80namespace
81{
82template<typename T>
83struct Expectation
84{
85 Expectation(const T& expected_value) : expected_value(expected_value)
86 {
87 }
88
89 bool satisfied() const
90 {
91 return triggered && current_value == expected_value;
92 }
93
94 bool triggered = false;
95 T expected_value;
96 T current_value;
97};
98}
99
100TEST(Property, signal_changed_is_emitted_with_correct_value_for_set)
101{
102 static const int default_value = 42;
104 Expectation<int> expectation{default_value};
105
106 p1.changed().connect([&expectation](int value) { expectation.triggered = true; expectation.current_value = value; });
107
108 p1.set(default_value);
109
110 EXPECT_TRUE(expectation.satisfied());
111}
112
113TEST(Property, signal_changed_is_emitted_with_correct_value_for_assignment)
114{
115 static const int default_value = 42;
117
118 Expectation<int> expectation{42};
119
120 p1.changed().connect([&expectation](int value) { expectation.triggered = true; expectation.current_value = value; });
121
122 p1 = default_value;
123
124 EXPECT_TRUE(expectation.satisfied());
125}
126
127TEST(Property, signal_changed_is_emitted_with_correct_value_for_update)
128{
129 static const int default_value = 42;
131
132 Expectation<int> expectation{default_value};
133
134 p1.changed().connect([&expectation](int value) { expectation.triggered = true; expectation.current_value = value; });
135 p1.update([](int& value) { value = default_value; return true; });
136
137 EXPECT_TRUE(expectation.satisfied());
138}
139
140namespace
141{
142struct TextField
143{
144 void move_cursor_to(int new_position)
145 {
146 cursor_position.set(new_position);
147 }
148
149 core::Property<int> cursor_position;
150};
151}
152
153TEST(Property, cursor_position_changes_are_transported_correctly)
154{
155 int position = -1;
156
157 TextField tf;
158
159 tf.cursor_position.changed().connect(
160 [&position](int value)
161 {
162 position = value;
163 });
164
165 tf.move_cursor_to(22);
166
167 EXPECT_EQ(22, position);
168}
169
170TEST(Property, chaining_properties_works)
171{
172 core::Property<int> p1, p2;
173
174 p1 | p2;
175
176 p1.set(42);
177
178 EXPECT_EQ(42, p2.get());
179}
180
181TEST(Property, getter_is_invoked_for_get_operations)
182{
183 bool invoked = false;
184 auto getter = [&invoked]()
185 {
186 invoked = true;
187 return 42;
188 };
189
191 prop.install(getter);
192
193 EXPECT_EQ(42, prop.get());
194 EXPECT_TRUE(invoked);
195}
196
197TEST(Property, setter_is_invoked_for_set_operations)
198{
199 int value = 0;
200 auto setter = [&value](int new_value)
201 {
202 value = new_value;
203 };
204
206 prop.install(setter);
207
208 prop.set(42);
209 EXPECT_EQ(42, value);
210}
A very simple, templated class that allows for uniform declaration of get-able/set-able/observable me...
Definition property.h:38
void install(const Setter &setter)
install takes the provided functor and installs it for dispatching all set operations.
Definition property.h:198
virtual void set(const T &new_value)
Set the contained value to the provided value. Notify observers of the change.
Definition property.h:140
const Signal< T > & changed() const
Access to the changed signal, allows observers to subscribe to change notifications.
Definition property.h:169
virtual const T & get() const
Access the value contained within this property.
Definition property.h:157
virtual bool update(const std::function< bool(T &t)> &update_functor)
Provides in-place update facilities.
Definition property.h:183
Connection connect(const Slot &slot) const
Connects the provided slot to this signal instance.
Definition signal.h:86
TEST(Property, default_construction_yields_default_value)