1   /*
2    * Copyright (c) 1998, 2005 Gargoyle Software Inc. All rights reserved.
3    *
4    * Redistribution and use in source and binary forms, with or without
5    * modification, are permitted provided that the following conditions are met:
6    *
7    * 1. Redistributions of source code must retain the above copyright notice,
8    *    this list of conditions and the following disclaimer.
9    * 2. Redistributions in binary form must reproduce the above copyright notice,
10   *    this list of conditions and the following disclaimer in the documentation
11   *    and/or other materials provided with the distribution.
12   * 3. The end-user documentation included with the redistribution, if any, must
13   *    include the following acknowledgment:
14   *
15   *       "This product includes software developed by Gargoyle Software Inc.
16   *        (http://www.GargoyleSoftware.com/)."
17   *
18   *    Alternately, this acknowledgment may appear in the software itself, if
19   *    and wherever such third-party acknowledgments normally appear.
20   * 4. The name "Gargoyle Software" must not be used to endorse or promote
21   *    products derived from this software without prior written permission.
22   *    For written permission, please contact info@GargoyleSoftware.com.
23   * 5. Products derived from this software may not be called "GSBase", nor may
24   *    "GSBase" appear in their name, without prior written permission of
25   *    Gargoyle Software Inc.
26   *
27   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
28   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
29   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARGOYLE
30   * SOFTWARE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
31   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
33   * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
36   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37   */
38  package com.gargoylesoftware.base.collections;
39  
40  import com.gargoylesoftware.base.testing.EventCatcher;
41  import com.gargoylesoftware.base.testing.EventCatcherRecord;
42  import com.gargoylesoftware.base.util.DetailedNullPointerException;
43  import junit.framework.TestCase;
44  import java.util.ArrayList;
45  import java.util.List;
46  import java.util.EventObject;
47  
48  /***
49   * Tests for NotificationList.
50   *
51   * @version $Revision: 1.8 $
52   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
53   */
54  public class NotificationListTest extends TestCase {
55  
56      /***
57       * Create a new test.
58       * @param name The name of the test.
59       */
60      public NotificationListTest( final String name ) {
61          super(name);
62      }
63  
64      /***
65       * Test the constructor with a null delegate.
66       */
67      public void testConstructor_Null() {
68          try {
69              new NotificationList(null);
70              fail("Expected exception for null parameter");
71          }
72          catch( final DetailedNullPointerException e ) {
73              assertEquals("delegate", e.getArgumentName());
74          }
75      }
76  
77      /***
78       * Test adding a null listener.
79       */
80      public void testAddListener_Null() {
81          final NotificationList list = new NotificationList(new ArrayList());
82          try {
83              list.addNotificationListListener(null);
84              fail("Expected exception for null parameter");
85          }
86          catch( final DetailedNullPointerException e ) {
87              assertEquals("listener", e.getArgumentName());
88          }
89      }
90  
91      /***
92       * Test removing a null listener.
93       */
94      public void testRemoveListener_Null() {
95          final NotificationList list = new NotificationList(new ArrayList());
96          try {
97              list.removeNotificationListListener(null);
98              fail("Expected exception for null parameter");
99          }
100         catch( final DetailedNullPointerException e ) {
101             assertEquals("listener", e.getArgumentName());
102         }
103     }
104 
105     /***
106      * Test adding a new object.
107      * @throws Exception if the test fails
108      */
109     public void testAdd() throws Exception {
110         final NotificationList list = new NotificationList(new ArrayList());
111         final EventCatcher eventCatcher = new EventCatcher();
112 
113         eventCatcher.listenTo(list);
114 
115         list.add( "zero" );
116         assertEquals( "eventCatcher.size()", 1, eventCatcher.getEventCount() );
117         checkRecord(eventCatcher,0,0,0,1, NotificationListEvent.INSERT);
118 
119         list.add("one");
120         assertEquals( "eventCatcher.size()", 2, eventCatcher.getEventCount() );
121         checkRecord(eventCatcher,1,1,1,1, NotificationListEvent.INSERT);
122 
123         list.add( 1, "one-half" );
124         assertEquals( "eventCatcher.size()", 3, eventCatcher.getEventCount() );
125         checkRecord(eventCatcher,2,1,1,1, NotificationListEvent.INSERT);
126     }
127 
128     /***
129      * Test adding a null collection.
130      */
131     public void testAddAll_NullCollection() {
132         final NotificationList list = new NotificationList(new ArrayList());
133         try {
134             list.addAll(null);
135             fail("Expected exception");
136         }
137         catch( final DetailedNullPointerException e ) {
138             assertEquals("collection", e.getArgumentName());
139         }
140     }
141 
142     /***
143      * Test adding a new collection at a specified index.
144      */
145     public void testAddAll_Index_NullCollection() {
146         final NotificationList list = new NotificationList(new ArrayList());
147         try {
148             list.addAll(0, null);
149             fail("Expected exception");
150         }
151         catch( final DetailedNullPointerException e ) {
152             assertEquals("collection", e.getArgumentName());
153         }
154     }
155 
156     /***
157      * Test addAll().
158      * @throws Exception if the test fails
159      */
160     public void testAddAll() throws Exception {
161         final List listToAdd = new ArrayList();
162         listToAdd.add("Popeye");
163         listToAdd.add("Olive Oyl");
164         listToAdd.add("Wimpy");
165 
166         final NotificationList list = new NotificationList(new ArrayList());
167         final EventCatcher eventCatcher = new EventCatcher();
168 
169         eventCatcher.listenTo(list);
170 
171         list.addAll( listToAdd );
172         assertEquals( "eventCatcher.size()", 1, eventCatcher.getEventCount() );
173         checkRecord(eventCatcher,0,0,0,3, NotificationListEvent.INSERT);
174 
175         list.addAll( listToAdd );
176         assertEquals( "eventCatcher.size()", 2, eventCatcher.getEventCount() );
177         checkRecord(eventCatcher,1,3,3,3, NotificationListEvent.INSERT);
178 
179         // Now test adding at a specific offset
180         list.addAll( 4, listToAdd );
181         assertEquals( "eventCatcher.size()", 3, eventCatcher.getEventCount() );
182         checkRecord(eventCatcher,2,4,4,3, NotificationListEvent.INSERT);
183     }
184 
185     /***
186      * Check one record
187      * @param eventCatcher The event catcher
188      * @param recordIndex The record index
189      * @param startIndex The start index
190      * @param endIndex The end index
191      * @param elementCount The element count
192      * @param action The action
193      */
194     private void checkRecord( final EventCatcher eventCatcher,
195                               final int recordIndex,
196                               final int startIndex,
197                               final int endIndex,
198                               final int elementCount,
199                               final int action ) {
200         final EventCatcherRecord record = eventCatcher.getEventCatcherRecordAt(recordIndex);
201 
202         final EventObject eventObject = record.getEvent();
203         if( eventObject instanceof NotificationListEvent  == false ) {
204             fail("Expected instance of NotificationListEvent but got: "
205                  + eventObject.getClass().getName() );
206         }
207         final NotificationListEvent event = (NotificationListEvent)eventObject;
208 
209         final String prefix = "record["+recordIndex+"] ";
210         assertEquals( prefix+"startIndex", event.getStartIndex(), startIndex );
211         assertEquals( prefix+"endIndex", event.getEndIndex(), endIndex );
212         assertEquals( prefix+"action", event.getAction(), action );
213 
214         switch( action ) {
215             case NotificationListEvent.INSERT:
216                 assertEquals( prefix+"oldValues().size()",
217                               event.getOldValues().size(),
218                               0 );
219                 assertEquals( prefix+"newValues().size()",
220                               event.getNewValues().size(),
221                               elementCount );
222                 break;
223 
224             case NotificationListEvent.CHANGE:
225                 assertEquals( prefix+"oldValues().size()",
226                               event.getOldValues().size(),
227                               elementCount );
228                 assertEquals( prefix+"newValues().size()",
229                               event.getNewValues().size(),
230                               elementCount );
231                 break;
232 
233             case NotificationListEvent.REMOVE:
234                 assertEquals( prefix+"oldValues().size()",
235                               event.getOldValues().size(),
236                               elementCount );
237                 assertEquals( prefix+"newValues().size()",
238                               event.getNewValues().size(),
239                               0 );
240                 break;
241 
242             default:
243                 fail("Unexpected action: "+action);
244 
245         }
246     }
247 
248     /***
249      * Test set()
250      * @throws Exception if the test fails
251      */
252     public void testSet() throws Exception {
253         final List listToAdd = new ArrayList();
254         listToAdd.add("Popeye");
255         listToAdd.add("Olive Oyl");
256         listToAdd.add("Wimpy");
257 
258         final NotificationList list = new NotificationList(new ArrayList());
259         final EventCatcher eventCatcher = new EventCatcher();
260 
261         list.addAll( listToAdd );
262 
263         eventCatcher.listenTo(list);
264 
265         list.set( 1, "Scooby Doo" );
266 
267         assertEquals( "eventCatcher.size()", 1, eventCatcher.getEventCount() );
268         checkRecord(eventCatcher,0,1,1,1, NotificationListEvent.CHANGE);
269 
270         final NotificationListEvent event =
271         (NotificationListEvent)eventCatcher.getEventCatcherRecordAt(0).getEvent();
272         assertEquals("oldValue", event.getOldValues().get(0), "Olive Oyl");
273         assertEquals("newValue", event.getNewValues().get(0), "Scooby Doo");
274     }
275 
276     /***
277      * Test remove(int)
278      * @throws Exception if the test fails
279      */
280     public void testRemove_int() throws Exception {
281         final List listToAdd = new ArrayList();
282         listToAdd.add("Popeye");
283         listToAdd.add("Olive Oyl");
284         listToAdd.add("Wimpy");
285 
286         final NotificationList list = new NotificationList(new ArrayList());
287         final EventCatcher eventCatcher = new EventCatcher();
288 
289         list.addAll( listToAdd );
290         eventCatcher.listenTo(list);
291 
292         list.remove(1);
293 
294         assertEquals( "eventCatcher.size()", 1, eventCatcher.getEventCount() );
295         checkRecord(eventCatcher,0,1,1,1, NotificationListEvent.REMOVE);
296         assertEquals( "list.size()", list.size(), 2 );
297     }
298 }
299 
300