1   /*
2    * Copyright 2002-2004 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5    * use this file except in compliance with the License. You may obtain a copy of
6    * the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations under
14   * the License.
15   */
16  package org.springframework.richclient.command;
17  
18  import junit.framework.Assert;
19  import junit.framework.TestCase;
20  
21  import org.easymock.EasyMock;
22  import org.easymock.IArgumentMatcher;
23  import org.springframework.util.ObjectUtils;
24  
25  
26  /**
27   * This is an abstract test case for implementations of the {@link CommandRegistry} interface. 
28   * Subclasses only need to override the {@link #getCommandRegistry()} method to return the 
29   * concrete implementation to be tested.
30   *
31   * @author Kevin Stembridge
32   * @since 0.3
33   *
34   */
35  public abstract class AbstractCommandRegistryTests extends TestCase {
36  
37      /**
38       * Creates a new uninitialized {@code AbstractCommandRegistryTests}.
39       */
40      protected AbstractCommandRegistryTests() {
41          super();
42      }
43      
44      /**
45       * Subclasses must override this method to provide the concrete implementation of the registry
46       * to be tested. A new, empy registry must be provided. This method may be called often, so 
47       * subclasses should take care to not repeat any unnecessary initialization.
48       *
49       * @return The registry implementation to be tested, never null.
50       */
51      protected abstract CommandRegistry getCommandRegistry();
52      
53      /**
54       * Tests the {@link CommandRegistry#registerCommand(AbstractCommand)} method.
55       */
56      public void testRegisterCommand() {
57          
58          CommandRegistry registry = getCommandRegistry();
59          CommandRegistryListener listener 
60                  = (CommandRegistryListener) EasyMock.createStrictMock(CommandRegistryListener.class);
61          registry.addCommandRegistryListener(listener);
62          
63          EasyMock.replay(listener);
64  
65          try {
66              registry.registerCommand(null);
67              Assert.fail("Should throw IllegalArgumentException");
68          }
69          catch (IllegalArgumentException e) {
70              //test passes
71          }
72          
73          EasyMock.verify(listener);
74          EasyMock.reset(listener);
75          EasyMock.replay(listener);
76          
77          try {
78              registry.registerCommand(new TestCommand());
79              Assert.fail("Should throw IllegalArgumentException because commandId has not been set");
80          }
81          catch (IllegalArgumentException e) {
82              //test passes
83          }
84  
85          EasyMock.verify(listener);
86          EasyMock.reset(listener);
87          
88          TestCommand command1 = new TestCommand("command");
89          CommandRegistryEvent event = new CommandRegistryEvent(registry, command1);
90          
91          listener.commandRegistered(matchEvent(event));
92          
93          EasyMock.replay(listener);
94          registry.registerCommand(command1);
95          EasyMock.verify(listener);
96  
97          Assert.assertTrue("command1 not registered", registry.containsCommand(command1.getId()));
98          Assert.assertEquals("command1 not registered", command1, registry.getCommand(command1.getId()));
99  
100         TestCommand command2 = new TestCommand(command1.getId());
101         event = new CommandRegistryEvent(registry, command2);
102         
103         EasyMock.reset(listener);
104         
105         listener.commandRegistered(matchEvent(event));
106         EasyMock.replay(listener);
107         registry.registerCommand(command2);
108         EasyMock.verify(listener);
109         
110         Assert.assertTrue(registry.containsCommand(command2.getId()));
111         Assert.assertEquals("command1 not overridden", command2, registry.getCommand(command2.getId()));
112 
113     }
114     
115     /**
116      * Confirms that if a CommandGroup is being registered, it will obtain a reference to the 
117      * registry that it is being added to.
118      */
119     public void testRegisterCommandGroup() {
120         
121         CommandRegistry registry = getCommandRegistry();
122 
123         CommandGroup commandGroup = new CommandGroup("testCommandGroup");
124         registry.registerCommand(commandGroup);
125 
126         assertTrue("commandgroup not registered", registry.containsCommand("testCommandGroup"));
127         assertEquals("commandgroup not registered", commandGroup, registry.getCommand("testCommandGroup"));
128         
129         Assert.assertEquals(registry, commandGroup.getCommandRegistry());
130         
131     }
132     
133     /**
134      * Tests the {@link CommandRegistry#isTypeMatch(String, Class)} method.
135      */
136     public final void testIsTypeMatch() {
137         
138         CommandRegistry registry = getCommandRegistry();
139         
140         try {
141             registry.isTypeMatch(null, Object.class);
142             Assert.fail("Should have thrown IllegalArgumentException for null commandId");
143         }
144         catch (IllegalArgumentException e) {
145             //test passes
146         }
147         
148         try {
149             registry.isTypeMatch("bogusCommandId", null);
150             Assert.fail("Should have thrown IllegalArgumentException for null targetType");
151         }
152         catch (IllegalArgumentException e) {
153             //test passes
154         }
155         
156         //Add a command to the registry which is a subclass of AbstractCommand
157         TestCommand testCommand = new TestCommand("testCommand");
158         registry.registerCommand(testCommand);
159         
160         Assert.assertTrue("Assert isTypeMatch", registry.isTypeMatch(testCommand.getId(), TestCommand.class));
161         Assert.assertTrue("Assert isTypeMatch", registry.isTypeMatch(testCommand.getId(), AbstractCommand.class));
162         Assert.assertFalse("Assert isTypeMatch", registry.isTypeMatch(testCommand.getId(), String.class));
163         
164     }
165     
166     /**
167      * Tests the {@link CommandRegistry#containsCommand(String)} method.
168      */
169     public final void testContainsCommand() {
170      
171         CommandRegistry registry = getCommandRegistry();
172         
173         try {
174             registry.containsCommand(null);
175             Assert.fail("Should have thrown an IllegalArgumentException for null commandId");
176         }
177         catch (IllegalArgumentException e) {
178             //test passes
179         }
180         
181         Assert.assertFalse("Assert registry does not contain a command", registry.containsCommand("bogusCommandId"));
182         
183         TestCommand testCommand = new TestCommand("testCommand");
184         registry.registerCommand(testCommand);
185         
186         Assert.assertTrue("Assert registry contains command", registry.containsCommand(testCommand.getId()));
187         
188     }
189 
190     /**
191      * Tests the {@link CommandRegistry#getCommand(String)} method.
192      */
193     public final void testGetCommandById() {
194         
195         CommandRegistry registry = getCommandRegistry();
196         
197         try {
198             registry.getCommand(null);
199             Assert.fail("Should have thrown an IllegalArgumentException for null commandId");
200         }
201         catch (IllegalArgumentException e) {
202             //test passes
203         }
204         
205         Assert.assertNull("getCommand should return null", registry.getCommand("bogusCommandId"));
206         
207         TestCommand testCommand = new TestCommand("testCommand");
208         registry.registerCommand(testCommand);
209         
210         Assert.assertEquals(testCommand, registry.getCommand(testCommand.getId()));
211            
212     }
213 
214     /**
215      * Tests the {@link CommandRegistry#getCommand(String, Class)} method.
216      */
217     public final void testGetCommandByIdAndRequiredType() {
218         
219         CommandRegistry registry = getCommandRegistry();
220         
221         try {
222             registry.getCommand(null, Object.class);
223             Assert.fail("Should have thrown an IllegalArgumentException for null commandId");
224         }
225         catch (IllegalArgumentException e) {
226             //test passes
227         }
228 
229         Assert.assertNull(registry.getCommand("bogusCommandId", null));
230         
231         Assert.assertNull("getCommand should return null", registry.getCommand("bogusCommandId", TestCommand.class));
232         
233         TestCommand testCommand = new TestCommand("testCommand");
234         TestCommand2 testCommand2 = new TestCommand2("testCommand2");
235         registry.registerCommand(testCommand);
236         registry.registerCommand(testCommand2);
237         
238         Assert.assertEquals(testCommand, registry.getCommand(testCommand.getId(), TestCommand.class));
239         Assert.assertEquals(testCommand, registry.getCommand(testCommand.getId(), AbstractCommand.class));
240         
241         try {
242             registry.getCommand(testCommand.getId(), TestCommand2.class);
243             Assert.fail("Should have thrown CommandNotOfRequiredTypeException");
244         }
245         catch (CommandNotOfRequiredTypeException e) {
246             Assert.assertEquals(testCommand.getId(), e.getCommandId());
247             Assert.assertEquals(TestCommand2.class, e.getRequiredType());
248             Assert.assertEquals(TestCommand.class, e.getActualType());
249         }
250         
251     }
252 
253     /**
254      * Tests the {@link CommandRegistry#getType(String)} method.
255      */
256     public final void testGetType() {
257         
258         CommandRegistry registry = getCommandRegistry();
259         
260         try {
261             registry.getType(null);
262             Assert.fail("Should have thrown an IllegalArgumentException for null commandId");
263         }
264         catch (IllegalArgumentException e) {
265             //test passes
266         }
267 
268         Assert.assertNull("getType should return null", registry.getType("bogusCommandId"));
269         
270         TestCommand testCommand = new TestCommand("testCommand");
271         TestCommand2 testCommand2 = new TestCommand2("testCommand2");
272         registry.registerCommand(testCommand);
273         registry.registerCommand(testCommand2);
274         
275         Assert.assertEquals(testCommand.getClass(), registry.getType(testCommand.getId()));
276         Assert.assertEquals(testCommand2.getClass(), registry.getType(testCommand2.getId()));
277         
278     }
279     
280     /**
281      * Tests the {@link CommandRegistry#setTargetableActionCommandExecutor(String, ActionCommandExecutor)}
282      * method.
283      */
284     public void testSetTargetableActionCommandExecutor() {
285         
286         CommandRegistry registry = getCommandRegistry();
287         TestTargetableActionCommand targetableCommand = new TestTargetableActionCommand();
288         targetableCommand.setId("bogusId");
289         registry.registerCommand(targetableCommand);
290         ActionCommandExecutor executor = (ActionCommandExecutor) EasyMock.createMock(ActionCommandExecutor.class);
291         
292         try {
293             registry.setTargetableActionCommandExecutor(null, null);
294             Assert.fail("Should have thrown an IllegalArgumentException for null commandId");
295         }
296         catch (IllegalArgumentException e) {
297             //test passes
298         }
299         
300         registry.setTargetableActionCommandExecutor(targetableCommand.getId(), executor);
301         
302         Assert.assertEquals(executor, targetableCommand.getCommandExecutor());
303         
304         registry.setTargetableActionCommandExecutor(targetableCommand.getId(), null);
305         
306         Assert.assertEquals(null, targetableCommand.getCommandExecutor());
307         
308     }
309     
310     private static class TestCommand extends AbstractCommand {
311         
312         private String id;
313         
314         /**
315          * Creates a new uninitialized {@code TestCommand}.
316          *
317          */
318         public TestCommand() {
319             //do nothing
320         }
321 
322         /**
323          * Creates a new uninitialized {@code TestCommand}.
324          *
325          * @param id
326          */
327         public TestCommand(String id) {
328             this.id = id;
329         }
330         
331         public String getId() {
332             return this.id;
333         }
334 
335         /**
336          * {@inheritDoc}
337          */
338         public void execute() {
339             //do nothing
340         }
341         
342     }
343 
344     private static class TestCommand2 extends AbstractCommand {
345         
346         private String id;
347 
348         /**
349          * Creates a new uninitialized {@code TestCommand2}.
350          *
351          */
352         public TestCommand2() {
353             //do nothing
354         }
355 
356         /**
357          * Creates a new uninitialized {@code TestCommand2}.
358          *
359          * @param id
360          */
361         public TestCommand2(String id) {
362             this.id = id;
363         }
364         
365         public String getId() {
366             return this.id;
367         }
368 
369         /**
370          * {@inheritDoc}
371          */
372         public void execute() {
373             //do nothing
374         }
375         
376     }
377     
378     private static CommandRegistryEvent matchEvent(CommandRegistryEvent event) {
379         EasyMock.reportMatcher(new CommandRegistryEventMatcher(event));
380         return event;
381     }
382     
383     private static class CommandRegistryEventMatcher implements IArgumentMatcher {
384         
385         private CommandRegistryEvent expectedEvent;
386         
387         /**
388          * Creates a new {@code CommandRegistryEventMatcher}.
389          *
390          * @param expectedEvent
391          */
392         public CommandRegistryEventMatcher(CommandRegistryEvent expectedEvent) {
393             this.expectedEvent = expectedEvent;
394         }
395         
396         /**
397          * {@inheritDoc}
398          */
399         public void appendTo(StringBuffer buffer) {
400             buffer.append("(");
401             buffer.append(expectedEvent.getClass().getName());
402             buffer.append(" with message \"");
403             buffer.append(expectedEvent.getSource());
404             buffer.append("\"\")");
405             
406         }
407 
408         /**
409          * {@inheritDoc}
410          */
411         public boolean matches(Object argument) {
412             
413             if (!(argument instanceof CommandRegistryEvent)) {
414                 return false;
415             }
416             
417             CommandRegistryEvent other = (CommandRegistryEvent) argument;
418             
419             if (!ObjectUtils.nullSafeEquals(expectedEvent.getSource(), other.getSource())) {
420                 return false;
421             }
422             
423             if (!ObjectUtils.nullSafeEquals(expectedEvent.getCommand(), other.getCommand())) {
424                 return false;
425             }
426             
427             return true;
428             
429         }
430         
431     }
432     
433     private static class TestTargetableActionCommand extends TargetableActionCommand {
434         
435         private ActionCommandExecutor executor;
436         
437         /**
438          * {@inheritDoc}
439          */
440         public void setCommandExecutor(ActionCommandExecutor commandExecutor) {
441             this.executor = commandExecutor;
442         }
443 
444         public ActionCommandExecutor getCommandExecutor() {
445             return this.executor;
446         }
447         
448     }
449 
450 }