87 lines
3.9 KiB
Python
87 lines
3.9 KiB
Python
"""目标页数与一级篇章区间。"""
|
||
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()
|