1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <gmock/gmock.h>
18 #include <gtest/gtest.h>
19 
20 #include "java/java_proto_stream_code_generator.h"
21 
22 using ::testing::HasSubstr;
23 using ::testing::Not;
24 
add_my_test_proto_file(CodeGeneratorRequest * request)25 static void add_my_test_proto_file(CodeGeneratorRequest* request) {
26     request->add_file_to_generate("MyTestProtoFile");
27 
28     FileDescriptorProto* file_desc = request->add_proto_file();
29     file_desc->set_name("MyTestProtoFile");
30     file_desc->set_package("test.package");
31 
32     auto* file_options = file_desc->mutable_options();
33     file_options->set_java_multiple_files(false);
34 
35     auto* message = file_desc->add_message_type();
36     message->set_name("MyTestMessage");
37 
38     auto* field = message->add_field();
39     field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
40     field->set_name("my_test_field");
41 
42     field = message->add_field();
43     field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
44     field->set_name("my_other_test_field");
45 
46     field = message->add_field();
47     field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
48     field->set_name("my_other_test_message");
49 }
50 
add_my_other_test_proto_file(CodeGeneratorRequest * request)51 static void add_my_other_test_proto_file(CodeGeneratorRequest* request) {
52     request->add_file_to_generate("MyOtherTestProtoFile");
53 
54     FileDescriptorProto* file_desc = request->add_proto_file();
55     file_desc->set_name("MyOtherTestProtoFile");
56     file_desc->set_package("test.package");
57 
58     auto* file_options = file_desc->mutable_options();
59     file_options->set_java_multiple_files(false);
60 
61     auto* message = file_desc->add_message_type();
62     message->set_name("MyOtherTestMessage");
63 
64     auto* field = message->add_field();
65     field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
66     field->set_name("a_test_field");
67 
68     field = message->add_field();
69     field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
70     field->set_name("another_test_field");
71 }
72 
create_simple_two_file_request()73 static CodeGeneratorRequest create_simple_two_file_request() {
74     CodeGeneratorRequest request;
75 
76     add_my_test_proto_file(&request);
77     add_my_other_test_proto_file(&request);
78 
79     return request;
80 }
81 
create_simple_multi_file_request()82 static CodeGeneratorRequest create_simple_multi_file_request() {
83     CodeGeneratorRequest request;
84 
85     request.add_file_to_generate("MyMultiMessageTestProtoFile");
86 
87     FileDescriptorProto* file_desc = request.add_proto_file();
88     file_desc->set_name("MyMultiMessageTestProtoFile");
89     file_desc->set_package("test.package");
90 
91     auto* file_options = file_desc->mutable_options();
92     file_options->set_java_multiple_files(true);
93 
94     auto* message = file_desc->add_message_type();
95     message->set_name("MyTestMessage");
96 
97     auto* field = message->add_field();
98     field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
99     field->set_name("my_test_field");
100 
101     field = message->add_field();
102     field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
103     field->set_name("my_other_test_field");
104 
105     field = message->add_field();
106     field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
107     field->set_name("my_other_test_message");
108 
109     message = file_desc->add_message_type();
110     message->set_name("MyOtherTestMessage");
111 
112     field = message->add_field();
113     field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
114     field->set_name("a_test_field");
115 
116     field = message->add_field();
117     field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
118     field->set_name("another_test_field");
119 
120     return request;
121 }
122 
TEST(StreamingProtoJavaTest,NoFilter)123 TEST(StreamingProtoJavaTest, NoFilter) {
124     CodeGeneratorRequest request = create_simple_two_file_request();
125     CodeGeneratorResponse response = generate_java_protostream_code(request);
126 
127     auto generated_file_count = response.file_size();
128     EXPECT_EQ(generated_file_count, 2);
129 
130     EXPECT_EQ(response.file(0).name(), "test/package/MyTestProtoFile.java");
131     EXPECT_THAT(response.file(0).content(), HasSubstr("class MyTestProtoFile"));
132     EXPECT_THAT(response.file(0).content(), HasSubstr("class MyTestMessage"));
133     EXPECT_THAT(response.file(0).content(), HasSubstr("long MY_TEST_FIELD"));
134     EXPECT_THAT(response.file(0).content(), HasSubstr("long MY_OTHER_TEST_FIELD"));
135 
136     EXPECT_EQ(response.file(1).name(), "test/package/MyOtherTestProtoFile.java");
137     EXPECT_THAT(response.file(1).content(), HasSubstr("class MyOtherTestProtoFile"));
138     EXPECT_THAT(response.file(1).content(), HasSubstr("class MyOtherTestMessage"));
139     EXPECT_THAT(response.file(1).content(), HasSubstr("long A_TEST_FIELD"));
140     EXPECT_THAT(response.file(1).content(), HasSubstr("long ANOTHER_TEST_FIELD"));
141 }
142 
TEST(StreamingProtoJavaTest,WithFilter)143 TEST(StreamingProtoJavaTest, WithFilter) {
144     CodeGeneratorRequest request = create_simple_two_file_request();
145     request.set_parameter("include_filter:test.package.MyTestMessage");
146     CodeGeneratorResponse response = generate_java_protostream_code(request);
147 
148     auto generated_file_count = response.file_size();
149     EXPECT_EQ(generated_file_count, 1);
150 
151     EXPECT_EQ(response.file(0).name(), "test/package/MyTestProtoFile.java");
152     EXPECT_THAT(response.file(0).content(), HasSubstr("class MyTestProtoFile"));
153     EXPECT_THAT(response.file(0).content(), HasSubstr("class MyTestMessage"));
154     EXPECT_THAT(response.file(0).content(), HasSubstr("long MY_TEST_FIELD"));
155     EXPECT_THAT(response.file(0).content(), HasSubstr("long MY_OTHER_TEST_FIELD"));
156 }
157 
TEST(StreamingProtoJavaTest,WithoutFilter_MultipleJavaFiles)158 TEST(StreamingProtoJavaTest, WithoutFilter_MultipleJavaFiles) {
159     CodeGeneratorRequest request = create_simple_multi_file_request();
160     CodeGeneratorResponse response = generate_java_protostream_code(request);
161 
162     auto generated_file_count = response.file_size();
163     EXPECT_EQ(generated_file_count, 2);
164 
165     EXPECT_EQ(response.file(0).name(), "test/package/MyTestMessage.java");
166     EXPECT_THAT(response.file(0).content(), Not(HasSubstr("class MyTestProtoFile")));
167     EXPECT_THAT(response.file(0).content(), HasSubstr("class MyTestMessage"));
168     EXPECT_THAT(response.file(0).content(), HasSubstr("long MY_TEST_FIELD"));
169     EXPECT_THAT(response.file(0).content(), HasSubstr("long MY_OTHER_TEST_FIELD"));
170 
171     EXPECT_EQ(response.file(1).name(), "test/package/MyOtherTestMessage.java");
172     EXPECT_THAT(response.file(1).content(), Not(HasSubstr("class MyOtherTestProtoFile")));
173     EXPECT_THAT(response.file(1).content(), HasSubstr("class MyOtherTestMessage"));
174     EXPECT_THAT(response.file(1).content(), HasSubstr("long A_TEST_FIELD"));
175     EXPECT_THAT(response.file(1).content(), HasSubstr("long ANOTHER_TEST_FIELD"));
176 }
177 
TEST(StreamingProtoJavaTest,WithFilter_MultipleJavaFiles)178 TEST(StreamingProtoJavaTest, WithFilter_MultipleJavaFiles) {
179     CodeGeneratorRequest request = create_simple_multi_file_request();
180     request.set_parameter("include_filter:test.package.MyTestMessage");
181     CodeGeneratorResponse response = generate_java_protostream_code(request);
182 
183     auto generated_file_count = response.file_size();
184     EXPECT_EQ(generated_file_count, 1);
185 
186     EXPECT_EQ(response.file(0).name(), "test/package/MyTestMessage.java");
187     EXPECT_THAT(response.file(0).content(), Not(HasSubstr("class MyTestProtoFile")));
188     EXPECT_THAT(response.file(0).content(), HasSubstr("class MyTestMessage"));
189     EXPECT_THAT(response.file(0).content(), HasSubstr("long MY_TEST_FIELD"));
190     EXPECT_THAT(response.file(0).content(), HasSubstr("long MY_OTHER_TEST_FIELD"));
191 }
192