Toolbox snapshot
The Reactive C++ Toolbox
Loading...
Searching...
No Matches
Argv.ut.cpp
Go to the documentation of this file.
1// The Reactive C++ Toolbox.
2// Copyright (C) 2013-2019 Swirly Cloud Limited
3// Copyright (C) 2021 Reactive Markets Limited
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17#include "Argv.hpp"
18
19#include <boost/test/unit_test.hpp>
20
21#include <iostream>
22
23using namespace std;
24using namespace toolbox;
25
26namespace {
27
28struct Opts {
29 vector<string_view> args, fruit, veg;
30 bool blend{false};
31};
32
33void get_opts(int argc, const char* const argv[], Opts& opts)
34{
36 while (!lex.empty()) {
37 const auto opt = lex.opt();
38 if (opt.empty()) {
39 opts.args.push_back(lex.pop_value());
40 } else if (opt == "b" || opt == "blend") {
41 opts.blend = true;
42 lex.pop_switch();
43 } else if (opt == "f" || opt == "fruit") {
44 opts.fruit.push_back(lex.pop_value());
45 } else if (opt == "v" || opt == "veg") {
46 opts.veg.push_back(lex.pop_value());
47 } else {
48 throw runtime_error{"unknown option: " + string{opt}};
49 }
50 }
51}
52
53template <size_t N>
55
56} // namespace
57
59
61{
62 Opts opts;
63 Argv<0> argv{};
64 get_opts(argv.size(), argv.data(), opts);
65
66 BOOST_CHECK(opts.args.empty());
67 BOOST_CHECK(opts.fruit.empty());
68 BOOST_CHECK(opts.veg.empty());
69 BOOST_CHECK(!opts.blend);
70}
71
73{
74 Opts opts;
75 Argv<5> argv{"foo", "-", "bar", "--", "baz"};
76 get_opts(argv.size(), argv.data(), opts);
77
78 BOOST_CHECK_EQUAL(opts.args.size(), 5);
79 BOOST_CHECK_EQUAL(opts.args.at(0), "foo"sv);
80 BOOST_CHECK_EQUAL(opts.args.at(1), "-"sv);
81 BOOST_CHECK_EQUAL(opts.args.at(2), "bar"sv);
82 BOOST_CHECK_EQUAL(opts.args.at(3), "--"sv);
83 BOOST_CHECK_EQUAL(opts.args.at(4), "baz"sv);
84 BOOST_CHECK(opts.fruit.empty());
85 BOOST_CHECK(opts.veg.empty());
86 BOOST_CHECK(!opts.blend);
87}
88
90{
91 {
92 Opts opts;
93 Argv<2> argv{"-fapple", "-vcarrot"};
94 get_opts(argv.size(), argv.data(), opts);
95
96 BOOST_CHECK(opts.args.empty());
97 BOOST_CHECK_EQUAL(opts.fruit.size(), 1);
98 BOOST_CHECK_EQUAL(opts.fruit.at(0), "apple"sv);
99 BOOST_CHECK_EQUAL(opts.veg.size(), 1);
100 BOOST_CHECK_EQUAL(opts.veg.at(0), "carrot"sv);
101 BOOST_CHECK(!opts.blend);
102 }
103 {
104 Opts opts;
105 Argv<4> argv{"-v", "carrot", "-f", "apple"};
106 get_opts(argv.size(), argv.data(), opts);
107
108 BOOST_CHECK(opts.args.empty());
109 BOOST_CHECK_EQUAL(opts.fruit.size(), 1);
110 BOOST_CHECK_EQUAL(opts.fruit.at(0), "apple"sv);
111 BOOST_CHECK_EQUAL(opts.veg.size(), 1);
112 BOOST_CHECK_EQUAL(opts.veg.at(0), "carrot"sv);
113 BOOST_CHECK(!opts.blend);
114 }
115 {
116 // Empty option value.
117 Opts opts;
118 Argv<4> argv{"-f", "", "-v", ""};
119 get_opts(argv.size(), argv.data(), opts);
120
121 BOOST_CHECK(opts.args.empty());
122 BOOST_CHECK_EQUAL(opts.fruit.size(), 1);
123 BOOST_CHECK(opts.fruit.at(0).empty());
124 BOOST_CHECK_EQUAL(opts.veg.size(), 1);
125 BOOST_CHECK(opts.veg.at(0).empty());
126 BOOST_CHECK(!opts.blend);
127 }
128 {
129 // Missing option value.
130 Opts opts;
131 Argv<1> argv{"-v"};
132 BOOST_CHECK_THROW(get_opts(argv.size(), argv.data(), opts), std::runtime_error);
133 }
134}
135
137{
138 {
139 Opts opts;
140 Argv<2> argv{"-fapple", "-fbanana"};
141 get_opts(argv.size(), argv.data(), opts);
142
143 BOOST_CHECK(opts.args.empty());
144 BOOST_CHECK_EQUAL(opts.fruit.size(), 2);
145 BOOST_CHECK_EQUAL(opts.fruit.at(0), "apple"sv);
146 BOOST_CHECK_EQUAL(opts.fruit.at(1), "banana"sv);
147 BOOST_CHECK(opts.veg.empty());
148 BOOST_CHECK(!opts.blend);
149 }
150 {
151 Opts opts;
152 Argv<4> argv{"-v", "broccoli", "-v", "carrot"};
153 get_opts(argv.size(), argv.data(), opts);
154
155 BOOST_CHECK(opts.args.empty());
156 BOOST_CHECK(opts.fruit.empty());
157 BOOST_CHECK_EQUAL(opts.veg.size(), 2);
158 BOOST_CHECK_EQUAL(opts.veg.at(0), "broccoli"sv);
159 BOOST_CHECK_EQUAL(opts.veg.at(1), "carrot"sv);
160 BOOST_CHECK(!opts.blend);
161 }
162}
163
165{
166 {
167 Opts opts;
168 Argv<2> argv{"--fruit=apple", "--veg=carrot"};
169 get_opts(argv.size(), argv.data(), opts);
170
171 BOOST_CHECK(opts.args.empty());
172 BOOST_CHECK_EQUAL(opts.fruit.size(), 1);
173 BOOST_CHECK_EQUAL(opts.fruit.at(0), "apple"sv);
174 BOOST_CHECK_EQUAL(opts.veg.size(), 1);
175 BOOST_CHECK_EQUAL(opts.veg.at(0), "carrot"sv);
176 BOOST_CHECK(!opts.blend);
177 }
178 {
179 Opts opts;
180 Argv<4> argv{"--veg", "carrot", "--fruit", "apple"};
181 get_opts(argv.size(), argv.data(), opts);
182
183 BOOST_CHECK(opts.args.empty());
184 BOOST_CHECK_EQUAL(opts.fruit.size(), 1);
185 BOOST_CHECK_EQUAL(opts.fruit.at(0), "apple"sv);
186 BOOST_CHECK_EQUAL(opts.veg.size(), 1);
187 BOOST_CHECK_EQUAL(opts.veg.at(0), "carrot"sv);
188 BOOST_CHECK(!opts.blend);
189 }
190 {
191 // Empty option value.
192 Opts opts;
193 Argv<2> argv{"--fruit=", "--veg="};
194 get_opts(argv.size(), argv.data(), opts);
195
196 BOOST_CHECK(opts.args.empty());
197 BOOST_CHECK_EQUAL(opts.fruit.size(), 1);
198 BOOST_CHECK(opts.fruit.at(0).empty());
199 BOOST_CHECK_EQUAL(opts.veg.size(), 1);
200 BOOST_CHECK(opts.veg.at(0).empty());
201 BOOST_CHECK(!opts.blend);
202 }
203 {
204 // Missing option value.
205 Opts opts;
206 Argv<1> argv{"--veg"};
207 BOOST_CHECK_THROW(get_opts(argv.size(), argv.data(), opts), std::runtime_error);
208 }
209}
210
212{
213 {
214 Opts opts;
215 Argv<2> argv{"--fruit=apple", "--fruit=banana"};
216 get_opts(argv.size(), argv.data(), opts);
217
218 BOOST_CHECK(opts.args.empty());
219 BOOST_CHECK_EQUAL(opts.fruit.size(), 2);
220 BOOST_CHECK_EQUAL(opts.fruit.at(0), "apple"sv);
221 BOOST_CHECK_EQUAL(opts.fruit.at(1), "banana"sv);
222 BOOST_CHECK(opts.veg.empty());
223 BOOST_CHECK(!opts.blend);
224 }
225 {
226 Opts opts;
227 Argv<4> argv{"--veg", "broccoli", "--veg", "carrot"};
228 get_opts(argv.size(), argv.data(), opts);
229
230 BOOST_CHECK(opts.args.empty());
231 BOOST_CHECK(opts.fruit.empty());
232 BOOST_CHECK_EQUAL(opts.veg.size(), 2);
233 BOOST_CHECK_EQUAL(opts.veg.at(0), "broccoli"sv);
234 BOOST_CHECK_EQUAL(opts.veg.at(1), "carrot"sv);
235 BOOST_CHECK(!opts.blend);
236 }
237}
238
240{
241 {
242 Opts opts;
243 Argv<1> argv{"-b"};
244 get_opts(argv.size(), argv.data(), opts);
245
246 BOOST_CHECK(opts.args.empty());
247 BOOST_CHECK(opts.fruit.empty());
248 BOOST_CHECK(opts.veg.empty());
249 BOOST_CHECK(opts.blend);
250 }
251 {
252 Opts opts;
253 Argv<1> argv{"--blend"};
254 get_opts(argv.size(), argv.data(), opts);
255
256 BOOST_CHECK(opts.args.empty());
257 BOOST_CHECK(opts.fruit.empty());
258 BOOST_CHECK(opts.veg.empty());
259 BOOST_CHECK(opts.blend);
260 }
261 {
262 // Unexpected switch value.
263 Opts opts;
264 Argv<1> argv{"-b123"};
265 BOOST_CHECK_THROW(get_opts(argv.size(), argv.data(), opts), std::runtime_error);
266 }
267 {
268 // Unexpected switch value.
269 Opts opts;
270 Argv<1> argv{"--blend=123"};
271 BOOST_CHECK_THROW(get_opts(argv.size(), argv.data(), opts), std::runtime_error);
272 }
273}
274
BOOST_AUTO_TEST_CASE(ArgvEmptyCase)
Definition Argv.ut.cpp:60
BOOST_CHECK_EQUAL(v.size(), 10U)
std::string_view opt() const noexcept
Definition Argv.hpp:84
STL namespace.
std::string_view sv
Definition Tokeniser.hpp:26
constexpr auto bind() noexcept
Definition Slot.hpp:92
BOOST_CHECK(isnan(stod(""sv, numeric_limits< double >::quiet_NaN())))