FreshValueGenerator.java revision 7dd252788645e940eada959bdde927426e2531c9
1/*
2 * Copyright (C) 2012 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
17package com.google.common.testing;
18
19import static com.google.common.base.Preconditions.checkNotNull;
20
21import com.google.common.base.CharMatcher;
22import com.google.common.base.Charsets;
23import com.google.common.base.Equivalence;
24import com.google.common.base.Joiner;
25import com.google.common.base.Splitter;
26import com.google.common.base.Throwables;
27import com.google.common.base.Ticker;
28import com.google.common.collect.ArrayListMultimap;
29import com.google.common.collect.BiMap;
30import com.google.common.collect.HashBasedTable;
31import com.google.common.collect.HashBiMap;
32import com.google.common.collect.HashMultimap;
33import com.google.common.collect.HashMultiset;
34import com.google.common.collect.ImmutableBiMap;
35import com.google.common.collect.ImmutableCollection;
36import com.google.common.collect.ImmutableList;
37import com.google.common.collect.ImmutableListMultimap;
38import com.google.common.collect.ImmutableMap;
39import com.google.common.collect.ImmutableMultimap;
40import com.google.common.collect.ImmutableMultiset;
41import com.google.common.collect.ImmutableSet;
42import com.google.common.collect.ImmutableSetMultimap;
43import com.google.common.collect.ImmutableSortedMap;
44import com.google.common.collect.ImmutableSortedMultiset;
45import com.google.common.collect.ImmutableSortedSet;
46import com.google.common.collect.ImmutableTable;
47import com.google.common.collect.Iterables;
48import com.google.common.collect.LinkedHashMultimap;
49import com.google.common.collect.LinkedHashMultiset;
50import com.google.common.collect.ListMultimap;
51import com.google.common.collect.Lists;
52import com.google.common.collect.Maps;
53import com.google.common.collect.Multimap;
54import com.google.common.collect.Multiset;
55import com.google.common.collect.Ordering;
56import com.google.common.collect.RowSortedTable;
57import com.google.common.collect.SetMultimap;
58import com.google.common.collect.Sets;
59import com.google.common.collect.SortedMultiset;
60import com.google.common.collect.Table;
61import com.google.common.collect.TreeBasedTable;
62import com.google.common.collect.TreeMultiset;
63import com.google.common.primitives.UnsignedInteger;
64import com.google.common.primitives.UnsignedLong;
65import com.google.common.reflect.AbstractInvocationHandler;
66import com.google.common.reflect.Invokable;
67import com.google.common.reflect.Parameter;
68import com.google.common.reflect.Reflection;
69import com.google.common.reflect.TypeToken;
70
71import java.io.ByteArrayInputStream;
72import java.io.File;
73import java.io.InputStream;
74import java.io.Reader;
75import java.io.StringReader;
76import java.lang.annotation.ElementType;
77import java.lang.annotation.Retention;
78import java.lang.annotation.RetentionPolicy;
79import java.lang.annotation.Target;
80import java.lang.reflect.Array;
81import java.lang.reflect.InvocationTargetException;
82import java.lang.reflect.Method;
83import java.lang.reflect.TypeVariable;
84import java.math.BigDecimal;
85import java.math.BigInteger;
86import java.nio.Buffer;
87import java.nio.ByteBuffer;
88import java.nio.CharBuffer;
89import java.nio.DoubleBuffer;
90import java.nio.FloatBuffer;
91import java.nio.IntBuffer;
92import java.nio.LongBuffer;
93import java.nio.ShortBuffer;
94import java.nio.charset.Charset;
95import java.util.ArrayList;
96import java.util.Arrays;
97import java.util.Collection;
98import java.util.Comparator;
99import java.util.Currency;
100import java.util.HashMap;
101import java.util.HashSet;
102import java.util.LinkedHashMap;
103import java.util.LinkedHashSet;
104import java.util.LinkedList;
105import java.util.List;
106import java.util.Locale;
107import java.util.Map;
108import java.util.Set;
109import java.util.SortedMap;
110import java.util.SortedSet;
111import java.util.TreeMap;
112import java.util.TreeSet;
113import java.util.concurrent.ConcurrentMap;
114import java.util.concurrent.atomic.AtomicInteger;
115import java.util.regex.Pattern;
116
117import javax.annotation.Nullable;
118
119/**
120 * Generates fresh instances of types that are different from each other (if possible).
121 *
122 * @author Ben Yu
123 */
124class FreshValueGenerator {
125
126  private static final ImmutableMap<Class<?>, Method> GENERATORS;
127  static {
128    ImmutableMap.Builder<Class<?>, Method> builder =
129        ImmutableMap.builder();
130    for (Method method : FreshValueGenerator.class.getDeclaredMethods()) {
131      if (method.isAnnotationPresent(Generates.class)) {
132        builder.put(method.getReturnType(), method);
133      }
134    }
135    GENERATORS = builder.build();
136  }
137
138  private final AtomicInteger differentiator = new AtomicInteger(1);
139  private final ListMultimap<Class<?>, Object> sampleInstances = ArrayListMultimap.create();
140
141  <T> void addSampleInstances(Class<T> type, Iterable<? extends T> instances) {
142    sampleInstances.putAll(checkNotNull(type), checkNotNull(instances));
143  }
144
145  /**
146   * Returns a fresh instance for {@code type} if possible. The returned instance could be:
147   * <ul>
148   * <li>exactly of the given type, including generic type parameters, such as
149   *     {@code ImmutableList<String>};
150   * <li>of the raw type;
151   * <li>null if no fresh value can be generated.
152   * </ul>
153   */
154  @Nullable final <T> T generate(TypeToken<T> type) {
155    // Not completely safe since sample instances are registered by raw types.
156    // But we assume the generic type parameters are mostly unimportant for these dummy values,
157    // because what really matters are equals/hashCode.
158    @SuppressWarnings("unchecked")
159    T result = (T) generateIfPossible(type);
160    return result;
161  }
162
163  @Nullable final <T> T generate(Class<T> type) {
164    return generate(TypeToken.of(type));
165  }
166
167  @Nullable private Object generateIfPossible(TypeToken<?> type) {
168    Class<?> rawType = type.getRawType();
169    List<Object> samples = sampleInstances.get(rawType);
170    Object sample = nextInstance(samples, null);
171    if (sample != null) {
172      return sample;
173    }
174    if (rawType.isEnum()) {
175      return nextInstance(rawType.getEnumConstants(), null);
176    }
177    if (type.isArray()) {
178      TypeToken<?> componentType = type.getComponentType();
179      Object array = Array.newInstance(componentType.getRawType(), 1);
180      Array.set(array, 0, generateIfPossible(componentType));
181      return array;
182    }
183    Method generator = GENERATORS.get(rawType);
184    if (generator != null) {
185      ImmutableList<Parameter> params = Invokable.from(generator).getParameters();
186      List<Object> args = Lists.newArrayListWithCapacity(params.size());
187      TypeVariable<?>[] typeVars = rawType.getTypeParameters();
188      for (int i = 0; i < params.size(); i++) {
189        TypeToken<?> paramType = type.resolveType(typeVars[i]);
190        // We require all @Generates methods to either be parameter-less or accept non-null
191        // fresh values for their generic parameter types.
192        Object argValue = generateIfPossible(paramType);
193        if (argValue == null) {
194          return defaultGenerate(rawType);
195        }
196        args.add(argValue);
197      }
198      try {
199        return generator.invoke(this, args.toArray());
200      } catch (InvocationTargetException e) {
201        Throwables.propagate(e.getCause());
202      } catch (Exception e) {
203        throw Throwables.propagate(e);
204      }
205    }
206    return defaultGenerate(rawType);
207  }
208
209  private Object defaultGenerate(Class<?> rawType) {
210    if (rawType.isInterface()) {
211      // always create a new proxy
212      return newProxy(rawType);
213    }
214    return ArbitraryInstances.get(rawType);
215  }
216
217  final <T> T newProxy(final Class<T> interfaceType) {
218    return Reflection.newProxy(interfaceType, new FreshInvocationHandler(interfaceType));
219  }
220
221  private final class FreshInvocationHandler extends AbstractInvocationHandler {
222    private final int identity = freshInt();
223    private final Class<?> interfaceType;
224
225    FreshInvocationHandler(Class<?> interfaceType) {
226      this.interfaceType = interfaceType;
227    }
228
229    @Override protected Object handleInvocation(Object proxy, Method method, Object[] args) {
230      return interfaceMethodCalled(interfaceType, method);
231    }
232
233    @Override public int hashCode() {
234      return identity;
235    }
236
237    @Override public boolean equals(@Nullable Object obj) {
238      if (obj instanceof FreshInvocationHandler) {
239        FreshInvocationHandler that = (FreshInvocationHandler) obj;
240        return identity == that.identity;
241      }
242      return false;
243    }
244
245    @Override public String toString() {
246      return paramString(interfaceType, identity);
247    }
248  }
249
250  /** Subclasses can override to provide different return value for proxied interface methods. */
251  Object interfaceMethodCalled(
252      @SuppressWarnings("unused") Class<?> interfaceType,
253      @SuppressWarnings("unused") Method method) {
254    throw new UnsupportedOperationException();
255  }
256
257  private <T> T nextInstance(T[] instances, T defaultValue) {
258    return nextInstance(Arrays.asList(instances), defaultValue);
259  }
260
261  private <T> T nextInstance(Collection<T> instances, T defaultValue) {
262    if (instances.isEmpty()) {
263      return defaultValue;
264    }
265    // freshInt() is 1-based.
266    return Iterables.get(instances, (freshInt() - 1) % instances.size());
267  }
268
269  private static String paramString(Class<?> type, int i) {
270    return type.getSimpleName() + '@' + i;
271  }
272
273  /**
274   * Annotates a method to be the instance generator of a certain type. The return type is the
275   * generated type. The method parameters are non-null fresh values for each method type variable
276   * in the same type variable declaration order of the return type.
277   */
278  @Target(ElementType.METHOD)
279  @Retention(RetentionPolicy.RUNTIME)
280  private @interface Generates {}
281
282  @Generates private Class<?> freshClass() {
283    return nextInstance(
284        ImmutableList.of(
285            int.class, long.class, void.class,
286            Object.class, Object[].class, Iterable.class),
287        Object.class);
288  }
289
290  @Generates private Object freshObject() {
291    return freshString();
292  }
293
294  @Generates private Number freshNumber() {
295    return freshInt();
296  }
297
298  @Generates private int freshInt() {
299    return differentiator.getAndIncrement();
300  }
301
302  @Generates private Integer freshInteger() {
303    return new Integer(freshInt());
304  }
305
306  @Generates private long freshLong() {
307    return freshInt();
308  }
309
310  @Generates private Long freshLongObject() {
311    return new Long(freshLong());
312  }
313
314  @Generates private float freshFloat() {
315    return freshInt();
316  }
317
318  @Generates private Float freshFloatObject() {
319    return new Float(freshFloat());
320  }
321
322  @Generates private double freshDouble() {
323    return freshInt();
324  }
325
326  @Generates private Double freshDoubleObject() {
327    return new Double(freshDouble());
328  }
329
330  @Generates private short freshShort() {
331    return (short) freshInt();
332  }
333
334  @Generates private Short freshShortObject() {
335    return new Short(freshShort());
336  }
337
338  @Generates private byte freshByte() {
339    return (byte) freshInt();
340  }
341
342  @Generates private Byte freshByteObject() {
343    return new Byte(freshByte());
344  }
345
346  @Generates private char freshChar() {
347    return freshString().charAt(0);
348  }
349
350  @Generates private Character freshCharacter() {
351    return new Character(freshChar());
352  }
353
354  @Generates private boolean freshBoolean() {
355    return freshInt() % 2 == 0;
356  }
357
358  @Generates private Boolean freshBooleanObject() {
359    return new Boolean(freshBoolean());
360  }
361
362  @Generates private UnsignedInteger freshUnsignedInteger() {
363    return UnsignedInteger.fromIntBits(freshInt());
364  }
365
366  @Generates private UnsignedLong freshUnsignedLong() {
367    return UnsignedLong.fromLongBits(freshLong());
368  }
369
370  @Generates private BigInteger freshBigInteger() {
371    return BigInteger.valueOf(freshInt());
372  }
373
374  @Generates private BigDecimal freshBigDecimal() {
375    return BigDecimal.valueOf(freshInt());
376  }
377
378  @Generates private CharSequence freshCharSequence() {
379    return freshString();
380  }
381
382  @Generates private String freshString() {
383    return Integer.toString(freshInt());
384  }
385
386  @Generates private Comparable<?> freshComparable() {
387    return freshString();
388  }
389
390  @Generates private Pattern freshPattern() {
391    return Pattern.compile(freshString());
392  }
393
394  @Generates private Charset freshCharset() {
395    return nextInstance(Charset.availableCharsets().values(), Charsets.UTF_8);
396  }
397
398  @Generates private Locale freshLocale() {
399    return nextInstance(Locale.getAvailableLocales(), Locale.US);
400  }
401
402  @Generates private Currency freshCurrency() {
403    for (Set<Locale> uselessLocales = Sets.newHashSet(); ; ) {
404      Locale locale = freshLocale();
405      if (uselessLocales.contains(locale)) { // exhausted all locales
406        return Currency.getInstance(Locale.US);
407      }
408      try {
409        return Currency.getInstance(locale);
410      } catch (IllegalArgumentException e) {
411        uselessLocales.add(locale);
412      }
413    }
414  }
415
416  // common.base
417  @Generates private Joiner freshJoiner() {
418    return Joiner.on(freshString());
419  }
420
421  @Generates private Splitter freshSplitter() {
422    return Splitter.on(freshString());
423  }
424
425  @Generates private <T> Equivalence<T> freshEquivalence() {
426    return new Equivalence<T>() {
427      @Override protected boolean doEquivalent(T a, T b) {
428        return false;
429      }
430      @Override protected int doHash(T t) {
431        return 0;
432      }
433      final String string = paramString(Equivalence.class, freshInt());
434      @Override public String toString() {
435        return string;
436      }
437    };
438  }
439
440  @Generates private CharMatcher freshCharMatcher() {
441    return new CharMatcher() {
442      @Override public boolean matches(char c) {
443        return false;
444      }
445      final String string = paramString(CharMatcher.class, freshInt());
446      @Override public String toString() {
447        return string;
448      }
449    };
450  }
451
452  @Generates private Ticker freshTicker() {
453    return new Ticker() {
454      @Override public long read() {
455        return 0;
456      }
457      final String string = paramString(Ticker.class, freshInt());
458      @Override public String toString() {
459        return string;
460      }
461    };
462  }
463
464  // collect
465  @Generates private <T> Comparator<T> freshComparator() {
466    return freshOrdering();
467  }
468
469  @Generates private <T> Ordering<T> freshOrdering() {
470    return new Ordering<T>() {
471      @Override public int compare(T left, T right) {
472        return 0;
473      }
474      final String string = paramString(Ordering.class, freshInt());
475      @Override public String toString() {
476        return string;
477      }
478    };
479  }
480
481  @Generates static private <E> Iterable<E> freshIterable(E freshElement) {
482    return freshList(freshElement);
483  }
484
485  @Generates static private <E> Collection<E> freshCollection(E freshElement) {
486    return freshList(freshElement);
487  }
488
489  @Generates static private <E> List<E> freshList(E freshElement) {
490    return freshArrayList(freshElement);
491  }
492
493  @Generates static private <E> ArrayList<E> freshArrayList(E freshElement) {
494    ArrayList<E> list = Lists.newArrayList();
495    list.add(freshElement);
496    return list;
497  }
498
499  @Generates static private <E> LinkedList<E> freshLinkedList(E freshElement) {
500    LinkedList<E> list = Lists.newLinkedList();
501    list.add(freshElement);
502    return list;
503  }
504
505  @Generates static private <E> ImmutableList<E> freshImmutableList(E freshElement) {
506    return ImmutableList.of(freshElement);
507  }
508
509  @Generates static private <E> ImmutableCollection<E> freshImmutableCollection(E freshElement) {
510    return freshImmutableList(freshElement);
511  }
512
513  @Generates static private <E> Set<E> freshSet(E freshElement) {
514    return freshHashSet(freshElement);
515  }
516
517  @Generates static private <E> HashSet<E> freshHashSet(E freshElement) {
518    return freshLinkedHashSet(freshElement);
519  }
520
521  @Generates static private <E> LinkedHashSet<E> freshLinkedHashSet(E freshElement) {
522    LinkedHashSet<E> set = Sets.newLinkedHashSet();
523    set.add(freshElement);
524    return set;
525  }
526
527  @Generates static private <E> ImmutableSet<E> freshImmutableSet(E freshElement) {
528    return ImmutableSet.of(freshElement);
529  }
530
531  @Generates static private <E extends Comparable<? super E>> SortedSet<E>
532      freshSortedSet(E freshElement) {
533    return freshTreeSet(freshElement);
534  }
535
536  @Generates static private <E extends Comparable<? super E>> TreeSet<E> freshTreeSet(
537      E freshElement) {
538    TreeSet<E> set = Sets.newTreeSet();
539    set.add(freshElement);
540    return set;
541  }
542
543  @Generates static private <E extends Comparable<? super E>> ImmutableSortedSet<E>
544      freshImmutableSortedSet(E freshElement) {
545    return ImmutableSortedSet.of(freshElement);
546  }
547
548  @Generates static private <E> Multiset<E> freshMultiset(E freshElement) {
549    return freshHashMultiset(freshElement);
550  }
551
552  @Generates static private <E> HashMultiset<E> freshHashMultiset(E freshElement) {
553    HashMultiset<E> multiset = HashMultiset.create();
554    multiset.add(freshElement);
555    return multiset;
556  }
557
558  @Generates static private <E> LinkedHashMultiset<E> freshLinkedHashMultiset(E freshElement) {
559    LinkedHashMultiset<E> multiset = LinkedHashMultiset.create();
560    multiset.add(freshElement);
561    return multiset;
562  }
563
564  @Generates static private <E> ImmutableMultiset<E> freshImmutableMultiset(E freshElement) {
565    return ImmutableMultiset.of(freshElement);
566  }
567
568  @Generates static private <E extends Comparable<E>> SortedMultiset<E> freshSortedMultiset(
569      E freshElement) {
570    return freshTreeMultiset(freshElement);
571  }
572
573  @Generates static private <E extends Comparable<E>> TreeMultiset<E> freshTreeMultiset(
574      E freshElement) {
575    TreeMultiset<E> multiset = TreeMultiset.create();
576    multiset.add(freshElement);
577    return multiset;
578  }
579
580  @Generates static private <E extends Comparable<E>> ImmutableSortedMultiset<E>
581      freshImmutableSortedMultiset(E freshElement) {
582    return ImmutableSortedMultiset.of(freshElement);
583  }
584
585  @Generates static private <K, V> Map<K, V> freshMap(K key, V value) {
586    return freshHashdMap(key, value);
587  }
588
589  @Generates static private <K, V> HashMap<K, V> freshHashdMap(K key, V value) {
590    return freshLinkedHashMap(key, value);
591  }
592
593  @Generates static private <K, V> LinkedHashMap<K, V> freshLinkedHashMap(K key, V value) {
594    LinkedHashMap<K, V> map = Maps.newLinkedHashMap();
595    map.put(key, value);
596    return map;
597  }
598
599  @Generates static private <K, V> ImmutableMap<K, V> freshImmutableMap(K key, V value) {
600    return ImmutableMap.of(key, value);
601  }
602
603  @Generates static private <K, V> ConcurrentMap<K, V> freshConcurrentMap(K key, V value) {
604    ConcurrentMap<K, V> map = Maps.newConcurrentMap();
605    map.put(key, value);
606    return map;
607  }
608
609  @Generates static private <K extends Comparable<? super K>, V> SortedMap<K, V>
610      freshSortedMap(K key, V value) {
611    return freshTreeMap(key, value);
612  }
613
614  @Generates static private <K extends Comparable<? super K>, V> TreeMap<K, V> freshTreeMap(
615      K key, V value) {
616    TreeMap<K, V> map = Maps.newTreeMap();
617    map.put(key, value);
618    return map;
619  }
620
621  @Generates static private <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V>
622      freshImmutableSortedMap(K key, V value) {
623    return ImmutableSortedMap.of(key, value);
624  }
625
626  @Generates static private <K, V> Multimap<K, V> freshMultimap(K key, V value) {
627    return freshListMultimap(key, value);
628  }
629
630  @Generates static private <K, V> ImmutableMultimap<K, V> freshImmutableMultimap(K key, V value) {
631    return ImmutableMultimap.of(key, value);
632  }
633
634  @Generates static private <K, V> ListMultimap<K, V> freshListMultimap(K key, V value) {
635    return freshArrayListMultimap(key, value);
636  }
637
638  @Generates static private <K, V> ArrayListMultimap<K, V> freshArrayListMultimap(K key, V value) {
639    ArrayListMultimap<K, V> multimap = ArrayListMultimap.create();
640    multimap.put(key, value);
641    return multimap;
642  }
643
644  @Generates static private <K, V> ImmutableListMultimap<K, V> freshImmutableListMultimap(
645      K key, V value) {
646    return ImmutableListMultimap.of(key, value);
647  }
648
649  @Generates static private <K, V> SetMultimap<K, V> freshSetMultimap(K key, V value) {
650    return freshLinkedHashMultimap(key, value);
651  }
652
653  @Generates static private <K, V> HashMultimap<K, V> freshHashMultimap(K key, V value) {
654    HashMultimap<K, V> multimap = HashMultimap.create();
655    multimap.put(key, value);
656    return multimap;
657  }
658
659  @Generates static private <K, V> LinkedHashMultimap<K, V> freshLinkedHashMultimap(
660      K key, V value) {
661    LinkedHashMultimap<K, V> multimap = LinkedHashMultimap.create();
662    multimap.put(key, value);
663    return multimap;
664  }
665
666  @Generates static private <K, V> ImmutableSetMultimap<K, V> freshImmutableSetMultimap(
667      K key, V value) {
668    return ImmutableSetMultimap.of(key, value);
669  }
670
671  @Generates static private <K, V> BiMap<K, V> freshBimap(K key, V value) {
672    return freshHashBiMap(key, value);
673  }
674
675  @Generates static private <K, V> HashBiMap<K, V> freshHashBiMap(K key, V value) {
676    HashBiMap<K, V> bimap = HashBiMap.create();
677    bimap.put(key, value);
678    return bimap;
679  }
680
681  @Generates static private <K, V> ImmutableBiMap<K, V> freshImmutableBimap(
682      K key, V value) {
683    return ImmutableBiMap.of(key, value);
684  }
685
686  @Generates static private <R, C, V> Table<R, C, V> freshTable(R row, C column, V value) {
687    return freshHashBasedTable(row, column, value);
688  }
689
690  @Generates static private <R, C, V> HashBasedTable<R, C, V> freshHashBasedTable(
691      R row, C column, V value) {
692    HashBasedTable<R, C, V> table = HashBasedTable.create();
693    table.put(row, column, value);
694    return table;
695  }
696
697  @SuppressWarnings("rawtypes") // TreeBasedTable.create() is defined as such
698  @Generates static private <R extends Comparable, C extends Comparable, V> RowSortedTable<R, C, V>
699      freshRowSortedTable(R row, C column, V value) {
700    return freshTreeBasedTable(row, column, value);
701  }
702
703  @SuppressWarnings("rawtypes") // TreeBasedTable.create() is defined as such
704  @Generates static private <R extends Comparable, C extends Comparable, V> TreeBasedTable<R, C, V>
705      freshTreeBasedTable(R row, C column, V value) {
706    TreeBasedTable<R, C, V> table = TreeBasedTable.create();
707    table.put(row, column, value);
708    return table;
709  }
710
711  @Generates static private <R, C, V> ImmutableTable<R, C, V> freshImmutableTable(
712      R row, C column, V value) {
713    return ImmutableTable.of(row, column, value);
714  }
715
716  // common.reflect
717  @Generates private TypeToken<?> freshTypeToken() {
718    return TypeToken.of(freshClass());
719  }
720
721  // io types
722  @Generates private File freshFile() {
723    return new File(freshString());
724  }
725
726  @Generates private static ByteArrayInputStream freshByteArrayInputStream() {
727    return new ByteArrayInputStream(new byte[0]);
728  }
729
730  @Generates private static InputStream freshInputStream() {
731    return freshByteArrayInputStream();
732  }
733
734  @Generates private StringReader freshStringReader() {
735    return new StringReader(freshString());
736  }
737
738  @Generates private Reader freshReader() {
739    return freshStringReader();
740  }
741
742  @Generates private Readable freshReadable() {
743    return freshReader();
744  }
745
746  @Generates private Buffer freshBuffer() {
747    return freshCharBuffer();
748  }
749
750  @Generates private CharBuffer freshCharBuffer() {
751    return CharBuffer.allocate(freshInt());
752  }
753
754  @Generates private ByteBuffer freshByteBuffer() {
755    return ByteBuffer.allocate(freshInt());
756  }
757
758  @Generates private ShortBuffer freshShortBuffer() {
759    return ShortBuffer.allocate(freshInt());
760  }
761
762  @Generates private IntBuffer freshIntBuffer() {
763    return IntBuffer.allocate(freshInt());
764  }
765
766  @Generates private LongBuffer freshLongBuffer() {
767    return LongBuffer.allocate(freshInt());
768  }
769
770  @Generates private FloatBuffer freshFloatBuffer() {
771    return FloatBuffer.allocate(freshInt());
772  }
773
774  @Generates private DoubleBuffer freshDoubleBuffer() {
775    return DoubleBuffer.allocate(freshInt());
776  }
777}
778