cpp_plugin_unittest.cc
Go to the documentation of this file.
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Author: kenton@google.com (Kenton Varda)
32 //
33 // TODO(kenton): Share code with the versions of this test in other languages?
34 // It seemed like parameterizing it would add more complexity than it is
35 // worth.
36 
37 #include <memory>
38 
43 
47 #include <gtest/gtest.h>
48 
49 namespace google {
50 namespace protobuf {
51 namespace compiler {
52 namespace cpp {
53 namespace {
54 
55 class TestGenerator : public CodeGenerator {
56  public:
57  TestGenerator() {}
58  ~TestGenerator() {}
59 
60  virtual bool Generate(const FileDescriptor* file,
61  const std::string& parameter, GeneratorContext* context,
62  std::string* error) const {
63  TryInsert("test.pb.h", "includes", context);
64  TryInsert("test.pb.h", "namespace_scope", context);
65  TryInsert("test.pb.h", "global_scope", context);
66  TryInsert("test.pb.h", "class_scope:foo.Bar", context);
67  TryInsert("test.pb.h", "class_scope:foo.Bar.Baz", context);
68 
69  TryInsert("test.pb.cc", "includes", context);
70  TryInsert("test.pb.cc", "namespace_scope", context);
71  TryInsert("test.pb.cc", "global_scope", context);
72 
73  // Check field accessors for an optional int32:
74  TryInsert("test.pb.h", "field_get:foo.Bar.optInt", context);
75  TryInsert("test.pb.h", "field_set:foo.Bar.optInt", context);
76 
77  // Check field accessors for a repeated int32:
78  TryInsert("test.pb.h", "field_get:foo.Bar.repeatedInt", context);
79  TryInsert("test.pb.h", "field_set:foo.Bar.repeatedInt", context);
80 
81  // Check field accessors for a required string:
82  TryInsert("test.pb.h", "field_get:foo.Bar.requiredString", context);
83  TryInsert("test.pb.h", "field_set:foo.Bar.requiredString", context);
84  TryInsert("test.pb.h", "field_set_char:foo.Bar.requiredString", context);
85  TryInsert("test.pb.h", "field_set_pointer:foo.Bar.requiredString", context);
86  TryInsert("test.pb.h", "field_mutable:foo.Bar.requiredString", context);
87  TryInsert("test.pb.h", "field_set_allocated:foo.Bar.requiredString",
88  context);
89  TryInsert("test.pb.h", "field_set_char:foo.Bar.requiredString", context);
90  TryInsert("test.pb.h", "field_set_pointer:foo.Bar.requiredString", context);
91 
92  // Check field accessors for a repeated string:
93  TryInsert("test.pb.h", "field_get:foo.Bar.repeatedString", context);
94  TryInsert("test.pb.h", "field_set:foo.Bar.repeatedString", context);
95  TryInsert("test.pb.h", "field_set_char:foo.Bar.repeatedString", context);
96  TryInsert("test.pb.h", "field_set_pointer:foo.Bar.repeatedString", context);
97  TryInsert("test.pb.h", "field_mutable:foo.Bar.repeatedString", context);
98  TryInsert("test.pb.h", "field_set_char:foo.Bar.repeatedString", context);
99  TryInsert("test.pb.h", "field_set_pointer:foo.Bar.repeatedString", context);
100 
101  // Check field accessors for an int inside oneof{}:
102  TryInsert("test.pb.h", "field_get:foo.Bar.oneOfInt", context);
103  TryInsert("test.pb.h", "field_set:foo.Bar.oneOfInt", context);
104 
105  // Check field accessors for a string inside oneof{}:
106  TryInsert("test.pb.h", "field_get:foo.Bar.oneOfString", context);
107  TryInsert("test.pb.h", "field_set:foo.Bar.oneOfString", context);
108  TryInsert("test.pb.h", "field_set_char:foo.Bar.oneOfString", context);
109  TryInsert("test.pb.h", "field_set_pointer:foo.Bar.oneOfString", context);
110  TryInsert("test.pb.h", "field_mutable:foo.Bar.oneOfString", context);
111  TryInsert("test.pb.h", "field_set_allocated:foo.Bar.oneOfString", context);
112  TryInsert("test.pb.h", "field_set_char:foo.Bar.oneOfString", context);
113  TryInsert("test.pb.h", "field_set_pointer:foo.Bar.oneOfString", context);
114 
115  // Check field accessors for an optional message:
116  TryInsert("test.pb.h", "field_get:foo.Bar.optMessage", context);
117  TryInsert("test.pb.h", "field_mutable:foo.Bar.optMessage", context);
118  TryInsert("test.pb.h", "field_set_allocated:foo.Bar.optMessage", context);
119 
120  // Check field accessors for a repeated message:
121  TryInsert("test.pb.h", "field_add:foo.Bar.repeatedMessage", context);
122  TryInsert("test.pb.h", "field_get:foo.Bar.repeatedMessage", context);
123  TryInsert("test.pb.h", "field_list:foo.Bar.repeatedMessage", context);
124  TryInsert("test.pb.h", "field_mutable:foo.Bar.repeatedMessage", context);
125  TryInsert("test.pb.h", "field_mutable_list:foo.Bar.repeatedMessage",
126  context);
127 
128  // Check field accessors for a message inside oneof{}:
129  TryInsert("test.pb.h", "field_get:foo.Bar.oneOfMessage", context);
130  TryInsert("test.pb.h", "field_mutable:foo.Bar.oneOfMessage", context);
131  TryInsert("test.pb.cc", "field_set_allocated:foo.Bar.oneOfMessage",
132  context);
133 
134  // Check field accessors for an optional enum:
135  TryInsert("test.pb.h", "field_get:foo.Bar.optEnum", context);
136  TryInsert("test.pb.h", "field_set:foo.Bar.optEnum", context);
137 
138  // Check field accessors for a repeated enum:
139  TryInsert("test.pb.h", "field_get:foo.Bar.repeatedEnum", context);
140  TryInsert("test.pb.h", "field_set:foo.Bar.repeatedEnum", context);
141  TryInsert("test.pb.h", "field_add:foo.Bar.repeatedEnum", context);
142  TryInsert("test.pb.h", "field_list:foo.Bar.repeatedEnum", context);
143  TryInsert("test.pb.h", "field_mutable_list:foo.Bar.repeatedEnum", context);
144 
145  // Check field accessors for an enum inside oneof{}:
146  TryInsert("test.pb.h", "field_get:foo.Bar.oneOfEnum", context);
147  TryInsert("test.pb.h", "field_set:foo.Bar.oneOfEnum", context);
148 
149  // Check field accessors for a required cord:
150  TryInsert("test.pb.h", "field_get:foo.Bar.requiredCord", context);
151  TryInsert("test.pb.h", "field_set:foo.Bar.requiredCord", context);
152  TryInsert("test.pb.h", "field_mutable:foo.Bar.requiredCord", context);
153 
154  // Check field accessors for a repeated cord:
155  TryInsert("test.pb.h", "field_get:foo.Bar.repeatedCord", context);
156  TryInsert("test.pb.h", "field_set:foo.Bar.repeatedCord", context);
157  TryInsert("test.pb.h", "field_add:foo.Bar.repeatedCord", context);
158  TryInsert("test.pb.h", "field_list:foo.Bar.repeatedCord", context);
159  TryInsert("test.pb.h", "field_mutable:foo.Bar.repeatedCord", context);
160  TryInsert("test.pb.h", "field_mutable_list:foo.Bar.repeatedCord", context);
161 
162  // Check field accessors for a cord inside oneof{}:
163  TryInsert("test.pb.h", "field_get:foo.Bar.oneOfCord", context);
164  TryInsert("test.pb.h", "field_set:foo.Bar.oneOfCord", context);
165  TryInsert("test.pb.h", "field_mutable:foo.Bar.oneOfCord", context);
166 
167  return true;
168  }
169 
170  void TryInsert(const std::string& filename,
171  const std::string& insertion_point,
172  GeneratorContext* context) const {
173  std::unique_ptr<io::ZeroCopyOutputStream> output(
174  context->OpenForInsert(filename, insertion_point));
175  io::Printer printer(output.get(), '$');
176  printer.Print("// inserted $name$\n", "name", insertion_point);
177  }
178 };
179 
180 // This test verifies that all the expected insertion points exist. It does
181 // not verify that they are correctly-placed; that would require actually
182 // compiling the output which is a bit more than I care to do for this test.
183 TEST(CppPluginTest, PluginTest) {
185  "syntax = \"proto2\";\n"
186  "package foo;\n"
187  "\n"
188  "enum Thud { VALUE = 0; }\n"
189  "\n"
190  "message Bar {\n"
191  " message Baz {}\n"
192  " optional int32 optInt = 1;\n"
193  " repeated int32 repeatedInt = 2;\n"
194  "\n"
195  " required string requiredString = 3;\n"
196  " repeated string repeatedString = 4;\n"
197  "\n"
198  " optional Baz optMessage = 6;\n"
199  " repeated Baz repeatedMessage = 7;\n"
200  "\n"
201  " optional Thud optEnum = 8;\n"
202  " repeated Thud repeatedEnum = 9;\n"
203  "\n"
204  " required string requiredCord = 10 [\n"
205  " ctype = CORD\n"
206  " ];\n"
207  " repeated string repeatedCord = 11 [\n"
208  " ctype = CORD\n"
209  " ];\n"
210  "\n"
211  " oneof Qux {\n"
212  " int64 oneOfInt = 20;\n"
213  " string oneOfString = 21;\n"
214  " Baz oneOfMessage = 22;\n"
215  " Thud oneOfEnum = 23;"
216  " string oneOfCord = 24 [\n"
217  " ctype = CORD\n"
218  " ];\n"
219  " }\n"
220  "}\n",
221  true));
222 
223  CommandLineInterface cli;
224  cli.SetInputsAreProtoPathRelative(true);
225 
226  CppGenerator cpp_generator;
227  TestGenerator test_generator;
228  cli.RegisterGenerator("--cpp_out", &cpp_generator, "");
229  cli.RegisterGenerator("--test_out", &test_generator, "");
230 
231  std::string proto_path = "-I" + TestTempDir();
232  std::string cpp_out = "--cpp_out=" + TestTempDir();
233  std::string test_out = "--test_out=" + TestTempDir();
234 
235  const char* argv[] = {"protoc", proto_path.c_str(), cpp_out.c_str(),
236  test_out.c_str(), "test.proto"};
237 
238  EXPECT_EQ(0, cli.Run(5, argv));
239 }
240 
241 } // namespace
242 } // namespace cpp
243 } // namespace compiler
244 } // namespace protobuf
245 } // namespace google
zero_copy_stream.h
google::protobuf::File::SetContents
static bool SetContents(const string &name, const string &contents, bool)
Definition: file.h:93
gtest.h
FileDescriptor
Definition: ruby/ext/google/protobuf_c/protobuf.h:125
EXPECT_EQ
#define EXPECT_EQ(val1, val2)
Definition: glog/src/googletest.h:155
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
cpp_generator.h
error
Definition: cJSON.c:88
printer.h
google::protobuf::TEST
TEST(ArenaTest, ArenaConstructable)
Definition: arena_unittest.cc:156
cpp
Definition: third_party/googletest/googlemock/scripts/generator/cpp/__init__.py:1
command_line_interface.h
GOOGLE_CHECK_OK
#define GOOGLE_CHECK_OK(A)
Definition: logging.h:155
googletest.h
file.h
output
const upb_json_parsermethod const upb_symtab upb_sink * output
Definition: ruby/ext/google/protobuf_c/upb.h:10503
google::protobuf::TestTempDir
string TestTempDir()
Definition: googletest.cc:189
compiler
Definition: plugin.pb.cc:22
google
Definition: data_proto2_to_proto3_util.h:11


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:49