| /* |
| * Copyright (C) 2015, The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "options.h" |
| |
| #include <iostream> |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include <gtest/gtest.h> |
| |
| using std::cerr; |
| using std::endl; |
| using std::string; |
| using std::unique_ptr; |
| using std::vector; |
| |
| namespace android { |
| namespace aidl { |
| namespace { |
| |
| const char kPreprocessCommandOutputFile[] = "output_file_name"; |
| const char kPreprocessCommandInput1[] = "input1.aidl"; |
| const char kPreprocessCommandInput2[] = "input2.aidl"; |
| const char kPreprocessCommandInput3[] = "input3.aidl"; |
| const char* kPreprocessCommand[] = { |
| "aidl", "--preprocess", |
| kPreprocessCommandOutputFile, |
| kPreprocessCommandInput1, |
| kPreprocessCommandInput2, |
| kPreprocessCommandInput3, |
| nullptr, |
| }; |
| |
| const char kCompileCommandInput[] = "directory/ITool.aidl"; |
| const char kCompileCommandIncludePath[] = "-Iinclude_path"; |
| const char* kCompileJavaCommand[] = { |
| "aidl", |
| "-b", |
| kCompileCommandIncludePath, |
| kCompileCommandInput, |
| nullptr, |
| }; |
| const char kCompileCommandJavaOutput[] = "directory/ITool.java"; |
| |
| const char kCompileDepFileNinja[] = "--ninja"; |
| const char* kCompileJavaCommandNinja[] = { |
| "aidl", |
| "-b", |
| kCompileDepFileNinja, |
| kCompileCommandIncludePath, |
| kCompileCommandInput, |
| nullptr, |
| }; |
| |
| const char kCompileDepFile[] = "-doutput.deps"; |
| const char kCompileCommandHeaderDir[] = "output/dir/"; |
| const char kCompileCommandCppOutput[] = "some/file.cpp"; |
| const char* kCompileCppCommand[] = { |
| "aidl-cpp", |
| kCompileCommandIncludePath, |
| kCompileDepFile, |
| kCompileCommandInput, |
| kCompileCommandHeaderDir, |
| kCompileCommandCppOutput, |
| nullptr, |
| }; |
| const char* kCompileCppCommandNinja[] = { |
| "aidl-cpp", |
| kCompileCommandIncludePath, |
| kCompileDepFile, |
| kCompileDepFileNinja, |
| kCompileCommandInput, |
| kCompileCommandHeaderDir, |
| kCompileCommandCppOutput, |
| nullptr, |
| }; |
| |
| unique_ptr<Options> GetOptions(const char* command[], |
| Options::Language default_lang = Options::Language::JAVA) { |
| int argc = 0; |
| const char** command_part = command; |
| for (; *command_part; ++argc, ++command_part) {} |
| unique_ptr<Options> ret(new Options(argc, command, default_lang)); |
| if (!ret->Ok()) { |
| cerr << ret->GetErrorMessage(); |
| cerr << "Failed to parse command line:"; |
| for (int i = 0; i < argc; ++i) { |
| cerr << " " << command[i]; |
| cerr << endl; |
| } |
| } |
| EXPECT_NE(ret, nullptr) << "Failed to parse options!"; |
| return ret; |
| } |
| |
| } // namespace |
| |
| TEST(OptionsTests, ParsesPreprocess) { |
| unique_ptr<Options> options = GetOptions(kPreprocessCommand); |
| EXPECT_EQ(Options::Task::PREPROCESS, options->GetTask()); |
| EXPECT_EQ(false, options->FailOnParcelable()); |
| EXPECT_EQ(0u, options->ImportDirs().size()); |
| EXPECT_EQ(0u, options->PreprocessedFiles().size()); |
| EXPECT_EQ(string{kPreprocessCommandOutputFile}, options->OutputFile()); |
| EXPECT_EQ(false, options->AutoDepFile()); |
| const vector<string> expected_input{kPreprocessCommandInput1, |
| kPreprocessCommandInput2, |
| kPreprocessCommandInput3}; |
| EXPECT_EQ(expected_input, options->InputFiles()); |
| } |
| |
| TEST(OptionsTests, ParsesCompileJava) { |
| unique_ptr<Options> options = GetOptions(kCompileJavaCommand); |
| EXPECT_EQ(Options::Task::COMPILE, options->GetTask()); |
| EXPECT_EQ(Options::Language::JAVA, options->TargetLanguage()); |
| EXPECT_EQ(true, options->FailOnParcelable()); |
| EXPECT_EQ(1u, options->ImportDirs().size()); |
| EXPECT_EQ(0u, options->PreprocessedFiles().size()); |
| EXPECT_EQ(string{kCompileCommandInput}, options->InputFiles().front()); |
| EXPECT_EQ(string{kCompileCommandJavaOutput}, options->OutputFile()); |
| EXPECT_EQ(false, options->AutoDepFile()); |
| EXPECT_EQ(false, options->DependencyFileNinja()); |
| EXPECT_EQ(false, options->GenParcelableToString()); |
| |
| const char* argv[] = { |
| "aidl", "-b", kCompileCommandIncludePath, kCompileCommandInput, "--parcelable-to-string", |
| nullptr, |
| }; |
| options = GetOptions(argv); |
| EXPECT_EQ(Options::Task::COMPILE, options->GetTask()); |
| EXPECT_EQ(Options::Language::JAVA, options->TargetLanguage()); |
| EXPECT_EQ(true, options->FailOnParcelable()); |
| EXPECT_EQ(1u, options->ImportDirs().size()); |
| EXPECT_EQ(0u, options->PreprocessedFiles().size()); |
| EXPECT_EQ(string{kCompileCommandInput}, options->InputFiles().front()); |
| EXPECT_EQ(string{kCompileCommandJavaOutput}, options->OutputFile()); |
| EXPECT_EQ(false, options->AutoDepFile()); |
| EXPECT_EQ(false, options->DependencyFileNinja()); |
| EXPECT_EQ(true, options->GenParcelableToString()); |
| } |
| |
| TEST(OptionsTests, ParsesCompileJavaNinja) { |
| unique_ptr<Options> options = GetOptions(kCompileJavaCommandNinja); |
| EXPECT_EQ(Options::Task::COMPILE, options->GetTask()); |
| EXPECT_EQ(Options::Language::JAVA, options->TargetLanguage()); |
| EXPECT_EQ(true, options->FailOnParcelable()); |
| EXPECT_EQ(1u, options->ImportDirs().size()); |
| EXPECT_EQ(0u, options->PreprocessedFiles().size()); |
| EXPECT_EQ(string{kCompileCommandInput}, options->InputFiles().front()); |
| EXPECT_EQ(string{kCompileCommandJavaOutput}, options->OutputFile()); |
| EXPECT_EQ(false, options->AutoDepFile()); |
| EXPECT_EQ(true, options->DependencyFileNinja()); |
| } |
| |
| TEST(OptionsTests, ParsesCompileCpp) { |
| unique_ptr<Options> options = GetOptions(kCompileCppCommand, Options::Language::CPP); |
| ASSERT_EQ(1u, options->ImportDirs().size()); |
| EXPECT_EQ(string{kCompileCommandIncludePath}.substr(2), *options->ImportDirs().begin()); |
| EXPECT_EQ(string{kCompileDepFile}.substr(2), options->DependencyFile()); |
| EXPECT_EQ(false, options->DependencyFileNinja()); |
| EXPECT_EQ(kCompileCommandInput, options->InputFiles().front()); |
| EXPECT_EQ(kCompileCommandHeaderDir, options->OutputHeaderDir()); |
| EXPECT_EQ(kCompileCommandCppOutput, options->OutputFile()); |
| EXPECT_EQ(false, options->GenParcelableToString()); |
| |
| const char* argv[] = { |
| "aidl-cpp", |
| kCompileCommandIncludePath, |
| kCompileDepFile, |
| kCompileCommandInput, |
| kCompileCommandHeaderDir, |
| kCompileCommandCppOutput, |
| "--parcelable-to-string", |
| nullptr, |
| }; |
| options = GetOptions(argv, Options::Language::CPP); |
| ASSERT_EQ(1u, options->ImportDirs().size()); |
| EXPECT_EQ(string{kCompileCommandIncludePath}.substr(2), *options->ImportDirs().begin()); |
| EXPECT_EQ(string{kCompileDepFile}.substr(2), options->DependencyFile()); |
| EXPECT_EQ(false, options->DependencyFileNinja()); |
| EXPECT_EQ(kCompileCommandInput, options->InputFiles().front()); |
| EXPECT_EQ(kCompileCommandHeaderDir, options->OutputHeaderDir()); |
| EXPECT_EQ(kCompileCommandCppOutput, options->OutputFile()); |
| EXPECT_EQ(true, options->GenParcelableToString()); |
| } |
| |
| TEST(OptionsTests, ParsesCompileCppNinja) { |
| unique_ptr<Options> options = GetOptions(kCompileCppCommandNinja, Options::Language::CPP); |
| ASSERT_EQ(1u, options->ImportDirs().size()); |
| EXPECT_EQ(string{kCompileCommandIncludePath}.substr(2), *options->ImportDirs().begin()); |
| EXPECT_EQ(string{kCompileDepFile}.substr(2), options->DependencyFile()); |
| EXPECT_EQ(true, options->DependencyFileNinja()); |
| EXPECT_EQ(kCompileCommandInput, options->InputFiles().front()); |
| EXPECT_EQ(kCompileCommandHeaderDir, options->OutputHeaderDir()); |
| EXPECT_EQ(kCompileCommandCppOutput, options->OutputFile()); |
| } |
| |
| TEST(OptionsTests, ParsesCompileJavaMultiInput) { |
| const char* argv[] = { |
| "aidl", |
| "--lang=java", |
| kCompileCommandIncludePath, |
| "-o src_out", |
| "directory/input1.aidl", |
| "directory/input2.aidl", |
| "directory/input3.aidl", |
| nullptr, |
| }; |
| unique_ptr<Options> options = GetOptions(argv); |
| EXPECT_EQ(Options::Task::COMPILE, options->GetTask()); |
| EXPECT_EQ(Options::Language::JAVA, options->TargetLanguage()); |
| EXPECT_EQ(false, options->FailOnParcelable()); |
| EXPECT_EQ(1u, options->ImportDirs().size()); |
| EXPECT_EQ(0u, options->PreprocessedFiles().size()); |
| const vector<string> expected_input{"directory/input1.aidl", "directory/input2.aidl", |
| "directory/input3.aidl"}; |
| EXPECT_EQ(expected_input, options->InputFiles()); |
| EXPECT_EQ(string{""}, options->OutputFile()); |
| EXPECT_EQ(false, options->AutoDepFile()); |
| EXPECT_EQ(false, options->DependencyFileNinja()); |
| EXPECT_EQ(string{""}, options->OutputHeaderDir()); |
| EXPECT_EQ(string{"src_out/"}, options->OutputDir()); |
| } |
| |
| TEST(OptionsTests, ParsesCompileJavaInvalid) { |
| // -o option is required |
| const char* arg_with_no_out_dir[] = { |
| "aidl", |
| "--lang=java", |
| kCompileCommandIncludePath, |
| "directory/input1.aidl", |
| "directory/input2.aidl", |
| "directory/input3.aidl", |
| nullptr, |
| }; |
| EXPECT_EQ(false, GetOptions(arg_with_no_out_dir)->Ok()); |
| |
| // -h options is not for Java |
| const char* arg_with_header_dir[] = { |
| "aidl", "--lang=java", kCompileCommandIncludePath, "-o src_out", |
| "-h header_out", "directory/input1.aidl", "directory/input2.aidl", "directory/input3.aidl", |
| nullptr, |
| }; |
| EXPECT_EQ(false, GetOptions(arg_with_header_dir)->Ok()); |
| } |
| |
| TEST(OptionsTests, ParsesCompileCppMultiInput) { |
| const char* argv[] = { |
| "aidl", |
| "--lang=cpp", |
| kCompileCommandIncludePath, |
| "-h header_out", |
| "-o src_out", |
| "directory/input1.aidl", |
| "directory/input2.aidl", |
| "directory/input3.aidl", |
| nullptr, |
| }; |
| unique_ptr<Options> options = GetOptions(argv); |
| EXPECT_EQ(Options::Task::COMPILE, options->GetTask()); |
| EXPECT_EQ(Options::Language::CPP, options->TargetLanguage()); |
| EXPECT_EQ(false, options->FailOnParcelable()); |
| EXPECT_EQ(1u, options->ImportDirs().size()); |
| EXPECT_EQ(0u, options->PreprocessedFiles().size()); |
| const vector<string> expected_input{"directory/input1.aidl", "directory/input2.aidl", |
| "directory/input3.aidl"}; |
| EXPECT_EQ(expected_input, options->InputFiles()); |
| EXPECT_EQ(string{""}, options->OutputFile()); |
| EXPECT_EQ(false, options->AutoDepFile()); |
| EXPECT_EQ(false, options->DependencyFileNinja()); |
| EXPECT_EQ(string{"header_out/"}, options->OutputHeaderDir()); |
| EXPECT_EQ(string{"src_out/"}, options->OutputDir()); |
| } |
| |
| TEST(OptionsTests, ParsesCompileCppInvalid) { |
| // -o option is required |
| const char* arg_with_no_out_dir[] = { |
| "aidl", |
| "--lang=cpp", |
| kCompileCommandIncludePath, |
| "directory/input1.aidl", |
| "directory/input2.aidl", |
| "directory/input3.aidl", |
| nullptr, |
| }; |
| EXPECT_EQ(false, GetOptions(arg_with_no_out_dir)->Ok()); |
| |
| // -h options is required as well |
| const char* arg_with_no_header_dir[] = { |
| "aidl", |
| "--lang=cpp", |
| kCompileCommandIncludePath, |
| "-o src_out", |
| "directory/input1.aidl", |
| "directory/input2.aidl", |
| "directory/input3.aidl", |
| nullptr, |
| }; |
| EXPECT_EQ(false, GetOptions(arg_with_no_header_dir)->Ok()); |
| } |
| |
| } // namespace aidl |
| } // namespace android |