"""目标页数与一级篇章区间。""" import random import unittest from utils import volume_chapters as vc class TestVolumeChapters(unittest.TestCase): def test_top_level_default_pages_zero(self): lo, hi = vc.top_level_chapter_range_from_pages(0) self.assertEqual((lo, hi), (8, 10)) def test_ranges_match_effective_volume_bands(self): self.assertEqual(vc.top_level_chapter_range_from_pages(100), (6, 8)) self.assertEqual(vc.top_level_chapter_range_from_pages(125), (6, 8)) self.assertEqual(vc.top_level_chapter_range_from_pages(150), (8, 10)) self.assertEqual(vc.top_level_chapter_range_from_pages(200), (10, 12)) self.assertEqual(vc.top_level_chapter_range_from_pages(300), (12, 16)) def test_hint_default_no_pages(self): h = vc.outline_chapter_count_hint(0, 'standard') self.assertIn('8-10', h) self.assertIn('不超过10', h) def test_hint_with_pages(self): h = vc.outline_chapter_count_hint(150, 'standard', 700) self.assertIn('约 8–10', h) self.assertIn('150', h) self.assertIn('105000', h) # 150×700 总字目标 self.assertIn('过细', h) def test_subchapter_base_anchor_points(self): self.assertAlmostEqual(vc.subchapter_total_base_from_pages(100), 78.0, places=5) self.assertAlmostEqual(vc.subchapter_total_base_from_pages(300), 212.0, places=5) self.assertEqual(vc.SUBCHAPTER_PAGES_SLOPE, 0.67) self.assertEqual(vc.SUBCHAPTER_PAGES_INTERCEPT, 11.0) def test_subchapter_jitter_bounds_78_anchor(self): """100 页基线 78 章,±10% 严格为 [70, 86]。""" self.assertEqual(vc.subchapter_jitter_bounds(78.0), (70, 86)) def test_subchapter_jitter_bounds_300_pages(self): self.assertEqual(vc.subchapter_jitter_bounds(212.0), (191, 233)) def test_allocate_subchapters_to_mains(self): self.assertEqual(vc.allocate_subchapters_to_mains(10, 3), [4, 3, 3]) self.assertEqual(vc.allocate_subchapters_to_mains(0, 3), [0, 0, 0]) self.assertEqual(vc.allocate_subchapters_to_mains(5, 2), [3, 2]) self.assertEqual(vc.allocate_subchapters_to_mains(7, 0), []) # n < k 时多出的主章 quota 为 0 a = vc.allocate_subchapters_to_mains(70, 100) self.assertEqual(len(a), 100) self.assertEqual(sum(a), 70) self.assertEqual(a.count(1), 70) self.assertEqual(a.count(0), 30) def test_subchapter_effective_respects_k_floor_and_jitter(self): # round(78 * u) for u in [0.9, 1.1] stays in [70, 86] for 78.0 base for seed in range(800): n = vc.subchapter_total_effective(100, 1, random.Random(seed)) self.assertGreaterEqual(n, 70) self.assertLessEqual(n, 86) # 主章数很大时,总条数仍须在 [70, 86](不得被 max(n,k) 抬到数百) for seed in range(20): nk = vc.subchapter_total_effective(100, 500, random.Random(seed)) self.assertGreaterEqual(nk, 70, msg=f'seed={seed}') self.assertLessEqual(nk, 86, msg=f'seed={seed}') def test_subchapter_effective_zero_pages(self): self.assertEqual(vc.subchapter_total_effective(0, 5), 0) self.assertEqual(vc.subchapter_total_effective(100, 0), 0) def test_resolve_expand_target_pages(self): self.assertEqual(vc.resolve_expand_target_pages(None, True, 100, 200), 0) self.assertEqual(vc.resolve_expand_target_pages(200, False, 100, 50), 200) self.assertEqual(vc.resolve_expand_target_pages(0, False, 80, 0), 80) self.assertEqual(vc.resolve_expand_target_pages(0, False, 0, 50), 50) self.assertEqual( vc.resolve_expand_target_pages(0, False, 0, 0), vc.EXPAND_OUTLINE_DEFAULT_TARGET_PAGES, ) self.assertEqual(vc.EXPAND_OUTLINE_DEFAULT_TARGET_PAGES, 100) if __name__ == '__main__': unittest.main()