"""含量均匀度接受值(AV)计算器测试。 基准校验:直接复算 SL-0010 源表中实验室自报的 A、S、A+2.2S 列,验证与药典 (ChP 0941)一致;并覆盖 USP <905> 常数、限值判定与不臆断退化。 """ from __future__ import annotations import math from skills.descriptive_summary.content_uniformity import acceptance_value # SL-0010 三规格含量均匀度逐单位含量(相对标示量%)。 _CU_20 = [99.19, 100.0, 97.68, 96.0, 98.81] _CU_40 = [99.25, 101.43, 99.59, 97.71, 99.48] _CU_60 = [100.5, 101.01, 99.85, 99.98, 97.23] def test_chp_matches_lab_reported_20ug(): """20μg:复算 A/S/AV 应与源表 A=1.664、S=1.5500、A+2.2S=5.074 一致。""" r = acceptance_value(_CU_20, standard="chp") assert math.isclose(r.mean, 98.336, abs_tol=1e-3) assert math.isclose(r.deviation, 1.664, abs_tol=1e-3) # A=|100−X̄| assert math.isclose(r.std, 1.55000967738914, rel_tol=1e-6) # S assert math.isclose(r.k, 2.2) assert math.isclose(r.acceptance_value, 5.074, abs_tol=1e-3) # A+2.2S assert r.within_spec is True assert r.limit == 15.0 and r.limit_is_default is True def test_chp_matches_lab_reported_40ug_60ug(): r40 = acceptance_value(_CU_40, standard="chp") assert math.isclose(r40.deviation, 0.508, abs_tol=1e-2) # 源 A=0.508 assert math.isclose(r40.acceptance_value, 3.418, abs_tol=1e-2) # 源 A+2.2S=3.418 assert r40.within_spec is True r60 = acceptance_value(_CU_60, standard="chp") assert math.isclose(r60.deviation, 0.286, abs_tol=1e-2) # 源 A=0.286 assert math.isclose(r60.acceptance_value, 3.504, abs_tol=1e-2) # 源 A+2.2S=3.504 assert r60.within_spec is True def test_usp_reference_m_and_constant(): """USP <905>:X̄ 落在 [98.5,101.5] 内 → M=X̄ → AV=k·s,k=2.4(n≤10)。""" r = acceptance_value(_CU_20, standard="usp") assert r.reference_m is not None # 98.336 < 98.5 → M=98.5;|M−X̄|=0.164 assert math.isclose(r.reference_m, 98.5, abs_tol=1e-9) assert math.isclose(r.deviation, abs(98.5 - r.mean), abs_tol=1e-6) assert math.isclose(r.k, 2.4) assert math.isclose(r.acceptance_value, r.deviation + 2.4 * r.std, rel_tol=1e-9) def test_usp_mean_within_band_uses_mean_as_m(): vals = [100.0, 100.5, 99.5, 100.2, 99.8] # 均值≈100 落在带内 r = acceptance_value(vals, standard="usp") assert math.isclose(r.reference_m, r.mean, rel_tol=1e-9) assert math.isclose(r.deviation, 0.0, abs_tol=1e-9) def test_explicit_limit_overrides_default(): r = acceptance_value(_CU_20, standard="chp", limit=10.0) assert r.limit == 10.0 and r.limit_is_default is False def test_fails_when_av_exceeds_limit(): """构造高变异样本使 AV>L → 判不合格。""" vals = [80.0, 120.0, 95.0, 110.0, 90.0] r = acceptance_value(vals, standard="chp") assert r.acceptance_value > 15.0 assert r.within_spec is False def test_insufficient_sample_returns_none(): assert acceptance_value([100.0], standard="chp") is None assert acceptance_value([], standard="chp") is None