feat(db): add video pages and up follower snapshot schema
This commit is contained in:
1 parent
707ed7d7d7
commit
4942d1d161
10 files changed
+521
-13
No files matched your search
+78
-1
@@ -10,15 +10,23 @@ sys.stdout.reconfigure(encoding="utf-8")
|
||||
from reaction_board.analytics import ( # noqa: E402
|
||||
DEFAULT_HEAT_WEIGHTS,
|
||||
METRICS,
|
||||
age_days,
|
||||
compute_growth,
|
||||
content_hours,
|
||||
eb_rate,
|
||||
effective_shrink_minutes,
|
||||
heat_scores,
|
||||
interactions_per_hour,
|
||||
interaction_rate,
|
||||
is_loopback,
|
||||
is_mature,
|
||||
median_of,
|
||||
normalize_cover,
|
||||
normalized_weights,
|
||||
percentile,
|
||||
robust_center_scale,
|
||||
score_percentiles,
|
||||
views_per_hour,
|
||||
)
|
||||
|
||||
|
||||
@@ -157,6 +165,72 @@ def test_normalize_cover_and_hosts():
|
||||
assert not is_loopback("192.168.1.2")
|
||||
|
||||
|
||||
def test_content_efficiency_helpers():
|
||||
assert content_hours(3600) == 1.0
|
||||
assert content_hours(7200) == 2.0
|
||||
assert content_hours(0) is None
|
||||
assert content_hours(-1) is None
|
||||
assert content_hours(None) is None
|
||||
assert content_hours(True) is None
|
||||
assert content_hours("bad") is None
|
||||
|
||||
assert views_per_hour(1000, 3600) == 1000.0
|
||||
assert views_per_hour(1000, 7200) == 500.0
|
||||
assert views_per_hour(None, 3600) == 0.0
|
||||
assert views_per_hour(1000, None) is None
|
||||
assert views_per_hour(1000, 0) is None
|
||||
|
||||
metrics = {"like": 30, "coin": 10, "favorite": 20, "view": 999}
|
||||
assert interactions_per_hour(metrics, 3600) == 60.0
|
||||
assert interactions_per_hour(metrics, 7200) == 30.0
|
||||
assert interactions_per_hour(None, 3600) is None
|
||||
assert interactions_per_hour(metrics, None) is None
|
||||
# 单项缺失按 0 处理,不抛异常
|
||||
assert interactions_per_hour({"like": None, "coin": "bad"}, 3600) == 0.0
|
||||
|
||||
|
||||
def test_age_and_maturity():
|
||||
reference = 1_800_000_000
|
||||
assert age_days(reference - 86400 * 10, reference) == 10
|
||||
assert age_days(reference, reference) == 0
|
||||
# 未来时间不产生负年龄
|
||||
assert age_days(reference + 86400, reference) == 0
|
||||
assert age_days(None, reference) is None
|
||||
assert age_days(0, reference) is None
|
||||
assert age_days("bad", reference) is None
|
||||
|
||||
assert is_mature(reference - 86400 * 14, reference, 14) is True
|
||||
assert is_mature(reference - 86400 * 13, reference, 14) is False
|
||||
assert is_mature(None, reference, 14) is False
|
||||
assert is_mature(reference - 86400 * 14, reference, 0) is True
|
||||
|
||||
|
||||
def test_shrinkage_helpers():
|
||||
assert median_of([]) is None
|
||||
assert median_of([None, "bad", True]) is None
|
||||
assert median_of([1, 3, 2]) == 2.0
|
||||
|
||||
# 自适应 κ 取各 UP 总分钟的中位数
|
||||
assert effective_shrink_minutes([10, 30, 20]) == 20.0
|
||||
assert effective_shrink_minutes([0, -5, None]) == 120.0
|
||||
assert effective_shrink_minutes([]) == 120.0
|
||||
assert effective_shrink_minutes([], fallback=60) == 60.0
|
||||
|
||||
# κ 越大越靠近先验;exposure 为 0 时直接返回先验
|
||||
assert abs(eb_rate(0, 0, 0.5, 100) - 0.5) < 1e-12
|
||||
assert eb_rate(100, 100, 1.0, 0) == 1.0
|
||||
assert eb_rate(100, 0, 1.0, 0) is None
|
||||
# (100 + 100*0.5) / (100 + 100) = 0.75
|
||||
assert abs(eb_rate(100, 100, 0.5, 100) - 0.75) < 1e-12
|
||||
assert eb_rate(None, 100, 0.5, 100) is None
|
||||
try:
|
||||
eb_rate(1, 1, 0.5, -1)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
raise AssertionError("负 prior_strength 必须报错")
|
||||
|
||||
|
||||
def main_test():
|
||||
test_percentile_and_robust_scale()
|
||||
test_normalized_weights()
|
||||
@@ -166,7 +240,10 @@ def main_test():
|
||||
test_interaction_rate_thresholds()
|
||||
test_compute_growth()
|
||||
test_normalize_cover_and_hosts()
|
||||
print("OK: analytics 热度/增长/互动率/封面测试全部通过")
|
||||
test_content_efficiency_helpers()
|
||||
test_age_and_maturity()
|
||||
test_shrinkage_helpers()
|
||||
print("OK: analytics 热度/增长/互动率/时长效率/收缩测试全部通过")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in new issue
Block a user