#include "fesa/analysis/analysis.h" #include #include #include #include #include namespace { using RunSignature = fesa::Status (fesa::Analysis::*)(const fesa::AnalysisRequest&); static_assert(std::has_virtual_destructor_v); static_assert(std::is_abstract_v); static_assert(std::is_same_v); class StatusAnalysis final : public fesa::Analysis { public: StatusAnalysis(bool& destroyed, fesa::Status result) : destroyed_{destroyed}, result_{std::move(result)} {} ~StatusAnalysis() override { destroyed_ = true; } fesa::Status Run(const fesa::AnalysisRequest& request) override { request_ = request; return result_; } const fesa::AnalysisRequest& Request() const noexcept { return request_; } private: bool& destroyed_; fesa::Status result_; fesa::AnalysisRequest request_; }; } // namespace TEST(Analysis, PropagatesStatusAndDestroysThroughMinimalAnalysis) { bool destroyed = false; const fesa::AnalysisRequest request{"model.inp", "results.h5"}; const fesa::Status failure = fesa::Status::Failure( fesa::FailureCategory::kSolver, {{fesa::Severity::kError, "analysis-test-failure", {}, "ANALYSIS", "", "The concrete procedure failure must propagate unchanged."}}); auto concrete = std::make_unique(destroyed, failure); StatusAnalysis* const concrete_observer = concrete.get(); std::unique_ptr analysis = std::move(concrete); const fesa::Status status = analysis->Run(request); ASSERT_FALSE(status.IsOk()); EXPECT_EQ(status.Category(), fesa::FailureCategory::kSolver); ASSERT_EQ(status.Diagnostics().size(), 1U); EXPECT_EQ(status.Diagnostics()[0U].code, "analysis-test-failure"); EXPECT_EQ(concrete_observer->Request().input_path, request.input_path); EXPECT_EQ(concrete_observer->Request().output_path, request.output_path); analysis.reset(); EXPECT_TRUE(destroyed); }