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+ }
0 commit comments