ClassNameTest.java
/*
* Copyright (C) 2014 Google, 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 com.google.testing.compile.CompilationRule;
import java.util.Map;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mockito;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.when;
@RunWith(JUnit4.class)
public final class ClassNameTest {
@Rule public CompilationRule compilationRule = new CompilationRule();
@Test public void bestGuessForString_simpleClass() {
assertThat(ClassName.bestGuess(String.class.getName()))
.isEqualTo(ClassName.get("java.lang", "String"));
}
@Test public void bestGuessNonAscii() {
ClassName className = ClassName.bestGuess(
"com.\ud835\udc1andro\ud835\udc22d.\ud835\udc00ctiv\ud835\udc22ty");
assertEquals("com.\ud835\udc1andro\ud835\udc22d", className.packageName());
assertEquals("\ud835\udc00ctiv\ud835\udc22ty", className.simpleName());
}
static class OuterClass {
static class InnerClass {}
}
@Test public void bestGuessForString_nestedClass() {
assertThat(ClassName.bestGuess(Map.Entry.class.getCanonicalName()))
.isEqualTo(ClassName.get("java.util", "Map", "Entry"));
assertThat(ClassName.bestGuess(OuterClass.InnerClass.class.getCanonicalName()))
.isEqualTo(ClassName.get("com.squareup.javapoet",
"ClassNameTest", "OuterClass", "InnerClass"));
}
@Test public void bestGuessForString_defaultPackage() {
assertThat(ClassName.bestGuess("SomeClass"))
.isEqualTo(ClassName.get("", "SomeClass"));
assertThat(ClassName.bestGuess("SomeClass.Nested"))
.isEqualTo(ClassName.get("", "SomeClass", "Nested"));
assertThat(ClassName.bestGuess("SomeClass.Nested.EvenMore"))
.isEqualTo(ClassName.get("", "SomeClass", "Nested", "EvenMore"));
}
@Test public void bestGuessForString_confusingInput() {
assertBestGuessThrows("");
assertBestGuessThrows(".");
assertBestGuessThrows(".Map");
assertBestGuessThrows("java");
assertBestGuessThrows("java.util");
assertBestGuessThrows("java.util.");
assertBestGuessThrows("java..util.Map.Entry");
assertBestGuessThrows("java.util..Map.Entry");
assertBestGuessThrows("java.util.Map..Entry");
assertBestGuessThrows("com.test.$");
assertBestGuessThrows("com.test.LooksLikeAClass.pkg");
assertBestGuessThrows("!@#$gibberish%^&*");
}
private void assertBestGuessThrows(String s) {
try {
ClassName.bestGuess(s);
fail();
} catch (IllegalArgumentException expected) {
}
}
@Test public void createNestedClass() {
ClassName foo = ClassName.get("com.example", "Foo");
ClassName bar = foo.nestedClass("Bar");
assertThat(bar).isEqualTo(ClassName.get("com.example", "Foo", "Bar"));
ClassName baz = bar.nestedClass("Baz");
assertThat(baz).isEqualTo(ClassName.get("com.example", "Foo", "Bar", "Baz"));
}
static class $Outer {
static class $Inner {}
}
@Test public void classNameFromTypeElement() {
Elements elements = compilationRule.getElements();
TypeElement object = elements.getTypeElement(Object.class.getCanonicalName());
assertThat(ClassName.get(object).toString()).isEqualTo("java.lang.Object");
TypeElement outer = elements.getTypeElement($Outer.class.getCanonicalName());
assertThat(ClassName.get(outer).toString()).isEqualTo("com.squareup.javapoet.ClassNameTest.$Outer");
TypeElement inner = elements.getTypeElement($Outer.$Inner.class.getCanonicalName());
assertThat(ClassName.get(inner).toString()).isEqualTo("com.squareup.javapoet.ClassNameTest.$Outer.$Inner");
}
/**
* Buck builds with "source-based ABI generation" and those builds don't support
* {@link TypeElement#getKind()}. Test to confirm that we don't use that API.
*/
@Test public void classNameFromTypeElementDoesntUseGetKind() {
Elements elements = compilationRule.getElements();
TypeElement object = elements.getTypeElement(Object.class.getCanonicalName());
assertThat(ClassName.get(preventGetKind(object)).toString())
.isEqualTo("java.lang.Object");
TypeElement outer = elements.getTypeElement($Outer.class.getCanonicalName());
assertThat(ClassName.get(preventGetKind(outer)).toString())
.isEqualTo("com.squareup.javapoet.ClassNameTest.$Outer");
TypeElement inner = elements.getTypeElement($Outer.$Inner.class.getCanonicalName());
assertThat(ClassName.get(preventGetKind(inner)).toString())
.isEqualTo("com.squareup.javapoet.ClassNameTest.$Outer.$Inner");
}
/** Returns a new instance like {@code object} that throws on {@code getKind()}. */
private TypeElement preventGetKind(TypeElement object) {
TypeElement spy = Mockito.spy(object);
when(spy.getKind()).thenThrow(new AssertionError());
when(spy.getEnclosingElement()).thenAnswer(invocation -> {
Object enclosingElement = invocation.callRealMethod();
return enclosingElement instanceof TypeElement
? preventGetKind((TypeElement) enclosingElement)
: enclosingElement;
});
return spy;
}
@Test public void classNameFromClass() {
assertThat(ClassName.get(Object.class).toString())
.isEqualTo("java.lang.Object");
assertThat(ClassName.get(OuterClass.InnerClass.class).toString())
.isEqualTo("com.squareup.javapoet.ClassNameTest.OuterClass.InnerClass");
assertThat((ClassName.get(new Object() {}.getClass())).toString())
.isEqualTo("com.squareup.javapoet.ClassNameTest$1");
assertThat((ClassName.get(new Object() { Object inner = new Object() {}; }.inner.getClass())).toString())
.isEqualTo("com.squareup.javapoet.ClassNameTest$2$1");
assertThat((ClassName.get($Outer.class)).toString())
.isEqualTo("com.squareup.javapoet.ClassNameTest.$Outer");
assertThat((ClassName.get($Outer.$Inner.class)).toString())
.isEqualTo("com.squareup.javapoet.ClassNameTest.$Outer.$Inner");
}
@Test public void peerClass() {
assertThat(ClassName.get(Double.class).peerClass("Short"))
.isEqualTo(ClassName.get(Short.class));
assertThat(ClassName.get("", "Double").peerClass("Short"))
.isEqualTo(ClassName.get("", "Short"));
assertThat(ClassName.get("a.b", "Combo", "Taco").peerClass("Burrito"))
.isEqualTo(ClassName.get("a.b", "Combo", "Burrito"));
}
@Test public void fromClassRejectionTypes() {
try {
ClassName.get(int.class);
fail();
} catch (IllegalArgumentException ignored) {
}
try {
ClassName.get(void.class);
fail();
} catch (IllegalArgumentException ignored) {
}
try {
ClassName.get(Object[].class);
fail();
} catch (IllegalArgumentException ignored) {
}
}
@Test
public void reflectionName() {
assertEquals("java.lang.Object", TypeName.OBJECT.reflectionName());
assertEquals("java.lang.Thread$State", ClassName.get(Thread.State.class).reflectionName());
assertEquals("java.util.Map$Entry", ClassName.get(Map.Entry.class).reflectionName());
assertEquals("Foo", ClassName.get("", "Foo").reflectionName());
assertEquals("Foo$Bar$Baz", ClassName.get("", "Foo", "Bar", "Baz").reflectionName());
assertEquals("a.b.c.Foo$Bar$Baz", ClassName.get("a.b.c", "Foo", "Bar", "Baz").reflectionName());
}
@Test
public void canonicalName() {
assertEquals("java.lang.Object", TypeName.OBJECT.canonicalName());
assertEquals("java.lang.Thread.State", ClassName.get(Thread.State.class).canonicalName());
assertEquals("java.util.Map.Entry", ClassName.get(Map.Entry.class).canonicalName());
assertEquals("Foo", ClassName.get("", "Foo").canonicalName());
assertEquals("Foo.Bar.Baz", ClassName.get("", "Foo", "Bar", "Baz").canonicalName());
assertEquals("a.b.c.Foo.Bar.Baz", ClassName.get("a.b.c", "Foo", "Bar", "Baz").canonicalName());
}
}