106 lines
3.9 KiB
Python
106 lines
3.9 KiB
Python
from dataclasses import replace
|
||
from decimal import Decimal
|
||
|
||
import pytest
|
||
|
||
from synthgen import dictionary, inn
|
||
from synthgen.config import Config
|
||
from synthgen.group import build_group, member_inn, variant_spelling
|
||
from synthgen.ecp import write_ecp
|
||
from synthgen.rng import stable_hash
|
||
|
||
|
||
@pytest.fixture(scope="module")
|
||
def orgs():
|
||
return dictionary.load()
|
||
|
||
|
||
def test_group_size_and_head(orgs):
|
||
g = build_group(Config(group_size=5), orgs)
|
||
assert len(g.members) == 5
|
||
assert [m.code for m in g.members] == ["C01", "C02", "C03", "C04", "C05"]
|
||
assert g.members[0].is_head and g.members[0].org.form == "АО" and g.members[0].head_share is None
|
||
for m in g.members:
|
||
assert m.org.form in ("ООО", "АО") and m.org.kind != "банк"
|
||
assert not m.is_head or m is g.members[0]
|
||
assert g.name == "ГК SYN" and g.gk_id == "SYN-000001"
|
||
for m in g.members:
|
||
assert m.name == f'{m.org.form} "SYN {m.org.root}"'
|
||
assert m.name_1c == f"SYN {m.org.root} {m.org.form}"
|
||
assert len(m.kpp) == 9 and inn.is_valid(m.inn)
|
||
|
||
|
||
def test_member_inn_range():
|
||
value = member_inn("SYN", 3)
|
||
assert inn.is_valid(value)
|
||
assert int(value[2:-1]) == 1000000 + 100 * stable_hash("SYN", 90000) + 3
|
||
|
||
|
||
def test_prefixes_do_not_collide(orgs):
|
||
a = {m.inn for m in build_group(Config(prefix="SYN"), orgs).members}
|
||
b = {m.inn for m in build_group(Config(prefix="DEMO2"), orgs).members}
|
||
assert not a & b
|
||
assert not (a | b) & {o.inn for o in orgs}
|
||
|
||
|
||
def test_externals_exclude_group_and_banks(orgs):
|
||
g = build_group(Config(group_size=8), orgs)
|
||
chosen = {m.org.inn for m in g.members}
|
||
assert all(o.kind != "банк" for o in g.externals)
|
||
assert not chosen & {o.inn for o in g.externals}
|
||
assert len(g.externals) == sum(o.kind != "банк" for o in orgs) - 8
|
||
assert len(g.banks) == 30 and all(o.kind == "банк" for o in g.banks)
|
||
|
||
|
||
def test_no_inn_selection(orgs):
|
||
g = build_group(Config(group_size=5, no_inn_companies=2), orgs)
|
||
assert len(g.no_inn) == 2 and "C01" not in g.no_inn
|
||
g = build_group(Config(group_size=5, no_inn_companies=4), orgs)
|
||
assert len(g.no_inn) == 4 and "C01" not in g.no_inn
|
||
g = build_group(Config(group_size=5, no_inn_companies=5), orgs)
|
||
assert g.no_inn == frozenset(m.code for m in g.members)
|
||
assert build_group(Config(no_inn_companies=0), orgs).no_inn == frozenset()
|
||
|
||
|
||
@pytest.mark.parametrize("size,n", [(2, 2), (5, 2), (5, 5), (10, 3)])
|
||
def test_variant_name(orgs, size, n):
|
||
g = build_group(Config(group_size=size, no_inn_companies=n), orgs)
|
||
by_code = {m.code: m for m in g.members}
|
||
assert set(g.variant_name) == set(g.no_inn)
|
||
for code, other in g.variant_name.items():
|
||
assert other != code and other in by_code
|
||
m = by_code[other]
|
||
variant = variant_spelling(m)
|
||
assert variant not in (m.name_1c, m.name)
|
||
assert variant != by_code[code].name_1c
|
||
|
||
|
||
def test_shares(orgs):
|
||
for size in (2, 5, 12):
|
||
g = build_group(Config(group_size=size), orgs)
|
||
children = g.members[1:]
|
||
for m in children:
|
||
assert Decimal("0.51") <= m.head_share <= Decimal("1.00")
|
||
with_min = [m for m in children if m.minority is not None]
|
||
assert len(with_min) <= 2
|
||
if size > 2:
|
||
assert 1 <= len(with_min)
|
||
for m in with_min:
|
||
assert m.head_share < 1
|
||
for m in children:
|
||
if m.minority is None:
|
||
assert m.head_share == Decimal("1.00")
|
||
|
||
|
||
def test_prefix_cyrillic_and_digits(orgs, tmp_path):
|
||
for prefix in ("ДЕМО", "2GK"):
|
||
g = build_group(Config(prefix=prefix), orgs)
|
||
assert g.gk_id == f"{prefix}-000001"
|
||
write_ecp(g, tmp_path / f"ecp-{prefix}.xlsx")
|
||
|
||
|
||
def test_group_deterministic(orgs):
|
||
cfg = Config(group_size=7, no_inn_companies=2, seed=5)
|
||
assert build_group(cfg, orgs) == build_group(cfg, orgs)
|
||
assert build_group(cfg, orgs) != build_group(replace(cfg, seed=6), orgs)
|