1/*
2 * Copyright 2015, Axel D��rfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "SettingsParserTest.h"
8
9#include <stdlib.h>
10
11#include <driver_settings.h>
12#include <String.h>
13
14#include <cppunit/TestCaller.h>
15#include <cppunit/TestSuite.h>
16
17#include "SettingsParser.h"
18
19
20SettingsParserTest::SettingsParserTest()
21{
22}
23
24
25SettingsParserTest::~SettingsParserTest()
26{
27}
28
29
30// #pragma mark - conditions
31
32
33void
34SettingsParserTest::TestConditionsEmpty()
35{
36	BMessage message;
37	CPPUNIT_ASSERT_EQUAL(B_OK, _ParseCondition("if {\n"
38		"}\n", message));
39	CPPUNIT_ASSERT(message.IsEmpty());
40}
41
42
43void
44SettingsParserTest::TestConditionsMultiLine()
45{
46	BMessage message;
47	CPPUNIT_ASSERT_EQUAL(B_OK, _ParseCondition("if {\n"
48		"\tsafemode\n"
49		"\tfile_exists one\n"
50		"}\n", message));
51	CPPUNIT_ASSERT_EQUAL(2, message.CountNames(B_ANY_TYPE));
52
53	BMessage subMessage;
54	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("safemode", &subMessage));
55	CPPUNIT_ASSERT(subMessage.IsEmpty());
56
57	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("file_exists",
58		&subMessage));
59	CPPUNIT_ASSERT_EQUAL(BString("one"),
60		BString(subMessage.GetString("args", 0, "-")));
61	CPPUNIT_ASSERT_EQUAL(1, subMessage.CountNames(B_ANY_TYPE));
62}
63
64
65void
66SettingsParserTest::TestConditionsFlat()
67{
68	BMessage message;
69	CPPUNIT_ASSERT_EQUAL(B_OK, _ParseCondition("if safemode\n", message));
70	CPPUNIT_ASSERT_EQUAL(1, message.CountNames(B_ANY_TYPE));
71
72	BMessage args;
73	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("safemode", &args));
74	CPPUNIT_ASSERT(args.IsEmpty());
75}
76
77
78void
79SettingsParserTest::TestConditionsFlatWithNot()
80{
81	BMessage message;
82	CPPUNIT_ASSERT_EQUAL(B_OK, _ParseCondition("if not safemode\n", message));
83	CPPUNIT_ASSERT_EQUAL(1, message.CountNames(B_ANY_TYPE));
84
85	BMessage subMessage;
86	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("not",
87		&subMessage));
88
89	BMessage args;
90	CPPUNIT_ASSERT_EQUAL(B_OK, subMessage.FindMessage("safemode", &args));
91	CPPUNIT_ASSERT(args.IsEmpty());
92}
93
94
95void
96SettingsParserTest::TestConditionsFlatWithArgs()
97{
98	BMessage message;
99	CPPUNIT_ASSERT_EQUAL(B_OK,
100		_ParseCondition("if file_exists one\n", message));
101	CPPUNIT_ASSERT_EQUAL(1, message.CountNames(B_ANY_TYPE));
102
103	BMessage args;
104	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("file_exists", &args));
105	CPPUNIT_ASSERT_EQUAL(BString("one"),
106		BString(args.GetString("args", 0, "-")));
107	CPPUNIT_ASSERT_EQUAL(1, args.CountNames(B_ANY_TYPE));
108}
109
110
111void
112SettingsParserTest::TestConditionsFlatWithNotAndArgs()
113{
114	BMessage message;
115	CPPUNIT_ASSERT_EQUAL(B_OK,
116		_ParseCondition("if not file_exists one\n", message));
117	CPPUNIT_ASSERT_EQUAL(1, message.CountNames(B_ANY_TYPE));
118
119	BMessage subMessage;
120	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("not",
121		&subMessage));
122
123	BMessage args;
124	CPPUNIT_ASSERT_EQUAL(B_OK, subMessage.FindMessage("file_exists", &args));
125	CPPUNIT_ASSERT_EQUAL(BString("one"),
126		BString(args.GetString("args", 0, "-")));
127	CPPUNIT_ASSERT_EQUAL(1, args.CountNames(B_ANY_TYPE));
128}
129
130
131void
132SettingsParserTest::TestConditionsMultiLineFlatNot()
133{
134	BMessage message;
135	CPPUNIT_ASSERT_EQUAL(B_OK, _ParseCondition("if {\n"
136		"\tnot safemode\n"
137		"}\n", message));
138
139	BMessage subMessage;
140	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("not",
141		&subMessage));
142	CPPUNIT_ASSERT_EQUAL(1, message.CountNames(B_ANY_TYPE));
143
144	BMessage args;
145	CPPUNIT_ASSERT_EQUAL(B_OK, subMessage.FindMessage("safemode", &args));
146	CPPUNIT_ASSERT_EQUAL(1, subMessage.CountNames(B_ANY_TYPE));
147	CPPUNIT_ASSERT(args.IsEmpty());
148}
149
150
151void
152SettingsParserTest::TestConditionsMultiLineFlatNotWithArgs()
153{
154	BMessage message;
155	CPPUNIT_ASSERT_EQUAL(B_OK, _ParseCondition("if {\n"
156		"\tnot file_exists one two\n"
157		"}\n", message));
158
159	BMessage subMessage;
160	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("not",
161		&subMessage));
162
163	BMessage args;
164	CPPUNIT_ASSERT_EQUAL(B_OK, subMessage.FindMessage("file_exists", &args));
165	CPPUNIT_ASSERT_EQUAL(BString("one"),
166		BString(args.GetString("args", 0, "-")));
167	CPPUNIT_ASSERT_EQUAL(BString("two"),
168		BString(args.GetString("args", 1, "-")));
169	CPPUNIT_ASSERT_EQUAL(1, args.CountNames(B_ANY_TYPE));
170	CPPUNIT_ASSERT_EQUAL(2, _ArrayCount(args, "args"));
171}
172
173
174void
175SettingsParserTest::TestConditionsMultiLineNot()
176{
177	BMessage message;
178	CPPUNIT_ASSERT_EQUAL(B_OK, _ParseCondition("if {\n"
179		"\tnot {\n"
180		"\t\tsafemode\n"
181		"\t}\n"
182		"}\n", message));
183
184	BMessage subMessage;
185	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("not", &subMessage));
186
187	BMessage args;
188	CPPUNIT_ASSERT_EQUAL(B_OK, subMessage.FindMessage("safemode", &args));
189	CPPUNIT_ASSERT(args.IsEmpty());
190}
191
192
193// #pragma mark - events
194
195
196void
197SettingsParserTest::TestEventsEmpty()
198{
199	BMessage message;
200	CPPUNIT_ASSERT_EQUAL(B_OK, _ParseEvent("on {\n"
201		"}\n", message));
202	CPPUNIT_ASSERT(message.IsEmpty());
203}
204
205
206void
207SettingsParserTest::TestEventsMultiLine()
208{
209	BMessage message;
210	CPPUNIT_ASSERT_EQUAL(B_OK, _ParseEvent("on {\n"
211		"\tfile_created one\n"
212		"\tdemand\n"
213		"}\n", message));
214	CPPUNIT_ASSERT_EQUAL(2, message.CountNames(B_ANY_TYPE));
215
216	BMessage subMessage;
217	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("demand", &subMessage));
218	CPPUNIT_ASSERT(subMessage.IsEmpty());
219
220	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("file_created",
221		&subMessage));
222	CPPUNIT_ASSERT_EQUAL(BString("one"),
223		BString(subMessage.GetString("args", 0, "-")));
224	CPPUNIT_ASSERT_EQUAL(1, subMessage.CountNames(B_ANY_TYPE));
225}
226
227
228void
229SettingsParserTest::TestEventsFlat()
230{
231	BMessage message;
232	CPPUNIT_ASSERT_EQUAL(B_OK, _ParseEvent("on demand\n", message));
233	CPPUNIT_ASSERT_EQUAL(1, message.CountNames(B_ANY_TYPE));
234
235	BMessage args;
236	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("demand", &args));
237	CPPUNIT_ASSERT(args.IsEmpty());
238}
239
240
241void
242SettingsParserTest::TestEventsFlatWithArgs()
243{
244	BMessage message;
245	CPPUNIT_ASSERT_EQUAL(B_OK, _ParseEvent("on file_created one\n", message));
246	CPPUNIT_ASSERT_EQUAL(1, message.CountNames(B_ANY_TYPE));
247
248	BMessage args;
249	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("file_created", &args));
250	CPPUNIT_ASSERT_EQUAL(BString("one"),
251		BString(args.GetString("args", 0, "-")));
252	CPPUNIT_ASSERT_EQUAL(1, args.CountNames(B_ANY_TYPE));
253}
254
255
256// #pragma mark - environment
257
258
259void
260SettingsParserTest::TestEnvironmentMultiLine()
261{
262	BMessage message;
263	CPPUNIT_ASSERT_EQUAL(B_OK, _ParseName("env", "env {\n"
264		"from_script SetupEnvironment\n"
265		"TEST well, yes\n"
266		"}\n", message));
267	CPPUNIT_ASSERT_EQUAL(2, message.CountNames(B_ANY_TYPE));
268
269	CPPUNIT_ASSERT_EQUAL(BString("SetupEnvironment"),
270		BString(message.GetString("from_script", "-")));
271	CPPUNIT_ASSERT_EQUAL(1, _ArrayCount(message, "from_script"));
272
273	CPPUNIT_ASSERT_EQUAL(BString("well,"),
274		BString(message.GetString("TEST", 0, "-")));
275	CPPUNIT_ASSERT_EQUAL(BString("yes"),
276		BString(message.GetString("TEST", 1, "-")));
277	CPPUNIT_ASSERT_EQUAL(2, _ArrayCount(message, "TEST"));
278}
279
280
281void
282SettingsParserTest::TestEnvironmentFlat()
283{
284	BMessage message;
285	CPPUNIT_ASSERT_EQUAL(B_OK, _ParseName("env", "env SetupEnvironment\n",
286		message));
287	CPPUNIT_ASSERT_EQUAL(1, message.CountNames(B_ANY_TYPE));
288
289	CPPUNIT_ASSERT_EQUAL(BString("SetupEnvironment"),
290		BString(message.GetString("from_script", "-")));
291	CPPUNIT_ASSERT_EQUAL(1, _ArrayCount(message, "from_script"));
292}
293
294
295// #pragma mark - run
296
297
298void
299SettingsParserTest::TestRunFlat()
300{
301	SettingsParser parser;
302	BMessage jobs;
303	CPPUNIT_ASSERT_EQUAL(B_OK, parser.Parse("run me", jobs));
304	CPPUNIT_ASSERT_EQUAL(1, jobs.CountNames(B_ANY_TYPE));
305
306	BMessage message;
307	CPPUNIT_ASSERT_EQUAL(B_OK, jobs.FindMessage("run", &message));
308	CPPUNIT_ASSERT_EQUAL(BString("me"),
309		BString(message.GetString("target", "-")));
310	CPPUNIT_ASSERT_EQUAL(1, _ArrayCount(message, "target"));
311	CPPUNIT_ASSERT_EQUAL(1, message.CountNames(B_ANY_TYPE));
312}
313
314
315void
316SettingsParserTest::TestRunMultiLine()
317{
318	SettingsParser parser;
319	BMessage jobs;
320	status_t status = parser.Parse("run {\n"
321		"\tme\n"
322		"\tyou\n"
323		"}\n", jobs);
324	CPPUNIT_ASSERT_EQUAL(B_OK, status);
325	CPPUNIT_ASSERT_EQUAL(1, jobs.CountNames(B_ANY_TYPE));
326
327	BMessage message;
328	CPPUNIT_ASSERT_EQUAL(B_OK, jobs.FindMessage("run", &message));
329	CPPUNIT_ASSERT_EQUAL(BString("me"),
330		BString(message.GetString("target", 0, "-")));
331	CPPUNIT_ASSERT_EQUAL(BString("you"),
332		BString(message.GetString("target", 1, "-")));
333	CPPUNIT_ASSERT_EQUAL(2, _ArrayCount(message, "target"));
334	CPPUNIT_ASSERT_EQUAL(1, message.CountNames(B_ANY_TYPE));
335}
336
337
338void
339SettingsParserTest::TestRunIfThenElseFlat()
340{
341	SettingsParser parser;
342	BMessage jobs;
343	status_t status = parser.Parse("run {\n"
344		"\tif safemode\n"
345		"\tthen this\n"
346		"\telse that\n"
347		"}\n", jobs);
348	CPPUNIT_ASSERT_EQUAL(B_OK, status);
349
350	BMessage message;
351	CPPUNIT_ASSERT_EQUAL(B_OK, jobs.FindMessage("run", &message));
352	CPPUNIT_ASSERT_EQUAL(3, message.CountNames(B_ANY_TYPE));
353
354	BMessage then;
355	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("then", &then));
356	CPPUNIT_ASSERT_EQUAL(BString("this"),
357		BString(then.GetString("target", "-")));
358	CPPUNIT_ASSERT_EQUAL(1, _ArrayCount(then, "target"));
359	CPPUNIT_ASSERT_EQUAL(1, then.CountNames(B_ANY_TYPE));
360
361	BMessage otherwise;
362	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("else", &otherwise));
363	CPPUNIT_ASSERT_EQUAL(BString("that"),
364		BString(otherwise.GetString("target", "-")));
365	CPPUNIT_ASSERT_EQUAL(1, _ArrayCount(otherwise, "target"));
366	CPPUNIT_ASSERT_EQUAL(1, otherwise.CountNames(B_ANY_TYPE));
367}
368
369
370void
371SettingsParserTest::TestRunIfThenElseMultiLine()
372{
373	SettingsParser parser;
374	BMessage jobs;
375	status_t status = parser.Parse("run {\n"
376		"\tif {\n"
377		"\t\tread_only\n"
378		"\t}\n"
379		"\tthen {\n"
380		"\t\tthis\n"
381		"\t}\n"
382		"\telse {\n"
383		"\t\tthat\n"
384		"\t}\n"
385		"}\n", jobs);
386	CPPUNIT_ASSERT_EQUAL(B_OK, status);
387
388	BMessage message;
389	CPPUNIT_ASSERT_EQUAL(B_OK, jobs.FindMessage("run", &message));
390	CPPUNIT_ASSERT_EQUAL(3, message.CountNames(B_ANY_TYPE));
391
392	BMessage then;
393	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("then", &then));
394	CPPUNIT_ASSERT_EQUAL(BString("this"),
395		BString(then.GetString("target", "-")));
396	CPPUNIT_ASSERT_EQUAL(1, _ArrayCount(then, "target"));
397	CPPUNIT_ASSERT_EQUAL(1, then.CountNames(B_ANY_TYPE));
398
399	BMessage otherwise;
400	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("else", &otherwise));
401	CPPUNIT_ASSERT_EQUAL(BString("that"),
402		BString(otherwise.GetString("target", "-")));
403	CPPUNIT_ASSERT_EQUAL(1, _ArrayCount(otherwise, "target"));
404	CPPUNIT_ASSERT_EQUAL(1, otherwise.CountNames(B_ANY_TYPE));
405}
406
407
408// #pragma mark -
409
410
411/*static*/ void
412SettingsParserTest::AddTests(BTestSuite& parent)
413{
414	CppUnit::TestSuite& suite = *new CppUnit::TestSuite("SettingsParserTest");
415
416	// Conditions
417	suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
418		"SettingsParserTest::TestConditionsEmpty",
419		&SettingsParserTest::TestConditionsEmpty));
420	suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
421		"SettingsParserTest::TestConditionsMultiLine",
422		&SettingsParserTest::TestConditionsMultiLine));
423	suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
424		"SettingsParserTest::TestConditionsFlat",
425		&SettingsParserTest::TestConditionsFlat));
426	suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
427		"SettingsParserTest::TestConditionsFlatWithNot",
428		&SettingsParserTest::TestConditionsFlatWithNot));
429	suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
430		"SettingsParserTest::TestConditionsFlatWithArgs",
431		&SettingsParserTest::TestConditionsFlatWithArgs));
432	suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
433		"SettingsParserTest::TestConditionsFlatWithNotAndArgs",
434		&SettingsParserTest::TestConditionsFlatWithNotAndArgs));
435	suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
436		"SettingsParserTest::TestConditionsMultiLineFlatNot",
437		&SettingsParserTest::TestConditionsMultiLineFlatNot));
438	suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
439		"SettingsParserTest::TestConditionsMultiLineFlatNotWithArgs",
440		&SettingsParserTest::TestConditionsMultiLineFlatNotWithArgs));
441	suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
442		"SettingsParserTest::TestConditionsMultiLineNot",
443		&SettingsParserTest::TestConditionsMultiLineNot));
444
445	// Events
446	suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
447		"SettingsParserTest::TestEventsEmpty",
448		&SettingsParserTest::TestEventsEmpty));
449	suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
450		"SettingsParserTest::TestEventsMultiLine",
451		&SettingsParserTest::TestEventsMultiLine));
452	suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
453		"SettingsParserTest::TestEventsFlat",
454		&SettingsParserTest::TestEventsFlat));
455	suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
456		"SettingsParserTest::TestEventsFlatWithArgs",
457		&SettingsParserTest::TestEventsFlatWithArgs));
458
459	// Environment
460	suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
461		"SettingsParserTest::TestEnvironmentMultiLine",
462		&SettingsParserTest::TestEnvironmentMultiLine));
463	suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
464		"SettingsParserTest::TestEnvironmentFlat",
465		&SettingsParserTest::TestEnvironmentFlat));
466
467	// Run
468	suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
469		"SettingsParserTest::TestRunFlat",
470		&SettingsParserTest::TestRunFlat));
471	suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
472		"SettingsParserTest::TestRunMultiLine",
473		&SettingsParserTest::TestRunMultiLine));
474	suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
475		"SettingsParserTest::TestRunIfThenElseFlat",
476		&SettingsParserTest::TestRunIfThenElseFlat));
477	suite.addTest(new CppUnit::TestCaller<SettingsParserTest>(
478		"SettingsParserTest::TestRunIfThenElseMultiLine",
479		&SettingsParserTest::TestRunIfThenElseMultiLine));
480
481	parent.addTest("SettingsParserTest", &suite);
482}
483
484
485status_t
486SettingsParserTest::_ParseCondition(const char* text, BMessage& message)
487{
488	return _ParseName("if", text, message);
489}
490
491
492status_t
493SettingsParserTest::_ParseEvent(const char* text, BMessage& message)
494{
495	return _ParseName("on", text, message);
496}
497
498
499status_t
500SettingsParserTest::_ParseName(const char* name, const char* text,
501	BMessage& message)
502{
503	SettingsParser parser;
504	BString input("job A {\n");
505	input << text << "\n}\n";
506
507	BMessage jobs;
508	status_t status = parser.Parse(input, jobs);
509	if (status != B_OK)
510		return status;
511
512	BMessage job;
513	status = jobs.FindMessage("job", 0, &job);
514	if (status != B_OK)
515		return status;
516
517	CPPUNIT_ASSERT_EQUAL(2, job.CountNames(B_ANY_TYPE));
518	CPPUNIT_ASSERT_EQUAL(BString("A"), BString(job.GetString("name")));
519
520	return job.FindMessage(name, &message);
521}
522
523
524int32
525SettingsParserTest::_ArrayCount(BMessage& message, const char* name)
526{
527	int32 found;
528	if (message.GetInfo(name, NULL, &found, NULL) != B_OK)
529		return 0;
530
531	return found;
532}
533