| 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 |