plan_execute_t1/tests/test_cms_engine.cpp

317 lines
12 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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";
}