Skip to content

Commit 165bc95

Browse files
committed
ConstructorHelperGenerator를 구현한다
1 parent c7341ed commit 165bc95

File tree

2 files changed

+137
-0
lines changed

2 files changed

+137
-0
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package io.github.protogenerator.core;
2+
3+
import com.google.protobuf.DescriptorProtos;
4+
5+
public class ConstructorHelperGenerator {
6+
public String generateConstructorHelper(String protoPackage, String originalClassName, DescriptorProtos.DescriptorProto message) {
7+
StringBuilder sb = new StringBuilder();
8+
9+
sb.append("package ").append(protoPackage).append(";\n\n");
10+
sb.append("public final class ").append(originalClassName).append("Constructor {\n\n");
11+
12+
sb.append(" private ").append(originalClassName).append("Constructor() {}\n\n");
13+
14+
sb.append(" public static ").append(originalClassName).append(" from(");
15+
for (int i = 0; i < message.getFieldCount(); i++) {
16+
DescriptorProtos.FieldDescriptorProto field = message.getField(i);
17+
sb.append(JavaTypeMapper.map(field.getType())).append(" ").append(field.getName());
18+
if (i < message.getFieldCount() - 1) {
19+
sb.append(", ");
20+
}
21+
}
22+
sb.append(") {\n");
23+
24+
sb.append(" return ").append(originalClassName).append(".newBuilder()\n");
25+
for (DescriptorProtos.FieldDescriptorProto field : message.getFieldList()) {
26+
sb.append(" .set").append(StringUtil.capitalize(field.getName())).append("(").append(field.getName()).append(")\n");
27+
}
28+
sb.append(" .build();\n");
29+
sb.append(" }\n");
30+
31+
sb.append("}\n");
32+
33+
return sb.toString();
34+
}
35+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package io.github.protogenerator.core;
2+
3+
import com.google.protobuf.DescriptorProtos;
4+
import org.junit.jupiter.api.DisplayName;
5+
import org.junit.jupiter.api.Test;
6+
import org.junit.jupiter.params.ParameterizedTest;
7+
import org.junit.jupiter.params.provider.CsvSource;
8+
9+
import static org.junit.jupiter.api.Assertions.*;
10+
11+
public class ConstructorHelperGeneratorTest {
12+
13+
@Test
14+
@DisplayName("returns valid constructor helper code for typical message")
15+
void sut_returns_valid_constructor_helper_code() {
16+
// Arrange
17+
var sut = new ConstructorHelperGenerator();
18+
DescriptorProtos.DescriptorProto message = DescriptorProtos.DescriptorProto.newBuilder()
19+
.setName("Person")
20+
.addField(DescriptorProtos.FieldDescriptorProto.newBuilder()
21+
.setName("name")
22+
.setType(DescriptorProtos.FieldDescriptorProto.Type.TYPE_STRING)
23+
.setNumber(1)
24+
.build())
25+
.addField(DescriptorProtos.FieldDescriptorProto.newBuilder()
26+
.setName("age")
27+
.setType(DescriptorProtos.FieldDescriptorProto.Type.TYPE_INT32)
28+
.setNumber(2)
29+
.build())
30+
.build();
31+
32+
// Act
33+
String generated = sut.generateConstructorHelper(
34+
"io.github.protogenerator.example",
35+
"Person",
36+
message
37+
);
38+
39+
// Assert
40+
assertAll(
41+
() -> assertTrue(generated.contains("package io.github.protogenerator.example;")),
42+
() -> assertTrue(generated.contains("public static Person from(String name, int age)")),
43+
() -> assertTrue(generated.contains(".setName(name)")),
44+
() -> assertTrue(generated.contains(".setAge(age)"))
45+
);
46+
}
47+
48+
@Test
49+
@DisplayName("returns empty constructor when message has no fields")
50+
void sut_returns_empty_constructor_for_empty_message() {
51+
// Arrange
52+
var sut = new ConstructorHelperGenerator();
53+
DescriptorProtos.DescriptorProto message = DescriptorProtos.DescriptorProto.newBuilder()
54+
.setName("EmptyMessage")
55+
.build();
56+
57+
// Act
58+
String generated = sut.generateConstructorHelper(
59+
"io.github.protogenerator.empty",
60+
"EmptyMessage",
61+
message
62+
);
63+
64+
// Assert
65+
assertTrue(generated.contains("public static EmptyMessage from()"));
66+
assertFalse(generated.contains(".set")); // 필드가 없으니까 set 메소드가 없어야 정상
67+
}
68+
69+
@ParameterizedTest(name = "maps proto type {0} to java type {1}")
70+
@CsvSource({
71+
"TYPE_STRING, String",
72+
"TYPE_INT32, int",
73+
"TYPE_INT64, long",
74+
"TYPE_BOOL, boolean",
75+
"TYPE_FLOAT, float",
76+
"TYPE_DOUBLE, double"
77+
})
78+
void sut_maps_proto_types_to_java_types(String protoTypeName, String expectedJavaType) {
79+
// Arrange
80+
var sut = new ConstructorHelperGenerator();
81+
DescriptorProtos.FieldDescriptorProto.Type protoType = DescriptorProtos.FieldDescriptorProto.Type.valueOf(protoTypeName);
82+
DescriptorProtos.DescriptorProto message = DescriptorProtos.DescriptorProto.newBuilder()
83+
.setName("SampleMessage")
84+
.addField(DescriptorProtos.FieldDescriptorProto.newBuilder()
85+
.setName("field")
86+
.setType(protoType)
87+
.setNumber(1)
88+
.build())
89+
.build();
90+
91+
// Act
92+
String generated = sut.generateConstructorHelper(
93+
"io.github.protogenerator.types",
94+
"SampleMessage",
95+
message
96+
);
97+
98+
// Assert
99+
assertTrue(generated.contains(expectedJavaType + " field"));
100+
assertTrue(generated.contains(".setField(field)"));
101+
}
102+
}

0 commit comments

Comments
 (0)