• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_operation.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 
10 namespace {
11 
12 class TestUndoOperation;
13 
14 // TestUndoService -------------------------------------------------------------
15 
16 class TestUndoService {
17  public:
18   TestUndoService();
19   ~TestUndoService();
20 
21   void Redo();
22   void TriggerOperation();
23   void RecordUndoCall();
24 
25   UndoManager undo_manager_;
26 
27   bool performing_redo_;
28 
29   int undo_operation_count_;
30   int redo_operation_count_;
31 };
32 
33 // TestUndoOperation -----------------------------------------------------------
34 
35 class TestUndoOperation : public UndoOperation {
36  public:
37   explicit TestUndoOperation(TestUndoService* undo_service);
38   virtual ~TestUndoOperation();
39 
40   // UndoOperation:
41   virtual void Undo() OVERRIDE;
42 
43  private:
44   TestUndoService* undo_service_;
45 
46   DISALLOW_COPY_AND_ASSIGN(TestUndoOperation);
47 };
48 
TestUndoOperation(TestUndoService * undo_service)49 TestUndoOperation::TestUndoOperation(TestUndoService* undo_service)
50       : undo_service_(undo_service) {
51 }
52 
~TestUndoOperation()53 TestUndoOperation::~TestUndoOperation() {
54 }
55 
Undo()56 void TestUndoOperation::Undo() {
57   undo_service_->TriggerOperation();
58   undo_service_->RecordUndoCall();
59 }
60 
61 // TestUndoService -------------------------------------------------------------
62 
TestUndoService()63 TestUndoService::TestUndoService() : performing_redo_(false),
64                                      undo_operation_count_(0),
65                                      redo_operation_count_(0) {
66 }
67 
~TestUndoService()68 TestUndoService::~TestUndoService() {
69 }
70 
Redo()71 void TestUndoService::Redo() {
72   base::AutoReset<bool> incoming_changes(&performing_redo_, true);
73   undo_manager_.Redo();
74 }
75 
TriggerOperation()76 void TestUndoService::TriggerOperation() {
77   scoped_ptr<TestUndoOperation> op(new TestUndoOperation(this));
78   undo_manager_.AddUndoOperation(op.PassAs<UndoOperation>());
79 }
80 
RecordUndoCall()81 void TestUndoService::RecordUndoCall() {
82   if (performing_redo_)
83     ++redo_operation_count_;
84   else
85     ++undo_operation_count_;
86 }
87 
88 // Tests -----------------------------------------------------------------------
89 
TEST(UndoServiceTest,AddUndoActions)90 TEST(UndoServiceTest, AddUndoActions) {
91   TestUndoService undo_service;
92 
93   undo_service.TriggerOperation();
94   undo_service.TriggerOperation();
95   EXPECT_EQ(2U, undo_service.undo_manager_.undo_count());
96   EXPECT_EQ(0U, undo_service.undo_manager_.redo_count());
97 }
98 
TEST(UndoServiceTest,UndoMultipleActions)99 TEST(UndoServiceTest, UndoMultipleActions) {
100   TestUndoService undo_service;
101 
102   undo_service.TriggerOperation();
103   undo_service.TriggerOperation();
104 
105   undo_service.undo_manager_.Undo();
106   EXPECT_EQ(1U, undo_service.undo_manager_.undo_count());
107   EXPECT_EQ(1U, undo_service.undo_manager_.redo_count());
108 
109   undo_service.undo_manager_.Undo();
110   EXPECT_EQ(0U, undo_service.undo_manager_.undo_count());
111   EXPECT_EQ(2U, undo_service.undo_manager_.redo_count());
112 
113   EXPECT_EQ(2, undo_service.undo_operation_count_);
114   EXPECT_EQ(0, undo_service.redo_operation_count_);
115 }
116 
TEST(UndoServiceTest,RedoAction)117 TEST(UndoServiceTest, RedoAction) {
118   TestUndoService undo_service;
119 
120   undo_service.TriggerOperation();
121 
122   undo_service.undo_manager_.Undo();
123   EXPECT_EQ(0U, undo_service.undo_manager_.undo_count());
124   EXPECT_EQ(1U, undo_service.undo_manager_.redo_count());
125 
126   undo_service.Redo();
127   EXPECT_EQ(1U, undo_service.undo_manager_.undo_count());
128   EXPECT_EQ(0U, undo_service.undo_manager_.redo_count());
129 
130   EXPECT_EQ(1, undo_service.undo_operation_count_);
131   EXPECT_EQ(1, undo_service.redo_operation_count_);
132 }
133 
TEST(UndoServiceTest,GroupActions)134 TEST(UndoServiceTest, GroupActions) {
135   TestUndoService undo_service;
136 
137   // Add two operations in a single action.
138   undo_service.undo_manager_.StartGroupingActions();
139   undo_service.TriggerOperation();
140   undo_service.TriggerOperation();
141   undo_service.undo_manager_.EndGroupingActions();
142 
143   // Check that only one action is created.
144   EXPECT_EQ(1U, undo_service.undo_manager_.undo_count());
145   EXPECT_EQ(0U, undo_service.undo_manager_.redo_count());
146 
147   undo_service.undo_manager_.Undo();
148   EXPECT_EQ(0U, undo_service.undo_manager_.undo_count());
149   EXPECT_EQ(1U, undo_service.undo_manager_.redo_count());
150 
151   undo_service.Redo();
152   EXPECT_EQ(1U, undo_service.undo_manager_.undo_count());
153   EXPECT_EQ(0U, undo_service.undo_manager_.redo_count());
154 
155   // Check that both operations were called in Undo and Redo.
156   EXPECT_EQ(2, undo_service.undo_operation_count_);
157   EXPECT_EQ(2, undo_service.redo_operation_count_);
158 }
159 
TEST(UndoServiceTest,SuspendUndoTracking)160 TEST(UndoServiceTest, SuspendUndoTracking) {
161   TestUndoService undo_service;
162 
163   undo_service.undo_manager_.SuspendUndoTracking();
164   EXPECT_TRUE(undo_service.undo_manager_.IsUndoTrakingSuspended());
165 
166   undo_service.TriggerOperation();
167 
168   undo_service.undo_manager_.ResumeUndoTracking();
169   EXPECT_FALSE(undo_service.undo_manager_.IsUndoTrakingSuspended());
170 
171   EXPECT_EQ(0U, undo_service.undo_manager_.undo_count());
172   EXPECT_EQ(0U, undo_service.undo_manager_.redo_count());
173 }
174 
TEST(UndoServiceTest,RedoEmptyAfterNewAction)175 TEST(UndoServiceTest, RedoEmptyAfterNewAction) {
176   TestUndoService undo_service;
177 
178   undo_service.TriggerOperation();
179   undo_service.undo_manager_.Undo();
180   EXPECT_EQ(0U, undo_service.undo_manager_.undo_count());
181   EXPECT_EQ(1U, undo_service.undo_manager_.redo_count());
182 
183   undo_service.TriggerOperation();
184   EXPECT_EQ(1U, undo_service.undo_manager_.undo_count());
185   EXPECT_EQ(0U, undo_service.undo_manager_.redo_count());
186 }
187 
TEST(UndoServiceTest,GetAllUndoOperations)188 TEST(UndoServiceTest, GetAllUndoOperations) {
189   TestUndoService undo_service;
190 
191   undo_service.TriggerOperation();
192 
193   undo_service.undo_manager_.StartGroupingActions();
194   undo_service.TriggerOperation();
195   undo_service.TriggerOperation();
196   undo_service.undo_manager_.EndGroupingActions();
197 
198   undo_service.TriggerOperation();
199 
200   undo_service.undo_manager_.Undo();
201   ASSERT_EQ(2U, undo_service.undo_manager_.undo_count());
202   ASSERT_EQ(1U, undo_service.undo_manager_.redo_count());
203 
204   std::vector<UndoOperation*> all_operations =
205       undo_service.undo_manager_.GetAllUndoOperations();
206   EXPECT_EQ(4U, all_operations.size());
207 }
208 
209 } // namespace
210