1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220 | #include "gate/tests.hpp"
#include "gate/applications.hpp"
using namespace gate;
static void checkCopyAssignOption(AppOptionDef const& testDef)
{
AppOptionDef testDefCopy(testDef);
AppOptionDef testDefAssigned = AppOptionDef::createSwitch("switch", "S", "other", "descr");<--- Variable 'testDefAssigned' is reassigned a value before the old one has been used.
testDefAssigned = testDefCopy;<--- Variable 'testDefAssigned' is reassigned a value before the old one has been used.
GATEXX_TEST_CHECK_EQUAL(testDef.Key(), testDefAssigned.Key());
GATEXX_TEST_CHECK_EQUAL(testDef.Alias(), testDefAssigned.Alias());
GATEXX_TEST_CHECK_EQUAL(testDef.OptionName(), testDefAssigned.OptionName());
GATEXX_TEST_CHECK_EQUAL(testDef.Description(), testDefAssigned.Description());
GATEXX_TEST_CHECK_EQUAL(testDef.Type(), testDefAssigned.Type());
GATEXX_TEST_CHECK_EQUAL(testDef.getBool(), testDefAssigned.getBool());
GATEXX_TEST_CHECK_EQUAL(testDef.getInt32(), testDefAssigned.getInt32());
GATEXX_TEST_CHECK_EQUAL(testDef.getInt64(), testDefAssigned.getInt64());
GATEXX_TEST_CHECK_EQUAL(testDef.getReal(), testDefAssigned.getReal());
GATEXX_TEST_CHECK_EQUAL(testDef.getString(), testDefAssigned.getString());
testDef.getStringArray();
}
template<class T>
void checkOptionDef(T& value, AppOptionDef::OptionTypeEnum otype)
{
const AppOptionDef testDef("key", otype, &value, "K", "value", "description");
checkCopyAssignOption(testDef);
}
template<class T>
void checkOptionDef(AppOptionDef::OptionTypeEnum otype)
{
T value = T();
checkOptionDef(value, otype);
}
GATEXX_TEST_UNIT(AppOption)
{
GATEXX_TEST_CHECK_NOTHROW(checkOptionDef<bool_t>(AppOptionDef::OptionType_Boolean));
GATEXX_TEST_CHECK_NOTHROW(checkOptionDef<int32_t>(AppOptionDef::OptionType_Int32));
GATEXX_TEST_CHECK_NOTHROW(checkOptionDef<int64_t>(AppOptionDef::OptionType_Int64));
GATEXX_TEST_CHECK_NOTHROW(checkOptionDef<real64_t>(AppOptionDef::OptionType_Real));
GATEXX_TEST_CHECK_NOTHROW(checkOptionDef<gate_string_t>(AppOptionDef::OptionType_String));
{
ArrayList<gate_string_t> tmp;
gate_arraylist_t a = tmp.c_impl();
GATEXX_TEST_CHECK_NOTHROW(checkOptionDef<gate_arraylist_t>(a, AppOptionDef::OptionType_StringArray));
}
AppOptionDef opt_switch = AppOptionDef::createSwitch("switch", "SW", NULL, NULL);
AppOptionDef opt_bool = AppOptionDef::createBool("bool", "B", false, NULL, NULL);
AppOptionDef opt_i32 = AppOptionDef::createInt32("int", "I", 0, NULL, NULL);
AppOptionDef opt_i64 = AppOptionDef::createInt64("long", "L", 0, NULL, NULL);
AppOptionDef opt_r64 = AppOptionDef::createReal64("real", "R", 0.0, NULL, NULL);
AppOptionDef opt_string = AppOptionDef::createString("string", "S", "", NULL, NULL);
AppOptionDef opt_array = AppOptionDef::createArray("array", "A", NULL, NULL);
AppOptionDef opt_unnamed1 = AppOptionDef::createString("");
AppOptionDef opt_unnamed2 = AppOptionDef::createInt32("");
checkCopyAssignOption(opt_switch);
checkCopyAssignOption(opt_bool);
checkCopyAssignOption(opt_i32);
checkCopyAssignOption(opt_i64);
checkCopyAssignOption(opt_r64);
checkCopyAssignOption(opt_string);
checkCopyAssignOption(opt_array);
AppOptionDef* opts[] =
{
&opt_switch,
&opt_bool,
&opt_i32,
&opt_i64,
&opt_r64,
&opt_string,
&opt_array,
&opt_unnamed1,
&opt_unnamed2
};
gate::size_t const optsCount = sizeof(opts) / sizeof(opts[0]);
ArrayList<String> test_args_builder;
test_args_builder
<< "--switch" // bool switch option
<< "--bool" << "1" // bool value option
<< "--int" << "12" // int32 value option
<< "--long" << "1234" // int64 value option
<< "--real" << "12.34" // float value option
<< "--string" << "text" // string value option
<< "--array" << "a" << "--array" << "b" << "--array" << "c" // multiple string option values
<< "hello" // unnamed string option
<< "42" // unnamed int32 option
;
Array<String> const test_args = test_args_builder.toArray();
gate::size_t args_parsed = App::parseAppOptions(test_args, opts, optsCount);
GATEXX_TEST_CHECK(args_parsed == test_args.length());
GATEXX_TEST_CHECK_EQUAL(opt_switch.getBool(), true);
GATEXX_TEST_CHECK_EQUAL(opt_bool.getBool(), true);
GATEXX_TEST_CHECK_EQUAL(opt_i32.getInt32(), 12);
GATEXX_TEST_CHECK_EQUAL(opt_i64.getInt64(), 1234);
GATEXX_TEST_CHECK_EQUAL(opt_r64.getReal(), 12.34);
GATEXX_TEST_CHECK_EQUAL(opt_string.getString(), "text");
GATEXX_TEST_CHECK_EQUAL(!opt_switch, false);
GATEXX_TEST_CHECK_EQUAL(!opt_bool, false);
GATEXX_TEST_CHECK_EQUAL(!opt_i32, false);
GATEXX_TEST_CHECK_EQUAL(!opt_i64, false);
GATEXX_TEST_CHECK_EQUAL(!opt_r64, false);
GATEXX_TEST_CHECK_EQUAL(!opt_string, false);
GATEXX_TEST_CHECK_EQUAL(!opt_array, false);
StringArray arr = opt_array.getStringArray();
GATEXX_TEST_REQUIRE_EQUAL(arr.length(), 3);
GATEXX_TEST_CHECK_EQUAL(arr[0], "a");
GATEXX_TEST_CHECK_EQUAL(arr[1], "b");
GATEXX_TEST_CHECK_EQUAL(arr[2], "c");
GATEXX_TEST_CHECK_EQUAL(opt_unnamed1.getString(), "hello");
GATEXX_TEST_CHECK_EQUAL(opt_unnamed2.getInt32(), 42);
MemStream printedHelp;
GATEXX_TEST_CHECK_NOTHROW(App::printAppOptions(opts, optsCount, printedHelp));
GATEXX_TEST_CHECK(printedHelp.size() > 0);
}
GATEXX_TEST_UNIT(AppArgs)
{
static StaticString const cmdLine = "a1 a2 \"a 3\" a4 \"a \\\"5\\\"\" a6";
Array<String> args;
GATEXX_TEST_CHECK_NOTHROW(args = App::parseCommandLine(cmdLine));
GATEXX_TEST_REQUIRE_EQUAL(args.length(), 6U);
GATEXX_TEST_CHECK_EQUAL(args[0], "a1");
GATEXX_TEST_CHECK_EQUAL(args[1], "a2");
GATEXX_TEST_CHECK_EQUAL(args[2], "a 3");
GATEXX_TEST_CHECK_EQUAL(args[3], "a4");
GATEXX_TEST_CHECK_EQUAL(args[4], "a \"5\"");
GATEXX_TEST_CHECK_EQUAL(args[5], "a6");
}
class GATE_CORE_CPP_API TestAppImpl : public App
{
public:
virtual void run() override
{
gate::uintptr_t appHandle = this->getHandle();
GATEXX_TEST_CHECK_EQUAL(appHandle, 1234);
String appPath = this->getPath();
GATEXX_TEST_CHECK_EQUAL(appPath, "pseudo_test_app");
Array<String> appArgs = this->getArgs();
GATEXX_TEST_CHECK_EQUAL(appArgs.length(), 2U);
this->setExitCode(12);
}
};
GATEXX_TEST_UNIT(AppInterface)
{
TestAppImpl app;
char const* appArgs[] = { "a1", "a2" };
int appExitCode = App::runApp(app, "pseudo_test_app", appArgs, 2, 1234);
GATEXX_TEST_CHECK_EQUAL(appExitCode, 12);
}
static char const* const test_svc_name = "pseudo_test_service";
class GATE_CORE_CPP_API TestAppServiceImpl : public AppService
{
public:
result_t initResultMockup;
TestAppServiceImpl()
: AppService(test_svc_name),
initResultMockup(results::Canceled)
{
}
virtual void onInit() override
{
gate_appservice_t* ptr_svc = this->c_impl();
AppService::on_start(ptr_svc);
this->run();
AppService::on_pause(ptr_svc);
AppService::on_continue(ptr_svc);
AppService::on_stop(ptr_svc);
AppService::on_error(ptr_svc, 0, 0, NULL);
gate::raiseException(this->initResultMockup);
}
virtual void run() override
{
String svcName = this->getServiceName();
GATEXX_TEST_CHECK_EQUAL(svcName, test_svc_name);
this->cancel();
}
};
GATEXX_TEST_UNIT(AppServiceInterface)
{
{
TestAppServiceImpl svc;
svc.initResultMockup = results::Canceled; // cancel initalization with error code
int exitCode = AppService::runService(svc, test_svc_name, NULL, 0, 0);
GATEXX_TEST_CHECK_EQUAL(exitCode, 0);
}
{
TestAppServiceImpl svc;
svc.initResultMockup = results::Failed; // init-fail with exception
int exitCode = AppService::runService(svc, test_svc_name, NULL, 0, 0);
GATEXX_TEST_CHECK_EQUAL(exitCode, GATE_RESULT_TO_EXITCODE(results::Failed));
}
}
|