File indexing completed on 2025-01-18 10:17:42
0001
0002
0003
0004
0005 #include "catch.hpp"
0006 #include "JANA/JFactoryGenerator.h"
0007 #include <JANA/JMultifactory.h>
0008 #include <JANA/Services/JComponentManager.h>
0009 #include <JANA/JEvent.h>
0010
0011 namespace multifactory_tests {
0012
0013 struct A {
0014 float x, y;
0015 };
0016
0017 struct B {
0018 int en, rn;
0019 };
0020
0021 struct MyMultifactory : public JMultifactory {
0022
0023 bool m_set_wrong_output = false;
0024 int m_process_call_count = 0;
0025 int m_init_call_count = 0;
0026
0027 public:
0028 MyMultifactory(bool set_wrong_output=false) : m_set_wrong_output(set_wrong_output) {
0029 DeclareOutput<A>("first");
0030 DeclareOutput<B>("second");
0031 }
0032
0033 void Init() override {
0034 auto app = GetApplication();
0035 REQUIRE(app != nullptr);
0036 m_init_call_count += 1;
0037 }
0038
0039 void Process(const std::shared_ptr<const JEvent>&) override {
0040 REQUIRE(GetApplication() != nullptr);
0041 m_process_call_count += 1;
0042 std::vector<A*> as;
0043 std::vector<B*> bs;
0044 as.push_back(new A {3.3, 4.4});
0045 as.push_back(new A {5.5, 6.6});
0046 bs.push_back(new B {1,1});
0047 SetData("first", as);
0048 SetData("second", bs);
0049 if (m_set_wrong_output) SetData("third", bs);
0050 }
0051 };
0052
0053 TEST_CASE("MultiFactoryTests") {
0054 JApplication app;
0055
0056
0057 SECTION("Calling from JEvent") {
0058 auto sut = new MyMultifactory(false);
0059 sut->SetApplication(&app);
0060 auto event = std::make_shared<JEvent>(&app);
0061 auto fs = new JFactorySet;
0062 fs->Add(sut);
0063 event->SetFactorySet(fs);
0064 auto as = event->Get<A>("first");
0065 REQUIRE(as.size() == 2);
0066 REQUIRE(as[1]->x == 5.5);
0067
0068 auto bs = event->Get<B>("second");
0069 REQUIRE(bs.size() == 1);
0070 REQUIRE(bs[0]->en == 1);
0071 }
0072
0073 SECTION("Multifactory sets the wrong data") {
0074 auto sut = new MyMultifactory(true);
0075 sut->SetApplication(&app);
0076 auto event = std::make_shared<JEvent>(&app);
0077 auto fs = new JFactorySet;
0078 fs->Add(sut);
0079 event->SetFactorySet(fs);
0080 REQUIRE_THROWS(event->Get<A>("first"));
0081 }
0082
0083 SECTION("Multifactories work with JFactoryGeneratorT") {
0084 app.Add(new JFactoryGeneratorT<MyMultifactory>());
0085 auto event = std::make_shared<JEvent>(&app);
0086 auto as = event->Get<A>("first");
0087 REQUIRE(as.size() == 2);
0088 REQUIRE(as[1]->x == 5.5);
0089 }
0090
0091 SECTION("Test that multifactory Process() is only called once") {
0092 app.Add(new JFactoryGeneratorT<MyMultifactory>());
0093 auto event = std::make_shared<JEvent>(&app);
0094
0095 auto helper_fac = dynamic_cast<JMultifactoryHelper<A>*>(event->GetFactory<A>("first"));
0096 REQUIRE(helper_fac != nullptr);
0097 auto sut = dynamic_cast<MyMultifactory*>(helper_fac->GetMultifactory());
0098 REQUIRE(sut != nullptr);
0099
0100 REQUIRE(sut->m_process_call_count == 0);
0101 REQUIRE(sut->m_init_call_count == 0);
0102
0103 auto as = event->Get<A>("first");
0104 REQUIRE(as.size() == 2);
0105 REQUIRE(as[1]->x == 5.5);
0106 REQUIRE(sut->m_init_call_count == 1);
0107 REQUIRE(sut->m_process_call_count == 1);
0108
0109 auto bs = event->Get<B>("second");
0110 REQUIRE(bs.size() == 1);
0111 REQUIRE(bs[0]->en == 1);
0112 REQUIRE(sut->m_init_call_count == 1);
0113 REQUIRE(sut->m_process_call_count == 1);
0114
0115 as = event->Get<A>("first");
0116 REQUIRE(as.size() == 2);
0117 REQUIRE(as[1]->x == 5.5);
0118 REQUIRE(sut->m_init_call_count == 1);
0119 REQUIRE(sut->m_process_call_count == 1);
0120 }
0121
0122 }
0123
0124 }