Add unit tests for OpenAI plugin and establish coding standards

- Introduced comprehensive unit tests for the OpenAI plugin, covering SSE parsing, sentinel matching, delta extraction, request building, and more.
- Created a new markdown file detailing coding and naming conventions for the dstalk project, including guidelines for comments, naming rules, code organization, and memory management practices.
This commit is contained in:
2026-05-31 00:51:59 +08:00
parent f2da0f2ed4
commit f6cb51b40a
21 changed files with 343 additions and 131 deletions

View File

@@ -0,0 +1,138 @@
# dstalk 编码规范和命名规范
## 一、编程语言
- 核心库和插件C11 / C++20
- 插件边界:纯 C ABI`extern "C"`),禁止跨 DLL 传递 C++ 对象
- 构建系统CMake 3.21+Ninja 生成器
## 二、注释规范
### 2.1 文件头注释(必须)
每个源文件(`.cpp` / `.hpp` / `.h`)开头必须有文件头注释,格式如下:
```cpp
/*
* @file 文件名.cpp
* @brief 英文简述。
* 中文简述。
* @version 0.1.1
* @date 2026-06-01
* Copyright (c) 2026 dstalk contributors. GPLv3.
*
* @changelog
* - 2026-06-01 v0.1.1: 修复线程安全问题 / Fix thread-safety issue
* - 2026-05-31 v0.1.0: 初始版本 / Initial version
*/
```
**规则说明**
- `@version`: 当前文件版本号,必须与 `@changelog` 最新条目一致
- `@date`: 最后修改日期,与 `@version` 同步更新
- `@changelog`: **每次修改代码时,必须在最上方新增一行**,格式为 `- 日期 版本: 中文说明 / English description`
- 最新变更始终在第一行,方便快速查看文件当前版本和最近改动
- 仅记录功能性变更bug修复、新功能、重构等纯注释或格式调整不需要记录
- 版本号递增规则:修订号用于 bugfix次版本号用于新功能主版本号用于不兼容变更
### 2.2 函数注释(必须)
每个函数/方法定义上方必须有中英双语注释,格式:
```cpp
// 从 TOML 文件加载键值对 / Load key-value pairs from a TOML file
int ConfigStore::load_file(const char* path)
```
### 2.3 行内注释
- 复杂逻辑分块必须有中英双语注释
- 格式:`// 中文说明 / English description`
- 简单代码不需要注释
### 2.4 段落注释
代码段落分隔使用:
```cpp
// === 中文标题 / English Title ===
```
### 2.5 版本变更
文件头的 `@brief` 行简述当前功能即可,详细变更历史通过 git log 追溯,不在文件内维护 changelog。
## 三、命名规范
### 3.1 文件和目录
| 类型 | 规则 | 示例 |
|------|------|------|
| 目录名 | 小写英文 + 数字 + 下划线/连字符,字母或下划线开头 | `dstalk-core``file-io``plugins` |
| 源文件 | 小写英文 + 下划线,字母开头 | `config_store.cpp``openai_plugin.cpp` |
| 头文件 | 同源文件规则 | `dstalk_host.h``event_bus.hpp` |
| 测试文件 | `<模块名>_test.cpp` | `event_bus_test.cpp``openai_plugin_test.cpp` |
### 3.2 C 层(公共 API跨 DLL
| 类型 | 规则 | 示例 |
|------|------|------|
| 函数 | `dstalk_` 前缀 + snake_case | `dstalk_init()``dstalk_service_query()` |
| 类型 | `dstalk_` 前缀 + snake_case + `_t` 后缀 | `dstalk_message_t``dstalk_ai_service_t` |
| 宏 | `DSTALK_` 前缀 + UPPER_SNAKE_CASE | `DSTALK_API``DSTALK_API_VERSION` |
| 枚举值 | `DSTALK_` 前缀 + UPPER_SNAKE_CASE | `DSTALK_LOG_ERROR``DSTALK_EVENT_MESSAGE` |
| 回调类型 | `dstalk_` 前缀 + snake_case + `_fn` / `_cb` 后缀 | `dstalk_stream_cb``dstalk_tool_handler_fn` |
### 3.3 C++ 层(内部实现)
| 类型 | 规则 | 示例 |
|------|------|------|
| 命名空间 | 小写单词 | `dstalk` |
| 类名 | PascalCase | `ConfigStore``EventBus``PluginLoader` |
| 成员变量 | snake_case + `_` 后缀 | `mutex_``data_``next_id_` |
| 局部变量 | snake_case | `history_count``plugin_dir` |
| 全局变量 | `g_` 前缀 + snake_case | `g_ai``g_session``g_quit_requested` |
| 常量 | `k` 前缀 + PascalCase | `kWebUiHtml` |
### 3.4 插件命名
| 类型 | 规则 | 示例 |
|------|------|------|
| 插件目录 | 功能名,小写 + 连字符 | `plugins/openai/``plugins/file-io/` |
| 插件源文件 | `<功能名>_plugin.cpp` | `openai_plugin.cpp``session_plugin.cpp` |
| CMake 目标 | `plugin-<功能名>` | `plugin-openai``plugin-network` |
| 服务注册名 | 小写 + 点号分级 | `"ai.openai"``"http"``"session"` |
| 插件入口函数 | 固定为 `dstalk_plugin_init` | — |
### 3.5 禁止项
- 禁止纯数字命名(如 `123.cpp`
- 禁止中文或特殊字符出现在文件名、变量名中
- 禁止在 C ABI 函数中抛出 C++ 异常(必须 try/catch 包裹)
- 禁止跨 DLL 边界传递 `std::string` 或其他 C++ 类型
## 四、代码组织
### 4.1 目录 README
- `dstalk/`(根目录)和所有二级目录(`dstalk-core/``dstalk-cli/``plugins/` 等)必须有 `README.md`
- 三级目录(如 `plugins/openai/`)如内容简单可暂不添加
### 4.2 include 路径
- 公共头文件放在 `dstalk-core/include/dstalk/`
- 私有实现头文件放在 `dstalk-core/src/`
- 插件不得被 core 反向依赖core 禁止 `#include` 插件目录下的文件)
### 4.3 内存管理
- 跨 DLL 的内存分配必须通过 `host->alloc` / `host->free` / `host->strdup`
- 禁止在一个 DLL 中 `malloc`,在另一个 DLL 中 `free`
- `dstalk_chat_result_t` 中的字符串字段由 `dstalk_strdup` 分配,调用方通过 `free_result()` 释放
## 五、构建规范
- 所有目标输出到 `${CMAKE_BINARY_DIR}/bin`(可执行文件)或 `${CMAKE_BINARY_DIR}/plugins`(插件 DLL
- 新前端通过 `option(DSTALK_BUILD_XXX)` 控制,默认 OFF
- 插件在 `plugins/CMakeLists.txt` 中按依赖顺序 `add_subdirectory`