blob: 50b6b2713e92b0a585372fac6a8bd27f1a168de9 [file] [log] [blame]
/*
* Copyright 2021 Google LLC
*
* 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.google.auto.value.processor;
import static com.google.common.base.StandardSystemProperty.JAVA_SPECIFICATION_VERSION;
import static com.google.common.truth.TruthJUnit.assume;
import static com.google.testing.compile.CompilationSubject.assertThat;
import static com.google.testing.compile.Compiler.javac;
import com.google.testing.compile.Compilation;
import com.google.testing.compile.JavaFileObjects;
import javax.tools.JavaFileObject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public final class AutoBuilderCompilationTest {
private static final JavaFileObject EXPECTED_SIMPLE_OUTPUT =
JavaFileObjects.forSourceLines(
"foo.bar.AutoBuilder_Baz_Builder",
"package foo.bar;",
"",
GeneratedImport.importGeneratedAnnotationType(),
"",
"@Generated(\"" + AutoBuilderProcessor.class.getName() + "\")",
"class AutoBuilder_Baz_Builder implements Baz.Builder {",
" private Integer anInt;",
" private String aString;",
"",
" AutoBuilder_Baz_Builder() {}",
"",
" @Override public Baz.Builder setAnInt(int anInt) {",
" this.anInt = anInt;",
" return this;",
" }",
"",
" @Override public Baz.Builder setAString(String aString) {",
" if (aString == null) {",
" throw new NullPointerException(\"Null aString\");",
" }",
" this.aString = aString;",
" return this;",
" }",
"",
" @Override",
" public Baz build() {",
" if (this.anInt == null",
" || this.aString == null) {",
" StringBuilder missing = new StringBuilder();",
" if (this.anInt == null) {",
" missing.append(\" anInt\");",
" }",
" if (this.aString == null) {",
" missing.append(\" aString\");",
" }",
" throw new IllegalStateException(\"Missing required properties:\" + missing);",
" }",
" return new Baz(",
" this.anInt,",
" this.aString);",
" }",
"}");
@Test
public void simpleSuccess() {
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"",
"public class Baz {",
" private final int anInt;",
" private final String aString;",
"",
" public Baz(int anInt, String aString) {",
" this.anInt = anInt;",
" this.aString = aString;",
" }",
"",
" public int anInt() {",
" return anInt;",
" }",
"",
" public String aString() {",
" return aString;",
" }",
"",
" public static Builder builder() {",
" return new AutoBuilder_Baz_Builder();",
" }",
"",
" @AutoBuilder",
" public interface Builder {",
" Builder setAnInt(int x);",
" Builder setAString(String x);",
" Baz build();",
" }",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject);
assertThat(compilation)
.generatedSourceFile("foo.bar.AutoBuilder_Baz_Builder")
.hasSourceEquivalentTo(EXPECTED_SIMPLE_OUTPUT);
}
@Test
public void simpleRecord() {
double version = Double.parseDouble(JAVA_SPECIFICATION_VERSION.value());
assume().that(version).isAtLeast(16.0);
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"",
"public record Baz(int anInt, String aString) {",
" public static Builder builder() {",
" return new AutoBuilder_Baz_Builder();",
" }",
"",
" @AutoBuilder",
" public interface Builder {",
" Builder setAnInt(int x);",
" Builder setAString(String x);",
" Baz build();",
" }",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject);
assertThat(compilation)
.generatedSourceFile("foo.bar.AutoBuilder_Baz_Builder")
.hasSourceEquivalentTo(EXPECTED_SIMPLE_OUTPUT);
}
@Test
public void buildOtherPackage() {
JavaFileObject built =
JavaFileObjects.forSourceLines(
"com.example.Built",
"package com.example;",
"",
"public class Built {",
" private final int anInt;",
" private final String aString;",
"",
" public Built(int anInt, String aString) {",
" this.anInt = anInt;",
" this.aString = aString;",
" }",
"}");
JavaFileObject builder =
JavaFileObjects.forSourceLines(
"foo.bar.Builder",
"package foo.bar;",
"",
"import com.example.Built;",
"import com.google.auto.value.AutoBuilder;",
"",
"@AutoBuilder(ofClass = Built.class)",
"public interface Builder {",
" public static Builder builder() {",
" return new AutoBuilder_Builder();",
" }",
"",
" Builder setAnInt(int x);",
" Builder setAString(String x);",
" Built build();",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(built, builder);
assertThat(compilation).succeededWithoutWarnings();
assertThat(compilation).generatedSourceFile("foo.bar.AutoBuilder_Builder");
}
@Test
public void autoBuilderOnEnum() {
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"",
"@AutoBuilder",
"public enum Baz {",
" ZIG, ZAG, DUSTIN,",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining(
"[AutoBuilderWrongType] @AutoBuilder only applies to classes and interfaces")
.inFile(javaFileObject)
.onLineContaining("enum Baz");
}
@Test
public void autoBuilderPrivate() {
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"",
"public class Baz {",
" @AutoBuilder",
" private interface Builder {",
" Baz build();",
" }",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining("[AutoBuilderPrivate] @AutoBuilder class must not be private")
.inFile(javaFileObject)
.onLineContaining("interface Builder");
}
@Test
public void autoBuilderNestedInPrivate() {
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"",
"public class Baz {",
" private static class Private {",
" @AutoBuilder",
" public interface Builder {",
" Baz build();",
" }",
" }",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining(
"[AutoBuilderInPrivate] @AutoBuilder class must not be nested in a private class")
.inFile(javaFileObject)
.onLineContaining("interface Builder");
}
@Test
public void autoBuilderInner() {
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"",
"public class Baz {",
" @AutoBuilder",
" abstract class Builder {",
" abstract Baz build();",
" }",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining("[AutoBuilderInner] Nested @AutoBuilder class must be static")
.inFile(javaFileObject)
.onLineContaining("class Builder");
}
@Test
public void innerConstructor() {
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"",
"public class Baz {",
" class Inner {}",
"",
" @AutoBuilder(ofClass = Inner.class)",
" interface Builder {",
" abstract Inner build();",
" }",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining("[AutoBuilderInner] Nested @AutoBuilder ofClass class must be static")
.inFile(javaFileObject)
.onLineContaining("interface Builder");
}
@Test
public void noVisibleConstructor() {
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"",
"public class Baz {",
" @AutoBuilder(ofClass = System.class)",
" interface Builder {",
" abstract System build();",
" }",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining("[AutoBuilderNoVisible] No visible constructor for java.lang.System")
.inFile(javaFileObject)
.onLineContaining("interface Builder");
}
@Test
public void noVisibleMethod() {
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"",
"public class Baz {",
" private static Baz of() {",
" return new Baz();",
" }",
"",
" @AutoBuilder(callMethod = \"of\")",
" interface Builder {",
" abstract Baz build();",
" }",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining(
"[AutoBuilderNoVisible] No visible static method named \"of\" for foo.bar.Baz")
.inFile(javaFileObject)
.onLineContaining("interface Builder");
}
@Test
public void methodNotStatic() {
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"",
"public class Baz {",
" Baz of() {",
" return this;",
" }",
"",
" @AutoBuilder(callMethod = \"of\")",
" interface Builder {",
" abstract Baz build();",
" }",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining(
"[AutoBuilderNoVisible] No visible static method named \"of\" for foo.bar.Baz")
.inFile(javaFileObject)
.onLineContaining("interface Builder");
}
@Test
public void noMatchingConstructor() {
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"",
"public class Baz {",
" public Baz(int notMe) {}",
"",
" public Baz(String notMeEither) {}",
"",
" @AutoBuilder",
" interface Builder {",
" Builder setBuh(String x);",
" abstract Baz build();",
" }",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining(
"[AutoBuilderNoMatch] Property names do not correspond to the parameter names of any"
+ " constructor:\n"
+ " Baz(int notMe)\n"
+ " Baz(java.lang.String notMeEither)")
.inFile(javaFileObject)
.onLineContaining("interface Builder");
}
@Test
public void twoMatchingConstructors() {
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"",
"public class Baz {",
" public Baz() {}",
"",
" public Baz(int buh) {}",
"",
" public Baz(String buh) {}",
"",
" @AutoBuilder",
" interface Builder {",
" Builder setBuh(String x);",
" abstract Baz build();",
" }",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining(
"[AutoBuilderAmbiguous] Property names correspond to more than one constructor:\n"
+ " Baz(int buh)\n"
+ " Baz(java.lang.String buh)")
.inFile(javaFileObject)
.onLineContaining("interface Builder");
}
@Test
public void constructInterface() {
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"",
"public interface Baz {",
" @AutoBuilder",
" interface Builder {",
" abstract Baz build();",
" }",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining(
"[AutoBuilderEnclosing] @AutoBuilder must specify ofClass=Something.class or it must"
+ " be nested inside the class to be built; actually nested inside interface"
+ " foo.bar.Baz")
.inFile(javaFileObject)
.onLineContaining("interface Builder");
}
@Test
public void inconsistentSetPrefix() {
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"",
"class Baz {",
" Baz(int one, int two) {}",
"",
" @AutoBuilder",
" interface Builder {",
" abstract Builder one(int x);",
" abstract Builder setTwo(int x);",
" abstract Baz build();",
" }",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining(
"[AutoBuilderSetNotSet] If any setter methods use the setFoo convention then all must")
.inFile(javaFileObject)
.onLineContaining("Builder one(int x)");
}
@Test
public void missingSetter() {
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"",
"class Baz {",
" Baz(int one, int two) {}",
"",
" @AutoBuilder",
" interface Builder {",
" abstract Builder one(int x);",
" abstract Baz build();",
" }",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining(
"[AutoBuilderBuilderMissingMethod] Expected a method with this signature:"
+ " foo.bar.Baz.Builder two(int), or a twoBuilder() method")
.inFile(javaFileObject)
.onLineContaining("interface Builder");
}
@Test
public void tooManyArgs() {
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"",
"class Baz {",
" Baz(int one, int two) {}",
"",
" @AutoBuilder",
" interface Builder {",
" abstract Builder one(int x);",
" abstract Builder two(int x);",
" abstract Builder many(int x, int y);",
" abstract Baz build();",
" }",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining("[AutoBuilderBuilderArgs] Builder methods must have 0 or 1 parameters")
.inFile(javaFileObject)
.onLineContaining("many(int x, int y)");
}
@Test
public void alienNoArgMethod() {
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"",
"class Baz {",
" Baz(int one, int two) {}",
"",
" @AutoBuilder",
" interface Builder {",
" abstract Builder one(int x);",
" abstract Builder two(int x);",
" abstract String alien();",
" abstract Baz build();",
" }",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining(
"[AutoBuilderBuilderNoArg] Method without arguments should be a build method returning"
+ " foo.bar.Baz, or a getter method with the same name and type as a parameter of"
+ " Baz(int one, int two), or fooBuilder() where foo is a parameter of Baz(int"
+ " one, int two)")
.inFile(javaFileObject)
.onLineContaining("String alien()");
}
@Test
public void alienOneArgMethod() {
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"",
"class Baz {",
" Baz(int one, int two) {}",
"",
" @AutoBuilder",
" interface Builder {",
" abstract Builder one(int x);",
" abstract Builder two(int x);",
" abstract Builder three(int x);",
" abstract Baz build();",
" }",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining(
"[AutoBuilderBuilderWhatProp] Method three does not correspond to "
+ "a parameter of Baz(int one, int two)")
.inFile(javaFileObject)
.onLineContaining("three(int x)");
}
@Test
public void setterReturnType() {
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"",
"class Baz {",
" Baz(int one, int two) {}",
"",
" @AutoBuilder",
" interface Builder {",
" abstract Builder one(int x);",
" abstract void two(int x);",
" abstract Baz build();",
" }",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining(
"[AutoBuilderBuilderRet] Setter methods must return foo.bar.Baz.Builder")
.inFile(javaFileObject)
.onLineContaining("two(int x)");
}
@Test
public void nullableSetterForNonNullableParameter() {
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"import org.checkerframework.checker.nullness.qual.Nullable;",
"",
"class Baz {",
" Baz(String thing) {}",
"",
" @AutoBuilder",
" interface Builder {",
" abstract Builder thing(@Nullable String x);",
" abstract Baz build();",
" }",
"}");
JavaFileObject nullableFileObject =
JavaFileObjects.forSourceLines(
"org.checkerframework.checker.nullness.qual.Nullable",
"package org.jspecify.nullness;",
"",
"import java.lang.annotation.ElementType;",
"import java.lang.annotation.Target;",
"",
"@Target(ElementType.TYPE_USE)",
"public @interface Nullable {}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject, nullableFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining(
"[AutoBuilderNullNotNull] Parameter of setter method is @Nullable but parameter"
+ " \"thing\" of Baz(java.lang.String thing) is not")
.inFile(javaFileObject)
.onLineContaining("thing(@Nullable String x)");
}
@Test
public void setterWrongType() {
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"",
"class Baz {",
" Baz(int up, int down) {}",
"",
" @AutoBuilder",
" interface Builder {",
" abstract Builder up(int x);",
" abstract Builder down(String x);",
" abstract Baz build();",
" }",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining(
"[AutoBuilderGetVsSet] Parameter type java.lang.String of setter method should be int"
+ " to match parameter \"down\" of Baz(int up, int down)")
.inFile(javaFileObject)
.onLineContaining("down(String x)");
}
@Test
public void setterWrongTypeEvenWithConversion() {
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"import java.util.Optional;",
"",
"class Baz {",
" Baz(Optional<String> maybe) {}",
"",
" @AutoBuilder",
" interface Builder {",
" abstract Builder maybe(int x);",
" abstract Baz build();",
" }",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining(
"[AutoBuilderGetVsSetOrConvert] Parameter type int of setter method should be"
+ " java.util.Optional<java.lang.String> to match parameter \"maybe\" of"
+ " Baz(java.util.Optional<java.lang.String> maybe), or it should be a type that"
+ " can be passed to Optional.of to produce java.util.Optional<java.lang.String>")
.inFile(javaFileObject)
.onLineContaining("maybe(int x)");
}
@Test
public void typeParamMismatch() {
JavaFileObject javaFileObject =
JavaFileObjects.forSourceLines(
"foo.bar.Baz",
"package foo.bar;",
"",
"import com.google.auto.value.AutoBuilder;",
"import java.util.Optional;",
"",
"class Baz<T> {",
" Baz(T param) {}",
"",
" @AutoBuilder",
" interface Builder<E> {",
" abstract Builder<E> param(E param);",
" abstract Baz<E> build();",
" }",
"}");
Compilation compilation =
javac()
.withProcessors(new AutoBuilderProcessor())
.withOptions("-Acom.google.auto.value.AutoBuilderIsUnstable")
.compile(javaFileObject);
assertThat(compilation).failed();
assertThat(compilation)
.hadErrorContaining(
"[AutoBuilderTypeParams] Builder type parameters <E> must match type parameters <T> of"
+ " Baz(T param)")
.inFile(javaFileObject)
.onLineContaining("interface Builder<E>");
}
}