fix tricky regression noticed by Vyacheslav Tokarev on Google Reader.
[kdelibs.git] / kde3support / tests / kcommandtest.cpp
blobd1c49cc585adbbf92b358bc9eee1153656e6ba57
1 #include "kcommandtest.h"
2 #include "kcommandtest.moc"
4 #include "qtest_kde.h"
6 #include <kactioncollection.h>
7 #include <kaction.h>
8 #include <k3command.h>
9 #include <klocale.h>
11 QTEST_KDEMAIN(KCommandTest, GUI)
13 class KTestCommand : public K3NamedCommand
15 public:
16 KTestCommand( const QString& name ) : K3NamedCommand( name ) {}
17 ~KTestCommand() {
18 deletedCommands.append( name() );
20 virtual void execute() {
21 executedCommands.append( name() );
23 virtual void unexecute() {
24 unexecutedCommands.append( name() );
26 static QStringList executedCommands;
27 static QStringList unexecutedCommands;
28 static QStringList deletedCommands;
29 static void clearLists() {
30 executedCommands.clear();
31 unexecutedCommands.clear();
32 deletedCommands.clear();
36 QStringList KTestCommand::executedCommands;
37 QStringList KTestCommand::unexecutedCommands;
38 QStringList KTestCommand::deletedCommands;
40 static QString commandListToString( const QList<K3Command *>& commands )
42 QStringList lst;
43 foreach( K3Command* cmd, commands )
44 lst.append( cmd->name() );
45 return lst.join(",");
48 void KCommandTest::testMacroCommand()
51 K3MacroCommand macroCommand( "foo" );
52 macroCommand.execute(); // no-op
53 macroCommand.unexecute(); // no-op
54 KTestCommand* c1 = new KTestCommand( "1" );
55 macroCommand.addCommand( c1 );
56 KTestCommand* c2 = new KTestCommand( "2" );
57 macroCommand.addCommand( c2 );
58 macroCommand.execute();
59 QCOMPARE( KTestCommand::executedCommands.join( "," ), QString( "1,2" ) );
60 macroCommand.unexecute();
61 QCOMPARE( KTestCommand::unexecutedCommands.join( "," ), QString( "2,1" ) ); // reverse order
62 } // end of scope for KMacroCommand
63 QCOMPARE( KTestCommand::deletedCommands.join( "," ), QString( "1,2" ) ); // ok the order doesn't matter ;)
65 KTestCommand::clearLists();
68 void KCommandTest::testCommandHistoryAdd()
70 KTestCommand::clearLists();
71 m_commandsExecuted = 0;
72 m_documentRestored = 0;
73 KActionCollection actionCollection( ( QWidget*)0 );
75 K3CommandHistory ch( &actionCollection );
76 connect( &ch, SIGNAL( commandExecuted( K3Command* ) ), this, SLOT( slotCommandExecuted( K3Command* ) ) );
77 connect( &ch, SIGNAL( documentRestored() ), this, SLOT( slotDocumentRestored() ) );
79 // Checking the empty state
80 QAction* undo = actionCollection.action( "edit_undo" );
81 QVERIFY( undo );
82 QVERIFY( !undo->isEnabled() );
83 QVERIFY( !ch.isUndoAvailable() );
84 QVERIFY( ch.undoCommands().isEmpty() );
85 QCOMPARE( undo->text(), i18n( "&Undo" ) );
86 QAction* redo = actionCollection.action( "edit_redo" );
87 QVERIFY( redo );
88 QVERIFY( !redo->isEnabled() );
89 QVERIFY( !ch.isRedoAvailable() );
90 QVERIFY( ch.redoCommands().isEmpty() );
91 QCOMPARE( redo->text(), i18n( "&Redo" ) );
92 ch.updateActions();
93 QVERIFY( !undo->isEnabled() );
94 QVERIFY( !ch.isUndoAvailable() );
95 QVERIFY( !redo->isEnabled() );
96 QVERIFY( !ch.isRedoAvailable() );
97 QCOMPARE( ch.presentCommand(), (K3Command * )0 );
99 KTestCommand* c1 = new KTestCommand( "1" );
100 ch.addCommand( c1 ); // executes the action
101 QCOMPARE( KTestCommand::executedCommands.join( "," ), QString( "1" ) );
102 QVERIFY( undo->isEnabled() );
103 QVERIFY( ch.isUndoAvailable() );
104 QCOMPARE( undo->text(), i18n( "&Undo: %1" , 1) );
105 QVERIFY( !redo->isEnabled() );
106 QVERIFY( !ch.isRedoAvailable() );
107 ch.updateActions();
108 QVERIFY( undo->isEnabled() );
109 QVERIFY( ch.isUndoAvailable() );
110 QVERIFY( !redo->isEnabled() );
111 QVERIFY( !ch.isRedoAvailable() );
112 QCOMPARE( m_documentRestored, 0 );
113 QCOMPARE( ch.presentCommand(), c1 );
114 //ch.undo();
115 undo->trigger();
116 QCOMPARE( m_documentRestored, 1 );
117 QCOMPARE( KTestCommand::unexecutedCommands.join( "," ), QString( "1" ) );
118 QVERIFY( !undo->isEnabled() );
119 QVERIFY( !ch.isUndoAvailable() );
120 QCOMPARE( undo->text(), i18n( "&Undo" ) );
121 QVERIFY( redo->isEnabled() );
122 QVERIFY( ch.isRedoAvailable() );
123 QCOMPARE( ch.presentCommand(), (K3Command * )0 );
124 ch.redo();
125 QCOMPARE( KTestCommand::executedCommands.join( "," ), QString( "1,1" ) );
126 QVERIFY( undo->isEnabled() );
127 QVERIFY( ch.isUndoAvailable() );
128 QVERIFY( !redo->isEnabled() );
129 QVERIFY( !ch.isRedoAvailable() );
130 QCOMPARE( ch.presentCommand(), c1 );
131 KTestCommand::clearLists();
133 KTestCommand* c2 = new KTestCommand( "2" );
134 ch.addCommand( c2 );
135 QVERIFY( undo->isEnabled() );
136 QVERIFY( ch.isUndoAvailable() );
137 QCOMPARE( undo->text(), i18n( "&Undo: %1" , 2) );
138 QCOMPARE( commandListToString( ch.undoCommands() ), QString( "2,1" ) );
139 QCOMPARE( commandListToString( ch.undoCommands(1) ), QString( "2" ) );
140 QVERIFY( !redo->isEnabled() );
141 QVERIFY( !ch.isRedoAvailable() );
142 ch.undo();
143 QVERIFY( undo->isEnabled() );
144 QVERIFY( ch.isUndoAvailable() );
145 QCOMPARE( commandListToString( ch.undoCommands() ), QString( "1" ) );
146 QVERIFY( redo->isEnabled() );
147 QVERIFY( ch.isRedoAvailable() );
148 QCOMPARE( commandListToString( ch.redoCommands() ), QString( "2" ) );
149 QCOMPARE( redo->text(), i18n( "&Redo: %1" , 2) );
150 ch.updateActions();
151 QVERIFY( undo->isEnabled() );
152 QVERIFY( ch.isUndoAvailable() );
153 QVERIFY( redo->isEnabled() );
154 QVERIFY( ch.isRedoAvailable() );
155 QCOMPARE( KTestCommand::unexecutedCommands.join( "," ), QString( "2" ) );
156 ch.undo();
157 QCOMPARE( m_documentRestored, 2 );
158 QVERIFY( !undo->isEnabled() );
159 QVERIFY( !ch.isUndoAvailable() );
160 QVERIFY( redo->isEnabled() );
161 QVERIFY( ch.isRedoAvailable() );
162 QCOMPARE( commandListToString( ch.redoCommands() ), QString( "1,2" ) );
163 QCOMPARE( commandListToString( ch.redoCommands(1) ), QString( "1" ) );
164 ch.updateActions();
165 QVERIFY( !undo->isEnabled() );
166 QVERIFY( !ch.isUndoAvailable() );
167 QVERIFY( redo->isEnabled() );
168 QVERIFY( ch.isRedoAvailable() );
169 QCOMPARE( redo->text(), i18n( "&Redo: %1" , 1) );
170 QCOMPARE( KTestCommand::unexecutedCommands.join( "," ), QString( "2,1" ) );
171 ch.redo();
172 QCOMPARE( KTestCommand::executedCommands.join( "," ), QString( "2,1" ) );
173 KTestCommand::clearLists();
175 // c3, check that it truncates history, i.e. the history is now 1,3
176 KTestCommand* c3 = new KTestCommand( "3" );
177 ch.addCommand( c3 );
178 // c2 got deleted
179 QCOMPARE( KTestCommand::deletedCommands.join( "," ), QString( "2" ) );
180 QCOMPARE( ch.presentCommand(), c3 );
181 ch.undo();
182 QVERIFY( undo->isEnabled() );
183 QVERIFY( ch.isUndoAvailable() );
184 QVERIFY( redo->isEnabled() );
185 QVERIFY( ch.isRedoAvailable() );
186 QCOMPARE( ch.presentCommand(), c1 );
187 ch.undo();
188 QCOMPARE( m_documentRestored, 3 );
189 QVERIFY( !undo->isEnabled() );
190 QVERIFY( !ch.isUndoAvailable() );
191 QVERIFY( redo->isEnabled() );
192 QVERIFY( ch.isRedoAvailable() );
194 ch.redo();
195 ch.redo();
196 QVERIFY( !redo->isEnabled() );
197 QVERIFY( !ch.isRedoAvailable() );
198 QCOMPARE( redo->text(), i18n( "&Redo" ) );
200 QCOMPARE( m_commandsExecuted, 12 ); // every add, undo and redo
201 QCOMPARE( m_documentRestored, 3 );
202 QCOMPARE( KTestCommand::deletedCommands.join( "," ), QString( "2,1,3" ) ); // ok the order doesn't matter ;)
205 void KCommandTest::testDocumentRestored()
207 KTestCommand::clearLists();
208 m_commandsExecuted = 0;
209 m_documentRestored = 0;
211 K3CommandHistory ch;
212 connect( &ch, SIGNAL( commandExecuted( K3Command* ) ), this, SLOT( slotCommandExecuted( K3Command* ) ) );
213 connect( &ch, SIGNAL( documentRestored() ), this, SLOT( slotDocumentRestored() ) );
215 ch.documentSaved(); // saved with empty history
217 KTestCommand* c1 = new KTestCommand( "1" );
218 ch.addCommand( c1 ); // executes the action
219 ch.undo();
220 QCOMPARE( m_documentRestored, 1 );
222 ch.redo();
223 ch.documentSaved(); // now saved with one item in the history
224 KTestCommand* c2 = new KTestCommand( "2" );
225 ch.addCommand( c2 );
226 QCOMPARE( m_documentRestored, 1 );
227 ch.undo();
228 QCOMPARE( m_documentRestored, 2 );
230 ch.undo();
231 ch.redo();
232 QCOMPARE( m_documentRestored, 3 );
234 QCOMPARE( m_commandsExecuted, 7 ); // every add, undo and redo
237 void KCommandTest::testUndoLimit()
239 KTestCommand::clearLists();
240 m_commandsExecuted = 0;
241 m_documentRestored = 0;
242 KActionCollection actionCollection( ( QWidget*)0 );
244 K3CommandHistory ch( &actionCollection );
245 ch.setUndoLimit( 2 );
246 ch.setRedoLimit( 2 );
248 KTestCommand* c1 = new KTestCommand( "1" );
249 ch.addCommand( c1 ); // executes the action
250 KTestCommand* c2 = new KTestCommand( "2" );
251 ch.addCommand( c2 );
252 KTestCommand* c3 = new KTestCommand( "3" );
253 ch.addCommand( c3 );
255 QAction* undo = actionCollection.action( "edit_undo" );
256 QVERIFY( undo );
257 // c1 should have been removed now; let's check that we can only undo twice.
258 //ch.undo();
259 //ch.undo();
260 undo->trigger();
261 undo->trigger();
262 QCOMPARE( m_documentRestored, 0 );
264 QVERIFY( !undo->isEnabled() );
265 QVERIFY( !ch.isUndoAvailable() );
266 QAction* redo = actionCollection.action( "edit_redo" );
267 QVERIFY( redo );
268 QVERIFY( redo->isEnabled() );
269 QVERIFY( ch.isRedoAvailable() );
270 QCOMPARE( redo->text(), i18n( "&Redo: %1" , 2 ) );
271 //ch.redo();
272 redo->trigger();
273 QVERIFY( undo->isEnabled() );
274 QVERIFY( ch.isUndoAvailable() );
275 QVERIFY( redo->isEnabled() );
276 QVERIFY( ch.isRedoAvailable() );
277 QCOMPARE( redo->text(), i18n( "&Redo: %1" , 3 ) );
278 ch.redo();
280 ch.setUndoLimit( 1 );
281 QVERIFY( undo->isEnabled() );
282 QVERIFY( ch.isUndoAvailable() );
283 ch.undo();
284 QVERIFY( !undo->isEnabled() );
285 QVERIFY( !ch.isUndoAvailable() );
286 QVERIFY( redo->isEnabled() );
287 QVERIFY( ch.isRedoAvailable() );
288 QCOMPARE( redo->text(), i18n( "&Redo: %1" , 3 ) );
290 redo->setEnabled( false ); // imagine the app goes into readonly mode
291 ch.updateActions(); // then back to readwrite, so it calls this
292 QVERIFY( !undo->isEnabled() );
293 QVERIFY( !ch.isUndoAvailable() );
294 QVERIFY( redo->isEnabled() );
295 QVERIFY( ch.isRedoAvailable() );
297 // test clear
298 ch.clear();
299 QVERIFY( !undo->isEnabled() );
300 QVERIFY( !ch.isUndoAvailable() );
301 QVERIFY( !redo->isEnabled() );
302 QVERIFY( !ch.isRedoAvailable() );
303 QCOMPARE( undo->text(), i18n( "&Undo" ) );
304 QCOMPARE( redo->text(), i18n( "&Redo" ) );
305 QCOMPARE( KTestCommand::deletedCommands.join( "," ), QString( "1,2,3" ) );
307 QCOMPARE( m_documentRestored, 0 );
310 // Helper slots
312 void KCommandTest::slotCommandExecuted( K3Command* )
314 ++m_commandsExecuted;
317 void KCommandTest::slotDocumentRestored()
319 ++m_documentRestored;