001    /*
002     * Copyright 2002-2004 the original author or authors.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package org.springframework.richclient.command;
017    
018    import junit.framework.Assert;
019    import junit.framework.TestCase;
020    
021    import org.easymock.EasyMock;
022    import org.easymock.IArgumentMatcher;
023    import org.springframework.util.ObjectUtils;
024    
025    
026    /**
027     * This is an abstract test case for implementations of the {@link CommandRegistry} interface. 
028     * Subclasses only need to override the {@link #getCommandRegistry()} method to return the 
029     * concrete implementation to be tested.
030     *
031     * @author Kevin Stembridge
032     * @since 0.3
033     *
034     */
035    public abstract class AbstractCommandRegistryTests extends TestCase {
036    
037        /**
038         * Creates a new uninitialized {@code AbstractCommandRegistryTests}.
039         */
040        protected AbstractCommandRegistryTests() {
041            super();
042        }
043        
044        /**
045         * Subclasses must override this method to provide the concrete implementation of the registry
046         * to be tested. A new, empy registry must be provided. This method may be called often, so 
047         * subclasses should take care to not repeat any unnecessary initialization.
048         *
049         * @return The registry implementation to be tested, never null.
050         */
051        protected abstract CommandRegistry getCommandRegistry();
052        
053        /**
054         * Tests the {@link CommandRegistry#registerCommand(AbstractCommand)} method.
055         */
056        public void testRegisterCommand() {
057            
058            CommandRegistry registry = getCommandRegistry();
059            CommandRegistryListener listener 
060                    = (CommandRegistryListener) EasyMock.createStrictMock(CommandRegistryListener.class);
061            registry.addCommandRegistryListener(listener);
062            
063            EasyMock.replay(listener);
064    
065            try {
066                registry.registerCommand(null);
067                Assert.fail("Should throw IllegalArgumentException");
068            }
069            catch (IllegalArgumentException e) {
070                //test passes
071            }
072            
073            EasyMock.verify(listener);
074            EasyMock.reset(listener);
075            EasyMock.replay(listener);
076            
077            try {
078                registry.registerCommand(new TestCommand());
079                Assert.fail("Should throw IllegalArgumentException because commandId has not been set");
080            }
081            catch (IllegalArgumentException e) {
082                //test passes
083            }
084    
085            EasyMock.verify(listener);
086            EasyMock.reset(listener);
087            
088            TestCommand command1 = new TestCommand("command");
089            CommandRegistryEvent event = new CommandRegistryEvent(registry, command1);
090            
091            listener.commandRegistered(matchEvent(event));
092            
093            EasyMock.replay(listener);
094            registry.registerCommand(command1);
095            EasyMock.verify(listener);
096    
097            Assert.assertTrue("command1 not registered", registry.containsCommand(command1.getId()));
098            Assert.assertEquals("command1 not registered", command1, registry.getCommand(command1.getId()));
099    
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    }