1 /*
2  * Copyright (C) 2010 The Guava Authors
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 
17 package com.google.common.collect;
18 
19 import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
20 import static com.google.common.truth.Truth.assertThat;
21 
22 import com.google.common.annotations.GwtCompatible;
23 import com.google.common.annotations.GwtIncompatible;
24 import com.google.common.collect.testing.IteratorTester;
25 import java.util.Iterator;
26 import java.util.NoSuchElementException;
27 import junit.framework.AssertionFailedError;
28 import junit.framework.TestCase;
29 
30 /** Tests for {@link AbstractSequentialIterator}. */
31 @GwtCompatible(emulated = true)
32 public class AbstractSequentialIteratorTest extends TestCase {
33   @GwtIncompatible // Too slow
testDoublerExhaustive()34   public void testDoublerExhaustive() {
35     new IteratorTester<Integer>(
36         3, UNMODIFIABLE, ImmutableList.of(1, 2), IteratorTester.KnownOrder.KNOWN_ORDER) {
37       @Override
38       protected Iterator<Integer> newTargetIterator() {
39         return newDoubler(1, 2);
40       }
41     }.test();
42   }
43 
testDoubler()44   public void testDoubler() {
45     Iterable<Integer> doubled =
46         new Iterable<Integer>() {
47           @Override
48           public Iterator<Integer> iterator() {
49             return newDoubler(2, 32);
50           }
51         };
52     assertThat(doubled).containsExactly(2, 4, 8, 16, 32).inOrder();
53   }
54 
testSampleCode()55   public void testSampleCode() {
56     Iterable<Integer> actual =
57         new Iterable<Integer>() {
58           @Override
59           public Iterator<Integer> iterator() {
60             Iterator<Integer> powersOfTwo =
61                 new AbstractSequentialIterator<Integer>(1) {
62                   @Override
63                   protected Integer computeNext(Integer previous) {
64                     return (previous == 1 << 30) ? null : previous * 2;
65                   }
66                 };
67             return powersOfTwo;
68           }
69         };
70     assertThat(actual)
71         .containsExactly(
72             1,
73             2,
74             4,
75             8,
76             16,
77             32,
78             64,
79             128,
80             256,
81             512,
82             1024,
83             2048,
84             4096,
85             8192,
86             16384,
87             32768,
88             65536,
89             131072,
90             262144,
91             524288,
92             1048576,
93             2097152,
94             4194304,
95             8388608,
96             16777216,
97             33554432,
98             67108864,
99             134217728,
100             268435456,
101             536870912,
102             1073741824)
103         .inOrder();
104   }
105 
testEmpty()106   public void testEmpty() {
107     Iterator<Object> empty = newEmpty();
108     assertFalse(empty.hasNext());
109     try {
110       empty.next();
111       fail();
112     } catch (NoSuchElementException expected) {
113     }
114     try {
115       empty.remove();
116       fail();
117     } catch (UnsupportedOperationException expected) {
118     }
119   }
120 
testBroken()121   public void testBroken() {
122     Iterator<Object> broken = newBroken();
123     assertTrue(broken.hasNext());
124     // We can't retrieve even the known first element:
125     try {
126       broken.next();
127       fail();
128     } catch (MyException expected) {
129     }
130     try {
131       broken.next();
132       fail();
133     } catch (MyException expected) {
134     }
135   }
136 
newDoubler(int first, final int last)137   private static Iterator<Integer> newDoubler(int first, final int last) {
138     return new AbstractSequentialIterator<Integer>(first) {
139       @Override
140       protected Integer computeNext(Integer previous) {
141         return (previous == last) ? null : previous * 2;
142       }
143     };
144   }
145 
146   private static <T> Iterator<T> newEmpty() {
147     return new AbstractSequentialIterator<T>(null) {
148       @Override
149       protected T computeNext(T previous) {
150         throw new AssertionFailedError();
151       }
152     };
153   }
154 
155   private static Iterator<Object> newBroken() {
156     return new AbstractSequentialIterator<Object>("UNUSED") {
157       @Override
158       protected Object computeNext(Object previous) {
159         throw new MyException();
160       }
161     };
162   }
163 
164   private static class MyException extends RuntimeException {}
165 }
166