|
|
|
|
@ -0,0 +1,316 @@
|
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include "app.hpp"
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
// Test Fixture for CmsEngine
|
|
|
|
|
// ============================================================================
|
|
|
|
|
class CmsEngineTest : public ::testing::Test {
|
|
|
|
|
protected:
|
|
|
|
|
CmsEngine engine;
|
|
|
|
|
|
|
|
|
|
void SetUp() override {
|
|
|
|
|
// Initialize with some plans for findPlanById and updatePlanStatus tests
|
|
|
|
|
TaskPlan plan1;
|
|
|
|
|
plan1.name = "Plan1";
|
|
|
|
|
engine.createTaskPlan(plan1);
|
|
|
|
|
|
|
|
|
|
TaskPlan plan2;
|
|
|
|
|
plan2.name = "Plan2";
|
|
|
|
|
engine.createTaskPlan(plan2);
|
|
|
|
|
|
|
|
|
|
// Register a template for registerTemplate tests
|
|
|
|
|
TemplateInstance tmpl;
|
|
|
|
|
tmpl.templateId = "TMPL-001";
|
|
|
|
|
tmpl.confidence = 0.8;
|
|
|
|
|
engine.registerTemplate(tmpl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Helper to get the first plan's ID
|
|
|
|
|
std::string getFirstPlanId() const {
|
|
|
|
|
const auto& plans = engine.getAllPlans();
|
|
|
|
|
if (!plans.empty()) {
|
|
|
|
|
return plans[0].id;
|
|
|
|
|
}
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Helper to get the second plan's ID
|
|
|
|
|
std::string getSecondPlanId() const {
|
|
|
|
|
const auto& plans = engine.getAllPlans();
|
|
|
|
|
if (plans.size() > 1) {
|
|
|
|
|
return plans[1].id;
|
|
|
|
|
}
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
// Tests for findPlanById
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @test 正常输入测试 - 查找存在的方案
|
|
|
|
|
* @description 使用有效的 planId 查找已存在的方案,应返回正确的方案指针
|
|
|
|
|
*/
|
|
|
|
|
TEST_F(CmsEngineTest, testFindPlanByIdExistingPlan) {
|
|
|
|
|
std::string planId = getFirstPlanId();
|
|
|
|
|
ASSERT_FALSE(planId.empty()) << "Plan ID should not be empty";
|
|
|
|
|
|
|
|
|
|
const TaskPlan* result = engine.findPlanById(planId);
|
|
|
|
|
ASSERT_NE(result, nullptr) << "Should find the existing plan";
|
|
|
|
|
EXPECT_EQ(result->id, planId) << "Plan ID should match";
|
|
|
|
|
EXPECT_EQ(result->name, "Plan1") << "Plan name should match";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @test 边界值测试 - 查找不存在的方案
|
|
|
|
|
* @description 使用不存在的 planId 查找方案,应返回 nullptr
|
|
|
|
|
*/
|
|
|
|
|
TEST_F(CmsEngineTest, testFindPlanByIdNonExistingPlan) {
|
|
|
|
|
const std::string nonExistingId = "ID-99999";
|
|
|
|
|
const TaskPlan* result = engine.findPlanById(nonExistingId);
|
|
|
|
|
EXPECT_EQ(result, nullptr) << "Should return nullptr for non-existing plan";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @test 边界值测试 - 查找空字符串 ID
|
|
|
|
|
* @description 使用空字符串作为 planId 查找方案,应返回 nullptr
|
|
|
|
|
*/
|
|
|
|
|
TEST_F(CmsEngineTest, testFindPlanByIdEmptyId) {
|
|
|
|
|
const std::string emptyId = "";
|
|
|
|
|
const TaskPlan* result = engine.findPlanById(emptyId);
|
|
|
|
|
EXPECT_EQ(result, nullptr) << "Should return nullptr for empty ID";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @test 特殊场景测试 - 查找多个方案中的特定方案
|
|
|
|
|
* @description 在多个方案中查找第二个方案,应返回正确的方案
|
|
|
|
|
*/
|
|
|
|
|
TEST_F(CmsEngineTest, testFindPlanByIdSecondPlan) {
|
|
|
|
|
std::string planId = getSecondPlanId();
|
|
|
|
|
ASSERT_FALSE(planId.empty()) << "Second plan ID should not be empty";
|
|
|
|
|
|
|
|
|
|
const TaskPlan* result = engine.findPlanById(planId);
|
|
|
|
|
ASSERT_NE(result, nullptr) << "Should find the second plan";
|
|
|
|
|
EXPECT_EQ(result->id, planId) << "Plan ID should match";
|
|
|
|
|
EXPECT_EQ(result->name, "Plan2") << "Plan name should match";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @test 异常输入测试 - 查找特殊字符 ID
|
|
|
|
|
* @description 使用包含特殊字符的 planId 查找方案,应返回 nullptr
|
|
|
|
|
*/
|
|
|
|
|
TEST_F(CmsEngineTest, testFindPlanByIdSpecialChars) {
|
|
|
|
|
const std::string specialId = "!@#$%^&*()";
|
|
|
|
|
const TaskPlan* result = engine.findPlanById(specialId);
|
|
|
|
|
EXPECT_EQ(result, nullptr) << "Should return nullptr for special character ID";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
// Tests for updatePlanStatus
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @test 正常输入测试 - 更新方案状态
|
|
|
|
|
* @description 使用有效的 planId 更新方案状态,应返回 true 并更新状态
|
|
|
|
|
*/
|
|
|
|
|
TEST_F(CmsEngineTest, testUpdatePlanStatusSuccess) {
|
|
|
|
|
std::string planId = getFirstPlanId();
|
|
|
|
|
ASSERT_FALSE(planId.empty()) << "Plan ID should not be empty";
|
|
|
|
|
|
|
|
|
|
PlanStatus newStatus = PlanStatus::Approved;
|
|
|
|
|
bool result = engine.updatePlanStatus(planId, newStatus);
|
|
|
|
|
EXPECT_TRUE(result) << "Should return true for successful update";
|
|
|
|
|
|
|
|
|
|
// Verify the status was updated
|
|
|
|
|
const TaskPlan* updatedPlan = engine.findPlanById(planId);
|
|
|
|
|
ASSERT_NE(updatedPlan, nullptr) << "Plan should still exist";
|
|
|
|
|
EXPECT_EQ(updatedPlan->status, newStatus) << "Plan status should be updated";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @test 边界值测试 - 更新不存在的方案状态
|
|
|
|
|
* @description 使用不存在的 planId 更新方案状态,应返回 false
|
|
|
|
|
*/
|
|
|
|
|
TEST_F(CmsEngineTest, testUpdatePlanStatusNonExistingPlan) {
|
|
|
|
|
const std::string nonExistingId = "ID-99999";
|
|
|
|
|
bool result = engine.updatePlanStatus(nonExistingId, PlanStatus::Approved);
|
|
|
|
|
EXPECT_FALSE(result) << "Should return false for non-existing plan";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @test 边界值测试 - 更新空字符串 ID 的方案状态
|
|
|
|
|
* @description 使用空字符串作为 planId 更新方案状态,应返回 false
|
|
|
|
|
*/
|
|
|
|
|
TEST_F(CmsEngineTest, testUpdatePlanStatusEmptyId) {
|
|
|
|
|
const std::string emptyId = "";
|
|
|
|
|
bool result = engine.updatePlanStatus(emptyId, PlanStatus::Approved);
|
|
|
|
|
EXPECT_FALSE(result) << "Should return false for empty ID";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @test 特殊场景测试 - 更新方案状态为 Drafting
|
|
|
|
|
* @description 更新方案状态为 Drafting,应返回 true 并更新状态
|
|
|
|
|
*/
|
|
|
|
|
TEST_F(CmsEngineTest, testUpdatePlanStatusToDrafting) {
|
|
|
|
|
std::string planId = getFirstPlanId();
|
|
|
|
|
ASSERT_FALSE(planId.empty()) << "Plan ID should not be empty";
|
|
|
|
|
|
|
|
|
|
bool result = engine.updatePlanStatus(planId, PlanStatus::Drafting);
|
|
|
|
|
EXPECT_TRUE(result) << "Should return true for successful update";
|
|
|
|
|
|
|
|
|
|
const TaskPlan* updatedPlan = engine.findPlanById(planId);
|
|
|
|
|
ASSERT_NE(updatedPlan, nullptr) << "Plan should still exist";
|
|
|
|
|
EXPECT_EQ(updatedPlan->status, PlanStatus::Drafting) << "Plan status should be Drafting";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @test 特殊场景测试 - 多次更新方案状态
|
|
|
|
|
* @description 连续多次更新同一方案的状态,应每次返回 true 并更新状态
|
|
|
|
|
*/
|
|
|
|
|
TEST_F(CmsEngineTest, testUpdatePlanStatusMultipleTimes) {
|
|
|
|
|
std::string planId = getFirstPlanId();
|
|
|
|
|
ASSERT_FALSE(planId.empty()) << "Plan ID should not be empty";
|
|
|
|
|
|
|
|
|
|
// First update
|
|
|
|
|
bool result1 = engine.updatePlanStatus(planId, PlanStatus::Approved);
|
|
|
|
|
EXPECT_TRUE(result1) << "First update should succeed";
|
|
|
|
|
|
|
|
|
|
// Second update
|
|
|
|
|
bool result2 = engine.updatePlanStatus(planId, PlanStatus::Executing);
|
|
|
|
|
EXPECT_TRUE(result2) << "Second update should succeed";
|
|
|
|
|
|
|
|
|
|
// Third update
|
|
|
|
|
bool result3 = engine.updatePlanStatus(planId, PlanStatus::Completed);
|
|
|
|
|
EXPECT_TRUE(result3) << "Third update should succeed";
|
|
|
|
|
|
|
|
|
|
// Verify final status
|
|
|
|
|
const TaskPlan* updatedPlan = engine.findPlanById(planId);
|
|
|
|
|
ASSERT_NE(updatedPlan, nullptr) << "Plan should still exist";
|
|
|
|
|
EXPECT_EQ(updatedPlan->status, PlanStatus::Completed) << "Plan status should be Completed";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
// Tests for registerTemplate
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @test 正常输入测试 - 注册模板
|
|
|
|
|
* @description 注册一个有效的模板实例,应成功添加
|
|
|
|
|
*/
|
|
|
|
|
TEST_F(CmsEngineTest, testRegisterTemplateSuccess) {
|
|
|
|
|
TemplateInstance tmpl;
|
|
|
|
|
tmpl.templateId = "TMPL-002";
|
|
|
|
|
tmpl.confidence = 0.9;
|
|
|
|
|
|
|
|
|
|
engine.registerTemplate(tmpl);
|
|
|
|
|
|
|
|
|
|
// Verify the template was registered by matching
|
|
|
|
|
const TemplateInstance* matched = engine.matchTemplate("test_scenario");
|
|
|
|
|
ASSERT_NE(matched, nullptr) << "Should find a template after registration";
|
|
|
|
|
EXPECT_EQ(matched->templateId, "TMPL-002") << "Should match the newly registered template";
|
|
|
|
|
EXPECT_EQ(matched->confidence, 0.9) << "Confidence should match";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @test 边界值测试 - 注册空 ID 模板
|
|
|
|
|
* @description 注册一个 templateId 为空的模板实例,应成功添加(允许空 ID)
|
|
|
|
|
*/
|
|
|
|
|
TEST_F(CmsEngineTest, testRegisterTemplateEmptyId) {
|
|
|
|
|
TemplateInstance tmpl;
|
|
|
|
|
tmpl.templateId = "";
|
|
|
|
|
tmpl.confidence = 0.5;
|
|
|
|
|
|
|
|
|
|
engine.registerTemplate(tmpl);
|
|
|
|
|
|
|
|
|
|
// Verify the template was registered
|
|
|
|
|
const TemplateInstance* matched = engine.matchTemplate("test_scenario");
|
|
|
|
|
ASSERT_NE(matched, nullptr) << "Should find a template after registration";
|
|
|
|
|
EXPECT_EQ(matched->templateId, "") << "Template ID should be empty";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @test 边界值测试 - 注册零置信度模板
|
|
|
|
|
* @description 注册一个置信度为 0 的模板实例,应成功添加
|
|
|
|
|
*/
|
|
|
|
|
TEST_F(CmsEngineTest, testRegisterTemplateZeroConfidence) {
|
|
|
|
|
TemplateInstance tmpl;
|
|
|
|
|
tmpl.templateId = "TMPL-003";
|
|
|
|
|
tmpl.confidence = 0.0;
|
|
|
|
|
|
|
|
|
|
engine.registerTemplate(tmpl);
|
|
|
|
|
|
|
|
|
|
// Verify the template was registered
|
|
|
|
|
const TemplateInstance* matched = engine.matchTemplate("test_scenario");
|
|
|
|
|
ASSERT_NE(matched, nullptr) << "Should find a template after registration";
|
|
|
|
|
EXPECT_EQ(matched->confidence, 0.0) << "Confidence should be 0.0";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @test 特殊场景测试 - 注册多个模板
|
|
|
|
|
* @description 注册多个模板实例,应全部成功添加
|
|
|
|
|
*/
|
|
|
|
|
TEST_F(CmsEngineTest, testRegisterTemplateMultiple) {
|
|
|
|
|
TemplateInstance tmpl1;
|
|
|
|
|
tmpl1.templateId = "TMPL-004";
|
|
|
|
|
tmpl1.confidence = 0.7;
|
|
|
|
|
|
|
|
|
|
TemplateInstance tmpl2;
|
|
|
|
|
tmpl2.templateId = "TMPL-005";
|
|
|
|
|
tmpl2.confidence = 0.9;
|
|
|
|
|
|
|
|
|
|
TemplateInstance tmpl3;
|
|
|
|
|
tmpl3.templateId = "TMPL-006";
|
|
|
|
|
tmpl3.confidence = 0.5;
|
|
|
|
|
|
|
|
|
|
engine.registerTemplate(tmpl1);
|
|
|
|
|
engine.registerTemplate(tmpl2);
|
|
|
|
|
engine.registerTemplate(tmpl3);
|
|
|
|
|
|
|
|
|
|
// Verify the best template is the one with highest confidence
|
|
|
|
|
const TemplateInstance* matched = engine.matchTemplate("test_scenario");
|
|
|
|
|
ASSERT_NE(matched, nullptr) << "Should find a template after registration";
|
|
|
|
|
EXPECT_EQ(matched->templateId, "TMPL-005") << "Should match the template with highest confidence";
|
|
|
|
|
EXPECT_EQ(matched->confidence, 0.9) << "Confidence should be 0.9";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @test 特殊场景测试 - 注册相同 ID 的模板
|
|
|
|
|
* @description 注册两个 templateId 相同的模板实例,应都成功添加
|
|
|
|
|
*/
|
|
|
|
|
TEST_F(CmsEngineTest, testRegisterTemplateDuplicateId) {
|
|
|
|
|
TemplateInstance tmpl1;
|
|
|
|
|
tmpl1.templateId = "TMPL-007";
|
|
|
|
|
tmpl1.confidence = 0.6;
|
|
|
|
|
|
|
|
|
|
TemplateInstance tmpl2;
|
|
|
|
|
tmpl2.templateId = "TMPL-007";
|
|
|
|
|
tmpl2.confidence = 0.8;
|
|
|
|
|
|
|
|
|
|
engine.registerTemplate(tmpl1);
|
|
|
|
|
engine.registerTemplate(tmpl2);
|
|
|
|
|
|
|
|
|
|
// Verify both templates are registered and the one with higher confidence is matched
|
|
|
|
|
const TemplateInstance* matched = engine.matchTemplate("test_scenario");
|
|
|
|
|
ASSERT_NE(matched, nullptr) << "Should find a template after registration";
|
|
|
|
|
EXPECT_EQ(matched->confidence, 0.8) << "Should match the template with higher confidence";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @test 异常输入测试 - 注册后立即匹配
|
|
|
|
|
* @description 注册一个模板后立即匹配,应返回刚注册的模板
|
|
|
|
|
*/
|
|
|
|
|
TEST_F(CmsEngineTest, testRegisterTemplateAndMatchImmediately) {
|
|
|
|
|
TemplateInstance tmpl;
|
|
|
|
|
tmpl.templateId = "TMPL-008";
|
|
|
|
|
tmpl.confidence = 1.0;
|
|
|
|
|
|
|
|
|
|
engine.registerTemplate(tmpl);
|
|
|
|
|
|
|
|
|
|
const TemplateInstance* matched = engine.matchTemplate("any_scenario");
|
|
|
|
|
ASSERT_NE(matched, nullptr) << "Should find a template immediately after registration";
|
|
|
|
|
EXPECT_EQ(matched->templateId, "TMPL-008") << "Should match the just registered template";
|
|
|
|
|
EXPECT_EQ(matched->confidence, 1.0) << "Confidence should be 1.0";
|
|
|
|
|
}
|