生成代码工程
This commit is contained in:
parent
ca430d7257
commit
098b8f35a6
|
|
@ -0,0 +1,42 @@
|
|||
cmake_minimum_required(VERSION 3.14)
|
||||
project(BookManager 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 编译选项
|
||||
if (MSVC)
|
||||
add_compile_options(/utf-8)
|
||||
endif()
|
||||
|
||||
# ============================================
|
||||
# 头文件目录
|
||||
# ============================================
|
||||
include_directories(${CMAKE_SOURCE_DIR}/include)
|
||||
|
||||
# ============================================
|
||||
# 主程序可执行文件
|
||||
# ============================================
|
||||
add_executable(book_manager
|
||||
src/main.cpp
|
||||
src/app.cpp
|
||||
src/book.cpp
|
||||
)
|
||||
|
||||
target_include_directories(book_manager PRIVATE
|
||||
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
|
||||
)
|
||||
|
||||
# ============================================
|
||||
# 测试可执行文件(使用标准库 assert)
|
||||
# ============================================
|
||||
add_executable(basic_test
|
||||
tests/basic_test.cpp
|
||||
src/app.cpp
|
||||
src/book.cpp
|
||||
)
|
||||
|
||||
target_include_directories(basic_test PRIVATE
|
||||
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
|
||||
)
|
||||
57
README.md
57
README.md
|
|
@ -1,3 +1,56 @@
|
|||
# 图书管理测试
|
||||
# 图书管理系统 (BookManager)
|
||||
|
||||
暂无描述
|
||||
一个简洁的 C++17 图书管理系统,支持图书的增删改查操作。
|
||||
|
||||
## 功能特性
|
||||
|
||||
- 添加图书(书名、作者、ISBN、是否借出)
|
||||
- 删除图书(按 ISBN)
|
||||
- 查询图书(按 ISBN 或关键字搜索书名/作者)
|
||||
- 借出 / 归还图书
|
||||
- 列出所有图书
|
||||
|
||||
## 构建与运行
|
||||
|
||||
### 前提条件
|
||||
|
||||
- CMake >= 3.14
|
||||
- C++17 兼容编译器(GCC 8+, Clang 7+, MSVC 2019+)
|
||||
|
||||
### 构建步骤
|
||||
|
||||
```bash
|
||||
# 在工程根目录下执行
|
||||
mkdir -p build && cd build
|
||||
cmake ..
|
||||
cmake --build .
|
||||
```
|
||||
|
||||
### 运行主程序
|
||||
|
||||
```bash
|
||||
./book_manager
|
||||
```
|
||||
|
||||
### 运行测试
|
||||
|
||||
```bash
|
||||
./basic_test
|
||||
```
|
||||
|
||||
## 工程结构
|
||||
|
||||
```
|
||||
.
|
||||
├── CMakeLists.txt
|
||||
├── README.md
|
||||
├── include/
|
||||
│ ├── app.hpp # App 主控类声明
|
||||
│ └── book.hpp # Book 数据类声明
|
||||
├── src/
|
||||
│ ├── main.cpp # 命令行入口
|
||||
│ ├── app.cpp # App 主控类实现
|
||||
│ └── book.cpp # Book 数据类实现
|
||||
└── tests/
|
||||
└── basic_test.cpp # 基础单元测试
|
||||
```
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"projectId": 33,
|
||||
"generationId": "codegen_55c8a684080349d59e4857797891b532",
|
||||
"language": "C++",
|
||||
"status": "completed",
|
||||
"fileIds": [],
|
||||
"outputDir": "D:\\devTools\\pyProjects\\ai-agent-integration\\agents\\ai_agents\\project-files\\codegen-runs\\codegen_55c8a684080349d59e4857797891b532",
|
||||
"relativeOutputDir": "codegen-runs/codegen_55c8a684080349d59e4857797891b532",
|
||||
"generatedFiles": [
|
||||
"CMakeLists.txt",
|
||||
"README.md",
|
||||
"events.ndjson",
|
||||
"include/app.hpp",
|
||||
"include/book.hpp",
|
||||
"src/app.cpp",
|
||||
"src/book.cpp",
|
||||
"src/main.cpp",
|
||||
"tests/basic_test.cpp"
|
||||
],
|
||||
"analysisSummary": "未提供参考文件,请仅根据用户自然语言描述生成C++工程。",
|
||||
"eventLogFile": "D:\\devTools\\pyProjects\\ai-agent-integration\\agents\\ai_agents\\project-files\\codegen-runs\\codegen_55c8a684080349d59e4857797891b532\\events.ndjson",
|
||||
"repoSettings": {
|
||||
"username": "root",
|
||||
"password": "pAssW0rd",
|
||||
"repoUrl": "http://47.108.255.216:3000/root/tushu.git",
|
||||
"branch": "main"
|
||||
},
|
||||
"repoUrl": "http://47.108.255.216:3000/root/tushu.git",
|
||||
"branch": "main"
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
#ifndef APP_HPP
|
||||
#define APP_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "book.hpp"
|
||||
|
||||
/// @brief 图书管理系统的主控类
|
||||
///
|
||||
/// 提供增删改查等核心业务逻辑,内部使用 std::vector<Book> 存储。
|
||||
class App {
|
||||
public:
|
||||
/// @brief 默认构造函数,初始化空的图书系统
|
||||
App() = default;
|
||||
|
||||
/// @brief 添加一本图书
|
||||
/// @param book 要添加的图书对象
|
||||
/// @return true 如果添加成功;如果 ISBN 已存在则返回 false
|
||||
bool addBook(const Book& book);
|
||||
|
||||
/// @brief 根据 ISBN 删除图书
|
||||
/// @param isbn 要删除的图书 ISBN
|
||||
/// @return true 如果找到并删除成功;否则返回 false
|
||||
bool removeBook(const std::string& isbn);
|
||||
|
||||
/// @brief 根据 ISBN 查找图书
|
||||
/// @param isbn 要查找的 ISBN
|
||||
/// @return 指向找到的图书的指针,未找到返回 nullptr
|
||||
[[nodiscard]] const Book* findByIsbn(const std::string& isbn) const;
|
||||
|
||||
/// @brief 根据关键字搜索(匹配书名或作者,不区分大小写)
|
||||
/// @param keyword 搜索关键字
|
||||
/// @return 匹配的图书列表
|
||||
[[nodiscard]] std::vector<Book> search(const std::string& keyword) const;
|
||||
|
||||
/// @brief 借出图书
|
||||
/// @param isbn 要借出的图书 ISBN
|
||||
/// @return true 如果图书存在且未被借出;否则 false
|
||||
bool borrowBook(const std::string& isbn);
|
||||
|
||||
/// @brief 归还图书
|
||||
/// @param isbn 要归还的图书 ISBN
|
||||
/// @return true 如果图书存在且已借出;否则 false
|
||||
bool returnBook(const std::string& isbn);
|
||||
|
||||
/// @brief 获取所有图书列表
|
||||
/// @return 所有图书的常量引用向量
|
||||
[[nodiscard]] const std::vector<Book>& getAllBooks() const noexcept;
|
||||
|
||||
/// @brief 获取图书数量
|
||||
/// @return 当前图书总数
|
||||
[[nodiscard]] size_t size() const noexcept;
|
||||
|
||||
private:
|
||||
std::vector<Book> books_;
|
||||
|
||||
/// @brief 辅助函数:将字符串转为小写
|
||||
/// @param str 输入字符串
|
||||
/// @return 全小写字符串
|
||||
static std::string toLower(const std::string& str);
|
||||
};
|
||||
|
||||
#endif // APP_HPP
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
#ifndef BOOK_HPP
|
||||
#define BOOK_HPP
|
||||
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
|
||||
/// @brief 表示一本图书的数据模型
|
||||
class Book {
|
||||
public:
|
||||
/// @brief 默认构造函数
|
||||
Book() = default;
|
||||
|
||||
/// @brief 构造一本完整的图书
|
||||
/// @param title 书名
|
||||
/// @param author 作者
|
||||
/// @param isbn ISBN 编号
|
||||
/// @param borrowed 是否已借出,默认 false
|
||||
Book(std::string title,
|
||||
std::string author,
|
||||
std::string isbn,
|
||||
bool borrowed = false);
|
||||
|
||||
/// @brief 获取书名
|
||||
/// @return 书名常量引用
|
||||
[[nodiscard]] const std::string& getTitle() const noexcept;
|
||||
|
||||
/// @brief 获取作者
|
||||
/// @return 作者常量引用
|
||||
[[nodiscard]] const std::string& getAuthor() const noexcept;
|
||||
|
||||
/// @brief 获取 ISBN
|
||||
/// @return ISBN 常量引用
|
||||
[[nodiscard]] const std::string& getIsbn() const noexcept;
|
||||
|
||||
/// @brief 判断是否已借出
|
||||
/// @return true 表示已借出
|
||||
[[nodiscard]] bool isBorrowed() const noexcept;
|
||||
|
||||
/// @brief 设置借出状态
|
||||
/// @param borrowed true 表示已借出
|
||||
void setBorrowed(bool borrowed) noexcept;
|
||||
|
||||
/// @brief 重载 ==,比较 ISBN 是否相同
|
||||
/// @param rhs 另一本图书
|
||||
/// @return true 当 ISBN 相同
|
||||
bool operator==(const Book& rhs) const;
|
||||
|
||||
/// @brief 输出图书信息到流
|
||||
/// @param os 输出流
|
||||
/// @param b 图书对象
|
||||
/// @return 输出流引用
|
||||
friend std::ostream& operator<<(std::ostream& os, const Book& b);
|
||||
|
||||
private:
|
||||
std::string title_;
|
||||
std::string author_;
|
||||
std::string isbn_;
|
||||
bool borrowed_ = false;
|
||||
};
|
||||
|
||||
#endif // BOOK_HPP
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
#include "app.hpp"
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <utility>
|
||||
|
||||
/// @brief 将字符串转为小写(辅助函数)
|
||||
std::string App::toLower(const std::string& str) {
|
||||
std::string result;
|
||||
result.reserve(str.size());
|
||||
for (const char c : str) {
|
||||
result.push_back(static_cast<char>(std::tolower(static_cast<unsigned char>(c))));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// @brief 添加一本图书
|
||||
/// @param book 要添加的图书对象
|
||||
/// @return true 如果添加成功;如果 ISBN 已存在则返回 false
|
||||
bool App::addBook(const Book& book) {
|
||||
// 检查 ISBN 是否已存在
|
||||
if (findByIsbn(book.getIsbn()) != nullptr) {
|
||||
return false;
|
||||
}
|
||||
books_.push_back(book);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @brief 根据 ISBN 删除图书
|
||||
/// @param isbn 要删除的图书 ISBN
|
||||
/// @return true 如果找到并删除成功;否则返回 false
|
||||
bool App::removeBook(const std::string& isbn) {
|
||||
const auto it = std::find_if(books_.begin(), books_.end(),
|
||||
[&isbn](const Book& b) { return b.getIsbn() == isbn; });
|
||||
|
||||
if (it == books_.end()) {
|
||||
return false;
|
||||
}
|
||||
books_.erase(it);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @brief 根据 ISBN 查找图书
|
||||
/// @param isbn 要查找的 ISBN
|
||||
/// @return 指向找到的图书的指针,未找到返回 nullptr
|
||||
const Book* App::findByIsbn(const std::string& isbn) const {
|
||||
const auto it = std::find_if(books_.cbegin(), books_.cend(),
|
||||
[&isbn](const Book& b) { return b.getIsbn() == isbn; });
|
||||
|
||||
if (it == books_.cend()) {
|
||||
return nullptr;
|
||||
}
|
||||
return &(*it);
|
||||
}
|
||||
|
||||
/// @brief 根据关键字搜索(匹配书名或作者,不区分大小写)
|
||||
/// @param keyword 搜索关键字
|
||||
/// @return 匹配的图书列表
|
||||
std::vector<Book> App::search(const std::string& keyword) const {
|
||||
const std::string lowerKw = toLower(keyword);
|
||||
std::vector<Book> result;
|
||||
|
||||
for (const auto& b : books_) {
|
||||
const std::string lowerTitle = toLower(b.getTitle());
|
||||
const std::string lowerAuthor = toLower(b.getAuthor());
|
||||
if (lowerTitle.find(lowerKw) != std::string::npos ||
|
||||
lowerAuthor.find(lowerKw) != std::string::npos) {
|
||||
result.push_back(b);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// @brief 借出图书
|
||||
/// @param isbn 要借出的图书 ISBN
|
||||
/// @return true 如果图书存在且未被借出;否则 false
|
||||
bool App::borrowBook(const std::string& isbn) {
|
||||
auto it = std::find_if(books_.begin(), books_.end(),
|
||||
[&isbn](const Book& b) { return b.getIsbn() == isbn; });
|
||||
|
||||
if (it == books_.end() || it->isBorrowed()) {
|
||||
return false;
|
||||
}
|
||||
it->setBorrowed(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @brief 归还图书
|
||||
/// @param isbn 要归还的图书 ISBN
|
||||
/// @return true 如果图书存在且已借出;否则 false
|
||||
bool App::returnBook(const std::string& isbn) {
|
||||
auto it = std::find_if(books_.begin(), books_.end(),
|
||||
[&isbn](const Book& b) { return b.getIsbn() == isbn; });
|
||||
|
||||
if (it == books_.end() || !it->isBorrowed()) {
|
||||
return false;
|
||||
}
|
||||
it->setBorrowed(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @brief 获取所有图书列表
|
||||
const std::vector<Book>& App::getAllBooks() const noexcept {
|
||||
return books_;
|
||||
}
|
||||
|
||||
/// @brief 获取图书数量
|
||||
size_t App::size() const noexcept {
|
||||
return books_.size();
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
#include "book.hpp"
|
||||
#include <utility>
|
||||
#include <cctype>
|
||||
|
||||
/// @brief 构造一本完整的图书
|
||||
/// @param title 书名
|
||||
/// @param author 作者
|
||||
/// @param isbn ISBN 编号
|
||||
/// @param borrowed 是否已借出
|
||||
Book::Book(std::string title,
|
||||
std::string author,
|
||||
std::string isbn,
|
||||
const bool borrowed)
|
||||
: title_(std::move(title))
|
||||
, author_(std::move(author))
|
||||
, isbn_(std::move(isbn))
|
||||
, borrowed_(borrowed) {}
|
||||
|
||||
/// @brief 获取书名
|
||||
const std::string& Book::getTitle() const noexcept { return title_; }
|
||||
|
||||
/// @brief 获取作者
|
||||
const std::string& Book::getAuthor() const noexcept { return author_; }
|
||||
|
||||
/// @brief 获取 ISBN
|
||||
const std::string& Book::getIsbn() const noexcept { return isbn_; }
|
||||
|
||||
/// @brief 判断是否已借出
|
||||
bool Book::isBorrowed() const noexcept { return borrowed_; }
|
||||
|
||||
/// @brief 设置借出状态
|
||||
void Book::setBorrowed(const bool borrowed) noexcept { borrowed_ = borrowed; }
|
||||
|
||||
/// @brief 重载 ==,比较 ISBN 是否相同
|
||||
bool Book::operator==(const Book& rhs) const {
|
||||
return isbn_ == rhs.isbn_;
|
||||
}
|
||||
|
||||
/// @brief 输出图书信息到流
|
||||
/// 格式示例:[已借出] 《书名》 作者 / ISBN
|
||||
std::ostream& operator<<(std::ostream& os, const Book& b) {
|
||||
os << (b.borrowed_ ? "[已借出] " : "[在馆] ")
|
||||
<< "《" << b.title_ << "》 "
|
||||
<< b.author_ << " / "
|
||||
<< b.isbn_;
|
||||
return os;
|
||||
}
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include "app.hpp"
|
||||
|
||||
/// @brief 显示所有图书
|
||||
/// @param app 图书管理系统实例
|
||||
static void listAllBooks(const App& app) {
|
||||
const auto& books = app.getAllBooks();
|
||||
if (books.empty()) {
|
||||
std::cout << "📚 当前没有图书。\n";
|
||||
return;
|
||||
}
|
||||
std::cout << "\n===== 全部图书 (" << books.size() << " 本) =====\n";
|
||||
for (size_t i = 0; i < books.size(); ++i) {
|
||||
std::cout << i + 1 << ". " << books[i] << "\n";
|
||||
}
|
||||
std::cout << "==========================\n\n";
|
||||
}
|
||||
|
||||
/// @brief 打印操作菜单
|
||||
static void printMenu() {
|
||||
std::cout << "\n====== 图书管理系统 ======\n"
|
||||
<< "1. 添加图书\n"
|
||||
<< "2. 删除图书\n"
|
||||
<< "3. 查找图书 (ISBN)\n"
|
||||
<< "4. 搜索图书 (关键字)\n"
|
||||
<< "5. 借出图书\n"
|
||||
<< "6. 归还图书\n"
|
||||
<< "7. 列出所有图书\n"
|
||||
<< "0. 退出\n"
|
||||
<< "请选择: ";
|
||||
}
|
||||
|
||||
/// @brief 程序主入口
|
||||
/// @return 0 表示正常退出
|
||||
int main() {
|
||||
App app;
|
||||
|
||||
// 预置几本示例图书
|
||||
app.addBook(Book{"C++ Primer", "Stanley Lippman", "978-7-111-1"});
|
||||
app.addBook(Book{"Effective Modern C++", "Scott Meyers", "978-7-111-2"});
|
||||
app.addBook(Book{"设计模式", "GoF", "978-7-111-3"});
|
||||
|
||||
std::cout << "欢迎使用图书管理系统!\n";
|
||||
|
||||
int choice = -1;
|
||||
while (choice != 0) {
|
||||
printMenu();
|
||||
std::string input;
|
||||
std::getline(std::cin, input);
|
||||
|
||||
// 处理空输入
|
||||
if (input.empty()) {
|
||||
continue;
|
||||
}
|
||||
choice = std::atoi(input.c_str());
|
||||
|
||||
switch (choice) {
|
||||
case 1: {
|
||||
std::string title, author, isbn;
|
||||
std::cout << "书名: "; std::getline(std::cin, title);
|
||||
std::cout << "作者: "; std::getline(std::cin, author);
|
||||
std::cout << "ISBN: "; std::getline(std::cin, isbn);
|
||||
if (app.addBook(Book{title, author, isbn})) {
|
||||
std::cout << "✅ 添加成功!\n";
|
||||
} else {
|
||||
std::cout << "❌ ISBN 已存在,添加失败。\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
std::string isbn;
|
||||
std::cout << "请输入要删除的 ISBN: ";
|
||||
std::getline(std::cin, isbn);
|
||||
if (app.removeBook(isbn)) {
|
||||
std::cout << "✅ 删除成功!\n";
|
||||
} else {
|
||||
std::cout << "❌ 未找到该 ISBN。\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
std::string isbn;
|
||||
std::cout << "请输入 ISBN: ";
|
||||
std::getline(std::cin, isbn);
|
||||
const Book* book = app.findByIsbn(isbn);
|
||||
if (book) {
|
||||
std::cout << "✅ 找到: " << *book << "\n";
|
||||
} else {
|
||||
std::cout << "❌ 未找到该 ISBN。\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
std::string keyword;
|
||||
std::cout << "请输入关键字: ";
|
||||
std::getline(std::cin, keyword);
|
||||
const auto results = app.search(keyword);
|
||||
if (results.empty()) {
|
||||
std::cout << "❌ 没有找到匹配的图书。\n";
|
||||
} else {
|
||||
std::cout << "✅ 找到 " << results.size() << " 本:\n";
|
||||
for (size_t i = 0; i < results.size(); ++i) {
|
||||
std::cout << " " << i + 1 << ". " << results[i] << "\n";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 5: {
|
||||
std::string isbn;
|
||||
std::cout << "请输入要借出的 ISBN: ";
|
||||
std::getline(std::cin, isbn);
|
||||
if (app.borrowBook(isbn)) {
|
||||
std::cout << "✅ 借出成功!\n";
|
||||
} else {
|
||||
std::cout << "❌ 借出失败(可能 ISBN 不存在或已被借出)。\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 6: {
|
||||
std::string isbn;
|
||||
std::cout << "请输入要归还的 ISBN: ";
|
||||
std::getline(std::cin, isbn);
|
||||
if (app.returnBook(isbn)) {
|
||||
std::cout << "✅ 归还成功!\n";
|
||||
} else {
|
||||
std::cout << "❌ 归还失败(可能 ISBN 不存在或未借出)。\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
listAllBooks(app);
|
||||
break;
|
||||
case 0:
|
||||
std::cout << "感谢使用,再见!\n";
|
||||
break;
|
||||
default:
|
||||
std::cout << "无效选项,请重新输入。\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include "app.hpp"
|
||||
|
||||
/// @brief 测试图书管理系统核心功能
|
||||
/// 使用标准库 assert,不依赖第三方测试框架。
|
||||
static void testAddAndFind() {
|
||||
std::cout << "[Test] testAddAndFind ... ";
|
||||
App app;
|
||||
assert(app.size() == 0);
|
||||
|
||||
Book b1{"书名A", "作者A", "ISBN-001"};
|
||||
assert(app.addBook(b1));
|
||||
assert(app.size() == 1);
|
||||
|
||||
// 重复 ISBN 应返回 false
|
||||
Book b2{"书名B", "作者B", "ISBN-001"};
|
||||
assert(!app.addBook(b2));
|
||||
assert(app.size() == 1);
|
||||
|
||||
const Book* found = app.findByIsbn("ISBN-001");
|
||||
assert(found != nullptr);
|
||||
assert(found->getTitle() == "书名A");
|
||||
assert(found->getAuthor() == "作者A");
|
||||
|
||||
// 不存在的 ISBN
|
||||
assert(app.findByIsbn("ISBN-999") == nullptr);
|
||||
std::cout << "PASSED\n";
|
||||
}
|
||||
|
||||
/// @brief 测试删除功能
|
||||
static void testRemove() {
|
||||
std::cout << "[Test] testRemove ... ";
|
||||
App app;
|
||||
app.addBook(Book{"A", "a", "X"});
|
||||
app.addBook(Book{"B", "b", "Y"});
|
||||
assert(app.size() == 2);
|
||||
|
||||
// 删除存在的
|
||||
assert(app.removeBook("X"));
|
||||
assert(app.size() == 1);
|
||||
|
||||
// 删除不存在的
|
||||
assert(!app.removeBook("Z"));
|
||||
assert(app.size() == 1);
|
||||
|
||||
std::cout << "PASSED\n";
|
||||
}
|
||||
|
||||
/// @brief 测试搜索功能(不区分大小写)
|
||||
static void testSearch() {
|
||||
std::cout << "[Test] testSearch ... ";
|
||||
App app;
|
||||
app.addBook(Book{"C++ Primer", "Stanley Lippman", "I1"});
|
||||
app.addBook(Book{"Effective Modern C++", "Scott Meyers", "I2"});
|
||||
app.addBook(Book{"设计模式", "GoF", "I3"});
|
||||
|
||||
// 按书名搜索(不区分大小写)
|
||||
auto r1 = app.search("c++");
|
||||
assert(r1.size() == 2);
|
||||
|
||||
// 按作者搜索
|
||||
auto r2 = app.search("stanley");
|
||||
assert(r2.size() == 1);
|
||||
assert(r2[0].getIsbn() == "I1");
|
||||
|
||||
// 无匹配
|
||||
auto r3 = app.search("不存在的书");
|
||||
assert(r3.empty());
|
||||
|
||||
std::cout << "PASSED\n";
|
||||
}
|
||||
|
||||
/// @brief 测试借出和归还
|
||||
static void testBorrowReturn() {
|
||||
std::cout << "[Test] testBorrowReturn ... ";
|
||||
App app;
|
||||
app.addBook(Book{"A", "a", "I-A"});
|
||||
|
||||
// 借出
|
||||
assert(app.borrowBook("I-A"));
|
||||
const Book* b = app.findByIsbn("I-A");
|
||||
assert(b != nullptr);
|
||||
assert(b->isBorrowed());
|
||||
|
||||
// 重复借出应失败
|
||||
assert(!app.borrowBook("I-A"));
|
||||
|
||||
// 归还
|
||||
assert(app.returnBook("I-A"));
|
||||
assert(!b->isBorrowed());
|
||||
|
||||
// 重复归还应失败
|
||||
assert(!app.returnBook("I-A"));
|
||||
|
||||
// 不存在的 ISBN
|
||||
assert(!app.borrowBook("I-NONE"));
|
||||
assert(!app.returnBook("I-NONE"));
|
||||
|
||||
std::cout << "PASSED\n";
|
||||
}
|
||||
|
||||
/// @brief 主测试入口
|
||||
int main() {
|
||||
std::cout << "===== 图书管理系统单元测试 =====\n\n";
|
||||
|
||||
testAddAndFind();
|
||||
testRemove();
|
||||
testSearch();
|
||||
testBorrowReturn();
|
||||
|
||||
std::cout << "\n✅ 所有测试通过!\n";
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue