#include <stdlib.h>
#include <driver_settings.h>
#include <String.h>
#include <TestSuiteAddon.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include "SettingsParser.h"
class SettingsParserTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(SettingsParserTest);
CPPUNIT_TEST(TestConditionsEmpty);
CPPUNIT_TEST(TestConditionsMultiLine);
CPPUNIT_TEST(TestConditionsFlat);
CPPUNIT_TEST(TestConditionsFlatWithNot);
CPPUNIT_TEST(TestConditionsFlatWithArgs);
CPPUNIT_TEST(TestConditionsFlatWithNotAndArgs);
CPPUNIT_TEST(TestConditionsMultiLineFlatNot);
CPPUNIT_TEST(TestConditionsMultiLineFlatNotWithArgs);
CPPUNIT_TEST(TestConditionsMultiLineNot);
CPPUNIT_TEST(TestEventsEmpty);
CPPUNIT_TEST(TestEventsMultiLine);
CPPUNIT_TEST(TestEventsFlat);
CPPUNIT_TEST(TestEventsFlatWithArgs);
CPPUNIT_TEST(TestEnvironmentMultiLine);
CPPUNIT_TEST(TestEnvironmentFlat);
CPPUNIT_TEST(TestRunFlat);
CPPUNIT_TEST(TestRunMultiLine);
CPPUNIT_TEST(TestRunIfThenElseFlat);
CPPUNIT_TEST(TestRunIfThenElseMultiLine);
CPPUNIT_TEST_SUITE_END();
status_t _ParseCondition(const char* text, BMessage& message)
{
return _ParseName("if", text, message);
}
status_t _ParseEvent(const char* text, BMessage& message)
{
return _ParseName("on", text, message);
}
status_t _ParseName(const char* name, const char* text, BMessage& message)
{
SettingsParser parser;
BString input("job A {\n");
input << text << "\n}\n";
BMessage jobs;
status_t status = parser.Parse(input, jobs);
if (status != B_OK)
return status;
BMessage job;
status = jobs.FindMessage("job", 0, &job);
if (status != B_OK)
return status;
CPPUNIT_ASSERT_EQUAL(2, (int)job.CountNames(B_ANY_TYPE));
CPPUNIT_ASSERT_EQUAL(BString("A"), BString(job.GetString("name")));
return job.FindMessage(name, &message);
}
int32 _ArrayCount(BMessage& message, const char* name)
{
int32 found;
if (message.GetInfo(name, NULL, &found, NULL) != B_OK)
return 0;
return found;
}
public:
void TestConditionsEmpty()
{
BMessage message;
CPPUNIT_ASSERT_EQUAL(B_OK, _ParseCondition("if {\n"
"}\n", message));
CPPUNIT_ASSERT(message.IsEmpty());
}
void TestConditionsMultiLine()
{
BMessage message;
CPPUNIT_ASSERT_EQUAL(B_OK, _ParseCondition("if {\n"
"\tsafemode\n"
"\tfile_exists one\n"
"}\n", message));
CPPUNIT_ASSERT_EQUAL(2, (int)message.CountNames(B_ANY_TYPE));
BMessage subMessage;
CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("safemode", &subMessage));
CPPUNIT_ASSERT(subMessage.IsEmpty());
CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("file_exists",
&subMessage));
CPPUNIT_ASSERT_EQUAL(BString("one"),
BString(subMessage.GetString("args", 0, "-")));
CPPUNIT_ASSERT_EQUAL(1, (int)subMessage.CountNames(B_ANY_TYPE));
}
void TestConditionsFlat()
{
BMessage message;
CPPUNIT_ASSERT_EQUAL(B_OK, _ParseCondition("if safemode\n", message));
CPPUNIT_ASSERT_EQUAL(1, (int)message.CountNames(B_ANY_TYPE));
BMessage args;
CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("safemode", &args));
CPPUNIT_ASSERT(args.IsEmpty());
}
void TestConditionsFlatWithNot()
{
BMessage message;
CPPUNIT_ASSERT_EQUAL(B_OK, _ParseCondition("if not safemode\n", message));
CPPUNIT_ASSERT_EQUAL(1, (int)message.CountNames(B_ANY_TYPE));
BMessage subMessage;
CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("not",
&subMessage));
BMessage args;
CPPUNIT_ASSERT_EQUAL(B_OK, subMessage.FindMessage("safemode", &args));
CPPUNIT_ASSERT(args.IsEmpty());
}
void TestConditionsFlatWithArgs()
{
BMessage message;
CPPUNIT_ASSERT_EQUAL(B_OK,
_ParseCondition("if file_exists one\n", message));
CPPUNIT_ASSERT_EQUAL(1, (int)message.CountNames(B_ANY_TYPE));
BMessage args;
CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("file_exists", &args));
CPPUNIT_ASSERT_EQUAL(BString("one"),
BString(args.GetString("args", 0, "-")));
CPPUNIT_ASSERT_EQUAL(1, (int)args.CountNames(B_ANY_TYPE));
}
void TestConditionsFlatWithNotAndArgs()
{
BMessage message;
CPPUNIT_ASSERT_EQUAL(B_OK,
_ParseCondition("if not file_exists one\n", message));
CPPUNIT_ASSERT_EQUAL(1, (int)message.CountNames(B_ANY_TYPE));
BMessage subMessage;
CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("not",
&subMessage));
BMessage args;
CPPUNIT_ASSERT_EQUAL(B_OK, subMessage.FindMessage("file_exists", &args));
CPPUNIT_ASSERT_EQUAL(BString("one"),
BString(args.GetString("args", 0, "-")));
CPPUNIT_ASSERT_EQUAL(1, (int)args.CountNames(B_ANY_TYPE));
}
void TestConditionsMultiLineFlatNot()
{
BMessage message;
CPPUNIT_ASSERT_EQUAL(B_OK, _ParseCondition("if {\n"
"\tnot safemode\n"
"}\n", message));
BMessage subMessage;
CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("not",
&subMessage));
CPPUNIT_ASSERT_EQUAL(1, (int)message.CountNames(B_ANY_TYPE));
BMessage args;
CPPUNIT_ASSERT_EQUAL(B_OK, subMessage.FindMessage("safemode", &args));
CPPUNIT_ASSERT_EQUAL(1, (int)subMessage.CountNames(B_ANY_TYPE));
CPPUNIT_ASSERT(args.IsEmpty());
}
void TestConditionsMultiLineFlatNotWithArgs()
{
BMessage message;
CPPUNIT_ASSERT_EQUAL(B_OK, _ParseCondition("if {\n"
"\tnot file_exists one two\n"
"}\n", message));
BMessage subMessage;
CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("not",
&subMessage));
BMessage args;
CPPUNIT_ASSERT_EQUAL(B_OK, subMessage.FindMessage("file_exists", &args));
CPPUNIT_ASSERT_EQUAL(BString("one"),
BString(args.GetString("args", 0, "-")));
CPPUNIT_ASSERT_EQUAL(BString("two"),
BString(args.GetString("args", 1, "-")));
CPPUNIT_ASSERT_EQUAL(1, (int)args.CountNames(B_ANY_TYPE));
CPPUNIT_ASSERT_EQUAL(2, (int)_ArrayCount(args, "args"));
}
void TestConditionsMultiLineNot()
{
BMessage message;
CPPUNIT_ASSERT_EQUAL(B_OK, _ParseCondition("if {\n"
"\tnot {\n"
"\t\tsafemode\n"
"\t}\n"
"}\n", message));
BMessage subMessage;
CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("not", &subMessage));
BMessage args;
CPPUNIT_ASSERT_EQUAL(B_OK, subMessage.FindMessage("safemode", &args));
CPPUNIT_ASSERT(args.IsEmpty());
}
void TestEventsEmpty()
{
BMessage message;
CPPUNIT_ASSERT_EQUAL(B_OK, _ParseEvent("on {\n"
"}\n", message));
CPPUNIT_ASSERT(message.IsEmpty());
}
void TestEventsMultiLine()
{
BMessage message;
CPPUNIT_ASSERT_EQUAL(B_OK, _ParseEvent("on {\n"
"\tfile_created one\n"
"\tdemand\n"
"}\n", message));
CPPUNIT_ASSERT_EQUAL(2, (int)message.CountNames(B_ANY_TYPE));
BMessage subMessage;
CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("demand", &subMessage));
CPPUNIT_ASSERT(subMessage.IsEmpty());
CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("file_created",
&subMessage));
CPPUNIT_ASSERT_EQUAL(BString("one"),
BString(subMessage.GetString("args", 0, "-")));
CPPUNIT_ASSERT_EQUAL(1, (int)subMessage.CountNames(B_ANY_TYPE));
}
void TestEventsFlat()
{
BMessage message;
CPPUNIT_ASSERT_EQUAL(B_OK, _ParseEvent("on demand\n", message));
CPPUNIT_ASSERT_EQUAL(1, (int)message.CountNames(B_ANY_TYPE));
BMessage args;
CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("demand", &args));
CPPUNIT_ASSERT(args.IsEmpty());
}
void TestEventsFlatWithArgs()
{
BMessage message;
CPPUNIT_ASSERT_EQUAL(B_OK, _ParseEvent("on file_created one\n", message));
CPPUNIT_ASSERT_EQUAL(1, (int)message.CountNames(B_ANY_TYPE));
BMessage args;
CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("file_created", &args));
CPPUNIT_ASSERT_EQUAL(BString("one"),
BString(args.GetString("args", 0, "-")));
CPPUNIT_ASSERT_EQUAL(1, (int)args.CountNames(B_ANY_TYPE));
}
void TestEnvironmentMultiLine()
{
BMessage message;
CPPUNIT_ASSERT_EQUAL(B_OK, _ParseName("env", "env {\n"
"from_script SetupEnvironment\n"
"TEST well, yes\n"
"}\n", message));
CPPUNIT_ASSERT_EQUAL(2, (int)message.CountNames(B_ANY_TYPE));
CPPUNIT_ASSERT_EQUAL(BString("SetupEnvironment"),
BString(message.GetString("from_script", "-")));
CPPUNIT_ASSERT_EQUAL(1, (int)_ArrayCount(message, "from_script"));
CPPUNIT_ASSERT_EQUAL(BString("well,"),
BString(message.GetString("TEST", 0, "-")));
CPPUNIT_ASSERT_EQUAL(BString("yes"),
BString(message.GetString("TEST", 1, "-")));
CPPUNIT_ASSERT_EQUAL(2, (int)_ArrayCount(message, "TEST"));
}
void TestEnvironmentFlat()
{
BMessage message;
CPPUNIT_ASSERT_EQUAL(B_OK, _ParseName("env", "env SetupEnvironment\n",
message));
CPPUNIT_ASSERT_EQUAL(1, (int)message.CountNames(B_ANY_TYPE));
CPPUNIT_ASSERT_EQUAL(BString("SetupEnvironment"),
BString(message.GetString("from_script", "-")));
CPPUNIT_ASSERT_EQUAL(1, (int)_ArrayCount(message, "from_script"));
}
void TestRunFlat()
{
SettingsParser parser;
BMessage jobs;
CPPUNIT_ASSERT_EQUAL(B_OK, parser.Parse("run me", jobs));
CPPUNIT_ASSERT_EQUAL(1, (int)jobs.CountNames(B_ANY_TYPE));
BMessage message;
CPPUNIT_ASSERT_EQUAL(B_OK, jobs.FindMessage("run", &message));
CPPUNIT_ASSERT_EQUAL(BString("me"),
BString(message.GetString("target", "-")));
CPPUNIT_ASSERT_EQUAL(1, (int)_ArrayCount(message, "target"));
CPPUNIT_ASSERT_EQUAL(1, (int)message.CountNames(B_ANY_TYPE));
}
void TestRunMultiLine()
{
SettingsParser parser;
BMessage jobs;
status_t status = parser.Parse("run {\n"
"\tme\n"
"\tyou\n"
"}\n", jobs);
CPPUNIT_ASSERT_EQUAL(B_OK, status);
CPPUNIT_ASSERT_EQUAL(1, (int)jobs.CountNames(B_ANY_TYPE));
BMessage message;
CPPUNIT_ASSERT_EQUAL(B_OK, jobs.FindMessage("run", &message));
CPPUNIT_ASSERT_EQUAL(BString("me"),
BString(message.GetString("target", 0, "-")));
CPPUNIT_ASSERT_EQUAL(BString("you"),
BString(message.GetString("target", 1, "-")));
CPPUNIT_ASSERT_EQUAL(2, (int)_ArrayCount(message, "target"));
CPPUNIT_ASSERT_EQUAL(1, (int)message.CountNames(B_ANY_TYPE));
}
void TestRunIfThenElseFlat()
{
SettingsParser parser;
BMessage jobs;
status_t status = parser.Parse("run {\n"
"\tif safemode\n"
"\tthen this\n"
"\telse that\n"
"}\n", jobs);
CPPUNIT_ASSERT_EQUAL(B_OK, status);
BMessage message;
CPPUNIT_ASSERT_EQUAL(B_OK, jobs.FindMessage("run", &message));
CPPUNIT_ASSERT_EQUAL(3, (int)message.CountNames(B_ANY_TYPE));
BMessage then;
CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("then", &then));
CPPUNIT_ASSERT_EQUAL(BString("this"),
BString(then.GetString("target", "-")));
CPPUNIT_ASSERT_EQUAL(1, (int)_ArrayCount(then, "target"));
CPPUNIT_ASSERT_EQUAL(1, (int)then.CountNames(B_ANY_TYPE));
BMessage otherwise;
CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("else", &otherwise));
CPPUNIT_ASSERT_EQUAL(BString("that"),
BString(otherwise.GetString("target", "-")));
CPPUNIT_ASSERT_EQUAL(1, (int)_ArrayCount(otherwise, "target"));
CPPUNIT_ASSERT_EQUAL(1, (int)otherwise.CountNames(B_ANY_TYPE));
}
void TestRunIfThenElseMultiLine()
{
SettingsParser parser;
BMessage jobs;
status_t status = parser.Parse("run {\n"
"\tif {\n"
"\t\tread_only\n"
"\t}\n"
"\tthen {\n"
"\t\tthis\n"
"\t}\n"
"\telse {\n"
"\t\tthat\n"
"\t}\n"
"}\n", jobs);
CPPUNIT_ASSERT_EQUAL(B_OK, status);
BMessage message;
CPPUNIT_ASSERT_EQUAL(B_OK, jobs.FindMessage("run", &message));
CPPUNIT_ASSERT_EQUAL(3, (int)message.CountNames(B_ANY_TYPE));
BMessage then;
CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("then", &then));
CPPUNIT_ASSERT_EQUAL(BString("this"),
BString(then.GetString("target", "-")));
CPPUNIT_ASSERT_EQUAL(1, (int)_ArrayCount(then, "target"));
CPPUNIT_ASSERT_EQUAL(1, (int)then.CountNames(B_ANY_TYPE));
BMessage otherwise;
CPPUNIT_ASSERT_EQUAL(B_OK, message.FindMessage("else", &otherwise));
CPPUNIT_ASSERT_EQUAL(BString("that"),
BString(otherwise.GetString("target", "-")));
CPPUNIT_ASSERT_EQUAL(1, (int)_ArrayCount(otherwise, "target"));
CPPUNIT_ASSERT_EQUAL(1, (int)otherwise.CountNames(B_ANY_TYPE));
}
};
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(SettingsParserTest, getTestSuiteName());