fix: Rsp.identify NO DATA (пробел); 119 тестов
This commit is contained in:
+4
-1
@@ -53,7 +53,10 @@ class Rsp:
|
||||
def identify(cls, raw: str) -> str:
|
||||
"""Определяет тип ответа по сырой строке."""
|
||||
u = raw.upper().strip()
|
||||
for tag in (cls.SEARCHING, cls.NODATA, cls.ERROR, cls.UNABLE,
|
||||
# NO DATA бывает как "NODATA" так и "NO DATA"
|
||||
if u.replace(" ", "") == "NODATA":
|
||||
return cls.NODATA
|
||||
for tag in (cls.SEARCHING, cls.ERROR, cls.UNABLE,
|
||||
cls.BUS_BUSY, cls.BUS_ERROR, cls.CAN_ERROR,
|
||||
cls.BUS_INIT, cls.STOPPED, cls.DATA_ERROR,
|
||||
cls.BUFFER_FULL, cls.RX_ERROR, cls.OK):
|
||||
|
||||
@@ -490,3 +490,117 @@ test("5 разных request_id — все сохранены",
|
||||
db3.close()
|
||||
if TEST_DB.exists():
|
||||
TEST_DB.unlink()
|
||||
|
||||
# ── 14. DTC модуль (api/dtc.py) ─────────────────────────────────
|
||||
print("\n═══ 14. DTC модуль ═══")
|
||||
|
||||
# Загрузка словаря из dtc.py
|
||||
dtc = _load_dtc_dict()
|
||||
test("dtc загружен из dtc.py", len(dtc) > 100)
|
||||
|
||||
# Известные коды
|
||||
test("P0301 = пропуски", "Пропуски" in dtc.get("P0301", ""))
|
||||
test("P0420 = катализатор", "катализатор" in dtc.get("P0420", "").lower())
|
||||
|
||||
# Протокольные коды
|
||||
test("ABS C0000", "ABS" in dtc.get("C0000", ""))
|
||||
test("шина U0000", "шина" in dtc.get("U0000", "").lower())
|
||||
test("кузов B0000", "кузов" in dtc.get("B0000", "").lower())
|
||||
|
||||
# ── 15. Ping модуль (api/ping.py) ────────────────────────────────
|
||||
print("\n═══ 15. Ping модуль ═══")
|
||||
|
||||
from api.ping import _ping_llm_cache
|
||||
|
||||
# Изначально кэш пуст
|
||||
test("ping кэш пуст изначально", _ping_llm_cache == {})
|
||||
|
||||
# ── 16. State модуль (obd/state.py) ─────────────────────────────
|
||||
print("\n═══ 16. State ELM ═══")
|
||||
|
||||
from obd.state import State, Rsp
|
||||
|
||||
# State enum
|
||||
test("State.UNDEFINED", State.UNDEFINED is not None)
|
||||
test("State.READY", State.READY is not None)
|
||||
test("State.ERROR", State.ERROR is not None)
|
||||
|
||||
# Rsp.identify
|
||||
test("Rsp.identify OK", Rsp.identify("OK") == Rsp.OK)
|
||||
test("Rsp.identify BUS ERROR", Rsp.identify("BUS ERROR") == Rsp.BUS_ERROR)
|
||||
test("Rsp.identify SEARCHING", Rsp.identify("SEARCHING...") == Rsp.SEARCHING)
|
||||
test("Rsp.identify NO DATA", Rsp.identify("NO DATA") == Rsp.NODATA)
|
||||
test("Rsp.identify CAN ERROR", Rsp.identify("CAN ERROR") == Rsp.CAN_ERROR)
|
||||
test("Rsp.identify BUFFER FULL", Rsp.identify("BUFFER FULL") == Rsp.BUFFER_FULL)
|
||||
test("Rsp.identify STOPPED", Rsp.identify("STOPPED") == Rsp.STOPPED)
|
||||
test("Rsp.identify UNABLE", Rsp.identify("UNABLE TO CONNECT") == Rsp.UNABLE)
|
||||
test("Rsp.identify RX ERROR", Rsp.identify("RX ERROR") == Rsp.RX_ERROR)
|
||||
test("Rsp.identify DATA ERROR", Rsp.identify("DATA ERROR") == Rsp.DATA_ERROR)
|
||||
|
||||
# PROMPT
|
||||
test("Rsp.identify PROMPT >", Rsp.identify(">") == Rsp.PROMPT)
|
||||
|
||||
# UNKNOWN — данные
|
||||
test("Rsp.identify UNKNOWN — данные", Rsp.identify("41 0C 0C A8") == Rsp.UNKNOWN)
|
||||
test("Rsp.identify UNKNOWN — VIN", Rsp.identify("49 02 01 57 56") == Rsp.UNKNOWN)
|
||||
|
||||
# Нижний регистр, пробелы
|
||||
test("Rsp.identify lower case", Rsp.identify("bus error") == Rsp.BUS_ERROR)
|
||||
test("Rsp.identify пробелы", Rsp.identify(" OK ") == Rsp.OK)
|
||||
|
||||
# ── 17. Timing модуль (obd/timing.py) ────────────────────────────
|
||||
print("\n═══ 17. Timing ELM ═══")
|
||||
|
||||
from obd.timing import AdaptiveTiming
|
||||
|
||||
t = AdaptiveTiming()
|
||||
test("timing DEFAULT", t.ms == 500)
|
||||
test("atst = ms/4", t.atst == 125)
|
||||
|
||||
t.increase()
|
||||
test("timing увеличился", t.ms > 500)
|
||||
|
||||
t.decrease()
|
||||
test("timing уменьшился", t.ms >= 500)
|
||||
|
||||
t.reset()
|
||||
test("timing сброс", t.ms == 500)
|
||||
|
||||
# Многократное увеличение
|
||||
for _ in range(100):
|
||||
t.increase()
|
||||
test("timing MAX не превышен", t.ms <= 2000)
|
||||
|
||||
# Многократное уменьшение
|
||||
for _ in range(100):
|
||||
t.decrease()
|
||||
test("timing MIN не превышен", t.ms >= 50)
|
||||
|
||||
t2 = AdaptiveTiming()
|
||||
t2.increase()
|
||||
t2.increase()
|
||||
v = t2.ms
|
||||
t2.reset()
|
||||
test("reset после increase", t2.ms == 500 and v > 500)
|
||||
|
||||
atst = t2.atst
|
||||
test("atst >= 1", atst >= 1)
|
||||
|
||||
# ── 18. DB — только sessions (мёртвые таблицы удалены) ──────────
|
||||
print("\n═══ 18. DB чистота ═══")
|
||||
|
||||
import sqlite3
|
||||
db4 = Database(TEST_DB)
|
||||
tables = [r[0] for r in db4.conn.execute("SELECT name FROM sqlite_master WHERE type='table'").fetchall()]
|
||||
test("нет мёртвых таблиц (cars,tokens)", not any(t in tables for t in ["cars", "diagnostic_tokens", "dtc_codes"]))
|
||||
|
||||
# Убедиться что мёртвые методы вызывают AttributeError
|
||||
test("get_or_create_car удалён", not hasattr(db4, "get_or_create_car"))
|
||||
test("create_token удалён", not hasattr(db4, "create_token"))
|
||||
test("add_llm_message удалён", not hasattr(db4, "add_llm_message"))
|
||||
test("add_parameter удалён", not hasattr(db4, "add_parameter"))
|
||||
test("add_dtc удалён", not hasattr(db4, "add_dtc"))
|
||||
|
||||
db4.close()
|
||||
if TEST_DB.exists():
|
||||
TEST_DB.unlink()
|
||||
|
||||
Reference in New Issue
Block a user