001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.functor;
018
019 import static org.junit.Assert.assertEquals;
020 import static org.junit.Assert.assertFalse;
021 import static org.junit.Assert.assertNotNull;
022 import static org.junit.Assert.assertSame;
023 import static org.junit.Assert.assertTrue;
024 import static org.junit.Assert.fail;
025
026 import java.util.ArrayList;
027 import java.util.Collection;
028 import java.util.HashSet;
029 import java.util.Iterator;
030 import java.util.List;
031 import java.util.NoSuchElementException;
032 import java.util.Set;
033
034 import org.apache.commons.functor.adapter.LeftBoundPredicate;
035 import org.apache.commons.functor.core.Identity;
036 import org.apache.commons.functor.core.IsEqual;
037 import org.apache.commons.functor.core.Limit;
038 import org.apache.commons.functor.core.Offset;
039 import org.apache.commons.functor.core.algorithm.DoUntil;
040 import org.apache.commons.functor.core.algorithm.DoWhile;
041 import org.apache.commons.functor.core.algorithm.FindWithinGenerator;
042 import org.apache.commons.functor.core.algorithm.FoldLeft;
043 import org.apache.commons.functor.core.algorithm.FoldRight;
044 import org.apache.commons.functor.core.algorithm.GeneratorContains;
045 import org.apache.commons.functor.core.algorithm.InPlaceTransform;
046 import org.apache.commons.functor.core.algorithm.RecursiveEvaluation;
047 import org.apache.commons.functor.core.algorithm.RemoveMatching;
048 import org.apache.commons.functor.core.algorithm.RetainMatching;
049 import org.apache.commons.functor.core.algorithm.UntilDo;
050 import org.apache.commons.functor.core.algorithm.WhileDo;
051 import org.apache.commons.functor.core.composite.UnaryNot;
052 import org.apache.commons.functor.generator.FilteredGenerator;
053 import org.apache.commons.functor.generator.Generator;
054 import org.apache.commons.functor.generator.IteratorToGeneratorAdapter;
055 import org.apache.commons.functor.generator.TransformedGenerator;
056 import org.apache.commons.functor.generator.util.IntegerRange;
057 import org.junit.After;
058 import org.junit.Before;
059 import org.junit.Test;
060
061 /**
062 * @version $Revision: 1171255 $ $Date: 2011-09-15 22:27:39 +0200 (Thu, 15 Sep 2011) $
063 * @author Rodney Waldhoff
064 */
065 @SuppressWarnings("unchecked")
066 public class TestAlgorithms {
067
068 // Lifecycle
069 // ------------------------------------------------------------------------
070
071 @Before
072 public void setUp() throws Exception {
073 list = new ArrayList();
074 evens = new ArrayList();
075 doubled = new ArrayList();
076 listWithDuplicates = new ArrayList();
077 sum = 0;
078 for (int i=0;i<10;i++) {
079 list.add(new Integer(i));
080 doubled.add(new Integer(i*2));
081 listWithDuplicates.add(new Integer(i));
082 listWithDuplicates.add(new Integer(i));
083 sum += i;
084 if (i%2 == 0) {
085 evens.add(new Integer(i));
086 }
087 }
088 }
089
090 @After
091 public void tearDown() throws Exception {
092 list = null;
093 evens = null;
094 listWithDuplicates = null;
095 sum = 0;
096 }
097
098 // Tests
099 // ------------------------------------------------------------------------
100
101 @Test
102 public void testDetect() {
103 assertEquals(new Integer(3),FindWithinGenerator.instance().evaluate(IteratorToGeneratorAdapter.adapt(list.iterator()),equalsThree));
104 try {
105 FindWithinGenerator.instance().evaluate(IteratorToGeneratorAdapter.adapt(list.iterator()),equalsTwentyThree);
106 fail("Expected NoSuchElementException");
107 } catch(NoSuchElementException e) {
108 // expected
109 }
110 }
111
112 @Test
113 public void testDetectIfNone() {
114 assertEquals(new Integer(3),new FindWithinGenerator("Xyzzy").evaluate(IteratorToGeneratorAdapter.adapt(list.iterator()),equalsThree));
115 assertEquals("Xyzzy",new FindWithinGenerator("Xyzzy").evaluate(IteratorToGeneratorAdapter.adapt(list.iterator()),equalsTwentyThree));
116 }
117
118 @Test
119 public void testRun() {
120 Summer summer = new Summer();
121 IteratorToGeneratorAdapter.adapt(list.iterator()).run(summer);
122 assertEquals(sum,summer.sum);
123 }
124
125 @Test
126 public void testSelect1() {
127 Collection result = new FilteredGenerator(IteratorToGeneratorAdapter.adapt(list.iterator()),isEven).toCollection();
128 assertNotNull(result);
129 assertEquals(evens,result);
130 }
131
132 @Test
133 public void testSelect2() {
134 ArrayList result = new ArrayList();
135 assertSame(result,new FilteredGenerator(IteratorToGeneratorAdapter.adapt(list.iterator()),isEven).to(result));
136 assertEquals(evens,result);
137 }
138
139 @Test
140 public void testReject1() {
141 Collection result = new FilteredGenerator(IteratorToGeneratorAdapter.adapt(list.iterator()),new UnaryNot(isOdd)).toCollection();
142 assertNotNull(result);
143 assertEquals(evens,result);
144 }
145
146 @Test
147 public void testReject2() {
148 ArrayList result = new ArrayList();
149 assertSame(result,new FilteredGenerator(IteratorToGeneratorAdapter.adapt(list.iterator()),new UnaryNot(isOdd)).to(result));
150 assertEquals(evens,result);
151 }
152
153 @Test
154 public void testRetain() {
155 RetainMatching.instance().run(list.iterator(),isEven);
156 assertEquals(evens,list);
157 }
158
159 @Test
160 public void testRemove() {
161 RemoveMatching.instance().run(list.iterator(),isOdd);
162 assertEquals(evens,list);
163 }
164
165 @Test
166 public void testTransform() {
167 InPlaceTransform.instance().run(
168 list.listIterator(),
169 new UnaryFunction() {
170 public Object evaluate(Object obj) {
171 return new Integer(((Number) obj).intValue()*2);
172 }
173 }
174 );
175 assertEquals(doubled,list);
176 }
177
178 @Test
179 public void testApplyToGenerator() {
180 Generator gen = new IntegerRange(1,5);
181 Summer summer = new Summer();
182
183 new TransformedGenerator(gen, new Doubler()).run(summer);
184
185 assertEquals(2*(1+2+3+4),summer.sum);
186 }
187
188 @Test
189 public void testApply() {
190 Collection result = new TransformedGenerator(IteratorToGeneratorAdapter.adapt(list.iterator()), new Doubler())
191 .toCollection();
192 assertNotNull(result);
193 assertEquals(doubled,result);
194 }
195
196 @Test
197 public void testApply2() {
198 Set set = new HashSet();
199 assertSame(set, new TransformedGenerator(IteratorToGeneratorAdapter.adapt(list.iterator()), Identity.instance())
200 .to(set));
201 assertEquals(list.size(),set.size());
202 for (Iterator iter = list.iterator(); iter.hasNext(); ) {
203 assertTrue(set.contains(iter.next()));
204 }
205 }
206
207 @Test
208 public void testApply3() {
209 Set set = new HashSet();
210 assertSame(set, new TransformedGenerator(IteratorToGeneratorAdapter.adapt(listWithDuplicates.iterator()),
211 Identity.instance()).to(set));
212 assertTrue(listWithDuplicates.size() > set.size());
213 for (Iterator iter = listWithDuplicates.iterator(); iter.hasNext(); ) {
214 assertTrue(set.contains(iter.next()));
215 }
216 }
217
218 @Test
219 public void testContains() {
220 assertTrue(GeneratorContains.instance().test(IteratorToGeneratorAdapter.adapt(list.iterator()),equalsThree));
221 assertFalse(GeneratorContains.instance().test(IteratorToGeneratorAdapter.adapt(list.iterator()),equalsTwentyThree));
222 }
223
224 @Test
225 public void testFoldLeft() {
226 FoldLeft foldLeft = new FoldLeft(new BinaryFunction() {
227 public Object evaluate(Object a, Object b) {
228 return new Integer(((Number) a).intValue() + ((Number) b).intValue());
229 }
230 });
231 assertEquals(new Integer(sum), foldLeft.evaluate(IteratorToGeneratorAdapter.adapt(list.iterator())));
232 assertEquals(new Integer(sum), foldLeft.evaluate(IteratorToGeneratorAdapter.adapt(list.iterator()), new Integer(0)));
233 }
234
235 @Test
236 public void testFoldRight() {
237 FoldRight foldRight = new FoldRight(new BinaryFunction() {
238 public Object evaluate(Object left, Object right) {
239 StringBuffer buf = left instanceof StringBuffer ? (StringBuffer) left : new StringBuffer().append(left);
240 return buf.append(right);
241 }
242 });
243 assertEquals("0123456789", foldRight.evaluate(IteratorToGeneratorAdapter.adapt(list.iterator())).toString());
244 assertEquals("0123456789x", foldRight.evaluate(IteratorToGeneratorAdapter.adapt(list.iterator()), "x").toString());
245 }
246
247 @Test
248 public void testDoUntil() {
249 for (int i=0;i<3;i++){
250 Counter counter = new Counter();
251 new DoUntil(counter, new Offset(i)).run();
252 assertEquals(i+1,counter.count);
253 }
254 }
255
256 @Test
257 public void testDoWhile() {
258 for (int i=0;i<3;i++){
259 Counter counter = new Counter();
260 new DoWhile(counter, new Limit(i)).run();
261 assertEquals(i+1,counter.count);
262 }
263 }
264
265 @Test
266 public void testUntilDo() {
267 for (int i=0;i<3;i++){
268 Counter counter = new Counter();
269 new UntilDo(new Offset(i), counter).run();
270 assertEquals(i,counter.count);
271 }
272 }
273
274 @Test
275 public void testWhileDo() {
276 for (int i=0;i<3;i++){
277 Counter counter = new Counter();
278 new WhileDo(new Limit(i),counter).run();
279 assertEquals(i,counter.count);
280 }
281 }
282
283 @Test
284 public void testRecurse() {
285 assertEquals(new Integer(5), new RecursiveEvaluation(new RecFunc(0, false)).evaluate());
286
287 // this version will return a function. since it is not the same type
288 // as RecFunc recursion will end.
289 Function func = (Function) new RecursiveEvaluation(new RecFunc(0, true)).evaluate();
290 assertEquals(new Integer(5), func.evaluate());
291 }
292
293 /** Recursive function for test. */
294 class RecFunc implements Function {
295 int times = 0; boolean returnFunc = false;
296
297 public RecFunc(int times, boolean returnFunc) {
298 this.times = times;
299 this.returnFunc = returnFunc;
300 }
301
302 public Object evaluate() {
303 if (times < 5) {
304 return new RecFunc(++times, returnFunc);
305 } else {
306 if (returnFunc) {
307 return new Function() {
308 public Object evaluate() {
309 return new Integer(times);
310 }
311 };
312 } else {
313 return new Integer(times);
314 }
315 }
316 }
317 }
318
319 // Attributes
320 // ------------------------------------------------------------------------
321 private List list = null;
322 private List doubled = null;
323 private List evens = null;
324 private List listWithDuplicates = null;
325 private int sum = 0;
326 private UnaryPredicate equalsThree = LeftBoundPredicate.bind(IsEqual.instance(),new Integer(3));
327 private UnaryPredicate equalsTwentyThree = LeftBoundPredicate.bind(IsEqual.instance(),new Integer(23));
328 private UnaryPredicate isEven = new UnaryPredicate() {
329 public boolean test(Object obj) {
330 return ((Number) obj).intValue() % 2 == 0;
331 }
332 };
333 private UnaryPredicate isOdd = new UnaryPredicate() {
334 public boolean test(Object obj) {
335 return ((Number) obj).intValue() % 2 != 0;
336 }
337 };
338
339 // Classes
340 // ------------------------------------------------------------------------
341
342 static class Counter implements Procedure {
343 public void run() {
344 count++;
345 }
346 public int count = 0;
347 }
348
349 static class Summer implements UnaryProcedure {
350 public void run(Object that) {
351 sum += ((Number) that).intValue();
352 }
353 public int sum = 0;
354 }
355
356 static class Doubler implements UnaryFunction {
357 public Object evaluate(Object obj) {
358 return new Integer(2*((Number) obj).intValue());
359 }
360 }
361 }