blob: 3cb5dc9fe1556782110fbcae919b7d94d31a7755 [file] [log] [blame]
Patrick Venture8f6c5152018-09-11 17:45:33 -07001#include "argument_test.hpp"
William A. Kennington IIIe335ed92018-01-23 22:13:44 -08002
3#include "argument.hpp"
Patrick Venture8f6c5152018-09-11 17:45:33 -07004
5#include <string>
6#include <vector>
William A. Kennington IIIe335ed92018-01-23 22:13:44 -08007
8static const std::string expected_path1 = "/arg1-test-path";
9static const std::string expected_target1 = "t1.target";
William A. Kennington III5d307182018-01-23 22:00:55 -080010static const std::string expected_target2 = "t2.target";
William A. Kennington IIIe335ed92018-01-23 22:13:44 -080011
12// Allow for a single unrecognized option then the Usage printout
13static const std::string invalid_arg_regex =
Patrick Venture8f6c5152018-09-11 17:45:33 -070014 "^[^\n]*unrecognized option[^\n]*\nUsage: ";
William A. Kennington IIIe335ed92018-01-23 22:13:44 -080015
16static const std::string clean_usage_regex = "^Usage: ";
17
18namespace phosphor
19{
20namespace watchdog
21{
22
23void ArgumentTest::SetUp()
24{
25 arg0 = "argument_test";
26}
27
28/** @brief ArgumentParser should return no values if given no options */
29TEST_F(ArgumentTest, NoOptions)
30{
Patrick Venture8f6c5152018-09-11 17:45:33 -070031 char* const args[] = {&arg0[0], nullptr};
32 ArgumentParser ap(sizeof(args) / sizeof(char*) - 1, args);
William A. Kennington III5d307182018-01-23 22:00:55 -080033 EXPECT_EQ(std::vector<std::string>({}), ap["path"]);
34 EXPECT_EQ(std::vector<std::string>({}), ap["continue"]);
35 EXPECT_EQ(std::vector<std::string>({}), ap["arbitrary_unknown"]);
William A. Kennington IIIe335ed92018-01-23 22:13:44 -080036}
37
38/** @brief ArgumentParser should return true for an existing no-arg option
39 * Make sure we don't parse arguments if an option takes none
40 * Also make sure we don't populate options not used.
41 */
42TEST_F(ArgumentTest, LongOptionNoArg)
43{
44 std::string arg_continue = "--continue";
45 std::string arg_extra = "not-a-bool";
Patrick Venture8f6c5152018-09-11 17:45:33 -070046 char* const args[] = {&arg0[0], &arg_continue[0], &arg_extra[0], nullptr};
47 ArgumentParser ap(sizeof(args) / sizeof(char*) - 1, args);
William A. Kennington III5d307182018-01-23 22:00:55 -080048 EXPECT_EQ(std::vector<std::string>({}), ap["path"]);
49 EXPECT_EQ(std::vector<std::string>({ArgumentParser::trueString}),
Patrick Venture8f6c5152018-09-11 17:45:33 -070050 ap["continue"]);
William A. Kennington IIIe335ed92018-01-23 22:13:44 -080051}
52
53/** @brief ArgumentParser should return a string for long options that
54 * take an arg
55 */
56TEST_F(ArgumentTest, LongOptionRequiredArg)
57{
58 std::string arg_path = "--path";
59 std::string arg_path_val = expected_path1;
60 std::string arg_extra = "/unused-path";
Patrick Venture8f6c5152018-09-11 17:45:33 -070061 char* const args[] = {&arg0[0], &arg_path[0], &arg_path_val[0],
62 &arg_extra[0], nullptr};
63 ArgumentParser ap(sizeof(args) / sizeof(char*) - 1, args);
William A. Kennington III5d307182018-01-23 22:00:55 -080064 EXPECT_EQ(std::vector<std::string>({expected_path1}), ap["path"]);
William A. Kennington IIIe335ed92018-01-23 22:13:44 -080065}
66
67/** @brief ArgumentParser should return a string for long options that
68 * accept an argument when passed an argument inline
69 */
70TEST_F(ArgumentTest, LongOptionInlineArg)
71{
72 std::string arg_path = "--path=" + expected_path1;
73 std::string arg_extra = "/unused-path";
Patrick Venture8f6c5152018-09-11 17:45:33 -070074 char* const args[] = {&arg0[0], &arg_path[0], &arg_extra[0], nullptr};
75 ArgumentParser ap(sizeof(args) / sizeof(char*) - 1, args);
William A. Kennington III5d307182018-01-23 22:00:55 -080076 EXPECT_EQ(std::vector<std::string>({expected_path1}), ap["path"]);
William A. Kennington IIIe335ed92018-01-23 22:13:44 -080077}
78
79/** @brief ArgumentParser should return a string for short options that
80 * accept an argument.
81 */
82TEST_F(ArgumentTest, ShortOptionRequiredArg)
83{
84 std::string arg_path = "-p";
85 std::string arg_path_val = expected_path1;
86 std::string arg_extra = "/unused-path";
Patrick Venture8f6c5152018-09-11 17:45:33 -070087 char* const args[] = {&arg0[0], &arg_path[0], &arg_path_val[0],
88 &arg_extra[0], nullptr};
89 ArgumentParser ap(sizeof(args) / sizeof(char*) - 1, args);
William A. Kennington III5d307182018-01-23 22:00:55 -080090 EXPECT_EQ(std::vector<std::string>({expected_path1}), ap["path"]);
William A. Kennington IIIe335ed92018-01-23 22:13:44 -080091}
92
93/** @brief ArgumentParser should be able to handle parsing multiple options
William A. Kennington IIIe335ed92018-01-23 22:13:44 -080094 * Make sure this works for no-arg and required-arg type options
95 * Make sure this works between short and long options
96 */
97TEST_F(ArgumentTest, MultiOptionOverride)
98{
99 std::string arg_continue_short = "-c";
100 std::string arg_path = "--path=" + expected_path1;
101 std::string arg_continue_long = "--continue";
William A. Kennington III5d307182018-01-23 22:00:55 -0800102 std::string arg_target = "--target=" + expected_target2;
William A. Kennington IIIe335ed92018-01-23 22:13:44 -0800103 std::string arg_target_short = "-t";
104 std::string arg_target_val = expected_target1;
Patrick Venture8f6c5152018-09-11 17:45:33 -0700105 char* const args[] = {&arg0[0], &arg_continue_short[0],
106 &arg_path[0], &arg_continue_long[0],
107 &arg_target[0], &arg_target_short[0],
108 &arg_target_val[0], nullptr};
109 ArgumentParser ap(sizeof(args) / sizeof(char*) - 1, args);
William A. Kennington III5d307182018-01-23 22:00:55 -0800110 EXPECT_EQ(std::vector<std::string>({expected_path1}), ap["path"]);
Patrick Venture8f6c5152018-09-11 17:45:33 -0700111 EXPECT_EQ(std::vector<std::string>(
112 {ArgumentParser::trueString, ArgumentParser::trueString}),
113 ap["continue"]);
William A. Kennington III5d307182018-01-23 22:00:55 -0800114 EXPECT_EQ(std::vector<std::string>({expected_target2, expected_target1}),
Patrick Venture8f6c5152018-09-11 17:45:33 -0700115 ap["target"]);
William A. Kennington IIIe335ed92018-01-23 22:13:44 -0800116}
117
118/** @brief ArgumentParser should print usage information when given a help
119 * argument anywhere in the arguments array
120 */
121TEST_F(ArgumentTest, ShortOptionHelp)
122{
123 std::string arg_extra = "extra";
124 std::string arg_help = "-h";
Patrick Venture8f6c5152018-09-11 17:45:33 -0700125 char* const args[] = {&arg0[0], &arg_extra[0], &arg_help[0], nullptr};
126 EXPECT_EXIT(ArgumentParser(sizeof(args) / sizeof(char*) - 1, args),
127 ::testing::ExitedWithCode(255), clean_usage_regex);
William A. Kennington IIIe335ed92018-01-23 22:13:44 -0800128}
129
130/** @brief ArgumentParser should print usage information when given a help
131 * argument anywhere in the arguments array
132 */
133TEST_F(ArgumentTest, LongOptionHelp)
134{
135 std::string arg_help = "--help";
136 std::string arg_extra = "extra";
Patrick Venture8f6c5152018-09-11 17:45:33 -0700137 char* const args[] = {&arg0[0], &arg_help[0], &arg_extra[0], nullptr};
138 EXPECT_EXIT(ArgumentParser(sizeof(args) / sizeof(char*) - 1, args),
139 ::testing::ExitedWithCode(255), clean_usage_regex);
William A. Kennington IIIe335ed92018-01-23 22:13:44 -0800140}
141
142/** @brief ArgumentParser should print an invalid argument error and
143 * usage information when given an invalid argument anywhere
144 * in the arguments array
145 */
146TEST_F(ArgumentTest, InvalidOptionHelp)
147{
148 std::string arg_continue = "--continue";
149 std::string arg_bad = "--bad_arg";
150 std::string arg_target = "--target=/unused-path";
Patrick Venture8f6c5152018-09-11 17:45:33 -0700151 char* const args[] = {&arg0[0], &arg_continue[0], &arg_bad[0],
152 &arg_target[0], nullptr};
153 EXPECT_EXIT(ArgumentParser(sizeof(args) / sizeof(char*) - 1, args),
154 ::testing::ExitedWithCode(255), invalid_arg_regex);
William A. Kennington IIIe335ed92018-01-23 22:13:44 -0800155}
156
Patrick Venture8f6c5152018-09-11 17:45:33 -0700157} // namespace watchdog
158} // namespace phosphor