File indexing completed on 2025-10-17 09:11:23
0001
0002
0003
0004
0005
0006 #include "JANA/Components/JComponentFwd.h"
0007 #include "JANA/JApplicationFwd.h"
0008 #include "JANA/JFactory.h"
0009 #include "catch.hpp"
0010 #include "JFactoryTests.h"
0011
0012 #include <JANA/JEvent.h>
0013 #include <JANA/JFactoryT.h>
0014
0015 TEST_CASE("JFactoryTests") {
0016
0017
0018 SECTION("CreateAndGetData calls Init, ChangeRun, and Process as needed") {
0019
0020 JFactoryTestDummyFactory sut;
0021 auto event = std::make_shared<JEvent>();
0022
0023
0024 sut.CreateAndGetData(event);
0025 REQUIRE(sut.init_call_count == 1);
0026 REQUIRE(sut.change_run_call_count == 1);
0027 REQUIRE(sut.process_call_count == 1);
0028
0029
0030
0031 sut.CreateAndGetData(event);
0032 REQUIRE(sut.init_call_count == 1);
0033 REQUIRE(sut.change_run_call_count == 1);
0034 REQUIRE(sut.process_call_count == 1);
0035
0036
0037 sut.ClearData();
0038 sut.CreateAndGetData(event);
0039 REQUIRE(sut.init_call_count == 1);
0040 REQUIRE(sut.change_run_call_count == 1);
0041 REQUIRE(sut.process_call_count == 2);
0042
0043 sut.ClearData();
0044 }
0045
0046 SECTION("If no factory is present and nothing inserted, GetObjects called") {
0047
0048
0049
0050 auto event = std::make_shared<JEvent>();
0051 JFactoryTestDummySource sut;
0052
0053
0054 event->GetFactorySet()->Add(new JFactoryT<JFactoryTestDummyObject>());
0055 event->SetJEventSource(&sut);
0056
0057 auto data = event->Get<JFactoryTestDummyObject>("");
0058 REQUIRE(data[0]->data == 8);
0059 REQUIRE(data[1]->data == 88);
0060 }
0061
0062 SECTION("ChangeRun called only when run number changes") {
0063 auto event = std::make_shared<JEvent>();
0064 JFactoryTestDummyFactory sut;
0065
0066
0067 event->SetEventNumber(1);
0068 event->SetRunNumber(22);
0069 sut.CreateAndGetData(event);
0070 REQUIRE(sut.change_run_call_count == 1);
0071
0072
0073 event->SetEventNumber(2);
0074 sut.ClearData();
0075 sut.CreateAndGetData(event);
0076
0077 event->SetEventNumber(3);
0078 sut.ClearData();
0079 sut.CreateAndGetData(event);
0080 REQUIRE(sut.change_run_call_count == 1);
0081
0082
0083 event->SetEventNumber(4);
0084 event->SetRunNumber(49);
0085 sut.ClearData();
0086 sut.CreateAndGetData(event);
0087 REQUIRE(sut.change_run_call_count == 2);
0088
0089
0090 event->SetEventNumber(5);
0091 event->SetRunNumber(6180);
0092 sut.ClearData();
0093 sut.CreateAndGetData(event);
0094 REQUIRE(sut.change_run_call_count == 3);
0095
0096 sut.ClearData();
0097 }
0098
0099 SECTION("not PERSISTENT && not NOT_OBJECT_OWNER => JObject is cleared and deleted") {
0100 auto event = std::make_shared<JEvent>();
0101 JFactoryT<JFactoryTestDummyObject> sut;
0102 bool deleted_flag = false;
0103 sut.ClearFactoryFlag(JFactory::PERSISTENT);
0104 sut.ClearFactoryFlag(JFactory::NOT_OBJECT_OWNER);
0105 sut.Insert(new JFactoryTestDummyObject(42, &deleted_flag));
0106 sut.ClearData();
0107 auto results = sut.CreateAndGetData(event);
0108 REQUIRE(std::distance(results.first, results.second) == 0);
0109 REQUIRE(deleted_flag == true);
0110 }
0111
0112 SECTION("not PERSISTENT && NOT_OBJECT_OWNER => JObject is cleared but not deleted") {
0113 auto event = std::make_shared<JEvent>();
0114 JFactoryT<JFactoryTestDummyObject> sut;
0115 bool deleted_flag = false;
0116 sut.ClearFactoryFlag(JFactory::PERSISTENT);
0117 sut.SetFactoryFlag(JFactory::NOT_OBJECT_OWNER);
0118 auto* obj = new JFactoryTestDummyObject(42, &deleted_flag);
0119 sut.Insert(obj);
0120 sut.ClearData();
0121 auto results = sut.CreateAndGetData(event);
0122 REQUIRE(std::distance(results.first, results.second) == 0);
0123 REQUIRE(deleted_flag == false);
0124 delete obj;
0125 REQUIRE(deleted_flag == true);
0126 }
0127
0128 SECTION("PERSISTENT && not NOT_OBJECT_OWNER => JObject is neither cleared nor deleted") {
0129 JFactoryT<JFactoryTestDummyObject> sut;
0130 auto event = std::make_shared<JEvent>();
0131 bool deleted_flag = false;
0132 sut.SetFactoryFlag(JFactory::PERSISTENT);
0133 sut.ClearFactoryFlag(JFactory::NOT_OBJECT_OWNER);
0134 auto* obj = new JFactoryTestDummyObject(42, &deleted_flag);
0135 sut.Insert(obj);
0136 sut.ClearData();
0137 auto results = sut.CreateAndGetData(event);
0138 REQUIRE(std::distance(results.first, results.second) == 1);
0139 REQUIRE(deleted_flag == false);
0140 delete obj;
0141 REQUIRE(deleted_flag == true);
0142 }
0143
0144 SECTION("PERSISTENT && NOT_OBJECT_OWNER => JObject is neither cleared nor deleted") {
0145 JFactoryT<JFactoryTestDummyObject> sut;
0146 auto event = std::make_shared<JEvent>();
0147 bool deleted_flag = false;
0148 sut.SetFactoryFlag(JFactory::PERSISTENT);
0149 sut.SetFactoryFlag(JFactory::NOT_OBJECT_OWNER);
0150 auto* obj = new JFactoryTestDummyObject(42, &deleted_flag);
0151 sut.Insert(obj);
0152 sut.ClearData();
0153 auto results = sut.CreateAndGetData(event);
0154 REQUIRE(std::distance(results.first, results.second) == 1);
0155 REQUIRE(deleted_flag == false);
0156 delete obj;
0157 REQUIRE(deleted_flag == true);
0158 }
0159
0160 struct Issue135Factory : public JFactoryT<JFactoryTestDummyObject> {
0161 void Process(const std::shared_ptr<const JEvent>&) override {
0162 mData.emplace_back(new JFactoryTestDummyObject(3));
0163 mData.emplace_back(new JFactoryTestDummyObject(4));
0164 mData.emplace_back(new JFactoryTestDummyObject(5));
0165 Set(mData);
0166 }
0167 };
0168 SECTION("Issue 135: Users modifying mData directly and calling Set() afterwards") {
0169
0170
0171
0172
0173
0174
0175
0176 Issue135Factory sut;
0177 auto event = std::make_shared<JEvent>();
0178 auto results = sut.CreateAndGetData(event);
0179 REQUIRE(sut.GetNumObjects() == 3);
0180 REQUIRE(std::distance(results.first, results.second) == 3);
0181
0182 int data = 3;
0183 for (auto it = results.first; it != results.second; ++it ) {
0184 REQUIRE((*it)->data == data);
0185 data++;
0186 }
0187 sut.ClearData();
0188 }
0189
0190 struct RegenerateFactory : public JFactoryT<JFactoryTestDummyObject> {
0191 RegenerateFactory() {
0192 SetRegenerateFlag(true);
0193 }
0194 void Process(const std::shared_ptr<const JEvent>&) override {
0195 mData.emplace_back(new JFactoryTestDummyObject(49));
0196 Set(mData);
0197 }
0198 };
0199
0200 SECTION("Factory regeneration") {
0201 RegenerateFactory sut;
0202 auto event = std::make_shared<JEvent>();
0203
0204 std::vector<JFactoryTestDummyObject*> inserted_data;
0205 inserted_data.push_back(new JFactoryTestDummyObject(22));
0206 inserted_data.push_back(new JFactoryTestDummyObject(618));
0207 sut.Set(inserted_data);
0208
0209 REQUIRE(sut.GetStatus() == JFactory::Status::Inserted);
0210
0211 auto results = sut.CreateAndGetData(event);
0212 auto it = results.first;
0213 REQUIRE((*it)->data == 49);
0214 REQUIRE(sut.GetNumObjects() == 1);
0215
0216 sut.ClearData();
0217 }
0218
0219 SECTION("Exception in JFactory::Process") {
0220 LOG << "JFactoryTests: Exception in JFactory::Process" << LOG_END;
0221 auto event = std::make_shared<JEvent>();
0222 JFactoryTestExceptingFactory fac;
0223 REQUIRE(fac.GetStatus() == JFactory::Status::Uninitialized);
0224 REQUIRE_THROWS(fac.CreateAndGetData(event));
0225
0226 REQUIRE(fac.GetStatus() == JFactory::Status::Excepted);
0227 REQUIRE_THROWS(fac.CreateAndGetData(event));
0228 }
0229
0230 SECTION("Exception in JFactory::Init") {
0231 LOG << "JFactoryTests: Exception in JFactory::Init" << LOG_END;
0232 auto event = std::make_shared<JEvent>();
0233 JFactoryTestExceptingInInitFactory fac;
0234 REQUIRE(fac.GetStatus() == JFactory::Status::Uninitialized);
0235 REQUIRE_THROWS(fac.CreateAndGetData(event));
0236
0237 REQUIRE(fac.GetStatus() == JFactory::Status::Uninitialized);
0238 REQUIRE_THROWS(fac.CreateAndGetData(event));
0239 }
0240 }
0241
0242
0243 struct MyExceptingFactory : public JFactoryT<JFactoryTestDummyObject> {
0244 void Process(const std::shared_ptr<const JEvent>&) override {
0245 throw std::runtime_error("Weird mystery!");
0246 }
0247 };
0248
0249 TEST_CASE("JFactory_Exception") {
0250 JApplication app;
0251 app.Add(new JEventSource);
0252 app.Add(new JFactoryGeneratorT<MyExceptingFactory>());
0253 app.SetParameterValue("autoactivate", "JFactoryTestDummyObject");
0254 bool found_throw = false;
0255 try {
0256 app.Run();
0257 }
0258 catch(JException& ex) {
0259 LOG << ex << LOG_END;
0260 REQUIRE(ex.function_name == "JFactory::Process");
0261 REQUIRE(ex.message == "Weird mystery!");
0262 REQUIRE(ex.exception_type == "std::runtime_error");
0263 REQUIRE(ex.type_name == "MyExceptingFactory");
0264 REQUIRE(ex.instance_name == "JFactoryTestDummyObject");
0265 found_throw = true;
0266 }
0267 REQUIRE(found_throw == true);
0268 }
0269
0270 struct ExceptingInitFactory : public JFactoryT<JFactoryTestDummyObject> {
0271 void Init() override {
0272 throw std::runtime_error("Exception in Init");
0273 }
0274 void Process(const std::shared_ptr<const JEvent>&) override {
0275 throw std::runtime_error("Exception in Process");
0276 }
0277 };
0278
0279 TEST_CASE("JFactoryTests_ExceptingInitCalledTwice") {
0280 JApplication app;
0281 app.SetParameterValue("jana:loglevel", "error");
0282 app.Add(new JFactoryGeneratorT<ExceptingInitFactory>());
0283 auto event = std::make_shared<JEvent>(&app);
0284
0285 bool found_throw = false;
0286 try {
0287 event->Get<JFactoryTestDummyObject>();
0288 }
0289 catch(JException& ex) {
0290 LOG << ex << LOG_END;
0291 REQUIRE(ex.function_name == "JFactory::Init");
0292 REQUIRE(ex.message == "Exception in Init");
0293 REQUIRE(ex.exception_type == "std::runtime_error");
0294 REQUIRE(ex.type_name == "ExceptingInitFactory");
0295 REQUIRE(ex.instance_name == "JFactoryTestDummyObject");
0296 found_throw = true;
0297 }
0298 REQUIRE(found_throw == true);
0299
0300
0301 found_throw = false;
0302 try {
0303 event->Get<JFactoryTestDummyObject>();
0304 }
0305 catch(JException& ex) {
0306 LOG << ex << LOG_END;
0307 REQUIRE(ex.function_name == "JFactory::Init");
0308 REQUIRE(ex.message == "Exception in Init");
0309 REQUIRE(ex.exception_type == "std::runtime_error");
0310 REQUIRE(ex.type_name == "ExceptingInitFactory");
0311 REQUIRE(ex.instance_name == "JFactoryTestDummyObject");
0312 found_throw = true;
0313 }
0314 REQUIRE(found_throw == true);
0315 }
0316
0317
0318 struct MyLoggedFactory : public JFactoryT<JFactoryTestDummyObject> {
0319 MyLoggedFactory() {
0320 SetPrefix("myfac");
0321 }
0322 void Process(const std::shared_ptr<const JEvent>&) override {
0323 LOG_INFO(GetLogger()) << "Process ran!" << LOG_END;
0324 REQUIRE(GetLogger().level == JLogger::Level::DEBUG);
0325 }
0326 };
0327 TEST_CASE("JFactory_Logger") {
0328 JApplication app;
0329 app.Add(new JEventSource);
0330 app.Add(new JFactoryGeneratorT<MyLoggedFactory>());
0331 app.SetParameterValue("jana:loglevel", "off");
0332 app.SetParameterValue("myfac:loglevel", "debug");
0333 app.SetParameterValue("jana:nevents", "1");
0334 app.SetParameterValue("autoactivate", "JFactoryTestDummyObject");
0335 app.Run();
0336 }
0337
0338 std::vector<std::string> factory_with_finish_log;
0339
0340 struct SourceWithRunNumberChange : public JEventSource {
0341 SourceWithRunNumberChange() {
0342 SetCallbackStyle(CallbackStyle::ExpertMode);
0343 }
0344 Result Emit(JEvent& event) {
0345 if (GetEmittedEventCount() < 2) {
0346 event.SetRunNumber(48);
0347 }
0348 else {
0349 event.SetRunNumber(49);
0350 }
0351 return Result::Success;
0352 }
0353 };
0354
0355 struct FactoryWithFinish : public JFactoryT<JFactoryTestDummyObject> {
0356 Parameter<bool> except_on_init {this, "except_on_init", false, "Except on init"};
0357 Parameter<bool> except_on_beginrun {this, "except_on_beginrun", false, "Except on beginrun"};
0358 Parameter<bool> except_on_process {this, "except_on_process", false, "Except on process"};
0359 Parameter<bool> except_on_endrun {this, "except_on_endrun", false, "Except on endrun"};
0360 Parameter<bool> except_on_finish {this, "except_on_finish", false, "Except on finish"};
0361
0362 void Init() override {
0363 LOG_INFO(GetLogger()) << "FactoryWithFinish::Init: " << this << LOG_END;
0364 factory_with_finish_log.push_back("init");
0365 if (*except_on_init) throw std::runtime_error("Mystery");
0366 }
0367 void BeginRun(const std::shared_ptr<const JEvent>&) override {
0368 LOG_INFO(GetLogger()) << "FactoryWithFinish::BeginRun: " << this << LOG_END;
0369 factory_with_finish_log.push_back("beginrun");
0370 if (*except_on_beginrun) throw std::runtime_error("Mystery");
0371 }
0372 void Process(const std::shared_ptr<const JEvent>&) override {
0373 LOG_INFO(GetLogger()) << "FactoryWithFinish::Process: " << this << LOG_END;
0374 factory_with_finish_log.push_back("process");
0375 if (*except_on_process) throw std::runtime_error("Mystery");
0376 }
0377 void EndRun() override {
0378 LOG_INFO(GetLogger()) << "FactoryWithFinish::EndRun: " << this << LOG_END;
0379 factory_with_finish_log.push_back("endrun");
0380 if (*except_on_endrun) throw std::runtime_error("Mystery");
0381 }
0382 void Finish() override {
0383 LOG_INFO(GetLogger()) << "FactoryWithFinish::Finish: " << this << LOG_END;
0384 factory_with_finish_log.push_back("finish");
0385 if (*except_on_finish) throw std::runtime_error("Mystery");
0386 }
0387 };
0388
0389 TEST_CASE("JFactory_CallbackSequence") {
0390 JApplication app;
0391 app.Add(new JFactoryGeneratorT<FactoryWithFinish>());
0392 app.SetParameterValue("autoactivate", "JFactoryTestDummyObject");
0393 app.SetParameterValue("jana:max_inflight_events", 1);
0394
0395 SECTION("NoRunNumber") {
0396 app.Add(new JEventSource);
0397 app.SetParameterValue("jana:nevents", 2);
0398 app.Initialize();
0399 factory_with_finish_log.clear();
0400 app.Run();
0401 for (auto& s : factory_with_finish_log) {
0402 std::cout << s << std::endl;
0403 }
0404 REQUIRE(factory_with_finish_log.size() == 6);
0405 REQUIRE(factory_with_finish_log.at(0) == "init");
0406 REQUIRE(factory_with_finish_log.at(1) == "beginrun");
0407 REQUIRE(factory_with_finish_log.at(2) == "process");
0408 REQUIRE(factory_with_finish_log.at(3) == "process");
0409 REQUIRE(factory_with_finish_log.at(4) == "endrun");
0410 REQUIRE(factory_with_finish_log.at(5) == "finish");
0411 }
0412 SECTION("ConstantRunNumber") {
0413 app.Add(new SourceWithRunNumberChange);
0414 app.SetParameterValue("jana:nevents", 2);
0415 app.Initialize();
0416 factory_with_finish_log.clear();
0417 app.Run();
0418 REQUIRE(factory_with_finish_log.size() == 6);
0419 REQUIRE(factory_with_finish_log.at(0) == "init");
0420 REQUIRE(factory_with_finish_log.at(1) == "beginrun");
0421 REQUIRE(factory_with_finish_log.at(2) == "process");
0422 REQUIRE(factory_with_finish_log.at(3) == "process");
0423 REQUIRE(factory_with_finish_log.at(4) == "endrun");
0424 REQUIRE(factory_with_finish_log.at(5) == "finish");
0425 }
0426 SECTION("MultipleRunNumbers") {
0427 app.Add(new SourceWithRunNumberChange);
0428 app.SetParameterValue("jana:nevents", 5);
0429 app.Initialize();
0430 factory_with_finish_log.clear();
0431 app.Run();
0432 REQUIRE(factory_with_finish_log.size() == 11);
0433 REQUIRE(factory_with_finish_log.at(0) == "init");
0434 REQUIRE(factory_with_finish_log.at(1) == "beginrun");
0435 REQUIRE(factory_with_finish_log.at(2) == "process");
0436 REQUIRE(factory_with_finish_log.at(3) == "process");
0437 REQUIRE(factory_with_finish_log.at(4) == "endrun");
0438 REQUIRE(factory_with_finish_log.at(5) == "beginrun");
0439 REQUIRE(factory_with_finish_log.at(6) == "process");
0440 REQUIRE(factory_with_finish_log.at(7) == "process");
0441 REQUIRE(factory_with_finish_log.at(8) == "process");
0442 REQUIRE(factory_with_finish_log.at(9) == "endrun");
0443 REQUIRE(factory_with_finish_log.at(10) == "finish");
0444 }
0445 }
0446
0447 TEST_CASE("JFactory_ExceptionHandling") {
0448 JApplication app;
0449 app.Add(new JFactoryGeneratorT<FactoryWithFinish>());
0450 app.SetParameterValue("autoactivate", "JFactoryTestDummyObject");
0451 app.SetParameterValue("jana:max_inflight_events", 1);
0452
0453 SECTION("ExceptOnInit") {
0454 app.Add(new SourceWithRunNumberChange);
0455 app.SetParameterValue("jana:nevents", 2);
0456 app.SetParameterValue("JFactoryTestDummyObject:except_on_init", true);
0457 app.Initialize();
0458 factory_with_finish_log.clear();
0459 bool found_throw = false;
0460 try {
0461 app.Run();
0462 }
0463 catch(JException& ex) {
0464 LOG << ex << LOG_END;
0465 REQUIRE(ex.function_name == "JFactory::Init");
0466 REQUIRE(ex.message == "Mystery");
0467 REQUIRE(ex.exception_type == "std::runtime_error");
0468 REQUIRE(ex.type_name == "FactoryWithFinish");
0469 REQUIRE(ex.instance_name == "JFactoryTestDummyObject");
0470 found_throw = true;
0471 }
0472 REQUIRE(found_throw == true);
0473 REQUIRE(factory_with_finish_log.size() == 1);
0474 REQUIRE(factory_with_finish_log.at(0) == "init");
0475 }
0476
0477 SECTION("ExceptOnBeginRun") {
0478 app.Add(new SourceWithRunNumberChange);
0479 app.SetParameterValue("jana:nevents", 2);
0480 app.SetParameterValue("JFactoryTestDummyObject:except_on_beginrun", true);
0481 app.Initialize();
0482 factory_with_finish_log.clear();
0483 bool found_throw = false;
0484 try {
0485 app.Run();
0486 }
0487 catch(JException& ex) {
0488 LOG << ex << LOG_END;
0489 REQUIRE(ex.function_name == "JFactory::BeginRun");
0490 REQUIRE(ex.message == "Mystery");
0491 REQUIRE(ex.exception_type == "std::runtime_error");
0492 REQUIRE(ex.type_name == "FactoryWithFinish");
0493 REQUIRE(ex.instance_name == "JFactoryTestDummyObject");
0494 found_throw = true;
0495 }
0496 REQUIRE(found_throw == true);
0497 REQUIRE(factory_with_finish_log.size() == 2);
0498 REQUIRE(factory_with_finish_log.at(0) == "init");
0499 REQUIRE(factory_with_finish_log.at(1) == "beginrun");
0500 }
0501
0502 SECTION("ExceptOnProcess") {
0503 app.Add(new SourceWithRunNumberChange);
0504 app.SetParameterValue("jana:nevents", 2);
0505 app.SetParameterValue("JFactoryTestDummyObject:except_on_process", true);
0506 app.Initialize();
0507 factory_with_finish_log.clear();
0508 bool found_throw = false;
0509 try {
0510 app.Run();
0511 }
0512 catch(JException& ex) {
0513 LOG << ex << LOG_END;
0514 REQUIRE(ex.function_name == "JFactory::Process");
0515 REQUIRE(ex.message == "Mystery");
0516 REQUIRE(ex.exception_type == "std::runtime_error");
0517 REQUIRE(ex.type_name == "FactoryWithFinish");
0518 REQUIRE(ex.instance_name == "JFactoryTestDummyObject");
0519 found_throw = true;
0520 }
0521 REQUIRE(found_throw == true);
0522 REQUIRE(factory_with_finish_log.size() == 3);
0523 REQUIRE(factory_with_finish_log.at(0) == "init");
0524 REQUIRE(factory_with_finish_log.at(1) == "beginrun");
0525 REQUIRE(factory_with_finish_log.at(2) == "process");
0526 }
0527
0528 SECTION("ExceptOnEndRun") {
0529 app.Add(new SourceWithRunNumberChange);
0530 app.SetParameterValue("jana:nevents", 2);
0531 app.SetParameterValue("JFactoryTestDummyObject:except_on_endrun", true);
0532 app.Initialize();
0533 factory_with_finish_log.clear();
0534 bool found_throw = false;
0535 try {
0536 app.Run();
0537 }
0538 catch(JException& ex) {
0539 LOG << ex << LOG_END;
0540 REQUIRE(ex.function_name == "JFactory::EndRun");
0541 REQUIRE(ex.message == "Mystery");
0542 REQUIRE(ex.exception_type == "std::runtime_error");
0543 REQUIRE(ex.type_name == "FactoryWithFinish");
0544 REQUIRE(ex.instance_name == "JFactoryTestDummyObject");
0545 found_throw = true;
0546 }
0547 REQUIRE(found_throw == true);
0548 REQUIRE(factory_with_finish_log.size() == 5);
0549 REQUIRE(factory_with_finish_log.at(0) == "init");
0550 REQUIRE(factory_with_finish_log.at(1) == "beginrun");
0551 REQUIRE(factory_with_finish_log.at(2) == "process");
0552 REQUIRE(factory_with_finish_log.at(3) == "process");
0553 REQUIRE(factory_with_finish_log.at(4) == "endrun");
0554 }
0555 SECTION("ExceptOnFinish") {
0556 app.Add(new SourceWithRunNumberChange);
0557 app.SetParameterValue("jana:nevents", 2);
0558 app.SetParameterValue("JFactoryTestDummyObject:except_on_finish", true);
0559 app.Initialize();
0560 factory_with_finish_log.clear();
0561 bool found_throw = false;
0562 try {
0563 app.Run();
0564 }
0565 catch(JException& ex) {
0566 LOG << ex << LOG_END;
0567 REQUIRE(ex.function_name == "JFactory::Finish");
0568 REQUIRE(ex.message == "Mystery");
0569 REQUIRE(ex.exception_type == "std::runtime_error");
0570 REQUIRE(ex.type_name == "FactoryWithFinish");
0571 REQUIRE(ex.instance_name == "JFactoryTestDummyObject");
0572 found_throw = true;
0573 }
0574 REQUIRE(found_throw == true);
0575 REQUIRE(factory_with_finish_log.size() == 6);
0576 REQUIRE(factory_with_finish_log.at(0) == "init");
0577 REQUIRE(factory_with_finish_log.at(1) == "beginrun");
0578 REQUIRE(factory_with_finish_log.at(2) == "process");
0579 REQUIRE(factory_with_finish_log.at(3) == "process");
0580 REQUIRE(factory_with_finish_log.at(4) == "endrun");
0581 REQUIRE(factory_with_finish_log.at(5) == "finish");
0582 }
0583 }
0584
0585 TEST_CASE("JFactory_GetObjects_Caching") {
0586 JApplication app;
0587 app.Add(new JFactoryGeneratorT<JFactoryT<JFactoryTestDummyObject>>());
0588 app.Add(new JFactoryGeneratorT<JFactoryT<DifferentDummyObject>>());
0589 auto source = new JFactoryTestDummySource;
0590 app.Add(source);
0591 auto event = std::make_shared<JEvent>(&app);
0592 event->SetJEventSource(source);
0593
0594 SECTION("RepeatedGetObjectsAreCached") {
0595 auto dummies = event->Get<JFactoryTestDummyObject>();
0596 REQUIRE(dummies.at(0)->data == 8);
0597 REQUIRE(source->get_objects_count == 1);
0598 REQUIRE(source->get_objects_dummy_count == 1);
0599
0600 dummies = event->Get<JFactoryTestDummyObject>();
0601 REQUIRE(dummies.at(0)->data == 8);
0602 REQUIRE(source->get_objects_count == 1);
0603 REQUIRE(source->get_objects_dummy_count == 1);
0604 }
0605
0606 SECTION("DifferentGetObjectsAreNotCached") {
0607 auto dummies = event->Get<JFactoryTestDummyObject>();
0608 REQUIRE(dummies.at(0)->data == 8);
0609 REQUIRE(source->get_objects_count == 1);
0610 REQUIRE(source->get_objects_dummy_count == 1);
0611 REQUIRE(source->get_objects_different_count == 0);
0612
0613 auto different = event->Get<DifferentDummyObject>();
0614 REQUIRE(different.at(0)->E == 123.0);
0615 REQUIRE(source->get_objects_count == 2);
0616 REQUIRE(source->get_objects_dummy_count == 1);
0617 REQUIRE(source->get_objects_different_count == 1);
0618
0619 different = event->Get<DifferentDummyObject>();
0620 REQUIRE(different.at(0)->E == 123.0);
0621 REQUIRE(source->get_objects_count == 2);
0622 REQUIRE(source->get_objects_dummy_count == 1);
0623 REQUIRE(source->get_objects_different_count == 1);
0624 }
0625 }
0626
0627
0628 struct PersistentFactory: public JFactoryT<JFactoryTestDummyObject> {
0629 size_t processed_count = 0;
0630 PersistentFactory() {
0631 SetFactoryFlag(JFactory::PERSISTENT);
0632 }
0633
0634 void Process(const std::shared_ptr<const JEvent>& event) override {
0635 REQUIRE(processed_count == 0);
0636 processed_count += 1;
0637 event->Insert(new JFactoryTestDummyObject(22));
0638 }
0639
0640 void Finish() override {
0641 for (auto* item : mData) {
0642 delete item;
0643 }
0644 mData.clear();
0645 }
0646 };
0647
0648 TEST_CASE("PersistentFactory_Test") {
0649 JApplication app;
0650 app.Add(new JFactoryGeneratorT<PersistentFactory>());
0651 auto event = std::make_shared<JEvent>(&app);
0652
0653 auto data = event->Get<JFactoryTestDummyObject>();
0654 REQUIRE(data.size() == 1);
0655 REQUIRE(data.at(0)->data == 22);
0656
0657
0658 event->Clear();
0659 REQUIRE(data.size() == 1);
0660 REQUIRE(data.at(0)->data == 22);
0661
0662 event->Finish();
0663 }
0664
0665