You've already forked HeurAMS-legacy
format
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
DashboardScreen 的测试,包括单元测试和 pilot 测试。
|
||||
DashboardScreen 的测试, 包括单元测试和 pilot 测试.
|
||||
"""
|
||||
import unittest
|
||||
import tempfile
|
||||
@@ -16,15 +16,15 @@ from heurams.interface.screens.dashboard import DashboardScreen
|
||||
|
||||
|
||||
class TestDashboardScreenUnit(unittest.TestCase):
|
||||
"""DashboardScreen 的单元测试(不启动完整应用)。"""
|
||||
"""DashboardScreen 的单元测试(不启动完整应用). """
|
||||
|
||||
def setUp(self):
|
||||
"""在每个测试之前运行,设置临时目录和配置。"""
|
||||
"""在每个测试之前运行, 设置临时目录和配置. """
|
||||
# 创建临时目录用于测试数据
|
||||
self.temp_dir = tempfile.TemporaryDirectory()
|
||||
self.temp_path = pathlib.Path(self.temp_dir.name)
|
||||
|
||||
# 创建默认配置,并修改路径指向临时目录
|
||||
# 创建默认配置, 并修改路径指向临时目录
|
||||
default_config_path = (
|
||||
pathlib.Path(__file__).parent.parent.parent
|
||||
/ "src/heurams/default/config/config.toml"
|
||||
@@ -36,7 +36,7 @@ class TestDashboardScreenUnit(unittest.TestCase):
|
||||
config_data["paths"]["electron_dir"] = str(self.temp_path / "electron")
|
||||
config_data["paths"]["orbital_dir"] = str(self.temp_path / "orbital")
|
||||
config_data["paths"]["cache_dir"] = str(self.temp_path / "cache")
|
||||
# 禁用快速通过,避免测试干扰
|
||||
# 禁用快速通过, 避免测试干扰
|
||||
config_data["quick_pass"] = 0
|
||||
# 禁用时间覆盖
|
||||
config_data["daystamp_override"] = -1
|
||||
@@ -53,12 +53,12 @@ class TestDashboardScreenUnit(unittest.TestCase):
|
||||
self.config_ctx.__enter__()
|
||||
|
||||
def tearDown(self):
|
||||
"""在每个测试之后清理。"""
|
||||
"""在每个测试之后清理. """
|
||||
self.config_ctx.__exit__(None, None, None)
|
||||
self.temp_dir.cleanup()
|
||||
|
||||
def test_compose(self):
|
||||
"""测试 compose 方法返回正确的部件。"""
|
||||
"""测试 compose 方法返回正确的部件. """
|
||||
screen = DashboardScreen()
|
||||
# 手动调用 compose 并收集部件
|
||||
from textual.app import ComposeResult
|
||||
@@ -77,14 +77,14 @@ class TestDashboardScreenUnit(unittest.TestCase):
|
||||
|
||||
container_present = any(isinstance(w, ScrollableContainer) for w in widgets)
|
||||
self.assertTrue(container_present)
|
||||
# 使用 query_one 查找 union-list,即使屏幕未挂载也可能有效
|
||||
# 使用 query_one 查找 union-list, 即使屏幕未挂载也可能有效
|
||||
list_view = screen.query_one("#union-list")
|
||||
self.assertIsNotNone(list_view)
|
||||
self.assertEqual(list_view.id, "union-list")
|
||||
self.assertEqual(list_view.__class__.__name__, "ListView")
|
||||
|
||||
def test_item_desc_generator(self):
|
||||
"""测试 item_desc_generator 函数。"""
|
||||
"""测试 item_desc_generator 函数. """
|
||||
screen = DashboardScreen()
|
||||
# 模拟一个文件名
|
||||
filename = "test.toml"
|
||||
@@ -94,16 +94,16 @@ class TestDashboardScreenUnit(unittest.TestCase):
|
||||
self.assertIn(1, result)
|
||||
# 检查内容
|
||||
self.assertIn("test.toml", result[0])
|
||||
# 由于 electron 文件不存在,应显示“尚未激活”
|
||||
# 由于 electron 文件不存在, 应显示“尚未激活”
|
||||
self.assertIn("尚未激活", result[1])
|
||||
|
||||
|
||||
@unittest.skip("Pilot 测试需要进一步配置,暂不运行")
|
||||
@unittest.skip("Pilot 测试需要进一步配置, 暂不运行")
|
||||
class TestDashboardScreenPilot(unittest.TestCase):
|
||||
"""使用 Textual Pilot 的集成测试。"""
|
||||
"""使用 Textual Pilot 的集成测试. """
|
||||
|
||||
def setUp(self):
|
||||
"""配置临时目录和配置。"""
|
||||
"""配置临时目录和配置. """
|
||||
self.temp_dir = tempfile.TemporaryDirectory()
|
||||
self.temp_path = pathlib.Path(self.temp_dir.name)
|
||||
|
||||
@@ -134,11 +134,11 @@ class TestDashboardScreenPilot(unittest.TestCase):
|
||||
self.temp_dir.cleanup()
|
||||
|
||||
def test_dashboard_loads_with_pilot(self):
|
||||
"""使用 Pilot 测试 DashboardScreen 加载。"""
|
||||
"""使用 Pilot 测试 DashboardScreen 加载. """
|
||||
with patch("heurams.interface.__main__.environment_check"):
|
||||
app = HeurAMSApp()
|
||||
# 注意:Pilot 在 Textual 6.9.0 中的用法可能不同
|
||||
# 以下为示例代码,可能需要调整
|
||||
# 注意: Pilot 在 Textual 6.9.0 中的用法可能不同
|
||||
# 以下为示例代码, 可能需要调整
|
||||
pilot = Pilot(app)
|
||||
# 等待应用启动
|
||||
pilot.pause()
|
||||
|
||||
@@ -36,7 +36,7 @@ class TestSM2Algorithm(unittest.TestCase):
|
||||
self.assertEqual(defaults["last_date"], 0)
|
||||
self.assertEqual(defaults["next_date"], 0)
|
||||
self.assertEqual(defaults["is_activated"], 0)
|
||||
# last_modify 是动态的,仅检查存在性
|
||||
# last_modify 是动态的, 仅检查存在性
|
||||
self.assertIn("last_modify", defaults)
|
||||
|
||||
def test_revisor_feedback_minus_one(self):
|
||||
@@ -129,12 +129,12 @@ class TestSM2Algorithm(unittest.TestCase):
|
||||
}
|
||||
}
|
||||
SM2Algorithm.revisor(algodata, feedback=4)
|
||||
# rept 从 0 递增到 1,因此 interval 应为 6
|
||||
# rept 从 0 递增到 1, 因此 interval 应为 6
|
||||
self.assertEqual(algodata[SM2Algorithm.algo_name]["interval"], 6)
|
||||
|
||||
# 现在 rept=1,再次调用 revisor 递增到 2
|
||||
# 现在 rept=1, 再次调用 revisor 递增到 2
|
||||
SM2Algorithm.revisor(algodata, feedback=4)
|
||||
# rept=2,interval = round(6 * 2.5) = 15
|
||||
# rept=2, interval = round(6 * 2.5) = 15
|
||||
self.assertEqual(algodata[SM2Algorithm.algo_name]["interval"], 15)
|
||||
|
||||
# 单独测试 rept=1 的情况
|
||||
@@ -147,7 +147,7 @@ class TestSM2Algorithm(unittest.TestCase):
|
||||
}
|
||||
}
|
||||
SM2Algorithm.revisor(algodata2, feedback=4)
|
||||
# rept 递增到 2,interval = round(0 * 2.5) = 0
|
||||
# rept 递增到 2, interval = round(0 * 2.5) = 0
|
||||
self.assertEqual(algodata2[SM2Algorithm.algo_name]["interval"], 0)
|
||||
|
||||
def test_revisor_updates_dates(self):
|
||||
|
||||
@@ -31,7 +31,7 @@ class TestElectron(unittest.TestCase):
|
||||
defaults = electron.algo.defaults
|
||||
for key, value in defaults.items():
|
||||
if key == "last_modify":
|
||||
# last_modify 是动态的,只检查存在性
|
||||
# last_modify 是动态的, 只检查存在性
|
||||
self.assertIn(key, electron.algodata[electron.algo])
|
||||
elif key == "is_activated":
|
||||
# TODO: 调查为什么 is_activated 是 1
|
||||
@@ -45,7 +45,7 @@ class TestElectron(unittest.TestCase):
|
||||
electron = Electron("test_electron", algodata=algodata)
|
||||
self.assertEqual(electron.algodata[electron.algo]["efactor"], 2.5)
|
||||
self.assertEqual(electron.algodata[electron.algo]["interval"], 1)
|
||||
# 其他字段可能不存在,因为未提供默认初始化
|
||||
# 其他字段可能不存在, 因为未提供默认初始化
|
||||
# 检查 real_rept 不存在
|
||||
self.assertNotIn("real_rept", electron.algodata[electron.algo])
|
||||
|
||||
@@ -98,7 +98,7 @@ class TestElectron(unittest.TestCase):
|
||||
electron = Electron("test_electron")
|
||||
with patch.object(electron.algo, "rate") as mock_rate:
|
||||
mock_rate.return_value = "good"
|
||||
result = electron.rate()
|
||||
result = electron.get_rate()
|
||||
mock_rate.assert_called_once_with(electron.algodata)
|
||||
self.assertEqual(result, "good")
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ class TestClozePuzzle(unittest.TestCase):
|
||||
# 检查 wording 和 answer
|
||||
self.assertNotEqual(puzzle.wording, "填空题 - 尚未刷新谜题")
|
||||
self.assertNotEqual(puzzle.answer, ["填空题 - 尚未刷新谜题"])
|
||||
# 根据模拟,应该有两个填空
|
||||
# 根据模拟, 应该有两个填空
|
||||
self.assertEqual(len(puzzle.answer), 2)
|
||||
self.assertEqual(puzzle.answer, ["hello", "test"])
|
||||
# wording 应包含下划线
|
||||
|
||||
@@ -34,9 +34,9 @@ class TestMCQPuzzle(unittest.TestCase):
|
||||
def test_init_jammer_ensures_minimum(self):
|
||||
"""测试干扰项至少保证 4 个"""
|
||||
puzzle = MCQPuzzle({}, [])
|
||||
# 正确答案为空,干扰项为空,应填充空格
|
||||
# 正确答案为空, 干扰项为空, 应填充空格
|
||||
self.assertEqual(len(puzzle.jammer), 4)
|
||||
self.assertEqual(set(puzzle.jammer), {" "}) # 三个空格?实际上循环填充空格
|
||||
self.assertEqual(set(puzzle.jammer), {" "}) # 三个空格? 实际上循环填充空格
|
||||
|
||||
@patch("random.sample")
|
||||
@patch("random.shuffle")
|
||||
|
||||
@@ -32,7 +32,7 @@ class TestPhaser(unittest.TestCase):
|
||||
atoms = [self.atom_old, self.atom_new, self.atom_old]
|
||||
phaser = Phaser(atoms)
|
||||
|
||||
# 应该创建两个 Procession:一个用于旧原子,一个用于新原子,以及一个总体复习
|
||||
# 应该创建两个 Procession: 一个用于旧原子, 一个用于新原子, 以及一个总体复习
|
||||
self.assertEqual(self.mock_procession_class.call_count, 3)
|
||||
|
||||
# 检查调用参数
|
||||
@@ -52,7 +52,7 @@ class TestPhaser(unittest.TestCase):
|
||||
atoms = [self.atom_old, self.atom_old]
|
||||
phaser = Phaser(atoms)
|
||||
|
||||
# 应该创建两个 Procession:一个初始复习,一个总体复习
|
||||
# 应该创建两个 Procession: 一个初始复习, 一个总体复习
|
||||
self.assertEqual(self.mock_procession_class.call_count, 2)
|
||||
calls = self.mock_procession_class.call_args_list
|
||||
self.assertEqual(calls[0][0][0], atoms)
|
||||
|
||||
Reference in New Issue
Block a user