1   /*
2   * E-nspire Gemini.
3   * A Java and AspectJ based framework that enables transparent 
4   * bidirectional relationships between Plain Old Java Objects.
5   * 
6   * Copyright (C) 2005 Dragan Djuric
7   * 
8   * This program is free software; you can redistribute it and/or
9   * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  * 
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  * 
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21  * 
22  * Contact the author at dragand@dev.java.net
23  */
24  package com.enspire.gemini.bidirectional;
25  
26  import java.util.Collection;
27  import java.util.HashSet;
28  import java.util.Iterator;
29  import java.util.LinkedList;
30  import java.util.Set;
31  
32  import org.jmock.Mock;
33  
34  import com.enspire.collections.decorator.SetDecorator;
35  import com.enspire.collections.decorator.SetDecoratorTest;
36  import com.enspire.gemini.RelationshipUpdater;
37  
38  /***
39   * @author Dragan Djuric <dragand@dev.java.net>
40   *
41   */
42  public class BidirectionalSetTest extends SetDecoratorTest{
43  
44      private BidirectionalSet testBidirectionalSet;
45      
46      private Mock mockRelationshipUpdater;
47      private Object owner;
48      private String oppositeName = "name";
49      
50      protected BidirectionalSet createTestBidirectionalSet() {
51          return new BidirectionalSet();
52      }
53      
54      /***
55       * Creates a decorated decorated to test.
56       * @param c a decorated that is being decorated
57       * @return new bean to test
58       */
59      protected SetDecorator createTestedCollection(Collection c) {
60          return new BidirectionalSet();        
61      }
62      
63      /***
64       * @return Returns the mockRelationshipUpdater.
65       */
66      public Mock getMockRelationshipUpdater() {
67          return mockRelationshipUpdater;
68      }
69      
70      /***
71       * @return Returns the owner.
72       */
73      public Object getOwner() {
74          return owner;
75      }
76  
77      /***
78       * @see junit.framework.TestCase#setUp()
79       */
80      protected void setUp() throws Exception {
81          super.setUp();
82          owner = new Object();
83          testBidirectionalSet = (BidirectionalSet)getTestedCollection();
84          mockRelationshipUpdater = new Mock(RelationshipUpdater.class);
85          testBidirectionalSet.setOppositeName(oppositeName);
86          RelationshipUpdater relationshipUpdater = 
87                  (RelationshipUpdater)mockRelationshipUpdater.proxy();
88          testBidirectionalSet.setRelationshipUpdater(relationshipUpdater);
89          testBidirectionalSet.setOwner(owner);
90          testBidirectionalSet.setPropertyValue(getDecorated());
91      }
92  
93      /***
94       * @see com.enspire.collections.decorator.SetDecoratorTest#testAdd()
95       */
96      
97      public void testAdd() {
98          testBidirectionalSet.setPropertyValue(new HashSet());
99          Object object = new Object();
100         mockRelationshipUpdater.expects(once()).method("set").
101                 with(same(object), same(oppositeName), same(owner));
102         assertTrue("The add method of decoratedCollection collection should be invoked.", //$NON-NLS-1$
103                 testBidirectionalSet.add(object));
104     }
105     
106     public void testAddExisting() {
107         testBidirectionalSet.setPropertyValue(new HashSet());
108         Object object = new Object();
109         mockRelationshipUpdater.expects(once()).method("set").
110                 with(same(object), same(oppositeName), same(owner));
111         assertTrue("object should be added and relationshipUpdater.set invoked.", //$NON-NLS-1$
112                 testBidirectionalSet.add(object));
113         assertFalse("object should NOT be added and relationshipUpdater.set NOT invoked.", //$NON-NLS-1$
114                 testBidirectionalSet.add(object));
115     }
116     
117     public void testAddUpdaterThrowsException() {
118         testBidirectionalSet.setPropertyValue(new HashSet());
119         Object object = new Object();
120         mockRelationshipUpdater.expects(once()).method("set").
121                 with(same(object), same(oppositeName), same(owner)).will(
122                 throwException(new RuntimeException()));
123         try {
124             testBidirectionalSet.add(object);
125             fail("RuntimeException should be thrown.");
126         } catch(RuntimeException e) {
127             assertFalse("object should not be added.", 
128                     testBidirectionalSet.contains(object));
129         }        
130     }
131     
132     /***
133      * @see com.enspire.collections.decorator.SetDecoratorTest#testAddAll()
134      */
135     
136     public void testAddAll() {
137         testBidirectionalSet.setPropertyValue(new HashSet());
138         Collection coll = new LinkedList();
139         Object ok0 = new Object();
140         Object ok1 = new Object();
141         coll.add(ok0);
142         coll.add(ok1);
143         mockRelationshipUpdater.expects(once()).method("set").
144                 with(same(ok0), same(oppositeName), same(owner));
145         mockRelationshipUpdater.expects(once()).method("set").
146                 with(same(ok1), same(oppositeName), same(owner));
147         assertTrue("coll elements should be added.", 
148                 testBidirectionalSet.addAll(coll));
149     }
150 
151     public void testAddAllUpdaterThrowsException() {
152         testBidirectionalSet.setPropertyValue(new HashSet());
153         Collection coll = new LinkedList();
154         Object ok = new Object();
155         Object wrong = new Object();
156         coll.add(ok);
157         coll.add(wrong);
158         mockRelationshipUpdater.expects(once()).method("set").
159                 with(same(ok), same(oppositeName), same(owner));
160         mockRelationshipUpdater.expects(once()).method("unset").
161                 with(same(ok), same(oppositeName), same(owner));
162         mockRelationshipUpdater.expects(once()).method("set").
163                 with(same(wrong), same(oppositeName), same(owner)).will(
164                         throwException(new RuntimeException()));
165         try {
166             testBidirectionalSet.addAll(coll);
167             fail("RuntimeException should be thrown.");
168         } catch(RuntimeException e) {
169             assertFalse("ok should not be added.", 
170                     testBidirectionalSet.contains(ok));
171             assertFalse("wrong should not be added.", 
172                     testBidirectionalSet.contains(ok));
173         }    
174     }
175     
176     /***
177      * @see com.enspire.collections.decorator.SetDecoratorTest#testRemove()
178      */
179     
180     public void testRemove() {
181         Set unidirectional = new HashSet();
182         testBidirectionalSet.setPropertyValue(unidirectional);
183         Object object = new Object();
184         unidirectional.add(object);
185         mockRelationshipUpdater.expects(once()).method("unset").
186                 with(same(object), same(oppositeName), same(owner));
187         assertTrue("The remove method of decoratedCollection collection should be invoked.", //$NON-NLS-1$
188                 testBidirectionalSet.remove(object));
189     }
190     
191     public void testRemoveNonExisting() {
192         testBidirectionalSet.setPropertyValue(new HashSet());
193         Object object = new Object();
194         assertFalse("object should NOT be removed and relationshipUpdater.unset NOT invoked.", //$NON-NLS-1$
195                 testBidirectionalSet.remove(object));
196     }
197     
198     public void testRemoveUpdaterThrowsException() {
199         Set unidirectional = new HashSet();
200         testBidirectionalSet.setPropertyValue(unidirectional);
201         Object object = new Object();
202         unidirectional.add(object);
203         mockRelationshipUpdater.expects(once()).method("unset").
204                 with(same(object), same(oppositeName), same(owner)).will(
205                 throwException(new RuntimeException()));
206         try {
207             testBidirectionalSet.remove(object);
208             fail("RuntimeException should be thrown.");
209         } catch(RuntimeException e) {
210             assertTrue("object should not be removed.", 
211                     testBidirectionalSet.contains(object));
212         }        
213     }
214     
215     /***
216      * @see com.enspire.collections.decorator.SetDecoratorTest#testRemoveAll()
217      */
218     
219     public void testRemoveAll() {
220         Set unidirectional = new HashSet();
221         testBidirectionalSet.setPropertyValue(unidirectional);
222         Collection coll = new LinkedList();
223         Object ok0 = new Object();
224         Object ok1 = new Object();
225         unidirectional.add(ok0);
226         unidirectional.add(ok1);
227         coll.add(ok0);
228         coll.add(ok1);
229         mockRelationshipUpdater.expects(once()).method("unset").
230                 with(same(ok0), same(oppositeName), same(owner));
231         mockRelationshipUpdater.expects(once()).method("unset").
232                 with(same(ok1), same(oppositeName), same(owner));
233         assertTrue("coll elements should be removed.", 
234                 testBidirectionalSet.removeAll(coll));
235     }
236 
237     public void testRemoveAllUpdaterThrowsException() {
238         Set unidirectional = new HashSet();
239         testBidirectionalSet.setPropertyValue(unidirectional);
240         Collection coll = new LinkedList();
241         Object ok = new Object();
242         Object wrong = new Object();
243         unidirectional.add(ok);
244         unidirectional.add(wrong);
245         coll.add(ok);
246         coll.add(wrong);
247         mockRelationshipUpdater.expects(once()).method("unset").
248                 with(same(ok), same(oppositeName), same(owner));
249         mockRelationshipUpdater.expects(once()).method("set").
250                 with(same(ok), same(oppositeName), same(owner));
251         mockRelationshipUpdater.expects(once()).method("unset").
252                 with(same(wrong), same(oppositeName), same(owner)).will(
253                         throwException(new RuntimeException()));
254         try {
255             testBidirectionalSet.removeAll(coll);
256             fail("RuntimeException should be thrown.");
257         } catch(RuntimeException e) {
258             assertTrue("ok should not be removed.", 
259                     testBidirectionalSet.contains(ok));
260             assertTrue("wrong should not be removed.", 
261                     testBidirectionalSet.contains(ok));
262         }    
263     }
264     
265     /***
266      * Tests <code>retainAll()</code> method.
267      */
268     public void testRetainAll() {
269         try {
270             testBidirectionalSet.retainAll(null);
271             fail("The operation should throw an exception, it is unsupported.");
272         } catch (UnsupportedOperationException e) {
273             assertTrue("retainAll() is not supported.", true);
274         }
275     }
276     
277     /***
278      * Tests <code>clear()</code> method.
279      */
280     public void testClear() {
281         try {
282             testBidirectionalSet.clear();
283             fail("The operation should throw an exception, it is unsupported.");
284         } catch (UnsupportedOperationException e) {
285             assertTrue("clear() is not supported.", true);
286         }
287     }
288     
289     /***
290      * Tests <code>iterator()</code> method.
291      */
292     public void testIterator() {
293         testBidirectionalSet.setPropertyValue(new HashSet());
294         Object object = new Object();
295         mockRelationshipUpdater.expects(once()).method("set").
296                 with(same(object), same(oppositeName), same(owner));
297         mockRelationshipUpdater.expects(once()).method("unset").
298                 with(same(object), same(oppositeName), same(owner));
299         testBidirectionalSet.add(object);
300         Iterator it = testBidirectionalSet.iterator();
301         it.next();
302         it.remove();
303     }
304 }