Skip to content

Commit 8c184f5

Browse files
committed
test: add unit tests for arg_parser_arg class
1 parent 7d5347b commit 8c184f5

File tree

7 files changed

+365
-13
lines changed

7 files changed

+365
-13
lines changed
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
// BSD 3-Clause License
2+
//
3+
// Copyright (c) 2024, Arm Limited
4+
// All rights reserved.
5+
//
6+
// Redistribution and use in source and binary forms, with or without
7+
// modification, are permitted provided that the following conditions are met:
8+
//
9+
// 1. Redistributions of source code must retain the above copyright notice, this
10+
// list of conditions and the following disclaimer.
11+
//
12+
// 2. Redistributions in binary form must reproduce the above copyright notice,
13+
// this list of conditions and the following disclaimer in the documentation
14+
// and/or other materials provided with the distribution.
15+
//
16+
// 3. Neither the name of the copyright holder nor the names of its
17+
// contributors may be used to endorse or promote products derived from
18+
// this software without specific prior written permission.
19+
//
20+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24+
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25+
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26+
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27+
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28+
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
31+
#include "pch.h"
32+
#include "CppUnitTest.h"
33+
#include <unordered_map>
34+
#include "parser/arg-parser-arg.h"
35+
36+
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
37+
38+
namespace argparser_arg_tests
39+
{
40+
41+
TEST_CLASS(ArgParserArgTests)
42+
{
43+
public:
44+
TEST_METHOD(TestConstructor)
45+
{
46+
arg_parser_arg arg(L"--name", { L"-n" }, L"Description of the argument", { L"default" }, 1);
47+
Assert::AreEqual(std::wstring(L"--name"), arg.get_name());
48+
Assert::AreEqual(std::wstring(L"-n"), arg.get_alias_string());
49+
Assert::AreEqual(std::wstring(L"Description of the argument"), arg.get_usage_text());
50+
}
51+
52+
TEST_METHOD(TestIsMatch)
53+
{
54+
arg_parser_arg arg(L"--name", { L"-n" }, L"Test argument");
55+
Assert::IsTrue(arg.is_match(L"--name"));
56+
Assert::IsTrue(arg.is_match(L"-n"));
57+
Assert::IsFalse(arg.is_match(L"--unknown"));
58+
}
59+
60+
TEST_METHOD(TestAddAlias)
61+
{
62+
arg_parser_arg arg(L"--name", { L"-n" }, L"Test argument");
63+
arg.add_alias(L"-alias");
64+
Assert::AreEqual(std::wstring(L"-n, -alias"), arg.get_alias_string());
65+
Assert::AreEqual(std::wstring(L"--name, -n, -alias"), arg.get_all_flags_string());
66+
}
67+
68+
TEST_METHOD(TestAddCheckFunc)
69+
{
70+
arg_parser_arg arg(L"--name", {}, L"Test argument", {}, 1);
71+
arg.add_check_func([](const std::wstring& value) { return value.length() < 10; });
72+
Assert::ExpectException<std::invalid_argument>([&]() {
73+
arg.parse({ L"--name", L"value_that_is_too_long" });
74+
});
75+
}
76+
77+
TEST_METHOD(TestParseSuccess)
78+
{
79+
arg_parser_arg arg(L"--name", {}, L"Test argument", {}, 1);
80+
Assert::IsTrue(arg.parse({ L"--name", L"value" }));
81+
auto values = arg.get_values();
82+
Assert::AreEqual(size_t(1), values.size());
83+
Assert::AreEqual(std::wstring(L"value"), values[0]);
84+
}
85+
86+
TEST_METHOD(TestParseFailure)
87+
{
88+
arg_parser_arg arg(L"--name", {}, L"Test argument", {}, 1);
89+
Assert::ExpectException<std::invalid_argument>([&]() {
90+
arg.parse({ L"--name" }); // Not enough arguments
91+
});
92+
}
93+
94+
TEST_METHOD(TestGetHelp)
95+
{
96+
arg_parser_arg arg(L"--help", { L"-h" }, L"Shows help information");
97+
auto help_text = arg.get_help();
98+
Assert::IsTrue(help_text.find(L"--help, -h") != std::wstring::npos);
99+
Assert::IsTrue(help_text.find(L"Shows help information") != std::wstring::npos);
100+
}
101+
102+
TEST_METHOD(TestOptionalArgument)
103+
{
104+
arg_parser_arg_opt arg(L"--optional", {}, L"An optional argument");
105+
Assert::AreEqual(0, arg.get_arg_count());
106+
Assert::IsTrue(arg.parse({ L"--optional" }));
107+
Assert::IsTrue(arg.is_set());
108+
}
109+
110+
TEST_METHOD(TestPositionalArgument)
111+
{
112+
arg_parser_arg_pos arg(L"filename", {}, L"Input file", {}, 1);
113+
Assert::AreEqual(1, arg.get_arg_count());
114+
Assert::IsTrue(arg.parse({ L"filename", L"input.txt" }));
115+
auto values = arg.get_values();
116+
Assert::AreEqual(std::wstring(L"input.txt"), values[0]);
117+
Assert::IsTrue(arg.is_set());
118+
}
119+
TEST_METHOD(TestGetHelpSingleAlias)
120+
{
121+
arg_parser_arg arg(L"--help", { L"-h" }, L"Displays help information.");
122+
auto help_text = arg.get_help();
123+
124+
// Check if the help text includes all flags and description
125+
Assert::IsTrue(help_text.find(L"--help, -h") != std::wstring::npos);
126+
Assert::IsTrue(help_text.find(L"Displays help information.") != std::wstring::npos);
127+
}
128+
129+
TEST_METHOD(TestGetHelpMultipleAliases)
130+
{
131+
arg_parser_arg arg(L"--output", { L"-o", L"-out" }, L"Specifies the output file.");
132+
auto help_text = arg.get_help();
133+
134+
// Verify the help output contains all aliases and description
135+
Assert::IsTrue(help_text.find(L"--output, -o, -out") != std::wstring::npos);
136+
Assert::IsTrue(help_text.find(L"Specifies the output file.") != std::wstring::npos);
137+
}
138+
139+
TEST_METHOD(TestGetHelpWithoutAliases)
140+
{
141+
arg_parser_arg arg(L"--verbose", {}, L"Enables verbose mode.");
142+
auto help_text = arg.get_help();
143+
144+
// Ensure the help text only includes the main name when no aliases are defined
145+
Assert::IsTrue(help_text.find(L"--verbose") != std::wstring::npos);
146+
Assert::IsFalse(help_text.find(L",") != std::wstring::npos); // No aliases
147+
Assert::IsTrue(help_text.find(L"Enables verbose mode.") != std::wstring::npos);
148+
}
149+
150+
TEST_METHOD(TestGetAllFlagsStringSingleAlias)
151+
{
152+
arg_parser_arg arg(L"--help", { L"-h" }, L"Displays help information.");
153+
auto flags = arg.get_all_flags_string();
154+
155+
// Verify that all flags are correctly concatenated
156+
Assert::AreEqual(std::wstring(L"--help, -h"), flags);
157+
}
158+
159+
TEST_METHOD(TestGetAllFlagsStringMultipleAliases)
160+
{
161+
arg_parser_arg arg(L"--input", { L"-i", L"-in" }, L"Specifies the input file.");
162+
auto flags = arg.get_all_flags_string();
163+
164+
// Check concatenation of all flags with multiple aliases
165+
Assert::AreEqual(std::wstring(L"--input, -i, -in"), flags);
166+
}
167+
168+
TEST_METHOD(TestGetAllFlagsStringNoAlias)
169+
{
170+
arg_parser_arg arg(L"--quiet", {}, L"Enables quiet mode.");
171+
auto flags = arg.get_all_flags_string();
172+
173+
// Ensure that the main flag name is returned without extra formatting
174+
Assert::AreEqual(std::wstring(L"--quiet"), flags);
175+
}
176+
};
177+
}
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
// BSD 3-Clause License
2+
//
3+
// Copyright (c) 2024, Arm Limited
4+
// All rights reserved.
5+
//
6+
// Redistribution and use in source and binary forms, with or without
7+
// modification, are permitted provided that the following conditions are met:
8+
//
9+
// 1. Redistributions of source code must retain the above copyright notice, this
10+
// list of conditions and the following disclaimer.
11+
//
12+
// 2. Redistributions in binary form must reproduce the above copyright notice,
13+
// this list of conditions and the following disclaimer in the documentation
14+
// and/or other materials provided with the distribution.
15+
//
16+
// 3. Neither the name of the copyright holder nor the names of its
17+
// contributors may be used to endorse or promote products derived from
18+
// this software without specific prior written permission.
19+
//
20+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24+
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25+
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26+
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27+
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28+
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
31+
#include "pch.h"
32+
#include "CppUnitTest.h"
33+
#include <unordered_map>
34+
#include "parser/arg-parser-arg.h"
35+
36+
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
37+
38+
namespace argparser_arg_utils_tests
39+
{
40+
41+
TEST_CLASS(ArgParserArgFormatToLengthTests)
42+
{
43+
public:
44+
TEST_METHOD(TestEmptyString)
45+
{
46+
std::wstring input = L"";
47+
size_t max_width = 10;
48+
std::wstring expected = L"";
49+
Assert::AreEqual(expected, arg_parser_format_string_to_length(input, max_width));
50+
}
51+
52+
TEST_METHOD(TestSingleShortLine)
53+
{
54+
std::wstring input = L"Short line.";
55+
size_t max_width = 20;
56+
std::wstring expected = L"Short line.";
57+
Assert::AreEqual(expected, arg_parser_format_string_to_length(input, max_width));
58+
}
59+
60+
TEST_METHOD(TestSingleLongLine)
61+
{
62+
std::wstring input = L"This is a line that exceeds the width.";
63+
size_t max_width = 15;
64+
std::wstring expected = L"This is a line\nthat exceeds\nthe width.";
65+
Assert::AreEqual(expected, arg_parser_format_string_to_length(input, max_width));
66+
}
67+
68+
TEST_METHOD(TestMultipleLines)
69+
{
70+
std::wstring input = L"Line one.\nLine two is a bit longer.\nShort.";
71+
size_t max_width = 15;
72+
std::wstring expected = L"Line one.\n\nLine two is a\nbit longer.\n\nShort.";
73+
Assert::AreEqual(expected, arg_parser_format_string_to_length(input, max_width));
74+
}
75+
76+
TEST_METHOD(TestTrailingNewlineRemoval)
77+
{
78+
std::wstring input = L"Line with trailing newline.\n";
79+
size_t max_width = 30;
80+
std::wstring expected = L"Line with trailing newline.";
81+
Assert::AreEqual(expected, arg_parser_format_string_to_length(input, max_width));
82+
}
83+
84+
TEST_METHOD(TestExactFit)
85+
{
86+
std::wstring input = L"Exactly fifteen";
87+
size_t max_width = 15;
88+
std::wstring expected = L"Exactly fifteen";
89+
Assert::AreEqual(expected, arg_parser_format_string_to_length(input, max_width));
90+
}
91+
92+
TEST_METHOD(TestSingleWordExceedsWidth)
93+
{
94+
std::wstring input = L"Supercalifragilisticexpialidocious";
95+
size_t max_width = 10;
96+
std::wstring expected = L"Supercalifragilisticexpialidocious";
97+
Assert::AreEqual(expected, arg_parser_format_string_to_length(input, max_width));
98+
}
99+
};
100+
TEST_CLASS(ArgParserAddPrefixTests)
101+
{
102+
public:
103+
TEST_METHOD(TestEmptyString)
104+
{
105+
std::wstring input = L"";
106+
std::wstring prefix = L"-> ";
107+
std::wstring expected = L"";
108+
Assert::AreEqual(expected, arg_parser_add_wstring_behind_multiline_text(input, prefix));
109+
}
110+
111+
TEST_METHOD(TestSingleLineWithPrefix)
112+
{
113+
std::wstring input = L"Hello, world!";
114+
std::wstring prefix = L"\t-> ";
115+
std::wstring expected = L"\t-> Hello, world!\n";
116+
Assert::AreEqual(expected, arg_parser_add_wstring_behind_multiline_text(input, prefix));
117+
}
118+
119+
TEST_METHOD(TestMultipleLinesWithPrefix)
120+
{
121+
std::wstring input = L"Line one.\nLine two.\nLine three.";
122+
std::wstring prefix = L"\t* ";
123+
std::wstring expected = L"\t* Line one.\n\t* Line two.\n\t* Line three.\n";
124+
Assert::AreEqual(expected, arg_parser_add_wstring_behind_multiline_text(input, prefix));
125+
}
126+
127+
TEST_METHOD(TestLinesWithEmptyLines)
128+
{
129+
std::wstring input = L"Line one.\n\nLine three.";
130+
std::wstring prefix = L"# ";
131+
std::wstring expected = L"# Line one.\n\n# Line three.\n";
132+
Assert::AreEqual(expected, arg_parser_add_wstring_behind_multiline_text(input, prefix));
133+
}
134+
135+
TEST_METHOD(TestNoPrefixOnEmptyLines)
136+
{
137+
std::wstring input = L"\n\n";
138+
std::wstring prefix = L"-> ";
139+
std::wstring expected = L"\n\n";
140+
Assert::AreEqual(expected, arg_parser_add_wstring_behind_multiline_text(input, prefix));
141+
}
142+
143+
TEST_METHOD(TestPrefixWithSpecialCharacters)
144+
{
145+
std::wstring input = L"Special line.";
146+
std::wstring prefix = L"*** ";
147+
std::wstring expected = L"*** Special line.\n";
148+
Assert::AreEqual(expected, arg_parser_add_wstring_behind_multiline_text(input, prefix));
149+
}
150+
151+
TEST_METHOD(TestPrefixAndMultilineSpacing)
152+
{
153+
std::wstring input = L"Line one.\n\nLine two.\n\n";
154+
std::wstring prefix = L"--> ";
155+
std::wstring expected = L"--> Line one.\n\n--> Line two.\n\n";
156+
Assert::AreEqual(expected, arg_parser_add_wstring_behind_multiline_text(input, prefix));
157+
}
158+
};
159+
}

parser-tests/parser-tests.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@
162162
</Link>
163163
</ItemDefinitionGroup>
164164
<ItemGroup>
165+
<ClCompile Include="arg-parser-arg-tests.cpp" />
166+
<ClCompile Include="arg-parser-arg-utils-tests.cpp" />
165167
<ClCompile Include="parser-tests.cpp" />
166168
<ClCompile Include="pch.cpp">
167169
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>

parser-tests/parser-tests.vcxproj.filters

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@
2121
<ClCompile Include="pch.cpp">
2222
<Filter>Source Files</Filter>
2323
</ClCompile>
24+
<ClCompile Include="arg-parser-arg-utils-tests.cpp">
25+
<Filter>Source Files</Filter>
26+
</ClCompile>
27+
<ClCompile Include="arg-parser-arg-tests.cpp">
28+
<Filter>Source Files</Filter>
29+
</ClCompile>
2430
</ItemGroup>
2531
<ItemGroup>
2632
<ClInclude Include="pch.h">

0 commit comments

Comments
 (0)