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 "ConditionsTest.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 "Conditions.h"
18#include "SettingsParser.h"
19
20
21class TestConditionContext : public ConditionContext {
22public:
23			bool				IsSafeMode() const
24									{ return false; }
25			bool				BootVolumeIsReadOnly() const
26									{ return false; }
27};
28
29
30static TestConditionContext sConditionContext;
31
32
33ConditionsTest::ConditionsTest()
34{
35}
36
37
38ConditionsTest::~ConditionsTest()
39{
40}
41
42
43void
44ConditionsTest::TestEmpty()
45{
46	Condition* condition = _Condition("");
47	CPPUNIT_ASSERT(condition == NULL);
48}
49
50
51void
52ConditionsTest::TestSafemode()
53{
54	Condition* condition = _Condition("safemode");
55	CPPUNIT_ASSERT(!condition->Test(sConditionContext));
56	CPPUNIT_ASSERT(condition->IsConstant(sConditionContext));
57
58	class SafemodeConditionContext : public TestConditionContext {
59	public:
60		bool IsSafeMode() const
61		{
62			return true;
63		}
64	} safemodeContext;
65	CPPUNIT_ASSERT(condition->Test(safemodeContext));
66	CPPUNIT_ASSERT(condition->IsConstant(safemodeContext));
67}
68
69
70void
71ConditionsTest::TestFileExists()
72{
73	Condition* condition = _Condition("file_exists /boot");
74	CPPUNIT_ASSERT(condition->Test(sConditionContext));
75	CPPUNIT_ASSERT(!condition->IsConstant(sConditionContext));
76
77	condition = _Condition("file_exists /boot/don't fool me!");
78	CPPUNIT_ASSERT(!condition->Test(sConditionContext));
79}
80
81
82void
83ConditionsTest::TestOr()
84{
85	Condition* condition = _Condition("or {\n"
86		"file_exists /boot\n"
87		"}\n");
88	CPPUNIT_ASSERT(condition->Test(sConditionContext));
89	CPPUNIT_ASSERT(!condition->IsConstant(sConditionContext));
90
91	condition = _Condition("or {\n"
92		"file_exists /nowhere\n"
93		"}\n");
94	CPPUNIT_ASSERT(!condition->Test(sConditionContext));
95	CPPUNIT_ASSERT(!condition->IsConstant(sConditionContext));
96
97	condition = _Condition("or {\n"
98		"file_exists /boot\n"
99		"file_exists /nowhere\n"
100		"}\n");
101	CPPUNIT_ASSERT(condition->Test(sConditionContext));
102	CPPUNIT_ASSERT(!condition->IsConstant(sConditionContext));
103
104	condition = _Condition("or {\n"
105		"not safemode\n"
106		"file_exists /boot\n"
107		"}\n");
108	CPPUNIT_ASSERT(condition->Test(sConditionContext));
109	CPPUNIT_ASSERT(condition->IsConstant(sConditionContext));
110
111	condition = _Condition("or {\n"
112		"safemode\n"
113		"file_exists /boot\n"
114		"}\n");
115	CPPUNIT_ASSERT(condition->Test(sConditionContext));
116	CPPUNIT_ASSERT(!condition->IsConstant(sConditionContext));
117}
118
119
120void
121ConditionsTest::TestAnd()
122{
123	Condition* condition = _Condition("and {\n"
124		"file_exists /boot\n"
125		"}\n");
126	CPPUNIT_ASSERT(condition->Test(sConditionContext));
127	CPPUNIT_ASSERT(!condition->IsConstant(sConditionContext));
128
129	condition = _Condition("and {\n"
130		"file_exists /nowhere\n"
131		"}\n");
132	CPPUNIT_ASSERT(!condition->Test(sConditionContext));
133	CPPUNIT_ASSERT(!condition->IsConstant(sConditionContext));
134
135	condition = _Condition("and {\n"
136		"file_exists /boot\n"
137		"file_exists /nowhere\n"
138		"}\n");
139	CPPUNIT_ASSERT(!condition->Test(sConditionContext));
140	CPPUNIT_ASSERT(!condition->IsConstant(sConditionContext));
141
142	condition = _Condition("and {\n"
143		"safemode\n"
144		"file_exists /nowhere\n"
145		"}\n");
146	CPPUNIT_ASSERT(!condition->Test(sConditionContext));
147	CPPUNIT_ASSERT(condition->IsConstant(sConditionContext));
148
149	condition = _Condition("and {\n"
150		"not safemode\n"
151		"file_exists /nowhere\n"
152		"}\n");
153	CPPUNIT_ASSERT(!condition->Test(sConditionContext));
154	CPPUNIT_ASSERT(!condition->IsConstant(sConditionContext));
155
156	condition = _Condition("and {\n"
157		"safemode\n"
158		"}\n");
159	CPPUNIT_ASSERT(!condition->Test(sConditionContext));
160	CPPUNIT_ASSERT(condition->IsConstant(sConditionContext));
161}
162
163
164void
165ConditionsTest::TestNot()
166{
167	Condition* condition = _Condition("not safemode");
168	CPPUNIT_ASSERT(condition->Test(sConditionContext));
169
170	class SafemodeConditionContext : public TestConditionContext {
171	public:
172		bool IsSafeMode() const
173		{
174			return true;
175		}
176	} safemodeContext;
177	CPPUNIT_ASSERT(!condition->Test(safemodeContext));
178
179}
180
181
182/*static*/ void
183ConditionsTest::AddTests(BTestSuite& parent)
184{
185	CppUnit::TestSuite& suite = *new CppUnit::TestSuite("ConditionsTest");
186
187	suite.addTest(new CppUnit::TestCaller<ConditionsTest>(
188		"ConditionsTest::TestEmpty", &ConditionsTest::TestEmpty));
189	suite.addTest(new CppUnit::TestCaller<ConditionsTest>(
190		"ConditionsTest::TestSafemode", &ConditionsTest::TestSafemode));
191	suite.addTest(new CppUnit::TestCaller<ConditionsTest>(
192		"ConditionsTest::TestFileExists", &ConditionsTest::TestFileExists));
193	suite.addTest(new CppUnit::TestCaller<ConditionsTest>(
194		"ConditionsTest::TestOr", &ConditionsTest::TestOr));
195	suite.addTest(new CppUnit::TestCaller<ConditionsTest>(
196		"ConditionsTest::TestAnd", &ConditionsTest::TestAnd));
197	suite.addTest(new CppUnit::TestCaller<ConditionsTest>(
198		"ConditionsTest::TestNot", &ConditionsTest::TestNot));
199
200	parent.addTest("ConditionsTest", &suite);
201}
202
203
204Condition*
205ConditionsTest::_Condition(const char* string)
206{
207	SettingsParser parser;
208	BString input("job A {\nif {");
209	input << string << "\n}\n}\n";
210
211	BMessage jobs;
212	CPPUNIT_ASSERT_EQUAL(B_OK, parser.Parse(input, jobs));
213
214	BMessage job;
215	CPPUNIT_ASSERT_EQUAL(B_OK, jobs.FindMessage("job", 0, &job));
216	CPPUNIT_ASSERT_EQUAL(2, job.CountNames(B_ANY_TYPE));
217	CPPUNIT_ASSERT_EQUAL(BString("A"), BString(job.GetString("name")));
218
219	BMessage message;
220	CPPUNIT_ASSERT_EQUAL(B_OK, job.FindMessage("if", &message));
221
222	Condition* condition = Conditions::FromMessage(message);
223	if (string[0] != '\0')
224		CPPUNIT_ASSERT(condition != NULL);
225	return condition;
226}
227