1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format 2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc. All rights reserved. 3afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// https://developers.google.com/protocol-buffers/ 4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without 6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are 7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met: 8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions of source code must retain the above copyright 10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer. 11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions in binary form must reproduce the above 12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer 13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the 14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution. 15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Neither the name of Google Inc. nor the names of its 16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from 17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission. 18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Author: kenton@google.com (Kenton Varda) 32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Based on original Protocol Buffers design by 33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Sanjay Ghemawat, Jeff Dean, and others. 34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 35b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <google/protobuf/compiler/importer.h> 36b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/hash.h> 38a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson#include <memory> 39b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#ifndef _SHARED_PTR_H 40b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <google/protobuf/stubs/shared_ptr.h> 41b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#endif 42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 43b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <google/protobuf/stubs/logging.h> 44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/common.h> 45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/testing/file.h> 46b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <google/protobuf/testing/file.h> 47b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <google/protobuf/testing/file.h> 48b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <google/protobuf/io/zero_copy_stream_impl.h> 49b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <google/protobuf/descriptor.h> 50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/strutil.h> 51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/substitute.h> 52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/testing/googletest.h> 53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <gtest/gtest.h> 54b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <google/protobuf/stubs/map_util.h> 55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google { 57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf { 58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace compiler { 59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace { 61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 62b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerbool FileExists(const string& path) { 63b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return File::Exists(path); 64b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 65b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define EXPECT_SUBSTRING(needle, haystack) \ 67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_PRED_FORMAT2(testing::IsSubstring, (needle), (haystack)) 68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleclass MockErrorCollector : public MultiFileErrorCollector { 70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public: 71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MockErrorCollector() {} 72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ~MockErrorCollector() {} 73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string text_; 75b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer string warning_text_; 76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // implements ErrorCollector --------------------------------------- 78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void AddError(const string& filename, int line, int column, 79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& message) { 80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", 81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville filename, line, column, message); 82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 83b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 84b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer void AddWarning(const string& filename, int line, int column, 85b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer const string& message) { 86b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer strings::SubstituteAndAppend(&warning_text_, "$0:$1:$2: $3\n", 87b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer filename, line, column, message); 88b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ------------------------------------------------------------------- 92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A dummy implementation of SourceTree backed by a simple map. 94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleclass MockSourceTree : public SourceTree { 95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public: 96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MockSourceTree() {} 97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ~MockSourceTree() {} 98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void AddFile(const string& name, const char* contents) { 100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville files_[name] = contents; 101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // implements SourceTree ------------------------------------------- 104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::ZeroCopyInputStream* Open(const string& filename) { 105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const char* contents = FindPtrOrNull(files_, filename); 106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (contents == NULL) { 107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return new io::ArrayInputStream(contents, strlen(contents)); 110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 113a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson string GetLastErrorMessage() { 114a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return "File not found."; 115a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 116a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville private: 118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville hash_map<string, const char*> files_; 119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =================================================================== 122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleclass ImporterTest : public testing::Test { 124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville protected: 125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ImporterTest() 126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : importer_(&source_tree_, &error_collector_) {} 127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void AddFile(const string& filename, const char* text) { 129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.AddFile(filename, text); 130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Return the collected error text 133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string error() const { return error_collector_.text_; } 134b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer string warning() const { return error_collector_.warning_text_; } 135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MockErrorCollector error_collector_; 137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MockSourceTree source_tree_; 138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Importer importer_; 139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(ImporterTest, Import) { 142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test normal importing. 143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddFile("foo.proto", 144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {}\n"); 146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FileDescriptor* file = importer_.Import("foo.proto"); 148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ("", error_collector_.text_); 149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASSERT_TRUE(file != NULL); 150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASSERT_EQ(1, file->message_type_count()); 152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ("Foo", file->message_type(0)->name()); 153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Importing again should return same object. 155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(file, importer_.Import("foo.proto")); 156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(ImporterTest, ImportNested) { 159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test that importing a file which imports another file works. 160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddFile("foo.proto", 161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "import \"bar.proto\";\n" 163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Foo {\n" 164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville " optional Bar bar = 1;\n" 165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "}\n"); 166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddFile("bar.proto", 167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message Bar {}\n"); 169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Note that both files are actually parsed by the first call to Import() 171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // here, since foo.proto imports bar.proto. The second call just returns 172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the same ProtoFile for bar.proto which was constructed while importing 173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // foo.proto. We test that this is the case below by checking that bar 174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // is among foo's dependencies (by pointer). 175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FileDescriptor* foo = importer_.Import("foo.proto"); 176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FileDescriptor* bar = importer_.Import("bar.proto"); 177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ("", error_collector_.text_); 178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASSERT_TRUE(foo != NULL); 179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASSERT_TRUE(bar != NULL); 180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Check that foo's dependency is the same object as bar. 182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASSERT_EQ(1, foo->dependency_count()); 183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(bar, foo->dependency(0)); 184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Check that foo properly cross-links bar. 186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASSERT_EQ(1, foo->message_type_count()); 187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASSERT_EQ(1, bar->message_type_count()); 188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASSERT_EQ(1, foo->message_type(0)->field_count()); 189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, 190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville foo->message_type(0)->field(0)->type()); 191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(bar->message_type(0), 192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville foo->message_type(0)->field(0)->message_type()); 193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(ImporterTest, FileNotFound) { 196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Error: Parsing a file that doesn't exist. 197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(importer_.Import("foo.proto") == NULL); 198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ( 199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "foo.proto:-1:0: File not found.\n", 200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville error_collector_.text_); 201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(ImporterTest, ImportNotFound) { 204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Error: Importing a file that doesn't exist. 205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddFile("foo.proto", 206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "import \"bar.proto\";\n"); 208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(importer_.Import("foo.proto") == NULL); 210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ( 211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "bar.proto:-1:0: File not found.\n" 212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "foo.proto:-1:0: Import \"bar.proto\" was not found or had errors.\n", 213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville error_collector_.text_); 214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(ImporterTest, RecursiveImport) { 217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Error: Recursive import. 218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddFile("recursive1.proto", 219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "import \"recursive2.proto\";\n"); 221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddFile("recursive2.proto", 222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "syntax = \"proto2\";\n" 223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "import \"recursive1.proto\";\n"); 224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(importer_.Import("recursive1.proto") == NULL); 226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ( 227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "recursive1.proto:-1:0: File recursively imports itself: recursive1.proto " 228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "-> recursive2.proto -> recursive1.proto\n" 229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "recursive2.proto:-1:0: Import \"recursive1.proto\" was not found " 230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "or had errors.\n" 231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "recursive1.proto:-1:0: Import \"recursive2.proto\" was not found " 232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "or had errors.\n", 233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville error_collector_.text_); 234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 236a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =================================================================== 238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleclass DiskSourceTreeTest : public testing::Test { 240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville protected: 241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville virtual void SetUp() { 242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville dirnames_.push_back(TestTempDir() + "/test_proto2_import_path_1"); 243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville dirnames_.push_back(TestTempDir() + "/test_proto2_import_path_2"); 244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < dirnames_.size(); i++) { 246b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (FileExists(dirnames_[i])) { 247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville File::DeleteRecursively(dirnames_[i], NULL, NULL); 248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 249a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GOOGLE_CHECK_OK(File::CreateDir(dirnames_[i], 0777)); 250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville virtual void TearDown() { 254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < dirnames_.size(); i++) { 255b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (FileExists(dirnames_[i])) { 256b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer File::DeleteRecursively(dirnames_[i], NULL, NULL); 257b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void AddFile(const string& filename, const char* contents) { 262a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GOOGLE_CHECK_OK(File::SetContents(filename, contents, true)); 263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void AddSubdir(const string& dirname) { 266a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GOOGLE_CHECK_OK(File::CreateDir(dirname, 0777)); 267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ExpectFileContents(const string& filename, 270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const char* expected_contents) { 271b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer google::protobuf::scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename)); 272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASSERT_FALSE(input == NULL); 274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Read all the data from the file. 276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string file_contents; 277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const void* data; 278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int size; 279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (input->Next(&data, &size)) { 280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file_contents.append(reinterpret_cast<const char*>(data), size); 281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(expected_contents, file_contents); 284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 286a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson void ExpectCannotOpenFile(const string& filename, 287a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const string& error_message) { 288b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer google::protobuf::scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename)); 289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(input == NULL); 290a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson EXPECT_EQ(error_message, source_tree_.GetLastErrorMessage()); 291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DiskSourceTree source_tree_; 294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Paths of two on-disk directories to use during the test. 296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<string> dirnames_; 297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(DiskSourceTreeTest, MapRoot) { 300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test opening a file in a directory that is mapped to the root of the 301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // source tree. 302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddFile(dirnames_[0] + "/foo", "Hello World!"); 303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.MapPath("", dirnames_[0]); 304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectFileContents("foo", "Hello World!"); 306a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson ExpectCannotOpenFile("bar", "File not found."); 307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(DiskSourceTreeTest, MapDirectory) { 310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test opening a file in a directory that is mapped to somewhere other 311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // than the root of the source tree. 312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddFile(dirnames_[0] + "/foo", "Hello World!"); 314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.MapPath("baz", dirnames_[0]); 315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectFileContents("baz/foo", "Hello World!"); 317a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson ExpectCannotOpenFile("baz/bar", "File not found."); 318a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson ExpectCannotOpenFile("foo", "File not found."); 319a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson ExpectCannotOpenFile("bar", "File not found."); 320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Non-canonical file names should not work. 322a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson ExpectCannotOpenFile("baz//foo", 323a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "Backslashes, consecutive slashes, \".\", or \"..\" are " 324a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "not allowed in the virtual path"); 325a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson ExpectCannotOpenFile("baz/../baz/foo", 326a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "Backslashes, consecutive slashes, \".\", or \"..\" are " 327a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "not allowed in the virtual path"); 328a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson ExpectCannotOpenFile("baz/./foo", 329a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "Backslashes, consecutive slashes, \".\", or \"..\" are " 330a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "not allowed in the virtual path"); 331a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson ExpectCannotOpenFile("baz/foo/", "File not found."); 332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(DiskSourceTreeTest, NoParent) { 335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test that we cannot open files in a parent of a mapped directory. 336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddFile(dirnames_[0] + "/foo", "Hello World!"); 338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddSubdir(dirnames_[0] + "/bar"); 339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddFile(dirnames_[0] + "/bar/baz", "Blah."); 340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.MapPath("", dirnames_[0] + "/bar"); 341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectFileContents("baz", "Blah."); 343a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson ExpectCannotOpenFile("../foo", 344a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "Backslashes, consecutive slashes, \".\", or \"..\" are " 345a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "not allowed in the virtual path"); 346a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson ExpectCannotOpenFile("../bar/baz", 347a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "Backslashes, consecutive slashes, \".\", or \"..\" are " 348a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "not allowed in the virtual path"); 349fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 350fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(DiskSourceTreeTest, MapFile) { 352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test opening a file that is mapped directly into the source tree. 353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 354fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddFile(dirnames_[0] + "/foo", "Hello World!"); 355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.MapPath("foo", dirnames_[0] + "/foo"); 356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectFileContents("foo", "Hello World!"); 358a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson ExpectCannotOpenFile("bar", "File not found."); 359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(DiskSourceTreeTest, SearchMultipleDirectories) { 362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test mapping and searching multiple directories. 363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddFile(dirnames_[0] + "/foo", "Hello World!"); 365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddFile(dirnames_[1] + "/foo", "This file should be hidden."); 366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddFile(dirnames_[1] + "/bar", "Goodbye World!"); 367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.MapPath("", dirnames_[0]); 368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.MapPath("", dirnames_[1]); 369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectFileContents("foo", "Hello World!"); 371fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectFileContents("bar", "Goodbye World!"); 372a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson ExpectCannotOpenFile("baz", "File not found."); 373fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(DiskSourceTreeTest, OrderingTrumpsSpecificity) { 376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test that directories are always searched in order, even when a latter 377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // directory is more-specific than a former one. 378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Create the "bar" directory so we can put a file in it. 380a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GOOGLE_CHECK_OK(File::CreateDir(dirnames_[0] + "/bar", 0777)); 381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Add files and map paths. 383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddFile(dirnames_[0] + "/bar/foo", "Hello World!"); 384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddFile(dirnames_[1] + "/foo", "This file should be hidden."); 385fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.MapPath("", dirnames_[0]); 386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.MapPath("bar", dirnames_[1]); 387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Check. 389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExpectFileContents("bar/foo", "Hello World!"); 390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(DiskSourceTreeTest, DiskFileToVirtualFile) { 393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test DiskFileToVirtualFile. 394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddFile(dirnames_[0] + "/foo", "Hello World!"); 396fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddFile(dirnames_[1] + "/foo", "This file should be hidden."); 397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.MapPath("bar", dirnames_[0]); 398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.MapPath("bar", dirnames_[1]); 399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string virtual_file; 401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string shadowing_disk_file; 402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 403fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(DiskSourceTree::NO_MAPPING, 404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.DiskFileToVirtualFile( 405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "/foo", &virtual_file, &shadowing_disk_file)); 406fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 407fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(DiskSourceTree::SHADOWED, 408fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.DiskFileToVirtualFile( 409fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville dirnames_[1] + "/foo", &virtual_file, &shadowing_disk_file)); 410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ("bar/foo", virtual_file); 411fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(dirnames_[0] + "/foo", shadowing_disk_file); 412fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 413fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(DiskSourceTree::CANNOT_OPEN, 414fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.DiskFileToVirtualFile( 415fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville dirnames_[1] + "/baz", &virtual_file, &shadowing_disk_file)); 416fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ("bar/baz", virtual_file); 417fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 418fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(DiskSourceTree::SUCCESS, 419fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.DiskFileToVirtualFile( 420fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville dirnames_[0] + "/foo", &virtual_file, &shadowing_disk_file)); 421fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ("bar/foo", virtual_file); 422fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 423fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 424fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(DiskSourceTreeTest, DiskFileToVirtualFileCanonicalization) { 425fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test handling of "..", ".", etc. in DiskFileToVirtualFile(). 426fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 427fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.MapPath("dir1", ".."); 428fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.MapPath("dir2", "../../foo"); 429fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.MapPath("dir3", "./foo/bar/."); 430fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.MapPath("dir4", "."); 431fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.MapPath("", "/qux"); 432fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.MapPath("dir5", "/quux/"); 433fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 434fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string virtual_file; 435fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string shadowing_disk_file; 436fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 437fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // "../.." should not be considered to be under "..". 438fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(DiskSourceTree::NO_MAPPING, 439fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.DiskFileToVirtualFile( 440fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "../../baz", &virtual_file, &shadowing_disk_file)); 441fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 442fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // "/foo" is not mapped (it should not be misintepreted as being under "."). 443fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(DiskSourceTree::NO_MAPPING, 444fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.DiskFileToVirtualFile( 445fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "/foo", &virtual_file, &shadowing_disk_file)); 446fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 447fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifdef WIN32 448fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // "C:\foo" is not mapped (it should not be misintepreted as being under "."). 449fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(DiskSourceTree::NO_MAPPING, 450fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.DiskFileToVirtualFile( 451fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "C:\\foo", &virtual_file, &shadowing_disk_file)); 452fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif // WIN32 453fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 454fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // But "../baz" should be. 455fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(DiskSourceTree::CANNOT_OPEN, 456fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.DiskFileToVirtualFile( 457fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "../baz", &virtual_file, &shadowing_disk_file)); 458fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ("dir1/baz", virtual_file); 459fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 460fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // "../../foo/baz" is under "../../foo". 461fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(DiskSourceTree::CANNOT_OPEN, 462fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.DiskFileToVirtualFile( 463fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "../../foo/baz", &virtual_file, &shadowing_disk_file)); 464fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ("dir2/baz", virtual_file); 465fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 466fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // "foo/./bar/baz" is under "./foo/bar/.". 467fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(DiskSourceTree::CANNOT_OPEN, 468fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.DiskFileToVirtualFile( 469fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "foo/bar/baz", &virtual_file, &shadowing_disk_file)); 470fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ("dir3/baz", virtual_file); 471fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 472fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // "bar" is under ".". 473fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(DiskSourceTree::CANNOT_OPEN, 474fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.DiskFileToVirtualFile( 475fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "bar", &virtual_file, &shadowing_disk_file)); 476fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ("dir4/bar", virtual_file); 477fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 478fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // "/qux/baz" is under "/qux". 479fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(DiskSourceTree::CANNOT_OPEN, 480fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.DiskFileToVirtualFile( 481fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "/qux/baz", &virtual_file, &shadowing_disk_file)); 482fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ("baz", virtual_file); 483fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 484fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // "/quux/bar" is under "/quux". 485fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(DiskSourceTree::CANNOT_OPEN, 486fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.DiskFileToVirtualFile( 487fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "/quux/bar", &virtual_file, &shadowing_disk_file)); 488fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ("dir5/bar", virtual_file); 489fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 490fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 491fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(DiskSourceTreeTest, VirtualFileToDiskFile) { 492fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test VirtualFileToDiskFile. 493fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 494fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddFile(dirnames_[0] + "/foo", "Hello World!"); 495fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddFile(dirnames_[1] + "/foo", "This file should be hidden."); 496fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddFile(dirnames_[1] + "/quux", "This file should not be hidden."); 497fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.MapPath("bar", dirnames_[0]); 498fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville source_tree_.MapPath("bar", dirnames_[1]); 499fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 500fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Existent files, shadowed and non-shadowed case. 501fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string disk_file; 502fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(source_tree_.VirtualFileToDiskFile("bar/foo", &disk_file)); 503fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(dirnames_[0] + "/foo", disk_file); 504fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(source_tree_.VirtualFileToDiskFile("bar/quux", &disk_file)); 505fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(dirnames_[1] + "/quux", disk_file); 506fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 507fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Nonexistent file in existent directory and vice versa. 508fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string not_touched = "not touched"; 509fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_FALSE(source_tree_.VirtualFileToDiskFile("bar/baz", ¬_touched)); 510fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ("not touched", not_touched); 511fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_FALSE(source_tree_.VirtualFileToDiskFile("baz/foo", ¬_touched)); 512fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ("not touched", not_touched); 513fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 514fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Accept NULL as output parameter. 515fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(source_tree_.VirtualFileToDiskFile("bar/foo", NULL)); 516fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_FALSE(source_tree_.VirtualFileToDiskFile("baz/foo", NULL)); 517fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 518fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 519fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace 520fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 521fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace compiler 522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace protobuf 523fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace google 524