options_unittest.cpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /*
  2. * Copyright (C) 2015, The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "options.h"
  17. #include <iostream>
  18. #include <memory>
  19. #include <string>
  20. #include <vector>
  21. #include <gtest/gtest.h>
  22. using std::cerr;
  23. using std::endl;
  24. using std::string;
  25. using std::unique_ptr;
  26. using std::vector;
  27. namespace android {
  28. namespace aidl {
  29. namespace {
  30. const char kPreprocessCommandOutputFile[] = "output_file_name";
  31. const char kPreprocessCommandInput1[] = "input1.aidl";
  32. const char kPreprocessCommandInput2[] = "input2.aidl";
  33. const char kPreprocessCommandInput3[] = "input3.aidl";
  34. const char* kPreprocessCommand[] = {
  35. "aidl", "--preprocess",
  36. kPreprocessCommandOutputFile,
  37. kPreprocessCommandInput1,
  38. kPreprocessCommandInput2,
  39. kPreprocessCommandInput3,
  40. nullptr,
  41. };
  42. const char kCompileCommandInput[] = "directory/ITool.aidl";
  43. const char kCompileCommandIncludePath[] = "-Iinclude_path";
  44. const char* kCompileJavaCommand[] = {
  45. "aidl",
  46. "-b",
  47. kCompileCommandIncludePath,
  48. kCompileCommandInput,
  49. nullptr,
  50. };
  51. const char kCompileCommandJavaOutput[] = "directory/ITool.java";
  52. const char kCompileDepFileNinja[] = "--ninja";
  53. const char* kCompileJavaCommandNinja[] = {
  54. "aidl",
  55. "-b",
  56. kCompileDepFileNinja,
  57. kCompileCommandIncludePath,
  58. kCompileCommandInput,
  59. nullptr,
  60. };
  61. const char kCompileDepFile[] = "-doutput.deps";
  62. const char kCompileCommandHeaderDir[] = "output/dir/";
  63. const char kCompileCommandCppOutput[] = "some/file.cpp";
  64. const char* kCompileCppCommand[] = {
  65. "aidl-cpp",
  66. kCompileCommandIncludePath,
  67. kCompileDepFile,
  68. kCompileCommandInput,
  69. kCompileCommandHeaderDir,
  70. kCompileCommandCppOutput,
  71. nullptr,
  72. };
  73. const char* kCompileCppCommandNinja[] = {
  74. "aidl-cpp",
  75. kCompileCommandIncludePath,
  76. kCompileDepFile,
  77. kCompileDepFileNinja,
  78. kCompileCommandInput,
  79. kCompileCommandHeaderDir,
  80. kCompileCommandCppOutput,
  81. nullptr,
  82. };
  83. unique_ptr<Options> GetOptions(const char* command[],
  84. Options::Language default_lang = Options::Language::JAVA) {
  85. int argc = 0;
  86. const char** command_part = command;
  87. for (; *command_part; ++argc, ++command_part) {}
  88. unique_ptr<Options> ret(new Options(argc, command, default_lang));
  89. if (!ret->Ok()) {
  90. cerr << ret->GetErrorMessage();
  91. cerr << "Failed to parse command line:";
  92. for (int i = 0; i < argc; ++i) {
  93. cerr << " " << command[i];
  94. cerr << endl;
  95. }
  96. }
  97. EXPECT_NE(ret, nullptr) << "Failed to parse options!";
  98. return ret;
  99. }
  100. } // namespace
  101. TEST(OptionsTests, ParsesPreprocess) {
  102. unique_ptr<Options> options = GetOptions(kPreprocessCommand);
  103. EXPECT_EQ(Options::Task::PREPROCESS, options->GetTask());
  104. EXPECT_EQ(false, options->FailOnParcelable());
  105. EXPECT_EQ(0u, options->ImportDirs().size());
  106. EXPECT_EQ(0u, options->PreprocessedFiles().size());
  107. EXPECT_EQ(string{kPreprocessCommandOutputFile}, options->OutputFile());
  108. EXPECT_EQ(false, options->AutoDepFile());
  109. const vector<string> expected_input{kPreprocessCommandInput1,
  110. kPreprocessCommandInput2,
  111. kPreprocessCommandInput3};
  112. EXPECT_EQ(expected_input, options->InputFiles());
  113. }
  114. TEST(OptionsTests, ParsesCompileJava) {
  115. unique_ptr<Options> options = GetOptions(kCompileJavaCommand);
  116. EXPECT_EQ(Options::Task::COMPILE, options->GetTask());
  117. EXPECT_EQ(Options::Language::JAVA, options->TargetLanguage());
  118. EXPECT_EQ(true, options->FailOnParcelable());
  119. EXPECT_EQ(1u, options->ImportDirs().size());
  120. EXPECT_EQ(0u, options->PreprocessedFiles().size());
  121. EXPECT_EQ(string{kCompileCommandInput}, options->InputFiles().front());
  122. EXPECT_EQ(string{kCompileCommandJavaOutput}, options->OutputFile());
  123. EXPECT_EQ(false, options->AutoDepFile());
  124. EXPECT_EQ(false, options->DependencyFileNinja());
  125. }
  126. TEST(OptionsTests, ParsesCompileJavaNinja) {
  127. unique_ptr<Options> options = GetOptions(kCompileJavaCommandNinja);
  128. EXPECT_EQ(Options::Task::COMPILE, options->GetTask());
  129. EXPECT_EQ(Options::Language::JAVA, options->TargetLanguage());
  130. EXPECT_EQ(true, options->FailOnParcelable());
  131. EXPECT_EQ(1u, options->ImportDirs().size());
  132. EXPECT_EQ(0u, options->PreprocessedFiles().size());
  133. EXPECT_EQ(string{kCompileCommandInput}, options->InputFiles().front());
  134. EXPECT_EQ(string{kCompileCommandJavaOutput}, options->OutputFile());
  135. EXPECT_EQ(false, options->AutoDepFile());
  136. EXPECT_EQ(true, options->DependencyFileNinja());
  137. }
  138. TEST(OptionsTests, ParsesCompileCpp) {
  139. unique_ptr<Options> options = GetOptions(kCompileCppCommand, Options::Language::CPP);
  140. ASSERT_EQ(1u, options->ImportDirs().size());
  141. EXPECT_EQ(string{kCompileCommandIncludePath}.substr(2), *options->ImportDirs().begin());
  142. EXPECT_EQ(string{kCompileDepFile}.substr(2), options->DependencyFile());
  143. EXPECT_EQ(false, options->DependencyFileNinja());
  144. EXPECT_EQ(kCompileCommandInput, options->InputFiles().front());
  145. EXPECT_EQ(kCompileCommandHeaderDir, options->OutputHeaderDir());
  146. EXPECT_EQ(kCompileCommandCppOutput, options->OutputFile());
  147. }
  148. TEST(OptionsTests, ParsesCompileCppNinja) {
  149. unique_ptr<Options> options = GetOptions(kCompileCppCommandNinja, Options::Language::CPP);
  150. ASSERT_EQ(1u, options->ImportDirs().size());
  151. EXPECT_EQ(string{kCompileCommandIncludePath}.substr(2), *options->ImportDirs().begin());
  152. EXPECT_EQ(string{kCompileDepFile}.substr(2), options->DependencyFile());
  153. EXPECT_EQ(true, options->DependencyFileNinja());
  154. EXPECT_EQ(kCompileCommandInput, options->InputFiles().front());
  155. EXPECT_EQ(kCompileCommandHeaderDir, options->OutputHeaderDir());
  156. EXPECT_EQ(kCompileCommandCppOutput, options->OutputFile());
  157. }
  158. TEST(OptionsTests, ParsesCompileJavaMultiInput) {
  159. const char* argv[] = {
  160. "aidl",
  161. "--lang=java",
  162. kCompileCommandIncludePath,
  163. "-o src_out",
  164. "directory/input1.aidl",
  165. "directory/input2.aidl",
  166. "directory/input3.aidl",
  167. nullptr,
  168. };
  169. unique_ptr<Options> options = GetOptions(argv);
  170. EXPECT_EQ(Options::Task::COMPILE, options->GetTask());
  171. EXPECT_EQ(Options::Language::JAVA, options->TargetLanguage());
  172. EXPECT_EQ(false, options->FailOnParcelable());
  173. EXPECT_EQ(1u, options->ImportDirs().size());
  174. EXPECT_EQ(0u, options->PreprocessedFiles().size());
  175. const vector<string> expected_input{"directory/input1.aidl", "directory/input2.aidl",
  176. "directory/input3.aidl"};
  177. EXPECT_EQ(expected_input, options->InputFiles());
  178. EXPECT_EQ(string{""}, options->OutputFile());
  179. EXPECT_EQ(false, options->AutoDepFile());
  180. EXPECT_EQ(false, options->DependencyFileNinja());
  181. EXPECT_EQ(string{""}, options->OutputHeaderDir());
  182. EXPECT_EQ(string{"src_out/"}, options->OutputDir());
  183. }
  184. TEST(OptionsTests, ParsesCompileJavaInvalid) {
  185. // -o option is required
  186. const char* arg_with_no_out_dir[] = {
  187. "aidl",
  188. "--lang=java",
  189. kCompileCommandIncludePath,
  190. "directory/input1.aidl",
  191. "directory/input2.aidl",
  192. "directory/input3.aidl",
  193. nullptr,
  194. };
  195. EXPECT_EQ(false, GetOptions(arg_with_no_out_dir)->Ok());
  196. // -h options is not for Java
  197. const char* arg_with_header_dir[] = {
  198. "aidl", "--lang=java", kCompileCommandIncludePath, "-o src_out",
  199. "-h header_out", "directory/input1.aidl", "directory/input2.aidl", "directory/input3.aidl",
  200. nullptr,
  201. };
  202. EXPECT_EQ(false, GetOptions(arg_with_header_dir)->Ok());
  203. }
  204. TEST(OptionsTests, ParsesCompileCppMultiInput) {
  205. const char* argv[] = {
  206. "aidl",
  207. "--lang=cpp",
  208. kCompileCommandIncludePath,
  209. "-h header_out",
  210. "-o src_out",
  211. "directory/input1.aidl",
  212. "directory/input2.aidl",
  213. "directory/input3.aidl",
  214. nullptr,
  215. };
  216. unique_ptr<Options> options = GetOptions(argv);
  217. EXPECT_EQ(Options::Task::COMPILE, options->GetTask());
  218. EXPECT_EQ(Options::Language::CPP, options->TargetLanguage());
  219. EXPECT_EQ(false, options->FailOnParcelable());
  220. EXPECT_EQ(1u, options->ImportDirs().size());
  221. EXPECT_EQ(0u, options->PreprocessedFiles().size());
  222. const vector<string> expected_input{"directory/input1.aidl", "directory/input2.aidl",
  223. "directory/input3.aidl"};
  224. EXPECT_EQ(expected_input, options->InputFiles());
  225. EXPECT_EQ(string{""}, options->OutputFile());
  226. EXPECT_EQ(false, options->AutoDepFile());
  227. EXPECT_EQ(false, options->DependencyFileNinja());
  228. EXPECT_EQ(string{"header_out/"}, options->OutputHeaderDir());
  229. EXPECT_EQ(string{"src_out/"}, options->OutputDir());
  230. }
  231. TEST(OptionsTests, ParsesCompileCppInvalid) {
  232. // -o option is required
  233. const char* arg_with_no_out_dir[] = {
  234. "aidl",
  235. "--lang=cpp",
  236. kCompileCommandIncludePath,
  237. "directory/input1.aidl",
  238. "directory/input2.aidl",
  239. "directory/input3.aidl",
  240. nullptr,
  241. };
  242. EXPECT_EQ(false, GetOptions(arg_with_no_out_dir)->Ok());
  243. // -h options is required as well
  244. const char* arg_with_no_header_dir[] = {
  245. "aidl",
  246. "--lang=cpp",
  247. kCompileCommandIncludePath,
  248. "-o src_out",
  249. "directory/input1.aidl",
  250. "directory/input2.aidl",
  251. "directory/input3.aidl",
  252. nullptr,
  253. };
  254. EXPECT_EQ(false, GetOptions(arg_with_no_header_dir)->Ok());
  255. }
  256. } // namespace android
  257. } // namespace aidl