Files
gausse/tests/test_real_components_smoke.py
jze9 f22fd89612 Populate real retail component database (Stage 1 complete)
Wire (Cu/Al ПЭТВ-2), capacitors (350-450V electrolytic bank), switches
(КУ202Н/BT151 SCR, IRFP250/IRFP4468 MOSFET, IRG4PC50F IGBT), sensors
(A3144E Hall, TCST2103 optical, LM393-based inductive pickup), and
projectile materials (Ст3, Сталь 10, армко-железо) sourced from
procontact74.ru/chipdip.ru/cable.ru research.

Every entry's `source` field states plainly whether the number is a
REAL scraped retail price/spec (with URL) or an ОЦЕНКА (estimate) with
its basis (e.g. aluminum magnet wire has no self-service retail price
in RU stores, so it's priced as a fraction of equivalent copper) — no
value is presented as real when it isn't. Added a smoke test proving
the real database runs end-to-end through the full physics + chaining
pipeline, not just against synthetic test fixtures.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-06 20:06:27 +05:00

71 lines
3.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Дымовой тест: реальная база компонентов (Этап 1) действительно прогоняется.
Не проверяет конкретные числа (это будет делать sweep/оптимизатор) — только
то, что хотя бы одна разумная комбинация реальных деталей из
components/data/*.json физически прогоняется через полную цепочку без
исключений, и что честная отбраковка (feasible=False) тоже доступна и не
падает, если комбинация неудачная.
"""
from gausse.components.database import ComponentDatabase
from gausse.sim.coilgun import CoilgunConfig, run_coilgun
from gausse.sim.stage import ProjectileConfig, StageConfig
def _find(items, **kwargs):
for item in items:
if all(getattr(item, k) == v for k, v in kwargs.items()):
return item
raise AssertionError(f"не найден компонент с {kwargs} среди {len(items)} записей")
def test_real_component_database_loads_and_is_nonempty():
db = ComponentDatabase.load()
assert len(db.wires) > 0
assert len(db.capacitors) > 0
assert len(db.switches) > 0
assert len(db.sensors) > 0
assert len(db.projectile_materials) > 0
def test_real_component_combination_runs_end_to_end():
db = ComponentDatabase.load()
wire = _find(db.wires, part_id="cu-petv2-1.0mm")
capacitor = _find(db.capacitors, part_number="cap-470uf-400v")
switch = _find(db.switches, part_number="IRFP250PBF")
sensor = _find(db.sensors, part_number="TCST2103")
steel = _find(db.projectile_materials, name="Ст3 (конструкционная сталь)")
projectile = ProjectileConfig(material=steel, diameter_m=0.008, length_m=0.02)
stage = StageConfig(
wire=wire,
capacitor=capacitor,
switch=switch,
sensor=sensor,
tube_od_m=0.01,
turns_per_layer=20,
layers=4,
sensor_to_coil_distance_m=0.02,
charge_voltage_v=350.0,
)
config = CoilgunConfig(
stages=[stage, stage],
inter_stage_gaps_m=[0.05],
projectile=projectile,
initial_x_m=-0.05,
initial_v_mps=5.0,
)
result = run_coilgun(config)
# Реальные детали могут дать как удачную, так и провальную (feasible=False)
# конфигурацию — это тоже честный результат. Тест лишь гарантирует, что
# весь путь (реальные JSON -> физика -> цепочка) не падает с исключением
# и возвращает осмысленный, самосогласованный результат в любом случае.
if result.feasible:
assert result.exit_v_mps is not None
assert 0.0 <= result.efficiency <= 1.0
else:
assert result.reason is not None
assert result.failed_stage_index is not None