### Question:
Types { public static ParameterizedType newParameterizedTypeWithOwner( Type ownerType, Type rawType, Type... typeArguments) { if (typeArguments.length == 0) { throw new IllegalArgumentException("Missing type arguments for " + rawType); } return new ParameterizedTypeImpl(ownerType, rawType, typeArguments); } private  Types(); static String generatedJsonAdapterName(Class<?> clazz); static String generatedJsonAdapterName(String className); static @Nullable Set<? extends Annotation> nextAnnotations(
      Set<? extends Annotation> annotations, Class<? extends Annotation> jsonQualifier); static ParameterizedType newParameterizedType(Type rawType, Type... typeArguments); static ParameterizedType newParameterizedTypeWithOwner(
      Type ownerType, Type rawType, Type... typeArguments); static GenericArrayType arrayOf(Type componentType); static WildcardType subtypeOf(Type bound); static WildcardType supertypeOf(Type bound); static Class<?> getRawType(Type type); static Type collectionElementType(Type context, Class<?> contextRawType); static boolean equals(@Nullable Type a, @Nullable Type b); static Set<? extends Annotation> getFieldJsonQualifierAnnotations(
      Class<?> clazz, String fieldName);  }### Answer:
@Test public void getFirstTypeArgument() throws Exception { assertThat(getFirstTypeArgument(A.class)).isNull(); Type type = Types.newParameterizedTypeWithOwner(TypesTest.class, A.class, B.class, C.class); assertThat(getFirstTypeArgument(type)).isEqualTo(B.class); }
@Test public void recursiveTypeVariablesResolve() { JsonAdapter<RecursiveTypeVars<String>> adapter = new Moshi.Builder() .build() .adapter( Types.newParameterizedTypeWithOwner( TypesTest.class, RecursiveTypeVars.class, String.class)); assertThat(adapter).isNotNull(); }
@Test public void parameterizedTypeWithUnnecessaryOwnerProvided() throws Exception { try { Types.newParameterizedTypeWithOwner(A.class, List.class, B.class); fail(); } catch (IllegalArgumentException expected) { assertThat(expected) .hasMessageThat() .isEqualTo("unexpected owner type for " + List.class + ": " + A.class); } }
@Test public void parameterizedTypeWithIncorrectOwnerProvided() throws Exception { try { Types.newParameterizedTypeWithOwner(A.class, D.class, B.class); fail(); } catch (IllegalArgumentException expected) { assertThat(expected) .hasMessageThat() .isEqualTo("unexpected owner type for " + D.class + ": " + A.class); } }