生成代码工程
This commit is contained in:
parent
3ab57c4681
commit
38d8cca2e8
|
|
@ -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)
|
||||
65
README.md
65
README.md
|
|
@ -1,49 +1,32 @@
|
|||
没问题,根据你的要求,我为你撰写了一份《任务自主规划与执行软件需求规格说明书》。
|
||||
# AISE Platform — 智能化工程支撑平台
|
||||
|
||||
这份文档涵盖了从用户交互、核心规划引擎到执行监控及非功能性需求的完整分析。你可以直接阅读,也可以利用App的朗读功能将其转为语音文件。
|
||||
## 概述
|
||||
|
||||
📋 任务自主规划与执行软件需求规格说明书
|
||||
AISE(AI-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 自主规划引擎
|
||||
动态排程: 基于用户设定的“专注时间段”、历史工作效率数据及任务优先级,自动将任务填充至日程表中。
|
||||
冲突检测与解决: 当新任务与现有日程冲突时,系统应提供自动调整建议(如推迟低优先级任务、延长工作时间或拆分任务)。
|
||||
依赖关系管理: 识别任务间的先后顺序(如“必须先完成A才能开始B”),确保规划逻辑的合理性。
|
||||
```bash
|
||||
mkdir -p build && cd build
|
||||
cmake ..
|
||||
cmake --build .
|
||||
./aise # 运行主程序
|
||||
./aise_test # 运行测试
|
||||
```
|
||||
|
||||
2.3 执行辅助与自动化
|
||||
智能提醒: 根据任务准备时间和用户当前位置/状态,提供最佳开始时间的提醒,而非仅截止提醒。
|
||||
自动化工作流: 针对重复性或规则明确的任务(如“每周五发送周报”),系统应具备自动执行或一键生成的能力。
|
||||
干扰屏蔽: 在执行高优先级任务期间,自动屏蔽非紧急通知。
|
||||
## 技术栈
|
||||
|
||||
2.4 监控与反馈闭环
|
||||
进度追踪: 实时可视化任务完成进度,对比“计划时间”与“实际耗时”。
|
||||
自适应学习: 若用户频繁推迟某类任务,系统应自动调整对该类任务的时间预估模型,优化未来规划。
|
||||
|
||||
非功能性需求
|
||||
|
||||
3.1 性能要求
|
||||
规划响应速度: 复杂任务重排程算法应在3秒内完成计算并呈现结果。
|
||||
同步延迟: 多端(手机、PC、穿戴设备)数据同步延迟不得超过1秒。
|
||||
|
||||
3.2 安全与隐私
|
||||
数据加密: 所有用户任务数据及个人日程信息需采用端到端加密存储。
|
||||
权限控制: 若涉及企业版,需支持基于角色的访问控制,确保任务数据隔离。
|
||||
|
||||
3.3 可用性与交互
|
||||
极简交互: 核心功能(添加任务、查看今日计划)应在3次点击内完成。
|
||||
可视化: 提供甘特图、看板、日历等多种视图模式,满足不同用户的认知习惯。
|
||||
|
||||
用户角色定义
|
||||
个人用户: 关注个人效率、习惯养成及工作生活平衡。
|
||||
团队管理者: 关注任务分配、团队整体进度及瓶颈识别。
|
||||
|
||||
💡 如何转为语音文件:
|
||||
你可以长按我刚才回复的这条消息,选择“朗读”或类似选项,手机就会把这段文字读出来。如果需要保存为文件,可以使用手机自带的录屏或录音功能将声音录制下来。
|
||||
- C++17 / CMake 3.14+
|
||||
- 无外部第三方依赖
|
||||
- 支持 MSVC (Windows) 与 GCC/Clang (Linux)
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
Loading…
Reference in New Issue