/// @file basic_test.cpp /// @brief ETMS 核心模块单元测试(使用标准库 assert,无外部依赖)。 #include "app.hpp" #include #include #include #include /// @brief 测试事件状态枚举与字符串转换。 static void test_EventStatusToString() { std::cout << " [test] EventStatusToString ... "; assert(std::string(etms::EventStatusToString(etms::EventStatus::Received)) == "Received"); assert(std::string(etms::EventStatusToString(etms::EventStatus::Processed)) == "Processed"); assert(std::string(etms::EventStatusToString(etms::EventStatus::PendingTask)) == "Pending Task"); assert(std::string(etms::EventStatusToString(etms::EventStatus::Rejected)) == "Rejected"); assert(std::string(etms::EventStatusToString(etms::EventStatus::TaskGenerated)) == "Task Generated"); std::cout << "PASSED\n"; } /// @brief 测试接收原始事件(正常情况)。 static void test_ReceiveRawEvent_Valid() { std::cout << " [test] ReceiveRawEvent (valid JSON) ... "; const std::string json = R"({"event_id":"EVT-TEST-001","event_type":"侦察"})"; auto ack = etms::ReceiveRawEvent(json); assert(ack.accepted == true); assert(ack.event_id == "EVT-TEST-001"); assert(!ack.message.empty()); std::cout << "PASSED\n"; } /// @brief 测试接收原始事件(空载荷应拒绝)。 static void test_ReceiveRawEvent_Empty() { std::cout << " [test] ReceiveRawEvent (empty) ... "; auto ack = etms::ReceiveRawEvent(""); assert(ack.accepted == false); assert(ack.event_id.empty()); std::cout << "PASSED\n"; } /// @brief 测试接收原始事件(缺少 event_id 应拒绝)。 static void test_ReceiveRawEvent_MissingId() { std::cout << " [test] ReceiveRawEvent (missing event_id) ... "; const std::string json = R"({"event_type":"打击"})"; auto ack = etms::ReceiveRawEvent(json); assert(ack.accepted == false); std::cout << "PASSED\n"; } /// @brief 测试处理事件:状态从 Received → Processed。 static void test_ProcessEvent() { std::cout << " [test] ProcessEvent ... "; etms::Event evt; evt.event_id = "EVT-PROC-001"; evt.status = etms::EventStatus::Received; bool ok = etms::ProcessEvent(evt); assert(ok == true); assert(evt.status == etms::EventStatus::Processed); std::cout << "PASSED\n"; } /// @brief 测试处理事件:非 Received 状态不应被处理。 static void test_ProcessEvent_WrongStatus() { std::cout << " [test] ProcessEvent (wrong status) ... "; etms::Event evt; evt.status = etms::EventStatus::TaskGenerated; bool ok = etms::ProcessEvent(evt); assert(ok == false); assert(evt.status == etms::EventStatus::TaskGenerated); std::cout << "PASSED\n"; } /// @brief 测试事件查询返回非空列表。 static void test_QueryAllEvents() { std::cout << " [test] QueryAllEvents ... "; auto events = etms::QueryAllEvents(); assert(!events.empty()); // 默认应倒序(create_time 递减) for (size_t i = 1; i < events.size(); ++i) { assert(events[i - 1].create_time >= events[i].create_time); } std::cout << "PASSED (" << events.size() << " events)\n"; } /// @brief 测试紧迫事件筛选。 static void test_FilterUrgentEvents() { std::cout << " [test] FilterUrgentEvents ... "; auto events = etms::QueryAllEvents(); auto urgent = etms::FilterUrgentEvents(events); for (const auto& e : urgent) { assert(e.level >= 8); } assert(!urgent.empty()); std::cout << "PASSED (" << urgent.size() << " urgent)\n"; } /// @brief 测试模板推荐(匹配类型应返回对应模板 ID)。 static void test_RecommendTemplate() { std::cout << " [test] RecommendTemplate ... "; auto templates = etms::GetAvailableTemplates(); etms::Event recon_evt; recon_evt.event_type = "侦察"; auto id1 = etms::RecommendTemplate(recon_evt, templates); assert(id1 == "TMPL-RECON-001"); etms::Event strike_evt; strike_evt.event_type = "打击"; auto id2 = etms::RecommendTemplate(strike_evt, templates); assert(id2 == "TMPL-STRIKE-001"); // 不匹配类型时应返回兜底(第一个模板) etms::Event unknown_evt; unknown_evt.event_type = "未知"; auto id3 = etms::RecommendTemplate(unknown_evt, templates); assert(id3 == templates.front().template_id); std::cout << "PASSED\n"; } /// @brief 测试空模板列表时的推荐行为。 static void test_RecommendTemplate_EmptyTemplates() { std::cout << " [test] RecommendTemplate (empty list) ... "; std::vector empty; etms::Event evt; evt.event_type = "侦察"; auto id = etms::RecommendTemplate(evt, empty); assert(id.empty()); std::cout << "PASSED\n"; } /// @brief 测试任务请求组装。 static void test_BuildTaskRequest() { std::cout << " [test] BuildTaskRequest ... "; std::map params = {{"key1", "val1"}, {"key2", "val2"}}; auto req = etms::BuildTaskRequest("EVT-REQ-001", "TMPL-001", "KB-V1.0", params); assert(req.request_id.find("REQ-") == 0); assert(req.event_id == "EVT-REQ-001"); assert(req.template_id == "TMPL-001"); assert(req.kb_version_id == "KB-V1.0"); assert(req.params.size() == 2); assert(req.request_time > 0); std::cout << "PASSED\n"; } /// @brief 测试知识库版本查询。 static void test_GetAvailableKbVersions() { std::cout << " [test] GetAvailableKbVersions ... "; auto versions = etms::GetAvailableKbVersions(); assert(!versions.empty()); bool has_active = false; for (const auto& v : versions) { if (v.status == "Active") has_active = true; } assert(has_active); std::cout << "PASSED (" << versions.size() << " versions)\n"; } /// @brief 测试模板查询。 static void test_GetAvailableTemplates() { std::cout << " [test] GetAvailableTemplates ... "; auto templates = etms::GetAvailableTemplates(); assert(!templates.empty()); for (const auto& t : templates) { assert(!t.template_id.empty()); assert(!t.name.empty()); } std::cout << "PASSED (" << templates.size() << " templates)\n"; } /// @brief 测试事件状态推进机。 static void test_AdvanceEventStatus() { std::cout << " [test] AdvanceEventStatus ... "; etms::Event evt; evt.status = etms::EventStatus::Received; // Received → Processed assert(etms::AdvanceEventStatus(evt) == true); assert(evt.status == etms::EventStatus::Processed); // Processed → PendingTask assert(etms::AdvanceEventStatus(evt) == true); assert(evt.status == etms::EventStatus::PendingTask); // PendingTask → TaskGenerated assert(etms::AdvanceEventStatus(evt) == true); assert(evt.status == etms::EventStatus::TaskGenerated); // TaskGenerated → 不可再推进 assert(etms::AdvanceEventStatus(evt) == false); assert(evt.status == etms::EventStatus::TaskGenerated); std::cout << "PASSED\n"; } /// @brief 测试 Rejected 状态不可推进。 static void test_AdvanceEventStatus_Rejected() { std::cout << " [test] AdvanceEventStatus (Rejected) ... "; etms::Event evt; evt.status = etms::EventStatus::Rejected; assert(etms::AdvanceEventStatus(evt) == false); assert(evt.status == etms::EventStatus::Rejected); std::cout << "PASSED\n"; } /// @brief 测试排序函数(按等级降序)。 static void test_SortEventsByLevelDesc() { std::cout << " [test] SortEventsByLevelDesc ... "; auto events = etms::QueryAllEvents(); etms::SortEventsByLevelDesc(events); for (size_t i = 1; i < events.size(); ++i) { assert(events[i - 1].level >= events[i].level); } std::cout << "PASSED\n"; } /// @brief 测试排序函数(按时间升序)。 static void test_SortEventsByTimeAsc() { std::cout << " [test] SortEventsByTimeAsc ... "; auto events = etms::QueryAllEvents(); etms::SortEventsByTimeAsc(events); for (size_t i = 1; i < events.size(); ++i) { assert(events[i - 1].timestamp <= events[i].timestamp); } std::cout << "PASSED\n"; } /// @brief 主测试入口。 int main() { std::cout << "=== ETMS Basic Unit Tests ===\n\n"; test_EventStatusToString(); test_ReceiveRawEvent_Valid(); test_ReceiveRawEvent_Empty(); test_ReceiveRawEvent_MissingId(); test_ProcessEvent(); test_ProcessEvent_WrongStatus(); test_QueryAllEvents(); test_FilterUrgentEvents(); test_RecommendTemplate(); test_RecommendTemplate_EmptyTemplates(); test_BuildTaskRequest(); test_GetAvailableKbVersions(); test_GetAvailableTemplates(); test_AdvanceEventStatus(); test_AdvanceEventStatus_Rejected(); test_SortEventsByLevelDesc(); test_SortEventsByTimeAsc(); std::cout << "\n=== All " << 17 << " tests PASSED ===\n"; return 0; }