Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:17:43

0001 
0002 // Copyright 2020, Jefferson Science Associates, LLC.
0003 // Subject to the terms in the LICENSE file found in the top-level directory.
0004 
0005 
0006 #include <JANA/Services/JParameterManager.h>
0007 #include "catch.hpp"
0008 
0009 TEST_CASE("JParameterManager::SetDefaultParameter") {
0010 
0011     JParameterManager jpm;
0012 
0013 
0014    SECTION("Multiple calls to SetDefaultParameter with same defaults succeed") {
0015 
0016         jpm.SetParameter("testing:dummy_var", 22);
0017 
0018         int x = 44;
0019         jpm.SetDefaultParameter("testing:dummy_var", x);
0020         REQUIRE(x == 22);
0021 
0022         int y = 44;
0023         jpm.SetDefaultParameter("testing:dummy_var", y);
0024         REQUIRE(y == 22);
0025     }
0026 
0027 
0028     SECTION("Multiple calls to SetDefaultParameter with same defaults succeed, float") {
0029 
0030         float x = 1.1;
0031         jpm.SetDefaultParameter("small_float", x);
0032         float y = 1.1;
0033         jpm.SetDefaultParameter("small_float", y);
0034         float temp;
0035         jpm.Parse<float>(jpm.Stringify(1.1f), temp);
0036         REQUIRE(jpm.Equals(temp, 1.1f));
0037         jpm.Parse<float>(jpm.Stringify(1.1f), temp);
0038         REQUIRE(!jpm.Equals(temp, 1.10001f));
0039 
0040         float v = 1.1e20f;
0041         jpm.SetDefaultParameter("large_float", v);
0042         float w = 1.1e20f;
0043 
0044         jpm.SetDefaultParameter("large_float", w);
0045         jpm.Parse<float>(jpm.Stringify(1.1e20f), temp);
0046         REQUIRE(jpm.Equals(temp, 1.1e20f));
0047         jpm.Parse<float>(jpm.Stringify(1.1e20f), temp);
0048         REQUIRE(!jpm.Equals(temp, 1.100001e20f));
0049 
0050         double xx = 1.1;
0051         jpm.SetDefaultParameter("small_double", xx);
0052         double yy = 1.1;
0053         jpm.SetDefaultParameter("small_double", yy);
0054         
0055         double tempD;
0056         jpm.Parse<double>(jpm.Stringify(1.1), tempD);
0057         REQUIRE(jpm.Equals(tempD, 1.1));
0058         jpm.Parse<double>(jpm.Stringify(1.1), tempD);
0059         REQUIRE(!jpm.Equals(tempD, 1.100001));
0060 
0061         double vv = 1.1e50;
0062         jpm.SetDefaultParameter("large_double", vv);
0063         double ww = 1.1e50;
0064         jpm.SetDefaultParameter("large_double", ww);
0065 
0066         jpm.Parse<double>(jpm.Stringify(1.1e20), tempD);
0067         REQUIRE(jpm.Equals(tempD, 1.1e20));
0068         REQUIRE(!jpm.Equals(tempD, 1.1000000001e20));
0069     }
0070 
0071 
0072     SECTION("Multiple calls to SetDefaultParameter with different defaults") {
0073 
0074         // If set, the user provided value overrides ALL default values
0075 
0076         jpm.SetParameter("testing:dummy_var", 22);
0077 
0078         int x = 44;
0079         jpm.SetDefaultParameter("testing:dummy_var", x);
0080         REQUIRE(x == 22);
0081 
0082         int y = 77;
0083         jpm.SetDefaultParameter("testing:dummy_var", y);
0084         REQUIRE(x == 22);
0085 
0086 
0087         // If no value set and there are two conflicting defaults, use the _local_ one
0088         int z = 44;
0089         jpm.SetDefaultParameter("testing:dummy_var_2", z);
0090         REQUIRE(z == 44);
0091 
0092         int zz = 77;
0093         jpm.SetDefaultParameter("testing:dummy_var_2", zz);
0094         REQUIRE(zz == 77);
0095     }
0096 
0097     SECTION("Multiple calls to check strings with spaces") {
0098 
0099         // basic string test
0100         std::string x = "MyStringValue";
0101         jpm.SetDefaultParameter("testing:dummy_var", x);
0102         REQUIRE(x == "MyStringValue");
0103 
0104         // string with spaces
0105         std::string y = "My String Value With Spaces";
0106         auto p = jpm.SetDefaultParameter("testing:dummy_var2", y);
0107         REQUIRE(p->GetValue() == "My String Value With Spaces");
0108 
0109         // Stringify returns identical string
0110         REQUIRE( jpm.Stringify("My String Value With Spaces") == "My String Value With Spaces" );
0111 
0112         // Parse returns identical string
0113         std::string z = "My String Value With Spaces";
0114         std::string testString;
0115         jpm.Parse<std::string>(z,testString);
0116         REQUIRE( testString == "My String Value With Spaces" );
0117     }
0118 }
0119 
0120 
0121 TEST_CASE("JParameterManagerBoolTests") {
0122     JParameterManager jpm;
0123 
0124     SECTION("'0' parses to false") {
0125         jpm.SetParameter("test_param", "0");
0126         bool val = jpm.GetParameterValue<bool>("test_param");
0127         REQUIRE(val == false);
0128     }
0129 
0130     SECTION("'1' parses to true") {
0131         jpm.SetParameter("test_param", "1");
0132         bool val = jpm.GetParameterValue<bool>("test_param");
0133         REQUIRE(val == true);
0134     }
0135 
0136     SECTION("'off' parses to false") {
0137         jpm.SetParameter("test_param", "off");
0138         bool val = jpm.GetParameterValue<bool>("test_param");
0139         REQUIRE(val == false);
0140     }
0141 
0142     SECTION("'on' parses to true") {
0143         jpm.SetParameter("test_param", "on");
0144         bool val = jpm.GetParameterValue<bool>("test_param");
0145         REQUIRE(val == true);
0146     }
0147 
0148     SECTION("'true' parses to true") {
0149         jpm.SetParameter("test_param", "true");
0150         bool val = jpm.GetParameterValue<bool>("test_param");
0151         REQUIRE(val == true);
0152     }
0153 
0154     SECTION("'false' parses to false") {
0155         jpm.SetParameter("test_param", "false");
0156         bool val = jpm.GetParameterValue<bool>("test_param");
0157         REQUIRE(val == false);
0158     }
0159 
0160     SECTION("Parsing anything else as bool throws an exception") {
0161         jpm.SetParameter("test_param", "maybe");
0162         CHECK_THROWS(jpm.GetParameterValue<bool>("test_param"));
0163     }
0164 
0165     SECTION("Stringify still works") {
0166         jpm.SetParameter("test_param", false);
0167         std::string val = jpm.GetParameterValue<std::string>("test_param");
0168         REQUIRE(val == "0");
0169 
0170         jpm.SetParameter("test_param", true);
0171         val = jpm.GetParameterValue<std::string>("test_param");
0172         REQUIRE(val == "1");
0173     }
0174 }
0175 
0176 TEST_CASE("JParameterManager_VectorParams") {
0177     JParameterManager jpm;
0178 
0179     SECTION("Reading a vector of strings") {
0180         jpm.SetParameter("test", "simple,whitespace in middle, also with whitespace padding ");
0181         std::vector<std::string> vals;
0182         jpm.GetParameter<std::vector<std::string>>("test", vals);
0183 
0184         REQUIRE(vals[0] == "simple");
0185         REQUIRE(vals[1] == "whitespace in middle");
0186         REQUIRE(vals[2] == " also with whitespace padding ");
0187     }
0188     SECTION("Writing a vector of strings") {
0189         std::vector<std::string> inputs;
0190         inputs.emplace_back("first");
0191         inputs.emplace_back("second one");
0192         inputs.emplace_back(" third one ");
0193 
0194         jpm.SetDefaultParameter("test", inputs);
0195         std::vector<std::string> outputs;
0196         auto param = jpm.GetParameter("test", outputs);
0197         REQUIRE(param->GetValue() == "first,second one, third one ");
0198         REQUIRE(inputs.size()==3); // an additional test to see that the size of the input vector remains the same: Issue #256
0199     }
0200     SECTION("Reading a vector of ints") {
0201         jpm.SetParameter("test", "1,2, 3 ");
0202         std::vector<int32_t> vals;
0203         jpm.GetParameter("test", vals);
0204 
0205         REQUIRE(vals[0] == 1);
0206         REQUIRE(vals[1] == 2);
0207         REQUIRE(vals[2] == 3);
0208     }
0209     SECTION("Writing a vector of ints") {
0210         std::vector<int32_t> inputs;
0211         inputs.emplace_back(22);
0212         inputs.emplace_back(49);
0213         inputs.emplace_back(42);
0214 
0215         jpm.SetDefaultParameter("test", inputs);
0216         std::vector<std::string> outputs;
0217         auto param = jpm.GetParameter("test", outputs);
0218         REQUIRE(param->GetValue() == "22,49,42");
0219     }
0220     SECTION("Reading a vector of floats") {
0221         jpm.SetParameter("test", "1,2,3");
0222         std::vector<float> vals;
0223         jpm.GetParameter("test", vals);
0224 
0225         REQUIRE(vals[0] == 1.0f);
0226         REQUIRE(vals[1] == 2.0f);
0227         REQUIRE(vals[2] == 3.0f);
0228     }
0229     SECTION("Writing a vector of floats") {
0230         std::vector<float> inputs;
0231         inputs.emplace_back(22.0);
0232         inputs.emplace_back(49.2);
0233         inputs.emplace_back(42.0);
0234 
0235         jpm.SetDefaultParameter("test", inputs);
0236         std::vector<float> outputs;
0237         auto param = jpm.GetParameter("test", outputs);
0238         REQUIRE(param->GetValue() == "22,49.2,42");
0239     }
0240 }
0241 
0242 TEST_CASE("JParameterManager::RegisterParameter") {
0243 
0244     JParameterManager jpm;
0245 
0246     SECTION("Set/Get") {
0247         int x_default = 44;
0248         auto x_actual = jpm.RegisterParameter("testing:dummy_var", x_default);
0249         REQUIRE(x_actual == x_default);
0250     }
0251 
0252     SECTION("Set/Get templated float") {
0253         auto y_actual = jpm.RegisterParameter("testing:dummy_var2", 22.0);
0254         REQUIRE(y_actual == 22.0);
0255     }
0256 
0257     SECTION("Set/Get default") {
0258         jpm.SetParameter("testing:dummy_var", 22);
0259         auto x_actual = jpm.RegisterParameter("testing:dummy_var", 44);  // this should set the default value to 44 while keeping value at 22
0260         auto x_default_str = jpm.FindParameter("testing:dummy_var")->GetDefault();
0261         int x_default;
0262         jpm.Parse<int>(x_default_str,x_default);
0263         REQUIRE(x_actual == 22);
0264         REQUIRE(x_default == 44);
0265     }
0266 
0267 }
0268 
0269 TEST_CASE("JParameterManager_ArrayParams") {
0270     JParameterManager jpm;
0271 
0272     SECTION("Reading a array of strings") {
0273         jpm.SetParameter("test", "simple,whitespace in middle, also with whitespace padding ");
0274         std::array<std::string,3> vals;
0275         jpm.GetParameter<std::array<std::string,3>>("test", vals); 
0276         REQUIRE(vals[0] == "simple");
0277         REQUIRE(vals[1] == "whitespace in middle");
0278         REQUIRE(vals[2] == " also with whitespace padding ");
0279     }
0280     SECTION("Writing a array of strings") {
0281         std::array<std::string,3> inputs = {"first", "second one" , " third one "};
0282         jpm.SetDefaultParameter("test", inputs);
0283         std::array<std::string,3> outputs;
0284         auto param = jpm.GetParameter("test", outputs);
0285         REQUIRE(param->GetValue() == "first,second one, third one ");
0286     }
0287     SECTION("Reading a array of ints") {
0288         jpm.SetParameter("test", "1,2, 3 ");
0289         std::array<int32_t,3> vals;
0290         jpm.GetParameter("test", vals);
0291 
0292         REQUIRE(vals[0] == 1);
0293         REQUIRE(vals[1] == 2);
0294         REQUIRE(vals[2] == 3);
0295     }
0296     SECTION("Writing a array of ints") {
0297         std::array<int32_t,3> inputs = {22,49,42};
0298         jpm.SetDefaultParameter("test", inputs);
0299         std::array<std::string,3> outputs;
0300         auto param = jpm.GetParameter("test", outputs);
0301         REQUIRE(param->GetValue() == "22,49,42");
0302     }
0303     SECTION("Reading a array of floats") {
0304         jpm.SetParameter("test", "1,2,3");
0305         std::array<float,3> vals;
0306         jpm.GetParameter("test", vals);
0307 
0308         REQUIRE(vals[0] == 1.0f);
0309         REQUIRE(vals[1] == 2.0f);
0310         REQUIRE(vals[2] == 3.0f);
0311     }
0312     SECTION("Writing a array of floats") {
0313         std::array<float,3> inputs = {22.0,49.2,42.0};
0314         jpm.SetDefaultParameter("test", inputs);
0315         std::array<float,3> outputs;
0316         auto param = jpm.GetParameter("test", outputs);
0317         REQUIRE(param->GetValue() == "22,49.2,42");
0318     }
0319 }
0320 
0321 TEST_CASE("JParameterManagerFloatingPointRoundTrip") {
0322     JParameterManager jpm;
0323 
0324     SECTION("Integer") {
0325         const std::string testValString = jpm.Stringify(123);
0326         REQUIRE(testValString == "123");
0327         int testValParsed;
0328         jpm.Parse<int>(testValString, testValParsed);
0329         REQUIRE(testValParsed == 123);
0330     }
0331 
0332     SECTION("Double requiring low precision") {
0333         const double testVal = 123;
0334         const std::string testValString = jpm.Stringify(testVal);
0335         REQUIRE(testValString == "123");
0336         double testValParsed;
0337         jpm.Parse<double>(testValString, testValParsed);
0338         REQUIRE(testValParsed == 123.0);
0339     }
0340 
0341     SECTION("Double requiring low precision, with extra zeros") {
0342         const double testVal = 123.0;
0343         const std::string testValString = jpm.Stringify(testVal);
0344         REQUIRE(testValString == "123");
0345         double testValParsed;
0346         jpm.Parse<double>(testValString, testValParsed);
0347         REQUIRE(testValParsed == 123.0);
0348     }
0349 
0350     SECTION("Double requiring high precision") {
0351         const double testVal = 123.0001;
0352         const std::string testValString = jpm.Stringify(testVal);
0353         std::cout << "High-precision double stringified to " << testValString << std::endl;
0354         // REQUIRE(testValString == "123.0001");
0355         double testValParsed;
0356         jpm.Parse<double>(testValString, testValParsed);
0357         REQUIRE(testValParsed == 123.0001);
0358     }
0359 
0360     SECTION("Float requiring high precision") {
0361         const float testVal = 123.0001f;
0362         const std::string testValString = jpm.Stringify(testVal);
0363         std::cout << "High-precision float stringified to " << testValString << std::endl;
0364         // REQUIRE(testValString == "123.0001");
0365         float testValParsed;
0366         jpm.Parse<float>(testValString, testValParsed);
0367         REQUIRE(testValParsed == 123.0001f);
0368     }
0369 
0370     SECTION("Float requiring low precision") {
0371         const float testVal = 123.0f;
0372         const std::string testValString = jpm.Stringify(testVal);
0373         REQUIRE(testValString == "123");
0374         float testValParsed;
0375         jpm.Parse<float>(testValString, testValParsed);
0376         REQUIRE(testValParsed == 123.0f);
0377     }
0378 
0379 }
0380 
0381 
0382 TEST_CASE("JParameterManagerIssue233") {
0383     JParameterManager jpm;
0384     double x = 0.0;
0385     jpm.SetDefaultParameter("x", x, "Description");
0386     // This should NOT print out a warning about losing equality with itself after stringification
0387 
0388     // We reproduce the logic inside SetDefaultParameter here so that CI can catch regressions
0389     std::string x_stringified = JParameterManager::Stringify(x);
0390     double x_roundtrip;
0391     JParameterManager::Parse(x_stringified, x_roundtrip);
0392     REQUIRE(JParameterManager::Equals(x_roundtrip, x));
0393 }
0394 
0395 
0396 TEST_CASE("JParameterManager_Issue217StringsWithWhitespace") {
0397     JParameterManager jpm;
0398     SECTION("Reading a array of strings") {
0399         jpm.SetParameter("test", "(  abs(fmod(tower_1, 24) - fmod(tower_2, 24))  + min(      abs((sector_1 - sector_2) * (2 * 5) + (floor(tower_1 / 24) - floor(tower_2 / 24)) * 5 + fmod(tile_1, 5) - fmod(tile_2, 5)),      (32 * 2 * 5) - abs((sector_1 - sector_2) * (2 * 5) + (floor(tower_1 / 24) - floor(tower_2 / 24)) * 5 + fmod(tile_1, 5) - fmod(tile_2, 5))    )) == 1");
0400         std::string vals;
0401         jpm.GetParameter<std::string>("test", vals); 
0402         REQUIRE(vals == "(  abs(fmod(tower_1, 24) - fmod(tower_2, 24))  + min(      abs((sector_1 - sector_2) * (2 * 5) + (floor(tower_1 / 24) - floor(tower_2 / 24)) * 5 + fmod(tile_1, 5) - fmod(tile_2, 5)),      (32 * 2 * 5) - abs((sector_1 - sector_2) * (2 * 5) + (floor(tower_1 / 24) - floor(tower_2 / 24)) * 5 + fmod(tile_1, 5) - fmod(tile_2, 5))    )) == 1");
0403     }
0404 }
0405 
0406 
0407 enum class Mood {Good, Bad, Mediocre};
0408 TEST_CASE("JParameterManager_CompileTimeErrorForParseAndStringify") {
0409 
0410     int x;
0411     JParameterManager::Parse("22", x);
0412     // Uncomment these to test compile-time error message
0413     //Mood m;
0414     //JParameterManager::Parse("Mediocre", m);
0415     //JParameterManager::Stringify(m);
0416 }
0417 
0418 
0419 TEST_CASE("JParameterManager_Strictness") {
0420     JParameterManager sut;
0421     sut.SetParameter("jana:parameter_strictness", 2);
0422     sut.SetParameter("jana:unused", 22);
0423     bool exception_found = false;
0424     try {
0425         sut.PrintParameters();
0426     }
0427     catch (JException& e) {
0428         exception_found = true;
0429     }
0430     REQUIRE(exception_found == true);
0431 }
0432 
0433 
0434 
0435 TEST_CASE("JParameterManager_ConflictingDefaults") {
0436 
0437     int x1 = 3;
0438     int x2 = 4;
0439     int x3 = 3;
0440     int x4 = 4;
0441 
0442     JParameterManager sut;
0443     sut.SetLogger(JLogger());
0444 
0445     // Simulate a FactorySet containing two JFactories, each of which declares the same parameter with different default values
0446     auto p1 = sut.SetDefaultParameter("my_param_name", x1, "Tests how conflicting defaults are handled");
0447     REQUIRE(p1->HasDefault() == true);
0448     REQUIRE(p1->IsDefault() == true);
0449     REQUIRE(p1->GetDefault() == "3"); // Should be the _latest_ default found
0450     REQUIRE(p1->GetValue() == "3"); // Should be the _latest_ default value
0451     REQUIRE(x1 == 3);
0452     auto p2 = sut.SetDefaultParameter("my_param_name", x2, "Tests how conflicting defaults are handled");
0453     REQUIRE(p2->HasDefault() == true);
0454     REQUIRE(p2->IsDefault() == true);
0455     REQUIRE(p2->GetDefault() == "4"); // Should be the _latest_ default found
0456     REQUIRE(p2->GetValue() == "4"); // Should be the _latest_ default value
0457     REQUIRE(x2 == 4);
0458     
0459     // Simulate a _second_ FactorySet containing fresh instances of the same two JFactories, 
0460     auto p3 = sut.SetDefaultParameter("my_param_name", x3, "Tests how conflicting defaults are handled");
0461     REQUIRE(p3->HasDefault() == true);
0462     REQUIRE(p3->IsDefault() == true);
0463     REQUIRE(p3->GetDefault() == "3"); // Should be the _latest_ default found
0464     REQUIRE(p3->GetValue() == "3"); // Should be the _latest_ default value
0465     REQUIRE(x3 == 3);
0466     auto p4 = sut.SetDefaultParameter("my_param_name", x4, "Tests how conflicting defaults are handled");
0467     REQUIRE(p4->HasDefault() == true);
0468     REQUIRE(p4->IsDefault() == true);
0469     REQUIRE(p4->GetDefault() == "4"); // Should be the _latest_ default value found
0470     REQUIRE(p4->GetValue() == "4"); // Should be the _latest_ default value
0471     REQUIRE(x4 == 4);
0472 
0473     sut.PrintParameters(2,1);
0474 }
0475 
0476 
0477 
0478 
0479 
0480 
0481 
0482