OLD | NEW |
| (Empty) |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "base/auto_reset.h" | |
6 #include "chrome/browser/undo/undo_manager.h" | |
7 #include "chrome/browser/undo/undo_manager_observer.h" | |
8 #include "chrome/browser/undo/undo_operation.h" | |
9 #include "testing/gtest/include/gtest/gtest.h" | |
10 | |
11 namespace { | |
12 | |
13 class TestUndoOperation; | |
14 | |
15 // TestUndoService ------------------------------------------------------------- | |
16 | |
17 class TestUndoService { | |
18 public: | |
19 TestUndoService(); | |
20 ~TestUndoService(); | |
21 | |
22 void Redo(); | |
23 void TriggerOperation(); | |
24 void RecordUndoCall(); | |
25 | |
26 UndoManager undo_manager_; | |
27 | |
28 bool performing_redo_; | |
29 | |
30 int undo_operation_count_; | |
31 int redo_operation_count_; | |
32 }; | |
33 | |
34 // TestUndoOperation ----------------------------------------------------------- | |
35 | |
36 class TestUndoOperation : public UndoOperation { | |
37 public: | |
38 explicit TestUndoOperation(TestUndoService* undo_service); | |
39 ~TestUndoOperation() override; | |
40 | |
41 // UndoOperation: | |
42 void Undo() override; | |
43 int GetUndoLabelId() const override; | |
44 int GetRedoLabelId() const override; | |
45 | |
46 private: | |
47 TestUndoService* undo_service_; | |
48 | |
49 DISALLOW_COPY_AND_ASSIGN(TestUndoOperation); | |
50 }; | |
51 | |
52 TestUndoOperation::TestUndoOperation(TestUndoService* undo_service) | |
53 : undo_service_(undo_service) { | |
54 } | |
55 | |
56 TestUndoOperation::~TestUndoOperation() { | |
57 } | |
58 | |
59 void TestUndoOperation::Undo() { | |
60 undo_service_->TriggerOperation(); | |
61 undo_service_->RecordUndoCall(); | |
62 } | |
63 | |
64 int TestUndoOperation::GetUndoLabelId() const { | |
65 return 0; | |
66 } | |
67 | |
68 int TestUndoOperation::GetRedoLabelId() const { | |
69 return 0; | |
70 } | |
71 | |
72 // TestUndoService ------------------------------------------------------------- | |
73 | |
74 TestUndoService::TestUndoService() : performing_redo_(false), | |
75 undo_operation_count_(0), | |
76 redo_operation_count_(0) { | |
77 } | |
78 | |
79 TestUndoService::~TestUndoService() { | |
80 } | |
81 | |
82 void TestUndoService::Redo() { | |
83 base::AutoReset<bool> incoming_changes(&performing_redo_, true); | |
84 undo_manager_.Redo(); | |
85 } | |
86 | |
87 void TestUndoService::TriggerOperation() { | |
88 undo_manager_.AddUndoOperation(make_scoped_ptr(new TestUndoOperation(this))); | |
89 } | |
90 | |
91 void TestUndoService::RecordUndoCall() { | |
92 if (performing_redo_) | |
93 ++redo_operation_count_; | |
94 else | |
95 ++undo_operation_count_; | |
96 } | |
97 | |
98 // TestObserver ---------------------------------------------------------------- | |
99 | |
100 class TestObserver : public UndoManagerObserver { | |
101 public: | |
102 TestObserver() : state_change_count_(0) {} | |
103 // Returns the number of state change callbacks | |
104 int state_change_count() { return state_change_count_; } | |
105 | |
106 void OnUndoManagerStateChange() override { ++state_change_count_; } | |
107 | |
108 private: | |
109 int state_change_count_; | |
110 | |
111 DISALLOW_COPY_AND_ASSIGN(TestObserver); | |
112 }; | |
113 | |
114 // Tests ----------------------------------------------------------------------- | |
115 | |
116 TEST(UndoServiceTest, AddUndoActions) { | |
117 TestUndoService undo_service; | |
118 | |
119 undo_service.TriggerOperation(); | |
120 undo_service.TriggerOperation(); | |
121 EXPECT_EQ(2U, undo_service.undo_manager_.undo_count()); | |
122 EXPECT_EQ(0U, undo_service.undo_manager_.redo_count()); | |
123 } | |
124 | |
125 TEST(UndoServiceTest, UndoMultipleActions) { | |
126 TestUndoService undo_service; | |
127 | |
128 undo_service.TriggerOperation(); | |
129 undo_service.TriggerOperation(); | |
130 | |
131 undo_service.undo_manager_.Undo(); | |
132 EXPECT_EQ(1U, undo_service.undo_manager_.undo_count()); | |
133 EXPECT_EQ(1U, undo_service.undo_manager_.redo_count()); | |
134 | |
135 undo_service.undo_manager_.Undo(); | |
136 EXPECT_EQ(0U, undo_service.undo_manager_.undo_count()); | |
137 EXPECT_EQ(2U, undo_service.undo_manager_.redo_count()); | |
138 | |
139 EXPECT_EQ(2, undo_service.undo_operation_count_); | |
140 EXPECT_EQ(0, undo_service.redo_operation_count_); | |
141 } | |
142 | |
143 TEST(UndoServiceTest, RedoAction) { | |
144 TestUndoService undo_service; | |
145 | |
146 undo_service.TriggerOperation(); | |
147 | |
148 undo_service.undo_manager_.Undo(); | |
149 EXPECT_EQ(0U, undo_service.undo_manager_.undo_count()); | |
150 EXPECT_EQ(1U, undo_service.undo_manager_.redo_count()); | |
151 | |
152 undo_service.Redo(); | |
153 EXPECT_EQ(1U, undo_service.undo_manager_.undo_count()); | |
154 EXPECT_EQ(0U, undo_service.undo_manager_.redo_count()); | |
155 | |
156 EXPECT_EQ(1, undo_service.undo_operation_count_); | |
157 EXPECT_EQ(1, undo_service.redo_operation_count_); | |
158 } | |
159 | |
160 TEST(UndoServiceTest, GroupActions) { | |
161 TestUndoService undo_service; | |
162 | |
163 // Add two operations in a single action. | |
164 undo_service.undo_manager_.StartGroupingActions(); | |
165 undo_service.TriggerOperation(); | |
166 undo_service.TriggerOperation(); | |
167 undo_service.undo_manager_.EndGroupingActions(); | |
168 | |
169 // Check that only one action is created. | |
170 EXPECT_EQ(1U, undo_service.undo_manager_.undo_count()); | |
171 EXPECT_EQ(0U, undo_service.undo_manager_.redo_count()); | |
172 | |
173 undo_service.undo_manager_.Undo(); | |
174 EXPECT_EQ(0U, undo_service.undo_manager_.undo_count()); | |
175 EXPECT_EQ(1U, undo_service.undo_manager_.redo_count()); | |
176 | |
177 undo_service.Redo(); | |
178 EXPECT_EQ(1U, undo_service.undo_manager_.undo_count()); | |
179 EXPECT_EQ(0U, undo_service.undo_manager_.redo_count()); | |
180 | |
181 // Check that both operations were called in Undo and Redo. | |
182 EXPECT_EQ(2, undo_service.undo_operation_count_); | |
183 EXPECT_EQ(2, undo_service.redo_operation_count_); | |
184 } | |
185 | |
186 TEST(UndoServiceTest, SuspendUndoTracking) { | |
187 TestUndoService undo_service; | |
188 | |
189 undo_service.undo_manager_.SuspendUndoTracking(); | |
190 EXPECT_TRUE(undo_service.undo_manager_.IsUndoTrakingSuspended()); | |
191 | |
192 undo_service.TriggerOperation(); | |
193 | |
194 undo_service.undo_manager_.ResumeUndoTracking(); | |
195 EXPECT_FALSE(undo_service.undo_manager_.IsUndoTrakingSuspended()); | |
196 | |
197 EXPECT_EQ(0U, undo_service.undo_manager_.undo_count()); | |
198 EXPECT_EQ(0U, undo_service.undo_manager_.redo_count()); | |
199 } | |
200 | |
201 TEST(UndoServiceTest, RedoEmptyAfterNewAction) { | |
202 TestUndoService undo_service; | |
203 | |
204 undo_service.TriggerOperation(); | |
205 undo_service.undo_manager_.Undo(); | |
206 EXPECT_EQ(0U, undo_service.undo_manager_.undo_count()); | |
207 EXPECT_EQ(1U, undo_service.undo_manager_.redo_count()); | |
208 | |
209 undo_service.TriggerOperation(); | |
210 EXPECT_EQ(1U, undo_service.undo_manager_.undo_count()); | |
211 EXPECT_EQ(0U, undo_service.undo_manager_.redo_count()); | |
212 } | |
213 | |
214 TEST(UndoServiceTest, GetAllUndoOperations) { | |
215 TestUndoService undo_service; | |
216 | |
217 undo_service.TriggerOperation(); | |
218 | |
219 undo_service.undo_manager_.StartGroupingActions(); | |
220 undo_service.TriggerOperation(); | |
221 undo_service.TriggerOperation(); | |
222 undo_service.undo_manager_.EndGroupingActions(); | |
223 | |
224 undo_service.TriggerOperation(); | |
225 | |
226 undo_service.undo_manager_.Undo(); | |
227 ASSERT_EQ(2U, undo_service.undo_manager_.undo_count()); | |
228 ASSERT_EQ(1U, undo_service.undo_manager_.redo_count()); | |
229 | |
230 std::vector<UndoOperation*> all_operations = | |
231 undo_service.undo_manager_.GetAllUndoOperations(); | |
232 EXPECT_EQ(4U, all_operations.size()); | |
233 } | |
234 | |
235 TEST(UndoServiceTest, ObserverCallbacks) { | |
236 TestObserver observer; | |
237 TestUndoService undo_service; | |
238 undo_service.undo_manager_.AddObserver(&observer); | |
239 EXPECT_EQ(0, observer.state_change_count()); | |
240 | |
241 undo_service.TriggerOperation(); | |
242 EXPECT_EQ(1, observer.state_change_count()); | |
243 | |
244 undo_service.undo_manager_.StartGroupingActions(); | |
245 undo_service.TriggerOperation(); | |
246 undo_service.TriggerOperation(); | |
247 undo_service.undo_manager_.EndGroupingActions(); | |
248 EXPECT_EQ(2, observer.state_change_count()); | |
249 | |
250 // There should be at least 1 observer callback for undo. | |
251 undo_service.undo_manager_.Undo(); | |
252 int callback_count_after_undo = observer.state_change_count(); | |
253 EXPECT_GT(callback_count_after_undo, 2); | |
254 | |
255 // There should be at least 1 observer callback for redo. | |
256 undo_service.undo_manager_.Redo(); | |
257 int callback_count_after_redo = observer.state_change_count(); | |
258 EXPECT_GT(callback_count_after_redo, callback_count_after_undo); | |
259 | |
260 undo_service.undo_manager_.RemoveObserver(&observer); | |
261 undo_service.undo_manager_.Undo(); | |
262 EXPECT_EQ(callback_count_after_redo, observer.state_change_count()); | |
263 } | |
264 | |
265 } // namespace | |
OLD | NEW |