- synthgen/config.py: Config, load_config (YAML + --set), dump_config, проверки диапазонов §3 - synthgen/rng.py: rng_for (SHA-256 → Random), stable_hash - synthgen/__main__.py: разбор --config/--set/--out/--force, ошибка конфигурации → код 2 - synthgen/examples/default.yaml: все ключи §3 со значениями по умолчанию - копии из synthetic-group/gen (#35): inn, xlsx, ledger, chart (+80.09, 91.09 из seed arm-core) - тесты: config, inn, ledger; conftest с маркерами parser/slow - .gitignore: out/ - спека: решения 15–16 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
86 lines
2.4 KiB
Python
86 lines
2.4 KiB
Python
from decimal import Decimal
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
import yaml
|
|
|
|
from synthgen.__main__ import main
|
|
from synthgen.config import Config, ConfigError, dump_config, load_config
|
|
from synthgen.rng import rng_for
|
|
|
|
EXAMPLE = Path(__file__).resolve().parent.parent / "examples" / "default.yaml"
|
|
|
|
|
|
def test_defaults():
|
|
assert load_config(None, []) == Config()
|
|
|
|
|
|
def test_example_matches_defaults():
|
|
assert load_config(EXAMPLE, []) == Config()
|
|
|
|
|
|
def test_yaml_and_set_override(tmp_path):
|
|
path = tmp_path / "cfg.yaml"
|
|
path.write_text("group_size: 7\n", encoding="utf-8")
|
|
assert load_config(path, []).group_size == 7
|
|
assert load_config(path, ["group_size=9"]).group_size == 9
|
|
assert load_config(None, ["vgo_mismatch_share=0.25"]).vgo_mismatch_share == Decimal("0.25")
|
|
|
|
|
|
def test_dump_roundtrip(tmp_path):
|
|
cfg = Config(group_size=12, prefix="DEMO2", vgo_mismatch_share=Decimal("0.25"))
|
|
path = tmp_path / "dump.yaml"
|
|
path.write_text(dump_config(cfg), encoding="utf-8")
|
|
assert load_config(path, []) == cfg
|
|
keys = list(yaml.safe_load(dump_config(cfg)))
|
|
assert keys == [
|
|
"group_size", "prefix", "periods", "start", "osv_counterparties_mean",
|
|
"no_inn_companies", "vgo_mismatch_share", "seed", "out",
|
|
]
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"override",
|
|
[
|
|
"group_size=1",
|
|
"group_size=41",
|
|
"periods=0",
|
|
"periods=13",
|
|
"start=2025-Q5",
|
|
"start=2019-Q4",
|
|
"prefix=A",
|
|
"prefix=A B",
|
|
"prefix=ABCDEFGHIJKLM",
|
|
"osv_counterparties_mean=151",
|
|
"no_inn_companies=6",
|
|
"vgo_mismatch_share=1.5",
|
|
"unknown=1",
|
|
],
|
|
)
|
|
def test_validation(override):
|
|
with pytest.raises(ConfigError):
|
|
load_config(None, [override])
|
|
|
|
|
|
def test_unknown_key_in_yaml(tmp_path):
|
|
path = tmp_path / "cfg.yaml"
|
|
path.write_text("unknown: 1\n", encoding="utf-8")
|
|
with pytest.raises(ConfigError):
|
|
load_config(path, [])
|
|
|
|
|
|
def test_cli_bad_config_exit_2(capsys):
|
|
assert main(["--set", "group_size=1"]) == 2
|
|
assert capsys.readouterr().err != ""
|
|
|
|
|
|
def test_cli_prints_config(capsys):
|
|
assert main(["--set", "group_size=7"]) == 0
|
|
assert "group_size: 7" in capsys.readouterr().out
|
|
|
|
|
|
def test_rng_for_stable():
|
|
assert rng_for(1, "a").random() == rng_for(1, "a").random()
|
|
assert rng_for(1, "a").random() != rng_for(1, "b").random()
|
|
assert rng_for(1, "a").random() != rng_for(2, "a").random()
|