1 #include "kcommandtest.h"
2 #include "kcommandtest.moc"
6 #include <kactioncollection.h>
11 QTEST_KDEMAIN(KCommandTest
, GUI
)
13 class KTestCommand
: public K3NamedCommand
16 KTestCommand( const QString
& name
) : K3NamedCommand( name
) {}
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
)
43 foreach( K3Command
* cmd
, commands
)
44 lst
.append( cmd
->name() );
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" );
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" );
88 QVERIFY( !redo
->isEnabled() );
89 QVERIFY( !ch
.isRedoAvailable() );
90 QVERIFY( ch
.redoCommands().isEmpty() );
91 QCOMPARE( redo
->text(), i18n( "&Redo" ) );
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() );
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
);
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 );
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" );
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() );
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) );
151 QVERIFY( undo
->isEnabled() );
152 QVERIFY( ch
.isUndoAvailable() );
153 QVERIFY( redo
->isEnabled() );
154 QVERIFY( ch
.isRedoAvailable() );
155 QCOMPARE( KTestCommand::unexecutedCommands
.join( "," ), QString( "2" ) );
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" ) );
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" ) );
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" );
179 QCOMPARE( KTestCommand::deletedCommands
.join( "," ), QString( "2" ) );
180 QCOMPARE( ch
.presentCommand(), c3
);
182 QVERIFY( undo
->isEnabled() );
183 QVERIFY( ch
.isUndoAvailable() );
184 QVERIFY( redo
->isEnabled() );
185 QVERIFY( ch
.isRedoAvailable() );
186 QCOMPARE( ch
.presentCommand(), c1
);
188 QCOMPARE( m_documentRestored
, 3 );
189 QVERIFY( !undo
->isEnabled() );
190 QVERIFY( !ch
.isUndoAvailable() );
191 QVERIFY( redo
->isEnabled() );
192 QVERIFY( ch
.isRedoAvailable() );
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;
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
220 QCOMPARE( m_documentRestored
, 1 );
223 ch
.documentSaved(); // now saved with one item in the history
224 KTestCommand
* c2
= new KTestCommand( "2" );
226 QCOMPARE( m_documentRestored
, 1 );
228 QCOMPARE( m_documentRestored
, 2 );
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" );
252 KTestCommand
* c3
= new KTestCommand( "3" );
255 QAction
* undo
= actionCollection
.action( "edit_undo" );
257 // c1 should have been removed now; let's check that we can only undo twice.
262 QCOMPARE( m_documentRestored
, 0 );
264 QVERIFY( !undo
->isEnabled() );
265 QVERIFY( !ch
.isUndoAvailable() );
266 QAction
* redo
= actionCollection
.action( "edit_redo" );
268 QVERIFY( redo
->isEnabled() );
269 QVERIFY( ch
.isRedoAvailable() );
270 QCOMPARE( redo
->text(), i18n( "&Redo: %1" , 2 ) );
273 QVERIFY( undo
->isEnabled() );
274 QVERIFY( ch
.isUndoAvailable() );
275 QVERIFY( redo
->isEnabled() );
276 QVERIFY( ch
.isRedoAvailable() );
277 QCOMPARE( redo
->text(), i18n( "&Redo: %1" , 3 ) );
280 ch
.setUndoLimit( 1 );
281 QVERIFY( undo
->isEnabled() );
282 QVERIFY( ch
.isUndoAvailable() );
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() );
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 );
312 void KCommandTest::slotCommandExecuted( K3Command
* )
314 ++m_commandsExecuted
;
317 void KCommandTest::slotDocumentRestored()
319 ++m_documentRestored
;