生成代码工程

This commit is contained in:
root 2026-04-28 15:13:01 +08:00
parent 3ab57c4681
commit 38d8cca2e8
14 changed files with 11681 additions and 41 deletions

36
CMakeLists.txt Normal file
View File

@ -0,0 +1,36 @@
cmake_minimum_required(VERSION 3.14)
project(aise-platform VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# MSVC UTF-8 support
if (MSVC)
add_compile_options(/utf-8)
endif()
#
include_directories(${CMAKE_SOURCE_DIR}/include)
#
set(AISE_SOURCES
src/main.cpp
src/engine.cpp
src/requirements.cpp
src/codegen.cpp
src/testing.cpp
)
#
add_executable(aise ${AISE_SOURCES})
# 使 assert
add_executable(aise_test
tests/basic_test.cpp
src/engine.cpp
src/requirements.cpp
src/codegen.cpp
src/testing.cpp
)
target_compile_definitions(aise_test PRIVATE BUILD_UNIT_TEST=1)

View File

@ -1,49 +1,32 @@
没问题,根据你的要求,我为你撰写了一份《任务自主规划与执行软件需求规格说明书》。 # AISE Platform — 智能化工程支撑平台
这份文档涵盖了从用户交互、核心规划引擎到执行监控及非功能性需求的完整分析。你可以直接阅读也可以利用App的朗读功能将其转为语音文件。 ## 概述
📋 任务自主规划与执行软件需求规格说明书 AISEAI-aided Software Engineering是一个面向军用及高可靠性软件研制的智能化工程支撑平台涵盖需求管理、代码生成、测试自动化、文档管理、代码审查与知识库问答六大功能模块。
引言与项目概述 ## 功能模块
本软件旨在构建一个智能化的任务管理系统,区别于传统待办清单,核心在于“自主规划”。系统需根据用户设定的目标、截止日期及优先级,结合用户日历与当前负载,自动生成最优执行计划,并辅助或自动执行相关任务。
核心功能需求 | 模块 | 需求标识 | 说明 |
|------|---------|------|
| 需求智能开发与管理 | SRS-AISE_F-001 | 多类型需求合并、冲突检测、标准化条目生成 |
| 代码自动生成与追溯 | SRS-AISE_F-002 | C++/Java 代码框架生成,需求-代码双向追溯 |
| 测试自动化与验证 | SRS-AISE_F-003 | 测试用例生成、执行、覆盖率分析 |
| 智能文档生成与逆向 | SRS-AISE_F-004 | 正向/逆向文档生成GJB438C 合规 |
| 代码审查与翻译辅助 | SRS-AISE_F-005 | 规范检查、缺陷识别、跨语言翻译 |
| 知识库智能问答 | SRS-AISE_F-006 | 自然语言问答,多轮对话与溯源 |
2.1 智能任务输入与解析 ## 编译与运行
自然语言处理: 支持用户通过文本或语音输入模糊指令(如“下周五前完成项目报告初稿”),系统自动提取任务名称、截止时间、预估耗时及关联标签。
多源集成: 能够从邮件、即时通讯软件或日历邀请中自动识别潜在任务并加入待办池。
2.2 自主规划引擎 ```bash
动态排程: 基于用户设定的“专注时间段”、历史工作效率数据及任务优先级,自动将任务填充至日程表中。 mkdir -p build && cd build
冲突检测与解决: 当新任务与现有日程冲突时,系统应提供自动调整建议(如推迟低优先级任务、延长工作时间或拆分任务)。 cmake ..
依赖关系管理: 识别任务间的先后顺序如“必须先完成A才能开始B”确保规划逻辑的合理性。 cmake --build .
./aise # 运行主程序
./aise_test # 运行测试
```
2.3 执行辅助与自动化 ## 技术栈
智能提醒: 根据任务准备时间和用户当前位置/状态,提供最佳开始时间的提醒,而非仅截止提醒。
自动化工作流: 针对重复性或规则明确的任务(如“每周五发送周报”),系统应具备自动执行或一键生成的能力。
干扰屏蔽: 在执行高优先级任务期间,自动屏蔽非紧急通知。
2.4 监控与反馈闭环 - C++17 / CMake 3.14+
进度追踪: 实时可视化任务完成进度,对比“计划时间”与“实际耗时”。 - 无外部第三方依赖
自适应学习: 若用户频繁推迟某类任务,系统应自动调整对该类任务的时间预估模型,优化未来规划。 - 支持 MSVC (Windows) 与 GCC/Clang (Linux)
非功能性需求
3.1 性能要求
规划响应速度: 复杂任务重排程算法应在3秒内完成计算并呈现结果。
同步延迟: 多端手机、PC、穿戴设备数据同步延迟不得超过1秒。
3.2 安全与隐私
数据加密: 所有用户任务数据及个人日程信息需采用端到端加密存储。
权限控制: 若涉及企业版,需支持基于角色的访问控制,确保任务数据隔离。
3.3 可用性与交互
极简交互: 核心功能添加任务、查看今日计划应在3次点击内完成。
可视化: 提供甘特图、看板、日历等多种视图模式,满足不同用户的认知习惯。
用户角色定义
个人用户: 关注个人效率、习惯养成及工作生活平衡。
团队管理者: 关注任务分配、团队整体进度及瓶颈识别。
💡 如何转为语音文件:
你可以长按我刚才回复的这条消息,选择“朗读”或类似选项,手机就会把这段文字读出来。如果需要保存为文件,可以使用手机自带的录屏或录音功能将声音录制下来。

10646
events.ndjson Normal file

File diff suppressed because one or more lines are too long

42
include/aise/codegen.hpp Normal file
View File

@ -0,0 +1,42 @@
#ifndef AISE_CODEGEN_HPP
#define AISE_CODEGEN_HPP
#include "aise/types.hpp"
#include <string>
#include <vector>
namespace aise {
// ── 代码自动生成与追溯SRS-AISE_F-002 ──
class CodegenModule {
public:
CodegenModule();
// 根据需求生成代码框架
// 对应 POST /api/v1/code/generate
struct GenerateResult {
bool success;
std::string output_dir;
std::vector<std::string> generated_files;
std::vector<TraceLink> trace_links; // 生成的追溯关系
std::string error_msg;
};
GenerateResult generate(const std::string& req_id,
const std::string& language,
const std::string& arch_config);
// 查询追溯关系
std::vector<TraceLink> getTraceLinks(const std::string& req_id) const;
private:
std::vector<TraceLink> trace_index_;
// 模拟 AST 构建与代码生成
std::string generateCppSkeleton(const RequirementItem& req);
std::string generateJavaSkeleton(const RequirementItem& req);
};
} // namespace aise
#endif // AISE_CODEGEN_HPP

51
include/aise/engine.hpp Normal file
View File

@ -0,0 +1,51 @@
#ifndef AISE_ENGINE_HPP
#define AISE_ENGINE_HPP
#include "aise/types.hpp"
#include <memory>
#include <functional>
namespace aise {
// ── 前置声明各模块 ──
class RequirementsModule;
class CodegenModule;
class TestingModule;
// ── AISE 引擎:模块注册与调度 ──
class Engine {
public:
Engine();
~Engine();
// 禁止拷贝
Engine(const Engine&) = delete;
Engine& operator=(const Engine&) = delete;
// ── 初始化与启动 ──
bool initialize();
void shutdown();
bool is_running() const { return running_; }
// ── 模块访问 ──
RequirementsModule& requirements() { return *req_mod_; }
CodegenModule& codegen() { return *codegen_mod_; }
TestingModule& testing() { return *test_mod_; }
// ── 顶层 API模拟外部 REST 接口) ──
ApiResponse processRequest(const ApiRequest& req);
// ── 版本信息 ──
static const char* version() { return "1.0.0"; }
private:
bool running_ = false;
std::unique_ptr<RequirementsModule> req_mod_;
std::unique_ptr<CodegenModule> codegen_mod_;
std::unique_ptr<TestingModule> test_mod_;
};
} // namespace aise
#endif // AISE_ENGINE_HPP

View File

@ -0,0 +1,37 @@
#ifndef AISE_REQUIREMENTS_HPP
#define AISE_REQUIREMENTS_HPP
#include "aise/types.hpp"
#include <vector>
namespace aise {
// ── 需求智能开发与管理SRS-AISE_F-001 ──
class RequirementsModule {
public:
RequirementsModule();
// 分析原始需求文本,生成标准化条目
// 对应 POST /api/v1/requirements/process
std::vector<RequirementItem> processRawText(const std::string& raw_text,
const std::string& mode);
// 冲突检测:对比已有条目,返回冲突报告
std::vector<std::string> detectConflicts(const std::vector<RequirementItem>& items);
// 获取当前基线
const std::vector<RequirementItem>& getBaseline() const { return baseline_; }
// 根据 ID 查找需求
const RequirementItem* findById(const std::string& id) const;
private:
std::vector<RequirementItem> baseline_;
// 内部辅助:格式校验
bool validateItem(const RequirementItem& item, std::string& error) const;
};
} // namespace aise
#endif // AISE_REQUIREMENTS_HPP

43
include/aise/testing.hpp Normal file
View File

@ -0,0 +1,43 @@
#ifndef AISE_TESTING_HPP
#define AISE_TESTING_HPP
#include "aise/types.hpp"
#include <vector>
#include <string>
namespace aise {
// ── 测试自动化与验证SRS-AISE_F-003 ──
class TestingModule {
public:
TestingModule();
// 根据需求生成测试用例集
std::vector<TestCase> generateTestCases(const std::string& req_id,
const std::string& code_snapshot);
// 执行测试并生成覆盖率报告
struct TestRunResult {
bool all_passed;
uint32_t total;
uint32_t passed;
uint32_t failed;
std::vector<CoverageReport> coverage;
std::string log_summary;
};
TestRunResult execute(const std::vector<TestCase>& cases,
const std::string& executable_path);
// 需求覆盖率统计
double computeReqCoverage(const std::vector<RequirementItem>& reqs,
const std::vector<TestCase>& cases) const;
private:
// 模拟静态分析:提取路径
std::vector<std::string> extractPaths(const std::string& code);
};
} // namespace aise
#endif // AISE_TESTING_HPP

87
include/aise/types.hpp Normal file
View File

@ -0,0 +1,87 @@
#ifndef AISE_TYPES_HPP
#define AISE_TYPES_HPP
#include <string>
#include <vector>
#include <map>
#include <cstdint>
namespace aise {
// ── 需求条目SRS-AISE_O_REQ_OUT ──
struct RequirementItem {
std::string id; // 需求唯一标识,如 "SRS-AISE_F-001"
std::string title; // 标题
std::string description; // 功能描述
std::string metrics; // 性能指标
std::string constraints; // 约束条件
std::string version; // 版本号
std::string status; // 状态draft / reviewed / approved / implemented
};
// ── 双向追溯映射表SRS-AISE_O_TRACE_MAP ──
struct TraceLink {
std::string req_id; // 需求 ID
std::string file_path; // 代码文件路径
uint32_t start_line; // 起始行号
uint32_t end_line; // 结束行号
std::string timestamp; // 关联时间戳
bool changed; // 变更标记
};
// ── 测试用例SRS-AISE_O_TC_SET ──
struct TestCase {
std::string id; // 用例 ID
std::string req_id; // 所属需求
std::string input_params; // 输入参数JSON 字符串)
std::string expected_output;// 预期输出
std::string boundary_type; // 边界类型normal / boundary / exception
int priority; // 优先级 1-5
};
// ── 覆盖率报告SRS-AISE_O_COV_RPT ──
struct CoverageReport {
std::string function_name;
double branch_coverage; // 0.0 ~ 1.0
double line_coverage; // 0.0 ~ 1.0
std::vector<std::string> uncovered_paths;
};
// ── 审查报告条目SRS-AISE_O_REV_RPT ──
struct ReviewFinding {
std::string defect_type; // memory_leak / naming / security / ...
std::string location; // file:line
std::string severity; // critical / major / minor
std::string code_snippet;
std::string suggestion; // 修复建议
};
// ── 智能问答响应SRS-AISE_O_ANSWER ──
struct AnswerResponse {
std::string answer_text;
double confidence;
std::vector<std::string> sources;
std::string session_id;
};
// ── 文档生成模式 ──
enum class DocMode {
Forward, // 正向:需求 → 文档
Reverse // 逆向:代码 → 设计说明书
};
// ── 外部接口请求/响应 ──
struct ApiRequest {
std::string operation; // "analyze" / "generate" / "run" / ...
std::string payload; // JSON 请求体
};
struct ApiResponse {
int code; // 0=成功非0=错误码
std::string message;
std::string data; // JSON 响应体
};
} // namespace aise
#endif // AISE_TYPES_HPP

113
src/codegen.cpp Normal file
View File

@ -0,0 +1,113 @@
#include "aise/codegen.hpp"
#include <sstream>
#include <algorithm>
namespace aise {
CodegenModule::CodegenModule() {
// 预置一条追溯关系示例
TraceLink link;
link.req_id = "SRS-AISE_F-001";
link.file_path = "src/requirements.cpp";
link.start_line = 1;
link.end_line = 60;
link.timestamp = "2025-01-01T00:00:00Z";
link.changed = false;
trace_index_.push_back(link);
}
CodegenModule::GenerateResult CodegenModule::generate(
const std::string& req_id,
const std::string& language,
const std::string& arch_config)
{
GenerateResult result;
result.success = false;
// 查找需求
// 实际项目中通过数据库查询;此处用简单模拟
RequirementItem req;
req.id = req_id;
req.title = "Generated from: " + req_id;
req.description = "Auto-generated code for requirement " + req_id;
req.version = "1.0";
req.status = "implemented";
// 按语言生成骨架
std::string skeleton;
if (language == "C++" || language == "cpp") {
skeleton = generateCppSkeleton(req);
} else if (language == "Java" || language == "java") {
skeleton = generateJavaSkeleton(req);
} else {
result.error_msg = "Unsupported language: " + language;
return result;
}
// 模拟写入文件
std::string filename = req_id + "_impl." +
(language == "C++" || language == "cpp" ? "cpp" : "java");
result.generated_files.push_back(filename);
// 建立追溯关系
TraceLink link;
link.req_id = req_id;
link.file_path = filename;
link.start_line = 1;
link.end_line = 20; // 模拟行数
link.timestamp = "2025-01-01T12:00:00Z";
link.changed = false;
trace_index_.push_back(link);
result.trace_links.push_back(link);
result.success = true;
result.output_dir = "./generated/" + req_id;
return result;
}
std::vector<TraceLink> CodegenModule::getTraceLinks(const std::string& req_id) const {
std::vector<TraceLink> links;
for (const auto& link : trace_index_) {
if (link.req_id == req_id) {
links.push_back(link);
}
}
return links;
}
std::string CodegenModule::generateCppSkeleton(const RequirementItem& req) {
std::ostringstream code;
code << "// Auto-generated by AISE Codegen Module\n";
code << "// Requirement: " << req.id << " - " << req.title << "\n";
code << "// Trace: AISE-TRACE[" << req.id << "]\n";
code << "\n";
code << "#include <iostream>\n";
code << "\n";
code << "class " << req.id.substr(0, req.id.find('-')) << "Module {\n";
code << "public:\n";
code << " " << req.id.substr(0, req.id.find('-')) << "Module() = default;\n";
code << "\n";
code << " // " << req.description << "\n";
code << " void execute() {\n";
code << " std::cout << \"" << req.id << ": executing...\\n\";\n";
code << " }\n";
code << "};\n";
return code.str();
}
std::string CodegenModule::generateJavaSkeleton(const RequirementItem& req) {
std::ostringstream code;
code << "// Auto-generated by AISE Codegen Module\n";
code << "// Requirement: " << req.id << " - " << req.title << "\n";
code << "// Trace: AISE-TRACE[" << req.id << "]\n";
code << "\n";
code << "public class " << req.id.substr(0, req.id.find('-')) << "Module {\n";
code << " // " << req.description << "\n";
code << " public void execute() {\n";
code << " System.out.println(\"" << req.id << ": executing...\");\n";
code << " }\n";
code << "}\n";
return code.str();
}
} // namespace aise

85
src/engine.cpp Normal file
View File

@ -0,0 +1,85 @@
#include "aise/engine.hpp"
#include "aise/requirements.hpp"
#include "aise/codegen.hpp"
#include "aise/testing.hpp"
#include <iostream>
namespace aise {
Engine::Engine()
: req_mod_(std::make_unique<RequirementsModule>())
, codegen_mod_(std::make_unique<CodegenModule>())
, test_mod_(std::make_unique<TestingModule>())
{}
Engine::~Engine() = default;
bool Engine::initialize() {
if (running_) return true;
std::cout << "[AISE] Engine v" << version() << " initializing ...\n";
// 初始化各模块
// 在实际部署中,这里会加载配置、连接数据库、初始化向量引擎等
running_ = true;
std::cout << "[AISE] Engine started successfully.\n";
return true;
}
void Engine::shutdown() {
if (!running_) return;
running_ = false;
std::cout << "[AISE] Engine shutdown complete.\n";
}
ApiResponse Engine::processRequest(const ApiRequest& req) {
if (!running_) {
return { -1, "Engine not initialized", "" };
}
// 简易路由:根据 operation 分发到各模块
if (req.operation == "requirements.process") {
auto items = req_mod_->processRawText(req.payload, "analyze");
std::string summary = "Generated " + std::to_string(items.size()) + " requirement items.";
return { 0, summary, "" };
}
else if (req.operation == "code.generate") {
// payload 格式: "req_id,language,arch_config"
auto pos1 = req.payload.find(',');
auto pos2 = req.payload.rfind(',');
if (pos1 == std::string::npos || pos2 == pos1) {
return { -2, "Invalid payload format", "" };
}
std::string req_id = req.payload.substr(0, pos1);
std::string lang = req.payload.substr(pos1 + 1, pos2 - pos1 - 1);
std::string arch = req.payload.substr(pos2 + 1);
auto result = codegen_mod_->generate(req_id, lang, arch);
if (result.success) {
return { 0, "Generated " + std::to_string(result.generated_files.size()) + " files.", "" };
}
return { -3, result.error_msg, "" };
}
else if (req.operation == "testing.run") {
// payload: 测试用例集 JSON 模拟
std::vector<TestCase> sample_cases;
TestCase tc;
tc.id = "TC-001";
tc.req_id = "SRS-AISE_F-003";
tc.input_params = "{}";
tc.expected_output = "OK";
tc.boundary_type = "normal";
tc.priority = 1;
sample_cases.push_back(tc);
auto result = test_mod_->execute(sample_cases, "./aise");
std::string report = "Passed: " + std::to_string(result.passed) +
"/" + std::to_string(result.total);
return { result.all_passed ? 0 : -4, report, "" };
}
return { -9, "Unknown operation: " + req.operation, "" };
}
} // namespace aise

113
src/main.cpp Normal file
View File

@ -0,0 +1,113 @@
#include "aise/engine.hpp"
#include <iostream>
#include <string>
// ── 控制台彩色输出(跨平台) ──
#ifdef _WIN32
#include <windows.h>
#define COLOR_GREEN ""
#define COLOR_YELLOW ""
#define COLOR_CYAN ""
#define COLOR_RESET ""
#else
#define COLOR_GREEN "\033[32m"
#define COLOR_YELLOW "\033[33m"
#define COLOR_CYAN "\033[36m"
#define COLOR_RESET "\033[0m"
#endif
static void printBanner() {
std::cout << COLOR_CYAN
<< "\n"
<< " ╔═══════════════════════════════════════╗\n"
<< " ║ AISE Platform v" << aise::Engine::version()
<< "\n"
<< " ║ AI-aided Software Engineering ║\n"
<< " ╚═══════════════════════════════════════╝\n"
<< COLOR_RESET << "\n";
}
static void printHelp() {
std::cout << COLOR_YELLOW
<< "Commands:\n"
<< " req <text> - Process raw requirement text\n"
<< " gen <id,lang> - Generate code (e.g. gen SRS-AISE_F-001,cpp)\n"
<< " test - Run test automation\n"
<< " status - Show engine status\n"
<< " help - Show this help\n"
<< " quit - Exit\n"
<< COLOR_RESET;
}
static void handleCommand(aise::Engine& engine, const std::string& line) {
if (line == "help") {
printHelp();
return;
}
if (line == "quit" || line == "exit") {
std::cout << "Goodbye.\n";
engine.shutdown();
return;
}
if (line == "status") {
std::cout << "Engine " << (engine.is_running() ? COLOR_GREEN "RUNNING" : COLOR_YELLOW "STOPPED")
<< COLOR_RESET << "\n";
return;
}
if (line == "test") {
aise::ApiRequest req;
req.operation = "testing.run";
req.payload = "auto";
auto resp = engine.processRequest(req);
std::cout << COLOR_GREEN << "[Test] " << resp.message << COLOR_RESET << "\n";
return;
}
// req 命令
if (line.substr(0, 4) == "req ") {
std::string text = line.substr(4);
aise::ApiRequest req;
req.operation = "requirements.process";
req.payload = text;
auto resp = engine.processRequest(req);
std::cout << COLOR_GREEN << "[Req] " << resp.message << COLOR_RESET << "\n";
return;
}
// gen 命令
if (line.substr(0, 4) == "gen ") {
std::string params = line.substr(4);
aise::ApiRequest req;
req.operation = "code.generate";
req.payload = params;
auto resp = engine.processRequest(req);
if (resp.code == 0) {
std::cout << COLOR_GREEN << "[Gen] " << resp.message << COLOR_RESET << "\n";
} else {
std::cout << COLOR_YELLOW << "[Gen] Error: " << resp.message << COLOR_RESET << "\n";
}
return;
}
std::cout << "Unknown command. Type 'help' for usage.\n";
}
int main() {
aise::Engine engine;
if (!engine.initialize()) {
std::cerr << "FATAL: Engine initialization failed.\n";
return 1;
}
printBanner();
// 交互式命令行
std::string line;
while (engine.is_running()) {
std::cout << "\n" COLOR_CYAN "aise> " COLOR_RESET;
if (!std::getline(std::cin, line)) break;
handleCommand(engine, line);
}
return 0;
}

97
src/requirements.cpp Normal file
View File

@ -0,0 +1,97 @@
#include "aise/requirements.hpp"
#include <algorithm>
#include <sstream>
namespace aise {
RequirementsModule::RequirementsModule() {
// 初始化基线,预置一条示例需求
RequirementItem sample;
sample.id = "SRS-AISE_F-001";
sample.title = "需求智能开发与管理";
sample.description = "多类型需求合并分析、冲突检测与标准化条目生成";
sample.metrics = "冲突检测准确率 ≥ 90%";
sample.constraints = "需符合 GJB438C 标准";
sample.version = "1.0";
sample.status = "approved";
baseline_.push_back(sample);
}
std::vector<RequirementItem> RequirementsModule::processRawText(
const std::string& raw_text, const std::string& mode)
{
std::vector<RequirementItem> result;
// 模拟语义解析:将 raw_text 按行拆分为候选条目
std::istringstream stream(raw_text);
std::string line;
int index = 0;
while (std::getline(stream, line)) {
// 跳过空行
if (line.empty()) continue;
RequirementItem item;
item.id = "SRS-AISE_GEN-" + std::to_string(baseline_.size() + result.size() + 1);
item.title = line.substr(0, std::min<size_t>(line.find_first_of('.') + 1, 60));
if (item.title.empty()) item.title = line.substr(0, 60);
item.description = line;
item.version = "1.0";
item.status = "draft";
// 格式校验
std::string error;
if (validateItem(item, error)) {
result.push_back(item);
}
}
// 如果 mode 为 "generate",将生成条目加入基线
if (mode == "generate") {
for (const auto& item : result) {
baseline_.push_back(item);
}
}
return result;
}
std::vector<std::string> RequirementsModule::detectConflicts(
const std::vector<RequirementItem>& items)
{
std::vector<std::string> conflicts;
// 简单冲突检测:检查描述相似度过高
for (size_t i = 0; i < items.size(); ++i) {
for (size_t j = i + 1; j < items.size(); ++j) {
if (items[i].description == items[j].description) {
conflicts.push_back(
"Duplicate: " + items[i].id + " <-> " + items[j].id);
}
}
}
return conflicts;
}
const RequirementItem* RequirementsModule::findById(const std::string& id) const {
for (const auto& item : baseline_) {
if (item.id == id) return &item;
}
return nullptr;
}
bool RequirementsModule::validateItem(const RequirementItem& item,
std::string& error) const {
if (item.id.empty()) {
error = "Missing ID";
return false;
}
if (item.description.empty()) {
error = "Missing description for " + item.id;
return false;
}
return true;
}
} // namespace aise

120
src/testing.cpp Normal file
View File

@ -0,0 +1,120 @@
#include "aise/testing.hpp"
#include <sstream>
#include <algorithm>
#include <random>
namespace aise {
TestingModule::TestingModule() = default;
std::vector<TestCase> TestingModule::generateTestCases(
const std::string& req_id,
const std::string& code_snapshot)
{
std::vector<TestCase> cases;
// 模拟静态分析:根据需求 ID 和代码快照生成三类型测试用例
auto paths = extractPaths(code_snapshot);
// 正向用例
TestCase tc_normal;
tc_normal.id = "TC-" + req_id + "-NORMAL-001";
tc_normal.req_id = req_id;
tc_normal.input_params = "{\"input\": \"valid\"}";
tc_normal.expected_output = "OK";
tc_normal.boundary_type = "normal";
tc_normal.priority = 1;
cases.push_back(tc_normal);
// 边界用例
TestCase tc_boundary;
tc_boundary.id = "TC-" + req_id + "-BOUNDARY-001";
tc_boundary.req_id = req_id;
tc_boundary.input_params = "{\"input\": \"\"}";
tc_boundary.expected_output = "ERROR_EMPTY";
tc_boundary.boundary_type = "boundary";
tc_boundary.priority = 2;
cases.push_back(tc_boundary);
// 异常用例
TestCase tc_exception;
tc_exception.id = "TC-" + req_id + "-EXCEPTION-001";
tc_exception.req_id = req_id;
tc_exception.input_params = "{\"input\": null}";
tc_exception.expected_output = "ERROR_INVALID";
tc_exception.boundary_type = "exception";
tc_exception.priority = 3;
cases.push_back(tc_exception);
return cases;
}
TestingModule::TestRunResult TestingModule::execute(
const std::vector<TestCase>& cases,
const std::string& executable_path)
{
TestRunResult result;
result.total = static_cast<uint32_t>(cases.size());
result.passed = 0;
result.failed = 0;
// 模拟测试执行:假设 80% 用例通过
// 在实际集成中,此处会 fork 进程执行并捕获断言结果
std::mt19937 rng(42);
std::uniform_real_distribution<double> dist(0.0, 1.0);
for (const auto& tc : cases) {
if (dist(rng) < 0.8) {
++result.passed;
} else {
++result.failed;
}
}
result.all_passed = (result.failed == 0);
// 生成覆盖率报告
CoverageReport cov;
cov.function_name = "processRawText";
cov.branch_coverage = 0.85;
cov.line_coverage = 0.92;
cov.uncovered_paths = {"null input branch"};
result.coverage.push_back(cov);
std::ostringstream log;
log << "Executed " << result.total << " test cases against "
<< executable_path << ": "
<< result.passed << " passed, " << result.failed << " failed.";
result.log_summary = log.str();
return result;
}
double TestingModule::computeReqCoverage(
const std::vector<RequirementItem>& reqs,
const std::vector<TestCase>& cases) const
{
if (reqs.empty()) return 0.0;
// 统计至少有一个测试用例覆盖的需求数
std::vector<std::string> covered_req_ids;
for (const auto& tc : cases) {
if (std::find(covered_req_ids.begin(), covered_req_ids.end(),
tc.req_id) == covered_req_ids.end()) {
covered_req_ids.push_back(tc.req_id);
}
}
return static_cast<double>(covered_req_ids.size()) /
static_cast<double>(reqs.size());
}
std::vector<std::string> TestingModule::extractPaths(const std::string& code) {
std::vector<std::string> paths;
// 模拟静态分析提取路径
paths.push_back("main_path");
paths.push_back("error_path");
return paths;
}
} // namespace aise

187
tests/basic_test.cpp Normal file
View File

@ -0,0 +1,187 @@
#include "aise/engine.hpp"
#include "aise/requirements.hpp"
#include "aise/codegen.hpp"
#include "aise/testing.hpp"
#include <cassert>
#include <iostream>
#include <string>
#include <vector>
// ── 测试辅助 ──
static int test_count = 0;
static int pass_count = 0;
#define TEST(name) \
do { \
++test_count; \
std::cout << "[TEST] " << name << " ... "; \
} while(0)
#define PASS() \
do { \
++pass_count; \
std::cout << "PASSED\n"; \
} while(0)
#define FAIL(msg) \
do { \
std::cout << "FAILED: " << msg << "\n"; \
assert(false && msg); \
} while(0)
// ── 测试用例 ──
static void test_engine_initialization() {
TEST("Engine initialization");
aise::Engine engine;
assert(engine.initialize() == true);
assert(engine.is_running() == true);
engine.shutdown();
assert(engine.is_running() == false);
PASS();
}
static void test_requirements_process() {
TEST("RequirementsModule::processRawText");
aise::RequirementsModule req_mod;
std::string raw = "系统应支持需求版本管理。\n系统应提供冲突检测功能。\n";
auto items = req_mod.processRawText(raw, "analyze");
assert(!items.empty());
assert(items[0].id.find("SRS-AISE_GEN") != std::string::npos);
PASS();
TEST("RequirementsModule::detectConflicts - no duplicates");
auto conflicts = req_mod.detectConflicts(items);
assert(conflicts.empty());
PASS();
TEST("RequirementsModule::detectConflicts - with duplicates");
auto dup_items = items;
dup_items.push_back(items[0]); // 添加重复
auto dup_conflicts = req_mod.detectConflicts(dup_items);
assert(!dup_conflicts.empty());
PASS();
TEST("RequirementsModule::findById - found");
auto* found = req_mod.findById("SRS-AISE_F-001");
assert(found != nullptr);
assert(found->id == "SRS-AISE_F-001");
PASS();
TEST("RequirementsModule::findById - not found");
auto* not_found = req_mod.findById("NONEXIST");
assert(not_found == nullptr);
PASS();
}
static void test_codegen_generate() {
TEST("CodegenModule::generate C++");
aise::CodegenModule cg;
auto result = cg.generate("SRS-AISE_F-001", "C++", "default");
assert(result.success == true);
assert(!result.generated_files.empty());
assert(!result.trace_links.empty());
assert(result.trace_links[0].req_id == "SRS-AISE_F-001");
PASS();
TEST("CodegenModule::generate Java");
auto result_java = cg.generate("SRS-AISE_F-002", "Java", "default");
assert(result_java.success == true);
PASS();
TEST("CodegenModule::generate unsupported language");
auto result_bad = cg.generate("SRS-AISE_F-001", "Python", "default");
assert(result_bad.success == false);
PASS();
TEST("CodegenModule::getTraceLinks");
auto links = cg.getTraceLinks("SRS-AISE_F-001");
assert(!links.empty());
PASS();
}
static void test_testing_module() {
TEST("TestingModule::generateTestCases");
aise::TestingModule tm;
auto cases = tm.generateTestCases("SRS-AISE_F-003", "int main(){}");
assert(cases.size() >= 3); // normal, boundary, exception
PASS();
TEST("TestingModule::execute");
auto exec_result = tm.execute(cases, "./fake_binary");
assert(exec_result.total == cases.size());
PASS();
TEST("TestingModule::computeReqCoverage");
std::vector<aise::RequirementItem> reqs;
aise::RequirementItem r1, r2;
r1.id = "SRS-AISE_F-001";
r2.id = "SRS-AISE_F-002";
reqs.push_back(r1);
reqs.push_back(r2);
std::vector<aise::TestCase> tc_list;
aise::TestCase tc;
tc.req_id = "SRS-AISE_F-001";
tc_list.push_back(tc);
tc.req_id = "SRS-AISE_F-002";
tc_list.push_back(tc);
double cov = tm.computeReqCoverage(reqs, tc_list);
assert(cov == 1.0);
PASS();
}
static void test_engine_process_request() {
TEST("Engine::processRequest - requirements.process");
aise::Engine engine;
engine.initialize();
aise::ApiRequest req;
req.operation = "requirements.process";
req.payload = "新需求条目";
auto resp = engine.processRequest(req);
assert(resp.code == 0);
PASS();
TEST("Engine::processRequest - code.generate");
req.operation = "code.generate";
req.payload = "SRS-AISE_F-001,cpp,default";
resp = engine.processRequest(req);
assert(resp.code == 0);
PASS();
TEST("Engine::processRequest - testing.run");
req.operation = "testing.run";
req.payload = "auto";
resp = engine.processRequest(req);
assert(resp.code == 0);
PASS();
TEST("Engine::processRequest - unknown operation");
req.operation = "unknown.op";
resp = engine.processRequest(req);
assert(resp.code == -9);
PASS();
engine.shutdown();
}
int main() {
std::cout << "========================================\n";
std::cout << " AISE Platform - Unit Tests\n";
std::cout << "========================================\n\n";
test_engine_initialization();
test_requirements_process();
test_codegen_generate();
test_testing_module();
test_engine_process_request();
std::cout << "\n========================================\n";
std::cout << " Results: " << pass_count << "/" << test_count << " passed\n";
std::cout << "========================================\n";
return (pass_count == test_count) ? 0 : 1;
}