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 "DriverSettingsMessageAdapterTest.h"
8
9#include <stdlib.h>
10
11#include <driver_settings.h>
12#include <String.h>
13
14#include <DriverSettingsMessageAdapter.h>
15
16#include <cppunit/TestCaller.h>
17#include <cppunit/TestSuite.h>
18
19
20namespace {
21
22
23class Settings {
24public:
25	Settings(const char* string)
26	{
27		fSettings = parse_driver_settings_string(string);
28		CppUnit::Asserter::failIf(fSettings == NULL,
29			"Could not parse settings");
30	}
31
32	status_t ToMessage(const settings_template* settingsTemplate,
33		BMessage& message)
34	{
35		DriverSettingsMessageAdapter adapter;
36		return adapter.ConvertFromDriverSettings(
37			*get_driver_settings(fSettings), settingsTemplate, message);
38	}
39
40	~Settings()
41	{
42		unload_driver_settings(fSettings);
43	}
44
45private:
46	void* fSettings;
47};
48
49
50}	// empty namespace
51
52
53// #pragma mark -
54
55
56DriverSettingsMessageAdapterTest::DriverSettingsMessageAdapterTest()
57{
58}
59
60
61DriverSettingsMessageAdapterTest::~DriverSettingsMessageAdapterTest()
62{
63}
64
65
66void
67DriverSettingsMessageAdapterTest::TestPrimitivesToMessage()
68{
69	const settings_template kTemplate[] = {
70		{B_BOOL_TYPE, "bool1", NULL},
71		{B_BOOL_TYPE, "bool2", NULL},
72		{B_BOOL_TYPE, "bool3", NULL},
73		{B_BOOL_TYPE, "bool4", NULL},
74		{B_BOOL_TYPE, "bool5", NULL},
75		{B_BOOL_TYPE, "bool6", NULL},
76		{B_BOOL_TYPE, "bool7", NULL},
77		{B_BOOL_TYPE, "bool8", NULL},
78		{B_BOOL_TYPE, "bool9", NULL},
79		{B_BOOL_TYPE, "empty_bool", NULL},
80		{B_INT32_TYPE, "int32", NULL},
81		{B_INT32_TYPE, "negative_int32", NULL},
82		{B_INT32_TYPE, "empty_int32", NULL},
83		{B_STRING_TYPE, "string", NULL},
84		{B_STRING_TYPE, "long_string", NULL},
85		{B_STRING_TYPE, "empty_string", NULL},
86		{}
87	};
88	Settings settings("bool1 true\n"
89		"bool2 1\n"
90		"bool3 on\n"
91		"bool4 yes\n"
92		"bool5 enabled\n"
93		"bool6 false\n"
94		"bool7 off\n"
95		"bool8 gurkensalat\n"
96		"bool9 0\n"
97		"empty_bool\n"
98		"int32 42\n"
99		"negative_int32 -42\n"
100		"empty_int32\n"
101		"string Hey\n"
102		"long_string \"This is but a test\"\n"
103		"empty_string\n");
104
105	BMessage message;
106	CPPUNIT_ASSERT_EQUAL(B_OK, settings.ToMessage(kTemplate, message));
107	CPPUNIT_ASSERT_EQUAL(10, message.CountNames(B_BOOL_TYPE));
108	CPPUNIT_ASSERT_EQUAL(2, message.CountNames(B_INT32_TYPE));
109	CPPUNIT_ASSERT_EQUAL(2, message.CountNames(B_STRING_TYPE));
110	CPPUNIT_ASSERT_EQUAL(14, message.CountNames(B_ANY_TYPE));
111
112	// bool values
113	CPPUNIT_ASSERT_EQUAL_MESSAGE("bool1", true, message.GetBool("bool1"));
114	CPPUNIT_ASSERT_EQUAL_MESSAGE("bool2", true, message.GetBool("bool2"));
115	CPPUNIT_ASSERT_EQUAL_MESSAGE("bool3", true, message.GetBool("bool3"));
116	CPPUNIT_ASSERT_EQUAL_MESSAGE("bool4", true, message.GetBool("bool4"));
117	CPPUNIT_ASSERT_EQUAL_MESSAGE("bool5", true, message.GetBool("bool5"));
118	CPPUNIT_ASSERT_EQUAL_MESSAGE("bool6", false,
119		message.GetBool("bool6", true));
120	CPPUNIT_ASSERT_EQUAL_MESSAGE("bool7", false,
121		message.GetBool("bool7", true));
122	CPPUNIT_ASSERT_EQUAL_MESSAGE("bool8", false,
123		message.GetBool("bool8", true));
124	CPPUNIT_ASSERT_EQUAL_MESSAGE("bool9", false,
125		message.GetBool("bool9", true));
126	CPPUNIT_ASSERT_EQUAL_MESSAGE("empty_bool", true,
127		message.GetBool("empty_bool"));
128
129	// int32 values
130	CPPUNIT_ASSERT_EQUAL(42, message.GetInt32("int32", 0));
131	CPPUNIT_ASSERT_EQUAL(-42, message.GetInt32("negative_int32", 0));
132	CPPUNIT_ASSERT_EQUAL(false, message.HasInt32("empty_int32"));
133
134	// string values
135	CPPUNIT_ASSERT_EQUAL(BString("Hey"), BString(message.GetString("string")));
136	CPPUNIT_ASSERT_EQUAL(BString("This is but a test"),
137		BString(message.GetString("long_string")));
138	CPPUNIT_ASSERT_EQUAL(false, message.HasString("empty_string"));
139}
140
141
142void
143DriverSettingsMessageAdapterTest::TestMessage()
144{
145	const settings_template kSubTemplate[] = {
146		{B_BOOL_TYPE, "bool", NULL},
147		{}
148	};
149	const settings_template kTemplate[] = {
150		{B_MESSAGE_TYPE, "message", kSubTemplate},
151		{}
152	};
153	Settings settingsA("message {\n"
154		"    bool\n"
155		"}\n");
156	BMessage message;
157	CPPUNIT_ASSERT_EQUAL(B_OK, settingsA.ToMessage(kTemplate, message));
158	BMessage subMessage;
159	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("message", &subMessage));
160	CPPUNIT_ASSERT_EQUAL_MESSAGE("bool", true, subMessage.GetBool("bool"));
161	CPPUNIT_ASSERT_EQUAL(1, message.CountNames(B_ANY_TYPE));
162
163	Settings settingsB("message {\n"
164		"}\n");
165	CPPUNIT_ASSERT_EQUAL(B_OK, settingsB.ToMessage(kTemplate, message));
166	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("message", &subMessage));
167	CPPUNIT_ASSERT_EQUAL(1, message.CountNames(B_ANY_TYPE));
168
169	Settings settingsC("\n");
170	CPPUNIT_ASSERT_EQUAL(B_OK, settingsC.ToMessage(kTemplate, message));
171	CPPUNIT_ASSERT(message.IsEmpty());
172}
173
174
175void
176DriverSettingsMessageAdapterTest::TestParent()
177{
178	const settings_template kSubTemplate[] = {
179		{B_STRING_TYPE, "name", NULL, true},
180		{B_BOOL_TYPE, "bool", NULL},
181		{}
182	};
183	const settings_template kTemplate[] = {
184		{B_MESSAGE_TYPE, "message", kSubTemplate},
185		{}
186	};
187	Settings settingsA("message first {\n"
188		"    bool\n"
189		"}\n");
190	BMessage message;
191	CPPUNIT_ASSERT_EQUAL(B_OK, settingsA.ToMessage(kTemplate, message));
192	BMessage subMessage;
193	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("message", &subMessage));
194	CPPUNIT_ASSERT_EQUAL_MESSAGE("bool", true, subMessage.GetBool("bool"));
195	CPPUNIT_ASSERT_EQUAL(BString("first"),
196		BString(subMessage.GetString("name")));
197
198	Settings settingsB("message second\n");
199	CPPUNIT_ASSERT_EQUAL(B_OK, settingsB.ToMessage(kTemplate, message));
200	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("message", &subMessage));
201	CPPUNIT_ASSERT_EQUAL(false, subMessage.HasBool("bool"));
202	CPPUNIT_ASSERT_EQUAL(BString("second"),
203		BString(subMessage.GetString("name", "-/-")));
204
205	const settings_template kSubSubTemplateC[] = {
206		{B_STRING_TYPE, "subname", NULL, true},
207		{B_BOOL_TYPE, "bool", NULL},
208		{}
209	};
210	const settings_template kSubTemplateC[] = {
211		{B_STRING_TYPE, "name", NULL, true},
212		{B_MESSAGE_TYPE, "sub", kSubSubTemplateC},
213		{}
214	};
215	const settings_template kTemplateC[] = {
216		{B_MESSAGE_TYPE, "message", kSubTemplateC},
217		{}
218	};
219
220	Settings settingsC("message other {\n"
221		"    sub third {\n"
222		"        hun audo\n"
223		"    }\n"
224		"    sub fourth\n"
225		"}");
226	CPPUNIT_ASSERT_EQUAL(B_OK, settingsC.ToMessage(kTemplateC, message));
227	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("message", &subMessage));
228	CPPUNIT_ASSERT_EQUAL(false, subMessage.HasBool("bool"));
229	CPPUNIT_ASSERT_EQUAL(BString("other"),
230		BString(subMessage.GetString("name", "-/-")));
231}
232
233
234void
235DriverSettingsMessageAdapterTest::TestConverter()
236{
237	class HexConverter : public DriverSettingsConverter {
238	public:
239		status_t ConvertFromDriverSettings(const driver_parameter& parameter,
240			const char* name, int32 index, uint32 type, BMessage& target)
241		{
242			const char* value = parameter.values[index];
243			if (value[0] == '0' && value[1] == 'x')
244				return target.AddInt32(name, (int32)strtol(value, NULL, 0));
245			return B_NOT_SUPPORTED;
246		}
247
248		status_t ConvertToDriverSettings(const BMessage& source,
249			const char* name, int32 index, uint32 type, BString& value)
250		{
251			int32 intValue;
252			if (index == 0 && source.FindInt32(name, 0, &intValue) == B_OK) {
253				BString string;
254				string.SetToFormat("0x%" B_PRIu32, intValue);
255				value << string;
256
257				return B_OK;
258			}
259			return B_NOT_SUPPORTED;
260		}
261	} converter;
262
263	const settings_template kTemplate[] = {
264		{B_INT32_TYPE, "test", NULL, false, &converter},
265		{}
266	};
267
268	Settings settings("test 0x2a 43");
269	BMessage message;
270	CPPUNIT_ASSERT_EQUAL(B_OK, settings.ToMessage(kTemplate, message));
271	CPPUNIT_ASSERT_EQUAL(42, message.GetInt32("test", 0, 0));
272	CPPUNIT_ASSERT_EQUAL(43, message.GetInt32("test", 1, 0));
273	CPPUNIT_ASSERT_EQUAL(1, message.CountNames(B_ANY_TYPE));
274}
275
276
277void
278DriverSettingsMessageAdapterTest::TestWildcard()
279{
280	const settings_template kTemplateA[] = {
281		{B_STRING_TYPE, NULL, NULL},
282		{B_INT32_TYPE, "test", NULL},
283		{}
284	};
285
286	Settings settingsA("this is\n"
287		"just a\n"
288		"test 42 43");
289	BMessage message;
290	CPPUNIT_ASSERT_EQUAL(B_OK, settingsA.ToMessage(kTemplateA, message));
291	CPPUNIT_ASSERT_EQUAL(42, message.GetInt32("test", 0, 0));
292	CPPUNIT_ASSERT_EQUAL(43, message.GetInt32("test", 1, 0));
293	CPPUNIT_ASSERT_EQUAL(3, message.CountNames(B_ANY_TYPE));
294	CPPUNIT_ASSERT_EQUAL(BString("is"),
295		BString(message.GetString("this", "-")));
296	CPPUNIT_ASSERT_EQUAL(BString("a"),
297		BString(message.GetString("just", "-")));
298
299	const settings_template kSubTemplateB[] = {
300		{B_STRING_TYPE, NULL, NULL, true},
301		{}
302	};
303	const settings_template kTemplateB[] = {
304		{B_MESSAGE_TYPE, "it", kSubTemplateB},
305		{}
306	};
307
308	Settings settingsB("it just works\n");
309	CPPUNIT_ASSERT_EQUAL(B_OK, settingsB.ToMessage(kTemplateB, message));
310	CPPUNIT_ASSERT_EQUAL(1, message.CountNames(B_ANY_TYPE));
311	BMessage subMessage;
312	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("it", &subMessage));
313	CPPUNIT_ASSERT_EQUAL(BString("just"),
314		BString(subMessage.GetString("it", 0, "-")));
315	CPPUNIT_ASSERT_EQUAL(BString("works"),
316		BString(subMessage.GetString("it", 1, "-")));
317	CPPUNIT_ASSERT_EQUAL(1, subMessage.CountNames(B_ANY_TYPE));
318
319	Settings settingsC("it {\n"
320		"\tstill works\n"
321		"}\n");
322	CPPUNIT_ASSERT_EQUAL(B_OK, settingsC.ToMessage(kTemplateB, message));
323	CPPUNIT_ASSERT_EQUAL(1, message.CountNames(B_ANY_TYPE));
324	CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("it", &subMessage));
325	CPPUNIT_ASSERT_EQUAL(BString("works"),
326		BString(subMessage.GetString("still", "-")));
327	CPPUNIT_ASSERT_EQUAL(1, subMessage.CountNames(B_ANY_TYPE));
328}
329
330
331/*static*/ void
332DriverSettingsMessageAdapterTest::AddTests(BTestSuite& parent)
333{
334	CppUnit::TestSuite& suite = *new CppUnit::TestSuite(
335		"DriverSettingsMessageAdapterTest");
336
337	suite.addTest(new CppUnit::TestCaller<DriverSettingsMessageAdapterTest>(
338		"DriverSettingsMessageAdapterTest::TestPrimitivesToMessage",
339		&DriverSettingsMessageAdapterTest::TestPrimitivesToMessage));
340	suite.addTest(new CppUnit::TestCaller<DriverSettingsMessageAdapterTest>(
341		"DriverSettingsMessageAdapterTest::TestMessage",
342		&DriverSettingsMessageAdapterTest::TestMessage));
343	suite.addTest(new CppUnit::TestCaller<DriverSettingsMessageAdapterTest>(
344		"DriverSettingsMessageAdapterTest::TestParent",
345		&DriverSettingsMessageAdapterTest::TestParent));
346	suite.addTest(new CppUnit::TestCaller<DriverSettingsMessageAdapterTest>(
347		"DriverSettingsMessageAdapterTest::TestConverter",
348		&DriverSettingsMessageAdapterTest::TestConverter));
349	suite.addTest(new CppUnit::TestCaller<DriverSettingsMessageAdapterTest>(
350		"DriverSettingsMessageAdapterTest::TestWildcard",
351		&DriverSettingsMessageAdapterTest::TestWildcard));
352
353	parent.addTest("DriverSettingsMessageAdapterTest", &suite);
354}
355