- canonical_plate (uppercase alnum, strips space/dot/hyphen) at all plate write sites; pretty_plate for render (history, XLSX, operator tile) so B 1234 XYZ and B1234XYZ are one plate everywhere - group_dos_by_plate compares canonical plates -> no false mixed_plates - warn-only (never blocking) plate format hint in operator + monitoring modals - batch.default_mode: manual (auto merged truck loads when a sack sat in the counting ROI); operator banner explains plate -> start -> stop - docs + AGENTS known-limitation note; 85 tests pass
This commit is contained in:
1 parent
7ad995d8d1
commit
6c5b1c8b30
11 files changed
+128
-32
No files matched your search
@@ -41,7 +41,7 @@ def test_repo_config_loads_and_validates(repo_config_path):
|
||||
|
||||
def test_do_block_and_batch_default_mode(repo_config_path):
|
||||
cfg = load_config(repo_config_path)
|
||||
assert cfg.batch.default_mode == "auto"
|
||||
assert cfg.batch.default_mode == "manual"
|
||||
# timeout_seconds = sack-idle (pause); truck_gone_tolerance_seconds = finalize
|
||||
assert cfg.batch.timeout_seconds == 20.0
|
||||
assert cfg.batch.truck_gone_tolerance_seconds == 30.0
|
||||
|
||||
+34
-3
@@ -8,7 +8,9 @@ import pytest
|
||||
from src.do_batch import (
|
||||
BATCH_MODES,
|
||||
OCR_ENGINES,
|
||||
canonical_plate,
|
||||
classify_unit_token,
|
||||
pretty_plate,
|
||||
empty_do_settings,
|
||||
group_dos_by_plate,
|
||||
is_valid_batch_mode,
|
||||
@@ -23,6 +25,35 @@ from src.do_batch import (
|
||||
from src.do_ocr import parse_fields_from_text
|
||||
|
||||
|
||||
def test_canonical_plate_strips_separators():
|
||||
assert canonical_plate(" b 1234 xyz ") == "B1234XYZ"
|
||||
assert canonical_plate("B-1234-XYZ") == "B1234XYZ"
|
||||
assert canonical_plate("B.1234.XYZ") == "B1234XYZ"
|
||||
assert canonical_plate("b1234xyz") == canonical_plate("B 1234 XYZ")
|
||||
assert canonical_plate(None) == ""
|
||||
assert canonical_plate(" ") == ""
|
||||
|
||||
|
||||
def test_pretty_plate_display_form():
|
||||
assert pretty_plate("B1234XYZ") == "B 1234 XYZ"
|
||||
assert pretty_plate("b 1234. xyz") == "B 1234 XYZ"
|
||||
assert pretty_plate("B1") == "B 1"
|
||||
assert pretty_plate("1234AB") == "1234 AB"
|
||||
assert pretty_plate("") == ""
|
||||
assert pretty_plate("!!") == "!!" # not a plate pattern, raw fallback
|
||||
|
||||
|
||||
def test_group_dos_by_plate_ignores_spacing_only_difference():
|
||||
dos = [
|
||||
{"no_do": "D1", "plate": "B 1234 XYZ"},
|
||||
{"no_do": "D2", "plate": "b1234xyz"},
|
||||
{"no_do": "D3", "plate": "B-1234-XYZ"},
|
||||
]
|
||||
plate, out = group_dos_by_plate(dos)
|
||||
assert plate == "B1234XYZ"
|
||||
assert all(d["plate"] == "B1234XYZ" for d in out)
|
||||
|
||||
|
||||
def test_normalize_batch_mode_defaults_auto():
|
||||
assert normalize_batch_mode(None) == "auto"
|
||||
assert normalize_batch_mode("bogus") == "auto"
|
||||
@@ -59,7 +90,7 @@ def test_group_dos_same_plate():
|
||||
{"no_do": "DO-2", "plate": "B 1234 XYZ"},
|
||||
]
|
||||
plate, out = group_dos_by_plate(dos)
|
||||
assert plate == "B 1234 XYZ"
|
||||
assert plate == "B1234XYZ"
|
||||
assert [d["no_do"] for d in out] == ["DO-1", "DO-2"]
|
||||
|
||||
|
||||
@@ -293,10 +324,10 @@ def test_manual_start_with_plate_normalizes_and_persists(dash_client):
|
||||
assert res.status_code == 200
|
||||
body = res.get_json()
|
||||
assert body["success"] is True
|
||||
assert body["plate"] == "B 1234 XYZ"
|
||||
assert body["plate"] == "B1234XYZ"
|
||||
assert state_path.exists()
|
||||
state = json.loads(state_path.read_text())
|
||||
assert state["plate"] == "B 1234 XYZ"
|
||||
assert state["plate"] == "B1234XYZ"
|
||||
assert state["batch_mode"] == "manual"
|
||||
assert state["manual_control"] is True
|
||||
|
||||
|
||||
Reference in new issue
Block a user