task_plan_2/tests/test_task_generator.cpp

383 lines
11 KiB
C++
Raw Permalink Normal View History

2026-05-26 05:33:17 +00:00
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "core/task.hpp"
using namespace battlefield;
// ==================== DraftStatus 枚举 ====================
TEST(TaskEnumTest, DraftStatusValues) {
EXPECT_EQ(static_cast<int>(DraftStatus::DRAFT), 0);
EXPECT_EQ(static_cast<int>(DraftStatus::SUBMITTED), 1);
EXPECT_EQ(static_cast<int>(DraftStatus::APPROVED), 2);
EXPECT_EQ(static_cast<int>(DraftStatus::REJECTED), 3);
}
// ==================== TaskDraft 结构体 ====================
TEST(TaskDraftTest, DefaultConstruction) {
TaskDraft draft;
EXPECT_TRUE(draft.id.empty());
EXPECT_TRUE(draft.title.empty());
EXPECT_TRUE(draft.description.empty());
EXPECT_EQ(draft.priority, 0);
EXPECT_EQ(draft.status, DraftStatus::DRAFT);
EXPECT_TRUE(draft.relatedEventId.empty());
EXPECT_TRUE(draft.taskType.empty());
EXPECT_TRUE(draft.requiredResources.empty());
}
// ==================== CreateTaskFromEvent (INTEL) ====================
TEST(TaskGeneratorTest, CreateIntelligenceTask) {
TaskGenerator tg;
Event evt;
evt.id = "EVT-INTEL-001";
evt.type = EventType::INTEL;
evt.priority = 6;
evt.location = "sector-7";
evt.source = "recon_unit";
TaskDraft draft = tg.CreateTaskFromEvent(evt);
EXPECT_EQ(draft.relatedEventId, "EVT-INTEL-001");
EXPECT_EQ(draft.taskType, "INTEL_ANALYSIS");
EXPECT_GE(draft.priority, 5);
EXPECT_EQ(draft.status, DraftStatus::DRAFT);
EXPECT_FALSE(draft.title.empty());
EXPECT_FALSE(draft.description.empty());
EXPECT_FALSE(draft.requiredResources.empty());
EXPECT_NE(draft.title.find("情报"), std::string::npos);
}
// ==================== CreateTaskFromEvent (THREAT) ====================
TEST(TaskGeneratorTest, CreateThreatTask) {
TaskGenerator tg;
Event evt;
evt.id = "EVT-THREAT-001";
evt.type = EventType::THREAT;
evt.priority = 8;
evt.location = "hot-zone";
evt.source = "early_warning";
TaskDraft draft = tg.CreateTaskFromEvent(evt);
EXPECT_EQ(draft.relatedEventId, "EVT-THREAT-001");
EXPECT_EQ(draft.taskType, "THREAT_RESPONSE");
EXPECT_EQ(draft.priority, 10); // 8+2 capped at 10
EXPECT_EQ(draft.status, DraftStatus::DRAFT);
EXPECT_FALSE(draft.title.empty());
EXPECT_FALSE(draft.requiredResources.empty());
}
// ==================== CreateTaskFromEvent (MISSION) ====================
TEST(TaskGeneratorTest, CreateMissionTask) {
TaskGenerator tg;
Event evt;
evt.id = "EVT-MISSION-001";
evt.type = EventType::MISSION;
evt.priority = 5;
evt.location = "battlefront";
TaskDraft draft = tg.CreateTaskFromEvent(evt);
EXPECT_EQ(draft.relatedEventId, "EVT-MISSION-001");
EXPECT_EQ(draft.taskType, "COMBAT_MISSION");
EXPECT_EQ(draft.priority, 5);
}
// ==================== CreateTaskFromEvent (LOGISTIC) ====================
TEST(TaskGeneratorTest, CreateLogisticTask) {
TaskGenerator tg;
Event evt;
evt.id = "EVT-LOG-001";
evt.type = EventType::LOGISTIC;
evt.priority = 6;
evt.location = "base-alpha";
TaskDraft draft = tg.CreateTaskFromEvent(evt);
EXPECT_EQ(draft.relatedEventId, "EVT-LOG-001");
EXPECT_EQ(draft.taskType, "LOGISTIC_SUPPORT");
EXPECT_EQ(draft.priority, 5); // 6-1
}
TEST(TaskGeneratorTest, CreateLogisticTaskLowPriority) {
TaskGenerator tg;
Event evt;
evt.id = "EVT-LOG-002";
evt.type = EventType::LOGISTIC;
evt.priority = 1;
TaskDraft draft = tg.CreateTaskFromEvent(evt);
EXPECT_EQ(draft.priority, 1); // max(1-1, 1)
}
// ==================== CreateTaskFromEvent (UNKNOWN) ====================
TEST(TaskGeneratorTest, CreateUnknownTypeTask) {
TaskGenerator tg;
Event evt;
evt.id = "EVT-UNK-001";
evt.type = EventType::UNKNOWN;
evt.priority = 4;
TaskDraft draft = tg.CreateTaskFromEvent(evt);
EXPECT_EQ(draft.relatedEventId, "EVT-UNK-001");
// UNKNOWN falls back to first strategy (Intel)
EXPECT_EQ(draft.taskType, "INTEL_ANALYSIS");
}
// ==================== GetDraftList ====================
TEST(TaskGeneratorTest, GetDraftListEmpty) {
TaskGenerator tg;
auto list = tg.GetDraftList();
EXPECT_TRUE(list.empty());
}
TEST(TaskGeneratorTest, GetDraftListAfterGeneration) {
TaskGenerator tg;
Event evt;
evt.id = "e1";
evt.type = EventType::INTEL;
evt.priority = 5;
tg.CreateTaskFromEvent(evt);
tg.CreateTaskFromEvent(evt);
auto list = tg.GetDraftList();
EXPECT_EQ(list.size(), 2u);
}
// ==================== SubmitDraft ====================
TEST(TaskGeneratorTest, SubmitDraftSuccess) {
TaskGenerator tg;
Event evt;
evt.id = "e1";
evt.type = EventType::INTEL;
evt.priority = 5;
TaskDraft draft = tg.CreateTaskFromEvent(evt);
bool submitted = tg.SubmitDraft(draft.id, "http://engine.local/submit");
EXPECT_TRUE(submitted);
}
TEST(TaskGeneratorTest, SubmitDraftNotFound) {
TaskGenerator tg;
bool submitted = tg.SubmitDraft("nonexistent", "http://engine.local");
EXPECT_FALSE(submitted);
}
TEST(TaskGeneratorTest, SubmitDraftTwice) {
TaskGenerator tg;
Event evt;
evt.id = "e1";
evt.type = EventType::INTEL;
evt.priority = 5;
TaskDraft draft = tg.CreateTaskFromEvent(evt);
EXPECT_TRUE(tg.SubmitDraft(draft.id, "url1"));
EXPECT_FALSE(tg.SubmitDraft(draft.id, "url2")); // 已提交后不能再提交
}
// ==================== SubmitDraftAsJson ====================
TEST(TaskGeneratorTest, SubmitDraftAsJsonSuccess) {
TaskGenerator tg;
Event evt;
evt.id = "e1";
evt.type = EventType::THREAT;
evt.priority = 8;
TaskDraft draft = tg.CreateTaskFromEvent(evt);
nlohmann::json result = tg.SubmitDraftAsJson(draft.id);
EXPECT_FALSE(result.empty());
EXPECT_EQ(result["draftId"], draft.id);
EXPECT_EQ(result["priority"], draft.priority);
EXPECT_EQ(result["status"], "SUBMITTED");
EXPECT_TRUE(result.contains("resources"));
EXPECT_TRUE(result["resources"].is_array());
}
TEST(TaskGeneratorTest, SubmitDraftAsJsonNotFound) {
TaskGenerator tg;
nlohmann::json result = tg.SubmitDraftAsJson("nonexistent");
EXPECT_TRUE(result.empty());
}
TEST(TaskGeneratorTest, SubmitDraftAsJsonTwice) {
TaskGenerator tg;
Event evt;
evt.id = "e1";
evt.type = EventType::INTEL;
evt.priority = 5;
TaskDraft draft = tg.CreateTaskFromEvent(evt);
auto r1 = tg.SubmitDraftAsJson(draft.id);
EXPECT_FALSE(r1.empty());
auto r2 = tg.SubmitDraftAsJson(draft.id);
EXPECT_TRUE(r2.empty());
}
// ==================== SortDraftsByPriority ====================
TEST(TaskGeneratorTest, SortDraftsByPriorityAscending) {
TaskGenerator tg;
for (int p : {3, 9, 1, 7}) {
Event evt;
evt.id = "e" + std::to_string(p);
evt.type = EventType::THREAT;
evt.priority = p;
tg.CreateTaskFromEvent(evt);
}
tg.SortDraftsByPriority(true);
auto list = tg.GetDraftList();
// Threat strategy: p' = min(p+2, 10):
// 3→5, 9→10, 1→3, 7→9 → ascending: [3,5,9,10]
EXPECT_EQ(list[0].priority, 3);
EXPECT_EQ(list[3].priority, 10);
}
TEST(TaskGeneratorTest, SortDraftsByPriorityDescending) {
TaskGenerator tg;
for (int p : {2, 8, 4, 6}) {
Event evt;
evt.id = "e" + std::to_string(p);
evt.type = EventType::INTEL;
evt.priority = p;
tg.CreateTaskFromEvent(evt);
}
tg.SortDraftsByPriority(false);
auto list = tg.GetDraftList();
// Intel strategy: p' = max(p, 5):
// 2→5, 8→8, 4→5, 6→6 → descending: [8, 6, 5, 5]
EXPECT_EQ(list[0].priority, 8);
EXPECT_EQ(list[3].priority, 5);
}
// ==================== Observer Pattern ====================
TEST(TaskGeneratorTest, OnEventReceivedAutoGenerateEnabled) {
TaskGenerator tg;
tg.SetAutoGenerate(true);
Event evt;
evt.id = "OBS-1";
evt.type = EventType::MISSION;
evt.priority = 5;
tg.OnEventReceived(evt);
EXPECT_EQ(tg.GetDraftCount(), 1u);
auto drafts = tg.GetDraftList();
EXPECT_EQ(drafts[0].relatedEventId, "OBS-1");
EXPECT_EQ(drafts[0].taskType, "COMBAT_MISSION");
}
TEST(TaskGeneratorTest, OnEventReceivedAutoGenerateDisabled) {
TaskGenerator tg;
tg.SetAutoGenerate(false);
Event evt;
evt.id = "OBS-2";
evt.type = EventType::THREAT;
evt.priority = 9;
tg.OnEventReceived(evt);
EXPECT_EQ(tg.GetDraftCount(), 0u);
}
TEST(TaskGeneratorTest, OnEventReceivedWithArchivedEvent) {
TaskGenerator tg;
tg.SetAutoGenerate(true);
Event evt;
evt.id = "OBS-3";
evt.type = EventType::INTEL;
evt.priority = 5;
evt.status = EventStatus::ARCHIVED;
tg.OnEventReceived(evt);
EXPECT_EQ(tg.GetDraftCount(), 0u);
}
// ==================== SetAutoGenerate / GetDraftCount ====================
TEST(TaskGeneratorTest, DefaultAutoGenerateIsOff) {
TaskGenerator tg;
Event evt;
evt.id = "e1";
evt.type = EventType::INTEL;
evt.priority = 5;
tg.OnEventReceived(evt);
EXPECT_EQ(tg.GetDraftCount(), 0u);
}
// ==================== Strategy Names ====================
TEST(StrategyTest, StrategyNames) {
IntelTaskStrategy intel;
EXPECT_EQ(intel.Name(), "IntelTaskStrategy");
ThreatTaskStrategy threat;
EXPECT_EQ(threat.Name(), "ThreatTaskStrategy");
MissionTaskStrategy mission;
EXPECT_EQ(mission.Name(), "MissionTaskStrategy");
LogisticTaskStrategy logistic;
EXPECT_EQ(logistic.Name(), "LogisticTaskStrategy");
}
TEST(StrategyTest, IntelStrategyResources) {
IntelTaskStrategy strat;
Event evt;
evt.id = "e1";
evt.priority = 5;
evt.location = "zone";
evt.source = "src";
TaskDraft draft = strat.Generate(evt, "DRF-1");
EXPECT_EQ(draft.requiredResources.size(), 3u);
EXPECT_THAT(draft.requiredResources, testing::Contains("ANALYST_TEAM"));
EXPECT_THAT(draft.requiredResources, testing::Contains("SAT_IMAGERY"));
EXPECT_THAT(draft.requiredResources, testing::Contains("SIGINT_UNIT"));
}
TEST(StrategyTest, ThreatStrategyResources) {
ThreatTaskStrategy strat;
Event evt;
evt.id = "e1";
evt.priority = 5;
evt.location = "zone";
evt.source = "src";
TaskDraft draft = strat.Generate(evt, "DRF-1");
EXPECT_EQ(draft.requiredResources.size(), 3u);
EXPECT_THAT(draft.requiredResources, testing::Contains("STRIKE_UNIT"));
}
TEST(StrategyTest, MissionStrategyResources) {
MissionTaskStrategy strat;
Event evt;
evt.id = "e1";
evt.priority = 5;
evt.location = "zone";
evt.source = "src";
TaskDraft draft = strat.Generate(evt, "DRF-1");
EXPECT_EQ(draft.requiredResources.size(), 3u);
EXPECT_THAT(draft.requiredResources, testing::Contains("INFANTRY_PLT"));
}
TEST(StrategyTest, LogisticStrategyResources) {
LogisticTaskStrategy strat;
Event evt;
evt.id = "e1";
evt.priority = 5;
evt.location = "zone";
evt.source = "src";
TaskDraft draft = strat.Generate(evt, "DRF-1");
EXPECT_EQ(draft.requiredResources.size(), 3u);
EXPECT_THAT(draft.requiredResources, testing::Contains("SUPPLY_CONVOY"));
}
// ==================== 边界与压力测试 ====================
TEST(TaskGeneratorTest, CreateManyTasks) {
TaskGenerator tg;
for (int i = 0; i < 100; ++i) {
Event evt;
evt.id = "bulk-" + std::to_string(i);
evt.type = EventType::INTEL;
evt.priority = (i % 10) + 1;
tg.CreateTaskFromEvent(evt);
}
EXPECT_EQ(tg.GetDraftCount(), 100u);
tg.SortDraftsByPriority(false);
auto list = tg.GetDraftList();
EXPECT_GE(list[0].priority, list.back().priority);
}