Skip to content

Commit

Permalink
fix: do not override fields already set through constructor in build …
Browse files Browse the repository at this point in the history
…method
  • Loading branch information
jonas-grgt committed Apr 11, 2024
1 parent 81726b5 commit 04ad195
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 12 deletions.
17 changes: 5 additions & 12 deletions processor/src/main/java/io/jonasg/bob/TypeSpecFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -138,18 +138,11 @@ private MethodSpec generateBuildMethod() {
private void createConstructorAndSetterAwareBuildMethod(Builder builder) {
builder.addStatement("var instance = new $T($L)", className(this.typeDefinition),
this.toConstructorCallingStatement(this.constructorDefinition));
typeDefinition.getSetterMethods()
.forEach(method -> {
String fieldName;
if (method.methodName().startsWith("set")) {
fieldName = method.methodName().substring(3, 4).toLowerCase()
+ method.methodName().substring(4);
builder.addStatement("instance.%s(this.%s)".formatted(method.methodName(), fieldName));
} else {
fieldName = method.methodName();
builder.addStatement("instance.%s(this.%s)".formatted(setterName(fieldName), fieldName));
}
});
this.buildableFields.stream()
.filter(field -> !field.isConstructorArgument() && field.setterMethodName().isPresent())
.forEach(field -> builder
.addStatement("instance.%s(this.%s)".formatted(setterName(field.setterMethodName().get()),
field.fieldName())));
builder.addStatement("return instance");
}

Expand Down
20 changes: 20 additions & 0 deletions processor/src/test/java/io/jonasg/bob/BobFeaturesTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -238,4 +238,24 @@ void allPublicSettersThatHaveCorrespondingFieldsAreBuildable() {
.executeTest();
}

@Test
void allPublicSettersExceptThoseUsedInConstructorAreBuildable() {
Cute.blackBoxTest()
.given()
.processors(List.of(BuildableProcessor.class))
.andSourceFiles(
"/tests/successful-compilation/AllPublicSettersExceptThoseUsedInConstructorAreBuildable/AllPublicSettersExceptThoseUsedInConstructorAreBuildable.java")
.whenCompiled()
.thenExpectThat()
.compilationSucceeds()
.andThat()
.generatedSourceFile(
"io.jonasg.bob.test.builder.AllPublicSettersExceptThoseUsedInConstructorAreBuildableBuilder")
.matches(
CuteApi.ExpectedFileObjectMatcherKind.BINARY,
JavaFileObjectUtils.readFromResource(
"/tests/successful-compilation/AllPublicSettersExceptThoseUsedInConstructorAreBuildable/Expected_AllPublicSettersExceptThoseUsedInConstructorAreBuildable.java"))
.executeTest();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package io.jonasg.bob.test;

import io.jonasg.bob.Buildable;

@Buildable
public class AllPublicSettersExceptThoseUsedInConstructorAreBuildable {
private String make;

private int year;

private double engineSize;

private boolean isElectric;

private float fuelEfficiency;

public AllPublicSettersExceptThoseUsedInConstructorAreBuildable() {
}

public AllPublicSettersExceptThoseUsedInConstructorAreBuildable(String make, int year) {
this.make = make;
this.year = year;
}

public AllPublicSettersExceptThoseUsedInConstructorAreBuildable setEngineSize(double engineSize) {
this.engineSize = engineSize;
return this;
}

public AllPublicSettersExceptThoseUsedInConstructorAreBuildable setIsElectric(boolean isElectric) {
isElectric = isElectric;
return this;
}

public AllPublicSettersExceptThoseUsedInConstructorAreBuildable setFuelEfficiency(float fuelEfficiency) {
this.fuelEfficiency = fuelEfficiency;
return this;
}

public AllPublicSettersExceptThoseUsedInConstructorAreBuildable setMake(String make) {
this.make = make;
return this;
}

public AllPublicSettersExceptThoseUsedInConstructorAreBuildable setYear(int year) {
this.year = year;
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package io.jonasg.bob.test.builder;

import io.jonasg.bob.test.AllPublicSettersExceptThoseUsedInConstructorAreBuildable;
import java.lang.String;

public final class AllPublicSettersExceptThoseUsedInConstructorAreBuildableBuilder {
private String make;

private int year;

private double engineSize;

private boolean isElectric;

private float fuelEfficiency;

public AllPublicSettersExceptThoseUsedInConstructorAreBuildableBuilder() {
}

public AllPublicSettersExceptThoseUsedInConstructorAreBuildableBuilder make(String make) {
this.make = make;
return this;
}

public AllPublicSettersExceptThoseUsedInConstructorAreBuildableBuilder year(int year) {
this.year = year;
return this;
}

public AllPublicSettersExceptThoseUsedInConstructorAreBuildableBuilder engineSize(
double engineSize) {
this.engineSize = engineSize;
return this;
}

public AllPublicSettersExceptThoseUsedInConstructorAreBuildableBuilder isElectric(
boolean isElectric) {
this.isElectric = isElectric;
return this;
}

public AllPublicSettersExceptThoseUsedInConstructorAreBuildableBuilder fuelEfficiency(
float fuelEfficiency) {
this.fuelEfficiency = fuelEfficiency;
return this;
}

public AllPublicSettersExceptThoseUsedInConstructorAreBuildable build() {
var instance = new AllPublicSettersExceptThoseUsedInConstructorAreBuildable(make, year);
instance.setEngineSize(this.engineSize);
instance.setIsElectric(this.isElectric);
instance.setFuelEfficiency(this.fuelEfficiency);
return instance;
}
}

0 comments on commit 04ad195

Please sign in to comment.