001    package listFW.test;
002    
003    import junit.framework.TestCase;
004    import listFW.*;
005    import listFW.factory.*;
006    import listFW.visitor.*;
007    
008    /**
009     * A JUnit test case class.
010     * @author Mathias Ricken - Copyright 2008 - All rights reserved.
011     */
012    public class Test_NewList extends TestCase {
013      
014      /**
015       * Test the internal toString() method of a list
016       */
017      public void test_toString() {
018        IListFactory<String> f = new CompositeListFactory<String>();
019        
020        IList<String> l = f.makeEmptyList();
021        assertEquals("Empty list", "()", l.toString());
022        l = f.makeNEList("a",l);
023        //System.out.println("class = "+l.getClass());
024        assertEquals("(a)", "(a)", l.toString());
025        l = f.makeNEList("b",l);
026        assertEquals("(b, a)", "(b, a)", l.toString());
027        l = f.makeNEList("c",l);
028        assertEquals("(c, b, a)", "(c, b, a)", l.toString());
029      }
030      
031      /**
032       * Custom class used by the test_ToStringAlgo test
033       */
034      class TestClass {
035        private String s;
036        public TestClass(String s) {
037          this.s = s;
038        }
039        
040        public String toString() {
041          return "["+s+"]";
042        }
043      }
044      
045      /**
046       * Tests the universality of the ToStringAlgo visitor.
047       */
048      public void test_ToStringAlgo() {
049        IListFactory<String> fstr = new CompositeListFactory<String>();
050        
051        IListAlgo<Object, ?, ?> algo = ToStringAlgo.Singleton;
052        
053        IList<String> lstr = fstr.makeEmptyList();
054        assertEquals("Empty list", "()", lstr.execute(algo));
055        lstr = fstr.makeNEList("a",lstr);
056        assertEquals("(a)", "(a)", lstr.execute(algo));
057        lstr = fstr.makeNEList("b",lstr);
058        assertEquals("(b, a)", "(b, a)", lstr.execute(algo));
059        lstr = fstr.makeNEList("c",lstr);
060        assertEquals("(c, b, a)", "(c, b, a)", lstr.execute(algo));
061        
062        IListFactory<Double> fdoub = new CompositeListFactory<Double>();
063        IList<Double> ldoub = fdoub.makeEmptyList();
064        assertEquals("Empty list", "()", ldoub.execute(algo));
065        ldoub = fdoub.makeNEList(1.2,ldoub);
066        assertEquals("(1.2)", "(1.2)", ldoub.execute(algo));
067        ldoub = fdoub.makeNEList(3.4,ldoub);
068        assertEquals("(3.4, 1.2)", "(3.4, 1.2)", ldoub.execute(algo));
069        ldoub = fdoub.makeNEList(5.678,ldoub);
070        assertEquals("(5.678, 3.4, 1.2)", "(5.678, 3.4, 1.2)", ldoub.execute(algo));
071        
072        IListFactory<TestClass> ftc = new CompositeListFactory<TestClass>();
073        IList<TestClass> ltc = ftc.makeEmptyList();
074        assertEquals("Empty list", "()", ltc.execute(algo));
075        ltc = ftc.makeNEList(new TestClass("yahoo"),ltc);
076        assertEquals("([yahoo])", "([yahoo])", ltc.execute(algo));
077        ltc = ftc.makeNEList(new TestClass("google"),ltc);
078        assertEquals("([google], [yahoo])", "([google], [yahoo])", ltc.execute(algo));
079        ltc = ftc.makeNEList(new TestClass("msn"),ltc);
080        assertEquals("([msn], [google], [yahoo])", "([msn], [google], [yahoo])", ltc.execute(algo));
081      }
082      
083      /**
084       * Test a more complex visitor that uses an input parameter that is 
085       * not itself parameterized.
086       */
087      public void test_MakePhrase() {
088        IListFactory<String> f = new CompositeListFactory<String>();
089        IListAlgo<String, String, String> algo = MakePhrase.Singleton;
090        
091        IList<String> l = f.makeEmptyList();
092        assertEquals("Empty list", "", l.execute(algo));
093        l = f.makeNEList("a", l);
094        assertEquals("(a)","[ a ]", l.execute(algo, "[","]"));
095        l = f.makeNEList("b",l);
096        assertEquals("(b, a)", "[ b ][ a ]", l.execute(algo, "[","]"));
097        l = f.makeNEList("c",l);
098        assertEquals("(c, b, a)", "[ c ][ b ][ a ]", l.execute(algo, "[","]"));
099        
100        // Note the semantic difficulties that arise from the fact that the following test passes
101        // The visitor is called with only one parameter, not two, but it behaves as if two were passed.
102        // This is language issue, not a visitor issue.
103        assertEquals("(c, b, a)", "[ c ][ b ][ a ]", l.execute(algo, new String[]{"[","]"}));
104        
105      }
106      
107      /**
108       * Test the parameterized list factory
109       */
110      public void test_factory() {
111        IListFactory<Integer> fint = new CompositeListFactory<Integer>();
112        
113        IList<Integer> lint = fint.makeEmptyList();
114        assertEquals("Empty Integer list", "()", lint.toString());
115        
116        lint = fint.makeNEList(5, lint);
117        //fint.makeNEList(5.2, lint);  // should not compile
118        assertEquals("(5)", "(5)", lint.toString());
119        
120        IListFactory<Double> fdoub = new CompositeListFactory<Double>();
121        IList<Double> ldoub = fdoub.makeEmptyList();
122        assertEquals("Empty Double list", "()", ldoub.toString());
123        
124        // heterogeneous lists.   The following lines should not compile
125        // ldoub = fdoub.makeNEList(5.2, lint);
126        //IList<Integer> l = fint.makeNEList(7, ldoub);
127      }
128      
129      /**
130       * Test the summing of a list of integers
131       */
132      public void test_SumIntList() {
133        IListAlgo<Integer, ?, ?> algo = new SumIntList();
134        
135        IListFactory<Integer> fint = new CompositeListFactory<Integer>();
136        
137        IList<Integer> lint = fint.makeEmptyList(); 
138        assertEquals("Empty list", 0, lint.execute(algo));
139        
140        lint = fint.makeNEList(31, lint);
141        assertEquals("(31)", 31, lint.execute(algo));
142        
143        lint = fint.makeNEList(7, lint);
144        assertEquals("(7, 31)", 38, lint.execute(algo));
145        
146        IListFactory<Double> fdoub = new CompositeListFactory<Double>();
147        
148        // The following line won't even compile any more because heterogeneous lists 
149        // are disallowed.
150        //    lint = fdoub.makeNEList(1.2, lint);
151        // 
152        //    // algo for a homogeneous list should fail on a heterogeneous list
153        //    try {
154        //      fail("heterogeneous list "+lint+": result = " +lint.execute(algo));
155        //    } 
156        //    catch(ClassCastException e) {
157        //      // this exception should be thrown
158        //    }
159        //    catch(Exception e) {
160        //      fail("heterogeneous list "+lint+": Exception = "+ e);
161        //    }
162        
163        
164      }
165      
166      /**
167       * Test the summing of a list of numbers, which should work on a list of 
168       * integers or a list of doubles.
169       */
170      public void test_SumNumList() {
171        
172        IListAlgo<Number, ?, ?> algo = new SumNumList();
173        
174        //Try on list of Integers
175        IListFactory<Integer> fint = new CompositeListFactory<Integer>();
176        
177        IList<Integer> lint = fint.makeEmptyList(); 
178        assertEquals("Empty list", 0, lint.execute(algo));
179        
180        lint = fint.makeNEList(31, lint);
181        assertEquals("(31)", 31.0, lint.execute(algo));
182        
183        lint = fint.makeNEList(7, lint);
184        assertEquals("(7, 31)", 38.0, lint.execute(algo));
185        
186        //Try same algo on list of Doubles
187        IListFactory<Double> fdoub = new CompositeListFactory<Double>();
188        
189        IList<Double> ldoub = fdoub.makeEmptyList(); 
190        assertEquals("Empty list", 0, ldoub.execute(algo));
191        
192        ldoub = fdoub.makeNEList(31.2, ldoub);
193        assertEquals("(31.2)", 31.2, ldoub.execute(algo));
194        
195        ldoub = fdoub.makeNEList(7.5, ldoub);
196        assertEquals("(7.5, 31.2)", 38.7, ldoub.execute(algo));
197      }
198      
199      /**
200       * Test the summing of the integer part of a list of numbers.  This is just
201       * to show that an Integer can be returned when a Number is specified.
202       */
203      public void test_SumIntValList() {
204        
205        IListAlgo<Number, ?, ?> algo = new SumIntValList();
206        
207        // Note that the algo returns an Integer, not a Number, and that assertEquals
208        // is sensitive to this.
209        
210        //Try on list of Integers
211        IListFactory<Integer> fint = new CompositeListFactory<Integer>();
212        
213        IList<Integer> lint = fint.makeEmptyList(); 
214        assertEquals("Empty list", 0, lint.execute(algo));
215        
216        lint = fint.makeNEList(31, lint);
217        assertEquals("(31)", 31, lint.execute(algo));
218        
219        lint = fint.makeNEList(7, lint);
220        assertEquals("(7, 31)", 38, lint.execute(algo));
221        
222        //Try same algo on list of Doubles
223        IListFactory<Double> fdoub = new CompositeListFactory<Double>();
224        
225        IList<Double> ldoub = fdoub.makeEmptyList(); 
226        assertEquals("Empty list", 0, ldoub.execute(algo));
227        
228        ldoub = fdoub.makeNEList(31.2, ldoub);
229        assertEquals("(31.2)", 31, ldoub.execute(algo));
230        
231        ldoub = fdoub.makeNEList(7.5, ldoub);
232        assertEquals("(7.5, 31.2)", 38, ldoub.execute(algo));
233      }
234      
235      
236      /**
237       * Test a forward accumulation algorithm which is an algorithm that takes 
238       * an unparameterized input value.
239       */
240      public void test_SumIntList_Fwd() {
241        IListAlgo<Integer, ?, ?> algo = new SumIntList_Fwd();
242        
243        IListFactory<Integer> fint = new CompositeListFactory<Integer>();
244        
245        IList<Integer> lint = fint.makeEmptyList(); 
246        assertEquals("Empty list", 0, lint.execute(algo));
247        
248        lint = fint.makeNEList(31, lint);
249        assertEquals("(31)", 31, lint.execute(algo));
250        
251        lint = fint.makeNEList(7, lint);
252        assertEquals("(7, 31)", 38, lint.execute(algo));
253      }  
254      
255      
256     /**
257       * Test copying the list using a copy visitor that takes the factory as its 
258       * input parameter.
259       * Notice how the visitor (algo) is specfied as taking an IListFactory<?>
260       * which is not typed to be specifically the same as the list's type.
261       */
262      @SuppressWarnings("unchecked")
263      public void test_CopyList() {
264        IListAlgo<Integer, IList<Integer>, IListFactory<Integer>> algo = new CopyList<Integer>();
265        
266        IListFactory<Integer> fint = new CompositeListFactory<Integer>();
267        
268        IList<Integer> lint = fint.makeEmptyList(); 
269        assertEquals("Empty list", "()", lint.execute(algo, fint).toString());
270        
271        lint = fint.makeNEList(31, lint);
272        assertEquals("(31)", "(31)", lint.execute(algo, fint).toString());
273        
274        lint = fint.makeNEList(7, lint);
275        assertEquals("(7, 31)", "(7, 31)", lint.execute(algo, fint).toString());
276      }  
277    
278      /**
279       * Test copying the list using a copy visitor that takes the factory in its 
280       * constructor and thus does not use its parameter.
281       */
282      public void test_CopyList2() {
283        IListFactory<Integer> fint = new CompositeListFactory<Integer>();
284        IListAlgo<Integer, IList<Integer>, Void> algo = new CopyList2<Integer>(fint);
285            
286        IList<Integer> lint = fint.makeEmptyList(); 
287        assertEquals("Empty list", "()", lint.execute(algo).toString());
288        
289        lint = fint.makeNEList(31, lint);
290        assertEquals("(31)", "(31)", lint.execute(algo).toString());
291        
292        lint = fint.makeNEList(7, lint);
293        assertEquals("(7, 31)", "(7, 31)", lint.execute(algo).toString());
294      }  
295    
296      /**
297       * Test copying the list using a copy visitor that takes the factory as a parameter
298       */
299      @SuppressWarnings("unchecked")
300      public void test_CopyList3() {
301        IListFactory<Integer> fint = new CompositeListFactory<Integer>();
302        IListAlgo<Integer, IList<Integer>, IListFactory<Integer>> algo = new CopyList3<Integer>();
303            
304        IList<Integer> lint = fint.makeEmptyList(); 
305        assertEquals("Empty list", "()", lint.execute(algo,fint).toString());
306        
307        lint = fint.makeNEList(31, lint);
308        assertEquals("(31)", "(31)", lint.execute(algo, fint).toString());
309        
310        lint = fint.makeNEList(7, lint);
311        assertEquals("(7, 31)", "(7, 31)", lint.execute(algo, fint).toString());
312      }  
313      
314      @SuppressWarnings("unchecked")
315      public void test_ReverseList() {
316        IListAlgo<Integer, IList<Integer>, IListFactory<Integer>> algo = new ReverseList<Integer>();
317        
318        IListFactory<Integer> fint = new CompositeListFactory<Integer>();
319        
320        IList<Integer> lint = fint.makeEmptyList(); 
321        assertEquals("Empty list", "()", lint.execute(algo, fint).toString());
322        
323        lint = fint.makeNEList(31, lint);
324        assertEquals("(31)", "(31)", lint.execute(algo, fint).toString());
325        
326        lint = fint.makeNEList(7, lint);
327        assertEquals("(7, 31)", "(31, 7)", lint.execute(algo, fint).toString());
328    
329        lint = fint.makeNEList(5, lint);
330        assertEquals("(5, 7, 31)", "(31, 7, 5)", lint.execute(algo, fint).toString());
331      }  
332    
333      @SuppressWarnings("unchecked")
334      public void test_ReverseList2() {
335        IListAlgo<Integer, IList<Integer>, IListFactory<Integer>> algo = new ReverseList2<Integer>();
336        
337        IListFactory<Integer> fint = new CompositeListFactory<Integer>();
338        
339        IList<Integer> lint = fint.makeEmptyList(); 
340        IList<Integer> result = lint.execute(algo, fint);
341    
342        assertEquals("Empty list", "()", lint.execute(algo, fint).toString());
343        
344        lint = fint.makeNEList(31, lint);
345        assertEquals("(31)", "(31)", lint.execute(algo, fint).toString());
346        
347        lint = fint.makeNEList(7, lint);
348        assertEquals("(7, 31)", "(31, 7)", lint.execute(algo, fint).toString());
349    
350        lint = fint.makeNEList(5, lint);
351        assertEquals("(5, 7, 31)", "(31, 7, 5)", lint.execute(algo, fint).toString());
352      }  
353    
354      @SuppressWarnings("unchecked")
355      public void test_ReverseList3() {
356        IListAlgo<Object, IList<? extends Object>, IListFactory<?>> algo = new ReverseList3();
357        
358        IListFactory<Integer> fint = new CompositeListFactory<Integer>();
359        
360        IList<Integer> lint = fint.makeEmptyList(); 
361        //Note that the following cast is required b/c the return type is Object, not a list.
362        IList<Integer> result = (IList<Integer>)lint.execute(algo, fint);
363        
364        assertEquals("Empty list", "()", result.toString());
365    
366        
367        lint = fint.makeNEList(31, lint);
368        assertEquals("(31)", "(31)", lint.execute(algo, fint).toString());
369        
370        lint = fint.makeNEList(7, lint);
371        assertEquals("(7, 31)", "(31, 7)", lint.execute(algo, fint).toString());
372    
373        lint = fint.makeNEList(5, lint);
374        assertEquals("(5, 7, 31)", "(31, 7, 5)", lint.execute(algo, fint).toString());
375      }  
376      
377    }