Coverage Summary for Class: ArbitraryInstances (com.google.common.testing)

Class Method, % Line, %
ArbitraryInstances 87.5% (7/8) 96% (166/173)
ArbitraryInstances$1 100% (2/2) 100% (2/2)
ArbitraryInstances$AlwaysEqual 60% (3/5) 60% (3/5)
ArbitraryInstances$ByToString 80% (4/5) 80% (4/5)
ArbitraryInstances$Dummies 0% (0/1) 0% (0/1)
ArbitraryInstances$Dummies$DeterministicRandom 100% (1/1) 100% (2/2)
ArbitraryInstances$Dummies$DummyCountDownLatch 0% (0/1) 0% (0/2)
ArbitraryInstances$Dummies$DummyExecutor 100% (2/2) 100% (2/2)
ArbitraryInstances$Dummies$DummyRunnable 100% (2/2) 100% (2/2)
ArbitraryInstances$Dummies$DummyScheduledThreadPoolExecutor 0% (0/1) 0% (0/2)
ArbitraryInstances$Dummies$DummyThreadFactory 50% (1/2) 50% (1/2)
ArbitraryInstances$Dummies$InMemoryPrintStream 100% (1/1) 100% (2/2)
ArbitraryInstances$Dummies$InMemoryPrintWriter 100% (1/1) 100% (2/2)
ArbitraryInstances$NullByteSink 66.7% (2/3) 66.7% (2/3)
Total 74.3% (26/35) 91.7% (188/205)


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  17 package com.google.common.testing; 18  19 import static com.google.common.base.Preconditions.checkArgument; 20  21 import com.google.common.annotations.Beta; 22 import com.google.common.annotations.GwtIncompatible; 23 import com.google.common.base.CharMatcher; 24 import com.google.common.base.Charsets; 25 import com.google.common.base.Defaults; 26 import com.google.common.base.Equivalence; 27 import com.google.common.base.Joiner; 28 import com.google.common.base.Predicate; 29 import com.google.common.base.Predicates; 30 import com.google.common.base.Splitter; 31 import com.google.common.base.Stopwatch; 32 import com.google.common.base.Ticker; 33 import com.google.common.collect.BiMap; 34 import com.google.common.collect.ClassToInstanceMap; 35 import com.google.common.collect.ImmutableBiMap; 36 import com.google.common.collect.ImmutableClassToInstanceMap; 37 import com.google.common.collect.ImmutableCollection; 38 import com.google.common.collect.ImmutableList; 39 import com.google.common.collect.ImmutableListMultimap; 40 import com.google.common.collect.ImmutableMap; 41 import com.google.common.collect.ImmutableMultimap; 42 import com.google.common.collect.ImmutableMultiset; 43 import com.google.common.collect.ImmutableSet; 44 import com.google.common.collect.ImmutableSetMultimap; 45 import com.google.common.collect.ImmutableSortedMap; 46 import com.google.common.collect.ImmutableSortedMultiset; 47 import com.google.common.collect.ImmutableSortedSet; 48 import com.google.common.collect.ImmutableTable; 49 import com.google.common.collect.Iterators; 50 import com.google.common.collect.ListMultimap; 51 import com.google.common.collect.MapDifference; 52 import com.google.common.collect.Maps; 53 import com.google.common.collect.Multimap; 54 import com.google.common.collect.Multimaps; 55 import com.google.common.collect.Multiset; 56 import com.google.common.collect.Ordering; 57 import com.google.common.collect.PeekingIterator; 58 import com.google.common.collect.Range; 59 import com.google.common.collect.RowSortedTable; 60 import com.google.common.collect.SetMultimap; 61 import com.google.common.collect.Sets; 62 import com.google.common.collect.SortedMapDifference; 63 import com.google.common.collect.SortedMultiset; 64 import com.google.common.collect.SortedSetMultimap; 65 import com.google.common.collect.Table; 66 import com.google.common.collect.Tables; 67 import com.google.common.collect.TreeBasedTable; 68 import com.google.common.collect.TreeMultimap; 69 import com.google.common.io.ByteSink; 70 import com.google.common.io.ByteSource; 71 import com.google.common.io.ByteStreams; 72 import com.google.common.io.CharSink; 73 import com.google.common.io.CharSource; 74 import com.google.common.primitives.Primitives; 75 import com.google.common.primitives.UnsignedInteger; 76 import com.google.common.primitives.UnsignedLong; 77 import java.io.ByteArrayInputStream; 78 import java.io.ByteArrayOutputStream; 79 import java.io.File; 80 import java.io.InputStream; 81 import java.io.OutputStream; 82 import java.io.PrintStream; 83 import java.io.PrintWriter; 84 import java.io.Reader; 85 import java.io.Serializable; 86 import java.io.StringReader; 87 import java.io.StringWriter; 88 import java.io.Writer; 89 import java.lang.reflect.AnnotatedElement; 90 import java.lang.reflect.Array; 91 import java.lang.reflect.Constructor; 92 import java.lang.reflect.Field; 93 import java.lang.reflect.GenericDeclaration; 94 import java.lang.reflect.InvocationTargetException; 95 import java.lang.reflect.Modifier; 96 import java.lang.reflect.Type; 97 import java.math.BigDecimal; 98 import java.math.BigInteger; 99 import java.nio.Buffer; 100 import java.nio.ByteBuffer; 101 import java.nio.CharBuffer; 102 import java.nio.DoubleBuffer; 103 import java.nio.FloatBuffer; 104 import java.nio.IntBuffer; 105 import java.nio.LongBuffer; 106 import java.nio.ShortBuffer; 107 import java.nio.charset.Charset; 108 import java.util.ArrayDeque; 109 import java.util.Arrays; 110 import java.util.Collection; 111 import java.util.Comparator; 112 import java.util.Currency; 113 import java.util.Deque; 114 import java.util.Iterator; 115 import java.util.List; 116 import java.util.ListIterator; 117 import java.util.Locale; 118 import java.util.Map; 119 import java.util.NavigableMap; 120 import java.util.NavigableSet; 121 import java.util.Optional; 122 import java.util.OptionalDouble; 123 import java.util.OptionalInt; 124 import java.util.OptionalLong; 125 import java.util.Queue; 126 import java.util.Random; 127 import java.util.Set; 128 import java.util.SortedMap; 129 import java.util.SortedSet; 130 import java.util.UUID; 131 import java.util.concurrent.BlockingDeque; 132 import java.util.concurrent.BlockingQueue; 133 import java.util.concurrent.ConcurrentHashMap; 134 import java.util.concurrent.ConcurrentMap; 135 import java.util.concurrent.ConcurrentNavigableMap; 136 import java.util.concurrent.ConcurrentSkipListMap; 137 import java.util.concurrent.CountDownLatch; 138 import java.util.concurrent.Executor; 139 import java.util.concurrent.LinkedBlockingDeque; 140 import java.util.concurrent.ScheduledThreadPoolExecutor; 141 import java.util.concurrent.ThreadFactory; 142 import java.util.concurrent.ThreadPoolExecutor; 143 import java.util.concurrent.TimeUnit; 144 import java.util.logging.Level; 145 import java.util.logging.Logger; 146 import java.util.regex.MatchResult; 147 import java.util.regex.Matcher; 148 import java.util.regex.Pattern; 149 import java.util.stream.Stream; 150 import org.checkerframework.checker.nullness.qual.Nullable; 151  152 /** 153  * Supplies an arbitrary "default" instance for a wide range of types, often useful in testing 154  * utilities. 155  * 156  * <p>Covers arrays, enums and common types defined in {@code java.lang}, {@code java.lang.reflect}, 157  * {@code java.io}, {@code java.nio}, {@code java.math}, {@code java.util}, {@code 158  * java.util.concurrent}, {@code java.util.regex}, {@code com.google.common.base}, {@code 159  * com.google.common.collect} and {@code com.google.common.primitives}. In addition, if the type 160  * exposes at least one public static final constant of the same type, one of the constants will be 161  * used; or if the class exposes a public parameter-less constructor then it will be "new"d and 162  * returned. 163  * 164  * <p>All default instances returned by {@link #get} are generics-safe. Clients won't get type 165  * errors for using {@code get(Comparator.class)} as a {@code Comparator<Foo>}, for example. 166  * Immutable empty instances are returned for collection types; {@code ""} for string; {@code 0} for 167  * number types; reasonable default instance for other stateless types. For mutable types, a fresh 168  * instance is created each time {@code get()} is called. 169  * 170  * @author Kevin Bourrillion 171  * @author Ben Yu 172  * @since 12.0 173  */ 174 @Beta 175 @GwtIncompatible 176 public final class ArbitraryInstances { 177  178  private static final Ordering<Field> BY_FIELD_NAME = 179  new Ordering<Field>() { 180  @Override 181  public int compare(Field left, Field right) { 182  return left.getName().compareTo(right.getName()); 183  } 184  }; 185  186  /** 187  * Returns a new {@code MatchResult} that corresponds to a successful match. Apache Harmony (used 188  * in Android) requires a successful match in order to generate a {@code MatchResult}: 189  * http://goo.gl/5VQFmC 190  */ 191  private static MatchResult newMatchResult() { 192  Matcher matcher = Pattern.compile(".").matcher("X"); 193  matcher.find(); 194  return matcher.toMatchResult(); 195  } 196  197  private static final ClassToInstanceMap<Object> DEFAULTS = 198  ImmutableClassToInstanceMap.builder() 199  // primitives 200  .put(Object.class, "") 201  .put(Number.class, 0) 202  .put(UnsignedInteger.class, UnsignedInteger.ZERO) 203  .put(UnsignedLong.class, UnsignedLong.ZERO) 204  .put(BigInteger.class, BigInteger.ZERO) 205  .put(BigDecimal.class, BigDecimal.ZERO) 206  .put(CharSequence.class, "") 207  .put(String.class, "") 208  .put(Pattern.class, Pattern.compile("")) 209  .put(MatchResult.class, newMatchResult()) 210  .put(TimeUnit.class, TimeUnit.SECONDS) 211  .put(Charset.class, Charsets.UTF_8) 212  .put(Currency.class, Currency.getInstance(Locale.US)) 213  .put(Locale.class, Locale.US) 214  .put(Optional.class, Optional.empty()) 215  .put(OptionalInt.class, OptionalInt.empty()) 216  .put(OptionalLong.class, OptionalLong.empty()) 217  .put(OptionalDouble.class, OptionalDouble.empty()) 218  .put(UUID.class, UUID.randomUUID()) 219  // common.base 220  .put(CharMatcher.class, CharMatcher.none()) 221  .put(Joiner.class, Joiner.on(',')) 222  .put(Splitter.class, Splitter.on(',')) 223  .put(com.google.common.base.Optional.class, com.google.common.base.Optional.absent()) 224  .put(Predicate.class, Predicates.alwaysTrue()) 225  .put(Equivalence.class, Equivalence.equals()) 226  .put(Ticker.class, Ticker.systemTicker()) 227  .put(Stopwatch.class, Stopwatch.createUnstarted()) 228  // io types 229  .put(InputStream.class, new ByteArrayInputStream(new byte[0])) 230  .put(ByteArrayInputStream.class, new ByteArrayInputStream(new byte[0])) 231  .put(Readable.class, new StringReader("")) 232  .put(Reader.class, new StringReader("")) 233  .put(StringReader.class, new StringReader("")) 234  .put(Buffer.class, ByteBuffer.allocate(0)) 235  .put(CharBuffer.class, CharBuffer.allocate(0)) 236  .put(ByteBuffer.class, ByteBuffer.allocate(0)) 237  .put(ShortBuffer.class, ShortBuffer.allocate(0)) 238  .put(IntBuffer.class, IntBuffer.allocate(0)) 239  .put(LongBuffer.class, LongBuffer.allocate(0)) 240  .put(FloatBuffer.class, FloatBuffer.allocate(0)) 241  .put(DoubleBuffer.class, DoubleBuffer.allocate(0)) 242  .put(File.class, new File("")) 243  .put(ByteSource.class, ByteSource.empty()) 244  .put(CharSource.class, CharSource.empty()) 245  .put(ByteSink.class, NullByteSink.INSTANCE) 246  .put(CharSink.class, NullByteSink.INSTANCE.asCharSink(Charsets.UTF_8)) 247  // All collections are immutable empty. So safe for any type parameter. 248  .put(Iterator.class, ImmutableSet.of().iterator()) 249  .put(PeekingIterator.class, Iterators.peekingIterator(ImmutableSet.of().iterator())) 250  .put(ListIterator.class, ImmutableList.of().listIterator()) 251  .put(Iterable.class, ImmutableSet.of()) 252  .put(Collection.class, ImmutableList.of()) 253  .put(ImmutableCollection.class, ImmutableList.of()) 254  .put(List.class, ImmutableList.of()) 255  .put(ImmutableList.class, ImmutableList.of()) 256  .put(Set.class, ImmutableSet.of()) 257  .put(ImmutableSet.class, ImmutableSet.of()) 258  .put(SortedSet.class, ImmutableSortedSet.of()) 259  .put(ImmutableSortedSet.class, ImmutableSortedSet.of()) 260  .put(NavigableSet.class, Sets.unmodifiableNavigableSet(Sets.newTreeSet())) 261  .put(Map.class, ImmutableMap.of()) 262  .put(ImmutableMap.class, ImmutableMap.of()) 263  .put(SortedMap.class, ImmutableSortedMap.of()) 264  .put(ImmutableSortedMap.class, ImmutableSortedMap.of()) 265  .put(NavigableMap.class, Maps.unmodifiableNavigableMap(Maps.newTreeMap())) 266  .put(Multimap.class, ImmutableMultimap.of()) 267  .put(ImmutableMultimap.class, ImmutableMultimap.of()) 268  .put(ListMultimap.class, ImmutableListMultimap.of()) 269  .put(ImmutableListMultimap.class, ImmutableListMultimap.of()) 270  .put(SetMultimap.class, ImmutableSetMultimap.of()) 271  .put(ImmutableSetMultimap.class, ImmutableSetMultimap.of()) 272  .put( 273  SortedSetMultimap.class, 274  Multimaps.unmodifiableSortedSetMultimap(TreeMultimap.create())) 275  .put(Multiset.class, ImmutableMultiset.of()) 276  .put(ImmutableMultiset.class, ImmutableMultiset.of()) 277  .put(SortedMultiset.class, ImmutableSortedMultiset.of()) 278  .put(ImmutableSortedMultiset.class, ImmutableSortedMultiset.of()) 279  .put(BiMap.class, ImmutableBiMap.of()) 280  .put(ImmutableBiMap.class, ImmutableBiMap.of()) 281  .put(Table.class, ImmutableTable.of()) 282  .put(ImmutableTable.class, ImmutableTable.of()) 283  .put(RowSortedTable.class, Tables.unmodifiableRowSortedTable(TreeBasedTable.create())) 284  .put(ClassToInstanceMap.class, ImmutableClassToInstanceMap.builder().build()) 285  .put(ImmutableClassToInstanceMap.class, ImmutableClassToInstanceMap.builder().build()) 286  .put(Comparable.class, ByToString.INSTANCE) 287  .put(Comparator.class, AlwaysEqual.INSTANCE) 288  .put(Ordering.class, AlwaysEqual.INSTANCE) 289  .put(Range.class, Range.all()) 290  .put(MapDifference.class, Maps.difference(ImmutableMap.of(), ImmutableMap.of())) 291  .put( 292  SortedMapDifference.class, 293  Maps.difference(ImmutableSortedMap.of(), ImmutableSortedMap.of())) 294  // reflect 295  .put(AnnotatedElement.class, Object.class) 296  .put(GenericDeclaration.class, Object.class) 297  .put(Type.class, Object.class) 298  .build(); 299  300  /** 301  * type ? implementation. Inherently mutable interfaces and abstract classes are mapped to their 302  * default implementations and are "new"d upon get(). 303  */ 304  private static final ConcurrentMap<Class<?>, Class<?>> implementations = Maps.newConcurrentMap(); 305  306  private static <T> void setImplementation(Class<T> type, Class<? extends T> implementation) { 307  checkArgument(type != implementation, "Don't register %s to itself!", type); 308  checkArgument( 309  !DEFAULTS.containsKey(type), "A default value was already registered for %s", type); 310  checkArgument( 311  implementations.put(type, implementation) == null, 312  "Implementation for %s was already registered", 313  type); 314  } 315  316  static { 317  setImplementation(Appendable.class, StringBuilder.class); 318  setImplementation(BlockingQueue.class, LinkedBlockingDeque.class); 319  setImplementation(BlockingDeque.class, LinkedBlockingDeque.class); 320  setImplementation(ConcurrentMap.class, ConcurrentHashMap.class); 321  setImplementation(ConcurrentNavigableMap.class, ConcurrentSkipListMap.class); 322  setImplementation(CountDownLatch.class, Dummies.DummyCountDownLatch.class); 323  setImplementation(Deque.class, ArrayDeque.class); 324  setImplementation(OutputStream.class, ByteArrayOutputStream.class); 325  setImplementation(PrintStream.class, Dummies.InMemoryPrintStream.class); 326  setImplementation(PrintWriter.class, Dummies.InMemoryPrintWriter.class); 327  setImplementation(Queue.class, ArrayDeque.class); 328  setImplementation(Random.class, Dummies.DeterministicRandom.class); 329  setImplementation( 330  ScheduledThreadPoolExecutor.class, Dummies.DummyScheduledThreadPoolExecutor.class); 331  setImplementation(ThreadPoolExecutor.class, Dummies.DummyScheduledThreadPoolExecutor.class); 332  setImplementation(Writer.class, StringWriter.class); 333  setImplementation(Runnable.class, Dummies.DummyRunnable.class); 334  setImplementation(ThreadFactory.class, Dummies.DummyThreadFactory.class); 335  setImplementation(Executor.class, Dummies.DummyExecutor.class); 336  } 337  338  @SuppressWarnings("unchecked") // it's a subtype map 339  private static <T> @Nullable Class<? extends T> getImplementation(Class<T> type) { 340  return (Class<? extends T>) implementations.get(type); 341  } 342  343  private static final Logger logger = Logger.getLogger(ArbitraryInstances.class.getName()); 344  345  /** 346  * Returns an arbitrary instance for {@code type}, or {@code null} if no arbitrary instance can be 347  * determined. 348  */ 349  public static <T> @Nullable T get(Class<T> type) { 350  T defaultValue = DEFAULTS.getInstance(type); 351  if (defaultValue != null) { 352  return defaultValue; 353  } 354  Class<? extends T> implementation = getImplementation(type); 355  if (implementation != null) { 356  return get(implementation); 357  } 358  if (type == Stream.class) { 359  return type.cast(Stream.empty()); 360  } 361  if (type.isEnum()) { 362  T[] enumConstants = type.getEnumConstants(); 363  return (enumConstants.length == 0) ? null : enumConstants[0]; 364  } 365  if (type.isArray()) { 366  return createEmptyArray(type); 367  } 368  T jvmDefault = Defaults.defaultValue(Primitives.unwrap(type)); 369  if (jvmDefault != null) { 370  return jvmDefault; 371  } 372  if (Modifier.isAbstract(type.getModifiers()) || !Modifier.isPublic(type.getModifiers())) { 373  return arbitraryConstantInstanceOrNull(type); 374  } 375  final Constructor<T> constructor; 376  try { 377  constructor = type.getConstructor(); 378  } catch (NoSuchMethodException e) { 379  return arbitraryConstantInstanceOrNull(type); 380  } 381  constructor.setAccessible(true); // accessibility check is too slow 382  try { 383  return constructor.newInstance(); 384  /* 385  * Do not merge the 2 catch blocks below. javac would infer a type of 386  * ReflectiveOperationException, which Animal Sniffer would reject. (Old versions of 387  * Android don't *seem* to mind, but there might be edge cases of which we're unaware.) 388  */ 389  } catch (InstantiationException impossible) { 390  throw new AssertionError(impossible); 391  } catch (IllegalAccessException impossible) { 392  throw new AssertionError(impossible); 393  } catch (InvocationTargetException e) { 394  logger.log(Level.WARNING, "Exception while invoking default constructor.", e.getCause()); 395  return arbitraryConstantInstanceOrNull(type); 396  } 397  } 398  399  private static <T> @Nullable T arbitraryConstantInstanceOrNull(Class<T> type) { 400  Field[] fields = type.getDeclaredFields(); 401  Arrays.sort(fields, BY_FIELD_NAME); 402  for (Field field : fields) { 403  if (Modifier.isPublic(field.getModifiers()) 404  && Modifier.isStatic(field.getModifiers()) 405  && Modifier.isFinal(field.getModifiers())) { 406  if (field.getGenericType() == field.getType() && type.isAssignableFrom(field.getType())) { 407  field.setAccessible(true); 408  try { 409  T constant = type.cast(field.get(null)); 410  if (constant != null) { 411  return constant; 412  } 413  } catch (IllegalAccessException impossible) { 414  throw new AssertionError(impossible); 415  } 416  } 417  } 418  } 419  return null; 420  } 421  422  private static <T> T createEmptyArray(Class<T> arrayType) { 423  return arrayType.cast(Array.newInstance(arrayType.getComponentType(), 0)); 424  } 425  426  // Internal implementations of some classes, with public default constructor that get() needs. 427  private static final class Dummies { 428  429  public static final class InMemoryPrintStream extends PrintStream { 430  public InMemoryPrintStream() { 431  super(new ByteArrayOutputStream()); 432  } 433  } 434  435  public static final class InMemoryPrintWriter extends PrintWriter { 436  public InMemoryPrintWriter() { 437  super(new StringWriter()); 438  } 439  } 440  441  public static final class DeterministicRandom extends Random { 442  public DeterministicRandom() { 443  super(0); 444  } 445  } 446  447  public static final class DummyScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor { 448  public DummyScheduledThreadPoolExecutor() { 449  super(1); 450  } 451  } 452  453  public static final class DummyCountDownLatch extends CountDownLatch { 454  public DummyCountDownLatch() { 455  super(0); 456  } 457  } 458  459  public static final class DummyRunnable implements Runnable, Serializable { 460  @Override 461  public void run() {} 462  } 463  464  public static final class DummyThreadFactory implements ThreadFactory, Serializable { 465  @Override 466  public Thread newThread(Runnable r) { 467  return new Thread(r); 468  } 469  } 470  471  public static final class DummyExecutor implements Executor, Serializable { 472  @Override 473  public void execute(Runnable command) {} 474  } 475  } 476  477  private static final class NullByteSink extends ByteSink implements Serializable { 478  private static final NullByteSink INSTANCE = new NullByteSink(); 479  480  @Override 481  public OutputStream openStream() { 482  return ByteStreams.nullOutputStream(); 483  } 484  } 485  486  // Compare by toString() to satisfy 2 properties: 487  // 1. compareTo(null) should throw NullPointerException 488  // 2. the order is deterministic and easy to understand, for debugging purpose. 489  @SuppressWarnings("ComparableType") 490  private static final class ByToString implements Comparable<Object>, Serializable { 491  private static final ByToString INSTANCE = new ByToString(); 492  493  @Override 494  public int compareTo(Object o) { 495  return toString().compareTo(o.toString()); 496  } 497  498  @Override 499  public String toString() { 500  return "BY_TO_STRING"; 501  } 502  503  private Object readResolve() { 504  return INSTANCE; 505  } 506  } 507  508  // Always equal is a valid total ordering. And it works for any Object. 509  private static final class AlwaysEqual extends Ordering<Object> implements Serializable { 510  private static final AlwaysEqual INSTANCE = new AlwaysEqual(); 511  512  @Override 513  public int compare(Object o1, Object o2) { 514  return 0; 515  } 516  517  @Override 518  public String toString() { 519  return "ALWAYS_EQUAL"; 520  } 521  522  private Object readResolve() { 523  return INSTANCE; 524  } 525  } 526  527  private ArbitraryInstances() {} 528 }