Skip to content

Commit 0c66774

Browse files
authored
ISSUES-4 builder build uses mock (#14)
1 parent 1487e8d commit 0c66774

File tree

4 files changed

+107
-31
lines changed

4 files changed

+107
-31
lines changed

compiler/src/main/java/io/jbock/simple/processor/writing/BuilderImpl.java

Lines changed: 96 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -42,54 +42,125 @@ private BuilderImpl(
4242
}
4343

4444
TypeSpec generate(BuilderElement builder, MockBuilder mockBuilder) {
45+
if (component.omitMockBuilder()) {
46+
return generateNoMock(builder);
47+
} else {
48+
return generateMock(builder, mockBuilder);
49+
}
50+
}
51+
52+
private TypeSpec generateMock(BuilderElement builder, MockBuilder mockBuilder) {
4553
TypeMirror builderType = builder.element().asType();
4654
TypeSpec.Builder spec = TypeSpec.classBuilder(builder.generatedClass());
47-
if (!component.omitMockBuilder()) {
48-
FieldSpec field = FieldSpec.builder(mockBuilder.getClassName(), "mockBuilder", FINAL).build();
49-
spec.addField(field);
50-
ParameterSpec param = ParameterSpec.builder(mockBuilder.getClassName(), "mockBuilder").build();
51-
spec.addMethod(MethodSpec.constructorBuilder()
52-
.addParameter(param)
53-
.addStatement("this.$N = $N", field, param)
54-
.build());
55-
}
55+
FieldSpec mockBuilderField = FieldSpec.builder(mockBuilder.getClassName(), "mockBuilder", FINAL).build();
56+
spec.addField(mockBuilderField);
57+
ParameterSpec mockBuilderParam = ParameterSpec.builder(mockBuilder.getClassName(), "mockBuilder").build();
58+
spec.addMethod(MethodSpec.constructorBuilder()
59+
.addParameter(mockBuilderParam)
60+
.addStatement("this.$N = $N", mockBuilderField, mockBuilderParam)
61+
.build());
5662
MethodSpec.Builder buildMethod = MethodSpec.methodBuilder(builder.buildMethod().getSimpleName().toString());
57-
List<CodeBlock> constructorParameters = new ArrayList<>();
5863
for (NamedBinding namedBinding : sorted.values()) {
5964
Binding b = namedBinding.binding();
65+
if (b instanceof ParameterBinding) {
66+
continue;
67+
}
6068
Key key = b.key();
6169
CodeBlock invocation = b.invocation(names);
6270
ParameterSpec param = names.apply(key);
63-
if (namedBinding.isComponentRequest()) {
64-
constructorParameters.add(CodeBlock.of("$N", names.apply(key)));
65-
}
66-
if (b instanceof ParameterBinding) {
67-
spec.addField(FieldSpec.builder(b.key().typeName(), names.apply(b.key()).name).build());
68-
MethodSpec.Builder setterMethod = MethodSpec.methodBuilder(b.element().getSimpleName().toString());
69-
setterMethod.addAnnotation(Override.class);
70-
setterMethod.addParameter(names.apply(b.key()));
71-
setterMethod.addStatement("this.$N = $N", names.apply(b.key()), names.apply(b.key()));
72-
setterMethod.addStatement("return this");
73-
setterMethod.returns(TypeName.get(builderType));
74-
setterMethod.addModifiers(b.element().getModifiers().stream()
75-
.filter(m -> m == PUBLIC || m == PROTECTED).collect(Collectors.toList()));
76-
spec.addMethod(setterMethod.build());
71+
if (!key.typeName().isPrimitive()) {
72+
buildMethod.addStatement("$1T $2N = this.$3N != null && this.$3N.$2N != null ? this.$3N.$2N : $4L",
73+
key.typeName(), param, mockBuilderField, invocation);
7774
} else {
75+
FieldSpec auxField = FieldSpec.builder(TypeName.BOOLEAN, namedBinding.auxName(), PRIVATE).build();
76+
buildMethod.addStatement("$1T $2N = this.$3N != null && this.$3N.$4N ? this.$3N.$2N : $5L",
77+
key.typeName(), param, mockBuilderField, auxField, invocation);
78+
}
79+
}
80+
spec.addFields(fields());
81+
spec.addMethods(setterMethods(builder));
82+
spec.addModifiers(PRIVATE, STATIC, FINAL);
83+
spec.addSuperinterface(builderType);
84+
buildMethod.addAnnotation(Override.class);
85+
buildMethod.addModifiers(builder.buildMethod().getModifiers().stream()
86+
.filter(m -> m == PUBLIC || m == PROTECTED).collect(Collectors.toList()));
87+
buildMethod.returns(TypeName.get(component.element().asType()));
88+
buildMethod.addStatement("return new $T($L)", component.generatedClass(), constructorParameters().stream()
89+
.collect(CodeBlock.joining(", ")));
90+
spec.addMethod(buildMethod.build());
91+
return spec.build();
92+
}
93+
94+
private TypeSpec generateNoMock(BuilderElement builder) {
95+
TypeMirror builderType = builder.element().asType();
96+
TypeSpec.Builder spec = TypeSpec.classBuilder(builder.generatedClass());
97+
MethodSpec.Builder buildMethod = MethodSpec.methodBuilder(builder.buildMethod().getSimpleName().toString());
98+
for (NamedBinding namedBinding : sorted.values()) {
99+
Binding b = namedBinding.binding();
100+
Key key = b.key();
101+
CodeBlock invocation = b.invocation(names);
102+
ParameterSpec param = names.apply(key);
103+
if (!(b instanceof ParameterBinding)) {
78104
buildMethod.addStatement("$T $N = $L", key.typeName(), param, invocation);
79105
}
80106
}
107+
spec.addFields(fields());
108+
spec.addMethods(setterMethods(builder));
81109
spec.addModifiers(PRIVATE, STATIC, FINAL);
82110
spec.addSuperinterface(builderType);
83111
buildMethod.addAnnotation(Override.class);
84112
buildMethod.addModifiers(builder.buildMethod().getModifiers().stream()
85113
.filter(m -> m == PUBLIC || m == PROTECTED).collect(Collectors.toList()));
86114
buildMethod.returns(TypeName.get(component.element().asType()));
87-
buildMethod.addStatement("return new $T($L)", component.generatedClass(), constructorParameters.stream()
115+
buildMethod.addStatement("return new $T($L)", component.generatedClass(), constructorParameters().stream()
88116
.collect(CodeBlock.joining(", ")));
89117
spec.addMethod(buildMethod.build());
90118
return spec.build();
91119
}
92120

121+
private List<FieldSpec> fields() {
122+
List<FieldSpec> result = new ArrayList<>();
123+
for (NamedBinding namedBinding : sorted.values()) {
124+
Binding b = namedBinding.binding();
125+
if (b instanceof ParameterBinding) {
126+
result.add(FieldSpec.builder(b.key().typeName(), names.apply(b.key()).name).build());
127+
}
128+
}
129+
return result;
130+
}
131+
132+
private List<MethodSpec> setterMethods(BuilderElement builder) {
133+
TypeMirror builderType = builder.element().asType();
134+
List<MethodSpec> result = new ArrayList<>();
135+
for (NamedBinding namedBinding : sorted.values()) {
136+
Binding b = namedBinding.binding();
137+
if (b instanceof ParameterBinding) {
138+
MethodSpec.Builder setterMethod = MethodSpec.methodBuilder(b.element().getSimpleName().toString());
139+
setterMethod.addAnnotation(Override.class);
140+
setterMethod.addParameter(names.apply(b.key()));
141+
setterMethod.addStatement("this.$N = $N", names.apply(b.key()), names.apply(b.key()));
142+
setterMethod.addStatement("return this");
143+
setterMethod.returns(TypeName.get(builderType));
144+
setterMethod.addModifiers(b.element().getModifiers().stream()
145+
.filter(m -> m == PUBLIC || m == PROTECTED).collect(Collectors.toList()));
146+
result.add(setterMethod.build());
147+
}
148+
}
149+
return result;
150+
}
151+
152+
private List<CodeBlock> constructorParameters() {
153+
List<CodeBlock> result = new ArrayList<>();
154+
for (NamedBinding namedBinding : sorted.values()) {
155+
Binding b = namedBinding.binding();
156+
Key key = b.key();
157+
if (namedBinding.isComponentRequest()) {
158+
result.add(CodeBlock.of("$N", names.apply(key)));
159+
}
160+
}
161+
return result;
162+
}
163+
93164
public static final class Factory {
94165
private final ComponentElement component;
95166

compiler/src/main/java/io/jbock/simple/processor/writing/ComponentImpl.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,16 @@ private MethodSpec generateFactoryMethod(FactoryElement factory) {
108108
}
109109

110110
private MethodSpec generateBuilderMethod(BuilderElement builder) {
111-
return MethodSpec.methodBuilder(BUILDER_METHOD)
111+
MethodSpec.Builder spec = MethodSpec.methodBuilder(BUILDER_METHOD)
112112
.addModifiers(STATIC)
113113
.addModifiers(modifiers)
114-
.addStatement("return new $T(null)", builder.generatedClass())
115-
.returns(TypeName.get(builder.element().asType())).build();
114+
.returns(TypeName.get(builder.element().asType()));
115+
if (component.omitMockBuilder()) {
116+
spec.addStatement("return new $T()", builder.generatedClass());
117+
} else {
118+
spec.addStatement("return new $T(null)", builder.generatedClass());
119+
}
120+
return spec.build();
116121
}
117122

118123
private MethodSpec generateCreateMethod() {

compiler/src/main/java/io/jbock/simple/processor/writing/MockBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ private MethodSpec buildMethod() {
7272
if (namedBinding.isComponentRequest()) {
7373
constructorParameters.add(CodeBlock.of("$N", names.apply(key)));
7474
}
75-
if (namedBinding.binding() instanceof ParameterBinding) {
75+
if (b instanceof ParameterBinding) {
7676
method.addParameter(names.apply(b.key()));
7777
} else if (!key.typeName().isPrimitive()) {
7878
method.addStatement("$1T $2N = this.$2N != null ? this.$2N : $3L", key.typeName(), param, invocation);

compiler/src/test/java/io/jbock/simple/processor/BuilderTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ void noParameters() {
6060
" private static final class Builder_Impl implements TestClass.AComponent.Builder {",
6161
" @Override",
6262
" public TestClass.AComponent build() {",
63-
" TestClass.A a = new TestClass.A();",
63+
" TestClass.A a = this.mockBuilder != null && this.mockBuilder.a != null ? this.mockBuilder.a : new TestClass.A();",
6464
" return new TestClass_AComponent_Impl(a);",
6565
" }",
6666
" }",
@@ -186,7 +186,7 @@ void builderParameter() {
186186
"",
187187
" @Override",
188188
" public TestClass.AComponent build() {",
189-
" TestClass.A a = new TestClass.A(s);",
189+
" TestClass.A a = this.mockBuilder != null && this.mockBuilder.a != null ? this.mockBuilder.a : new TestClass.A(s);",
190190
" return new TestClass_AComponent_Impl(a);",
191191
" }",
192192
" }",

0 commit comments

Comments
 (0)