• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 #include "options.h"
18 
19 #include <iostream>
20 #include <memory>
21 #include <string>
22 #include <vector>
23 
24 #include <gtest/gtest.h>
25 
26 using std::cerr;
27 using std::endl;
28 using std::string;
29 using std::unique_ptr;
30 using std::vector;
31 
32 namespace android {
33 namespace aidl {
34 namespace {
35 
36 const char kPreprocessCommandOutputFile[] = "output_file_name";
37 const char kPreprocessCommandInput1[] = "input1.aidl";
38 const char kPreprocessCommandInput2[] = "input2.aidl";
39 const char kPreprocessCommandInput3[] = "input3.aidl";
40 const char* kPreprocessCommand[] = {
41     "aidl", "--preprocess",
42     kPreprocessCommandOutputFile,
43     kPreprocessCommandInput1,
44     kPreprocessCommandInput2,
45     kPreprocessCommandInput3,
46     nullptr,
47 };
48 
49 const char kCompileCommandInput[] = "directory/ITool.aidl";
50 const char kCompileCommandIncludePath[] = "-Iinclude_path";
51 const char* kCompileJavaCommand[] = {
52     "aidl",
53     "-b",
54     kCompileCommandIncludePath,
55     kCompileCommandInput,
56     nullptr,
57 };
58 const char kCompileCommandJavaOutput[] = "directory/ITool.java";
59 
60 const char kCompileDepFileNinja[] = "--ninja";
61 const char* kCompileJavaCommandNinja[] = {
62     "aidl",
63     "-b",
64     kCompileDepFileNinja,
65     kCompileCommandIncludePath,
66     kCompileCommandInput,
67     nullptr,
68 };
69 
70 const char kCompileDepFile[] = "-doutput.deps";
71 const char kCompileCommandHeaderDir[] = "output/dir/";
72 const char kCompileCommandCppOutput[] = "some/file.cpp";
73 const char* kCompileCppCommand[] = {
74     "aidl-cpp",
75     kCompileCommandIncludePath,
76     kCompileDepFile,
77     kCompileCommandInput,
78     kCompileCommandHeaderDir,
79     kCompileCommandCppOutput,
80     nullptr,
81 };
82 const char* kCompileCppCommandNinja[] = {
83     "aidl-cpp",
84     kCompileCommandIncludePath,
85     kCompileDepFile,
86     kCompileDepFileNinja,
87     kCompileCommandInput,
88     kCompileCommandHeaderDir,
89     kCompileCommandCppOutput,
90     nullptr,
91 };
92 
GetOptions(const char * command[],Options::Language default_lang=Options::Language::JAVA)93 unique_ptr<Options> GetOptions(const char* command[],
94                                Options::Language default_lang = Options::Language::JAVA) {
95   int argc = 0;
96   const char** command_part = command;
97   for (; *command_part; ++argc, ++command_part) {}
98   unique_ptr<Options> ret(new Options(argc, command, default_lang));
99   if (!ret->Ok()) {
100     cerr << ret->GetErrorMessage();
101     cerr << "Failed to parse command line:";
102     for (int i = 0; i < argc; ++i) {
103       cerr << " " << command[i];
104       cerr << endl;
105     }
106   }
107   EXPECT_NE(ret, nullptr) << "Failed to parse options!";
108   return ret;
109 }
110 
111 }  // namespace
112 
TEST(OptionsTests,ParsesPreprocess)113 TEST(OptionsTests, ParsesPreprocess) {
114   unique_ptr<Options> options = GetOptions(kPreprocessCommand);
115   EXPECT_EQ(Options::Task::PREPROCESS, options->GetTask());
116   EXPECT_EQ(false, options->FailOnParcelable());
117   EXPECT_EQ(0u, options->ImportDirs().size());
118   EXPECT_EQ(0u, options->PreprocessedFiles().size());
119   EXPECT_EQ(string{kPreprocessCommandOutputFile}, options->OutputFile());
120   EXPECT_EQ(false, options->AutoDepFile());
121   const vector<string> expected_input{kPreprocessCommandInput1,
122                                       kPreprocessCommandInput2,
123                                       kPreprocessCommandInput3};
124   EXPECT_EQ(expected_input, options->InputFiles());
125 }
126 
TEST(OptionsTests,ParsesCompileJava)127 TEST(OptionsTests, ParsesCompileJava) {
128   unique_ptr<Options> options = GetOptions(kCompileJavaCommand);
129   EXPECT_EQ(Options::Task::COMPILE, options->GetTask());
130   EXPECT_EQ(Options::Language::JAVA, options->TargetLanguage());
131   EXPECT_EQ(true, options->FailOnParcelable());
132   EXPECT_EQ(1u, options->ImportDirs().size());
133   EXPECT_EQ(0u, options->PreprocessedFiles().size());
134   EXPECT_EQ(string{kCompileCommandInput}, options->InputFiles().front());
135   EXPECT_EQ(string{kCompileCommandJavaOutput}, options->OutputFile());
136   EXPECT_EQ(false, options->AutoDepFile());
137   EXPECT_EQ(false, options->DependencyFileNinja());
138   EXPECT_EQ(false, options->GenParcelableToString());
139 
140   const char* argv[] = {
141       "aidl",  "-b", kCompileCommandIncludePath, kCompileCommandInput, "--parcelable-to-string",
142       nullptr,
143   };
144   options = GetOptions(argv);
145   EXPECT_EQ(Options::Task::COMPILE, options->GetTask());
146   EXPECT_EQ(Options::Language::JAVA, options->TargetLanguage());
147   EXPECT_EQ(true, options->FailOnParcelable());
148   EXPECT_EQ(1u, options->ImportDirs().size());
149   EXPECT_EQ(0u, options->PreprocessedFiles().size());
150   EXPECT_EQ(string{kCompileCommandInput}, options->InputFiles().front());
151   EXPECT_EQ(string{kCompileCommandJavaOutput}, options->OutputFile());
152   EXPECT_EQ(false, options->AutoDepFile());
153   EXPECT_EQ(false, options->DependencyFileNinja());
154   EXPECT_EQ(true, options->GenParcelableToString());
155 }
156 
TEST(OptionsTests,ParsesCompileJavaNinja)157 TEST(OptionsTests, ParsesCompileJavaNinja) {
158   unique_ptr<Options> options = GetOptions(kCompileJavaCommandNinja);
159   EXPECT_EQ(Options::Task::COMPILE, options->GetTask());
160   EXPECT_EQ(Options::Language::JAVA, options->TargetLanguage());
161   EXPECT_EQ(true, options->FailOnParcelable());
162   EXPECT_EQ(1u, options->ImportDirs().size());
163   EXPECT_EQ(0u, options->PreprocessedFiles().size());
164   EXPECT_EQ(string{kCompileCommandInput}, options->InputFiles().front());
165   EXPECT_EQ(string{kCompileCommandJavaOutput}, options->OutputFile());
166   EXPECT_EQ(false, options->AutoDepFile());
167   EXPECT_EQ(true, options->DependencyFileNinja());
168 }
169 
TEST(OptionsTests,ParsesCompileCpp)170 TEST(OptionsTests, ParsesCompileCpp) {
171   unique_ptr<Options> options = GetOptions(kCompileCppCommand, Options::Language::CPP);
172   ASSERT_EQ(1u, options->ImportDirs().size());
173   EXPECT_EQ(string{kCompileCommandIncludePath}.substr(2), *options->ImportDirs().begin());
174   EXPECT_EQ(string{kCompileDepFile}.substr(2), options->DependencyFile());
175   EXPECT_EQ(false, options->DependencyFileNinja());
176   EXPECT_EQ(kCompileCommandInput, options->InputFiles().front());
177   EXPECT_EQ(kCompileCommandHeaderDir, options->OutputHeaderDir());
178   EXPECT_EQ(kCompileCommandCppOutput, options->OutputFile());
179   EXPECT_EQ(false, options->GenParcelableToString());
180 
181   const char* argv[] = {
182       "aidl-cpp",
183       kCompileCommandIncludePath,
184       kCompileDepFile,
185       kCompileCommandInput,
186       kCompileCommandHeaderDir,
187       kCompileCommandCppOutput,
188       "--parcelable-to-string",
189       nullptr,
190   };
191   options = GetOptions(argv, Options::Language::CPP);
192   ASSERT_EQ(1u, options->ImportDirs().size());
193   EXPECT_EQ(string{kCompileCommandIncludePath}.substr(2), *options->ImportDirs().begin());
194   EXPECT_EQ(string{kCompileDepFile}.substr(2), options->DependencyFile());
195   EXPECT_EQ(false, options->DependencyFileNinja());
196   EXPECT_EQ(kCompileCommandInput, options->InputFiles().front());
197   EXPECT_EQ(kCompileCommandHeaderDir, options->OutputHeaderDir());
198   EXPECT_EQ(kCompileCommandCppOutput, options->OutputFile());
199   EXPECT_EQ(true, options->GenParcelableToString());
200 }
201 
TEST(OptionsTests,ParsesCompileCppNinja)202 TEST(OptionsTests, ParsesCompileCppNinja) {
203   unique_ptr<Options> options = GetOptions(kCompileCppCommandNinja, Options::Language::CPP);
204   ASSERT_EQ(1u, options->ImportDirs().size());
205   EXPECT_EQ(string{kCompileCommandIncludePath}.substr(2), *options->ImportDirs().begin());
206   EXPECT_EQ(string{kCompileDepFile}.substr(2), options->DependencyFile());
207   EXPECT_EQ(true, options->DependencyFileNinja());
208   EXPECT_EQ(kCompileCommandInput, options->InputFiles().front());
209   EXPECT_EQ(kCompileCommandHeaderDir, options->OutputHeaderDir());
210   EXPECT_EQ(kCompileCommandCppOutput, options->OutputFile());
211 }
212 
TEST(OptionsTests,ParsesCompileJavaMultiInput)213 TEST(OptionsTests, ParsesCompileJavaMultiInput) {
214   const char* argv[] = {
215       "aidl",
216       "--lang=java",
217       kCompileCommandIncludePath,
218       "-o src_out",
219       "directory/input1.aidl",
220       "directory/input2.aidl",
221       "directory/input3.aidl",
222       nullptr,
223   };
224   unique_ptr<Options> options = GetOptions(argv);
225   EXPECT_EQ(Options::Task::COMPILE, options->GetTask());
226   EXPECT_EQ(Options::Language::JAVA, options->TargetLanguage());
227   EXPECT_EQ(false, options->FailOnParcelable());
228   EXPECT_EQ(1u, options->ImportDirs().size());
229   EXPECT_EQ(0u, options->PreprocessedFiles().size());
230   const vector<string> expected_input{"directory/input1.aidl", "directory/input2.aidl",
231                                       "directory/input3.aidl"};
232   EXPECT_EQ(expected_input, options->InputFiles());
233   EXPECT_EQ(string{""}, options->OutputFile());
234   EXPECT_EQ(false, options->AutoDepFile());
235   EXPECT_EQ(false, options->DependencyFileNinja());
236   EXPECT_EQ(string{""}, options->OutputHeaderDir());
237   EXPECT_EQ(string{"src_out/"}, options->OutputDir());
238 }
239 
TEST(OptionsTests,ParsesCompileJavaInvalid)240 TEST(OptionsTests, ParsesCompileJavaInvalid) {
241   // -o option is required
242   const char* arg_with_no_out_dir[] = {
243       "aidl",
244       "--lang=java",
245       kCompileCommandIncludePath,
246       "directory/input1.aidl",
247       "directory/input2.aidl",
248       "directory/input3.aidl",
249       nullptr,
250   };
251   EXPECT_EQ(false, GetOptions(arg_with_no_out_dir)->Ok());
252 
253   // -h options is not for Java
254   const char* arg_with_header_dir[] = {
255       "aidl",          "--lang=java",           kCompileCommandIncludePath, "-o src_out",
256       "-h header_out", "directory/input1.aidl", "directory/input2.aidl",    "directory/input3.aidl",
257       nullptr,
258   };
259   EXPECT_EQ(false, GetOptions(arg_with_header_dir)->Ok());
260 }
261 
TEST(OptionsTests,ParsesCompileCppMultiInput)262 TEST(OptionsTests, ParsesCompileCppMultiInput) {
263   const char* argv[] = {
264       "aidl",
265       "--lang=cpp",
266       kCompileCommandIncludePath,
267       "-h header_out",
268       "-o src_out",
269       "directory/input1.aidl",
270       "directory/input2.aidl",
271       "directory/input3.aidl",
272       nullptr,
273   };
274   unique_ptr<Options> options = GetOptions(argv);
275   EXPECT_EQ(Options::Task::COMPILE, options->GetTask());
276   EXPECT_EQ(Options::Language::CPP, options->TargetLanguage());
277   EXPECT_EQ(false, options->FailOnParcelable());
278   EXPECT_EQ(1u, options->ImportDirs().size());
279   EXPECT_EQ(0u, options->PreprocessedFiles().size());
280   const vector<string> expected_input{"directory/input1.aidl", "directory/input2.aidl",
281                                       "directory/input3.aidl"};
282   EXPECT_EQ(expected_input, options->InputFiles());
283   EXPECT_EQ(string{""}, options->OutputFile());
284   EXPECT_EQ(false, options->AutoDepFile());
285   EXPECT_EQ(false, options->DependencyFileNinja());
286   EXPECT_EQ(string{"header_out/"}, options->OutputHeaderDir());
287   EXPECT_EQ(string{"src_out/"}, options->OutputDir());
288 }
289 
TEST(OptionsTests,ParsesCompileCppInvalid)290 TEST(OptionsTests, ParsesCompileCppInvalid) {
291   // -o option is required
292   const char* arg_with_no_out_dir[] = {
293       "aidl",
294       "--lang=cpp",
295       kCompileCommandIncludePath,
296       "directory/input1.aidl",
297       "directory/input2.aidl",
298       "directory/input3.aidl",
299       nullptr,
300   };
301   EXPECT_EQ(false, GetOptions(arg_with_no_out_dir)->Ok());
302 
303   // -h options is required as well
304   const char* arg_with_no_header_dir[] = {
305       "aidl",
306       "--lang=cpp",
307       kCompileCommandIncludePath,
308       "-o src_out",
309       "directory/input1.aidl",
310       "directory/input2.aidl",
311       "directory/input3.aidl",
312       nullptr,
313   };
314   EXPECT_EQ(false, GetOptions(arg_with_no_header_dir)->Ok());
315 }
316 
317 }  // namespace aidl
318 }  // namespace android
319