1// Protocol Buffers - Google's data interchange format 2// Copyright 2014 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#include <memory> 32 33#include <google/protobuf/compiler/ruby/ruby_generator.h> 34#include <google/protobuf/compiler/command_line_interface.h> 35#include <google/protobuf/io/zero_copy_stream.h> 36#include <google/protobuf/io/printer.h> 37 38#include <google/protobuf/testing/googletest.h> 39#include <gtest/gtest.h> 40#include <google/protobuf/testing/file.h> 41 42namespace google { 43namespace protobuf { 44namespace compiler { 45namespace ruby { 46namespace { 47 48string FindRubyTestDir(const string& file) { 49 // Inspired by TestSourceDir() in src/google/protobuf/testing/googletest.cc. 50#ifndef GOOGLE_THIRD_PARTY_PROTOBUF 51 string prefix = "."; 52 while (!File::Exists(prefix + "/src/google/protobuf/compiler/ruby" + file)) { 53 if (!File::Exists(prefix)) { 54 GOOGLE_LOG(FATAL) 55 << "Could not find Ruby test directory. Please run tests from " 56 "somewhere within the protobuf source package."; 57 } 58 prefix += "/.."; 59 } 60 return prefix + "/src/google/protobuf/compiler/ruby"; 61#else 62 return "third_party/protobuf/src/google/protobuf/compiler/ruby"; 63#endif // GOOGLE_THIRD_PARTY_PROTOBUF 64} 65 66// This test is a simple golden-file test over the output of the Ruby code 67// generator. When we make changes to the Ruby extension and alter the Ruby code 68// generator to use those changes, we should (i) manually test the output of the 69// code generator with the extension, and (ii) update the golden output above. 70// Some day, we may integrate build systems between protoc and the language 71// extensions to the point where we can do this test in a more automated way. 72 73TEST(RubyGeneratorTest, GeneratorTest) { 74 string ruby_tests = FindRubyTestDir("/ruby_generated_code.proto"); 75 76 google::protobuf::compiler::CommandLineInterface cli; 77 cli.SetInputsAreProtoPathRelative(true); 78 79 ruby::Generator ruby_generator; 80 cli.RegisterGenerator("--ruby_out", &ruby_generator, ""); 81 82 // Copy generated_code.proto to the temporary test directory. 83 string test_input; 84 GOOGLE_CHECK_OK(File::GetContents( 85 ruby_tests + "/ruby_generated_code.proto", 86 &test_input, 87 true)); 88 GOOGLE_CHECK_OK(File::SetContents( 89 TestTempDir() + "/ruby_generated_code.proto", 90 test_input, 91 true)); 92 93 // Invoke the proto compiler (we will be inside TestTempDir() at this point). 94 string ruby_out = "--ruby_out=" + TestTempDir(); 95 string proto_path = "--proto_path=" + TestTempDir(); 96 const char* argv[] = { 97 "protoc", 98 ruby_out.c_str(), 99 proto_path.c_str(), 100 "ruby_generated_code.proto", 101 }; 102 103 EXPECT_EQ(0, cli.Run(4, argv)); 104 105 // Load the generated output and compare to the expected result. 106 string output; 107 GOOGLE_CHECK_OK(File::GetContents( 108 TestTempDir() + "/ruby_generated_code.rb", 109 &output, 110 true)); 111 string expected_output; 112 GOOGLE_CHECK_OK(File::GetContents( 113 ruby_tests + "/ruby_generated_code.rb", 114 &expected_output, 115 true)); 116 EXPECT_EQ(expected_output, output); 117} 118 119} // namespace 120} // namespace ruby 121} // namespace compiler 122} // namespace protobuf 123} // namespace google 124