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 43eb0ed58302fdc26ca7a8ddb7bd8714a81e59af..56fad56ed3dd1433cbbcb1f4ab02d75a72b4909c 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. |
-// https://developers.google.com/protocol-buffers/ |
+// http://code.google.com/p/protobuf/ |
// |
// Redistribution and use in source and binary forms, with or without |
// modification, are permitted provided that the following conditions are |
@@ -33,17 +33,12 @@ |
// 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/common.h> |
#include <google/protobuf/testing/file.h> |
#include <google/protobuf/stubs/strutil.h> |
@@ -57,10 +52,6 @@ namespace compiler { |
namespace { |
-bool FileExists(const string& path) { |
- return File::Exists(path); |
-} |
- |
#define EXPECT_SUBSTRING(needle, haystack) \ |
EXPECT_PRED_FORMAT2(testing::IsSubstring, (needle), (haystack)) |
@@ -101,10 +92,6 @@ class MockSourceTree : public SourceTree { |
} |
} |
- string GetLastErrorMessage() { |
- return "File not found."; |
- } |
- |
private: |
hash_map<string, const char*> files_; |
}; |
@@ -223,6 +210,119 @@ 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()); |
+} |
// =================================================================== |
@@ -233,32 +333,30 @@ class DiskSourceTreeTest : public testing::Test { |
dirnames_.push_back(TestTempDir() + "/test_proto2_import_path_2"); |
for (int i = 0; i < dirnames_.size(); i++) { |
- if (FileExists(dirnames_[i])) { |
+ if (File::Exists(dirnames_[i])) { |
File::DeleteRecursively(dirnames_[i], NULL, NULL); |
} |
- GOOGLE_CHECK_OK(File::CreateDir(dirnames_[i], 0777)); |
+ GOOGLE_CHECK(File::CreateDir(dirnames_[i].c_str(), DEFAULT_FILE_MODE)); |
} |
} |
virtual void TearDown() { |
for (int i = 0; i < dirnames_.size(); i++) { |
- if (FileExists(dirnames_[i])) { |
- File::DeleteRecursively(dirnames_[i], NULL, NULL); |
- } |
+ File::DeleteRecursively(dirnames_[i], NULL, NULL); |
} |
} |
void AddFile(const string& filename, const char* contents) { |
- GOOGLE_CHECK_OK(File::SetContents(filename, contents, true)); |
+ File::WriteStringToFileOrDie(contents, filename); |
} |
void AddSubdir(const string& dirname) { |
- GOOGLE_CHECK_OK(File::CreateDir(dirname, 0777)); |
+ GOOGLE_CHECK(File::CreateDir(dirname.c_str(), DEFAULT_FILE_MODE)); |
} |
void ExpectFileContents(const string& filename, |
const char* expected_contents) { |
- google::protobuf::scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename)); |
+ scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename)); |
ASSERT_FALSE(input == NULL); |
@@ -273,11 +371,9 @@ class DiskSourceTreeTest : public testing::Test { |
EXPECT_EQ(expected_contents, file_contents); |
} |
- void ExpectCannotOpenFile(const string& filename, |
- const string& error_message) { |
- google::protobuf::scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename)); |
+ void ExpectFileNotFound(const string& filename) { |
+ scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename)); |
EXPECT_TRUE(input == NULL); |
- EXPECT_EQ(error_message, source_tree_.GetLastErrorMessage()); |
} |
DiskSourceTree source_tree_; |
@@ -293,7 +389,7 @@ TEST_F(DiskSourceTreeTest, MapRoot) { |
source_tree_.MapPath("", dirnames_[0]); |
ExpectFileContents("foo", "Hello World!"); |
- ExpectCannotOpenFile("bar", "File not found."); |
+ ExpectFileNotFound("bar"); |
} |
TEST_F(DiskSourceTreeTest, MapDirectory) { |
@@ -304,21 +400,15 @@ TEST_F(DiskSourceTreeTest, MapDirectory) { |
source_tree_.MapPath("baz", dirnames_[0]); |
ExpectFileContents("baz/foo", "Hello World!"); |
- ExpectCannotOpenFile("baz/bar", "File not found."); |
- ExpectCannotOpenFile("foo", "File not found."); |
- ExpectCannotOpenFile("bar", "File not found."); |
+ ExpectFileNotFound("baz/bar"); |
+ ExpectFileNotFound("foo"); |
+ ExpectFileNotFound("bar"); |
// Non-canonical file names should not work. |
- 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."); |
+ ExpectFileNotFound("baz//foo"); |
+ ExpectFileNotFound("baz/../baz/foo"); |
+ ExpectFileNotFound("baz/./foo"); |
+ ExpectFileNotFound("baz/foo/"); |
} |
TEST_F(DiskSourceTreeTest, NoParent) { |
@@ -330,12 +420,8 @@ TEST_F(DiskSourceTreeTest, NoParent) { |
source_tree_.MapPath("", dirnames_[0] + "/bar"); |
ExpectFileContents("baz", "Blah."); |
- 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"); |
+ ExpectFileNotFound("../foo"); |
+ ExpectFileNotFound("../bar/baz"); |
} |
TEST_F(DiskSourceTreeTest, MapFile) { |
@@ -345,7 +431,7 @@ TEST_F(DiskSourceTreeTest, MapFile) { |
source_tree_.MapPath("foo", dirnames_[0] + "/foo"); |
ExpectFileContents("foo", "Hello World!"); |
- ExpectCannotOpenFile("bar", "File not found."); |
+ ExpectFileNotFound("bar"); |
} |
TEST_F(DiskSourceTreeTest, SearchMultipleDirectories) { |
@@ -359,7 +445,7 @@ TEST_F(DiskSourceTreeTest, SearchMultipleDirectories) { |
ExpectFileContents("foo", "Hello World!"); |
ExpectFileContents("bar", "Goodbye World!"); |
- ExpectCannotOpenFile("baz", "File not found."); |
+ ExpectFileNotFound("baz"); |
} |
TEST_F(DiskSourceTreeTest, OrderingTrumpsSpecificity) { |
@@ -367,7 +453,8 @@ TEST_F(DiskSourceTreeTest, OrderingTrumpsSpecificity) { |
// directory is more-specific than a former one. |
// Create the "bar" directory so we can put a file in it. |
- GOOGLE_CHECK_OK(File::CreateDir(dirnames_[0] + "/bar", 0777)); |
+ ASSERT_TRUE(File::CreateDir((dirnames_[0] + "/bar").c_str(), |
+ DEFAULT_FILE_MODE)); |
// Add files and map paths. |
AddFile(dirnames_[0] + "/bar/foo", "Hello World!"); |