Skip to content

Commit

Permalink
Add unit test for time duration regexes, and limit number of times us…
Browse files Browse the repository at this point in the history
…ers see graphical recalibration message to once.
  • Loading branch information
wcjohns committed May 21, 2024
1 parent 4b51184 commit 3a037d8
Show file tree
Hide file tree
Showing 4 changed files with 323 additions and 2 deletions.
4 changes: 4 additions & 0 deletions InterSpec/InterSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -1645,6 +1645,10 @@ class InterSpec : public Wt::WContainerWidget
bool m_findingHintPeaks;
std::deque<boost::function<void()> > m_hintQueue;

/** Some informational messages should only be shown once, like when you click on the
energy tab, so we'll keep track of if we have shown a message.
*/
std::set<std::string> m_infoNotificationsMade;

#if( INCLUDE_ANALYSIS_TEST_SUITE )
friend class SpectrumViewerTester;
Expand Down
4 changes: 3 additions & 1 deletion InterSpec_resources/app_text/InterSpec.xml
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,9 @@

<message id="info-user-default-drf">Using the detector response function you specified to use as default for this detector.</message>
<message id="info-app-default-drf">Have loaded a default detector response function for this detection system.</message>

<message id="info-recal-tab-selected">You can also recalibrate graphically by right-clicking and dragging the spectrum to where you want.</message>


<!-- Toast message shown to user when they load a spectrum that has GPS coordinates -->
<message id="info-has-gps-txt">File contains GPS coordinates.</message>
<message id="info-has-gps-btn">Show on map</message>
Expand Down
1 change: 1 addition & 0 deletions InterSpec_resources/app_text/InterSpec_fr.xml
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@
<message id="window-hard-back-sub-round">Arrondir les comptes des canaux au nombre entier le plus proche</message>
<message id="info-user-default-drf">Utilisation de la fonction de réponse du détecteur que vous avez spécifiée comme défaut pour ce détecteur.</message>
<message id="info-app-default-drf">Une fonction de réponse du détecteur par défaut pour ce système de détection a été chargée.</message>
<message id="info-recal-tab-selected">Vous pouvez également recalibrer graphiquement en cliquant avec le bouton droit et en faisant glisser le spectre là où vous le souhaitez.</message>
<message id="info-has-gps-txt">Le fichier contient des coordonnées GPS.</message>
<message id="info-has-gps-btn">Afficher sur la carte</message>
<message id="info-has-rid-txt">Le fichier contenait des résultats RID embarqués</message>
Expand Down
316 changes: 315 additions & 1 deletion target/testing/test_PhysicalUnitsLocalized.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@
#include <map>
#include <tuple>
#include <cmath>
#include <regex>
#include <string>
#include <vector>
#include <cstdlib>

#include <Wt/WServer>
#include <Wt/WString>
#include <Wt/WMessageResourceBundle>


Expand Down Expand Up @@ -305,5 +308,316 @@ BOOST_AUTO_TEST_CASE( testStringToTimeDurationPossibleHalfLifeLocalized ) {
BOOST_CHECK_MESSAGE( false, "Failed to parse '" << input << "' using localized stringToTimeDurationPossibleHalfLife, recieved: " << e.what() << "." );
}
}
}
}//BOOST_AUTO_TEST_CASE( testStringToTimeDurationPossibleHalfLifeLocalized )


BOOST_AUTO_TEST_CASE( testLocalizedRegexs ) {
set_app_text_dir();

const std::string should_match_english[] = {
"1.2E-3 year 2m +5s 14.5 ms +18.1y",
"1.2E-3 year",
"2m",
"+5s",
"14.5 ms",
"+18.1y",
"1.3ms",
"5 years",
"2.3E+01 hours",
"2.2 Days",
"5 y",
"+5 y",
"5 year",
"5.year",
"5 year 2d 3h 4s",
"3s 5min",
".5s .25m",
".5 second .25 m",
".3ns ",
"8 nanosecond",
"3 minute",
"10m 23:59:59.100",
"88.3E+2s",
"23:59:59.100",
"23:59:59.100 + 10m",
};


const std::string should_match_french[] = {
"+18.1a",
"1.2E-3 year 2m +5s 14.5 ms +18.1y",
"1.2 an 3jours 5.1 heure",
"2.11années",
"1h 3ms",
"1.1E-3jour 1 heures +3.2min",
"1.1E-3 sec 3ms",
"1.1E-3années"
};

const std::string should_match_english_hl[] = {
//"0", //Shouldnt we be able to match 0, with no units? Doesnt look like it
"5 half-life",
"5hl",
"1y 5halflives",
"5half lifes",
"5 half life",
"1.1E3hl",
"5hl 0.53day"
};

const std::string should_match_french_hl[] = {
"5 demi vie",
"5dv",
"5demi-vies",
"5demi vie",
"5demi vies",
"1.1E3dv",
"5dv 0.53jour"
};



const std::string should_match_english_negative[] = {
"-5 half-life",
"-5hl",
"1y -5halflives",
"-5half lifes",
"-5 half life",
"-1.1E3hl",
"-5hl 0.53day"
};

const std::string should_match_french_negative[] = {
"-5 demi vie",
"-5dv",
"1a -5demi-vies",
"-5demi vie",
"-5demi vies",
"-1.1E3dv",
"-5dv 0.53jour"
};

const std::string should_not_match[] = {
"year",
"1.0",
"0.001",
"1.2y somethign",
"1.2 yrr", //We want regext to match the whole line
"y1.2",
"1.2y a3",
};


WMessageResourceBundle *bundle_french = new WMessageResourceBundle();
WMessageResourceBundle *bundle_english = new WMessageResourceBundle();

std::string path = SpecUtils::append_path(g_app_text_dir, "InterSpec");
bundle_english->use( path, true );
bundle_french->use( path + "_fr", true );

// We need to create a WServer, so strings can be localized
Wt::WServer server("","");

pair<WMessageResourceBundle *,bool> languages[] = {
{bundle_french, true},
{bundle_english, false}
};

for( const auto lang : languages )
{
WMessageResourceBundle *bundle = lang.first;
const bool test_french = lang.second;

server.setLocalizedStrings( bundle ); //Takes ownership of bundle

{//begin block to check ordinary duration regex
Wt::WString duration_regex;
BOOST_REQUIRE_NO_THROW( duration_regex = PhysicalUnitsLocalized::timeDurationRegex() );

const std::string duration_regex_str = duration_regex.toUTF8();
BOOST_REQUIRE_NO_THROW( std::regex( duration_regex_str, std::regex::ECMAScript | std::regex::icase ) );

try
{
std::regex duration_expression( duration_regex_str, std::regex::ECMAScript | std::regex::icase );

for( const string &str : should_match_english )
{
std::smatch mtch;
BOOST_CHECK_MESSAGE( std::regex_match( str, mtch, duration_expression ),
"Duration regex failed to match: '" << str << "'"
<< " with regex '" << duration_regex_str << "'" );
}

if( test_french )
{
for( const string &str : should_match_french )
{
std::smatch mtch;
BOOST_CHECK_MESSAGE( std::regex_match( str, mtch, duration_expression ),
"Duration regex failed to match: '" << str << "'"
<< " with regex '" << duration_regex_str << "'" );
}
}//if( test_french )

for( const string &str : should_not_match )
{
std::smatch mtch;
BOOST_CHECK_MESSAGE( !std::regex_match( str, mtch, duration_expression ),
"Duration regex matched when shouldnt have: '" << str << "'"
<< " with regex '" << duration_regex_str << "'" );
}
}catch( std::exception &e )
{
BOOST_CHECK_MESSAGE( false, "Caught exception testing regex. Exception='" << e.what()
<< "', regex='" << duration_regex_str << "'" );
}
}// end block to check ordinary duration regex


{ //begin block to check duration with possible HL regex
Wt::WString duration_hl_regex;
BOOST_REQUIRE_NO_THROW( duration_hl_regex = PhysicalUnitsLocalized::timeDurationHalfLiveOptionalRegex() );

const std::string duration_regex_hl_str = duration_hl_regex.toUTF8();
BOOST_REQUIRE_NO_THROW( std::regex( duration_regex_hl_str, std::regex::ECMAScript | std::regex::icase ) );

try
{
std::regex duration_expression( duration_regex_hl_str, std::regex::ECMAScript | std::regex::icase );

for( const string &str : should_match_english )
{
std::smatch mtch;
BOOST_CHECK_MESSAGE( std::regex_match( str, mtch, duration_expression ),
"Duration HL regex failed to match: '" << str << "'" );
}

if( test_french )
{
for( const string &str : should_match_french )
{
std::smatch mtch;
BOOST_CHECK_MESSAGE( std::regex_match( str, mtch, duration_expression ),
"Duration HL regex failed to match: '" << str << "'"
<< " with regex '" << duration_regex_hl_str << "'" );
}
}//if( test_french )


for( const string &str : should_match_english_hl )
{
std::smatch mtch;
BOOST_CHECK_MESSAGE( std::regex_match( str, mtch, duration_expression ),
"Duration HL regex failed to match: '" << str << "'" );
}


if( test_french )
{
for( const string &str : should_match_french_hl )
{
std::smatch mtch;
BOOST_CHECK_MESSAGE( std::regex_match( str, mtch, duration_expression ),
"Duration HL regex failed to match: '" << str << "'"
<< " with regex '" << duration_regex_hl_str << "'" );
}
}//if( test_french )


for( const string &str : should_not_match )
{
std::smatch mtch;
BOOST_CHECK_MESSAGE( !std::regex_match( str, mtch, duration_expression ),
"Duration regex matched when shouldnt have HL: '" << str << "'"
<< " with regex '" << duration_regex_hl_str << "'" );
}
}catch( std::exception &e )
{
BOOST_CHECK_MESSAGE( false, "Caught exception testing HL regex. Exception='"
<< e.what() << "', regex='" << duration_regex_hl_str << "'" );
}

}//end block to check duration with possible HL regex


{ //begin block to check duration with possible HL and negative regex
Wt::WString duration_hl_neg_regex;
BOOST_REQUIRE_NO_THROW( duration_hl_neg_regex = PhysicalUnitsLocalized::timeDurationHalfLiveOptionalPosOrNegRegex() );

const std::string duration_regex_hl_neg_str = duration_hl_neg_regex.toUTF8();
BOOST_REQUIRE_NO_THROW( std::regex( duration_regex_hl_neg_str, std::regex::ECMAScript | std::regex::icase ) );

try
{
std::regex duration_expression( duration_regex_hl_neg_str, std::regex::ECMAScript | std::regex::icase );

for( const string &str : should_match_english )
{
std::smatch mtch;
BOOST_CHECK_MESSAGE( std::regex_match( str, mtch, duration_expression ),
"Duration neg HL regex failed to match: '" << str << "'" );
}

if( test_french )
{
for( const string &str : should_match_french )
{
std::smatch mtch;
BOOST_CHECK_MESSAGE( std::regex_match( str, mtch, duration_expression ),
"Duration HL neg regex failed to match: '" << str << "'" << " with regex '"
<< duration_regex_hl_neg_str << "'" );
}
}//if( test_french )

for( const string &str : should_not_match )
{
std::smatch mtch;
BOOST_CHECK_MESSAGE( !std::regex_match( str, mtch, duration_expression ),
"Duration regex matched when shouldnt have HL neg: '" << str << "'"
<< " with regex '" << duration_regex_hl_neg_str << "'" );
}

for( const string &str : should_match_english_hl )
{
std::smatch mtch;
BOOST_CHECK_MESSAGE( std::regex_match( str, mtch, duration_expression ),
"Duration HL regex failed to match: '" << str << "'" );
}

for( const string &str : should_match_english_negative )
{
std::smatch mtch;
BOOST_CHECK_MESSAGE( std::regex_match( str, mtch, duration_expression ),
"Duration HL regex failed to match negative: '" << str << "'" );
}


if( test_french )
{
for( const string &str : should_match_french_hl )
{
std::smatch mtch;
BOOST_CHECK_MESSAGE( std::regex_match( str, mtch, duration_expression ),
"Duration HL regex failed to match: '" << str << "'"
<< " with regex '" << duration_regex_hl_neg_str << "'" );
}

for( const string &str : should_match_french_negative )
{
std::smatch mtch;
BOOST_CHECK_MESSAGE( std::regex_match( str, mtch, duration_expression ),
"Duration HL regex failed to match french negative: '" << str << "'"
<< " with regex '" << duration_regex_hl_neg_str << "'" );
}
}//if( test_french )
}catch( std::exception &e )
{
BOOST_CHECK_MESSAGE( false, "Caught exception testing HL neg regex. Exception='" << e.what()
<< "', regex='" << duration_regex_hl_neg_str << "'" );
}

}//for( const auto lang : languages )

}//begin block to check duration with possible HL and negative regex
}//BOOST_AUTO_TEST_CASE( printToBestTimeUnitsLocalized ) {

0 comments on commit 3a037d8

Please sign in to comment.