| /* |
| * Copyright (C) 2015 Square, Inc. |
| * |
| * 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.squareup.javapoet; |
| |
| import java.lang.annotation.ElementType; |
| import java.lang.annotation.Target; |
| import java.util.List; |
| import java.util.Map; |
| import org.junit.Test; |
| |
| import static com.google.common.truth.Truth.assertThat; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotEquals; |
| import static org.junit.Assert.assertTrue; |
| |
| public class AnnotatedTypeNameTest { |
| |
| private final static String NN = NeverNull.class.getCanonicalName(); |
| private final AnnotationSpec NEVER_NULL = AnnotationSpec.builder(NeverNull.class).build(); |
| private final static String TUA = TypeUseAnnotation.class.getCanonicalName(); |
| private final AnnotationSpec TYPE_USE_ANNOTATION = |
| AnnotationSpec.builder(TypeUseAnnotation.class).build(); |
| |
| @Target(ElementType.TYPE_USE) |
| public @interface NeverNull {} |
| |
| @Target(ElementType.TYPE_USE) |
| public @interface TypeUseAnnotation {} |
| |
| |
| @Test(expected=NullPointerException.class) public void nullAnnotationArray() { |
| TypeName.BOOLEAN.annotated((AnnotationSpec[]) null); |
| } |
| |
| @Test(expected=NullPointerException.class) public void nullAnnotationList() { |
| TypeName.DOUBLE.annotated((List<AnnotationSpec>) null); |
| } |
| |
| @Test public void annotated() { |
| TypeName simpleString = TypeName.get(String.class); |
| assertFalse(simpleString.isAnnotated()); |
| assertEquals(simpleString, TypeName.get(String.class)); |
| |
| TypeName annotated = simpleString.annotated(NEVER_NULL); |
| assertTrue(annotated.isAnnotated()); |
| assertEquals(annotated, annotated.annotated()); |
| } |
| |
| @Test public void annotatedType() { |
| TypeName type = TypeName.get(String.class); |
| TypeName actual = type.annotated(TYPE_USE_ANNOTATION); |
| assertThat(actual.toString()).isEqualTo("java.lang. @" + TUA + " String"); |
| } |
| |
| @Test public void annotatedTwice() { |
| TypeName type = TypeName.get(String.class); |
| TypeName actual = |
| type.annotated(NEVER_NULL) |
| .annotated(TYPE_USE_ANNOTATION); |
| assertThat(actual.toString()) |
| .isEqualTo("java.lang. @" + NN + " @" + TUA + " String"); |
| } |
| |
| @Test public void annotatedParameterizedType() { |
| TypeName type = ParameterizedTypeName.get(List.class, String.class); |
| TypeName actual = type.annotated(TYPE_USE_ANNOTATION); |
| assertThat(actual.toString()).isEqualTo("java.util. @" + TUA + " List<java.lang.String>"); |
| } |
| |
| @Test public void annotatedArgumentOfParameterizedType() { |
| TypeName type = TypeName.get(String.class).annotated(TYPE_USE_ANNOTATION); |
| TypeName actual = ParameterizedTypeName.get(ClassName.get(List.class), type); |
| assertThat(actual.toString()).isEqualTo("java.util.List<java.lang. @" + TUA + " String>"); |
| } |
| |
| @Test public void annotatedWildcardTypeNameWithSuper() { |
| TypeName type = TypeName.get(String.class).annotated(TYPE_USE_ANNOTATION); |
| TypeName actual = WildcardTypeName.supertypeOf(type); |
| assertThat(actual.toString()).isEqualTo("? super java.lang. @" + TUA + " String"); |
| } |
| |
| @Test public void annotatedWildcardTypeNameWithExtends() { |
| TypeName type = TypeName.get(String.class).annotated(TYPE_USE_ANNOTATION); |
| TypeName actual = WildcardTypeName.subtypeOf(type); |
| assertThat(actual.toString()).isEqualTo("? extends java.lang. @" + TUA + " String"); |
| } |
| |
| @Test public void annotatedEquivalence() { |
| annotatedEquivalence(TypeName.VOID); |
| annotatedEquivalence(ArrayTypeName.get(Object[].class)); |
| annotatedEquivalence(ClassName.get(Object.class)); |
| annotatedEquivalence(ParameterizedTypeName.get(List.class, Object.class)); |
| annotatedEquivalence(TypeVariableName.get(Object.class)); |
| annotatedEquivalence(WildcardTypeName.get(Object.class)); |
| } |
| |
| private void annotatedEquivalence(TypeName type) { |
| assertFalse(type.isAnnotated()); |
| assertEquals(type, type); |
| assertEquals(type.annotated(TYPE_USE_ANNOTATION), type.annotated(TYPE_USE_ANNOTATION)); |
| assertNotEquals(type, type.annotated(TYPE_USE_ANNOTATION)); |
| assertEquals(type.hashCode(), type.hashCode()); |
| assertEquals(type.annotated(TYPE_USE_ANNOTATION).hashCode(), |
| type.annotated(TYPE_USE_ANNOTATION).hashCode()); |
| assertNotEquals(type.hashCode(), type.annotated(TYPE_USE_ANNOTATION).hashCode()); |
| } |
| |
| // https://github.com/square/javapoet/issues/431 |
| @Test public void annotatedNestedType() { |
| TypeName type = TypeName.get(Map.Entry.class).annotated(TYPE_USE_ANNOTATION); |
| assertThat(type.toString()).isEqualTo("java.util.Map. @" + TUA + " Entry"); |
| } |
| |
| @Test public void annotatedEnclosingAndNestedType() { |
| TypeName type = ((ClassName) TypeName.get(Map.class).annotated(TYPE_USE_ANNOTATION)) |
| .nestedClass("Entry").annotated(TYPE_USE_ANNOTATION); |
| assertThat(type.toString()).isEqualTo("java.util. @" + TUA + " Map. @" + TUA + " Entry"); |
| } |
| |
| // https://github.com/square/javapoet/issues/431 |
| @Test public void annotatedNestedParameterizedType() { |
| TypeName type = ParameterizedTypeName.get(Map.Entry.class, Byte.class, Byte.class) |
| .annotated(TYPE_USE_ANNOTATION); |
| assertThat(type.toString()) |
| .isEqualTo("java.util.Map. @" + TUA + " Entry<java.lang.Byte, java.lang.Byte>"); |
| } |
| |
| @Test public void withoutAnnotationsOnAnnotatedEnclosingAndNestedType() { |
| TypeName type = ((ClassName) TypeName.get(Map.class).annotated(TYPE_USE_ANNOTATION)) |
| .nestedClass("Entry").annotated(TYPE_USE_ANNOTATION); |
| assertThat(type.isAnnotated()).isTrue(); |
| assertThat(type.withoutAnnotations()).isEqualTo(TypeName.get(Map.Entry.class)); |
| } |
| |
| @Test public void withoutAnnotationsOnAnnotatedEnclosingType() { |
| TypeName type = ((ClassName) TypeName.get(Map.class).annotated(TYPE_USE_ANNOTATION)) |
| .nestedClass("Entry"); |
| assertThat(type.isAnnotated()).isTrue(); |
| assertThat(type.withoutAnnotations()).isEqualTo(TypeName.get(Map.Entry.class)); |
| } |
| |
| @Test public void withoutAnnotationsOnAnnotatedNestedType() { |
| TypeName type = ((ClassName) TypeName.get(Map.class)) |
| .nestedClass("Entry").annotated(TYPE_USE_ANNOTATION); |
| assertThat(type.isAnnotated()).isTrue(); |
| assertThat(type.withoutAnnotations()).isEqualTo(TypeName.get(Map.Entry.class)); |
| } |
| |
| // https://github.com/square/javapoet/issues/614 |
| @Test public void annotatedArrayType() { |
| TypeName type = ArrayTypeName.of(ClassName.get(Object.class)).annotated(TYPE_USE_ANNOTATION); |
| assertThat(type.toString()).isEqualTo("java.lang.Object @" + TUA + " []"); |
| } |
| |
| @Test public void annotatedArrayElementType() { |
| TypeName type = ArrayTypeName.of(ClassName.get(Object.class).annotated(TYPE_USE_ANNOTATION)); |
| assertThat(type.toString()).isEqualTo("java.lang. @" + TUA + " Object[]"); |
| } |
| |
| // https://github.com/square/javapoet/issues/614 |
| @Test public void annotatedOuterMultidimensionalArrayType() { |
| TypeName type = ArrayTypeName.of(ArrayTypeName.of(ClassName.get(Object.class))) |
| .annotated(TYPE_USE_ANNOTATION); |
| assertThat(type.toString()).isEqualTo("java.lang.Object @" + TUA + " [][]"); |
| } |
| |
| // https://github.com/square/javapoet/issues/614 |
| @Test public void annotatedInnerMultidimensionalArrayType() { |
| TypeName type = ArrayTypeName.of(ArrayTypeName.of(ClassName.get(Object.class)) |
| .annotated(TYPE_USE_ANNOTATION)); |
| assertThat(type.toString()).isEqualTo("java.lang.Object[] @" + TUA + " []"); |
| } |
| |
| // https://github.com/square/javapoet/issues/614 |
| @Test public void annotatedArrayTypeVarargsParameter() { |
| TypeName type = ArrayTypeName.of(ArrayTypeName.of(ClassName.get(Object.class))) |
| .annotated(TYPE_USE_ANNOTATION); |
| MethodSpec varargsMethod = MethodSpec.methodBuilder("m") |
| .addParameter( |
| ParameterSpec.builder(type, "p") |
| .build()) |
| .varargs() |
| .build(); |
| assertThat(varargsMethod.toString()).isEqualTo("" |
| + "void m(java.lang.Object @" + TUA + " []... p) {\n" |
| + "}\n"); |
| } |
| |
| // https://github.com/square/javapoet/issues/614 |
| @Test public void annotatedArrayTypeInVarargsParameter() { |
| TypeName type = ArrayTypeName.of(ArrayTypeName.of(ClassName.get(Object.class)) |
| .annotated(TYPE_USE_ANNOTATION)); |
| MethodSpec varargsMethod = MethodSpec.methodBuilder("m") |
| .addParameter( |
| ParameterSpec.builder(type, "p") |
| .build()) |
| .varargs() |
| .build(); |
| assertThat(varargsMethod.toString()).isEqualTo("" |
| + "void m(java.lang.Object[] @" + TUA + " ... p) {\n" |
| + "}\n"); |
| } |
| } |