Java

Форк
0
356 строк · 10.3 Кб
1
/*
2
 * Copyright (C) 2008 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.testing;
18

19
import static com.google.common.collect.Lists.newArrayList;
20
import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
21
import static java.util.Collections.emptyList;
22

23
import com.google.common.annotations.GwtCompatible;
24
import com.google.common.collect.ImmutableList;
25
import com.google.common.collect.Lists;
26
import java.util.Iterator;
27
import java.util.List;
28
import java.util.NoSuchElementException;
29
import junit.framework.TestCase;
30

31
/**
32
 * Unit test for IteratorTester.
33
 *
34
 * @author Mick Killianey
35
 */
36
@GwtCompatible
37
@SuppressWarnings("serial") // No serialization is used in this test
38
public class IteratorTesterTest extends TestCase {
39

40
  public void testCanCatchDifferentLengthOfIteration() {
41
    IteratorTester<Integer> tester =
42
        new IteratorTester<Integer>(
43
            4, MODIFIABLE, newArrayList(1, 2, 3), IteratorTester.KnownOrder.KNOWN_ORDER) {
44
          @Override
45
          protected Iterator<Integer> newTargetIterator() {
46
            return Lists.newArrayList(1, 2, 3, 4).iterator();
47
          }
48
        };
49
    assertFailure(tester);
50
  }
51

52
  public void testCanCatchDifferentContents() {
53
    IteratorTester<Integer> tester =
54
        new IteratorTester<Integer>(
55
            3, MODIFIABLE, newArrayList(1, 2, 3), IteratorTester.KnownOrder.KNOWN_ORDER) {
56
          @Override
57
          protected Iterator<Integer> newTargetIterator() {
58
            return Lists.newArrayList(1, 3, 2).iterator();
59
          }
60
        };
61
    assertFailure(tester);
62
  }
63

64
  public void testCanCatchDifferentRemoveBehaviour() {
65
    IteratorTester<Integer> tester =
66
        new IteratorTester<Integer>(
67
            3, MODIFIABLE, newArrayList(1, 2), IteratorTester.KnownOrder.KNOWN_ORDER) {
68
          @Override
69
          protected Iterator<Integer> newTargetIterator() {
70
            return ImmutableList.of(1, 2).iterator();
71
          }
72
        };
73
    assertFailure(tester);
74
  }
75

76
  public void testUnknownOrder() {
77
    new IteratorTester<Integer>(
78
        3, MODIFIABLE, newArrayList(1, 2), IteratorTester.KnownOrder.UNKNOWN_ORDER) {
79
      @Override
80
      protected Iterator<Integer> newTargetIterator() {
81
        return newArrayList(2, 1).iterator();
82
      }
83
    }.test();
84
  }
85

86
  public void testUnknownOrderUnrecognizedElement() {
87
    IteratorTester<Integer> tester =
88
        new IteratorTester<Integer>(
89
            3, MODIFIABLE, newArrayList(1, 2, 50), IteratorTester.KnownOrder.UNKNOWN_ORDER) {
90
          @Override
91
          protected Iterator<Integer> newTargetIterator() {
92
            return newArrayList(2, 1, 3).iterator();
93
          }
94
        };
95
    assertFailure(tester);
96
  }
97

98
  /**
99
   * This Iterator wraps another iterator and gives it a bug found in JDK6.
100
   *
101
   * <p>This bug is this: if you create an iterator from a TreeSet and call next() on that iterator
102
   * when hasNext() is false, so that next() throws a NoSuchElementException, then subsequent calls
103
   * to remove() will incorrectly throw an IllegalStateException, instead of removing the last
104
   * element returned.
105
   *
106
   * <p>See <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6529795">Sun bug 6529795</a>
107
   */
108
  static class IteratorWithSunJavaBug6529795<T> implements Iterator<T> {
109
    Iterator<T> iterator;
110
    boolean nextThrewException;
111

112
    IteratorWithSunJavaBug6529795(Iterator<T> iterator) {
113
      this.iterator = iterator;
114
    }
115

116
    @Override
117
    public boolean hasNext() {
118
      return iterator.hasNext();
119
    }
120

121
    @Override
122
    public T next() {
123
      try {
124
        return iterator.next();
125
      } catch (NoSuchElementException e) {
126
        nextThrewException = true;
127
        throw e;
128
      }
129
    }
130

131
    @Override
132
    public void remove() {
133
      if (nextThrewException) {
134
        throw new IllegalStateException();
135
      }
136
      iterator.remove();
137
    }
138
  }
139

140
  public void testCanCatchSunJavaBug6529795InTargetIterator() {
141
    try {
142
      /* Choose 4 steps to get sequence [next, next, next, remove] */
143
      new IteratorTester<Integer>(
144
          4, MODIFIABLE, newArrayList(1, 2), IteratorTester.KnownOrder.KNOWN_ORDER) {
145
        @Override
146
        protected Iterator<Integer> newTargetIterator() {
147
          Iterator<Integer> iterator = Lists.newArrayList(1, 2).iterator();
148
          return new IteratorWithSunJavaBug6529795<>(iterator);
149
        }
150
      }.test();
151
    } catch (AssertionError e) {
152
      return;
153
    }
154
    fail("Should have caught jdk6 bug in target iterator");
155
  }
156

157
  private static final int STEPS = 3;
158

159
  static class TesterThatCountsCalls extends IteratorTester<Integer> {
160
    TesterThatCountsCalls() {
161
      super(STEPS, MODIFIABLE, newArrayList(1), IteratorTester.KnownOrder.KNOWN_ORDER);
162
    }
163

164
    int numCallsToNewTargetIterator;
165
    int numCallsToVerify;
166

167
    @Override
168
    protected Iterator<Integer> newTargetIterator() {
169
      numCallsToNewTargetIterator++;
170
      return Lists.newArrayList(1).iterator();
171
    }
172

173
    @Override
174
    protected void verify(List<Integer> elements) {
175
      numCallsToVerify++;
176
      super.verify(elements);
177
    }
178
  }
179

180
  public void testVerifyGetsCalled() {
181
    TesterThatCountsCalls tester = new TesterThatCountsCalls();
182

183
    tester.test();
184

185
    assertEquals(
186
        "Should have verified once per stimulus executed",
187
        tester.numCallsToVerify,
188
        tester.numCallsToNewTargetIterator * STEPS);
189
  }
190

191
  public void testVerifyCanThrowAssertionThatFailsTest() {
192
    final String message = "Important info about why verify failed";
193
    IteratorTester<Integer> tester =
194
        new IteratorTester<Integer>(
195
            1, MODIFIABLE, newArrayList(1, 2, 3), IteratorTester.KnownOrder.KNOWN_ORDER) {
196
          @Override
197
          protected Iterator<Integer> newTargetIterator() {
198
            return Lists.newArrayList(1, 2, 3).iterator();
199
          }
200

201
          @Override
202
          protected void verify(List<Integer> elements) {
203
            throw new AssertionError(message);
204
          }
205
        };
206
    AssertionError actual = null;
207
    try {
208
      tester.test();
209
    } catch (AssertionError e) {
210
      actual = e;
211
    }
212
    assertNotNull("verify() should be able to cause test failure", actual);
213
    assertTrue(
214
        "AssertionError should have info about why test failed",
215
        actual.getCause().getMessage().contains(message));
216
  }
217

218
  public void testMissingException() {
219
    List<Integer> emptyList = newArrayList();
220

221
    IteratorTester<Integer> tester =
222
        new IteratorTester<Integer>(
223
            1, MODIFIABLE, emptyList, IteratorTester.KnownOrder.KNOWN_ORDER) {
224
          @Override
225
          protected Iterator<Integer> newTargetIterator() {
226
            return new Iterator<Integer>() {
227
              @Override
228
              public void remove() {
229
                // We should throw here, but we won't!
230
              }
231

232
              @Override
233
              public Integer next() {
234
                // We should throw here, but we won't!
235
                return 0;
236
              }
237

238
              @Override
239
              public boolean hasNext() {
240
                return false;
241
              }
242
            };
243
          }
244
        };
245
    assertFailure(tester);
246
  }
247

248
  public void testUnexpectedException() {
249
    IteratorTester<Integer> tester =
250
        new IteratorTester<Integer>(
251
            1, MODIFIABLE, newArrayList(1), IteratorTester.KnownOrder.KNOWN_ORDER) {
252
          @Override
253
          protected Iterator<Integer> newTargetIterator() {
254
            return new ThrowingIterator<>(new IllegalStateException());
255
          }
256
        };
257
    assertFailure(tester);
258
  }
259

260
  public void testSimilarException() {
261
    List<Integer> emptyList = emptyList();
262
    IteratorTester<Integer> tester =
263
        new IteratorTester<Integer>(
264
            1, MODIFIABLE, emptyList, IteratorTester.KnownOrder.KNOWN_ORDER) {
265
          @Override
266
          protected Iterator<Integer> newTargetIterator() {
267
            return new Iterator<Integer>() {
268
              @Override
269
              public void remove() {
270
                throw new IllegalStateException() {
271
                  /* subclass */
272
                };
273
              }
274

275
              @Override
276
              public Integer next() {
277
                throw new NoSuchElementException() {
278
                  /* subclass */
279
                };
280
              }
281

282
              @Override
283
              public boolean hasNext() {
284
                return false;
285
              }
286
            };
287
          }
288
        };
289
    tester.test();
290
  }
291

292
  public void testMismatchedException() {
293
    List<Integer> emptyList = emptyList();
294
    IteratorTester<Integer> tester =
295
        new IteratorTester<Integer>(
296
            1, MODIFIABLE, emptyList, IteratorTester.KnownOrder.KNOWN_ORDER) {
297
          @Override
298
          protected Iterator<Integer> newTargetIterator() {
299
            return new Iterator<Integer>() {
300
              @Override
301
              public void remove() {
302
                // Wrong exception type.
303
                throw new IllegalArgumentException();
304
              }
305

306
              @Override
307
              public Integer next() {
308
                // Wrong exception type.
309
                throw new UnsupportedOperationException();
310
              }
311

312
              @Override
313
              public boolean hasNext() {
314
                return false;
315
              }
316
            };
317
          }
318
        };
319
    assertFailure(tester);
320
  }
321

322
  private static void assertFailure(IteratorTester<?> tester) {
323
    try {
324
      tester.test();
325
    } catch (AssertionError expected) {
326
      return;
327
    }
328
    fail();
329
  }
330

331
  private static final class ThrowingIterator<E> implements Iterator<E> {
332
    private final RuntimeException ex;
333

334
    private ThrowingIterator(RuntimeException ex) {
335
      this.ex = ex;
336
    }
337

338
    @Override
339
    public boolean hasNext() {
340
      // IteratorTester doesn't expect exceptions for hasNext().
341
      return true;
342
    }
343

344
    @Override
345
    public E next() {
346
      ex.fillInStackTrace();
347
      throw ex;
348
    }
349

350
    @Override
351
    public void remove() {
352
      ex.fillInStackTrace();
353
      throw ex;
354
    }
355
  }
356
}
357

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.