"""
工具模块测试用例
"""
import pytest
import time
from pathlib import Path
from unittest.mock import Mock, patch
# 添加源码路径
import sys
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'src'))
from utils.progress import (
TaskStatus,
TaskInfo,
ProgressTracker,
ProgressBar,
ProgressContext
)
from utils.interaction import (
InteractionLevel,
MessageType,
UserMessage,
InteractionManager
)
from utils.compatibility import (
Platform,
Architecture,
SystemInfo,
CompatibilityManager
)
from utils.version_manager import (
VersionType,
Version,
VersionManager
)
class TestTaskInfo:
"""任务信息测试"""
def test_task_info_creation(self):
"""测试任务信息创建"""
task = TaskInfo(
id="test_task",
name="Test Task",
status=TaskStatus.RUNNING,
progress=50.0,
message="Processing..."
)
assert task.id == "test_task"
assert task.name == "Test Task"
assert task.status == TaskStatus.RUNNING
assert task.progress == 50.0
assert task.message == "Processing..."
def test_task_info_elapsed_time(self):
"""测试任务已用时间"""
task = TaskInfo(
id="test_task",
name="Test Task",
status=TaskStatus.RUNNING
)
# 未开始的任务,已用时间为0
assert task.elapsed_time == 0.0
# 模拟开始时间
task.start_time = time.time() - 10
elapsed = task.elapsed_time
assert 9.0 <= elapsed <= 11.0 # 允许一些时间误差
def test_task_info_is_finished(self):
"""测试任务是否完成"""
# 运行中的任务
task_running = TaskInfo(
id="test_task",
name="Test Task",
status=TaskStatus.RUNNING
)
assert task_running.is_finished is False
# 完成的任务
task_completed = TaskInfo(
id="test_task",
name="Test Task",
status=TaskStatus.COMPLETED
)
assert task_completed.is_finished is True
# 失败的任务
task_failed = TaskInfo(
id="test_task",
name="Test Task",
status=TaskStatus.FAILED
)
assert task_failed.is_finished is True
class TestProgressTracker:
"""进度跟踪器测试"""
def setup_method(self):
"""设置测试环境"""
self.tracker = ProgressTracker()
def test_create_task(self):
"""测试创建任务"""
task = self.tracker.create_task("test_task", "Test Task")
assert task.id == "test_task"
assert task.name == "Test Task"
assert task.status == TaskStatus.PENDING
assert "test_task" in self.tracker.tasks
def test_create_duplicate_task(self):
"""测试创建重复任务"""
self.tracker.create_task("test_task", "Test Task")
# 尝试创建同名任务应该失败
with pytest.raises(ValueError):
self.tracker.create_task("test_task", "Another Task")
def test_start_task(self):
"""测试开始任务"""
task = self.tracker.create_task("test_task", "Test Task")
self.tracker.start_task("test_task")
assert task.status == TaskStatus.RUNNING
assert task.start_time is not None
def test_update_progress(self):
"""测试更新进度"""
task = self.tracker.create_task("test_task", "Test Task")
self.tracker.start_task("test_task")
self.tracker.update_progress("test_task", 75.0, "Almost done")
assert task.progress == 75.0
assert task.message == "Almost done"
def test_complete_task(self):
"""测试完成任务"""
task = self.tracker.create_task("test_task", "Test Task")
self.tracker.start_task("test_task")
self.tracker.complete_task("test_task", "All done")
assert task.status == TaskStatus.COMPLETED
assert task.progress == 100.0
assert task.message == "All done"
assert task.end_time is not None
def test_fail_task(self):
"""测试任务失败"""
task = self.tracker.create_task("test_task", "Test Task")
self.tracker.start_task("test_task")
self.tracker.fail_task("test_task", "Error occurred")
assert task.status == TaskStatus.FAILED
assert task.message == "Error occurred"
assert task.end_time is not None
def test_progress_callback(self):
"""测试进度回调"""
callback_called = []
def test_callback(task):
callback_called.append(task)
self.tracker.register_callback("test_task", test_callback)
task = self.tracker.create_task("test_task", "Test Task")
self.tracker.start_task("test_task")
self.tracker.update_progress("test_task", 50.0)
assert len(callback_called) >= 2 # 开始和进度更新
class TestProgressBar:
"""进度条测试"""
def setup_method(self):
"""设置测试环境"""
self.progress_bar = ProgressBar(width=20)
def test_render_start(self):
"""测试渲染开始状态"""
task = TaskInfo(
id="test_task",
name="Test Task",
progress=0.0,
message="Starting..."
)
rendered = self.progress_bar.render(task)
assert "Test Task" in rendered
assert "[░░░░░░░░░░░░░░░░░░░░]" in rendered
assert "0.0%" in rendered
assert "Starting..." in rendered
def test_render_middle(self):
"""测试渲染中间状态"""
task = TaskInfo(
id="test_task",
name="Test Task",
progress=50.0,
message="Processing..."
)
rendered = self.progress_bar.render(task)
assert "Test Task" in rendered
assert "[██████████░░░░░░░░]" in rendered
assert "50.0%" in rendered
assert "Processing..." in rendered
def test_render_complete(self):
"""测试渲染完成状态"""
task = TaskInfo(
id="test_task",
name="Test Task",
progress=100.0,
message="Complete!"
)
rendered = self.progress_bar.render(task)
assert "Test Task" in rendered
assert "[████████████████████]" in rendered
assert "100.0%" in rendered
assert "Complete!" in rendered
class TestInteractionManager:
"""交互管理器测试"""
def setup_method(self):
"""设置测试环境"""
self.interaction = InteractionManager()
def test_message_creation(self):
"""测试消息创建"""
message = self.interaction.message(
MessageType.INFO,
"Test Title",
"Test Content"
)
assert isinstance(message, UserMessage)
assert message.type == MessageType.INFO
assert message.title == "Test Title"
assert message.content == "Test Content"
def test_should_show_by_level(self):
"""测试按级别显示消息"""
# 基本级别应该只显示错误和成功消息
self.interaction.set_level(InteractionLevel.BASIC)
assert self.interaction.should_show(MessageType.ERROR) is True
assert self.interaction.should_show(MessageType.SUCCESS) is True
assert self.interaction.should_show(MessageType.INFO) is False
assert self.interaction.should_show(MessageType.DEBUG) is False
# 详细级别应该显示所有消息
self.interaction.set_level(InteractionLevel.VERBOSE)
assert self.interaction.should_show(MessageType.ERROR) is True
assert self.interaction.should_show(MessageType.SUCCESS) is True
assert self.interaction.should_show(MessageType.INFO) is True
assert self.interaction.should_show(MessageType.DEBUG) is True
def test_convenience_methods(self):
"""测试便捷方法"""
# 测试各种便捷方法不抛出异常
info_msg = self.interaction.info("Info Title", "Info Content")
success_msg = self.interaction.success("Success Title", "Success Content")
warning_msg = self.interaction.warning("Warning Title", "Warning Content")
error_msg = self.interaction.error("Error Title", "Error Content")
debug_msg = self.interaction.debug("Debug Title", "Debug Content")
assert info_msg.type == MessageType.INFO
assert success_msg.type == MessageType.SUCCESS
assert warning_msg.type == MessageType.WARNING
assert error_msg.type == MessageType.ERROR
assert debug_msg.type == MessageType.DEBUG
def test_message_history(self):
"""测试消息历史"""
self.interaction.info("Test 1", "Content 1")
self.interaction.error("Test 2", "Content 2")
history = self.interaction.get_history()
assert len(history) == 2
assert history[0].title == "Test 1"
assert history[1].title == "Test 2"
error_history = self.interaction.get_history(MessageType.ERROR)
assert len(error_history) == 1
assert error_history[0].title == "Test 2"
class TestCompatibilityManager:
"""兼容性管理器测试"""
def setup_method(self):
"""设置测试环境"""
self.compatibility = CompatibilityManager()
def test_system_info_detection(self):
"""测试系统信息检测"""
system_info = self.compatibility.get_system_info()
assert isinstance(system_info, SystemInfo)
assert isinstance(system_info.platform, Platform)
assert isinstance(system_info.architecture, Architecture)
assert isinstance(system_info.python_version, str)
assert isinstance(system_info.os_version, str)
def test_normalize_path_windows(self):
"""测试Windows路径标准化"""
# 模拟Windows环境
with patch.object(self.compatibility, 'system_info') as mock_info:
mock_info.platform = Platform.WINDOWS
# Unix风格路径转换为Windows风格
normalized = self.compatibility.normalize_path("src/utils/test.py")
assert normalized == "src\\utils\\test.py"
# 驱动器字母大写
normalized = self.compatibility.normalize_path("c:\\users\\test")
assert normalized == "C:\\users\\test"
def test_normalize_path_unix(self):
"""测试Unix路径标准化"""
# 模拟Unix环境
with patch.object(self.compatibility, 'system_info') as mock_info:
mock_info.platform = Platform.LINUX
# Windows风格路径转换为Unix风格
normalized = self.compatibility.normalize_path("src\\utils\\test.py")
assert normalized == "src/utils/test.py"
def test_get_executable_extension(self):
"""测试获取可执行文件扩展名"""
with patch.object(self.compatibility, 'system_info') as mock_info:
# Windows环境
mock_info.platform = Platform.WINDOWS
assert self.compatibility.get_executable_extension() == ".exe"
# Unix环境
mock_info.platform = Platform.LINUX
assert self.compatibility.get_executable_extension() == ""
def test_endpoint_registration(self):
"""测试API端点注册"""
from utils.compatibility import APIEndpoint, APIVersion
endpoint = APIEndpoint(
path="/api/test",
method="GET",
version=APIVersion.V1,
description="Test endpoint"
)
self.compatibility.register_endpoint("test_endpoint", endpoint)
retrieved = self.compatibility.get_endpoint("test_endpoint")
assert retrieved is not None
assert retrieved.path == "/api/test"
assert retrieved.method == "GET"
assert retrieved.version == APIVersion.V1
class TestVersionManager:
"""版本管理器测试"""
def setup_method(self):
"""设置测试环境"""
self.version_manager = VersionManager("test_version.json")
def test_version_parsing(self):
"""测试版本解析"""
# 标准版本
version = Version.parse("1.2.3")
assert version.major == 1
assert version.minor == 2
assert version.patch == 3
assert version.prerelease == ""
assert version.build == ""
assert str(version) == "1.2.3"
# 预发布版本
version = Version.parse("1.2.3-alpha.1")
assert version.major == 1
assert version.minor == 2
assert version.patch == 3
assert version.prerelease == "alpha.1"
assert version.build == ""
assert str(version) == "1.2.3-alpha.1"
# 构建版本
version = Version.parse("1.2.3+build.123")
assert version.major == 1
assert version.minor == 2
assert version.patch == 3
assert version.prerelease == ""
assert version.build == "build.123"
assert str(version) == "1.2.3+build.123"
def test_version_comparison(self):
"""测试版本比较"""
v1 = Version.parse("1.2.3")
v2 = Version.parse("1.2.4")
v3 = Version.parse("2.0.0")
assert v1.compare_to(v2) < 0
assert v2.compare_to(v1) > 0
assert v1.compare_to(v1) == 0
assert v3.compare_to(v2) > 0
def test_version_bump(self):
"""测试版本提升"""
version = Version.parse("1.2.3")
# 补丁版本
bumped = version.bump(VersionType.PATCH)
assert str(bumped) == "1.2.4"
# 次版本
bumped = version.bump(VersionType.MINOR)
assert str(bumped) == "1.3.0"
# 主版本
bumped = version.bump(VersionType.MAJOR)
assert str(bumped) == "2.0.0"
# 预发布版本
bumped = version.bump(VersionType.PRERELEASE)
assert str(bumped) == "1.2.3-alpha.1"
# 再次预发布版本
bumped = bumped.bump(VersionType.PRERELEASE)
assert str(bumped) == "1.2.3-alpha.2"
def test_set_and_get_current_version(self):
"""测试设置和获取当前版本"""
version = Version.parse("2.0.0")
self.version_manager.set_current_version(version)
current = self.version_manager.get_current_version()
assert current is not None
assert str(current) == "2.0.0"
def test_version_compatibility(self):
"""测试版本兼容性"""
self.version_manager.set_current_version("2.0.0")
# 兼容版本
assert self.version_manager.check_compatibility("2.1.0") is True
assert self.version_manager.check_compatibility("2.0.5") is True
# 不兼容版本
assert self.version_manager.check_compatibility("1.0.0") is False
assert self.version_manager.check_compatibility("3.0.0") is False
if __name__ == "__main__":
pytest.main([__file__, "-v"])