#include #include #include "core/event.hpp" #include using namespace battlefield; // ==================== EventType / EventStatus 枚举 ==================== TEST(EventEnumTest, EventTypeToString) { EXPECT_STREQ(EventTypeToString(EventType::UNKNOWN), "UNKNOWN"); EXPECT_STREQ(EventTypeToString(EventType::INTEL), "INTEL"); EXPECT_STREQ(EventTypeToString(EventType::THREAT), "THREAT"); EXPECT_STREQ(EventTypeToString(EventType::MISSION), "MISSION"); EXPECT_STREQ(EventTypeToString(EventType::LOGISTIC), "LOGISTIC"); } TEST(EventEnumTest, EventStatusToString) { EXPECT_STREQ(EventStatusToString(EventStatus::PENDING), "PENDING"); EXPECT_STREQ(EventStatusToString(EventStatus::PROCESSING), "PROCESSING"); EXPECT_STREQ(EventStatusToString(EventStatus::RESOLVED), "RESOLVED"); EXPECT_STREQ(EventStatusToString(EventStatus::ARCHIVED), "ARCHIVED"); } // ==================== Event 结构体 ==================== TEST(EventStructTest, DefaultConstruction) { Event evt; EXPECT_EQ(evt.type, EventType::UNKNOWN); EXPECT_EQ(evt.priority, 0); EXPECT_EQ(evt.status, EventStatus::PENDING); EXPECT_TRUE(evt.id.empty()); EXPECT_TRUE(evt.location.empty()); EXPECT_TRUE(evt.source.empty()); EXPECT_TRUE(evt.summary.empty()); } // ==================== ReceiveEvent ==================== TEST(EventProcessorTest, ReceiveEventValidJson) { EventProcessor ep; bool ok = ep.ReceiveEvent( R"({"eventId":"evt_001","type":"intel","source":"drone","priority":7,"location":"zone-1","message":"test"})", "drone"); EXPECT_TRUE(ok); EXPECT_EQ(ep.GetEventCount(), 1u); } TEST(EventProcessorTest, ReceiveEventMultiple) { EventProcessor ep; ep.ReceiveEvent(R"({"eventId":"e1","type":"intel","priority":5})"); ep.ReceiveEvent(R"({"eventId":"e2","type":"threat","priority":9})"); ep.ReceiveEvent(R"({"eventId":"e3","type":"logistic","priority":3})"); EXPECT_EQ(ep.GetEventCount(), 3u); } TEST(EventProcessorTest, ReceiveEventInvalidJson) { EventProcessor ep; bool ok = ep.ReceiveEvent("not a json string{", "test"); EXPECT_FALSE(ok); EXPECT_EQ(ep.GetEventCount(), 0u); } TEST(EventProcessorTest, ReceiveEventWithIdField) { EventProcessor ep; ep.ReceiveEvent(R"({"id":"alt_id","type":"mission","priority":5})"); EXPECT_EQ(ep.GetEventCount(), 1u); auto events = ep.GetPendingEvents(); EXPECT_EQ(events[0].id, "alt_id"); } TEST(EventProcessorTest, ReceiveEventWithoutId) { EventProcessor ep; ep.ReceiveEvent(R"({"type":"threat","priority":8})"); EXPECT_EQ(ep.GetEventCount(), 1u); auto events = ep.GetPendingEvents(); EXPECT_TRUE(events[0].id.find("EVT-") != std::string::npos); } // ==================== TransformEvent ==================== TEST(EventProcessorTest, TransformEventFullFields) { EventProcessor ep; Event evt = ep.TransformEvent( R"({"eventId":"evt_full","type":"threat","source":"radar","priority":9,"location":"zone-alpha","message":"enemy detected","timestamp":1716700000})", "radar"); EXPECT_EQ(evt.id, "evt_full"); EXPECT_EQ(evt.type, EventType::THREAT); EXPECT_EQ(evt.priority, 9); EXPECT_EQ(evt.location, "zone-alpha"); EXPECT_EQ(evt.source, "radar"); EXPECT_EQ(evt.summary, "enemy detected"); } TEST(EventProcessorTest, TransformEventFloatTimestamp) { EventProcessor ep; Event evt = ep.TransformEvent( R"({"eventId":"evt_ts","timestamp":1234567890.5})"); EXPECT_EQ(evt.id, "evt_ts"); } TEST(EventProcessorTest, TransformEventIntegerTimestamp) { EventProcessor ep; Event evt = ep.TransformEvent( R"({"eventId":"evt_int","timestamp":1716700000})"); EXPECT_EQ(evt.id, "evt_int"); } TEST(EventProcessorTest, TransformEventMapExternalIntel) { EventProcessor ep; Event evt = ep.TransformEvent( R"({"id":"e1","eventType":"analysis_started","domain":"codegen"})"); EXPECT_EQ(evt.type, EventType::INTEL); } TEST(EventProcessorTest, TransformEventMapExternalThreat) { EventProcessor ep; Event evt = ep.TransformEvent( R"({"id":"e1","eventType":"error_occurred","domain":"generation"})"); EXPECT_EQ(evt.type, EventType::THREAT); } TEST(EventProcessorTest, TransformEventMapExternalMission) { EventProcessor ep; Event evt = ep.TransformEvent( R"({"id":"e1","eventType":"generation_start","domain":"codegen"})"); EXPECT_EQ(evt.type, EventType::MISSION); } TEST(EventProcessorTest, TransformEventMapExternalLogistic) { EventProcessor ep; Event evt = ep.TransformEvent( R"({"id":"e1","eventType":"done","domain":"generation","priority":3})"); EXPECT_EQ(evt.type, EventType::LOGISTIC); } TEST(EventProcessorTest, TransformEventWithoutTimestamp) { EventProcessor ep; Event evt = ep.TransformEvent(R"({"eventId":"no_ts"})"); EXPECT_EQ(evt.id, "no_ts"); // timestamp 应被设为当前时间 } TEST(EventProcessorTest, TransformEventClampPriorityLow) { EventProcessor ep; Event evt = ep.TransformEvent(R"({"eventId":"low","priority":-5})"); EXPECT_EQ(evt.priority, 1); } TEST(EventProcessorTest, TransformEventClampPriorityHigh) { EventProcessor ep; Event evt = ep.TransformEvent(R"({"eventId":"high","priority":999})"); EXPECT_EQ(evt.priority, 10); } TEST(EventProcessorTest, TransformEventWithStatus) { EventProcessor ep; Event evt = ep.TransformEvent(R"({"eventId":"s1","status":2})"); EXPECT_EQ(evt.status, EventStatus::RESOLVED); } // ==================== ValidateEventData ==================== TEST(EventProcessorTest, ValidateEventDataValid) { EventProcessor ep; nlohmann::json valid1 = {{"eventId", "evt_001"}}; EXPECT_TRUE(ep.ValidateEventData(valid1)); nlohmann::json valid2 = {{"id", "evt_002"}}; EXPECT_TRUE(ep.ValidateEventData(valid2)); } TEST(EventProcessorTest, ValidateEventDataInvalidEmptyId) { EventProcessor ep; nlohmann::json invalid = {{"eventId", ""}}; EXPECT_FALSE(ep.ValidateEventData(invalid)); } TEST(EventProcessorTest, ValidateEventDataInvalidLongId) { EventProcessor ep; nlohmann::json invalid = {{"eventId", std::string(300, 'x')}}; EXPECT_FALSE(ep.ValidateEventData(invalid)); } TEST(EventProcessorTest, ValidateEventDataNoId) { EventProcessor ep; nlohmann::json invalid = {{"type", "threat"}}; EXPECT_FALSE(ep.ValidateEventData(invalid)); } // ==================== LoadEventsFromFile ==================== TEST(EventProcessorTest, LoadEventsFromFile) { EventProcessor ep; size_t loaded = ep.LoadEventsFromFile("events.ndjson", 10); if (loaded > 0) { EXPECT_LE(loaded, 10u); auto events = ep.GetPendingEvents(); for (const auto& e : events) { EXPECT_FALSE(e.id.empty()); } } } TEST(EventProcessorTest, LoadEventsFromFileAll) { EventProcessor ep; size_t loaded = ep.LoadEventsFromFile("events.ndjson"); EXPECT_EQ(ep.GetEventCount(), loaded); auto events = ep.GetPendingEvents(); for (const auto& e : events) { EXPECT_FALSE(e.id.empty()); EXPECT_GE(e.priority, 1); EXPECT_LE(e.priority, 10); } } TEST(EventProcessorTest, LoadEventsFromFileNotFound) { EventProcessor ep; size_t loaded = ep.LoadEventsFromFile("nonexistent_file.ndjson"); EXPECT_EQ(loaded, 0u); EXPECT_EQ(ep.GetEventCount(), 0u); } // ==================== 查询方法 ==================== TEST(EventProcessorTest, GetPendingEventsNew) { EventProcessor ep; ep.ReceiveEvent(R"({"eventId":"e1","type":"intel","priority":5})"); ep.ReceiveEvent(R"({"eventId":"e2","type":"threat","priority":8})"); auto pending = ep.GetPendingEvents(); EXPECT_EQ(pending.size(), 2u); } TEST(EventProcessorTest, GetEventsByStatus) { EventProcessor ep; ep.ReceiveEvent(R"({"eventId":"e1","type":"intel","priority":5})"); ep.ReceiveEvent(R"({"eventId":"e2","type":"threat","priority":8})"); auto pending = ep.GetEventsByStatus(EventStatus::PENDING); EXPECT_EQ(pending.size(), 2u); auto resolved = ep.GetEventsByStatus(EventStatus::RESOLVED); EXPECT_EQ(resolved.size(), 0u); auto archived = ep.GetEventsByStatus(EventStatus::ARCHIVED); EXPECT_EQ(archived.size(), 0u); } // ==================== 排序 ==================== TEST(EventProcessorTest, SortByPriorityAscending) { EventProcessor ep; ep.ReceiveEvent(R"({"eventId":"e1","priority":3})"); ep.ReceiveEvent(R"({"eventId":"e2","priority":9})"); ep.ReceiveEvent(R"({"eventId":"e3","priority":5})"); ep.SortEventsByPriority(true); auto events = ep.GetPendingEvents(); EXPECT_EQ(events[0].priority, 3); EXPECT_EQ(events[1].priority, 5); EXPECT_EQ(events[2].priority, 9); } TEST(EventProcessorTest, SortByPriorityDescending) { EventProcessor ep; ep.ReceiveEvent(R"({"eventId":"e1","priority":3})"); ep.ReceiveEvent(R"({"eventId":"e2","priority":9})"); ep.ReceiveEvent(R"({"eventId":"e3","priority":5})"); ep.SortEventsByPriority(false); auto events = ep.GetPendingEvents(); EXPECT_EQ(events[0].priority, 9); EXPECT_EQ(events[1].priority, 5); EXPECT_EQ(events[2].priority, 3); } TEST(EventProcessorTest, SortByCustomComparator) { EventProcessor ep; ep.ReceiveEvent(R"({"eventId":"aaa","priority":5})"); ep.ReceiveEvent(R"({"eventId":"bbb","priority":5})"); ep.ReceiveEvent(R"({"eventId":"ccc","priority":5})"); ep.SortEventsBy([](const Event& a, const Event& b) { return a.id > b.id; // 按 ID 降序 }); auto events = ep.GetPendingEvents(); EXPECT_EQ(events[0].id, "ccc"); EXPECT_EQ(events[1].id, "bbb"); EXPECT_EQ(events[2].id, "aaa"); } // ==================== 筛选 ==================== TEST(EventProcessorTest, FilterByType) { EventProcessor ep; ep.ReceiveEvent(R"({"eventId":"e1","type":"intel","priority":5})"); ep.ReceiveEvent(R"({"eventId":"e2","type":"threat","priority":8})"); ep.ReceiveEvent(R"({"eventId":"e3","type":"intel","priority":3})"); auto intels = ep.FilterByType(EventType::INTEL); EXPECT_EQ(intels.size(), 2u); auto threats = ep.FilterByType(EventType::THREAT); EXPECT_EQ(threats.size(), 1u); auto missions = ep.FilterByType(EventType::MISSION); EXPECT_EQ(missions.size(), 0u); auto unknowns = ep.FilterByType(EventType::UNKNOWN); EXPECT_EQ(unknowns.size(), 0u); } TEST(EventProcessorTest, FilterByPriority) { EventProcessor ep; ep.ReceiveEvent(R"({"eventId":"e1","priority":1})"); ep.ReceiveEvent(R"({"eventId":"e2","priority":5})"); ep.ReceiveEvent(R"({"eventId":"e3","priority":10})"); auto low = ep.FilterByPriority(1, 3); EXPECT_EQ(low.size(), 1u); auto mid = ep.FilterByPriority(4, 7); EXPECT_EQ(mid.size(), 1u); auto high = ep.FilterByPriority(8, 10); EXPECT_EQ(high.size(), 1u); auto all = ep.FilterByPriority(1, 10); EXPECT_EQ(all.size(), 3u); auto none = ep.FilterByPriority(11, 20); EXPECT_EQ(none.size(), 0u); } TEST(EventProcessorTest, FilterBySource) { EventProcessor ep; ep.ReceiveEvent(R"({"eventId":"e1"})", "radar_a"); ep.ReceiveEvent(R"({"eventId":"e2"})", "radar_a"); ep.ReceiveEvent(R"({"eventId":"e3"})", "drone_x"); auto fromRadar = ep.FilterBySource("radar_a"); EXPECT_EQ(fromRadar.size(), 2u); auto fromDrone = ep.FilterBySource("drone_x"); EXPECT_EQ(fromDrone.size(), 1u); auto fromNone = ep.FilterBySource("nonexistent"); EXPECT_EQ(fromNone.size(), 0u); } // ==================== 状态流转 ==================== TEST(EventProcessorTest, MarkProcessingValid) { EventProcessor ep; ep.ReceiveEvent(R"({"eventId":"e1","priority":5})"); EXPECT_TRUE(ep.MarkProcessing("e1")); auto pending = ep.GetPendingEvents(); EXPECT_EQ(pending.size(), 0u); auto processing = ep.GetEventsByStatus(EventStatus::PROCESSING); EXPECT_EQ(processing.size(), 1u); } TEST(EventProcessorTest, MarkProcessingInvalid) { EventProcessor ep; EXPECT_FALSE(ep.MarkProcessing("nonexistent")); } TEST(EventProcessorTest, MarkResolved) { EventProcessor ep; ep.ReceiveEvent(R"({"eventId":"e1","priority":5})"); EXPECT_TRUE(ep.MarkResolved("e1")); auto resolved = ep.GetEventsByStatus(EventStatus::RESOLVED); EXPECT_EQ(resolved.size(), 1u); } TEST(EventProcessorTest, MarkResolvedInvalid) { EventProcessor ep; EXPECT_FALSE(ep.MarkResolved("nonexistent")); } TEST(EventProcessorTest, MarkArchived) { EventProcessor ep; ep.ReceiveEvent(R"({"eventId":"e1","priority":5})"); EXPECT_TRUE(ep.MarkArchived("e1")); auto archived = ep.GetEventsByStatus(EventStatus::ARCHIVED); EXPECT_EQ(archived.size(), 1u); } TEST(EventProcessorTest, MarkArchivedInvalid) { EventProcessor ep; EXPECT_FALSE(ep.MarkArchived("nonexistent")); } TEST(EventProcessorTest, FullLifecycle) { EventProcessor ep; ep.ReceiveEvent(R"({"eventId":"lifecycle","priority":5})"); // PENDING -> PROCESSING EXPECT_TRUE(ep.MarkProcessing("lifecycle")); EXPECT_EQ(ep.GetPendingEvents().size(), 0u); EXPECT_EQ(ep.GetEventsByStatus(EventStatus::PROCESSING).size(), 1u); // PROCESSING -> RESOLVED EXPECT_TRUE(ep.MarkResolved("lifecycle")); EXPECT_EQ(ep.GetEventsByStatus(EventStatus::RESOLVED).size(), 1u); // RESOLVED -> ARCHIVED EXPECT_TRUE(ep.MarkArchived("lifecycle")); EXPECT_EQ(ep.GetEventsByStatus(EventStatus::ARCHIVED).size(), 1u); } // ==================== Clear / GetEventCount ==================== TEST(EventProcessorTest, Clear) { EventProcessor ep; ep.ReceiveEvent(R"({"eventId":"e1"})"); ep.ReceiveEvent(R"({"eventId":"e2"})"); EXPECT_EQ(ep.GetEventCount(), 2u); ep.Clear(); EXPECT_EQ(ep.GetEventCount(), 0u); } // ==================== 边界和特殊情况 ==================== TEST(EventProcessorTest, EmptyProcessor) { EventProcessor ep; EXPECT_EQ(ep.GetEventCount(), 0u); EXPECT_TRUE(ep.GetPendingEvents().empty()); EXPECT_TRUE(ep.GetEventsByStatus(EventStatus::PENDING).empty()); } TEST(EventProcessorTest, PriorityDefaultsByType) { EventProcessor ep; Event threat = ep.TransformEvent(R"({"eventId":"t1","type":"threat"})"); EXPECT_EQ(threat.priority, 9); Event intel = ep.TransformEvent(R"({"eventId":"i1","type":"intel"})"); EXPECT_EQ(intel.priority, 7); Event mission = ep.TransformEvent(R"({"eventId":"m1","type":"mission"})"); EXPECT_EQ(mission.priority, 5); Event logistic = ep.TransformEvent(R"({"eventId":"l1","type":"logistic"})"); EXPECT_EQ(logistic.priority, 3); Event unknown = ep.TransformEvent(R"({"eventId":"u1","type":"other"})"); EXPECT_EQ(unknown.priority, 1); } TEST(EventProcessorTest, SummaryFromMessageField) { EventProcessor ep; Event evt = ep.TransformEvent(R"({"eventId":"s1","message":"test message"})"); EXPECT_EQ(evt.summary, "test message"); } TEST(EventProcessorTest, SummaryFromSummaryField) { EventProcessor ep; Event evt = ep.TransformEvent(R"({"eventId":"s1","summary":"override summary"})"); EXPECT_EQ(evt.summary, "override summary"); } TEST(EventProcessorTest, LocationDefault) { EventProcessor ep; Event evt = ep.TransformEvent(R"({"eventId":"loc"})"); EXPECT_EQ(evt.location, "unknown-zone"); }