diff --git a/COLA.hh b/COLA.hh index b103456..455c7ff 100644 --- a/COLA.hh +++ b/COLA.hh @@ -193,8 +193,12 @@ namespace cola { "kName variable must be a string"); } - std::unique_ptr Create(const std::unordered_map& /* metaData */) override { - return std::make_unique(); + std::unique_ptr Create(const std::unordered_map& meta_data) override { + if constexpr (std::is_constructible_v) { + return std::make_unique(meta_data); + } else { + return std::make_unique(); + } } const std::string& GetFilterName() const final { return Filter::kName; } diff --git a/tests/cola_test.cc b/tests/cola_test.cc index 77d0bdc..ee6cca3 100644 --- a/tests/cola_test.cc +++ b/tests/cola_test.cc @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -116,6 +117,70 @@ class TestWriter : public VWriter { } }; +namespace { + + class ConfiguredConverter : public VConverter { + public: + // NOLINTNEXTLINE(bugprone-throwing-static-initialization) + static inline const std::string kName = "ConfiguredConverter"; + + explicit ConfiguredConverter(const std::unordered_map& parameters) + : factor_(std::stod(parameters.at("factor"))) {} + + std::unique_ptr operator()(std::unique_ptr&& data) override { + for (auto& particle : data->particles) { + particle.momentum.x *= factor_; + } + return std::move(data); + } + + private: + double factor_; + }; + + class OptionalConfiguredConverter : public ConfiguredConverter { + public: + OptionalConfiguredConverter() : ConfiguredConverter({{"factor", "1"}}) {} + using ConfiguredConverter::ConfiguredConverter; + }; + +} // namespace + +TEST(ColaFactory, MetadataConstructorPreferredOverDefault) { + GenericFactory factory; + auto filter = factory.Create({{"factor", "3"}}); + auto* converter = dynamic_cast(filter.get()); + ASSERT_NE(converter, nullptr); + TestGenerator generator; + const auto result = (*converter)(generator()); + EXPECT_DOUBLE_EQ(result->particles[0].momentum.x, 0.1 * 3); +} + +TEST(ColaFactory, InvalidMetadataPropagates) { + GenericFactory factory; + EXPECT_THROW(factory.Create({}), std::out_of_range); + EXPECT_THROW(factory.Create({{"factor", "invalid"}}), std::invalid_argument); +} + +TEST(ColaFactory, XmlConfiguresNonDefaultConstructibleFilter) { + auto xml = std::stringstream(R"( + + + + )"); + MetaProcessor processor; + processor.Register(std::make_unique>()); + processor.Register(std::make_unique>()); + processor.Register(std::make_unique>()); + auto ensemble = processor.Parse(xml); + auto* writer = dynamic_cast(ensemble.writer.get()); + ASSERT_NE(writer, nullptr); + ColaRunManager manager(std::move(ensemble)); + manager.Run(); + ASSERT_EQ(writer->recorded_events.size(), 1); + EXPECT_DOUBLE_EQ(writer->recorded_events[0]->particles[0].momentum.x, 0.4); +} + TEST(ColaPdgTest, CircularConsistency) { for (uint16_t atomic_mass = 1; atomic_mass < 100; ++atomic_mass) { for (uint16_t charge_number = 0; charge_number <= atomic_mass; ++charge_number) {