Home | History | Annotate | Download | only in javapoet
      1 /*
      2  * Copyright (C) 2015 Square, Inc.
      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 package com.squareup.javapoet;
     17 
     18 import java.lang.annotation.ElementType;
     19 import java.lang.annotation.Target;
     20 import java.util.List;
     21 import java.util.Map;
     22 import org.junit.Test;
     23 
     24 import static com.google.common.truth.Truth.assertThat;
     25 import static org.junit.Assert.assertEquals;
     26 import static org.junit.Assert.assertFalse;
     27 import static org.junit.Assert.assertNotEquals;
     28 import static org.junit.Assert.assertTrue;
     29 
     30 public class AnnotatedTypeNameTest {
     31 
     32   private final static String NN = NeverNull.class.getCanonicalName();
     33   private final AnnotationSpec NEVER_NULL = AnnotationSpec.builder(NeverNull.class).build();
     34   private final static String TUA = TypeUseAnnotation.class.getCanonicalName();
     35   private final AnnotationSpec TYPE_USE_ANNOTATION =
     36       AnnotationSpec.builder(TypeUseAnnotation.class).build();
     37 
     38   @Target(ElementType.TYPE_USE)
     39   public @interface NeverNull {}
     40 
     41   @Target(ElementType.TYPE_USE)
     42   public @interface TypeUseAnnotation {}
     43 
     44 
     45   @Test(expected=NullPointerException.class) public void nullAnnotationArray() {
     46     TypeName.BOOLEAN.annotated((AnnotationSpec[]) null);
     47   }
     48 
     49   @Test(expected=NullPointerException.class) public void nullAnnotationList() {
     50     TypeName.DOUBLE.annotated((List<AnnotationSpec>) null);
     51   }
     52 
     53   @Test public void annotated() {
     54     TypeName simpleString = TypeName.get(String.class);
     55     assertFalse(simpleString.isAnnotated());
     56     assertEquals(simpleString, TypeName.get(String.class));
     57 
     58     TypeName annotated = simpleString.annotated(NEVER_NULL);
     59     assertTrue(annotated.isAnnotated());
     60     assertEquals(annotated, annotated.annotated());
     61   }
     62 
     63   @Test public void annotatedType() {
     64     TypeName type = TypeName.get(String.class);
     65     TypeName actual = type.annotated(TYPE_USE_ANNOTATION);
     66     assertThat(actual.toString()).isEqualTo("java.lang. @" + TUA + " String");
     67   }
     68 
     69   @Test public void annotatedTwice() {
     70     TypeName type = TypeName.get(String.class);
     71     TypeName actual =
     72         type.annotated(NEVER_NULL)
     73             .annotated(TYPE_USE_ANNOTATION);
     74     assertThat(actual.toString())
     75         .isEqualTo("java.lang. @" + NN + " @" + TUA + " String");
     76   }
     77 
     78   @Test public void annotatedParameterizedType() {
     79     TypeName type = ParameterizedTypeName.get(List.class, String.class);
     80     TypeName actual = type.annotated(TYPE_USE_ANNOTATION);
     81     assertThat(actual.toString()).isEqualTo("java.util. @" + TUA + " List<java.lang.String>");
     82   }
     83 
     84   @Test public void annotatedArgumentOfParameterizedType() {
     85     TypeName type = TypeName.get(String.class).annotated(TYPE_USE_ANNOTATION);
     86     TypeName actual = ParameterizedTypeName.get(ClassName.get(List.class), type);
     87     assertThat(actual.toString()).isEqualTo("java.util.List<java.lang. @" + TUA + " String>");
     88   }
     89 
     90   @Test public void annotatedWildcardTypeNameWithSuper() {
     91     TypeName type = TypeName.get(String.class).annotated(TYPE_USE_ANNOTATION);
     92     TypeName actual = WildcardTypeName.supertypeOf(type);
     93     assertThat(actual.toString()).isEqualTo("? super java.lang. @" + TUA + " String");
     94   }
     95 
     96   @Test public void annotatedWildcardTypeNameWithExtends() {
     97     TypeName type = TypeName.get(String.class).annotated(TYPE_USE_ANNOTATION);
     98     TypeName actual = WildcardTypeName.subtypeOf(type);
     99     assertThat(actual.toString()).isEqualTo("? extends java.lang. @" + TUA + " String");
    100   }
    101 
    102   @Test public void annotatedEquivalence() {
    103     annotatedEquivalence(TypeName.VOID);
    104     annotatedEquivalence(ArrayTypeName.get(Object[].class));
    105     annotatedEquivalence(ClassName.get(Object.class));
    106     annotatedEquivalence(ParameterizedTypeName.get(List.class, Object.class));
    107     annotatedEquivalence(TypeVariableName.get(Object.class));
    108     annotatedEquivalence(WildcardTypeName.get(Object.class));
    109   }
    110 
    111   private void annotatedEquivalence(TypeName type) {
    112     assertFalse(type.isAnnotated());
    113     assertEquals(type, type);
    114     assertEquals(type.annotated(TYPE_USE_ANNOTATION), type.annotated(TYPE_USE_ANNOTATION));
    115     assertNotEquals(type, type.annotated(TYPE_USE_ANNOTATION));
    116     assertEquals(type.hashCode(), type.hashCode());
    117     assertEquals(type.annotated(TYPE_USE_ANNOTATION).hashCode(),
    118         type.annotated(TYPE_USE_ANNOTATION).hashCode());
    119     assertNotEquals(type.hashCode(), type.annotated(TYPE_USE_ANNOTATION).hashCode());
    120   }
    121 
    122   // https://github.com/square/javapoet/issues/431
    123   @Test public void annotatedNestedType() {
    124     TypeName type = TypeName.get(Map.Entry.class).annotated(TYPE_USE_ANNOTATION);
    125     assertThat(type.toString()).isEqualTo("java.util.Map. @" + TUA + " Entry");
    126   }
    127 
    128   @Test public void annotatedEnclosingAndNestedType() {
    129     TypeName type = ((ClassName) TypeName.get(Map.class).annotated(TYPE_USE_ANNOTATION))
    130         .nestedClass("Entry").annotated(TYPE_USE_ANNOTATION);
    131     assertThat(type.toString()).isEqualTo("java.util. @" + TUA + " Map. @" + TUA + " Entry");
    132   }
    133 
    134   // https://github.com/square/javapoet/issues/431
    135   @Test public void annotatedNestedParameterizedType() {
    136     TypeName type = ParameterizedTypeName.get(Map.Entry.class, Byte.class, Byte.class)
    137         .annotated(TYPE_USE_ANNOTATION);
    138     assertThat(type.toString())
    139         .isEqualTo("java.util.Map. @" + TUA + " Entry<java.lang.Byte, java.lang.Byte>");
    140   }
    141 
    142   @Test public void withoutAnnotationsOnAnnotatedEnclosingAndNestedType() {
    143     TypeName type = ((ClassName) TypeName.get(Map.class).annotated(TYPE_USE_ANNOTATION))
    144         .nestedClass("Entry").annotated(TYPE_USE_ANNOTATION);
    145     assertThat(type.isAnnotated()).isTrue();
    146     assertThat(type.withoutAnnotations()).isEqualTo(TypeName.get(Map.Entry.class));
    147   }
    148 
    149   @Test public void withoutAnnotationsOnAnnotatedEnclosingType() {
    150     TypeName type = ((ClassName) TypeName.get(Map.class).annotated(TYPE_USE_ANNOTATION))
    151         .nestedClass("Entry");
    152     assertThat(type.isAnnotated()).isTrue();
    153     assertThat(type.withoutAnnotations()).isEqualTo(TypeName.get(Map.Entry.class));
    154   }
    155 
    156   @Test public void withoutAnnotationsOnAnnotatedNestedType() {
    157     TypeName type = ((ClassName) TypeName.get(Map.class))
    158         .nestedClass("Entry").annotated(TYPE_USE_ANNOTATION);
    159     assertThat(type.isAnnotated()).isTrue();
    160     assertThat(type.withoutAnnotations()).isEqualTo(TypeName.get(Map.Entry.class));
    161   }
    162 
    163   // https://github.com/square/javapoet/issues/614
    164    @Test public void annotatedArrayType() {
    165     TypeName type = ArrayTypeName.of(ClassName.get(Object.class)).annotated(TYPE_USE_ANNOTATION);
    166     assertThat(type.toString()).isEqualTo("java.lang.Object @" + TUA + " []");
    167   }
    168 
    169   @Test public void annotatedArrayElementType() {
    170     TypeName type = ArrayTypeName.of(ClassName.get(Object.class).annotated(TYPE_USE_ANNOTATION));
    171     assertThat(type.toString()).isEqualTo("java.lang. @" + TUA + " Object[]");
    172   }
    173 
    174   // https://github.com/square/javapoet/issues/614
    175   @Test public void annotatedOuterMultidimensionalArrayType() {
    176     TypeName type = ArrayTypeName.of(ArrayTypeName.of(ClassName.get(Object.class)))
    177         .annotated(TYPE_USE_ANNOTATION);
    178     assertThat(type.toString()).isEqualTo("java.lang.Object @" + TUA + " [][]");
    179   }
    180 
    181   // https://github.com/square/javapoet/issues/614
    182   @Test public void annotatedInnerMultidimensionalArrayType() {
    183     TypeName type = ArrayTypeName.of(ArrayTypeName.of(ClassName.get(Object.class))
    184         .annotated(TYPE_USE_ANNOTATION));
    185     assertThat(type.toString()).isEqualTo("java.lang.Object[] @" + TUA + " []");
    186   }
    187 
    188   // https://github.com/square/javapoet/issues/614
    189   @Test public void annotatedArrayTypeVarargsParameter() {
    190     TypeName type = ArrayTypeName.of(ArrayTypeName.of(ClassName.get(Object.class)))
    191         .annotated(TYPE_USE_ANNOTATION);
    192     MethodSpec varargsMethod = MethodSpec.methodBuilder("m")
    193         .addParameter(
    194             ParameterSpec.builder(type, "p")
    195                 .build())
    196         .varargs()
    197         .build();
    198     assertThat(varargsMethod.toString()).isEqualTo(""
    199         + "void m(java.lang.Object @" + TUA + " []... p) {\n"
    200         + "}\n");
    201   }
    202 
    203   // https://github.com/square/javapoet/issues/614
    204   @Test public void annotatedArrayTypeInVarargsParameter() {
    205     TypeName type = ArrayTypeName.of(ArrayTypeName.of(ClassName.get(Object.class))
    206         .annotated(TYPE_USE_ANNOTATION));
    207     MethodSpec varargsMethod = MethodSpec.methodBuilder("m")
    208         .addParameter(
    209             ParameterSpec.builder(type, "p")
    210                 .build())
    211         .varargs()
    212         .build();
    213     assertThat(varargsMethod.toString()).isEqualTo(""
    214         + "void m(java.lang.Object[] @" + TUA + " ... p) {\n"
    215         + "}\n");
    216   }
    217 }
    218