Initial commit: Busbar Designer
Web tool for designing nickel/copper busbars over cylindrical-cell battery packs (21700, 18650) in hex holders. Flask + build123d backend exports STEP/DXF/SVG; vanilla JS frontend with live preview, multi-project SQLite persistence, snapshot history. Deploy scripts in deploy/ (proxmox-lxc.sh, install.sh, update.sh).
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
"""Sanity tests for storage.py — uses a fresh in-memory-ish DB per test."""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Point the storage module at a tmp DB before importing it.
|
||||
TMP_DB = Path(__file__).parent / "_tmp_storage.db"
|
||||
os.environ["BUSBAR_DB"] = str(TMP_DB)
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
||||
|
||||
import storage # noqa: E402
|
||||
|
||||
|
||||
def setup_function(_):
|
||||
if TMP_DB.exists():
|
||||
TMP_DB.unlink()
|
||||
storage.init_db()
|
||||
|
||||
|
||||
def teardown_module(_):
|
||||
if TMP_DB.exists():
|
||||
TMP_DB.unlink()
|
||||
|
||||
|
||||
def test_project_crud():
|
||||
pid = storage.create_project("test", {"cells": [{"x": 0, "y": 0}]})
|
||||
assert pid > 0
|
||||
p = storage.get_project(pid)
|
||||
assert p["name"] == "test"
|
||||
assert p["data"]["cells"][0]["x"] == 0
|
||||
|
||||
assert storage.update_project(pid, name="renamed")
|
||||
assert storage.get_project(pid)["name"] == "renamed"
|
||||
|
||||
assert storage.update_project(pid, data={"cells": [], "params": {"k": 1}})
|
||||
assert storage.get_project(pid)["data"]["params"]["k"] == 1
|
||||
|
||||
assert storage.delete_project(pid)
|
||||
assert storage.get_project(pid) is None
|
||||
|
||||
|
||||
def test_snapshot_created_and_restore():
|
||||
pid = storage.create_project("p", {"v": 1})
|
||||
# snapshot=True means: snapshot the CURRENT (v=1) state before applying v=2
|
||||
assert storage.update_project(pid, data={"v": 2}, snapshot=True, note="step")
|
||||
snaps = storage.list_snapshots(pid)
|
||||
assert len(snaps) == 1
|
||||
assert snaps[0]["note"] == "step"
|
||||
|
||||
sid = snaps[0]["id"]
|
||||
snap = storage.get_snapshot(sid)
|
||||
assert snap["data"]["v"] == 1 # the *prior* state
|
||||
|
||||
# Restore: rolls project back to v=1 (and creates another snapshot of v=2).
|
||||
assert storage.restore_snapshot(sid)
|
||||
assert storage.get_project(pid)["data"]["v"] == 1
|
||||
assert len(storage.list_snapshots(pid)) == 2
|
||||
|
||||
|
||||
def test_snapshot_retention_caps_at_N():
|
||||
pid = storage.create_project("p", {"v": 0})
|
||||
for i in range(1, storage.SNAPSHOT_RETENTION + 10):
|
||||
storage.update_project(pid, data={"v": i}, snapshot=True)
|
||||
snaps = storage.list_snapshots(pid)
|
||||
assert len(snaps) == storage.SNAPSHOT_RETENTION
|
||||
|
||||
|
||||
def test_preset_crud_and_name_unique():
|
||||
pid = storage.create_preset("21700", {"cellDia": 21.2})
|
||||
assert pid > 0
|
||||
assert storage.create_preset("21700", {"x": 1}) is None # name collision
|
||||
|
||||
assert storage.list_presets()[0]["params"]["cellDia"] == 21.2
|
||||
|
||||
assert storage.update_preset(pid, params={"cellDia": 21.4})
|
||||
assert storage.get_preset(pid)["params"]["cellDia"] == 21.4
|
||||
|
||||
assert storage.delete_preset(pid)
|
||||
assert storage.list_presets() == []
|
||||
|
||||
|
||||
def test_delete_project_cascades_snapshots():
|
||||
pid = storage.create_project("p", {"v": 1})
|
||||
storage.update_project(pid, data={"v": 2}, snapshot=True)
|
||||
storage.update_project(pid, data={"v": 3}, snapshot=True)
|
||||
assert len(storage.list_snapshots(pid)) == 2
|
||||
storage.delete_project(pid)
|
||||
assert storage.list_snapshots(pid) == []
|
||||
Reference in New Issue
Block a user