summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/common/Argument.cpp27
-rw-r--r--test/core/common/ArgumentTest.cpp146
2 files changed, 164 insertions, 9 deletions
diff --git a/src/core/common/Argument.cpp b/src/core/common/Argument.cpp
index 4e80f23..8face55 100644
--- a/src/core/common/Argument.cpp
+++ b/src/core/common/Argument.cpp
@@ -192,12 +192,12 @@ static std::unordered_map<std::string, size_t> buildArgumentNames(
for (const Argument &arg : arguments) {
if (!Utils::isIdentifier(arg.name)) {
throw OusiaException{std::string("Argument name ") + arg.name +
- std::string(" is not a valid identifier!")};
+ std::string(" is not a valid identifier")};
}
if (!res.emplace(arg.name, i++).second) {
throw OusiaException{
std::string("Argument names must be unique (") + arg.name +
- std::string(")!")};
+ std::string(")")};
}
}
return res;
@@ -210,6 +210,8 @@ Arguments::Arguments(std::initializer_list<Argument> arguments)
bool Arguments::validateArray(Variant::arrayType &arr, Logger &logger)
{
+ Logger nullLogger;
+
// Fetch the number of arguments N and the initial array size n
const size_t n = arr.size();
const size_t N = arguments.size();
@@ -235,9 +237,11 @@ bool Arguments::validateArray(Variant::arrayType &arr, Logger &logger)
if (arguments[a].hasDefault) {
arr[a] = arguments[a].defaultValue;
} else {
+ // Call "validate" to inject a standard value
+ arguments[a].validate(arr[a], nullLogger);
logger.error(std::string("Missing argument ") +
- std::to_string(a + 1) + std::string("(") +
- arguments[a].name + std::string(")!"));
+ std::to_string(a + 1) + std::string(" \"") +
+ arguments[a].name + std::string("\""));
ok = false;
}
}
@@ -249,6 +253,8 @@ bool Arguments::validateArray(Variant::arrayType &arr, Logger &logger)
bool Arguments::validateMap(Variant::mapType &map, Logger &logger,
bool ignoreUnknown)
{
+ Logger nullLogger;
+
// Fetch the number of arguments N
const size_t N = arguments.size();
std::vector<bool> set(N);
@@ -265,10 +271,10 @@ bool Arguments::validateMap(Variant::mapType &map, Logger &logger,
ok = ok && set[idx];
} else {
if (ignoreUnknown) {
- logger.note(std::string("Ignoring argument ") + e.first);
+ logger.note(std::string("Ignoring argument \"") + e.first + std::string("\""));
} else {
- logger.error(std::string("Unknown argument ") + e.first +
- std::string("!"));
+ logger.error(std::string("Unknown argument \"") + e.first +
+ std::string("\""));
ok = false;
}
}
@@ -280,8 +286,11 @@ bool Arguments::validateMap(Variant::mapType &map, Logger &logger,
if (arguments[a].hasDefault) {
map[arguments[a].name] = arguments[a].defaultValue;
} else {
- logger.error(std::string("Missing argument ") +
- arguments[a].name);
+ // Call "validate" to inject a standard value
+ map[arguments[a].name] = Variant{};
+ arguments[a].validate(map[arguments[a].name], nullLogger);
+ logger.error(std::string("Missing argument \"") +
+ arguments[a].name + std::string("\""));
ok = false;
}
}
diff --git a/test/core/common/ArgumentTest.cpp b/test/core/common/ArgumentTest.cpp
index f3f8f2b..d58f71b 100644
--- a/test/core/common/ArgumentTest.cpp
+++ b/test/core/common/ArgumentTest.cpp
@@ -52,6 +52,63 @@ static const Rtti<ousia::TestManaged2> TestManaged2 =
RttiBuilder("TestManaged2").parent(&TestManaged1);
}
+TEST(Argument, validateAny)
+{
+ Argument a = Argument::Any("a");
+
+ ASSERT_FALSE(a.hasDefault);
+
+ {
+ Variant v{true};
+ ASSERT_TRUE(a.validate(v, logger));
+ ASSERT_TRUE(v.isBool());
+ ASSERT_TRUE(v.asBool());
+ }
+
+ {
+ Variant v{"test"};
+ ASSERT_TRUE(a.validate(v, logger));
+ ASSERT_TRUE(v.isString());
+ ASSERT_EQ("test", v.asString());
+ }
+
+ {
+ Variant v{{1, 2, 3, 4}};
+ ASSERT_TRUE(a.validate(v, logger));
+ ASSERT_TRUE(v.isArray());
+ ASSERT_EQ(Variant::arrayType({1, 2, 3, 4}), v.asArray());
+ }
+}
+
+TEST(Argument, validateAnyDefault)
+{
+ Argument a = Argument::Any("a", true);
+
+ ASSERT_TRUE(a.hasDefault);
+ ASSERT_TRUE(a.defaultValue.asBool());
+
+ {
+ Variant v{true};
+ ASSERT_TRUE(a.validate(v, logger));
+ ASSERT_TRUE(v.isBool());
+ ASSERT_TRUE(v.asBool());
+ }
+
+ {
+ Variant v{"test"};
+ ASSERT_TRUE(a.validate(v, logger));
+ ASSERT_TRUE(v.isString());
+ ASSERT_EQ("test", v.asString());
+ }
+
+ {
+ Variant v{{1, 2, 3, 4}};
+ ASSERT_TRUE(a.validate(v, logger));
+ ASSERT_TRUE(v.isArray());
+ ASSERT_EQ(Variant::arrayType({1, 2, 3, 4}), v.asArray());
+ }
+}
+
TEST(Argument, validateBool)
{
Argument a = Argument::Bool("a");
@@ -716,5 +773,94 @@ TEST(Argument, validateMapInnerTypeDefault)
ASSERT_EQ(mapDefault, v.asMap());
}
}
+
+TEST(Arguments, construction)
+{
+ // This should work without exception
+ Arguments{Argument::Int("a"), Argument::Any("b")};
+
+ // This should throw an exception
+ ASSERT_THROW(Arguments({Argument::Int("a"), Argument::Any("a")}),
+ OusiaException);
+ ASSERT_THROW(Arguments({Argument::Int("test test")}), OusiaException);
+}
+
+TEST(Arguments, validateArray)
+{
+ Arguments args{Argument::Int("a"), Argument::String("b", "test"),
+ Argument::Bool("c", true)};
+
+ {
+ Variant::arrayType arr{1, 5, false};
+ ASSERT_TRUE(args.validateArray(arr, logger));
+ ASSERT_EQ(Variant::arrayType({1, "5", false}), arr);
+ }
+
+ {
+ Variant::arrayType arr{1, 5};
+ ASSERT_TRUE(args.validateArray(arr, logger));
+ ASSERT_EQ(Variant::arrayType({1, "5", true}), arr);
+ }
+
+ {
+ Variant::arrayType arr{1};
+ ASSERT_TRUE(args.validateArray(arr, logger));
+ ASSERT_EQ(Variant::arrayType({1, "test", true}), arr);
+ }
+
+ {
+ Variant::arrayType arr{};
+ ASSERT_FALSE(args.validateArray(arr, logger));
+ ASSERT_EQ(Variant::arrayType({0, "test", true}), arr);
+ }
+
+ {
+ Variant::arrayType arr{1, "bla", false, 42};
+ ASSERT_FALSE(args.validateArray(arr, logger));
+ ASSERT_EQ(Variant::arrayType({1, "bla", false}), arr);
+ }
+}
+
+TEST(Arguments, validateMap)
+{
+ Arguments args{Argument::Int("a"), Argument::String("b", "test"),
+ Argument::Bool("c", true)};
+
+ {
+ Variant::mapType map{{"a", 2}, {"b", 5}, {"c", true}};
+ ASSERT_TRUE(args.validateMap(map, logger, false));
+ ASSERT_EQ(Variant::mapType({{"a", 2}, {"b", "5"}, {"c", true}}), map);
+ }
+
+ {
+ Variant::mapType map{{"a", 2}, {"c", false}};
+ ASSERT_TRUE(args.validateMap(map, logger, false));
+ ASSERT_EQ(Variant::mapType({{"a", 2}, {"b", "test"}, {"c", false}}), map);
+ }
+
+ {
+ Variant::mapType map{{"a", 2}};
+ ASSERT_TRUE(args.validateMap(map, logger, false));
+ ASSERT_EQ(Variant::mapType({{"a", 2}, {"b", "test"}, {"c", true}}), map);
+ }
+
+ {
+ Variant::mapType map{};
+ ASSERT_FALSE(args.validateMap(map, logger, false));
+ ASSERT_EQ(Variant::mapType({{"a", 0}, {"b", "test"}, {"c", true}}), map);
+ }
+
+ {
+ Variant::mapType map{{"a", 2}, {"d", nullptr}};
+ ASSERT_FALSE(args.validateMap(map, logger, false));
+ ASSERT_EQ(Variant::mapType({{"a", 2}, {"b", "test"}, {"c", true}, {"d", nullptr}}), map);
+ }
+
+ {
+ Variant::mapType map{{"a", 2}, {"d", nullptr}};
+ ASSERT_TRUE(args.validateMap(map, logger, true));
+ ASSERT_EQ(Variant::mapType({{"a", 2}, {"b", "test"}, {"c", true}, {"d", nullptr}}), map);
+ }
+}
}