Skip to content

Commit e5f13ce

Browse files
authored
testrunner: bail out on unknown options (#8377)
1 parent c78ad5a commit e5f13ce

4 files changed

Lines changed: 71 additions & 27 deletions

File tree

test/main.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "fixture.h"
2323

2424
#include <cstdlib>
25+
#include <iostream>
2526

2627
int main(int argc, char *argv[])
2728
{
@@ -34,6 +35,13 @@ int main(int argc, char *argv[])
3435
TestFixture::printHelp();
3536
return EXIT_SUCCESS;
3637
}
38+
if (!args.errors().empty()) {
39+
for (const auto& error : args.errors())
40+
{
41+
std::cout << "error: " << error << '\n';
42+
}
43+
return EXIT_FAILURE;
44+
}
3745
const std::size_t failedTestsCount = TestFixture::runTests(args);
3846
return (failedTestsCount == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
3947
}

test/options.cpp

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,27 @@
1717
#include "options.h"
1818

1919
options::options(int argc, const char* const argv[])
20-
: mArgs(argv + 1, argv + argc)
21-
,mQuiet(mArgs.count("-q") != 0)
22-
,mHelp(mArgs.count("-h") != 0 || mArgs.count("--help"))
23-
,mSummary(mArgs.count("-n") == 0)
24-
,mDryRun(mArgs.count("-d") != 0)
25-
,mExcludeTests(mArgs.count("-x") != 0)
26-
,mExe(argv[0])
20+
: mExe(argv[0])
2721
{
28-
for (const auto& arg : mArgs) {
22+
const std::set<std::string> args(argv + 1, argv + argc);
23+
for (const auto& arg : args) {
2924
if (arg.empty())
3025
continue; // empty argument
31-
if (arg[0] == '-')
26+
if (arg[0] == '-') {
27+
if (arg == "-q")
28+
mQuiet = true;
29+
else if (arg == "-h" || arg == "--help")
30+
mHelp = true;
31+
else if (arg == "-n")
32+
mSummary = false;
33+
else if (arg == "-d")
34+
mDryRun = true;
35+
else if (arg == "-x")
36+
mExcludeTests = true;
37+
else
38+
mErrors.emplace_back("unknown option '" + arg + "'");
3239
continue; // command-line switch
40+
}
3341
const auto pos = arg.find("::");
3442
if (pos == std::string::npos) {
3543
mWhichTests[arg] = {}; // run whole fixture
@@ -78,3 +86,8 @@ bool options::exclude_tests() const
7886
{
7987
return mExcludeTests;
8088
}
89+
90+
const std::vector<std::string>& options::errors() const
91+
{
92+
return mErrors;
93+
}

test/options.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <map>
2121
#include <set>
2222
#include <string>
23+
#include <vector>
2324

2425
/**
2526
* @brief Class to parse command-line parameters for ./testrunner .
@@ -43,20 +44,23 @@ class options {
4344
/** Which tests should be run. */
4445
const std::map<std::string, std::set<std::string>>& which_tests() const;
4546

47+
/** Errors encountered during option processing. */
48+
const std::vector<std::string>& errors() const;
49+
4650
const std::string& exe() const;
4751

4852
options() = delete;
4953
options(const options&) = delete;
5054
options& operator =(const options&) = delete;
5155

5256
private:
53-
std::set<std::string> mArgs;
5457
std::map<std::string, std::set<std::string>> mWhichTests;
55-
const bool mQuiet;
56-
const bool mHelp;
57-
const bool mSummary;
58-
const bool mDryRun;
59-
const bool mExcludeTests;
58+
std::vector<std::string> mErrors;
59+
bool mQuiet{};
60+
bool mHelp{};
61+
bool mSummary{true};
62+
bool mDryRun{};
63+
bool mExcludeTests{};
6064
std::string mExe;
6165
};
6266

test/testoptions.cpp

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,16 @@ class TestOptions : public TestFixture {
3535
TEST_CASE(which_test);
3636
TEST_CASE(which_test_method);
3737
TEST_CASE(no_test_method);
38-
TEST_CASE(not_quiet);
38+
TEST_CASE(defaults);
3939
TEST_CASE(quiet);
40-
TEST_CASE(not_help);
4140
TEST_CASE(help);
4241
TEST_CASE(help_long);
4342
TEST_CASE(multiple_testcases);
4443
TEST_CASE(multiple_testcases_ignore_duplicates);
4544
TEST_CASE(invalid_switches);
4645
TEST_CASE(summary);
4746
TEST_CASE(dry_run);
47+
TEST_CASE(exclude_tests);
4848
}
4949

5050

@@ -55,6 +55,7 @@ class TestOptions : public TestFixture {
5555
{ "TestClass", {} }
5656
};
5757
ASSERT(expected == args.which_tests());
58+
ASSERT(args.errors().empty());
5859
}
5960

6061

@@ -65,6 +66,7 @@ class TestOptions : public TestFixture {
6566
{ "TestClass", {"TestMethod"} }
6667
};
6768
ASSERT(expected == args.which_tests());
69+
ASSERT(args.errors().empty());
6870
}
6971

7072

@@ -73,40 +75,41 @@ class TestOptions : public TestFixture {
7375
options args(getArrayLength(argv), argv);
7476
const std::map<std::string, std::set<std::string>> expected{};
7577
ASSERT(expected == args.which_tests());
78+
ASSERT(args.errors().empty());
7679
}
7780

7881

79-
void not_quiet() const {
80-
const char* argv[] = {"./test_runner", "TestClass::TestMethod", "-v"};
82+
void defaults() const {
83+
const char* argv[] = {"./test_runner", "TestClass::TestMethod"};
8184
options args(getArrayLength(argv), argv);
8285
ASSERT_EQUALS(false, args.quiet());
86+
ASSERT_EQUALS(false, args.help());
87+
ASSERT_EQUALS(true, args.summary());
88+
ASSERT_EQUALS(false, args.dry_run());
89+
ASSERT_EQUALS(false, args.exclude_tests());
90+
ASSERT(args.errors().empty());
8391
}
8492

85-
8693
void quiet() const {
8794
const char* argv[] = {"./test_runner", "TestClass::TestMethod", "-q"};
8895
options args(getArrayLength(argv), argv);
8996
ASSERT_EQUALS(true, args.quiet());
97+
ASSERT(args.errors().empty());
9098
}
9199

92-
void not_help() const {
93-
const char* argv[] = {"./test_runner", "TestClass::TestMethod", "-v"};
94-
options args(getArrayLength(argv), argv);
95-
ASSERT_EQUALS(false, args.help());
96-
}
97-
98-
99100
void help() const {
100101
const char* argv[] = {"./test_runner", "TestClass::TestMethod", "-h"};
101102
options args(getArrayLength(argv), argv);
102103
ASSERT_EQUALS(true, args.help());
104+
ASSERT(args.errors().empty());
103105
}
104106

105107

106108
void help_long() const {
107109
const char* argv[] = {"./test_runner", "TestClass::TestMethod", "--help"};
108110
options args(getArrayLength(argv), argv);
109111
ASSERT_EQUALS(true, args.help());
112+
ASSERT(args.errors().empty());
110113
}
111114

112115
void multiple_testcases() const {
@@ -116,6 +119,7 @@ class TestOptions : public TestFixture {
116119
{ "TestClass", { "TestMethod", "AnotherTestMethod" } }
117120
};
118121
ASSERT(expected == args.which_tests());
122+
ASSERT(args.errors().empty());
119123
}
120124

121125
void multiple_testcases_ignore_duplicates() const {
@@ -125,6 +129,7 @@ class TestOptions : public TestFixture {
125129
{ "TestClass", {} }
126130
};
127131
ASSERT(expected == args.which_tests());
132+
ASSERT(args.errors().empty());
128133
}
129134

130135
void invalid_switches() const {
@@ -135,18 +140,32 @@ class TestOptions : public TestFixture {
135140
};
136141
ASSERT(expected == args.which_tests());
137142
ASSERT_EQUALS(true, args.quiet());
143+
ASSERT_EQUALS(2, args.errors().size());
144+
auto it = args.errors().cbegin();
145+
ASSERT_EQUALS("unknown option '-a'", *it);
146+
++it;
147+
ASSERT_EQUALS("unknown option '-v'", *it);
138148
}
139149

140150
void summary() const {
141151
const char* argv[] = {"./test_runner", "TestClass::TestMethod", "-n"};
142152
options args(getArrayLength(argv), argv);
143153
ASSERT_EQUALS(false, args.summary());
154+
ASSERT(args.errors().empty());
144155
}
145156

146157
void dry_run() const {
147158
const char* argv[] = {"./test_runner", "TestClass::TestMethod", "-d"};
148159
options args(getArrayLength(argv), argv);
149160
ASSERT_EQUALS(true, args.dry_run());
161+
ASSERT(args.errors().empty());
162+
}
163+
164+
void exclude_tests() const {
165+
const char* argv[] = {"./test_runner", "TestClass::TestMethod", "-x"};
166+
options args(getArrayLength(argv), argv);
167+
ASSERT_EQUALS(true, args.exclude_tests());
168+
ASSERT(args.errors().empty());
150169
}
151170
};
152171

0 commit comments

Comments
 (0)