summaryrefslogtreecommitdiffstats
path: root/test/argument_test.cpp
blob: 3cb5dc9fe1556782110fbcae919b7d94d31a7755 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include "argument_test.hpp"

#include "argument.hpp"

#include <string>
#include <vector>

static const std::string expected_path1 = "/arg1-test-path";
static const std::string expected_target1 = "t1.target";
static const std::string expected_target2 = "t2.target";

// Allow for a single unrecognized option then the Usage printout
static const std::string invalid_arg_regex =
    "^[^\n]*unrecognized option[^\n]*\nUsage: ";

static const std::string clean_usage_regex = "^Usage: ";

namespace phosphor
{
namespace watchdog
{

void ArgumentTest::SetUp()
{
    arg0 = "argument_test";
}

/** @brief ArgumentParser should return no values if given no options */
TEST_F(ArgumentTest, NoOptions)
{
    char* const args[] = {&arg0[0], nullptr};
    ArgumentParser ap(sizeof(args) / sizeof(char*) - 1, args);
    EXPECT_EQ(std::vector<std::string>({}), ap["path"]);
    EXPECT_EQ(std::vector<std::string>({}), ap["continue"]);
    EXPECT_EQ(std::vector<std::string>({}), ap["arbitrary_unknown"]);
}

/** @brief ArgumentParser should return true for an existing no-arg option
 *         Make sure we don't parse arguments if an option takes none
 *         Also make sure we don't populate options not used.
 */
TEST_F(ArgumentTest, LongOptionNoArg)
{
    std::string arg_continue = "--continue";
    std::string arg_extra = "not-a-bool";
    char* const args[] = {&arg0[0], &arg_continue[0], &arg_extra[0], nullptr};
    ArgumentParser ap(sizeof(args) / sizeof(char*) - 1, args);
    EXPECT_EQ(std::vector<std::string>({}), ap["path"]);
    EXPECT_EQ(std::vector<std::string>({ArgumentParser::trueString}),
              ap["continue"]);
}

/** @brief ArgumentParser should return a string for long options that
 *         take an arg
 */
TEST_F(ArgumentTest, LongOptionRequiredArg)
{
    std::string arg_path = "--path";
    std::string arg_path_val = expected_path1;
    std::string arg_extra = "/unused-path";
    char* const args[] = {&arg0[0], &arg_path[0], &arg_path_val[0],
                          &arg_extra[0], nullptr};
    ArgumentParser ap(sizeof(args) / sizeof(char*) - 1, args);
    EXPECT_EQ(std::vector<std::string>({expected_path1}), ap["path"]);
}

/** @brief ArgumentParser should return a string for long options that
 *         accept an argument when passed an argument inline
 */
TEST_F(ArgumentTest, LongOptionInlineArg)
{
    std::string arg_path = "--path=" + expected_path1;
    std::string arg_extra = "/unused-path";
    char* const args[] = {&arg0[0], &arg_path[0], &arg_extra[0], nullptr};
    ArgumentParser ap(sizeof(args) / sizeof(char*) - 1, args);
    EXPECT_EQ(std::vector<std::string>({expected_path1}), ap["path"]);
}

/** @brief ArgumentParser should return a string for short options that
 *         accept an argument.
 */
TEST_F(ArgumentTest, ShortOptionRequiredArg)
{
    std::string arg_path = "-p";
    std::string arg_path_val = expected_path1;
    std::string arg_extra = "/unused-path";
    char* const args[] = {&arg0[0], &arg_path[0], &arg_path_val[0],
                          &arg_extra[0], nullptr};
    ArgumentParser ap(sizeof(args) / sizeof(char*) - 1, args);
    EXPECT_EQ(std::vector<std::string>({expected_path1}), ap["path"]);
}

/** @brief ArgumentParser should be able to handle parsing multiple options
 *         Make sure this works for no-arg and required-arg type options
 *         Make sure this works between short and long options
 */
TEST_F(ArgumentTest, MultiOptionOverride)
{
    std::string arg_continue_short = "-c";
    std::string arg_path = "--path=" + expected_path1;
    std::string arg_continue_long = "--continue";
    std::string arg_target = "--target=" + expected_target2;
    std::string arg_target_short = "-t";
    std::string arg_target_val = expected_target1;
    char* const args[] = {&arg0[0],           &arg_continue_short[0],
                          &arg_path[0],       &arg_continue_long[0],
                          &arg_target[0],     &arg_target_short[0],
                          &arg_target_val[0], nullptr};
    ArgumentParser ap(sizeof(args) / sizeof(char*) - 1, args);
    EXPECT_EQ(std::vector<std::string>({expected_path1}), ap["path"]);
    EXPECT_EQ(std::vector<std::string>(
                  {ArgumentParser::trueString, ArgumentParser::trueString}),
              ap["continue"]);
    EXPECT_EQ(std::vector<std::string>({expected_target2, expected_target1}),
              ap["target"]);
}

/** @brief ArgumentParser should print usage information when given a help
 *         argument anywhere in the arguments array
 */
TEST_F(ArgumentTest, ShortOptionHelp)
{
    std::string arg_extra = "extra";
    std::string arg_help = "-h";
    char* const args[] = {&arg0[0], &arg_extra[0], &arg_help[0], nullptr};
    EXPECT_EXIT(ArgumentParser(sizeof(args) / sizeof(char*) - 1, args),
                ::testing::ExitedWithCode(255), clean_usage_regex);
}

/** @brief ArgumentParser should print usage information when given a help
 *         argument anywhere in the arguments array
 */
TEST_F(ArgumentTest, LongOptionHelp)
{
    std::string arg_help = "--help";
    std::string arg_extra = "extra";
    char* const args[] = {&arg0[0], &arg_help[0], &arg_extra[0], nullptr};
    EXPECT_EXIT(ArgumentParser(sizeof(args) / sizeof(char*) - 1, args),
                ::testing::ExitedWithCode(255), clean_usage_regex);
}

/** @brief ArgumentParser should print an invalid argument error and
 *         usage information when given an invalid argument anywhere
 *         in the arguments array
 */
TEST_F(ArgumentTest, InvalidOptionHelp)
{
    std::string arg_continue = "--continue";
    std::string arg_bad = "--bad_arg";
    std::string arg_target = "--target=/unused-path";
    char* const args[] = {&arg0[0], &arg_continue[0], &arg_bad[0],
                          &arg_target[0], nullptr};
    EXPECT_EXIT(ArgumentParser(sizeof(args) / sizeof(char*) - 1, args),
                ::testing::ExitedWithCode(255), invalid_arg_regex);
}

} // namespace watchdog
} // namespace phosphor
OpenPOWER on IntegriCloud