tesseract v5.3.3.20231005
commandlineflags_test.cc
Go to the documentation of this file.
1// (C) Copyright 2017, Google Inc.
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5// http://www.apache.org/licenses/LICENSE-2.0
6// Unless required by applicable law or agreed to in writing, software
7// distributed under the License is distributed on an "AS IS" BASIS,
8// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9// See the License for the specific language governing permissions and
10// limitations under the License.
11
12#include "commandlineflags.h"
13
14#include "include_gunit.h"
15
16// Flags used for testing parser.
17INT_PARAM_FLAG(foo_int, 0, "Integer flag for testing");
18INT_PARAM_FLAG(bar_int, 0, "Integer flag for testing");
19DOUBLE_PARAM_FLAG(foo_double, 0.1, "Double flag for testing");
20DOUBLE_PARAM_FLAG(bar_double, 0.2, "Double flag for testing");
21STRING_PARAM_FLAG(foo_string, "foo", "String flag for testing");
22STRING_PARAM_FLAG(bar_string, "bar", "String flag for testing");
23BOOL_PARAM_FLAG(foo_bool, false, "Bool flag for testing");
24BOOL_PARAM_FLAG(bar_bool, false, "Bool flag for testing");
25// A flag whose name is a single character, tested for backward
26// compatibility. This should be selected to not conflict with existing flags
27// in commontraining.cpp.
28STRING_PARAM_FLAG(q, "", "Single character name");
29
30namespace tesseract {
31
33protected:
34 void TestParser(int argc, const char **const_argv) {
35 TestParser("", argc, const_argv);
36 }
37 void TestParser(const char *usage, int argc, const char **const_argv) {
38 // Make a copy of the pointer since it can be altered by the function.
39 char **argv = const_cast<char **>(const_argv);
40 tesseract::ParseCommandLineFlags(usage, &argc, &argv, true);
41 }
42};
43
45 const char *const_argv[] = {"Progname", "--foo_int", "3", "file1.h", "file2.h"};
46 int argc = countof(const_argv);
47 char **argv = const_cast<char **>(const_argv);
48 tesseract::ParseCommandLineFlags(argv[0], &argc, &argv, true);
49
50 // argv should be rearranged to look like { "Progname", "file1.h", "file2.h" }
51 EXPECT_EQ(3, argc);
52 EXPECT_STREQ("Progname", argv[0]);
53 EXPECT_STREQ("file1.h", argv[1]);
54 EXPECT_STREQ("file2.h", argv[2]);
55}
56
57#if 0 // TODO: this test needs an update (it currently fails).
58TEST_F(CommandlineflagsTest, PrintUsageAndExit) {
59 const char* argv[] = { "Progname", "--help" };
60 EXPECT_EXIT(TestParser("Progname [flags]", countof(argv), argv),
61 ::testing::ExitedWithCode(0),
62 "USAGE: Progname \\[flags\\]");
63}
64#endif
65
66TEST_F(CommandlineflagsTest, ExitsWithErrorOnInvalidFlag) {
67 const char *argv[] = {"", "--test_nonexistent_flag"};
68 EXPECT_EXIT(TestParser(countof(argv), argv), ::testing::ExitedWithCode(1),
69 "ERROR: Non-existent flag");
70}
71
72TEST_F(CommandlineflagsTest, ParseIntegerFlags) {
73 const char *argv[] = {"", "--foo_int=3", "--bar_int", "-4"};
74 TestParser(countof(argv), argv);
75 EXPECT_EQ(3, FLAGS_foo_int);
76 EXPECT_EQ(-4, FLAGS_bar_int);
77
78 const char *arg_no_value[] = {"", "--bar_int"};
79 EXPECT_EXIT(TestParser(countof(arg_no_value), arg_no_value), ::testing::ExitedWithCode(1),
80 "ERROR");
81
82 const char *arg_invalid_value[] = {"", "--bar_int", "--foo_int=3"};
83 EXPECT_EXIT(TestParser(countof(arg_invalid_value), arg_invalid_value),
84 ::testing::ExitedWithCode(1), "ERROR");
85
86 const char *arg_bad_format[] = {"", "--bar_int="};
87 EXPECT_EXIT(TestParser(countof(arg_bad_format), arg_bad_format), ::testing::ExitedWithCode(1),
88 "ERROR");
89}
90
91TEST_F(CommandlineflagsTest, ParseDoubleFlags) {
92 const char *argv[] = {"", "--foo_double=3.14", "--bar_double", "1.2"};
93 TestParser(countof(argv), argv);
94
95 EXPECT_EQ(3.14, FLAGS_foo_double);
96 EXPECT_EQ(1.2, FLAGS_bar_double);
97
98 const char *arg_no_value[] = {"", "--bar_double"};
99 EXPECT_EXIT(TestParser(2, arg_no_value), ::testing::ExitedWithCode(1), "ERROR");
100
101 const char *arg_bad_format[] = {"", "--bar_double="};
102 EXPECT_EXIT(TestParser(2, arg_bad_format), ::testing::ExitedWithCode(1), "ERROR");
103}
104
105TEST_F(CommandlineflagsTest, ParseStringFlags) {
106 const char *argv[] = {"", "--foo_string=abc", "--bar_string", "def"};
107 TestParser(countof(argv), argv);
108
109 EXPECT_STREQ("abc", FLAGS_foo_string.c_str());
110 EXPECT_STREQ("def", FLAGS_bar_string.c_str());
111
112 const char *arg_no_value[] = {"", "--bar_string"};
113 EXPECT_EXIT(TestParser(2, arg_no_value), ::testing::ExitedWithCode(1), "ERROR");
114
115 FLAGS_bar_string.set_value("bar");
116 const char *arg_empty_string[] = {"", "--bar_string="};
117 TestParser(2, arg_empty_string);
118 EXPECT_STREQ("", FLAGS_bar_string.c_str());
119}
120
121TEST_F(CommandlineflagsTest, ParseBoolFlags) {
122 const char *argv[] = {"", "--foo_bool=true", "--bar_bool=1"};
123 FLAGS_foo_bool.set_value(false);
124 FLAGS_bar_bool.set_value(false);
125 TestParser(countof(argv), argv);
126 // Verify changed value
127 EXPECT_TRUE(FLAGS_foo_bool);
128 EXPECT_TRUE(FLAGS_bar_bool);
129
130 const char *inv_argv[] = {"", "--foo_bool=false", "--bar_bool=0"};
131 FLAGS_foo_bool.set_value(true);
132 FLAGS_bar_bool.set_value(true);
133 TestParser(3, inv_argv);
134 // Verify changed value
135 EXPECT_FALSE(FLAGS_foo_bool);
136 EXPECT_FALSE(FLAGS_bar_bool);
137
138 const char *arg_implied_true[] = {"", "--bar_bool"};
139 FLAGS_bar_bool.set_value(false);
140 TestParser(2, arg_implied_true);
141 EXPECT_TRUE(FLAGS_bar_bool);
142
143 const char *arg_missing_val[] = {"", "--bar_bool="};
144 EXPECT_EXIT(TestParser(2, arg_missing_val), ::testing::ExitedWithCode(1), "ERROR");
145}
146
148 EXPECT_STREQ("", FLAGS_q.c_str());
149 const char *argv[] = {"", "-q", "text"};
150 TestParser(countof(argv), argv);
151 EXPECT_STREQ("text", FLAGS_q.c_str());
152}
153} // namespace tesseract
BOOL_PARAM_FLAG(foo_bool, false, "Bool flag for testing")
STRING_PARAM_FLAG(foo_string, "foo", "String flag for testing")
DOUBLE_PARAM_FLAG(foo_double, 0.1, "Double flag for testing")
INT_PARAM_FLAG(foo_int, 0, "Integer flag for testing")
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:2043
#define EXPECT_TRUE(condition)
Definition: gtest.h:1982
#define EXPECT_STREQ(s1, s2)
Definition: gtest.h:2112
#define EXPECT_FALSE(condition)
Definition: gtest.h:1986
void ParseCommandLineFlags(const char *usage, int *argc, char ***argv, const bool remove_flags)
constexpr size_t countof(T const (&)[N]) noexcept
Definition: serialis.h:34
TEST_F(EuroText, FastLatinOCR)
void TestParser(int argc, const char **const_argv)
void TestParser(const char *usage, int argc, const char **const_argv)