blob: e293e9997bc7c3ecd007b1055414b1a553f46395 [file] [log] [blame]
William A. Kennington IIIe335ed92018-01-23 22:13:44 -08001#include <string>
William A. Kennington III5d307182018-01-23 22:00:55 -08002#include <vector>
William A. Kennington IIIe335ed92018-01-23 22:13:44 -08003
4#include "argument.hpp"
5#include "argument_test.hpp"
6
7static const std::string expected_path1 = "/arg1-test-path";
8static const std::string expected_target1 = "t1.target";
William A. Kennington III5d307182018-01-23 22:00:55 -08009static const std::string expected_target2 = "t2.target";
William A. Kennington IIIe335ed92018-01-23 22:13:44 -080010
11// Allow for a single unrecognized option then the Usage printout
12static const std::string invalid_arg_regex =
13 "^[^\n]*unrecognized option[^\n]*\nUsage: ";
14
15static const std::string clean_usage_regex = "^Usage: ";
16
17namespace phosphor
18{
19namespace watchdog
20{
21
22void ArgumentTest::SetUp()
23{
24 arg0 = "argument_test";
25}
26
27/** @brief ArgumentParser should return no values if given no options */
28TEST_F(ArgumentTest, NoOptions)
29{
30 char * const args[] = {
31 &arg0[0], nullptr
32 };
33 ArgumentParser ap(sizeof(args)/sizeof(char *) - 1, args);
William A. Kennington III5d307182018-01-23 22:00:55 -080034 EXPECT_EQ(std::vector<std::string>({}), ap["path"]);
35 EXPECT_EQ(std::vector<std::string>({}), ap["continue"]);
36 EXPECT_EQ(std::vector<std::string>({}), ap["arbitrary_unknown"]);
William A. Kennington IIIe335ed92018-01-23 22:13:44 -080037}
38
39/** @brief ArgumentParser should return true for an existing no-arg option
40 * Make sure we don't parse arguments if an option takes none
41 * Also make sure we don't populate options not used.
42 */
43TEST_F(ArgumentTest, LongOptionNoArg)
44{
45 std::string arg_continue = "--continue";
46 std::string arg_extra = "not-a-bool";
47 char * const args[] = {
48 &arg0[0], &arg_continue[0], &arg_extra[0], nullptr
49 };
50 ArgumentParser ap(sizeof(args)/sizeof(char *) - 1, args);
William A. Kennington III5d307182018-01-23 22:00:55 -080051 EXPECT_EQ(std::vector<std::string>({}), ap["path"]);
52 EXPECT_EQ(std::vector<std::string>({ArgumentParser::trueString}),
53 ap["continue"]);
William A. Kennington IIIe335ed92018-01-23 22:13:44 -080054}
55
56/** @brief ArgumentParser should return a string for long options that
57 * take an arg
58 */
59TEST_F(ArgumentTest, LongOptionRequiredArg)
60{
61 std::string arg_path = "--path";
62 std::string arg_path_val = expected_path1;
63 std::string arg_extra = "/unused-path";
64 char * const args[] = {
65 &arg0[0], &arg_path[0], &arg_path_val[0], &arg_extra[0], nullptr
66 };
67 ArgumentParser ap(sizeof(args)/sizeof(char *) - 1, args);
William A. Kennington III5d307182018-01-23 22:00:55 -080068 EXPECT_EQ(std::vector<std::string>({expected_path1}), ap["path"]);
William A. Kennington IIIe335ed92018-01-23 22:13:44 -080069}
70
71/** @brief ArgumentParser should return a string for long options that
72 * accept an argument when passed an argument inline
73 */
74TEST_F(ArgumentTest, LongOptionInlineArg)
75{
76 std::string arg_path = "--path=" + expected_path1;
77 std::string arg_extra = "/unused-path";
78 char * const args[] = {
79 &arg0[0], &arg_path[0], &arg_extra[0], nullptr
80 };
81 ArgumentParser ap(sizeof(args)/sizeof(char *) - 1, args);
William A. Kennington III5d307182018-01-23 22:00:55 -080082 EXPECT_EQ(std::vector<std::string>({expected_path1}), ap["path"]);
William A. Kennington IIIe335ed92018-01-23 22:13:44 -080083}
84
85/** @brief ArgumentParser should return a string for short options that
86 * accept an argument.
87 */
88TEST_F(ArgumentTest, ShortOptionRequiredArg)
89{
90 std::string arg_path = "-p";
91 std::string arg_path_val = expected_path1;
92 std::string arg_extra = "/unused-path";
93 char * const args[] = {
94 &arg0[0], &arg_path[0], &arg_path_val[0], &arg_extra[0], nullptr
95 };
96 ArgumentParser ap(sizeof(args)/sizeof(char *) - 1, args);
William A. Kennington III5d307182018-01-23 22:00:55 -080097 EXPECT_EQ(std::vector<std::string>({expected_path1}), ap["path"]);
William A. Kennington IIIe335ed92018-01-23 22:13:44 -080098}
99
100/** @brief ArgumentParser should be able to handle parsing multiple options
William A. Kennington IIIe335ed92018-01-23 22:13:44 -0800101 * Make sure this works for no-arg and required-arg type options
102 * Make sure this works between short and long options
103 */
104TEST_F(ArgumentTest, MultiOptionOverride)
105{
106 std::string arg_continue_short = "-c";
107 std::string arg_path = "--path=" + expected_path1;
108 std::string arg_continue_long = "--continue";
William A. Kennington III5d307182018-01-23 22:00:55 -0800109 std::string arg_target = "--target=" + expected_target2;
William A. Kennington IIIe335ed92018-01-23 22:13:44 -0800110 std::string arg_target_short = "-t";
111 std::string arg_target_val = expected_target1;
112 char * const args[] = {
113 &arg0[0], &arg_continue_short[0], &arg_path[0], &arg_continue_long[0],
114 &arg_target[0], &arg_target_short[0], &arg_target_val[0], nullptr
115 };
116 ArgumentParser ap(sizeof(args)/sizeof(char *) - 1, args);
William A. Kennington III5d307182018-01-23 22:00:55 -0800117 EXPECT_EQ(std::vector<std::string>({expected_path1}), ap["path"]);
118 EXPECT_EQ(std::vector<std::string>({
119 ArgumentParser::trueString, ArgumentParser::trueString}),
120 ap["continue"]);
121 EXPECT_EQ(std::vector<std::string>({expected_target2, expected_target1}),
122 ap["target"]);
William A. Kennington IIIe335ed92018-01-23 22:13:44 -0800123}
124
125/** @brief ArgumentParser should print usage information when given a help
126 * argument anywhere in the arguments array
127 */
128TEST_F(ArgumentTest, ShortOptionHelp)
129{
130 std::string arg_extra = "extra";
131 std::string arg_help = "-h";
132 char * const args[] = {
133 &arg0[0], &arg_extra[0], &arg_help[0], nullptr
134 };
135 EXPECT_EXIT(ArgumentParser(sizeof(args)/sizeof(char *) - 1, args),
136 ::testing::ExitedWithCode(255), clean_usage_regex);
137}
138
139/** @brief ArgumentParser should print usage information when given a help
140 * argument anywhere in the arguments array
141 */
142TEST_F(ArgumentTest, LongOptionHelp)
143{
144 std::string arg_help = "--help";
145 std::string arg_extra = "extra";
146 char * const args[] = {
147 &arg0[0], &arg_help[0], &arg_extra[0], nullptr
148 };
149 EXPECT_EXIT(ArgumentParser(sizeof(args)/sizeof(char *) - 1, args),
150 ::testing::ExitedWithCode(255), clean_usage_regex);
151}
152
153/** @brief ArgumentParser should print an invalid argument error and
154 * usage information when given an invalid argument anywhere
155 * in the arguments array
156 */
157TEST_F(ArgumentTest, InvalidOptionHelp)
158{
159 std::string arg_continue = "--continue";
160 std::string arg_bad = "--bad_arg";
161 std::string arg_target = "--target=/unused-path";
162 char * const args[] = {
163 &arg0[0], &arg_continue[0], &arg_bad[0], &arg_target[0], nullptr
164 };
165 EXPECT_EXIT(ArgumentParser(sizeof(args)/sizeof(char *) - 1, args),
166 ::testing::ExitedWithCode(255), invalid_arg_regex);
167}
168
169} // namespace watchdog
170} // namespace phosphor