Reimplmented ParseMode based on string keys.

Completely reimplemented the ParseMode class. Now the main datastructure
is a map<string,action> where the possible error situations are the
keys. This approach allows for a much more flexible
setting/filtering/querying of the ParseMode settings.
This commit is contained in:
Joakim Hove
2015-08-08 12:36:52 +02:00
parent 601f1b577b
commit d26428dd52
9 changed files with 355 additions and 104 deletions

View File

@@ -179,15 +179,8 @@ namespace Opm {
if (unsupportedModifiers.find( keyword->name() ) != unsupportedModifiers.end()) { if (unsupportedModifiers.find( keyword->name() ) != unsupportedModifiers.end()) {
auto action = parseMode.unsupportedScheduleGeoModifiers;
if (action != InputError::IGNORE) {
std::string msg = "OPM does not support grid property modifier " + keyword->name() + " in the Schedule section. Error at report: " + std::to_string( currentStep ); std::string msg = "OPM does not support grid property modifier " + keyword->name() + " in the Schedule section. Error at report: " + std::to_string( currentStep );
if (action == InputError::THROW_EXCEPTION) parseMode.handleError( ParseMode::UNSUPPORTED_SCHEDULE_GEO_MODIFIER , msg );
throw std::invalid_argument( msg );
else if (action == InputError::WARN)
OpmLog::addMessage(Log::MessageType::Warning , msg );
}
} }
} }
@@ -243,16 +236,8 @@ namespace Opm {
for (const auto record : (*compordKeyword)) { for (const auto record : (*compordKeyword)) {
auto methodItem = record->getItem<ParserKeywords::COMPORD::ORDER_TYPE>(); auto methodItem = record->getItem<ParserKeywords::COMPORD::ORDER_TYPE>();
if (methodItem->getString(0) != "TRACK") { if (methodItem->getString(0) != "TRACK") {
auto action = parseMode.unsupportedCOMPORDType; std::string msg = "The COMPORD keyword only handles 'TRACK' order.";
if (action != InputError::IGNORE) { parseMode.handleError( ParseMode::UNSUPPORTED_COMPORD_TYPE , msg );
std::string msg = "The COMPORD keyword only handles 'TRACK' order. [ParseMode::unsupportedCOMPORDType]";
if (action == InputError::THROW_EXCEPTION)
throw std::invalid_argument(msg);
else
OpmLog::addMessage(Log::MessageType::Warning , msg );
}
} }
} }
} }

View File

@@ -104,14 +104,8 @@ namespace Opm {
m_thresholdPressureTable[r1 + maxEqlnum*r2] = p; m_thresholdPressureTable[r1 + maxEqlnum*r2] = p;
m_thresholdPressureTable[r2 + maxEqlnum*r1] = p; m_thresholdPressureTable[r2 + maxEqlnum*r1] = p;
} else { } else {
auto action = parseMode.unsupportedInitialTHPRES; std::string msg = "Inferring threshold pressure from the initial state is not supported.";
if (action != InputError::IGNORE) { parseMode.handleError( ParseMode::UNSUPPORTED_INITIAL_THPRES , msg );
std::string msg = "Inferring threshold pressure from the initial state is not supported. [ParseMode::unsupportedInitialTHPRES]";
if (action == InputError::THROW_EXCEPTION)
throw std::invalid_argument( msg );
else
OpmLog::addMessage(Log::MessageType::Warning , msg );
}
} }
} else } else
throw std::runtime_error("Missing region data for use of the THPRES keyword"); throw std::runtime_error("Missing region data for use of the THPRES keyword");

View File

@@ -222,7 +222,7 @@ BOOST_AUTO_TEST_CASE(ThresholdPressureThrowTest) {
BOOST_CHECK_THROW(std::make_shared<ThresholdPressure>(parseMode , deck, gridPropertiesEQLNUMall0), std::runtime_error); BOOST_CHECK_THROW(std::make_shared<ThresholdPressure>(parseMode , deck, gridPropertiesEQLNUMall0), std::runtime_error);
} }
parseMode.unsupportedInitialTHPRES = InputError::IGNORE; parseMode.update( ParseMode::UNSUPPORTED_INITIAL_THPRES , InputError::IGNORE );
BOOST_CHECK_NO_THROW(ThresholdPressure(parseMode,deck_missingPressure, gridProperties)); BOOST_CHECK_NO_THROW(ThresholdPressure(parseMode,deck_missingPressure, gridProperties));
} }

View File

@@ -39,7 +39,7 @@ using namespace Opm;
BOOST_AUTO_TEST_CASE( parse_EQUIL_MISSING_DIMS ) { BOOST_AUTO_TEST_CASE( parse_EQUIL_MISSING_DIMS ) {
Parser parser; Parser parser;
ParseMode parseMode; ParseMode parseMode;
parseMode.missingDIMSKeyword = InputError::IGNORE; parseMode.update(ParseMode::PARSE_MISSING_DIMS_KEYWORD, InputError::IGNORE);
const std::string equil = "EQUIL\n" const std::string equil = "EQUIL\n"
"2469 382.4 1705.0 0.0 500 0.0 1 1 20 /"; "2469 382.4 1705.0 0.0 500 0.0 1 1 20 /";
std::shared_ptr<const Deck> deck = parser.parseString(equil, parseMode); std::shared_ptr<const Deck> deck = parser.parseString(equil, parseMode);

View File

@@ -33,9 +33,10 @@ using namespace Opm;
BOOST_AUTO_TEST_CASE( test_parse ) { BOOST_AUTO_TEST_CASE( test_parse ) {
Parser parser(false); Parser parser(false);
ParseMode parseMode; ParseMode parseMode;
parseMode.unknownKeyword = InputError::IGNORE;
parseMode.randomText = InputError::IGNORE; parseMode.update( ParseMode::PARSE_UNKNOWN_KEYWORD , InputError::IGNORE );
parseMode.randomSlash = InputError::IGNORE; parseMode.update( ParseMode::PARSE_RANDOM_TEXT , InputError::IGNORE );
parseMode.update( ParseMode::PARSE_RANDOM_SLASH , InputError::IGNORE );
parser.addKeyword<ParserKeywords::SPECGRID>(); parser.addKeyword<ParserKeywords::SPECGRID>();
parser.addKeyword<ParserKeywords::FAULTS>(); parser.addKeyword<ParserKeywords::FAULTS>();
@@ -50,9 +51,10 @@ BOOST_AUTO_TEST_CASE( test_parse ) {
BOOST_AUTO_TEST_CASE( test_state ) { BOOST_AUTO_TEST_CASE( test_state ) {
Parser parser(false); Parser parser(false);
ParseMode parseMode; ParseMode parseMode;
parseMode.unknownKeyword = InputError::IGNORE;
parseMode.randomText = InputError::IGNORE; parseMode.update( ParseMode::PARSE_UNKNOWN_KEYWORD , InputError::IGNORE );
parseMode.randomSlash = InputError::IGNORE; parseMode.update( ParseMode::PARSE_RANDOM_TEXT , InputError::IGNORE );
parseMode.update( ParseMode::PARSE_RANDOM_SLASH , InputError::IGNORE );
parser.addKeyword<ParserKeywords::SPECGRID>(); parser.addKeyword<ParserKeywords::SPECGRID>();
parser.addKeyword<ParserKeywords::FAULTS>(); parser.addKeyword<ParserKeywords::FAULTS>();

View File

@@ -17,22 +17,198 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <ert/util/util.h>
#include <cstdlib>
#include <iostream>
#include <boost/algorithm/string.hpp>
#include <opm/parser/eclipse/OpmLog/OpmLog.hpp>
#include <opm/parser/eclipse/Parser/ParseMode.hpp> #include <opm/parser/eclipse/Parser/ParseMode.hpp>
#include <opm/parser/eclipse/Parser/InputErrorAction.hpp> #include <opm/parser/eclipse/Parser/InputErrorAction.hpp>
namespace Opm { namespace Opm {
/*
A set of predefined error modes are added, with the default
setting 'InputError::IGNORE, then afterwards the environment
variables 'OPM_ERRORS_EXCEPTION', 'OPM_ERRORS_WARN' and
'OPM_ERRORS_IGNORE' are consulted
*/
ParseMode::ParseMode() { ParseMode::ParseMode() {
unknownKeyword = InputError::THROW_EXCEPTION; initDefault();
randomText = InputError::THROW_EXCEPTION; initEnv();
randomSlash = InputError::THROW_EXCEPTION; }
missingDIMSKeyword = InputError::THROW_EXCEPTION;
unsupportedScheduleGeoModifiers = InputError::THROW_EXCEPTION; /*
unsupportedCOMPORDType = InputError::THROW_EXCEPTION; If you intend to hardwire settings you should use this
unsupportedInitialTHPRES = InputError::THROW_EXCEPTION; constructor, as that way the environment variables are applied
after the hawrdwired settings.
*/
ParseMode::ParseMode(const std::vector<std::pair<std::string , InputError::Action>> initial) {
initDefault();
for (const auto& pair : initial)
update( pair.first , pair.second );
initEnv();
}
void ParseMode::initDefault() {
addKey(PARSE_UNKNOWN_KEYWORD);
addKey(PARSE_RANDOM_TEXT);
addKey(PARSE_RANDOM_SLASH);
addKey(PARSE_MISSING_DIMS_KEYWORD);
addKey(UNSUPPORTED_SCHEDULE_GEO_MODIFIER);
addKey(UNSUPPORTED_COMPORD_TYPE);
addKey(UNSUPPORTED_INITIAL_THPRES);
}
void ParseMode::initEnv() {
envUpdate( "OPM_ERRORS_EXCEPTION" , InputError::THROW_EXCEPTION );
envUpdate( "OPM_ERRORS_WARN" , InputError::WARN );
envUpdate( "OPM_ERRORS_IGNORE" , InputError::IGNORE );
}
void ParseMode::handleError( const std::string& errorKey , const std::string& msg) const {
InputError::Action action = get( errorKey );
if (action == InputError::WARN)
OpmLog::addMessage(Log::MessageType::Warning , msg);
else if (action == InputError::THROW_EXCEPTION)
throw std::invalid_argument(errorKey + ": " + msg);
}
std::map<std::string,InputError::Action>::const_iterator ParseMode::begin() const {
return m_errorModes.begin();
}
std::map<std::string,InputError::Action>::const_iterator ParseMode::end() const {
return m_errorModes.end();
}
bool ParseMode::hasKey(const std::string& key) const {
if (m_errorModes.find( key ) == m_errorModes.end())
return false;
else
return true;
}
void ParseMode::addKey(const std::string& key) {
if (key.find_first_of("|:*") != std::string::npos)
throw std::invalid_argument("The ParseMode keys can not contain '|', '*' or ':'");
if (!hasKey(key))
m_errorModes.insert( std::pair<std::string , InputError::Action>( key , InputError::THROW_EXCEPTION ));
}
InputError::Action ParseMode::get(const std::string& key) const {
if (hasKey( key ))
return m_errorModes.find( key )->second;
else
throw std::invalid_argument("The errormode key: " + key + " has not been registered");
}
/*****************************************************************/
/*
This is the 'strict' update function, it will throw an exception
if the input string is not a defined error mode. This should
typically be used in a downstream module where the policy
regarding an error mode is hardcoded. When using this method the
static string constanst for the different error modes should be
used as arguments:
parseMode.updateKey( ParseMode::PARSE_RANDOM_SLASH , InputError::IGNORE )
*/
void ParseMode::updateKey(const std::string& key , InputError::Action action) {
if (hasKey(key))
m_errorModes[key] = action;
else
throw std::invalid_argument("The errormode key: " + key + " has not been registered");
}
void ParseMode::envUpdate( const std::string& envVariable , InputError::Action action ) {
const char * userSetting = getenv(envVariable.c_str());
if (userSetting )
update( userSetting , action);
}
void ParseMode::update(InputError::Action action) {
for (const auto& pair : m_errorModes) {
const std::string& key = pair.first;
updateKey( key , action );
} }
} }
void ParseMode::patternUpdate( const std::string& pattern , InputError::Action action) {
const char * c_pattern = pattern.c_str();
for (const auto& pair : m_errorModes) {
const std::string& key = pair.first;
if (util_fnmatch( c_pattern , key.c_str()) == 0)
updateKey( key , action );
}
}
/*
This is the most general update function. The input keyString is
"selector string", and all matching error modes will be set to
@action. The algorithm for decoding the @keyString is:
1. The input string is split into several tokens on occurences
of ':' or ':' - and then each element is treated
seperately.
2. For each element in the list from 1):
a) If it contains at least one '*' - update all error modes
matching the input string.
b) If it is exactly equal to recognized error mode - update
that.
c) Otherwise - silently ignore.
*/
void ParseMode::update(const std::string& keyString , InputError::Action action) {
std::vector<std::string> keys;
boost::split( keys , keyString , boost::is_any_of(":|"));
for (const auto& input_key : keys) {
std::vector<std::string> matching_keys;
size_t wildcard_pos = input_key.find("*");
if (wildcard_pos == std::string::npos) {
if (hasKey( input_key ))
updateKey( input_key , action );
} else
patternUpdate( input_key , action );
}
}
const std::string ParseMode::PARSE_UNKNOWN_KEYWORD = "PARSE_UNKNOWN_KEYWORD";
const std::string ParseMode::PARSE_RANDOM_TEXT = "PARSE_RANDOM_TEXT";
const std::string ParseMode::PARSE_RANDOM_SLASH = "PARSE_RANDOM_SLASH";
const std::string ParseMode::PARSE_MISSING_DIMS_KEYWORD = "PARSE_MISSING_DIMS_KEYWORD";
const std::string ParseMode::UNSUPPORTED_SCHEDULE_GEO_MODIFIER = "UNSUPPORTED_SCHEDULE_GEO_MODIFIER";
const std::string ParseMode::UNSUPPORTED_COMPORD_TYPE = "UNSUPPORTED_COMPORD_TYPE";
const std::string ParseMode::UNSUPPORTED_INITIAL_THPRES = "UNSUPPORTED_INITIAL_THPRES";
}

View File

@@ -21,22 +21,20 @@
#ifndef OPM_PARSE_MODE_HPP #ifndef OPM_PARSE_MODE_HPP
#define OPM_PARSE_MODE_HPP #define OPM_PARSE_MODE_HPP
#include <string>
#include <map>
#include <vector>
#include <opm/parser/eclipse/Parser/InputErrorAction.hpp> #include <opm/parser/eclipse/Parser/InputErrorAction.hpp>
namespace Opm { namespace Opm {
/* /*
The ParseMode struct is meant to control the behavior of the The ParseMode class is meant to control the behavior of the
parsing and EclipseState construction phase when parsing and EclipseState construction phase when
errors/inconsistencies/... are encountered in the input. errors/inconsistencies/... are encountered in the input.
The ParseMode struct should be used as a simple value object,
i.e. apart from the constructor there are no methods - the
object can not 'do anything'. It is perfectly legitimate for
calling scope to manipulate the fields of a parsemode instance
directly.
For each of the possible problems encountered the possible For each of the possible problems encountered the possible
actions are goverened by the InputError::Action enum: actions are goverened by the InputError::Action enum:
@@ -44,11 +42,59 @@ namespace Opm {
InputError::WARN InputError::WARN
InputError::IGNORE InputError::IGNORE
The internal datastructure is a map between string keys and
enum InputError::Action values. The string keys are meant to be
descriptive like:
"PARSE_RANDOMTEXT"
The constructor will consult the env variable
OPM_ERRORS_IGNORE, OPM_ERRORS_WARN and OPM_ERRORS_EXCEPTION
when initializing. The variables should be set as strings of
update syntax.
update_syntax: The main function for updating the policy of a
parseMode instance is the update() method. That takes a string
as input, and updates the matching flags. The string can
contain wildcards ('* and '?' mathced with fnmatch()) and is
split on ':' or '|' to allow multiple settings to be applied in
one go:
Just set one variable:
update("PARSE_RANDOM_SLASH" , InputError::IGNORE)
Ignore all unsupported features:
update("UNSUPPORTED_*" , InputError::IGNORE)
Set two variables:
update("UNSUPPORTED_INIITIAL_THPRES:PARSE_RANDOM_SLASH" , InputError::IGNORE)
The update function itself is quite tolerant, and will silently
ignore unknown keys. If you use the updateKey() function only
recognizd keys will be allowed.
*/ */
struct ParseMode { class ParseMode {
public:
ParseMode(); ParseMode();
ParseMode(const std::vector<std::pair<std::string , InputError::Action>> initial);
void handleError( const std::string& errorKey , const std::string& msg) const;
bool hasKey(const std::string& key) const;
void updateKey(const std::string& key , InputError::Action action);
void update(InputError::Action action);
void update(const std::string& keyString , InputError::Action action);
InputError::Action get(const std::string& key) const;
std::map<std::string,InputError::Action>::const_iterator begin() const;
std::map<std::string,InputError::Action>::const_iterator end() const;
/*
When the key is added it is inserted in 'strict mode',
i.e. with the value 'InputError::THROW_EXCEPTION. If you
want a different value you must subsequently call the update
method.
*/
void addKey(const std::string& key);
/* /*
The unknownKeyword field regulates how the parser should The unknownKeyword field regulates how the parser should
react when it encounters an unknwon keyword. Observe that react when it encounters an unknwon keyword. Observe that
@@ -72,21 +118,20 @@ namespace Opm {
subsequent piece of 'random text' might not be identified subsequent piece of 'random text' might not be identified
correctly as such. correctly as such.
*/ */
InputError::Action unknownKeyword; const static std::string PARSE_UNKNOWN_KEYWORD;
/* /*
With random text we mean a string in the input deck is not With random text we mean a string in the input deck is not
correctly formatted as a keyword heading. correctly formatted as a keyword heading.
*/ */
InputError::Action randomText; const static std::string PARSE_RANDOM_TEXT;
/* /*
It turns out that random '/' - i.e. typically an extra slash It turns out that random '/' - i.e. typically an extra slash
which is not needed - is quite common. This is therefor a which is not needed - is quite common. This is therefor a
special case treatment of the 'randomText' behaviour. special case treatment of the 'randomText' behaviour.
*/ */
InputError::Action randomSlash; const static std::string PARSE_RANDOM_SLASH;
/* /*
@@ -101,7 +146,7 @@ namespace Opm {
Observe that a fully defaulted XXXDIMS keyword does not Observe that a fully defaulted XXXDIMS keyword does not
trigger this behavior. trigger this behavior.
*/ */
InputError::Action missingDIMSKeyword; const static std::string PARSE_MISSING_DIMS_KEYWORD;
/* /*
Some property modfiers can be modified in the Schedule Some property modfiers can be modified in the Schedule
@@ -112,22 +157,26 @@ namespace Opm {
encountered in the Schedule section the behavior is encountered in the Schedule section the behavior is
regulated by this setting. regulated by this setting.
*/ */
InputError::Action unsupportedScheduleGeoModifiers; const static std::string UNSUPPORTED_SCHEDULE_GEO_MODIFIER;
/* /*
In the COMPORD implementation only the 'TRACK' input mode is supported. In the COMPORD implementation only the 'TRACK' input mode is supported.
*/ */
InputError::Action unsupportedCOMPORDType; const static std::string UNSUPPORTED_COMPORD_TYPE;
/* /*
If the third item in the THPRES keyword is defaulted the If the third item in the THPRES keyword is defaulted the
threshold pressure is inferred from the initial pressure; threshold pressure is inferred from the initial pressure;
this currently not supported. this currently not supported.
*/ */
InputError::Action unsupportedInitialTHPRES; const static std::string UNSUPPORTED_INITIAL_THPRES;
private:
void initDefault();
void initEnv();
void envUpdate( const std::string& envVariable , InputError::Action action );
void patternUpdate( const std::string& pattern , InputError::Action action);
std::map<std::string , InputError::Action> m_errorModes;
}; } }; }

View File

@@ -108,24 +108,19 @@ namespace Opm {
*/ */
void handleRandomText(const std::string& keywordString ) const { void handleRandomText(const std::string& keywordString ) const {
std::string errorKey;
std::stringstream msg; std::stringstream msg;
InputError::Action action;
std::string trimmedCopy = boost::algorithm::trim_copy( keywordString ); std::string trimmedCopy = boost::algorithm::trim_copy( keywordString );
if (trimmedCopy == "/") { if (trimmedCopy == "/") {
action = parseMode.randomSlash; errorKey = ParseMode::PARSE_RANDOM_SLASH;
msg << "Extra '/' detected at: " << dataFile << ":" << lineNR; msg << "Extra '/' detected at: " << dataFile << ":" << lineNR;
} else { } else {
action = parseMode.randomText; errorKey = ParseMode::PARSE_RANDOM_TEXT;
msg << "String \'" << keywordString << "\' not formatted/recognized as valid keyword at: " << dataFile << ":" << lineNR; msg << "String \'" << keywordString << "\' not formatted/recognized as valid keyword at: " << dataFile << ":" << lineNR;
} }
if (action == InputError::THROW_EXCEPTION) parseMode.handleError( errorKey , msg.str() );
throw std::invalid_argument( msg.str() );
else {
if (action == InputError::WARN)
OpmLog::addMessage(Log::MessageType::Warning , msg.str());
}
} }
}; };
@@ -405,17 +400,15 @@ namespace Opm {
} }
targetSize = sizeDefinitionItem->getInt(0); targetSize = sizeDefinitionItem->getInt(0);
} else { } else {
InputError::Action action = parserState->parseMode.missingDIMSKeyword; std::string msg = "Expected the kewyord: " + sizeKeyword.first + " to infer the number of records in: " + keywordString;
if (action == InputError::THROW_EXCEPTION) parserState->parseMode.handleError(ParseMode::PARSE_MISSING_DIMS_KEYWORD , msg );
throw std::invalid_argument("Excpeted the kewyord: " + sizeKeyword.first + " to infer the number of records in: " + keywordString);
else { {
auto keyword = getKeyword( sizeKeyword.first ); auto keyword = getKeyword( sizeKeyword.first );
auto record = keyword->getRecord(0); auto record = keyword->getRecord(0);
auto int_item = std::dynamic_pointer_cast<const ParserIntItem>( record->get( sizeKeyword.second ) ); auto int_item = std::dynamic_pointer_cast<const ParserIntItem>( record->get( sizeKeyword.second ) );
targetSize = int_item->getDefault( ); targetSize = int_item->getDefault( );
if (action == InputError::WARN)
OpmLog::addMessage(Log::MessageType::Warning , "Excpeted the kewyord: " + sizeKeyword.first + " to infer the number of records in: " + keywordString + " using default");
} }
} }
} }
@@ -423,14 +416,9 @@ namespace Opm {
} }
} else { } else {
if (ParserKeyword::validDeckName(keywordString)) { if (ParserKeyword::validDeckName(keywordString)) {
InputError::Action action = parserState->parseMode.unknownKeyword; std::string msg = "Keyword " + keywordString + " not recognized ";
if (action == InputError::THROW_EXCEPTION) parserState->parseMode.handleError( ParseMode::PARSE_UNKNOWN_KEYWORD , msg );
throw std::invalid_argument("Keyword " + keywordString + " not recognized ");
else {
if (action == InputError::WARN)
OpmLog::addMessage(Log::MessageType::Warning , "Keyword " + keywordString + " not recognized");
return std::shared_ptr<RawKeyword>( ); return std::shared_ptr<RawKeyword>( );
}
} else { } else {
parserState->handleRandomText( keywordString ); parserState->handleRandomText( keywordString );
return std::shared_ptr<RawKeyword>( ); return std::shared_ptr<RawKeyword>( );

View File

@@ -56,26 +56,26 @@ BOOST_AUTO_TEST_CASE(TestUnkownKeyword) {
parser.addKeyword<ParserKeywords::DIMENS>(); parser.addKeyword<ParserKeywords::DIMENS>();
parseMode.unknownKeyword = InputError::THROW_EXCEPTION; parseMode.update(ParseMode::PARSE_UNKNOWN_KEYWORD , InputError::THROW_EXCEPTION );
BOOST_CHECK_THROW( parser.parseString( deck1 , parseMode ) , std::invalid_argument); BOOST_CHECK_THROW( parser.parseString( deck1 , parseMode ) , std::invalid_argument);
parseMode.unknownKeyword = InputError::IGNORE; parseMode.update(ParseMode::PARSE_UNKNOWN_KEYWORD , InputError::IGNORE );
BOOST_CHECK_NO_THROW( parser.parseString( deck1 , parseMode ) ); BOOST_CHECK_NO_THROW( parser.parseString( deck1 , parseMode ) );
parseMode.randomText = InputError::IGNORE; parseMode.update(ParseMode::PARSE_UNKNOWN_KEYWORD , InputError::THROW_EXCEPTION );
parseMode.unknownKeyword = InputError::THROW_EXCEPTION; parseMode.update(ParseMode::PARSE_RANDOM_TEXT , InputError::IGNORE );
BOOST_CHECK_THROW( parser.parseString( deck2 , parseMode ) , std::invalid_argument); BOOST_CHECK_THROW( parser.parseString( deck2 , parseMode ) , std::invalid_argument);
parseMode.randomText = InputError::IGNORE; parseMode.update(ParseMode::PARSE_UNKNOWN_KEYWORD , InputError::IGNORE );
parseMode.unknownKeyword = InputError::IGNORE; parseMode.update(ParseMode::PARSE_RANDOM_TEXT , InputError::IGNORE );
BOOST_CHECK_NO_THROW( parser.parseString( deck2 , parseMode ) ); BOOST_CHECK_NO_THROW( parser.parseString( deck2 , parseMode ) );
parseMode.randomText = InputError::THROW_EXCEPTION; parseMode.update(ParseMode::PARSE_UNKNOWN_KEYWORD , InputError::IGNORE );
parseMode.unknownKeyword = InputError::IGNORE; parseMode.update(ParseMode::PARSE_RANDOM_TEXT , InputError::THROW_EXCEPTION );
BOOST_CHECK_THROW( parser.parseString( deck2 , parseMode ) , std::invalid_argument); BOOST_CHECK_THROW( parser.parseString( deck2 , parseMode ) , std::invalid_argument);
parseMode.randomText = InputError::IGNORE; parseMode.update(ParseMode::PARSE_UNKNOWN_KEYWORD , InputError::IGNORE );
parseMode.unknownKeyword = InputError::IGNORE; parseMode.update(ParseMode::PARSE_RANDOM_TEXT , InputError::IGNORE );
BOOST_CHECK_NO_THROW( parser.parseString( deck2 , parseMode ) ); BOOST_CHECK_NO_THROW( parser.parseString( deck2 , parseMode ) );
} }
@@ -95,10 +95,10 @@ BOOST_AUTO_TEST_CASE( CheckMissingSizeKeyword) {
parser.addKeyword<ParserKeywords::EQLDIMS>(); parser.addKeyword<ParserKeywords::EQLDIMS>();
parser.addKeyword<ParserKeywords::SOLUTION>(); parser.addKeyword<ParserKeywords::SOLUTION>();
parseMode.missingDIMSKeyword = InputError::THROW_EXCEPTION; parseMode.update( ParseMode::PARSE_MISSING_DIMS_KEYWORD , InputError::THROW_EXCEPTION );
BOOST_CHECK_THROW( parser.parseString( deck , parseMode ) , std::invalid_argument); BOOST_CHECK_THROW( parser.parseString( deck , parseMode ) , std::invalid_argument);
parseMode.missingDIMSKeyword = InputError::IGNORE; parseMode.update( ParseMode::PARSE_MISSING_DIMS_KEYWORD , InputError::IGNORE );
BOOST_CHECK_NO_THROW( parser.parseString( deck , parseMode ) ); BOOST_CHECK_NO_THROW( parser.parseString( deck , parseMode ) );
} }
@@ -123,10 +123,10 @@ BOOST_AUTO_TEST_CASE( CheckUnsoppertedInSCHEDULE ) {
std::shared_ptr<EclipseGrid> grid = std::make_shared<EclipseGrid>( deck ); std::shared_ptr<EclipseGrid> grid = std::make_shared<EclipseGrid>( deck );
std::shared_ptr<IOConfig> ioconfig = std::make_shared<IOConfig>( "path" ); std::shared_ptr<IOConfig> ioconfig = std::make_shared<IOConfig>( "path" );
parseMode.unsupportedScheduleGeoModifiers = InputError::IGNORE; parseMode.update( ParseMode::UNSUPPORTED_SCHEDULE_GEO_MODIFIER , InputError::IGNORE );
BOOST_CHECK_NO_THROW( Schedule( parseMode , grid , deck , ioconfig )); BOOST_CHECK_NO_THROW( Schedule( parseMode , grid , deck , ioconfig ));
parseMode.unsupportedScheduleGeoModifiers = InputError::THROW_EXCEPTION; parseMode.update( ParseMode::UNSUPPORTED_SCHEDULE_GEO_MODIFIER , InputError::THROW_EXCEPTION );
BOOST_CHECK_THROW( Schedule( parseMode , grid , deck , ioconfig ), std::invalid_argument ); BOOST_CHECK_THROW( Schedule( parseMode , grid , deck , ioconfig ), std::invalid_argument );
} }
@@ -153,14 +153,15 @@ BOOST_AUTO_TEST_CASE(TestRandomSlash) {
parser.addKeyword<ParserKeywords::TSTEP>(); parser.addKeyword<ParserKeywords::TSTEP>();
parser.addKeyword<ParserKeywords::SCHEDULE>(); parser.addKeyword<ParserKeywords::SCHEDULE>();
parseMode.randomSlash = InputError::THROW_EXCEPTION;
parseMode.randomText = InputError::IGNORE; parseMode.update(ParseMode::PARSE_RANDOM_SLASH , InputError::THROW_EXCEPTION);
parseMode.update(ParseMode::PARSE_RANDOM_TEXT , InputError::IGNORE);
BOOST_CHECK_THROW( parser.parseString( deck1 , parseMode ) , std::invalid_argument); BOOST_CHECK_THROW( parser.parseString( deck1 , parseMode ) , std::invalid_argument);
BOOST_CHECK_THROW( parser.parseString( deck2 , parseMode ) , std::invalid_argument); BOOST_CHECK_THROW( parser.parseString( deck2 , parseMode ) , std::invalid_argument);
parseMode.randomSlash = InputError::IGNORE;
parseMode.randomText = InputError::THROW_EXCEPTION;
parseMode.update(ParseMode::PARSE_RANDOM_SLASH , InputError::IGNORE);
parseMode.update(ParseMode::PARSE_RANDOM_TEXT , InputError::THROW_EXCEPTION);
BOOST_CHECK_NO_THROW( parser.parseString( deck1 , parseMode ) ); BOOST_CHECK_NO_THROW( parser.parseString( deck1 , parseMode ) );
BOOST_CHECK_NO_THROW( parser.parseString( deck2 , parseMode ) ); BOOST_CHECK_NO_THROW( parser.parseString( deck2 , parseMode ) );
} }
@@ -186,9 +187,65 @@ BOOST_AUTO_TEST_CASE(TestCOMPORD) {
std::shared_ptr<EclipseGrid> grid = std::make_shared<EclipseGrid>( deck ); std::shared_ptr<EclipseGrid> grid = std::make_shared<EclipseGrid>( deck );
std::shared_ptr<IOConfig> ioconfig = std::make_shared<IOConfig>( "path" ); std::shared_ptr<IOConfig> ioconfig = std::make_shared<IOConfig>( "path" );
parseMode.unsupportedCOMPORDType = InputError::IGNORE; parseMode.update( ParseMode::UNSUPPORTED_COMPORD_TYPE , InputError::IGNORE);
BOOST_CHECK_NO_THROW( Schedule( parseMode , grid , deck , ioconfig )); BOOST_CHECK_NO_THROW( Schedule( parseMode , grid , deck , ioconfig ));
parseMode.unsupportedCOMPORDType = InputError::THROW_EXCEPTION; parseMode.update( ParseMode::UNSUPPORTED_COMPORD_TYPE , InputError::THROW_EXCEPTION);
BOOST_CHECK_THROW( Schedule( parseMode , grid , deck , ioconfig ), std::invalid_argument ); BOOST_CHECK_THROW( Schedule( parseMode , grid , deck , ioconfig ), std::invalid_argument );
} }
BOOST_AUTO_TEST_CASE(TestInvalidKey) {
ParseMode parseMode;
BOOST_CHECK_THROW( parseMode.addKey("KEY*") , std::invalid_argument );
BOOST_CHECK_THROW( parseMode.addKey("KEY:") , std::invalid_argument );
}
BOOST_AUTO_TEST_CASE(TestNew) {
ParseMode parseMode;
BOOST_CHECK_EQUAL( false , parseMode.hasKey("NO"));
parseMode.addKey("NEW_KEY");
BOOST_CHECK_EQUAL( true , parseMode.hasKey("NEW_KEY"));
BOOST_CHECK_THROW( parseMode.get("NO") , std::invalid_argument );
BOOST_CHECK_EQUAL( parseMode.get("NEW_KEY") , InputError::THROW_EXCEPTION );
parseMode.addKey("KEY2");
BOOST_CHECK_EQUAL( parseMode.get("NEW_KEY") , InputError::THROW_EXCEPTION );
BOOST_CHECK_THROW( parseMode.updateKey("NO" , InputError::IGNORE) , std::invalid_argument);
parseMode.updateKey("NEW_KEY" , InputError::WARN);
BOOST_CHECK_EQUAL( parseMode.get("NEW_KEY") , InputError::WARN );
BOOST_CHECK_NO_THROW( parseMode.update("KEY2:NEW_KEY" , InputError::IGNORE));
BOOST_CHECK_NO_THROW( parseMode.update("UnknownKey" , InputError::IGNORE));
BOOST_CHECK_EQUAL( parseMode.get("NEW_KEY") , InputError::IGNORE );
BOOST_CHECK_EQUAL( parseMode.get("KEY2") , InputError::IGNORE );
parseMode.addKey("SECRET_KEY");
parseMode.addKey("NEW_KEY2");
parseMode.addKey("NEW_KEY3");
parseMode.update("NEW_KEY*" , InputError::WARN);
BOOST_CHECK_EQUAL( parseMode.get("NEW_KEY") , InputError::WARN );
BOOST_CHECK_EQUAL( parseMode.get("NEW_KEY2") , InputError::WARN );
BOOST_CHECK_EQUAL( parseMode.get("NEW_KEY3") , InputError::WARN );
parseMode.update( InputError::IGNORE );
BOOST_CHECK_EQUAL( parseMode.get("NEW_KEY3") , InputError::IGNORE );
BOOST_CHECK_EQUAL( parseMode.get("SECRET_KEY") , InputError::IGNORE );
}
BOOST_AUTO_TEST_CASE( test_constructor_with_values) {
ParseMode parseMode( {{ParseMode::PARSE_RANDOM_SLASH , InputError::IGNORE},
{"UNSUPPORTED_*" , InputError::WARN},
{"UNKNWON-IGNORED" , InputError::WARN}});
BOOST_CHECK_EQUAL( parseMode.get(ParseMode::PARSE_RANDOM_SLASH) , InputError::IGNORE );
BOOST_CHECK_EQUAL( parseMode.get(ParseMode::PARSE_RANDOM_TEXT) , InputError::THROW_EXCEPTION );
BOOST_CHECK_EQUAL( parseMode.get(ParseMode::UNSUPPORTED_INITIAL_THPRES) , InputError::WARN );
BOOST_CHECK_EQUAL( parseMode.get(ParseMode::UNSUPPORTED_COMPORD_TYPE) , InputError::WARN );
}