/*
* Copyright (C) 2012 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.common.testing;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.CharMatcher;
import com.google.common.base.Charsets;
import com.google.common.base.Equivalence;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.base.Splitter;
import com.google.common.base.Throwables;
import com.google.common.base.Ticker;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableMultiset;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.ImmutableSortedMultiset;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.LinkedHashMultiset;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multiset;
import com.google.common.collect.Ordering;
import com.google.common.collect.Range;
import com.google.common.collect.RowSortedTable;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
import com.google.common.collect.SortedMultiset;
import com.google.common.collect.Table;
import com.google.common.collect.TreeBasedTable;
import com.google.common.collect.TreeMultiset;
import com.google.common.primitives.Primitives;
import com.google.common.primitives.UnsignedInteger;
import com.google.common.primitives.UnsignedLong;
import com.google.common.reflect.AbstractInvocationHandler;
import com.google.common.reflect.Invokable;
import com.google.common.reflect.Parameter;
import com.google.common.reflect.Reflection;
import com.google.common.reflect.TypeToken;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ShortBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Currency;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.NavigableMap;
import java.util.NavigableSet;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
/**
* Generates fresh instances of types that are different from each other (if possible).
*
* @author Ben Yu
*/
class FreshValueGenerator {
private static final ImmutableMap<Class<?>, Method> GENERATORS;
static {
ImmutableMap.Builder<Class<?>, Method> builder =
ImmutableMap.builder();
for (Method method : FreshValueGenerator.class.getDeclaredMethods()) {
if (method.isAnnotationPresent(Generates.class)) {
builder.put(method.getReturnType(), method);
}
}
GENERATORS = builder.build();
}
private static final ImmutableMap<Class<?>, Method> EMPTY_GENEREATORS;
static {
ImmutableMap.Builder<Class<?>, Method> builder =
ImmutableMap.builder();
for (Method method : FreshValueGenerator.class.getDeclaredMethods()) {
if (method.isAnnotationPresent(Empty.class)) {
builder.put(method.getReturnType(), method);
}
}
EMPTY_GENEREATORS = builder.build();
}
private final AtomicInteger freshness = new AtomicInteger(1);
private final ListMultimap<Class<?>, Object> sampleInstances = ArrayListMultimap.create();
/**
* The freshness level at which the {@link Empty @Empty} annotated method was invoked to generate
* instance.
*/
private final Map<Type, Integer> emptyInstanceGenerated = new HashMap<Type, Integer>();
final <T> void addSampleInstances(Class<T> type, Iterable<? extends T> instances) {
sampleInstances.putAll(checkNotNull(type), checkNotNull(instances));
}
/**
* Returns a fresh instance for {@code type} if possible. The returned instance could be:
* <ul>
* <li>exactly of the given type, including generic type parameters, such as
* {@code ImmutableList<String>};
* <li>of the raw type;
* <li>null if no value can be generated.
* </ul>
*/
@Nullable final Object generateFresh(TypeToken<?> type) {
Object generated = generate(type);
if (generated != null) {
freshness.incrementAndGet();
}
return generated;
}
@Nullable final <T> T generateFresh(Class<T> type) {
return Primitives.wrap(type).cast(generateFresh(TypeToken.of(type)));
}
final <T> T newFreshProxy(final Class<T> interfaceType) {
T proxy = newProxy(interfaceType);
freshness.incrementAndGet();
return proxy;
}
/**
* Generates an instance for {@code type} using the current {@link #freshness}.
* The generated instance may or may not be unique across different calls.
*/
private Object generate(TypeToken<?> type) {
Class<?> rawType = type.getRawType();
List<Object> samples = sampleInstances.get(rawType);
Object sample = pickInstance(samples, null);
if (sample != null) {
return sample;
}
if (rawType.isEnum()) {
return pickInstance(rawType.getEnumConstants(), null);
}
if (type.isArray()) {
TypeToken<?> componentType = type.getComponentType();
Object array = Array.newInstance(componentType.getRawType(), 1);
Array.set(array, 0, generate(componentType));
return array;
}
Method emptyGenerate = EMPTY_GENEREATORS.get(rawType);
if (emptyGenerate != null) {
if (emptyInstanceGenerated.containsKey(type.getType())) {
// empty instance already generated
if (emptyInstanceGenerated.get(type.getType()).intValue() == freshness.get()) {
// same freshness, generate again.
return invokeGeneratorMethod(emptyGenerate);
} else {
// Cannot use empty generator. Proceed with other generators.
}
} else {
// never generated empty instance for this type before.
Object emptyInstance = invokeGeneratorMethod(emptyGenerate);
emptyInstanceGenerated.put(type.getType(), freshness.get());
return emptyInstance;
}
}
Method generate = GENERATORS.get(rawType);
if (generate != null) {
ImmutableList<Parameter> params = Invokable.from(generate).getParameters();
List<Object> args = Lists.newArrayListWithCapacity(params.size());
TypeVariable<?>[] typeVars = rawType.getTypeParameters();
for (int i = 0; i < params.size(); i++) {
TypeToken<?> paramType = type.resolveType(typeVars[i]);
// We require all @Generates methods to either be parameter-less or accept non-null
// values for their generic parameter types.
Object argValue = generate(paramType);
if (argValue == null) {
// When a parameter of a @Generates method cannot be created,
// The type most likely is a collection.
// Our distinct proxy doesn't work for collections.
// So just refuse to generate.
return null;
}
args.add(argValue);
}
return invokeGeneratorMethod(generate, args.toArray());
}
return defaultGenerate(rawType);
}
private <T> T defaultGenerate(Class<T> rawType) {
if (rawType.isInterface()) {
// always create a new proxy
return newProxy(rawType);
}
return ArbitraryInstances.get(rawType);
}
private <T> T newProxy(final Class<T> interfaceType) {
return Reflection.newProxy(interfaceType, new FreshInvocationHandler(interfaceType));
}
private Object invokeGeneratorMethod(Method generator, Object... args) {
try {
return generator.invoke(this, args);
} catch (InvocationTargetException e) {
throw Throwables.propagate(e.getCause());
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
private final class FreshInvocationHandler extends AbstractInvocationHandler {
private final int identity = generateInt();
private final Class<?> interfaceType;
FreshInvocationHandler(Class<?> interfaceType) {
this.interfaceType = interfaceType;
}
@Override protected Object handleInvocation(Object proxy, Method method, Object[] args) {
return interfaceMethodCalled(interfaceType, method);
}
@Override public int hashCode() {
return identity;
}
@Override public boolean equals(@Nullable Object obj) {
if (obj instanceof FreshInvocationHandler) {
FreshInvocationHandler that = (FreshInvocationHandler) obj;
return identity == that.identity;
}
return false;
}
@Override public String toString() {
return paramString(interfaceType, identity);
}
}
/** Subclasses can override to provide different return value for proxied interface methods. */
Object interfaceMethodCalled(
@SuppressWarnings("unused") Class<?> interfaceType,
@SuppressWarnings("unused") Method method) {
throw new UnsupportedOperationException();
}
private <T> T pickInstance(T[] instances, T defaultValue) {
return pickInstance(Arrays.asList(instances), defaultValue);
}
private <T> T pickInstance(Collection<T> instances, T defaultValue) {
if (instances.isEmpty()) {
return defaultValue;
}
// generateInt() is 1-based.
return Iterables.get(instances, (generateInt() - 1) % instances.size());
}
private static String paramString(Class<?> type, int i) {
return type.getSimpleName() + '@' + i;
}
/**
* Annotates a method to be the instance generator of a certain type. The return type is the
* generated type. The method parameters correspond to the generated type's type parameters.
* For example, if the annotated method returns {@code Map<K, V>}, the method signature should be:
* {@code Map<K, V> generateMap(K key, V value)}.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
private @interface Generates {}
/**
* Annotates a method to generate the "empty" instance of a collection. This method should accept
* no parameter. The value it generates should be unequal to the values generated by methods
* annotated with {@link Generates}.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
private @interface Empty {}
@Generates private Class<?> generateClass() {
return pickInstance(
ImmutableList.of(
int.class, long.class, void.class,
Object.class, Object[].class, Iterable.class),
Object.class);
}
@Generates private Object generateObject() {
return generateString();
}
@Generates private Number generateNumber() {
return generateInt();
}
@Generates private int generateInt() {
return freshness.get();
}
@Generates private Integer generateInteger() {
return new Integer(generateInt());
}
@Generates private long generateLong() {
return generateInt();
}
@Generates private Long generateLongObject() {
return new Long(generateLong());
}
@Generates private float generateFloat() {
return generateInt();
}
@Generates private Float generateFloatObject() {
return new Float(generateFloat());
}
@Generates private double generateDouble() {
return generateInt();
}
@Generates private Double generateDoubleObject() {
return new Double(generateDouble());
}
@Generates private short generateShort() {
return (short) generateInt();
}
@Generates private Short generateShortObject() {
return new Short(generateShort());
}
@Generates private byte generateByte() {
return (byte) generateInt();
}
@Generates private Byte generateByteObject() {
return new Byte(generateByte());
}
@Generates private char generateChar() {
return generateString().charAt(0);
}
@Generates private Character generateCharacter() {
return new Character(generateChar());
}
@Generates private boolean generateBoolean() {
return generateInt() % 2 == 0;
}
@Generates private Boolean generateBooleanObject() {
return new Boolean(generateBoolean());
}
@Generates private UnsignedInteger generateUnsignedInteger() {
return UnsignedInteger.fromIntBits(generateInt());
}
@Generates private UnsignedLong generateUnsignedLong() {
return UnsignedLong.fromLongBits(generateLong());
}
@Generates private BigInteger generateBigInteger() {
return BigInteger.valueOf(generateInt());
}
@Generates private BigDecimal generateBigDecimal() {
return BigDecimal.valueOf(generateInt());
}
@Generates private CharSequence generateCharSequence() {
return generateString();
}
@Generates private String generateString() {
return Integer.toString(generateInt());
}
@Generates private Comparable<?> generateComparable() {
return generateString();
}
@Generates private Pattern generatePattern() {
return Pattern.compile(generateString());
}
@Generates private Charset generateCharset() {
return pickInstance(Charset.availableCharsets().values(), Charsets.UTF_8);
}
@Generates private Locale generateLocale() {
return pickInstance(Locale.getAvailableLocales(), Locale.US);
}
@Generates private Currency generateCurrency() {
try {
Method method = Currency.class.getMethod("getAvailableCurrencies");
@SuppressWarnings("unchecked") // getAvailableCurrencies() returns Set<Currency>.
Set<Currency> currencies = (Set<Currency>) method.invoke(null);
return pickInstance(currencies, Currency.getInstance(Locale.US));
} catch (NoSuchMethodException notJava7) {
return preJava7FreshCurrency();
} catch (InvocationTargetException cantCallGetAvailableCurrencies) {
return preJava7FreshCurrency();
} catch (IllegalAccessException impossible) {
throw new AssertionError(impossible);
}
}
private Currency preJava7FreshCurrency() {
for (Set<Locale> uselessLocales = Sets.newHashSet(); ; ) {
Locale locale = generateLocale();
if (uselessLocales.contains(locale)) { // exhausted all locales
return Currency.getInstance(Locale.US);
}
try {
return Currency.getInstance(locale);
} catch (IllegalArgumentException e) {
uselessLocales.add(locale);
}
}
}
// common.base
@Empty private <T> Optional<T> generateOptional() {
return Optional.absent();
}
@Generates private <T> Optional<T> generateOptional(T value) {
return Optional.of(value);
}
@Generates private Joiner generateJoiner() {
return Joiner.on(generateString());
}
@Generates private Splitter generateSplitter() {
return Splitter.on(generateString());
}
@Generates private <T> Equivalence<T> generateEquivalence() {
return new Equivalence<T>() {
@Override protected boolean doEquivalent(T a, T b) {
return false;
}
@Override protected int doHash(T t) {
return 0;
}
final String string = paramString(Equivalence.class, generateInt());
@Override public String toString() {
return string;
}
};
}
@Generates private CharMatcher generateCharMatcher() {
return new CharMatcher() {
@Override public boolean matches(char c) {
return false;
}
final String string = paramString(CharMatcher.class, generateInt());
@Override public String toString() {
return string;
}
};
}
@Generates private Ticker generateTicker() {
return new Ticker() {
@Override public long read() {
return 0;
}
final String string = paramString(Ticker.class, generateInt());
@Override public String toString() {
return string;
}
};
}
// collect
@Generates private <T> Comparator<T> generateComparator() {
return generateOrdering();
}
@Generates private <T> Ordering<T> generateOrdering() {
return new Ordering<T>() {
@Override public int compare(T left, T right) {
return 0;
}
final String string = paramString(Ordering.class, generateInt());
@Override public String toString() {
return string;
}
};
}
@Empty private static <C extends Comparable<?>> Range<C> generateRange() {
return Range.all();
}
@Generates private static <C extends Comparable<?>> Range<C> generateRange(C freshElement) {
return Range.singleton(freshElement);
}
@Generates private static <E> Iterable<E> generateIterable(E freshElement) {
return generateList(freshElement);
}
@Generates private static <E> Collection<E> generateCollection(E freshElement) {
return generateList(freshElement);
}
@Generates private static <E> List<E> generateList(E freshElement) {
return generateArrayList(freshElement);
}
@Generates private static <E> ArrayList<E> generateArrayList(E freshElement) {
ArrayList<E> list = Lists.newArrayList();
list.add(freshElement);
return list;
}
@Generates private static <E> LinkedList<E> generateLinkedList(E freshElement) {
LinkedList<E> list = Lists.newLinkedList();
list.add(freshElement);
return list;
}
@Generates private static <E> ImmutableList<E> generateImmutableList(E freshElement) {
return ImmutableList.of(freshElement);
}
@Generates private static <E> ImmutableCollection<E> generateImmutableCollection(E freshElement) {
return generateImmutableList(freshElement);
}
@Generates private static <E> Set<E> generateSet(E freshElement) {
return generateHashSet(freshElement);
}
@Generates private static <E> HashSet<E> generateHashSet(E freshElement) {
return generateLinkedHashSet(freshElement);
}
@Generates private static <E> LinkedHashSet<E> generateLinkedHashSet(E freshElement) {
LinkedHashSet<E> set = Sets.newLinkedHashSet();
set.add(freshElement);
return set;
}
@Generates private static <E> ImmutableSet<E> generateImmutableSet(E freshElement) {
return ImmutableSet.of(freshElement);
}
@Generates private static <E extends Comparable<? super E>> SortedSet<E>
generateSortedSet(E freshElement) {
return generateNavigableSet(freshElement);
}
@Generates private static <E extends Comparable<? super E>> NavigableSet<E>
generateNavigableSet(E freshElement) {
return generateTreeSet(freshElement);
}
@Generates private static <E extends Comparable<? super E>> TreeSet<E> generateTreeSet(
E freshElement) {
TreeSet<E> set = Sets.newTreeSet();
set.add(freshElement);
return set;
}
@Generates private static <E extends Comparable<? super E>> ImmutableSortedSet<E>
generateImmutableSortedSet(E freshElement) {
return ImmutableSortedSet.of(freshElement);
}
@Generates private static <E> Multiset<E> generateMultiset(E freshElement) {
return generateHashMultiset(freshElement);
}
@Generates private static <E> HashMultiset<E> generateHashMultiset(E freshElement) {
HashMultiset<E> multiset = HashMultiset.create();
multiset.add(freshElement);
return multiset;
}
@Generates private static <E> LinkedHashMultiset<E> generateLinkedHashMultiset(E freshElement) {
LinkedHashMultiset<E> multiset = LinkedHashMultiset.create();
multiset.add(freshElement);
return multiset;
}
@Generates private static <E> ImmutableMultiset<E> generateImmutableMultiset(E freshElement) {
return ImmutableMultiset.of(freshElement);
}
@Generates private static <E extends Comparable<E>> SortedMultiset<E> generateSortedMultiset(
E freshElement) {
return generateTreeMultiset(freshElement);
}
@Generates private static <E extends Comparable<E>> TreeMultiset<E> generateTreeMultiset(
E freshElement) {
TreeMultiset<E> multiset = TreeMultiset.create();
multiset.add(freshElement);
return multiset;
}
@Generates private static <E extends Comparable<E>> ImmutableSortedMultiset<E>
generateImmutableSortedMultiset(E freshElement) {
return ImmutableSortedMultiset.of(freshElement);
}
@Generates private static <K, V> Map<K, V> generateMap(K key, V value) {
return generateHashdMap(key, value);
}
@Generates private static <K, V> HashMap<K, V> generateHashdMap(K key, V value) {
return generateLinkedHashMap(key, value);
}
@Generates private static <K, V> LinkedHashMap<K, V> generateLinkedHashMap(K key, V value) {
LinkedHashMap<K, V> map = Maps.newLinkedHashMap();
map.put(key, value);
return map;
}
@Generates private static <K, V> ImmutableMap<K, V> generateImmutableMap(K key, V value) {
return ImmutableMap.of(key, value);
}
@Empty private static <K, V> ConcurrentMap<K, V> generateConcurrentMap() {
return Maps.newConcurrentMap();
}
@Generates private static <K, V> ConcurrentMap<K, V> generateConcurrentMap(K key, V value) {
ConcurrentMap<K, V> map = Maps.newConcurrentMap();
map.put(key, value);
return map;
}
@Generates private static <K extends Comparable<? super K>, V> SortedMap<K, V>
generateSortedMap(K key, V value) {
return generateNavigableMap(key, value);
}
@Generates private static <K extends Comparable<? super K>, V> NavigableMap<K, V>
generateNavigableMap(K key, V value) {
return generateTreeMap(key, value);
}
@Generates private static <K extends Comparable<? super K>, V> TreeMap<K, V> generateTreeMap(
K key, V value) {
TreeMap<K, V> map = Maps.newTreeMap();
map.put(key, value);
return map;
}
@Generates private static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V>
generateImmutableSortedMap(K key, V value) {
return ImmutableSortedMap.of(key, value);
}
@Generates private static <K, V> Multimap<K, V> generateMultimap(K key, V value) {
return generateListMultimap(key, value);
}
@Generates private static <K, V> ImmutableMultimap<K, V> generateImmutableMultimap(
K key, V value) {
return ImmutableMultimap.of(key, value);
}
@Generates private static <K, V> ListMultimap<K, V> generateListMultimap(K key, V value) {
return generateArrayListMultimap(key, value);
}
@Generates private static <K, V> ArrayListMultimap<K, V> generateArrayListMultimap(
K key, V value) {
ArrayListMultimap<K, V> multimap = ArrayListMultimap.create();
multimap.put(key, value);
return multimap;
}
@Generates private static <K, V> ImmutableListMultimap<K, V> generateImmutableListMultimap(
K key, V value) {
return ImmutableListMultimap.of(key, value);
}
@Generates private static <K, V> SetMultimap<K, V> generateSetMultimap(K key, V value) {
return generateLinkedHashMultimap(key, value);
}
@Generates private static <K, V> HashMultimap<K, V> generateHashMultimap(K key, V value) {
HashMultimap<K, V> multimap = HashMultimap.create();
multimap.put(key, value);
return multimap;
}
@Generates private static <K, V> LinkedHashMultimap<K, V> generateLinkedHashMultimap(
K key, V value) {
LinkedHashMultimap<K, V> multimap = LinkedHashMultimap.create();
multimap.put(key, value);
return multimap;
}
@Generates private static <K, V> ImmutableSetMultimap<K, V> generateImmutableSetMultimap(
K key, V value) {
return ImmutableSetMultimap.of(key, value);
}
@Generates private static <K, V> BiMap<K, V> generateBimap(K key, V value) {
return generateHashBiMap(key, value);
}
@Generates private static <K, V> HashBiMap<K, V> generateHashBiMap(K key, V value) {
HashBiMap<K, V> bimap = HashBiMap.create();
bimap.put(key, value);
return bimap;
}
@Generates private static <K, V> ImmutableBiMap<K, V> generateImmutableBimap(
K key, V value) {
return ImmutableBiMap.of(key, value);
}
@Generates private static <R, C, V> Table<R, C, V> generateTable(R row, C column, V value) {
return generateHashBasedTable(row, column, value);
}
@Generates private static <R, C, V> HashBasedTable<R, C, V> generateHashBasedTable(
R row, C column, V value) {
HashBasedTable<R, C, V> table = HashBasedTable.create();
table.put(row, column, value);
return table;
}
@SuppressWarnings("rawtypes") // TreeBasedTable.create() is defined as such
@Generates private static <R extends Comparable, C extends Comparable, V> RowSortedTable<R, C, V>
generateRowSortedTable(R row, C column, V value) {
return generateTreeBasedTable(row, column, value);
}
@SuppressWarnings("rawtypes") // TreeBasedTable.create() is defined as such
@Generates private static <R extends Comparable, C extends Comparable, V> TreeBasedTable<R, C, V>
generateTreeBasedTable(R row, C column, V value) {
TreeBasedTable<R, C, V> table = TreeBasedTable.create();
table.put(row, column, value);
return table;
}
@Generates private static <R, C, V> ImmutableTable<R, C, V> generateImmutableTable(
R row, C column, V value) {
return ImmutableTable.of(row, column, value);
}
// common.reflect
@Generates private TypeToken<?> generateTypeToken() {
return TypeToken.of(generateClass());
}
// io types
@Generates private File generateFile() {
return new File(generateString());
}
@Generates private static ByteArrayInputStream generateByteArrayInputStream() {
return new ByteArrayInputStream(new byte[0]);
}
@Generates private static InputStream generateInputStream() {
return generateByteArrayInputStream();
}
@Generates private StringReader generateStringReader() {
return new StringReader(generateString());
}
@Generates private Reader generateReader() {
return generateStringReader();
}
@Generates private Readable generateReadable() {
return generateReader();
}
@Generates private Buffer generateBuffer() {
return generateCharBuffer();
}
@Generates private CharBuffer generateCharBuffer() {
return CharBuffer.allocate(generateInt());
}
@Generates private ByteBuffer generateByteBuffer() {
return ByteBuffer.allocate(generateInt());
}
@Generates private ShortBuffer generateShortBuffer() {
return ShortBuffer.allocate(generateInt());
}
@Generates private IntBuffer generateIntBuffer() {
return IntBuffer.allocate(generateInt());
}
@Generates private LongBuffer generateLongBuffer() {
return LongBuffer.allocate(generateInt());
}
@Generates private FloatBuffer generateFloatBuffer() {
return FloatBuffer.allocate(generateInt());
}
@Generates private DoubleBuffer generateDoubleBuffer() {
return DoubleBuffer.allocate(generateInt());
}
}