aboutsummaryrefslogtreecommitdiff
path: root/src/test/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/java/com')
-rw-r--r--src/test/java/com/squareup/javapoet/AnnotationSpecTest.java12
-rw-r--r--src/test/java/com/squareup/javapoet/ClassNameTest.java10
-rw-r--r--src/test/java/com/squareup/javapoet/CodeBlockTest.java9
-rw-r--r--src/test/java/com/squareup/javapoet/CodeWriterTest.java23
-rw-r--r--src/test/java/com/squareup/javapoet/FieldSpecTest.java21
-rw-r--r--src/test/java/com/squareup/javapoet/FileWritingTest.java7
-rw-r--r--src/test/java/com/squareup/javapoet/JavaFileTest.java322
-rw-r--r--src/test/java/com/squareup/javapoet/MethodSpecTest.java178
-rw-r--r--src/test/java/com/squareup/javapoet/NameAllocatorTest.java3
-rw-r--r--src/test/java/com/squareup/javapoet/ParameterSpecTest.java95
-rw-r--r--src/test/java/com/squareup/javapoet/TestUtil.java17
-rw-r--r--src/test/java/com/squareup/javapoet/TypeSpecTest.java199
12 files changed, 880 insertions, 16 deletions
diff --git a/src/test/java/com/squareup/javapoet/AnnotationSpecTest.java b/src/test/java/com/squareup/javapoet/AnnotationSpecTest.java
index 49606c7..97c1e6e 100644
--- a/src/test/java/com/squareup/javapoet/AnnotationSpecTest.java
+++ b/src/test/java/com/squareup/javapoet/AnnotationSpecTest.java
@@ -20,6 +20,8 @@ import java.lang.annotation.Annotation;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+
import javax.lang.model.element.TypeElement;
import org.junit.Rule;
import org.junit.Test;
@@ -371,6 +373,16 @@ public final class AnnotationSpecTest {
}
}
+ @Test public void modifyMembers() {
+ AnnotationSpec.Builder builder = AnnotationSpec.builder(SuppressWarnings.class)
+ .addMember("value", "$S", "Foo");
+
+ builder.members.clear();
+ builder.members.put("value", Arrays.asList(CodeBlock.of("$S", "Bar")));
+
+ assertThat(builder.build().toString()).isEqualTo("@java.lang.SuppressWarnings(\"Bar\")");
+ }
+
private String toString(TypeSpec typeSpec) {
return JavaFile.builder("com.squareup.tacos", typeSpec).build().toString();
}
diff --git a/src/test/java/com/squareup/javapoet/ClassNameTest.java b/src/test/java/com/squareup/javapoet/ClassNameTest.java
index e2cc55e..590ad5d 100644
--- a/src/test/java/com/squareup/javapoet/ClassNameTest.java
+++ b/src/test/java/com/squareup/javapoet/ClassNameTest.java
@@ -193,4 +193,14 @@ public final class ClassNameTest {
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());
+ }
}
diff --git a/src/test/java/com/squareup/javapoet/CodeBlockTest.java b/src/test/java/com/squareup/javapoet/CodeBlockTest.java
index 2862809..11b75fa 100644
--- a/src/test/java/com/squareup/javapoet/CodeBlockTest.java
+++ b/src/test/java/com/squareup/javapoet/CodeBlockTest.java
@@ -339,4 +339,13 @@ public final class CodeBlockTest {
CodeBlock joined = codeBlocks.stream().collect(CodeBlock.joining(" || ", "start {", "} end"));
assertThat(joined.toString()).isEqualTo("start {\"hello\" || world.World || need tacos} end");
}
+
+ @Test public void clear() {
+ CodeBlock block = CodeBlock.builder()
+ .addStatement("$S", "Test string")
+ .clear()
+ .build();
+
+ assertThat(block.toString()).isEmpty();
+ }
}
diff --git a/src/test/java/com/squareup/javapoet/CodeWriterTest.java b/src/test/java/com/squareup/javapoet/CodeWriterTest.java
new file mode 100644
index 0000000..331d000
--- /dev/null
+++ b/src/test/java/com/squareup/javapoet/CodeWriterTest.java
@@ -0,0 +1,23 @@
+package com.squareup.javapoet;
+
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static com.google.common.truth.Truth.assertThat;
+
+public class CodeWriterTest {
+
+ @Test
+ public void emptyLineInJavaDocDosEndings() throws IOException {
+ CodeBlock javadocCodeBlock = CodeBlock.of("A\r\n\r\nB\r\n");
+ StringBuilder out = new StringBuilder();
+ new CodeWriter(out).emitJavadoc(javadocCodeBlock);
+ assertThat(out.toString()).isEqualTo(
+ "/**\n" +
+ " * A\n" +
+ " *\n" +
+ " * B\n" +
+ " */\n");
+ }
+} \ No newline at end of file
diff --git a/src/test/java/com/squareup/javapoet/FieldSpecTest.java b/src/test/java/com/squareup/javapoet/FieldSpecTest.java
index 63f7aa8..bc68f6f 100644
--- a/src/test/java/com/squareup/javapoet/FieldSpecTest.java
+++ b/src/test/java/com/squareup/javapoet/FieldSpecTest.java
@@ -28,10 +28,12 @@ public class FieldSpecTest {
FieldSpec b = FieldSpec.builder(int.class, "foo").build();
assertThat(a.equals(b)).isTrue();
assertThat(a.hashCode()).isEqualTo(b.hashCode());
+ assertThat(a.toString()).isEqualTo(b.toString());
a = FieldSpec.builder(int.class, "FOO", Modifier.PUBLIC, Modifier.STATIC).build();
b = FieldSpec.builder(int.class, "FOO", Modifier.PUBLIC, Modifier.STATIC).build();
assertThat(a.equals(b)).isTrue();
assertThat(a.hashCode()).isEqualTo(b.hashCode());
+ assertThat(a.toString()).isEqualTo(b.toString());
}
@Test public void nullAnnotationsAddition() {
@@ -44,4 +46,21 @@ public class FieldSpecTest {
.isEqualTo("annotationSpecs == null");
}
}
-} \ No newline at end of file
+
+ @Test public void modifyAnnotations() {
+ FieldSpec.Builder builder = FieldSpec.builder(int.class, "foo")
+ .addAnnotation(Override.class)
+ .addAnnotation(SuppressWarnings.class);
+
+ builder.annotations.remove(1);
+ assertThat(builder.build().annotations).hasSize(1);
+ }
+
+ @Test public void modifyModifiers() {
+ FieldSpec.Builder builder = FieldSpec.builder(int.class, "foo")
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+
+ builder.modifiers.remove(1);
+ assertThat(builder.build().modifiers).containsExactly(Modifier.PUBLIC);
+ }
+}
diff --git a/src/test/java/com/squareup/javapoet/FileWritingTest.java b/src/test/java/com/squareup/javapoet/FileWritingTest.java
index f817ddb..58e5b62 100644
--- a/src/test/java/com/squareup/javapoet/FileWritingTest.java
+++ b/src/test/java/com/squareup/javapoet/FileWritingTest.java
@@ -216,4 +216,11 @@ public final class FileWritingTest {
+ "class Taco {\n"
+ "}\n");
}
+
+ @Test public void writeToPathReturnsPath() throws IOException {
+ JavaFile javaFile = JavaFile.builder("foo", TypeSpec.classBuilder("Taco").build()).build();
+ Path filePath = javaFile.writeToPath(fsRoot);
+ // Cast to avoid ambiguity between assertThat(Path) and assertThat(Iterable<?>)
+ assertThat((Iterable<?>) filePath).isEqualTo(fsRoot.resolve(fs.getPath("foo", "Taco.java")));
+ }
}
diff --git a/src/test/java/com/squareup/javapoet/JavaFileTest.java b/src/test/java/com/squareup/javapoet/JavaFileTest.java
index e056116..e75a019 100644
--- a/src/test/java/com/squareup/javapoet/JavaFileTest.java
+++ b/src/test/java/com/squareup/javapoet/JavaFileTest.java
@@ -15,12 +15,19 @@
*/
package com.squareup.javapoet;
+import java.io.File;
+import com.google.testing.compile.CompilationRule;
import java.util.Collections;
import java.util.Date;
import java.util.List;
+import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
import org.junit.Ignore;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -29,6 +36,13 @@ import static com.google.common.truth.Truth.assertThat;
@RunWith(JUnit4.class)
public final class JavaFileTest {
+
+ @Rule public final CompilationRule compilation = new CompilationRule();
+
+ private TypeElement getElement(Class<?> clazz) {
+ return compilation.getElements().getTypeElement(clazz.getCanonicalName());
+ }
+
@Test public void importStaticReadmeExample() {
ClassName hoverboard = ClassName.get("com.mattel", "Hoverboard");
ClassName namedBoards = ClassName.get("com.mattel", "Hoverboard", "Boards");
@@ -689,4 +703,312 @@ public final class JavaFileTest {
+ " A a;\n"
+ "}\n");
}
+
+ @Test public void modifyStaticImports() throws Exception {
+ JavaFile.Builder builder = JavaFile.builder("com.squareup.tacos",
+ TypeSpec.classBuilder("Taco")
+ .build())
+ .addStaticImport(File.class, "separator");
+
+ builder.staticImports.clear();
+ builder.staticImports.add(File.class.getCanonicalName() + ".separatorChar");
+
+ String source = builder.build().toString();
+
+ assertThat(source).isEqualTo(""
+ + "package com.squareup.tacos;\n"
+ + "\n"
+ + "import static java.io.File.separatorChar;\n"
+ + "\n"
+ + "class Taco {\n"
+ + "}\n");
+ }
+
+ @Test public void alwaysQualifySimple() {
+ String source = JavaFile.builder("com.squareup.tacos",
+ TypeSpec.classBuilder("Taco")
+ .addField(Thread.class, "thread")
+ .alwaysQualify("Thread")
+ .build())
+ .build()
+ .toString();
+ assertThat(source).isEqualTo(""
+ + "package com.squareup.tacos;\n"
+ + "\n"
+ + "class Taco {\n"
+ + " java.lang.Thread thread;\n"
+ + "}\n");
+ }
+
+ @Test public void alwaysQualifySupersedesJavaLangImports() {
+ String source = JavaFile.builder("com.squareup.tacos",
+ TypeSpec.classBuilder("Taco")
+ .addField(Thread.class, "thread")
+ .alwaysQualify("Thread")
+ .build())
+ .skipJavaLangImports(true)
+ .build()
+ .toString();
+ assertThat(source).isEqualTo(""
+ + "package com.squareup.tacos;\n"
+ + "\n"
+ + "class Taco {\n"
+ + " java.lang.Thread thread;\n"
+ + "}\n");
+ }
+
+ @Test public void avoidClashesWithNestedClasses_viaClass() {
+ String source = JavaFile.builder("com.squareup.tacos",
+ TypeSpec.classBuilder("Taco")
+ // These two should get qualified
+ .addField(ClassName.get("other", "NestedTypeA"), "nestedA")
+ .addField(ClassName.get("other", "NestedTypeB"), "nestedB")
+ // This one shouldn't since it's not a nested type of Foo
+ .addField(ClassName.get("other", "NestedTypeC"), "nestedC")
+ // This one shouldn't since we only look at nested types
+ .addField(ClassName.get("other", "Foo"), "foo")
+ .avoidClashesWithNestedClasses(Foo.class)
+ .build())
+ .build()
+ .toString();
+ assertThat(source).isEqualTo(""
+ + "package com.squareup.tacos;\n"
+ + "\n"
+ + "import other.Foo;\n"
+ + "import other.NestedTypeC;\n"
+ + "\n"
+ + "class Taco {\n"
+ + " other.NestedTypeA nestedA;\n"
+ + "\n"
+ + " other.NestedTypeB nestedB;\n"
+ + "\n"
+ + " NestedTypeC nestedC;\n"
+ + "\n"
+ + " Foo foo;\n"
+ + "}\n");
+ }
+
+ @Test public void avoidClashesWithNestedClasses_viaTypeElement() {
+ String source = JavaFile.builder("com.squareup.tacos",
+ TypeSpec.classBuilder("Taco")
+ // These two should get qualified
+ .addField(ClassName.get("other", "NestedTypeA"), "nestedA")
+ .addField(ClassName.get("other", "NestedTypeB"), "nestedB")
+ // This one shouldn't since it's not a nested type of Foo
+ .addField(ClassName.get("other", "NestedTypeC"), "nestedC")
+ // This one shouldn't since we only look at nested types
+ .addField(ClassName.get("other", "Foo"), "foo")
+ .avoidClashesWithNestedClasses(getElement(Foo.class))
+ .build())
+ .build()
+ .toString();
+ assertThat(source).isEqualTo(""
+ + "package com.squareup.tacos;\n"
+ + "\n"
+ + "import other.Foo;\n"
+ + "import other.NestedTypeC;\n"
+ + "\n"
+ + "class Taco {\n"
+ + " other.NestedTypeA nestedA;\n"
+ + "\n"
+ + " other.NestedTypeB nestedB;\n"
+ + "\n"
+ + " NestedTypeC nestedC;\n"
+ + "\n"
+ + " Foo foo;\n"
+ + "}\n");
+ }
+
+ @Test public void avoidClashesWithNestedClasses_viaSuperinterfaceType() {
+ String source = JavaFile.builder("com.squareup.tacos",
+ TypeSpec.classBuilder("Taco")
+ // These two should get qualified
+ .addField(ClassName.get("other", "NestedTypeA"), "nestedA")
+ .addField(ClassName.get("other", "NestedTypeB"), "nestedB")
+ // This one shouldn't since it's not a nested type of Foo
+ .addField(ClassName.get("other", "NestedTypeC"), "nestedC")
+ // This one shouldn't since we only look at nested types
+ .addField(ClassName.get("other", "Foo"), "foo")
+ .addType(TypeSpec.classBuilder("NestedTypeA").build())
+ .addType(TypeSpec.classBuilder("NestedTypeB").build())
+ .addSuperinterface(FooInterface.class)
+ .build())
+ .build()
+ .toString();
+ assertThat(source).isEqualTo("package com.squareup.tacos;\n"
+ + "\n"
+ + "import com.squareup.javapoet.JavaFileTest;\n"
+ + "import other.Foo;\n"
+ + "import other.NestedTypeC;\n"
+ + "\n"
+ + "class Taco implements JavaFileTest.FooInterface {\n"
+ + " other.NestedTypeA nestedA;\n"
+ + "\n"
+ + " other.NestedTypeB nestedB;\n"
+ + "\n"
+ + " NestedTypeC nestedC;\n"
+ + "\n"
+ + " Foo foo;\n"
+ + "\n"
+ + " class NestedTypeA {\n"
+ + " }\n"
+ + "\n"
+ + " class NestedTypeB {\n"
+ + " }\n"
+ + "}\n");
+ }
+
+ static class Foo {
+ static class NestedTypeA {
+
+ }
+ static class NestedTypeB {
+
+ }
+ }
+
+ interface FooInterface {
+ class NestedTypeA {
+
+ }
+ class NestedTypeB {
+
+ }
+ }
+
+ private TypeSpec.Builder childTypeBuilder() {
+ return TypeSpec.classBuilder("Child")
+ .addMethod(MethodSpec.methodBuilder("optionalString")
+ .returns(ParameterizedTypeName.get(Optional.class, String.class))
+ .addStatement("return $T.empty()", Optional.class)
+ .build())
+ .addMethod(MethodSpec.methodBuilder("pattern")
+ .returns(Pattern.class)
+ .addStatement("return null")
+ .build());
+ }
+
+ @Test
+ public void avoidClashes_parentChild_superclass_type() {
+ String source = JavaFile.builder("com.squareup.javapoet",
+ childTypeBuilder().superclass(Parent.class).build())
+ .build()
+ .toString();
+ assertThat(source).isEqualTo("package com.squareup.javapoet;\n"
+ + "\n"
+ + "import java.lang.String;\n"
+ + "\n"
+ + "class Child extends JavaFileTest.Parent {\n"
+ + " java.util.Optional<String> optionalString() {\n"
+ + " return java.util.Optional.empty();\n"
+ + " }\n"
+ + "\n"
+ + " java.util.regex.Pattern pattern() {\n"
+ + " return null;\n"
+ + " }\n"
+ + "}\n");
+ }
+
+ @Test
+ public void avoidClashes_parentChild_superclass_typeMirror() {
+ String source = JavaFile.builder("com.squareup.javapoet",
+ childTypeBuilder().superclass(getElement(Parent.class).asType()).build())
+ .build()
+ .toString();
+ assertThat(source).isEqualTo("package com.squareup.javapoet;\n"
+ + "\n"
+ + "import java.lang.String;\n"
+ + "\n"
+ + "class Child extends JavaFileTest.Parent {\n"
+ + " java.util.Optional<String> optionalString() {\n"
+ + " return java.util.Optional.empty();\n"
+ + " }\n"
+ + "\n"
+ + " java.util.regex.Pattern pattern() {\n"
+ + " return null;\n"
+ + " }\n"
+ + "}\n");
+ }
+
+ @Test
+ public void avoidClashes_parentChild_superinterface_type() {
+ String source = JavaFile.builder("com.squareup.javapoet",
+ childTypeBuilder().addSuperinterface(ParentInterface.class).build())
+ .build()
+ .toString();
+ assertThat(source).isEqualTo("package com.squareup.javapoet;\n"
+ + "\n"
+ + "import java.lang.String;\n"
+ + "import java.util.regex.Pattern;\n"
+ + "\n"
+ + "class Child implements JavaFileTest.ParentInterface {\n"
+ + " java.util.Optional<String> optionalString() {\n"
+ + " return java.util.Optional.empty();\n"
+ + " }\n"
+ + "\n"
+ + " Pattern pattern() {\n"
+ + " return null;\n"
+ + " }\n"
+ + "}\n");
+ }
+
+ @Test
+ public void avoidClashes_parentChild_superinterface_typeMirror() {
+ String source = JavaFile.builder("com.squareup.javapoet",
+ childTypeBuilder().addSuperinterface(getElement(ParentInterface.class).asType()).build())
+ .build()
+ .toString();
+ assertThat(source).isEqualTo("package com.squareup.javapoet;\n"
+ + "\n"
+ + "import java.lang.String;\n"
+ + "import java.util.regex.Pattern;\n"
+ + "\n"
+ + "class Child implements JavaFileTest.ParentInterface {\n"
+ + " java.util.Optional<String> optionalString() {\n"
+ + " return java.util.Optional.empty();\n"
+ + " }\n"
+ + "\n"
+ + " Pattern pattern() {\n"
+ + " return null;\n"
+ + " }\n"
+ + "}\n");
+ }
+
+ // Regression test for https://github.com/square/javapoet/issues/77
+ // This covers class and inheritance
+ static class Parent implements ParentInterface {
+ static class Pattern {
+
+ }
+ }
+
+ interface ParentInterface {
+ class Optional {
+
+ }
+ }
+
+ // Regression test for case raised here: https://github.com/square/javapoet/issues/77#issuecomment-519972404
+ @Test
+ public void avoidClashes_mapEntry() {
+ String source = JavaFile.builder("com.squareup.javapoet",
+ TypeSpec.classBuilder("MapType")
+ .addMethod(MethodSpec.methodBuilder("optionalString")
+ .returns(ClassName.get("com.foo", "Entry"))
+ .addStatement("return null")
+ .build())
+ .addSuperinterface(Map.class)
+ .build())
+ .build()
+ .toString();
+ assertThat(source).isEqualTo("package com.squareup.javapoet;\n"
+ + "\n"
+ + "import java.util.Map;\n"
+ + "\n"
+ + "class MapType implements Map {\n"
+ + " com.foo.Entry optionalString() {\n"
+ + " return null;\n"
+ + " }\n"
+ + "}\n");
+ }
}
diff --git a/src/test/java/com/squareup/javapoet/MethodSpecTest.java b/src/test/java/com/squareup/javapoet/MethodSpecTest.java
index 5dfabaa..b768351 100644
--- a/src/test/java/com/squareup/javapoet/MethodSpecTest.java
+++ b/src/test/java/com/squareup/javapoet/MethodSpecTest.java
@@ -21,8 +21,9 @@ import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.util.Arrays;
-import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeoutException;
import javax.lang.model.element.ExecutableElement;
@@ -37,6 +38,8 @@ import org.junit.Test;
import static com.google.common.collect.Iterables.getOnlyElement;
import static com.google.common.truth.Truth.assertThat;
+import static com.squareup.javapoet.MethodSpec.CONSTRUCTOR;
+import static com.squareup.javapoet.TestUtil.findFirst;
import static javax.lang.model.util.ElementFilter.methodsIn;
import static org.junit.Assert.fail;
@@ -55,15 +58,6 @@ public final class MethodSpecTest {
return elements.getTypeElement(clazz.getCanonicalName());
}
- private ExecutableElement findFirst(Collection<ExecutableElement> elements, String name) {
- for (ExecutableElement executableElement : elements) {
- if (executableElement.getSimpleName().toString().equals(name)) {
- return executableElement;
- }
- }
- throw new IllegalArgumentException(name + " not found in " + elements);
- }
-
@Test public void nullAnnotationsAddition() {
try {
MethodSpec.methodBuilder("doSomething").addAnnotations(null);
@@ -270,6 +264,59 @@ public final class MethodSpecTest {
assertThat(a.hashCode()).isEqualTo(b.hashCode());
}
+ @Test public void withoutParameterJavaDoc() {
+ MethodSpec methodSpec = MethodSpec.methodBuilder("getTaco")
+ .addModifiers(Modifier.PRIVATE)
+ .addParameter(TypeName.DOUBLE, "money")
+ .addJavadoc("Gets the best Taco\n")
+ .build();
+ assertThat(methodSpec.toString()).isEqualTo(""
+ + "/**\n"
+ + " * Gets the best Taco\n"
+ + " */\n"
+ + "private void getTaco(double money) {\n"
+ + "}\n");
+ }
+
+ @Test public void withParameterJavaDoc() {
+ MethodSpec methodSpec = MethodSpec.methodBuilder("getTaco")
+ .addParameter(ParameterSpec.builder(TypeName.DOUBLE, "money")
+ .addJavadoc("the amount required to buy the taco.\n")
+ .build())
+ .addParameter(ParameterSpec.builder(TypeName.INT, "count")
+ .addJavadoc("the number of Tacos to buy.\n")
+ .build())
+ .addJavadoc("Gets the best Taco money can buy.\n")
+ .build();
+ assertThat(methodSpec.toString()).isEqualTo(""
+ + "/**\n"
+ + " * Gets the best Taco money can buy.\n"
+ + " *\n"
+ + " * @param money the amount required to buy the taco.\n"
+ + " * @param count the number of Tacos to buy.\n"
+ + " */\n"
+ + "void getTaco(double money, int count) {\n"
+ + "}\n");
+ }
+
+ @Test public void withParameterJavaDocAndWithoutMethodJavadoc() {
+ MethodSpec methodSpec = MethodSpec.methodBuilder("getTaco")
+ .addParameter(ParameterSpec.builder(TypeName.DOUBLE, "money")
+ .addJavadoc("the amount required to buy the taco.\n")
+ .build())
+ .addParameter(ParameterSpec.builder(TypeName.INT, "count")
+ .addJavadoc("the number of Tacos to buy.\n")
+ .build())
+ .build();
+ assertThat(methodSpec.toString()).isEqualTo(""
+ + "/**\n"
+ + " * @param money the amount required to buy the taco.\n"
+ + " * @param count the number of Tacos to buy.\n"
+ + " */\n"
+ + "void getTaco(double money, int count) {\n"
+ + "}\n");
+ }
+
@Test public void duplicateExceptionsIgnored() {
ClassName ioException = ClassName.get(IOException.class);
ClassName timeoutException = ClassName.get(TimeoutException.class);
@@ -302,4 +349,115 @@ public final class MethodSpecTest {
assertThat(e.getMessage()).isEqualTo("modifiers == null");
}
}
+
+ @Test public void modifyMethodName() {
+ MethodSpec methodSpec = MethodSpec.methodBuilder("initialMethod")
+ .build()
+ .toBuilder()
+ .setName("revisedMethod")
+ .build();
+
+ assertThat(methodSpec.toString()).isEqualTo("" + "void revisedMethod() {\n" + "}\n");
+ }
+
+ @Test public void modifyAnnotations() {
+ MethodSpec.Builder builder = MethodSpec.methodBuilder("foo")
+ .addAnnotation(Override.class)
+ .addAnnotation(SuppressWarnings.class);
+
+ builder.annotations.remove(1);
+ assertThat(builder.build().annotations).hasSize(1);
+ }
+
+ @Test public void modifyModifiers() {
+ MethodSpec.Builder builder = MethodSpec.methodBuilder("foo")
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+
+ builder.modifiers.remove(1);
+ assertThat(builder.build().modifiers).containsExactly(Modifier.PUBLIC);
+ }
+
+ @Test public void modifyParameters() {
+ MethodSpec.Builder builder = MethodSpec.methodBuilder("foo")
+ .addParameter(int.class, "source");
+
+ builder.parameters.remove(0);
+ assertThat(builder.build().parameters).isEmpty();
+ }
+
+ @Test public void modifyTypeVariables() {
+ TypeVariableName t = TypeVariableName.get("T");
+ MethodSpec.Builder builder = MethodSpec.methodBuilder("foo")
+ .addTypeVariable(t)
+ .addTypeVariable(TypeVariableName.get("V"));
+
+ builder.typeVariables.remove(1);
+ assertThat(builder.build().typeVariables).containsExactly(t);
+ }
+
+ @Test public void ensureTrailingNewline() {
+ MethodSpec methodSpec = MethodSpec.methodBuilder("method")
+ .addCode("codeWithNoNewline();")
+ .build();
+
+ assertThat(methodSpec.toString()).isEqualTo(""
+ + "void method() {\n"
+ + " codeWithNoNewline();\n"
+ + "}\n");
+ }
+
+ /** Ensures that we don't add a duplicate newline if one is already present. */
+ @Test public void ensureTrailingNewlineWithExistingNewline() {
+ MethodSpec methodSpec = MethodSpec.methodBuilder("method")
+ .addCode("codeWithNoNewline();\n") // Have a newline already, so ensure we're not adding one
+ .build();
+
+ assertThat(methodSpec.toString()).isEqualTo(""
+ + "void method() {\n"
+ + " codeWithNoNewline();\n"
+ + "}\n");
+ }
+
+ @Test public void controlFlowWithNamedCodeBlocks() {
+ Map<String, Object> m = new HashMap<>();
+ m.put("field", "valueField");
+ m.put("threshold", "5");
+
+ MethodSpec methodSpec = MethodSpec.methodBuilder("method")
+ .beginControlFlow(named("if ($field:N > $threshold:L)", m))
+ .nextControlFlow(named("else if ($field:N == $threshold:L)", m))
+ .endControlFlow()
+ .build();
+
+ assertThat(methodSpec.toString()).isEqualTo(""
+ + "void method() {\n"
+ + " if (valueField > 5) {\n"
+ + " } else if (valueField == 5) {\n"
+ + " }\n"
+ + "}\n");
+ }
+
+ @Test public void doWhileWithNamedCodeBlocks() {
+ Map<String, Object> m = new HashMap<>();
+ m.put("field", "valueField");
+ m.put("threshold", "5");
+
+ MethodSpec methodSpec = MethodSpec.methodBuilder("method")
+ .beginControlFlow("do")
+ .addStatement(named("$field:N--", m))
+ .endControlFlow(named("while ($field:N > $threshold:L)", m))
+ .build();
+
+ assertThat(methodSpec.toString()).isEqualTo(""
+ + "void method() {\n" +
+ " do {\n" +
+ " valueField--;\n" +
+ " } while (valueField > 5);\n" +
+ "}\n");
+ }
+
+ private static CodeBlock named(String format, Map<String, ?> args){
+ return CodeBlock.builder().addNamed(format, args).build();
+ }
+
}
diff --git a/src/test/java/com/squareup/javapoet/NameAllocatorTest.java b/src/test/java/com/squareup/javapoet/NameAllocatorTest.java
index 1840107..71402c6 100644
--- a/src/test/java/com/squareup/javapoet/NameAllocatorTest.java
+++ b/src/test/java/com/squareup/javapoet/NameAllocatorTest.java
@@ -18,9 +18,11 @@ package com.squareup.javapoet;
import org.junit.Test;
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
public final class NameAllocatorTest {
+
@Test public void usage() throws Exception {
NameAllocator nameAllocator = new NameAllocator();
assertThat(nameAllocator.newName("foo", 1)).isEqualTo("foo");
@@ -59,6 +61,7 @@ public final class NameAllocatorTest {
@Test public void characterMappingInvalidStartButValidPart() throws Exception {
NameAllocator nameAllocator = new NameAllocator();
assertThat(nameAllocator.newName("1ab", 1)).isEqualTo("_1ab");
+ assertThat(nameAllocator.newName("a-1", 2)).isEqualTo("a_1");
}
@Test public void characterMappingInvalidStartIsInvalidPart() throws Exception {
diff --git a/src/test/java/com/squareup/javapoet/ParameterSpecTest.java b/src/test/java/com/squareup/javapoet/ParameterSpecTest.java
index 2f81866..c3effca 100644
--- a/src/test/java/com/squareup/javapoet/ParameterSpecTest.java
+++ b/src/test/java/com/squareup/javapoet/ParameterSpecTest.java
@@ -15,23 +15,49 @@
*/
package com.squareup.javapoet;
+import com.google.testing.compile.CompilationRule;
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.Nullable;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.util.Elements;
+import org.junit.Before;
+import org.junit.Rule;
+import javax.lang.model.element.Modifier;
import org.junit.Test;
import static com.google.common.truth.Truth.assertThat;
+import static com.squareup.javapoet.TestUtil.findFirst;
+import static javax.lang.model.util.ElementFilter.fieldsIn;
+import static javax.lang.model.util.ElementFilter.methodsIn;
import static org.junit.Assert.fail;
-import javax.lang.model.element.Modifier;
-
public class ParameterSpecTest {
+ @Rule public final CompilationRule compilation = new CompilationRule();
+
+ private Elements elements;
+
+ @Before public void setUp() {
+ elements = compilation.getElements();
+ }
+
+ private TypeElement getElement(Class<?> clazz) {
+ return elements.getTypeElement(clazz.getCanonicalName());
+ }
+
@Test public void equalsAndHashCode() {
ParameterSpec a = ParameterSpec.builder(int.class, "foo").build();
ParameterSpec b = ParameterSpec.builder(int.class, "foo").build();
assertThat(a.equals(b)).isTrue();
assertThat(a.hashCode()).isEqualTo(b.hashCode());
+ assertThat(a.toString()).isEqualTo(b.toString());
a = ParameterSpec.builder(int.class, "i").addModifiers(Modifier.STATIC).build();
b = ParameterSpec.builder(int.class, "i").addModifiers(Modifier.STATIC).build();
assertThat(a.equals(b)).isTrue();
assertThat(a.hashCode()).isEqualTo(b.hashCode());
+ assertThat(a.toString()).isEqualTo(b.toString());
}
@Test public void nullAnnotationsAddition() {
@@ -43,4 +69,67 @@ public class ParameterSpecTest {
.isEqualTo("annotationSpecs == null");
}
}
-} \ No newline at end of file
+
+ final class VariableElementFieldClass {
+ String name;
+ }
+
+ @Test public void fieldVariableElement() {
+ TypeElement classElement = getElement(VariableElementFieldClass.class);
+ List<VariableElement> methods = fieldsIn(elements.getAllMembers(classElement));
+ VariableElement element = findFirst(methods, "name");
+
+ try {
+ ParameterSpec.get(element);
+ fail();
+ } catch (IllegalArgumentException exception) {
+ assertThat(exception).hasMessageThat().isEqualTo("element is not a parameter");
+ }
+ }
+
+ final class VariableElementParameterClass {
+ public void foo(@Nullable final String bar) {
+ }
+ }
+
+ @Test public void parameterVariableElement() {
+ TypeElement classElement = getElement(VariableElementParameterClass.class);
+ List<ExecutableElement> methods = methodsIn(elements.getAllMembers(classElement));
+ ExecutableElement element = findFirst(methods, "foo");
+ VariableElement parameterElement = element.getParameters().get(0);
+
+ assertThat(ParameterSpec.get(parameterElement).toString())
+ .isEqualTo("@javax.annotation.Nullable java.lang.String arg0");
+ }
+
+ @Test public void addNonFinalModifier() {
+ List<Modifier> modifiers = new ArrayList<>();
+ modifiers.add(Modifier.FINAL);
+ modifiers.add(Modifier.PUBLIC);
+
+ try {
+ ParameterSpec.builder(int.class, "foo")
+ .addModifiers(modifiers);
+ fail();
+ } catch (Exception e) {
+ assertThat(e.getMessage()).isEqualTo("unexpected parameter modifier: public");
+ }
+ }
+
+ @Test public void modifyAnnotations() {
+ ParameterSpec.Builder builder = ParameterSpec.builder(int.class, "foo")
+ .addAnnotation(Override.class)
+ .addAnnotation(SuppressWarnings.class);
+
+ builder.annotations.remove(1);
+ assertThat(builder.build().annotations).hasSize(1);
+ }
+
+ @Test public void modifyModifiers() {
+ ParameterSpec.Builder builder = ParameterSpec.builder(int.class, "foo")
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+
+ builder.modifiers.remove(1);
+ assertThat(builder.build().modifiers).containsExactly(Modifier.PUBLIC);
+ }
+}
diff --git a/src/test/java/com/squareup/javapoet/TestUtil.java b/src/test/java/com/squareup/javapoet/TestUtil.java
new file mode 100644
index 0000000..f773d50
--- /dev/null
+++ b/src/test/java/com/squareup/javapoet/TestUtil.java
@@ -0,0 +1,17 @@
+package com.squareup.javapoet;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.VariableElement;
+import java.util.Collection;
+
+final class TestUtil {
+ static <E extends Element> E findFirst(Collection<E> elements, String name) {
+ for (E element : elements) {
+ if (element.getSimpleName().toString().equals(name)) {
+ return element;
+ }
+ }
+ throw new IllegalArgumentException(name + " not found in " + elements);
+ }
+}
diff --git a/src/test/java/com/squareup/javapoet/TypeSpecTest.java b/src/test/java/com/squareup/javapoet/TypeSpecTest.java
index 9cd22c2..0f67c5c 100644
--- a/src/test/java/com/squareup/javapoet/TypeSpecTest.java
+++ b/src/test/java/com/squareup/javapoet/TypeSpecTest.java
@@ -17,6 +17,7 @@ package com.squareup.javapoet;
import com.google.common.collect.ImmutableMap;
import com.google.testing.compile.CompilationRule;
+import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.math.BigDecimal;
@@ -985,6 +986,74 @@ public final class TypeSpecTest {
+ "}\n");
}
+ @Test public void simpleNameConflictsWithTypeVariable() {
+ ClassName inPackage = ClassName.get("com.squareup.tacos", "InPackage");
+ ClassName otherType = ClassName.get("com.other", "OtherType");
+ ClassName methodInPackage = ClassName.get("com.squareup.tacos", "MethodInPackage");
+ ClassName methodOtherType = ClassName.get("com.other", "MethodOtherType");
+ TypeSpec gen = TypeSpec.classBuilder("Gen")
+ .addTypeVariable(TypeVariableName.get("InPackage"))
+ .addTypeVariable(TypeVariableName.get("OtherType"))
+ .addField(FieldSpec.builder(inPackage, "inPackage").build())
+ .addField(FieldSpec.builder(otherType, "otherType").build())
+ .addMethod(MethodSpec.methodBuilder("withTypeVariables")
+ .addTypeVariable(TypeVariableName.get("MethodInPackage"))
+ .addTypeVariable(TypeVariableName.get("MethodOtherType"))
+ .addStatement("$T inPackage = null", methodInPackage)
+ .addStatement("$T otherType = null", methodOtherType)
+ .build())
+ .addMethod(MethodSpec.methodBuilder("withoutTypeVariables")
+ .addStatement("$T inPackage = null", methodInPackage)
+ .addStatement("$T otherType = null", methodOtherType)
+ .build())
+ .addMethod(MethodSpec.methodBuilder("againWithTypeVariables")
+ .addTypeVariable(TypeVariableName.get("MethodInPackage"))
+ .addTypeVariable(TypeVariableName.get("MethodOtherType"))
+ .addStatement("$T inPackage = null", methodInPackage)
+ .addStatement("$T otherType = null", methodOtherType)
+ .build())
+ // https://github.com/square/javapoet/pull/657#discussion_r205514292
+ .addMethod(MethodSpec.methodBuilder("masksEnclosingTypeVariable")
+ .addTypeVariable(TypeVariableName.get("InPackage"))
+ .build())
+ .addMethod(MethodSpec.methodBuilder("hasSimpleNameThatWasPreviouslyMasked")
+ .addStatement("$T inPackage = null", inPackage)
+ .build())
+ .build();
+ assertThat(toString(gen)).isEqualTo(""
+ + "package com.squareup.tacos;\n"
+ + "\n"
+ + "import com.other.MethodOtherType;\n"
+ + "\n"
+ + "class Gen<InPackage, OtherType> {\n"
+ + " com.squareup.tacos.InPackage inPackage;\n"
+ + "\n"
+ + " com.other.OtherType otherType;\n"
+ + "\n"
+ + " <MethodInPackage, MethodOtherType> void withTypeVariables() {\n"
+ + " com.squareup.tacos.MethodInPackage inPackage = null;\n"
+ + " com.other.MethodOtherType otherType = null;\n"
+ + " }\n"
+ + "\n"
+ + " void withoutTypeVariables() {\n"
+ + " MethodInPackage inPackage = null;\n"
+ + " MethodOtherType otherType = null;\n"
+ + " }\n"
+ + "\n"
+ + " <MethodInPackage, MethodOtherType> void againWithTypeVariables() {\n"
+ + " com.squareup.tacos.MethodInPackage inPackage = null;\n"
+ + " com.other.MethodOtherType otherType = null;\n"
+ + " }\n"
+ + "\n"
+ + " <InPackage> void masksEnclosingTypeVariable() {\n"
+ + " }\n"
+ + "\n"
+ + " void hasSimpleNameThatWasPreviouslyMasked() {\n"
+ + " com.squareup.tacos.InPackage inPackage = null;\n"
+ + " }\n"
+ + "}\n");
+ }
+
@Test public void originatingElementsIncludesThoseOfNestedTypes() {
Element outerElement = Mockito.mock(Element.class);
Element innerElement = Mockito.mock(Element.class);
@@ -1780,7 +1849,8 @@ public final class TypeSpecTest {
+ " }\n"
+ "\n"
+ " /**\n"
- + " * chosen by fair dice roll ;) */\n"
+ + " * chosen by fair dice roll ;)\n"
+ + " */\n"
+ " public int getRandomQuantity() {\n"
+ " return 4;\n"
+ " }\n"
@@ -1839,7 +1909,7 @@ public final class TypeSpecTest {
@Test public void nullModifiersAddition() {
try {
- TypeSpec.classBuilder("Taco").addModifiers((Modifier) null);
+ TypeSpec.classBuilder("Taco").addModifiers((Modifier) null).build();
fail();
} catch(IllegalArgumentException expected) {
assertThat(expected.getMessage())
@@ -2196,6 +2266,7 @@ public final class TypeSpecTest {
@Test public void initializersToBuilder() {
// Tests if toBuilder() contains correct static and instance initializers
+ Element originatingElement = getElement(TypeSpecTest.class);
TypeSpec taco = TypeSpec.classBuilder("Taco")
.addField(String.class, "foo", Modifier.PRIVATE)
.addField(String.class, "FOO", Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
@@ -2212,10 +2283,16 @@ public final class TypeSpecTest {
.addInitializerBlock(CodeBlock.builder()
.addStatement("foo = $S", "FOO")
.build())
+ .addOriginatingElement(originatingElement)
+ .alwaysQualify("com.example.AlwaysQualified")
.build();
TypeSpec recreatedTaco = taco.toBuilder().build();
assertThat(toString(taco)).isEqualTo(toString(recreatedTaco));
+ assertThat(taco.originatingElements)
+ .containsExactlyElementsIn(recreatedTaco.originatingElements);
+ assertThat(taco.alwaysQualifiedNames)
+ .containsExactlyElementsIn(recreatedTaco.alwaysQualifiedNames);
TypeSpec initializersAdded = taco.toBuilder()
.addInitializerBlock(CodeBlock.builder()
@@ -2356,4 +2433,122 @@ public final class TypeSpecTest {
assertThat(TypeSpec.enumBuilder(className).addEnumConstant("A").build().name).isEqualTo("Example");
assertThat(TypeSpec.annotationBuilder(className).build().name).isEqualTo("Example");
}
+
+ @Test
+ public void modifyAnnotations() {
+ TypeSpec.Builder builder =
+ TypeSpec.classBuilder("Taco")
+ .addAnnotation(Override.class)
+ .addAnnotation(SuppressWarnings.class);
+
+ builder.annotations.remove(1);
+ assertThat(builder.build().annotations).hasSize(1);
+ }
+
+ @Test
+ public void modifyModifiers() {
+ TypeSpec.Builder builder =
+ TypeSpec.classBuilder("Taco").addModifiers(Modifier.PUBLIC, Modifier.FINAL);
+
+ builder.modifiers.remove(1);
+ assertThat(builder.build().modifiers).containsExactly(Modifier.PUBLIC);
+ }
+
+ @Test
+ public void modifyFields() {
+ TypeSpec.Builder builder = TypeSpec.classBuilder("Taco")
+ .addField(int.class, "source");
+
+ builder.fieldSpecs.remove(0);
+ assertThat(builder.build().fieldSpecs).isEmpty();
+ }
+
+ @Test
+ public void modifyTypeVariables() {
+ TypeVariableName t = TypeVariableName.get("T");
+ TypeSpec.Builder builder =
+ TypeSpec.classBuilder("Taco")
+ .addTypeVariable(t)
+ .addTypeVariable(TypeVariableName.get("V"));
+
+ builder.typeVariables.remove(1);
+ assertThat(builder.build().typeVariables).containsExactly(t);
+ }
+
+ @Test
+ public void modifySuperinterfaces() {
+ TypeSpec.Builder builder = TypeSpec.classBuilder("Taco")
+ .addSuperinterface(File.class);
+
+ builder.superinterfaces.clear();
+ assertThat(builder.build().superinterfaces).isEmpty();
+ }
+
+ @Test
+ public void modifyMethods() {
+ TypeSpec.Builder builder = TypeSpec.classBuilder("Taco")
+ .addMethod(MethodSpec.methodBuilder("bell").build());
+
+ builder.methodSpecs.clear();
+ assertThat(builder.build().methodSpecs).isEmpty();
+ }
+
+ @Test
+ public void modifyTypes() {
+ TypeSpec.Builder builder = TypeSpec.classBuilder("Taco")
+ .addType(TypeSpec.classBuilder("Bell").build());
+
+ builder.typeSpecs.clear();
+ assertThat(builder.build().typeSpecs).isEmpty();
+ }
+
+ @Test
+ public void modifyEnumConstants() {
+ TypeSpec constantType = TypeSpec.anonymousClassBuilder("").build();
+ TypeSpec.Builder builder = TypeSpec.enumBuilder("Taco")
+ .addEnumConstant("BELL", constantType)
+ .addEnumConstant("WUT", TypeSpec.anonymousClassBuilder("").build());
+
+ builder.enumConstants.remove("WUT");
+ assertThat(builder.build().enumConstants).containsExactly("BELL", constantType);
+ }
+
+ @Test
+ public void modifyOriginatingElements() {
+ TypeSpec.Builder builder = TypeSpec.classBuilder("Taco")
+ .addOriginatingElement(Mockito.mock(Element.class));
+
+ builder.originatingElements.clear();
+ assertThat(builder.build().originatingElements).isEmpty();
+ }
+
+ @Test public void javadocWithTrailingLineDoesNotAddAnother() {
+ TypeSpec spec = TypeSpec.classBuilder("Taco")
+ .addJavadoc("Some doc with a newline\n")
+ .build();
+
+ assertThat(toString(spec)).isEqualTo(""
+ + "package com.squareup.tacos;\n"
+ + "\n"
+ + "/**\n"
+ + " * Some doc with a newline\n"
+ + " */\n"
+ + "class Taco {\n"
+ + "}\n");
+ }
+
+ @Test public void javadocEnsuresTrailingLine() {
+ TypeSpec spec = TypeSpec.classBuilder("Taco")
+ .addJavadoc("Some doc with a newline")
+ .build();
+
+ assertThat(toString(spec)).isEqualTo(""
+ + "package com.squareup.tacos;\n"
+ + "\n"
+ + "/**\n"
+ + " * Some doc with a newline\n"
+ + " */\n"
+ + "class Taco {\n"
+ + "}\n");
+ }
}