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