View Javadoc
1   /*
2      Copyright 2011 Atlassian
3   
4      Licensed under the Apache License, Version 2.0 (the "License");
5      you may not use this file except in compliance with the License.
6      You may obtain a copy of the License at
7   
8          http://www.apache.org/licenses/LICENSE-2.0
9   
10     Unless required by applicable law or agreed to in writing, software
11     distributed under the License is distributed on an "AS IS" BASIS,
12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     See the License for the specific language governing permissions and
14     limitations under the License.
15   */
16  package io.atlassian.fugue;
17  
18  import org.junit.Test;
19  
20  import java.lang.reflect.InvocationTargetException;
21  import java.util.Arrays;
22  import java.util.Collections;
23  import java.util.Iterator;
24  import java.util.List;
25  import java.util.NoSuchElementException;
26  import java.util.function.Function;
27  import java.util.function.Predicate;
28  
29  import static io.atlassian.fugue.Iterables.all;
30  import static io.atlassian.fugue.Iterables.any;
31  import static io.atlassian.fugue.Iterables.emptyIterable;
32  import static io.atlassian.fugue.Iterables.findFirst;
33  import static io.atlassian.fugue.Iterables.join;
34  import static io.atlassian.fugue.Iterables.map;
35  import static io.atlassian.fugue.Iterables.partition;
36  import static io.atlassian.fugue.Iterables.rangeTo;
37  import static io.atlassian.fugue.Iterables.rangeUntil;
38  import static java.util.Arrays.asList;
39  import static java.util.Collections.emptyList;
40  import static java.util.Collections.singletonList;
41  import static org.hamcrest.MatcherAssert.assertThat;
42  import static org.hamcrest.Matchers.contains;
43  import static org.hamcrest.Matchers.everyItem;
44  import static org.hamcrest.Matchers.is;
45  import static org.hamcrest.Matchers.nullValue;
46  
47  public class IterablesTest {
48  
49    private final Predicate<Integer> grepOne = input -> new Integer(1).equals(input);
50    private final Option<Integer> none = Option.<Integer> none();
51  
52    @Test public void emptyIterableIteratorHasNext() {
53      assertThat(emptyIterable().iterator().hasNext(), is(false));
54    }
55  
56    @Test(expected = NoSuchElementException.class) public void emptyIterableIteratorNext() {
57      emptyIterable().iterator().next();
58    }
59  
60    @Test(expected = UnsupportedOperationException.class) public void emptyIterableIteratorRemove() {
61      emptyIterable().iterator().remove();
62    }
63  
64    @Test public void emptyIterablesAreEqual() {
65      assertThat(emptyIterable(), is(emptyIterable()));
66    }
67  
68    @Test public void emptyIterablesToString() {
69      assertThat(emptyIterable().toString(), is("[]"));
70    }
71  
72    @Test public void findFirstEmpty() {
73      assertThat(findFirst(emptyList(), grepOne), is(Option.<Integer> none()));
74    }
75  
76    @Test public void findFirstAbsent() {
77      assertThat(findFirst(singletonList(2), grepOne), is(none));
78    }
79  
80    @Test public void findFirstSingle() {
81      assertThat(findFirst(singletonList(1), grepOne), is(Option.some(1)));
82    }
83  
84    @Test public void findFirstWhenNotFirstElement() {
85      assertThat(findFirst(asList(2, 1), grepOne), is(Option.some(1)));
86    }
87  
88    @Test public void findFirstMultipleMatches() {
89      final Pair<Integer, Integer> expected = Pair.pair(1, 1);
90      final List<Pair<Integer, Integer>> ts = Arrays.asList(expected, Pair.pair(2, 2), Pair.pair(1, 3), Pair.pair(2, 4));
91  
92      final Option<Pair<Integer, Integer>> found = findFirst(ts, input -> input.left().equals(1));
93  
94      assertThat(found, is(Option.some(expected)));
95    }
96  
97    @Test public void rangeToSingle() {
98      assertThat(rangeTo(1, 5), is(contains(1, 2, 3, 4, 5)));
99    }
100 
101   @Test public void rangeToSingleNegative() {
102     assertThat(rangeTo(5, 1), is(contains(5, 4, 3, 2, 1)));
103   }
104 
105   @Test public void rangeUntilSingle() {
106     assertThat(rangeUntil(1, 5), is(contains(1, 2, 3, 4)));
107   }
108 
109   @Test public void rangeUntilSingleNegative() {
110     assertThat(rangeUntil(5, 1), is(contains(5, 4, 3, 2)));
111   }
112 
113   @Test public void rangeToStep() {
114     assertThat(rangeTo(1, 5, 2), is(contains(1, 3, 5)));
115   }
116 
117   @Test public void rangeToMaxValue() {
118     assertThat(rangeTo(Integer.MAX_VALUE - 1, Integer.MAX_VALUE), is(contains(Integer.MAX_VALUE - 1, Integer.MAX_VALUE)));
119   }
120 
121   @Test public void rangeToMinValue() {
122     assertThat(rangeTo(Integer.MIN_VALUE + 1, Integer.MIN_VALUE), is(contains(Integer.MIN_VALUE + 1, Integer.MIN_VALUE)));
123   }
124 
125   @Test(expected = NoSuchElementException.class) public void rangeToIterator() {
126     final Iterator<Integer> iterator = rangeTo(1, 1, 1).iterator();
127     iterator.next();
128     iterator.next();
129   }
130 
131   @Test public void rangeUntilStep() {
132     assertThat(rangeUntil(1, 5, 2), is(contains(1, 3)));
133   }
134 
135   @Test public void rangeToNegativeStep() {
136     assertThat(rangeTo(8, -1, -3), is(contains(8, 5, 2, -1)));
137   }
138 
139   @Test public void rangeUntilNegativeStep() {
140     assertThat(rangeUntil(8, -1, -3), is(contains(8, 5, 2)));
141   }
142 
143   @Test public void rangeToEqual() {
144     assertThat(rangeTo(1, 1), is(contains(1)));
145   }
146 
147   @Test(expected = IllegalArgumentException.class) public void rangeToNegative() {
148     assertThat(rangeTo(1, 2, -1), is(contains(1)));
149   }
150 
151   @Test(expected = IllegalArgumentException.class) public void rangeToBackwardsPositive() {
152     assertThat(rangeTo(2, 1, 1), is(contains(1)));
153   }
154 
155   @Test(expected = IllegalArgumentException.class) public void rangeToZero() {
156     assertThat(rangeTo(1, 2, 0), is(contains(1)));
157   }
158 
159   @Test(expected = IllegalArgumentException.class) public void rangeUntilNegative() {
160     assertThat(rangeUntil(1, 2, -1), is(contains(1)));
161   }
162 
163   @Test(expected = IllegalArgumentException.class) public void rangeUntilBackwardsPositive() {
164     assertThat(rangeUntil(2, 1, 1), is(contains(1)));
165   }
166 
167   @Test(expected = IllegalArgumentException.class) public void rangeUntilZero() {
168     assertThat(rangeUntil(1, 2, 0), is(contains(1)));
169   }
170 
171   @Test public void partitionSimple() {
172     final Pair<Iterable<Integer>, Iterable<Integer>> part = partition(asList(1, 2, 3, 4), i -> i > 2);
173     assertThat(part.left(), contains(3, 4));
174     assertThat(part.right(), contains(1, 2));
175   }
176 
177   @Test public void flatMapConcatenates() {
178     final Iterable<String> result = Iterables.flatMap(asList("123", "ABC"), CharSplitter::new);
179     assertThat(result, contains("1", "2", "3", "A", "B", "C"));
180   }
181 
182   @Test public void findFirstFunctionWorks() {
183     assertThat(findFirst(Predicate.isEqual(3)).apply(asList(1, 2, 3)), is(Option.some(3)));
184   }
185 
186   @Test public void findFirstFunctionFails() {
187     assertThat(findFirst(Predicate.isEqual(3)).apply(asList(1, 2, 4)), is(Option.<Integer> none()));
188   }
189 
190   @Test(expected = InvocationTargetException.class) public void nonInstantiable() throws Exception {
191     Eithers.getOrThrow(UtilityFunctions.<Iterables> defaultCtor().apply(Iterables.class));
192   }
193 
194   @Test public void revMap() {
195     final Iterable<Function<Integer, Integer>> fs = asList(from -> from + 1, from -> from + 2, from -> from * from);
196     assertThat(Iterables.revMap(fs, 3), contains(4, 5, 9));
197   }
198 
199   @Test public void flattenCollapses() {
200     final Iterable<Iterable<Integer>> iterables = asList(singletonList(1), singletonList(2));
201     assertThat(join(iterables), contains(1, 2));
202   }
203 
204   @Test public void findAnyMatching() {
205     assertThat(any(Arrays.asList(1, 2, 3), ii -> ii > 2), is(true));
206   }
207 
208   @Test public void findAnyNoMatching() {
209     assertThat(any(Arrays.asList(1, 2, 3), ii -> ii < 0), is(false));
210   }
211 
212   @Test public void findAnyEmpty() {
213     assertThat(any(Collections.<Integer> emptyList(), ii -> ii < 0), is(false));
214   }
215 
216   @Test public void findAllMatching() {
217     assertThat(all(Arrays.asList(1, 2, 3), ii -> ii > 0), is(true));
218   }
219 
220   @Test public void findAllNoMatching() {
221     assertThat(all(Arrays.asList(1, 2, 3), ii -> ii < 2), is(false));
222   }
223 
224   @Test public void findAllEmpty() {
225     assertThat(all(Collections.<Integer> emptyList(), ii -> ii < 0), is(true));
226   }
227 
228   @Test public void mapChangesIterable() {
229     assertThat(map(Arrays.asList(1, 2, 3), i -> i + 1), contains(2, 3, 4));
230   }
231 
232   @Test public void mappingNull() {
233     assertThat(map(Arrays.asList(1, 2, 3), i -> null), everyItem(nullValue()));
234   }
235 
236   /**
237    * Splits a string into characters.
238    */
239   static class CharSplitter implements Iterable<String> {
240     private final CharSequence from;
241 
242     CharSplitter(final CharSequence from) {
243       this.from = from;
244     }
245 
246     @Override public Iterator<String> iterator() {
247       return new Iterators.Abstract<String>() {
248         int index = 0;
249 
250         @Override protected String computeNext() {
251           if (index >= from.length()) {
252             return endOfData();
253           }
254           return from.subSequence(index, ++index).toString(); // up by 1
255         }
256       };
257     }
258   }
259 }