• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 Google, 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 com.google.testing.compile.CompilationRule;
19 import java.util.Map;
20 import javax.lang.model.element.TypeElement;
21 import javax.lang.model.util.Elements;
22 import org.junit.Rule;
23 import org.junit.Test;
24 import org.junit.runner.RunWith;
25 import org.junit.runners.JUnit4;
26 import org.mockito.Mockito;
27 
28 import static com.google.common.truth.Truth.assertThat;
29 import static org.junit.Assert.assertEquals;
30 import static org.junit.Assert.fail;
31 import static org.mockito.Mockito.when;
32 
33 @RunWith(JUnit4.class)
34 public final class ClassNameTest {
35   @Rule public CompilationRule compilationRule = new CompilationRule();
36 
bestGuessForString_simpleClass()37   @Test public void bestGuessForString_simpleClass() {
38     assertThat(ClassName.bestGuess(String.class.getName()))
39         .isEqualTo(ClassName.get("java.lang", "String"));
40   }
41 
bestGuessNonAscii()42   @Test public void bestGuessNonAscii() {
43     ClassName className = ClassName.bestGuess(
44         "com.\ud835\udc1andro\ud835\udc22d.\ud835\udc00ctiv\ud835\udc22ty");
45     assertEquals("com.\ud835\udc1andro\ud835\udc22d", className.packageName());
46     assertEquals("\ud835\udc00ctiv\ud835\udc22ty", className.simpleName());
47   }
48 
49   static class OuterClass {
50     static class InnerClass {}
51   }
52 
bestGuessForString_nestedClass()53   @Test public void bestGuessForString_nestedClass() {
54     assertThat(ClassName.bestGuess(Map.Entry.class.getCanonicalName()))
55         .isEqualTo(ClassName.get("java.util", "Map", "Entry"));
56     assertThat(ClassName.bestGuess(OuterClass.InnerClass.class.getCanonicalName()))
57         .isEqualTo(ClassName.get("com.squareup.javapoet",
58             "ClassNameTest", "OuterClass", "InnerClass"));
59   }
60 
bestGuessForString_defaultPackage()61   @Test public void bestGuessForString_defaultPackage() {
62     assertThat(ClassName.bestGuess("SomeClass"))
63         .isEqualTo(ClassName.get("", "SomeClass"));
64     assertThat(ClassName.bestGuess("SomeClass.Nested"))
65         .isEqualTo(ClassName.get("", "SomeClass", "Nested"));
66     assertThat(ClassName.bestGuess("SomeClass.Nested.EvenMore"))
67         .isEqualTo(ClassName.get("", "SomeClass", "Nested", "EvenMore"));
68   }
69 
bestGuessForString_confusingInput()70   @Test public void bestGuessForString_confusingInput() {
71     assertBestGuessThrows("");
72     assertBestGuessThrows(".");
73     assertBestGuessThrows(".Map");
74     assertBestGuessThrows("java");
75     assertBestGuessThrows("java.util");
76     assertBestGuessThrows("java.util.");
77     assertBestGuessThrows("java..util.Map.Entry");
78     assertBestGuessThrows("java.util..Map.Entry");
79     assertBestGuessThrows("java.util.Map..Entry");
80     assertBestGuessThrows("com.test.$");
81     assertBestGuessThrows("com.test.LooksLikeAClass.pkg");
82     assertBestGuessThrows("!@#$gibberish%^&*");
83   }
84 
assertBestGuessThrows(String s)85   private void assertBestGuessThrows(String s) {
86     try {
87       ClassName.bestGuess(s);
88       fail();
89     } catch (IllegalArgumentException expected) {
90     }
91   }
92 
createNestedClass()93   @Test public void createNestedClass() {
94     ClassName foo = ClassName.get("com.example", "Foo");
95     ClassName bar = foo.nestedClass("Bar");
96     assertThat(bar).isEqualTo(ClassName.get("com.example", "Foo", "Bar"));
97     ClassName baz = bar.nestedClass("Baz");
98     assertThat(baz).isEqualTo(ClassName.get("com.example", "Foo", "Bar", "Baz"));
99   }
100 
101   static class $Outer {
102     static class $Inner {}
103   }
104 
classNameFromTypeElement()105   @Test public void classNameFromTypeElement() {
106     Elements elements = compilationRule.getElements();
107     TypeElement object = elements.getTypeElement(Object.class.getCanonicalName());
108     assertThat(ClassName.get(object).toString()).isEqualTo("java.lang.Object");
109     TypeElement outer = elements.getTypeElement($Outer.class.getCanonicalName());
110     assertThat(ClassName.get(outer).toString()).isEqualTo("com.squareup.javapoet.ClassNameTest.$Outer");
111     TypeElement inner = elements.getTypeElement($Outer.$Inner.class.getCanonicalName());
112     assertThat(ClassName.get(inner).toString()).isEqualTo("com.squareup.javapoet.ClassNameTest.$Outer.$Inner");
113   }
114 
115   /**
116    * Buck builds with "source-based ABI generation" and those builds don't support
117    * {@link TypeElement#getKind()}. Test to confirm that we don't use that API.
118    */
classNameFromTypeElementDoesntUseGetKind()119   @Test public void classNameFromTypeElementDoesntUseGetKind() {
120     Elements elements = compilationRule.getElements();
121     TypeElement object = elements.getTypeElement(Object.class.getCanonicalName());
122     assertThat(ClassName.get(preventGetKind(object)).toString())
123         .isEqualTo("java.lang.Object");
124     TypeElement outer = elements.getTypeElement($Outer.class.getCanonicalName());
125     assertThat(ClassName.get(preventGetKind(outer)).toString())
126         .isEqualTo("com.squareup.javapoet.ClassNameTest.$Outer");
127     TypeElement inner = elements.getTypeElement($Outer.$Inner.class.getCanonicalName());
128     assertThat(ClassName.get(preventGetKind(inner)).toString())
129         .isEqualTo("com.squareup.javapoet.ClassNameTest.$Outer.$Inner");
130   }
131 
132   /** Returns a new instance like {@code object} that throws on {@code getKind()}. */
preventGetKind(TypeElement object)133   private TypeElement preventGetKind(TypeElement object) {
134     TypeElement spy = Mockito.spy(object);
135     when(spy.getKind()).thenThrow(new AssertionError());
136     when(spy.getEnclosingElement()).thenAnswer(invocation -> {
137       Object enclosingElement = invocation.callRealMethod();
138       return enclosingElement instanceof TypeElement
139           ? preventGetKind((TypeElement) enclosingElement)
140           : enclosingElement;
141     });
142     return spy;
143   }
144 
classNameFromClass()145   @Test public void classNameFromClass() {
146     assertThat(ClassName.get(Object.class).toString())
147         .isEqualTo("java.lang.Object");
148     assertThat(ClassName.get(OuterClass.InnerClass.class).toString())
149         .isEqualTo("com.squareup.javapoet.ClassNameTest.OuterClass.InnerClass");
150     assertThat((ClassName.get(new Object() {}.getClass())).toString())
151         .isEqualTo("com.squareup.javapoet.ClassNameTest$1");
152     assertThat((ClassName.get(new Object() { Object inner = new Object() {}; }.inner.getClass())).toString())
153         .isEqualTo("com.squareup.javapoet.ClassNameTest$2$1");
154     assertThat((ClassName.get($Outer.class)).toString())
155         .isEqualTo("com.squareup.javapoet.ClassNameTest.$Outer");
156     assertThat((ClassName.get($Outer.$Inner.class)).toString())
157         .isEqualTo("com.squareup.javapoet.ClassNameTest.$Outer.$Inner");
158   }
159 
peerClass()160   @Test public void peerClass() {
161     assertThat(ClassName.get(Double.class).peerClass("Short"))
162         .isEqualTo(ClassName.get(Short.class));
163     assertThat(ClassName.get("", "Double").peerClass("Short"))
164         .isEqualTo(ClassName.get("", "Short"));
165     assertThat(ClassName.get("a.b", "Combo", "Taco").peerClass("Burrito"))
166         .isEqualTo(ClassName.get("a.b", "Combo", "Burrito"));
167   }
168 
fromClassRejectionTypes()169   @Test public void fromClassRejectionTypes() {
170     try {
171       ClassName.get(int.class);
172       fail();
173     } catch (IllegalArgumentException ignored) {
174     }
175     try {
176       ClassName.get(void.class);
177       fail();
178     } catch (IllegalArgumentException ignored) {
179     }
180     try {
181       ClassName.get(Object[].class);
182       fail();
183     } catch (IllegalArgumentException ignored) {
184     }
185   }
186 
187   @Test
reflectionName()188   public void reflectionName() {
189     assertEquals("java.lang.Object", TypeName.OBJECT.reflectionName());
190     assertEquals("java.lang.Thread$State", ClassName.get(Thread.State.class).reflectionName());
191     assertEquals("java.util.Map$Entry", ClassName.get(Map.Entry.class).reflectionName());
192     assertEquals("Foo", ClassName.get("", "Foo").reflectionName());
193     assertEquals("Foo$Bar$Baz", ClassName.get("", "Foo", "Bar", "Baz").reflectionName());
194     assertEquals("a.b.c.Foo$Bar$Baz", ClassName.get("a.b.c", "Foo", "Bar", "Baz").reflectionName());
195   }
196 
197   @Test
canonicalName()198   public void canonicalName() {
199     assertEquals("java.lang.Object", TypeName.OBJECT.canonicalName());
200     assertEquals("java.lang.Thread.State", ClassName.get(Thread.State.class).canonicalName());
201     assertEquals("java.util.Map.Entry", ClassName.get(Map.Entry.class).canonicalName());
202     assertEquals("Foo", ClassName.get("", "Foo").canonicalName());
203     assertEquals("Foo.Bar.Baz", ClassName.get("", "Foo", "Bar", "Baz").canonicalName());
204     assertEquals("a.b.c.Foo.Bar.Baz", ClassName.get("a.b.c", "Foo", "Bar", "Baz").canonicalName());
205   }
206 }
207