From 2ebd2604f2ffa61a98f7103921f4108df7fde733 Mon Sep 17 00:00:00 2001 From: JonasG Date: Wed, 24 Apr 2024 16:55:20 +0200 Subject: [PATCH] fix: allow Step Builder to have a custom setter prefix --- .../io/jonasg/bob/BuilderTypeSpecFactory.java | 4 +- .../StepBuilderInterfaceTypeSpecFactory.java | 14 ++++-- .../java/io/jonasg/bob/StrategyTests.java | 27 ++++++++++ ..._DefaultSetterWithCustomPrefixBuilder.java | 50 +++++++++++++++++++ ...xpected_SetterWithCustomPrefixBuilder.java | 27 ++++++++++ .../SetterWithCustomPrefix.java | 33 ++++++++++++ 6 files changed, 150 insertions(+), 5 deletions(-) create mode 100644 processor/src/test/resources/tests/Strategies/StepWise/SetterWithCustomPrefix/Expected_DefaultSetterWithCustomPrefixBuilder.java create mode 100644 processor/src/test/resources/tests/Strategies/StepWise/SetterWithCustomPrefix/Expected_SetterWithCustomPrefixBuilder.java create mode 100644 processor/src/test/resources/tests/Strategies/StepWise/SetterWithCustomPrefix/SetterWithCustomPrefix.java diff --git a/processor/src/main/java/io/jonasg/bob/BuilderTypeSpecFactory.java b/processor/src/main/java/io/jonasg/bob/BuilderTypeSpecFactory.java index e80408f..6636b74 100644 --- a/processor/src/main/java/io/jonasg/bob/BuilderTypeSpecFactory.java +++ b/processor/src/main/java/io/jonasg/bob/BuilderTypeSpecFactory.java @@ -240,12 +240,12 @@ protected CodeBlock generateFieldAssignment(BuildableField field) { if (field.isConstructorArgument() && isAnEnforcedConstructorPolicy() || field.isMandatory()) { return CodeBlock.builder() .addStatement("instance.$L(this.$L.orElseThrow())", - setterName(field.setterMethodName().orElseThrow()), field.name()) + field.setterMethodName().orElseThrow(), field.name()) .build(); } else { return CodeBlock.builder() .addStatement( - String.format("instance.%s(this.%s)", setterName(field.setterMethodName().orElseThrow()), + String.format("instance.%s(this.%s)", field.setterMethodName().orElseThrow(), field.name())) .build(); } diff --git a/processor/src/main/java/io/jonasg/bob/StepBuilderInterfaceTypeSpecFactory.java b/processor/src/main/java/io/jonasg/bob/StepBuilderInterfaceTypeSpecFactory.java index a524fd5..2d69e95 100644 --- a/processor/src/main/java/io/jonasg/bob/StepBuilderInterfaceTypeSpecFactory.java +++ b/processor/src/main/java/io/jonasg/bob/StepBuilderInterfaceTypeSpecFactory.java @@ -105,7 +105,7 @@ BuilderDetails typeSpec(String builderImplName) { reversedBuildableFields.stream() .filter(this::notExcluded) .filter(field -> (!field.isConstructorArgument()) && !field.isMandatory()) - .forEach(field -> buildStepInterfaceBuilder.addMethod(MethodSpec.methodBuilder(field.name()) + .forEach(field -> buildStepInterfaceBuilder.addMethod(MethodSpec.methodBuilder(setterName(field.name())) .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) .returns(ClassName.get("", "BuildStep")) .addParameter(TypeName.get(field.type()), field.name()) @@ -137,7 +137,7 @@ BuilderDetails typeSpec(String builderImplName) { String name = String.format("%sStep", capitalize(field.name())); interfaces.add(ClassName.get("", builderInterfaceName + "." + name)); return TypeSpecInterfaceBuilder.functionalInterface(name) - .methodName(field.name()) + .methodName(setterName(field.name())) .addArgument(TypeName.get(field.type()), field.name()) .returns(ClassName.get("", nextStep.get().name)) .build(); @@ -148,7 +148,7 @@ BuilderDetails typeSpec(String builderImplName) { // the initial field to be built BuildableField buildableField = mandatoryFields .get(mandatoryFields.size() - 1); - stepBuilderBuilder.addMethod(MethodSpec.methodBuilder(buildableField.name()) + stepBuilderBuilder.addMethod(MethodSpec.methodBuilder(setterName(buildableField.name())) .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT) .addParameter(TypeName.get(buildableField.type()), buildableField.name()) .returns(ClassName.get("", nextStep.get().name)) @@ -176,4 +176,12 @@ private List reverseList(List originalList) { } return reversedList; } + + protected String setterName(String name) { + if (buildable.setterPrefix().isEmpty()) { + return name; + } + return Formatter.format("$setterPrefix$name", buildable.setterPrefix(), + name.substring(0, 1).toUpperCase() + name.substring(1)); + } } diff --git a/processor/src/test/java/io/jonasg/bob/StrategyTests.java b/processor/src/test/java/io/jonasg/bob/StrategyTests.java index 39fdbfb..65746af 100644 --- a/processor/src/test/java/io/jonasg/bob/StrategyTests.java +++ b/processor/src/test/java/io/jonasg/bob/StrategyTests.java @@ -225,5 +225,32 @@ void generateStepBuilderWithSingleMandatoryAnnotatedField() { "/tests/Strategies/StepWise/GenerateStepBuilderWithSingleMandatoryAnnotatedField/Expected_GenerateStepBuilderWithSingleMandatoryAnnotatedFieldBuilder.java")) .executeTest(); } + + @Test + void setterWithCustomPrefix() { + Cute.blackBoxTest() + .given() + .processors(List.of(BuildableProcessor.class)) + .andSourceFiles( + "/tests/Strategies/StepWise/SetterWithCustomPrefix/SetterWithCustomPrefix.java") + .whenCompiled() + .thenExpectThat() + .compilationSucceeds() + .andThat() + .generatedSourceFile( + "io.jonasg.bob.test.SetterWithCustomPrefixBuilder") + .matches( + CuteApi.ExpectedFileObjectMatcherKind.BINARY, + JavaFileObjectUtils.readFromResource( + "/tests/Strategies/StepWise/SetterWithCustomPrefix/Expected_SetterWithCustomPrefixBuilder.java")) + .andThat() + .generatedSourceFile( + "io.jonasg.bob.test.DefaultSetterWithCustomPrefixBuilder") + .matches( + CuteApi.ExpectedFileObjectMatcherKind.BINARY, + JavaFileObjectUtils.readFromResource( + "/tests/Strategies/StepWise/SetterWithCustomPrefix/Expected_DefaultSetterWithCustomPrefixBuilder.java")) + .executeTest(); + } } } diff --git a/processor/src/test/resources/tests/Strategies/StepWise/SetterWithCustomPrefix/Expected_DefaultSetterWithCustomPrefixBuilder.java b/processor/src/test/resources/tests/Strategies/StepWise/SetterWithCustomPrefix/Expected_DefaultSetterWithCustomPrefixBuilder.java new file mode 100644 index 0000000..f2c605f --- /dev/null +++ b/processor/src/test/resources/tests/Strategies/StepWise/SetterWithCustomPrefix/Expected_DefaultSetterWithCustomPrefixBuilder.java @@ -0,0 +1,50 @@ +package io.jonasg.bob.test; + +import java.lang.String; + +public final class DefaultSetterWithCustomPrefixBuilder implements SetterWithCustomPrefixBuilder, SetterWithCustomPrefixBuilder.BuildStep, SetterWithCustomPrefixBuilder.FuelEfficiencyStep, SetterWithCustomPrefixBuilder.IsElectricStep { + private double engineSize; + + private boolean isElectric; + + private float fuelEfficiency; + + private String make; + + private int year; + + public DefaultSetterWithCustomPrefixBuilder() { + } + + public DefaultSetterWithCustomPrefixBuilder withEngineSize(double engineSize) { + this.engineSize = engineSize; + return this; + } + + public DefaultSetterWithCustomPrefixBuilder withIsElectric(boolean isElectric) { + this.isElectric = isElectric; + return this; + } + + public DefaultSetterWithCustomPrefixBuilder withFuelEfficiency(float fuelEfficiency) { + this.fuelEfficiency = fuelEfficiency; + return this; + } + + public DefaultSetterWithCustomPrefixBuilder withMake(String make) { + this.make = make; + return this; + } + + public DefaultSetterWithCustomPrefixBuilder withYear(int year) { + this.year = year; + return this; + } + + public SetterWithCustomPrefix build() { + var instance = new SetterWithCustomPrefix(engineSize, isElectric, fuelEfficiency); + instance.setMake(this.make); + instance.setYear(this.year); + return instance; + } +} diff --git a/processor/src/test/resources/tests/Strategies/StepWise/SetterWithCustomPrefix/Expected_SetterWithCustomPrefixBuilder.java b/processor/src/test/resources/tests/Strategies/StepWise/SetterWithCustomPrefix/Expected_SetterWithCustomPrefixBuilder.java new file mode 100644 index 0000000..74c8da5 --- /dev/null +++ b/processor/src/test/resources/tests/Strategies/StepWise/SetterWithCustomPrefix/Expected_SetterWithCustomPrefixBuilder.java @@ -0,0 +1,27 @@ +package io.jonasg.bob.test; + +import java.lang.String; + +public interface SetterWithCustomPrefixBuilder { + static SetterWithCustomPrefixBuilder newBuilder() { + return new DefaultSetterWithCustomPrefixBuilder(); + } + + IsElectricStep withEngineSize(double engineSize); + + interface BuildStep { + BuildStep withYear(int year); + + BuildStep withMake(String make); + + SetterWithCustomPrefix build(); + } + + interface FuelEfficiencyStep { + BuildStep withFuelEfficiency(float fuelEfficiency); + } + + interface IsElectricStep { + FuelEfficiencyStep withIsElectric(boolean isElectric); + } +} diff --git a/processor/src/test/resources/tests/Strategies/StepWise/SetterWithCustomPrefix/SetterWithCustomPrefix.java b/processor/src/test/resources/tests/Strategies/StepWise/SetterWithCustomPrefix/SetterWithCustomPrefix.java new file mode 100644 index 0000000..eb7fe92 --- /dev/null +++ b/processor/src/test/resources/tests/Strategies/StepWise/SetterWithCustomPrefix/SetterWithCustomPrefix.java @@ -0,0 +1,33 @@ +package io.jonasg.bob.test; + +import io.jonasg.bob.Buildable; +import io.jonasg.bob.Strategy; + +@Buildable(strategy = Strategy.STEP_WISE, setterPrefix = "with") +public class SetterWithCustomPrefix { + private String make; + + private int year; + + private double engineSize; + + private boolean isElectric; + + private float fuelEfficiency; + + public SetterWithCustomPrefix(double engineSize, boolean isElectric, float fuelEfficiency) { + this.engineSize = engineSize; + this.isElectric = isElectric; + this.fuelEfficiency = fuelEfficiency; + } + + public SetterWithCustomPrefix setMake(String make) { + this.make = make; + return this; + } + + public SetterWithCustomPrefix setYear(int year) { + this.year = year; + return this; + } +}