Index: third_party/protobuf/src/google/protobuf/compiler/importer_unittest.cc |
diff --git a/third_party/protobuf/src/google/protobuf/compiler/importer_unittest.cc b/third_party/protobuf/src/google/protobuf/compiler/importer_unittest.cc |
index 56fad56ed3dd1433cbbcb1f4ab02d75a72b4909c..be19aa2e60640aac7680fdd1be5fe19e494aa273 100644 |
--- a/third_party/protobuf/src/google/protobuf/compiler/importer_unittest.cc |
+++ b/third_party/protobuf/src/google/protobuf/compiler/importer_unittest.cc |
@@ -1,6 +1,6 @@ |
// Protocol Buffers - Google's data interchange format |
// Copyright 2008 Google Inc. All rights reserved. |
-// http://code.google.com/p/protobuf/ |
+// https://developers.google.com/protocol-buffers/ |
// |
// Redistribution and use in source and binary forms, with or without |
// modification, are permitted provided that the following conditions are |
@@ -33,12 +33,18 @@ |
// Sanjay Ghemawat, Jeff Dean, and others. |
#include <google/protobuf/stubs/hash.h> |
+#include <memory> |
+#ifndef _SHARED_PTR_H |
+#include <google/protobuf/stubs/shared_ptr.h> |
+#endif |
#include <google/protobuf/compiler/importer.h> |
#include <google/protobuf/descriptor.h> |
+#include <google/protobuf/testing/file.h> |
#include <google/protobuf/io/zero_copy_stream_impl.h> |
-#include <google/protobuf/stubs/map-util.h> |
+#include <google/protobuf/stubs/map_util.h> |
+#include <google/protobuf/stubs/logging.h> |
#include <google/protobuf/stubs/common.h> |
#include <google/protobuf/testing/file.h> |
#include <google/protobuf/stubs/strutil.h> |
@@ -52,6 +58,10 @@ namespace compiler { |
namespace { |
+bool FileExists(const string& path) { |
+ return File::Exists(path); |
+} |
+ |
#define EXPECT_SUBSTRING(needle, haystack) \ |
EXPECT_PRED_FORMAT2(testing::IsSubstring, (needle), (haystack)) |
@@ -61,6 +71,7 @@ class MockErrorCollector : public MultiFileErrorCollector { |
~MockErrorCollector() {} |
string text_; |
+ string warning_text_; |
// implements ErrorCollector --------------------------------------- |
void AddError(const string& filename, int line, int column, |
@@ -68,6 +79,12 @@ class MockErrorCollector : public MultiFileErrorCollector { |
strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", |
filename, line, column, message); |
} |
+ |
+ void AddWarning(const string& filename, int line, int column, |
+ const string& message) { |
+ strings::SubstituteAndAppend(&warning_text_, "$0:$1:$2: $3\n", |
+ filename, line, column, message); |
+ } |
}; |
// ------------------------------------------------------------------- |
@@ -92,6 +109,10 @@ class MockSourceTree : public SourceTree { |
} |
} |
+ string GetLastErrorMessage() { |
+ return "File not found."; |
+ } |
+ |
private: |
hash_map<string, const char*> files_; |
}; |
@@ -109,6 +130,7 @@ class ImporterTest : public testing::Test { |
// Return the collected error text |
string error() const { return error_collector_.text_; } |
+ string warning() const { return error_collector_.warning_text_; } |
MockErrorCollector error_collector_; |
MockSourceTree source_tree_; |
@@ -210,119 +232,6 @@ TEST_F(ImporterTest, RecursiveImport) { |
error_collector_.text_); |
} |
-// TODO(sanjay): The MapField tests below more properly belong in |
-// descriptor_unittest, but are more convenient to test here. |
-TEST_F(ImporterTest, MapFieldValid) { |
- AddFile( |
- "map.proto", |
- "syntax = \"proto2\";\n" |
- "message Item {\n" |
- " required string key = 1;\n" |
- "}\n" |
- "message Map {\n" |
- " repeated Item items = 1 [experimental_map_key = \"key\"];\n" |
- "}\n" |
- ); |
- const FileDescriptor* file = importer_.Import("map.proto"); |
- ASSERT_TRUE(file != NULL) << error_collector_.text_; |
- EXPECT_EQ("", error_collector_.text_); |
- |
- // Check that Map::items points to Item::key |
- const Descriptor* item_type = file->FindMessageTypeByName("Item"); |
- ASSERT_TRUE(item_type != NULL); |
- const Descriptor* map_type = file->FindMessageTypeByName("Map"); |
- ASSERT_TRUE(map_type != NULL); |
- const FieldDescriptor* key_field = item_type->FindFieldByName("key"); |
- ASSERT_TRUE(key_field != NULL); |
- const FieldDescriptor* items_field = map_type->FindFieldByName("items"); |
- ASSERT_TRUE(items_field != NULL); |
- EXPECT_EQ(items_field->experimental_map_key(), key_field); |
-} |
- |
-TEST_F(ImporterTest, MapFieldNotRepeated) { |
- AddFile( |
- "map.proto", |
- "syntax = \"proto2\";\n" |
- "message Item {\n" |
- " required string key = 1;\n" |
- "}\n" |
- "message Map {\n" |
- " required Item items = 1 [experimental_map_key = \"key\"];\n" |
- "}\n" |
- ); |
- EXPECT_TRUE(importer_.Import("map.proto") == NULL); |
- EXPECT_SUBSTRING("only allowed for repeated fields", error()); |
-} |
- |
-TEST_F(ImporterTest, MapFieldNotMessageType) { |
- AddFile( |
- "map.proto", |
- "syntax = \"proto2\";\n" |
- "message Map {\n" |
- " repeated int32 items = 1 [experimental_map_key = \"key\"];\n" |
- "}\n" |
- ); |
- EXPECT_TRUE(importer_.Import("map.proto") == NULL); |
- EXPECT_SUBSTRING("only allowed for fields with a message type", error()); |
-} |
- |
-TEST_F(ImporterTest, MapFieldTypeNotFound) { |
- AddFile( |
- "map.proto", |
- "syntax = \"proto2\";\n" |
- "message Map {\n" |
- " repeated Unknown items = 1 [experimental_map_key = \"key\"];\n" |
- "}\n" |
- ); |
- EXPECT_TRUE(importer_.Import("map.proto") == NULL); |
- EXPECT_SUBSTRING("not defined", error()); |
-} |
- |
-TEST_F(ImporterTest, MapFieldKeyNotFound) { |
- AddFile( |
- "map.proto", |
- "syntax = \"proto2\";\n" |
- "message Item {\n" |
- " required string key = 1;\n" |
- "}\n" |
- "message Map {\n" |
- " repeated Item items = 1 [experimental_map_key = \"badkey\"];\n" |
- "}\n" |
- ); |
- EXPECT_TRUE(importer_.Import("map.proto") == NULL); |
- EXPECT_SUBSTRING("Could not find field", error()); |
-} |
- |
-TEST_F(ImporterTest, MapFieldKeyRepeated) { |
- AddFile( |
- "map.proto", |
- "syntax = \"proto2\";\n" |
- "message Item {\n" |
- " repeated string key = 1;\n" |
- "}\n" |
- "message Map {\n" |
- " repeated Item items = 1 [experimental_map_key = \"key\"];\n" |
- "}\n" |
- ); |
- EXPECT_TRUE(importer_.Import("map.proto") == NULL); |
- EXPECT_SUBSTRING("must not name a repeated field", error()); |
-} |
- |
-TEST_F(ImporterTest, MapFieldKeyNotScalar) { |
- AddFile( |
- "map.proto", |
- "syntax = \"proto2\";\n" |
- "message ItemKey { }\n" |
- "message Item {\n" |
- " required ItemKey key = 1;\n" |
- "}\n" |
- "message Map {\n" |
- " repeated Item items = 1 [experimental_map_key = \"key\"];\n" |
- "}\n" |
- ); |
- EXPECT_TRUE(importer_.Import("map.proto") == NULL); |
- EXPECT_SUBSTRING("must name a scalar or string", error()); |
-} |
// =================================================================== |
@@ -333,30 +242,32 @@ class DiskSourceTreeTest : public testing::Test { |
dirnames_.push_back(TestTempDir() + "/test_proto2_import_path_2"); |
for (int i = 0; i < dirnames_.size(); i++) { |
- if (File::Exists(dirnames_[i])) { |
+ if (FileExists(dirnames_[i])) { |
File::DeleteRecursively(dirnames_[i], NULL, NULL); |
} |
- GOOGLE_CHECK(File::CreateDir(dirnames_[i].c_str(), DEFAULT_FILE_MODE)); |
+ GOOGLE_CHECK_OK(File::CreateDir(dirnames_[i], 0777)); |
} |
} |
virtual void TearDown() { |
for (int i = 0; i < dirnames_.size(); i++) { |
- File::DeleteRecursively(dirnames_[i], NULL, NULL); |
+ if (FileExists(dirnames_[i])) { |
+ File::DeleteRecursively(dirnames_[i], NULL, NULL); |
+ } |
} |
} |
void AddFile(const string& filename, const char* contents) { |
- File::WriteStringToFileOrDie(contents, filename); |
+ GOOGLE_CHECK_OK(File::SetContents(filename, contents, true)); |
} |
void AddSubdir(const string& dirname) { |
- GOOGLE_CHECK(File::CreateDir(dirname.c_str(), DEFAULT_FILE_MODE)); |
+ GOOGLE_CHECK_OK(File::CreateDir(dirname, 0777)); |
} |
void ExpectFileContents(const string& filename, |
const char* expected_contents) { |
- scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename)); |
+ google::protobuf::scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename)); |
ASSERT_FALSE(input == NULL); |
@@ -371,9 +282,11 @@ class DiskSourceTreeTest : public testing::Test { |
EXPECT_EQ(expected_contents, file_contents); |
} |
- void ExpectFileNotFound(const string& filename) { |
- scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename)); |
+ void ExpectCannotOpenFile(const string& filename, |
+ const string& error_message) { |
+ google::protobuf::scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename)); |
EXPECT_TRUE(input == NULL); |
+ EXPECT_EQ(error_message, source_tree_.GetLastErrorMessage()); |
} |
DiskSourceTree source_tree_; |
@@ -389,7 +302,7 @@ TEST_F(DiskSourceTreeTest, MapRoot) { |
source_tree_.MapPath("", dirnames_[0]); |
ExpectFileContents("foo", "Hello World!"); |
- ExpectFileNotFound("bar"); |
+ ExpectCannotOpenFile("bar", "File not found."); |
} |
TEST_F(DiskSourceTreeTest, MapDirectory) { |
@@ -400,15 +313,21 @@ TEST_F(DiskSourceTreeTest, MapDirectory) { |
source_tree_.MapPath("baz", dirnames_[0]); |
ExpectFileContents("baz/foo", "Hello World!"); |
- ExpectFileNotFound("baz/bar"); |
- ExpectFileNotFound("foo"); |
- ExpectFileNotFound("bar"); |
+ ExpectCannotOpenFile("baz/bar", "File not found."); |
+ ExpectCannotOpenFile("foo", "File not found."); |
+ ExpectCannotOpenFile("bar", "File not found."); |
// Non-canonical file names should not work. |
- ExpectFileNotFound("baz//foo"); |
- ExpectFileNotFound("baz/../baz/foo"); |
- ExpectFileNotFound("baz/./foo"); |
- ExpectFileNotFound("baz/foo/"); |
+ ExpectCannotOpenFile("baz//foo", |
+ "Backslashes, consecutive slashes, \".\", or \"..\" are " |
+ "not allowed in the virtual path"); |
+ ExpectCannotOpenFile("baz/../baz/foo", |
+ "Backslashes, consecutive slashes, \".\", or \"..\" are " |
+ "not allowed in the virtual path"); |
+ ExpectCannotOpenFile("baz/./foo", |
+ "Backslashes, consecutive slashes, \".\", or \"..\" are " |
+ "not allowed in the virtual path"); |
+ ExpectCannotOpenFile("baz/foo/", "File not found."); |
} |
TEST_F(DiskSourceTreeTest, NoParent) { |
@@ -420,8 +339,12 @@ TEST_F(DiskSourceTreeTest, NoParent) { |
source_tree_.MapPath("", dirnames_[0] + "/bar"); |
ExpectFileContents("baz", "Blah."); |
- ExpectFileNotFound("../foo"); |
- ExpectFileNotFound("../bar/baz"); |
+ ExpectCannotOpenFile("../foo", |
+ "Backslashes, consecutive slashes, \".\", or \"..\" are " |
+ "not allowed in the virtual path"); |
+ ExpectCannotOpenFile("../bar/baz", |
+ "Backslashes, consecutive slashes, \".\", or \"..\" are " |
+ "not allowed in the virtual path"); |
} |
TEST_F(DiskSourceTreeTest, MapFile) { |
@@ -431,7 +354,7 @@ TEST_F(DiskSourceTreeTest, MapFile) { |
source_tree_.MapPath("foo", dirnames_[0] + "/foo"); |
ExpectFileContents("foo", "Hello World!"); |
- ExpectFileNotFound("bar"); |
+ ExpectCannotOpenFile("bar", "File not found."); |
} |
TEST_F(DiskSourceTreeTest, SearchMultipleDirectories) { |
@@ -445,7 +368,7 @@ TEST_F(DiskSourceTreeTest, SearchMultipleDirectories) { |
ExpectFileContents("foo", "Hello World!"); |
ExpectFileContents("bar", "Goodbye World!"); |
- ExpectFileNotFound("baz"); |
+ ExpectCannotOpenFile("baz", "File not found."); |
} |
TEST_F(DiskSourceTreeTest, OrderingTrumpsSpecificity) { |
@@ -453,8 +376,7 @@ TEST_F(DiskSourceTreeTest, OrderingTrumpsSpecificity) { |
// directory is more-specific than a former one. |
// Create the "bar" directory so we can put a file in it. |
- ASSERT_TRUE(File::CreateDir((dirnames_[0] + "/bar").c_str(), |
- DEFAULT_FILE_MODE)); |
+ GOOGLE_CHECK_OK(File::CreateDir(dirnames_[0] + "/bar", 0777)); |
// Add files and map paths. |
AddFile(dirnames_[0] + "/bar/foo", "Hello World!"); |