Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions src/coreComponents/codingUtilities/RTTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ rtTypes::RegexMapType rtTypes::createBasicTypesRegexMap()
// string_view const ru = "[\\d]+";// unused

string_view const intDesc = "Input value must be a signed int (eg. -123, 455, +789, etc.)";
string_view const intRegex = "[+-]?[\\d]+";
string_view const intRegex = "\\s*[+-]?[\\d]+\\s*";

// Explanation of parts:
// [+-]?[\\d]* matches an optional +/- at the beginning, any numbers preceding the decimal
Expand All @@ -160,28 +160,31 @@ rtTypes::RegexMapType rtTypes::createBasicTypesRegexMap()
// ([eE][-+]?[\\d]+|\\s*) matches an optional scientific notation number
// Note: the xsd regex implementation does not allow an empty branch, so use allow whitespace at the end
string_view const realDesc = "Input value must be a real number (eg. 1, .25, +2.3, -.4, 5.6e7, -8E-9, etc.)";
string_view const realRegex = "[+-]?[\\d]*([\\d]\\.?|\\.[\\d])[\\d]*([eE][-+]?[\\d]+|\\s*)";
string_view const realRegex = "\\s*[+-]?[\\d]*([\\d]\\.?|\\.[\\d])[\\d]*([eE][-+]?[\\d]+|\\s*)";

string_view const R1Desc = "Input value must be a R1Tensor, an array of 3 real numbers surrounded by braces and separated by commas (eg. \"{ 1, .25, +2.3}\", \"{ -.4, 5.6e7, -8E-9\", etc.) .";
string const R1Regex = "\\s*\\{\\s*(" + string( realRegex ) + "\\s*,\\s*){2}" + string( realRegex ) + "\\s*\\}\\s*";
string_view const R2Desc = "Input value must be a R2SymTensor, an array of 6 real numbers surrounded by braces and separated by commas (eg. \"{ 1, .25, +2.3, -.4, 5.6e7, -8E-9\", etc.) .";
string const R2Regex = "\\s*\\{\\s*(" + string( realRegex ) + "\\s*,\\s*){5}" + string( realRegex ) + "\\s*\\}\\s*";

string_view const strDesc = "Input value must be a string that cannot be empty, contain any whitespaces nor the characters , { }";
string_view const strRegex = "[^,\\{\\}\\s]+\\s*";
string_view const strRegex = "\\s*[^,\\{\\}\\s]+\\s*";
string_view const strEDesc = "Input value must be a string that cannot contain any whitespaces nor the characters , { }";
string_view const strERegex = "[^,\\{\\}\\s]*\\s*";
string_view const strERegex = "\\s*[^,\\{\\}\\s]*\\s*";

string_view const pathDesc = "Input value must be a string that cannot be empty, contain any whitespaces nor the characters * ? < > | : \" ";
string_view const pathRegex = "[^*?<>\\|:\";,\\s]+\\s*";
string_view const pathRegex = "\\s*[^*?<>\\|:\";,\\s]+\\s*";
string_view const pathEDesc = "Input value must be a string that cannot contain any whitespaces nor the characters * ? < > | : \" ";
string_view const pathERegex = "[^*?<>\\|:\";,\\s]*\\s*";
string_view const pathERegex = "\\s*[^*?<>\\|:\";,\\s]*\\s*";

string_view const groupNameDesc = "Input value must be a string that cannot be empty and contains only upper/lower letters, digits, and the characters . - _";
string_view const groupNameRegex = "[a-zA-Z0-9.\\-_]+";
string_view const groupNameRegex = "\\s*[a-zA-Z0-9.\\-_]+\\s*";
// to reference groups, we need to support the / for paths, and * [ ] for fnmatch patterns.
string_view const groupNameRefDesc = "Input value must be a string that can contain only upper/lower letters, digits, and the characters . - _ / * [ ]";
string_view const groupNameRefRegex = "[a-zA-Z0-9.\\-_/*\\[\\]]*";
string_view const groupNameRefRegex = "\\s*[a-zA-Z0-9.\\-_/*\\[\\]]*\\s*";
// to reference an array of groups, we need to support the / for paths, and * [ ] for fnmatch patterns.
string_view const groupNameRefArrayDesc = "Input value must be a list of strings that can contain only upper/lower letters, digits, and the characters . - _ / * [ ]";
string_view const groupNameRefArrayRegex = "\\s*\\{([a-zA-Z0-9.\\-_/*\\[\\], ]+)*\\}\\s*";


// Build master list of regexes
Expand Down Expand Up @@ -220,7 +223,7 @@ rtTypes::RegexMapType rtTypes::createBasicTypesRegexMap()
{ string( CustomTypes::plotLevel ), Regex( intRegex, intDesc ) },
{ string( CustomTypes::groupName ), Regex( groupNameRegex, groupNameDesc ) },
{ string( CustomTypes::groupNameRef ), Regex( groupNameRefRegex, groupNameRefDesc ) },
{ string( CustomTypes::groupNameRefArray ), constructArrayRegex( groupNameRefRegex, groupNameRefDesc, 1 ) }
{ string( CustomTypes::groupNameRefArray ), Regex( groupNameRefArrayRegex, groupNameRefArrayDesc ) }
};
return regexMap;
}
Expand Down
105 changes: 98 additions & 7 deletions src/coreComponents/dataRepository/unitTests/testXmlWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,9 @@ INSTANTIATE_TEST_SUITE_P(
real64AttributeTests,
real64AttributeTestFixture,
::testing::Values( std::make_tuple( "1", 1, false ),
std::make_tuple( "1 ", 1, false ),
std::make_tuple( " 1", 1, false ),
std::make_tuple( " 1 ", 1, false ),
std::make_tuple( "-23", -23, false ),
std::make_tuple( "4.5", 4.5, false ),
std::make_tuple( "4.", 4.0, false ),
Expand All @@ -260,7 +263,6 @@ INSTANTIATE_TEST_SUITE_P(
std::make_tuple( "1.234gamma", 0, true ),
std::make_tuple( "1.2.3", 0, true ),
std::make_tuple( "1e2.3 ", 0, true ),
std::make_tuple( "1 ", 0, true ),
std::make_tuple( "1e", 0, true ),
std::make_tuple( "1e-", 0, true ),
std::make_tuple( "1e+", 0, true )));
Expand All @@ -284,6 +286,9 @@ INSTANTIATE_TEST_SUITE_P(
real32AttributeTests,
real32AttributeTestFixture,
::testing::Values( std::make_tuple( "1", 1, false ),
std::make_tuple( "1 ", 1, false ),
std::make_tuple( " 1", 1, false ),
std::make_tuple( " 1 ", 1, false ),
std::make_tuple( "-23", -23, false ),
std::make_tuple( "4.5", 4.5, false ),
std::make_tuple( "4.", 4.0, false ),
Expand All @@ -301,7 +306,6 @@ INSTANTIATE_TEST_SUITE_P(
std::make_tuple( "1.234gamma", 0, true ),
std::make_tuple( "1.2.3", 0, true ),
std::make_tuple( "1e2.3 ", 0, true ),
std::make_tuple( "1 ", 0, true ),
std::make_tuple( "1e", 0, true ),
std::make_tuple( "1e-", 0, true ),
std::make_tuple( "1e+", 0, true )));
Expand All @@ -319,13 +323,15 @@ INSTANTIATE_TEST_SUITE_P(
integerAttributeTests,
integerAttributeTestFixture,
::testing::Values( std::make_tuple( "1", 1, false ),
std::make_tuple( "1 ", 1, false ),
std::make_tuple( " 1", 1, false ),
std::make_tuple( " 1 ", 1, false ),
std::make_tuple( "-23", -23, false ),
std::make_tuple( "4.5", 0, true ),
std::make_tuple( "4.", 0, true ),
std::make_tuple( "alpha", 0, true ),
std::make_tuple( "1beta234", 0, true ),
std::make_tuple( "1234gamma", 0, true ),
std::make_tuple( "1 ", 0, true ),
std::make_tuple( "1 2", 0, true )));


Expand Down Expand Up @@ -374,12 +380,13 @@ TEST( testXmlWrapper, testGroupNamesFormats )
GroupNameTest( groupNameRegex, "testname01" ),
GroupNameTest( groupNameRegex, "test_name" ),
GroupNameTest( groupNameRegex, "test-name" ),
GroupNameTest( groupNameRegex, "test.name" ),
GroupNameTest( groupNameRegex, " testname " ),
GroupNameTest( groupNameRegex, " \t testname \n " ),
};
for( GroupNameTest const & input : workingInputs )
{
EXPECT_NO_THROW( xmlWrapper::stringToInputVariable( groupName, input.m_valueToTest, input.m_regex ) );
EXPECT_STREQ( input.m_valueToTest.c_str(), groupName.c_str() );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the place that needs to be reworked.

EXPECT_STREQ( groupName.c_str(), groupName.c_str() );
}
}
{
Expand All @@ -391,13 +398,97 @@ TEST( testXmlWrapper, testGroupNamesFormats )
//white spaces
GroupNameTest( groupNameRegex, "test name" ),
GroupNameTest( groupNameRegex, "test\tname" ),
GroupNameTest( groupNameRegex, "testname " ),
GroupNameTest( groupNameRegex, " testname" ),
//fordbiden characters
GroupNameTest( groupNameRegex, "test/name" ),
GroupNameTest( groupNameRegex, "test:name" ),
GroupNameTest( groupNameRegex, "test;name" ),
GroupNameTest( groupNameRegex, "test\\name" ),
GroupNameTest( groupNameRegex, "{[arrayElement]}" ),
GroupNameTest( groupNameRegex, "{name1,name2,name3}" ),
};
for( GroupNameTest const & input : erroneousInputs )
{
EXPECT_THROW( xmlWrapper::stringToInputVariable( groupName, input.m_valueToTest, input.m_regex ),
InputError ) << "Parsing input '"<< input.m_valueToTest
<< "' with regex '" << input.m_regex.m_regexStr << "' didn't throw an InputError as expected.";
}
}
}
TEST( testXmlWrapper, testGroupNamesArrayFormats )
{
struct GroupNameTest
{
Regex const & m_regex;
string m_valueToTest;
GroupNameTest( Regex const & regex, string_view valueToTest ):
m_regex( regex ), m_valueToTest( valueToTest ) {}
};

Regex const & groupNameRefArrayRegex = rtTypes::getTypeRegex< string >( rtTypes::CustomTypes::groupNameRefArray );
string groupName;

{
stdVector< GroupNameTest > workingInputs = {
GroupNameTest( groupNameRefArrayRegex, "{}" ),
GroupNameTest( groupNameRefArrayRegex, " {} " ),
GroupNameTest( groupNameRefArrayRegex, " \t {} \n " ),
GroupNameTest( groupNameRefArrayRegex, "{groupName}" ),
GroupNameTest( groupNameRefArrayRegex, "{123name}" ),
GroupNameTest( groupNameRefArrayRegex, "{name123}" ),
GroupNameTest( groupNameRefArrayRegex, "{a-Z0-9./*[]-_,}" ),
GroupNameTest( groupNameRefArrayRegex, "{name.with-special_chars}" ),
GroupNameTest( groupNameRefArrayRegex, "{path/to/resource*}" ),
GroupNameTest( groupNameRefArrayRegex, "{[arrayElement]}" ),
GroupNameTest( groupNameRefArrayRegex, "{name1,name2,name3}" ),
};
for( GroupNameTest const & input : workingInputs )
{
EXPECT_NO_THROW( xmlWrapper::stringToInputVariable( groupName, input.m_valueToTest, input.m_regex ) );
EXPECT_STREQ( groupName.c_str(), groupName.c_str() );
}
}
{
stdVector< GroupNameTest > erroneousInputs = {
GroupNameTest( groupNameRefArrayRegex, "" ),
GroupNameTest( groupNameRefArrayRegex, " " ),
GroupNameTest( groupNameRefArrayRegex, " \t " ),
GroupNameTest( groupNameRefArrayRegex, "{\t}" ),
GroupNameTest( groupNameRefArrayRegex, "{test:name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test;name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test\\name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test|name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test^name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test$name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test&name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test#name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test!name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test%name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test@name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test(name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test)name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test=name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test+name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test<name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test>name}" ),
GroupNameTest( groupNameRefArrayRegex, "{test\tname}" ),
GroupNameTest( groupNameRefArrayRegex, "{test\nname}" ),
GroupNameTest( groupNameRefArrayRegex, "{test\rname}" ),
GroupNameTest( groupNameRefArrayRegex, "groupName" ),
GroupNameTest( groupNameRefArrayRegex, "{groupName" ),
GroupNameTest( groupNameRefArrayRegex, "groupName}" ),
GroupNameTest( groupNameRefArrayRegex, "{groupName}} " ),
GroupNameTest( groupNameRefArrayRegex, "{}groupName" ),
GroupNameTest( groupNameRefArrayRegex, "groupName{}" ),
GroupNameTest( groupNameRefArrayRegex, "{hello, \t\n\r ,world}" ),
GroupNameTest( groupNameRefArrayRegex, "test{groupName}" ),
GroupNameTest( groupNameRefArrayRegex, "{groupName}test" ),
GroupNameTest( groupNameRefArrayRegex, "{groupName} test" ),
GroupNameTest( groupNameRefArrayRegex, "{element with space, another}" ),
GroupNameTest( groupNameRefArrayRegex, "{element, element with space, 123.456, a-b}" ),
GroupNameTest( groupNameRefArrayRegex, "{ space at ends } " ),
GroupNameTest( groupNameRefArrayRegex, "{valuewith,,commas }" ),
GroupNameTest( groupNameRefArrayRegex, "{ value with , commas }" ),
GroupNameTest( groupNameRefArrayRegex, "{{groupname}}" ),
};
for( GroupNameTest const & input : erroneousInputs )
{
Expand Down
4 changes: 2 additions & 2 deletions src/coreComponents/dataRepository/xmlWrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,8 @@ std::enable_if_t< traits::CanStreamInto< std::istringstream, T > >
stringToInputVariable( T & target, string const & value, Regex const & regex )
{
validateString( value, regex );

std::istringstream ss( value );
string_view stringTrimed = stringutilities::trimSpaces( value );
std::istringstream ss( (string( stringTrimed )) );
ss >> target;
GEOS_THROW_IF( ss.fail() || !ss.eof(),
"Error detected while parsing string \"" << value <<
Expand Down
Loading
Loading