35 #include <google/protobuf/compiler/importer.h>
38 #include <unordered_map>
40 #include <google/protobuf/stubs/logging.h>
41 #include <google/protobuf/stubs/common.h>
42 #include <google/protobuf/testing/file.h>
43 #include <google/protobuf/testing/file.h>
44 #include <google/protobuf/testing/file.h>
45 #include <google/protobuf/io/zero_copy_stream_impl.h>
46 #include <google/protobuf/descriptor.h>
47 #include <google/protobuf/testing/googletest.h>
48 #include <gtest/gtest.h>
49 #include <google/protobuf/stubs/substitute.h>
50 #include <google/protobuf/stubs/map_util.h>
51 #include <google/protobuf/stubs/strutil.h>
63 #define EXPECT_SUBSTRING(needle, haystack) \
64 EXPECT_PRED_FORMAT2(testing::IsSubstring, (needle), (haystack))
68 MockErrorCollector() {}
69 ~MockErrorCollector() {}
91 class MockSourceTree :
public SourceTree {
110 std::string GetLastErrorMessage() {
return "File not found."; }
113 std::unordered_map<std::string, const char*>
files_;
134 TEST_F(ImporterTest, Import) {
137 "syntax = \"proto2\";\n"
151 TEST_F(ImporterTest, ImportNested) {
154 "syntax = \"proto2\";\n"
155 "import \"bar.proto\";\n"
157 " optional Bar bar = 1;\n"
160 "syntax = \"proto2\";\n"
183 foo->message_type(0)->field(0)->type());
185 foo->message_type(0)->field(0)->message_type());
188 TEST_F(ImporterTest, FileNotFound) {
194 TEST_F(ImporterTest, ImportNotFound) {
197 "syntax = \"proto2\";\n"
198 "import \"bar.proto\";\n");
202 "bar.proto:-1:0: File not found.\n"
203 "foo.proto:1:0: Import \"bar.proto\" was not found or had errors.\n",
207 TEST_F(ImporterTest, RecursiveImport) {
210 "syntax = \"proto2\";\n"
212 "import \"recursive2.proto\";\n");
214 "syntax = \"proto2\";\n"
215 "import \"recursive1.proto\";\n");
219 "recursive1.proto:2:0: File recursively imports itself: "
221 "-> recursive2.proto -> recursive1.proto\n"
222 "recursive2.proto:1:0: Import \"recursive1.proto\" was not found "
224 "recursive1.proto:2:0: Import \"recursive2.proto\" was not found "
229 TEST_F(ImporterTest, RecursiveImportSelf) {
232 "syntax = \"proto2\";\n"
234 "import \"recursive.proto\";\n");
238 "recursive.proto:2:0: File recursively imports itself: "
239 "recursive.proto -> recursive.proto\n",
243 TEST_F(ImporterTest, LiteRuntimeImport) {
246 "syntax = \"proto2\";\n"
247 "option optimize_for = LITE_RUNTIME;\n");
249 "syntax = \"proto2\";\n"
250 "import \"bar.proto\";\n");
254 "foo.proto:1:0: Files that do not use optimize_for = LITE_RUNTIME "
255 "cannot import files which do use this option. This file is not "
256 "lite, but it imports \"bar.proto\" which is.\n",
265 virtual void SetUp() {
277 virtual void TearDown() {
294 const char* expected_contents) {
304 file_contents.append(
reinterpret_cast<const char*
>(
data),
size);
307 EXPECT_EQ(expected_contents, file_contents);
323 TEST_F(DiskSourceTreeTest, MapRoot) {
329 ExpectFileContents(
"foo",
"Hello World!");
330 ExpectCannotOpenFile(
"bar",
"File not found.");
333 TEST_F(DiskSourceTreeTest, MapDirectory) {
340 ExpectFileContents(
"baz/foo",
"Hello World!");
341 ExpectCannotOpenFile(
"baz/bar",
"File not found.");
342 ExpectCannotOpenFile(
"foo",
"File not found.");
343 ExpectCannotOpenFile(
"bar",
"File not found.");
346 ExpectCannotOpenFile(
"baz//foo",
347 "Backslashes, consecutive slashes, \".\", or \"..\" are "
348 "not allowed in the virtual path");
349 ExpectCannotOpenFile(
"baz/../baz/foo",
350 "Backslashes, consecutive slashes, \".\", or \"..\" are "
351 "not allowed in the virtual path");
352 ExpectCannotOpenFile(
"baz/./foo",
353 "Backslashes, consecutive slashes, \".\", or \"..\" are "
354 "not allowed in the virtual path");
355 ExpectCannotOpenFile(
"baz/foo/",
"File not found.");
358 TEST_F(DiskSourceTreeTest, NoParent) {
366 ExpectFileContents(
"baz",
"Blah.");
367 ExpectCannotOpenFile(
"../foo",
368 "Backslashes, consecutive slashes, \".\", or \"..\" are "
369 "not allowed in the virtual path");
370 ExpectCannotOpenFile(
"../bar/baz",
371 "Backslashes, consecutive slashes, \".\", or \"..\" are "
372 "not allowed in the virtual path");
375 TEST_F(DiskSourceTreeTest, MapFile) {
381 ExpectFileContents(
"foo",
"Hello World!");
382 ExpectCannotOpenFile(
"bar",
"File not found.");
385 TEST_F(DiskSourceTreeTest, SearchMultipleDirectories) {
394 ExpectFileContents(
"foo",
"Hello World!");
395 ExpectFileContents(
"bar",
"Goodbye World!");
396 ExpectCannotOpenFile(
"baz",
"File not found.");
399 TEST_F(DiskSourceTreeTest, OrderingTrumpsSpecificity) {
413 ExpectFileContents(
"bar/foo",
"Hello World!");
416 TEST_F(DiskSourceTreeTest, DiskFileToVirtualFile) {
428 source_tree_.DiskFileToVirtualFile(
"/foo", &virtual_file,
429 &shadowing_disk_file));
433 dirnames_[1] +
"/foo", &virtual_file, &shadowing_disk_file));
439 dirnames_[1] +
"/baz", &virtual_file, &shadowing_disk_file));
444 dirnames_[0] +
"/foo", &virtual_file, &shadowing_disk_file));
448 TEST_F(DiskSourceTreeTest, DiskFileToVirtualFileCanonicalization) {
463 source_tree_.DiskFileToVirtualFile(
"../../baz", &virtual_file,
464 &shadowing_disk_file));
468 source_tree_.DiskFileToVirtualFile(
"/foo", &virtual_file,
469 &shadowing_disk_file));
475 source_tree_.DiskFileToVirtualFile(
"C:\\foo", &virtual_file,
476 &shadowing_disk_file));
481 source_tree_.DiskFileToVirtualFile(
"../baz", &virtual_file,
482 &shadowing_disk_file));
487 source_tree_.DiskFileToVirtualFile(
"../../foo/baz", &virtual_file,
488 &shadowing_disk_file));
493 source_tree_.DiskFileToVirtualFile(
"foo/bar/baz", &virtual_file,
494 &shadowing_disk_file));
499 source_tree_.DiskFileToVirtualFile(
"bar", &virtual_file,
500 &shadowing_disk_file));
505 source_tree_.DiskFileToVirtualFile(
"/qux/baz", &virtual_file,
506 &shadowing_disk_file));
511 source_tree_.DiskFileToVirtualFile(
"/quux/bar", &virtual_file,
512 &shadowing_disk_file));
516 TEST_F(DiskSourceTreeTest, VirtualFileToDiskFile) {