Skip to content

Commit

Permalink
handling VALUE and DEFAULT for sequences
Browse files Browse the repository at this point in the history
  • Loading branch information
joanvallve committed Jul 25, 2024
1 parent 7071529 commit f6d59d1
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 42 deletions.
160 changes: 128 additions & 32 deletions src/yaml_schema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,32 +154,79 @@ void checkSchema(const YAML::Node& node_schema,
// OPTIONAL 'value'
if (node_schema[VALUE])
{
// CHECK TYPE (take BASE if "derived")
// trivial type
if (isTrivialType(type))
// schema is a sequence type
if (isSequenceSchema(node_schema))
{
if (not tryNodeAs(node_schema[VALUE], type))
// check value is sequence as well
if (not node_schema[VALUE].IsSequence())
{
throw std::runtime_error("YAML schema: " + node_field + ", " + VALUE + " of wrong type");
throw std::runtime_error("YAML schema: " + node_field + ", " + VALUE + " should be a sequence");
}
}
// type with schema
else if (isNonTrivialType(type, folders_schema))
{
std::stringstream log;
YAML::Node node_schema_value = node_schema[VALUE];
if (not applySchema(node_schema_value, type, folders_schema, log, ""))

// check type for each node
for (auto n_i = 0; n_i < node_schema[VALUE].size(); n_i++)
{
throw std::runtime_error("YAML schema: " + node_field + ", " + VALUE +
" value did not pass the schema check with error: " + log.str());
// CHECK TYPE (taking BASE if "derived")
// trivial type
if (isTrivialType(type))
{
if (not tryNodeAs(node_schema[VALUE][n_i], type))
{
throw std::runtime_error("YAML schema: " + node_field + ", " + VALUE + "[" +
std::to_string(n_i) + "] of wrong type");
}
}
// type with schema
else if (isNonTrivialType(type, folders_schema))
{
std::stringstream log;
YAML::Node node_schema_value = node_schema[VALUE][n_i];

if (not applySchema(node_schema_value, type, folders_schema, log, ""))
{
throw std::runtime_error("YAML schema: " + node_field + ", " + VALUE + "[" +
std::to_string(n_i) +
"] did not pass the schema check with error: " + log.str());
}
}
else
{
throw std::runtime_error("YAML schema: " + node_field + ", " + VALUE + " value unknown type.");
}
}
}
// schema is a scalar type
else
{
throw std::runtime_error("YAML schema: " + node_field + ", " + VALUE + " value unknown type.");
// CHECK TYPE (taking BASE if "derived")
// trivial type
if (isTrivialType(type))
{
if (not tryNodeAs(node_schema[VALUE], type))
{
throw std::runtime_error("YAML schema: " + node_field + ", " + VALUE + " of wrong type");
}
}
// type with schema
else if (isNonTrivialType(type, folders_schema))
{
std::stringstream log;
YAML::Node node_schema_value = node_schema[VALUE];

if (not applySchema(node_schema_value, type, folders_schema, log, ""))
{
throw std::runtime_error("YAML schema: " + node_field + ", " + VALUE +
" did not pass the schema check with error: " + log.str());
}
}
else
{
throw std::runtime_error("YAML schema: " + node_field + ", " + VALUE + " value unknown type.");
}
}

// if 'value', 'mandatory' should be false (no sense requiring user to define something already defined)
// if 'value', 'mandatory' should be false (no sense requiring user to define something already
// defined)
if (isExpression(node_schema[MANDATORY]) or node_schema[MANDATORY].as<bool>())
{
throw std::runtime_error("YAML schema: " + node_field + ", if " + VALUE + " defined, " + MANDATORY +
Expand All @@ -196,29 +243,77 @@ void checkSchema(const YAML::Node& node_schema,
" value cannot be defined in mandatory field");
}

// CHECK TYPE (take BASE if "derived")
// trivial type
if (isTrivialType(type))
// schema is a sequence type
if (isSequenceSchema(node_schema))
{
if (not tryNodeAs(node_schema[DEFAULT], type))
// check value is sequence as well
if (not node_schema[DEFAULT].IsSequence())
{
throw std::runtime_error("YAML schema: " + node_field + ", " + DEFAULT + " value wrong type");
throw std::runtime_error("YAML schema: " + node_field + ", " + DEFAULT + " should be a sequence");
}
}
// type with schema
else if (isNonTrivialType(type, folders_schema))
{
std::stringstream log;
YAML::Node node_schema_default = node_schema[DEFAULT];
if (not applySchema(node_schema_default, type, folders_schema, log, ""))

// check type for each node
for (auto n_i = 0; n_i < node_schema[DEFAULT].size(); n_i++)
{
throw std::runtime_error("YAML schema: " + node_field + ", " + DEFAULT +
" value did not pass the schema check with error: " + log.str());
// CHECK TYPE (take BASE if "derived")
// trivial type
if (isTrivialType(type))
{
if (not tryNodeAs(node_schema[DEFAULT][n_i], type))
{
throw std::runtime_error("YAML schema: " + node_field + ", " + DEFAULT + "[" +
std::to_string(n_i) + "] wrong type");
}
}
// type with schema
else if (isNonTrivialType(type, folders_schema))
{
std::stringstream log;
YAML::Node node_schema_default = node_schema[DEFAULT][n_i];
// type
if (not applySchema(
node_schema_default, type, folders_schema, log, ""))
{
throw std::runtime_error("YAML schema: " + node_field + ", " + DEFAULT + "[" +
std::to_string(n_i) +
"] did not pass the schema check with error: " + log.str());
}
}
else
{
throw std::runtime_error("YAML schema: " + node_field + ", " + DEFAULT + "[" +
std::to_string(n_i) + "] unknown type.");
}
}
}
// schema is a scalar type
else
{
throw std::runtime_error("YAML schema: " + node_field + ", " + DEFAULT + " value unknown type.");
// CHECK TYPE (take BASE if "derived")
// trivial type
if (isTrivialType(type))
{
if (not tryNodeAs(node_schema[DEFAULT], type))
{
throw std::runtime_error("YAML schema: " + node_field + ", " + DEFAULT + " value wrong type");
}
}
// type with schema
else if (isNonTrivialType(type, folders_schema))
{
std::stringstream log;
YAML::Node node_schema_default = node_schema[DEFAULT];
if (not applySchema(
node_schema_default, type, folders_schema, log, ""))
{
throw std::runtime_error("YAML schema: " + node_field + ", " + DEFAULT +
" value did not pass the schema check with error: " + log.str());
}
}
else
{
throw std::runtime_error("YAML schema: " + node_field + ", " + DEFAULT + " value unknown type.");
}
}
}
// OPTIONAL sequence 'options'
Expand Down Expand Up @@ -352,7 +447,8 @@ bool validateAllSchemas(const std::vector<std::string>& folders_schema, bool ver
continue;
}

// Flatten yaml nodes (containing "follow") to a single YAML node containing all the information
// Flatten yaml nodes (containing "follow") to a single YAML node containing all the
// information
try
{
flattenNode(node_schema, entry.path().parent_path().string(), folders_schema, true, override);
Expand Down
18 changes: 9 additions & 9 deletions test/gtest_schema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ TEST(schema, plain_yaml)
std::stringstream log;
auto node_schema = loadSchema(
"test1.schema", {ROOT_DIR + "/test/schema/folder_schema", ROOT_DIR + "/test/schema/other_folder_schema"}, log);
ASSERT_TRUE(node_schema.IsDefined());
EXPECT_TRUE(node_schema.IsDefined());
std::cout << log.str() << std::endl;
}

Expand All @@ -20,7 +20,7 @@ TEST(schema, follow)
std::stringstream log;
auto node_schema = loadSchema(
"test2.schema", {ROOT_DIR + "/test/schema/folder_schema", ROOT_DIR + "/test/schema/other_folder_schema"}, log);
ASSERT_TRUE(node_schema.IsDefined());
EXPECT_TRUE(node_schema.IsDefined());
std::cout << log.str() << std::endl;
}

Expand All @@ -30,7 +30,7 @@ TEST(schema, empty)
auto node_schema = loadSchema(
"empty.schema", {ROOT_DIR + "/test/schema/folder_schema", ROOT_DIR + "/test/schema/other_folder_schema"}, log);

ASSERT_TRUE(node_schema.IsDefined());
EXPECT_TRUE(node_schema.IsDefined());
std::cout << log.str() << std::endl;
}

Expand All @@ -41,7 +41,7 @@ TEST(schema, nontrivial_options_default_value)
loadSchema("nontrivial_options_default_value.schema",
{ROOT_DIR + "/test/schema/folder_schema", ROOT_DIR + "/test/schema/other_folder_schema"},
log);
ASSERT_TRUE(node_schema.IsDefined());
EXPECT_TRUE(node_schema.IsDefined());
std::cout << "node_schema: \n" << node_schema << std::endl;
std::cout << log.str() << std::endl;
}
Expand Down Expand Up @@ -69,7 +69,7 @@ TEST(schema, wrong)
std::stringstream log;
std::cout << "Checking " << w_schema << ".schema..." << std::endl;
auto node_schema = loadSchema(w_schema + ".schema", {ROOT_DIR + "/test/wrong_schema"}, log);
ASSERT_FALSE(node_schema.IsDefined());
EXPECT_FALSE(node_schema.IsDefined());
std::cout << log.str() << std::endl;
}
}
Expand All @@ -83,7 +83,7 @@ TEST(schema, override)
std::stringstream log;
std::cout << "Checking " << w_schema << ".schema..." << std::endl;
auto node_schema = loadSchema(w_schema + ".schema", {ROOT_DIR + "/test/schema"}, log);
ASSERT_TRUE(node_schema.IsDefined());
EXPECT_TRUE(node_schema.IsDefined());
std::cout << log.str() << std::endl;
}
}
Expand All @@ -97,15 +97,15 @@ TEST(schema, dont_override)
std::stringstream log;
std::cout << "Checking " << w_schema << ".schema..." << std::endl;
auto node_schema = loadSchema(w_schema + ".schema", {ROOT_DIR + "/test/schema"}, log);
ASSERT_TRUE(node_schema.IsDefined());
EXPECT_TRUE(node_schema.IsDefined());
std::cout << log.str() << std::endl;
}
}

TEST(schema, validate_all_schemas)
{
ASSERT_TRUE(validateAllSchemas({ROOT_DIR + "/test/schema"}, true));
ASSERT_FALSE(validateAllSchemas({ROOT_DIR + "/test/wrong_schema"}, true));
EXPECT_TRUE(validateAllSchemas({ROOT_DIR + "/test/schema"}, true));
EXPECT_FALSE(validateAllSchemas({ROOT_DIR + "/test/wrong_schema"}, true));
}

int main(int argc, char **argv)
Expand Down
12 changes: 11 additions & 1 deletion test/schema/folder_schema/base_input_derived.schema
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,14 @@ param2:
_options:
- "string"
- "strong"
- "streng"
- "streng"
param10:
_mandatory: false
_type: int[]
_default: []
_doc: "seq of ints"
param12:
_mandatory: false
_type: int[]
_value: []
_doc: "seq of ints"

0 comments on commit f6d59d1

Please sign in to comment.