1 /*
2 Copyright 2019-2022 René Ferdinand Rivera Morell
3 Distributed under the Boost Software License, Version 1.0.
4 (See accompanying file LICENSE.txt or copy at
5 http://www.boost.org/LICENSE_1_0.txt)
6 */
7 
8 #include <lyra/lyra.hpp>
9 #include "mini_test.hpp"
10 
main()11 int main()
12 {
13 	using namespace lyra;
14 	bfg::mini_test::scope test;
15 	struct Config
16 	{
17 		std::string process_name;
18 		std::string file_name;
19 		int number = 0;
20 		int index = 0;
21 		bool flag = false;
22 		std::string first_pos;
23 		std::string second_pos;
24 		std::vector<std::string> unpositional;
25 	} config;
26 	auto parser
27 		= exe_name( config.process_name )
28 			| opt( config.file_name, "filename" )
29 				["-o"]["--output"]
30 				( "specifies output file" )
31 			| opt( config.number, "an integral value" )
32 				["-n"]
33 			| opt( [&]( int i ) {
34 					if (i < 0 || i > 10)
35 						return parser_result::error(
36 							parser_result_type::no_match,
37 							"index must be between 0 and 10");
38 					else {
39 						config.index = i;
40 						return parser_result::ok( parser_result_type::matched );
41 					}
42 				}, "index" )
43 				["-i"]
44 				( "An index, which is an integer between 0 and 10, inclusive" )
45 			| opt( config.flag )
46 				["-f"]
47 				( "A flag" )
48 			| arg( config.first_pos, "first arg" )
49 				( "First position" )
50 			| arg( config.second_pos, "second arg" )
51 				( "Second position" );
52 
53 	config = Config();
54 	{
55 		auto result = parser.parse( { "TestApp", "-o", "filename.ext" } );
56 		test
57 			(REQUIRE( result ))
58 			(REQUIRE( config.process_name == "TestApp" ));
59 	}
60 	config = Config();
61 	{
62 		auto result = parser.parse( { "TestApp", "-o", "filename.ext" } );
63 		test
64 			(REQUIRE( result ))
65 			(REQUIRE( config.file_name == "filename.ext" ));
66 	}
67 	config = Config();
68 	{
69 		auto result = parser.parse( { "TestApp", "-o=filename.ext" } );
70 		test
71 			(REQUIRE( result ))
72 			(REQUIRE( config.file_name == "filename.ext" ));
73 	}
74 	config = Config();
75 	{
76 		auto result = parser.parse( { "TestApp", "--output", "%stdout" } );
77 		test
78 			(REQUIRE( result ))
79 			(REQUIRE( config.file_name == "%stdout" ));
80 	}
81 	config = Config();
82 	{
83 		auto result = parser.parse( { "TestApp", "-n", "42" } );
84 		test
85 			(REQUIRE( result ))
86 			(REQUIRE( config.number == 42 ));
87 	}
88 	config = Config();
89 	{
90 		auto result = parser.parse( { "TestApp", "-n", "forty-two" } );
91 		test
92 			(REQUIRE( !result ))
93 			(REQUIRE( result.message() == "Unable to convert 'forty-two' to destination type" ))
94 			(REQUIRE( config.number == 0 ));
95 	}
96 	config = Config();
97 	{
98 		auto result = parser.parse( { "TestApp", "-i", "3" } );
99 		test
100 			(REQUIRE( result ))
101 			(REQUIRE( config.index == 3 ));
102 	}
103 	config = Config();
104 	{
105 		auto result = parser.parse( { "TestApp", "-i", "42" } );
106 		test
107 			(REQUIRE( !result ))
108 			(REQUIRE( result.message() == "index must be between 0 and 10" ));
109 	}
110 	config = Config();
111 	{
112 		auto result = parser.parse({ "TestApp", "-f" });
113 		test
114 			(REQUIRE( result ))
115 			(REQUIRE(config.flag));
116 	}
117 	config = Config();
118 	{
119 		auto result = parser.parse({ "TestApp" });
120 		test
121 			(REQUIRE( result ))
122 			(REQUIRE( result.value().type() == parser_result_type::matched))
123 			(REQUIRE( config.flag == false ));
124 	}
125 	config = Config();
126 	{
127 		auto result = parser.parse({ "TestApp", "-f", "something" });
128 		test
129 			(REQUIRE( result ))
130 			(REQUIRE( config.flag ))
131 			(REQUIRE( config.first_pos == "something" ));
132 	}
133 	config = Config();
134 	{
135 		auto result = parser.parse({ "TestApp", "something", "-f" });
136 		test
137 			(REQUIRE( result ))
138 			(REQUIRE( config.flag ))
139 			(REQUIRE( config.first_pos == "something" ));
140 	}
141 	config = Config();
142 	{
143 		auto result = parser.parse({ "TestApp", "something" });
144 		test
145 			(REQUIRE( result ))
146 			(REQUIRE( config.flag == false ))
147 			(REQUIRE( config.first_pos == "something" ));
148 	}
149 	config = Config();
150 	{
151 		auto result = parser.parse( { "TestApp", "-f", "1st", "-o", "filename", "2nd" } );
152 		test
153 			(REQUIRE( result ))
154 			(REQUIRE( config.first_pos == "1st" ))
155 			(REQUIRE( config.second_pos == "2nd" ));
156 	}
157 
158 	return test;
159 }
160