feat(generator): эталонный мир зафиксирован равным стартовому
- Зачем:
- у дней 8-13 описи не нашлось читателя: обещание эталона в 14 дней
снято решением владельца 2026-08-30 (#192, этап 7 — #9).
- Что:
- резолюция перенесена в обе спеки, докстринг описи и словарь CONTEXT.md;
- добавлен тест: проигранный через CLI день совпадает с хешем описи;
- сняты замеры: пересборка описи 20,5 с, снимок 460,7 МБ, make test
176,5 с — записаны в карту проверок и таблицу бюджетов.
- Проверка:
- cd generator && make lint && make typecheck && make test (437 passed);
- git diff по data/world-inventory.json пуст.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f93c924b33
commit
c1b61d81b9
8 files changed
+88
-38
No files matched your search
@@ -14,8 +14,8 @@ import pytest
|
||||
from clickstream_generator import plan, reference, world
|
||||
from clickstream_generator.seeds import CANONICAL_SEED
|
||||
|
||||
# Горизонт эталонного снимка — две недели (спека, раздел 5).
|
||||
SNAPSHOT_DAYS = 14
|
||||
# Окно замера плана — две недели: два цикла недельной сезонности.
|
||||
WINDOW_DAYS = 14
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
@@ -54,9 +54,9 @@ def test_the_plan_is_a_pure_function_of_the_seed():
|
||||
|
||||
|
||||
def test_counters_are_a_pure_function_of_the_seed():
|
||||
first = plan.counters(CANONICAL_SEED, SNAPSHOT_DAYS)
|
||||
first = plan.counters(CANONICAL_SEED, WINDOW_DAYS)
|
||||
plan.cohort.cache_clear()
|
||||
assert first == plan.counters(CANONICAL_SEED, SNAPSHOT_DAYS)
|
||||
assert first == plan.counters(CANONICAL_SEED, WINDOW_DAYS)
|
||||
|
||||
|
||||
def test_a_remembered_cohort_cannot_be_spoiled_from_outside():
|
||||
@@ -216,12 +216,12 @@ def test_the_passport_points_into_the_directories():
|
||||
|
||||
def test_the_daily_audience_matches_the_spec_band():
|
||||
"""6–8 тыс. посетителей в день — правдоподобный средний магазин."""
|
||||
counters = plan.counters(CANONICAL_SEED, SNAPSHOT_DAYS)
|
||||
counters = plan.counters(CANONICAL_SEED, WINDOW_DAYS)
|
||||
assert all(6_000 <= size <= 8_000 for size in counters.audience)
|
||||
|
||||
|
||||
def test_the_influx_holds_its_daily_number():
|
||||
counters = plan.counters(CANONICAL_SEED, SNAPSHOT_DAYS)
|
||||
counters = plan.counters(CANONICAL_SEED, WINDOW_DAYS)
|
||||
average = sum(counters.new_cookies) / len(counters.new_cookies)
|
||||
assert abs(average - world.DAILY_INFLUX) < world.DAILY_INFLUX // 10
|
||||
|
||||
@@ -232,7 +232,7 @@ def test_the_influx_breathes_with_the_week():
|
||||
def mean(numbers: tuple[int, ...] | list[int]) -> float:
|
||||
return sum(numbers) / len(numbers)
|
||||
|
||||
counters = plan.counters(CANONICAL_SEED, SNAPSHOT_DAYS)
|
||||
counters = plan.counters(CANONICAL_SEED, WINDOW_DAYS)
|
||||
weekdays = [size for day, size in enumerate(counters.new_cookies) if day % 7 < 5]
|
||||
weekend = [size for day, size in enumerate(counters.new_cookies) if day % 7 >= 5]
|
||||
expected = mean(world.WEEKLY_PROFILE_PERCENT[5:]) / mean(
|
||||
@@ -250,7 +250,7 @@ def test_the_influx_differs_even_on_the_same_weekday():
|
||||
def test_the_influx_is_visible_on_the_plan():
|
||||
"""Накопленная аудитория растёт с горизонтом и с дневной не сходится."""
|
||||
week = plan.counters(CANONICAL_SEED, 7)
|
||||
fortnight = plan.counters(CANONICAL_SEED, SNAPSHOT_DAYS)
|
||||
fortnight = plan.counters(CANONICAL_SEED, WINDOW_DAYS)
|
||||
assert week.visitors < fortnight.visitors
|
||||
assert fortnight.visitors > 2 * max(fortnight.audience)
|
||||
|
||||
@@ -258,21 +258,21 @@ def test_the_influx_is_visible_on_the_plan():
|
||||
def test_the_horizon_is_a_prefix_not_another_world():
|
||||
"""Продление истории днём N+1 не трогает дни 1…N."""
|
||||
week = plan.counters(CANONICAL_SEED, 7)
|
||||
fortnight = plan.counters(CANONICAL_SEED, SNAPSHOT_DAYS)
|
||||
fortnight = plan.counters(CANONICAL_SEED, WINDOW_DAYS)
|
||||
assert fortnight.audience[:7] == week.audience
|
||||
assert fortnight.new_cookies[:7] == week.new_cookies
|
||||
|
||||
|
||||
def test_counters_count_the_same_audience_that_the_day_gets():
|
||||
"""Счётчики и дня-функция спрашивают один план — расходиться им негде."""
|
||||
counters = plan.counters(CANONICAL_SEED, SNAPSHOT_DAYS)
|
||||
for day in (0, 7, SNAPSHOT_DAYS - 1):
|
||||
counters = plan.counters(CANONICAL_SEED, WINDOW_DAYS)
|
||||
for day in (0, 7, WINDOW_DAYS - 1):
|
||||
actual = plan.audience(CANONICAL_SEED, day).client_id.size
|
||||
assert actual == counters.audience[day]
|
||||
|
||||
|
||||
def test_counters_know_the_pairs_before_a_single_event():
|
||||
counters = plan.counters(CANONICAL_SEED, SNAPSHOT_DAYS)
|
||||
counters = plan.counters(CANONICAL_SEED, WINDOW_DAYS)
|
||||
assert counters.pairs > 0
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user