Files
ew8bakandClaude Opus 5 d6a7dd96c5 test(cat): стенд разбора команд — свойства всего набора, а не список
Команд в CATEngine больше трёхсот, и проверять их поимённо бессмысленно: список
отстанет от кода в первую же неделю. Поэтому стенд ходит по кодам перебором
AA..ZZ (незнакомый движок отсеет сам, ответив «?;») и проверяет свойства,
которые обязаны выполняться на всём наборе сразу.

Круговой прогон: то, что команда отдала на опрос, она обязана принять обратно.
Это ловит расхождение ширин GET и SET — клиент, который читает значение и пишет
его назад, обычная идиома логгеров. Read-only статусы (IF, ID, ZZIF, ZZID)
исключены списком: их ответ — составной снимок, обратно его не пишут ни Kenwood,
ни Thetis.

Мусор в поле: разбор не имеет права упасть ни на одном аргументе (сборка с
-Criot: диапазоны, переполнения, приведения типов) и обязан отвечать либо ничем,
либо «?;»/«E;», либо ОДНИМ корректным кадром — лишняя ';' внутри ответа для
клиента означает две команды вместо одной, и дальше он читает мусор. Отдельным
прогоном на чистом радио: нечисловое поле не имеет права ничего перестроить.
Числовые формы в этот прогон не входят намеренно — «ZZFA00000000000;»
синтаксически законна, и решать её судьбу должен контроллер, а не разбор.

Радио подставное (TFakeRadio): ни движка, ни железа, но геттеры и сеттеры
настоящие, поэтому видно не «команда ответила», а ЧТО она изменила.

Плюс точечные регрессии на дефекты, которые уже случались: заглушка, молча
правившая радио (ZZVB копировал VFO A в VFO B прямо на опросе), ошибочные
алиасы, нечисловое поле как индекс 0, ширины полей.

★-B в обоих стендах (и в TCI тоже). Не «для чистоты»: fpc сверяет .ppu с
исходником по времени с точностью до секунды, и правка, попавшая в ту же
секунду, что и прошлая сборка, молча не подхватывается — стенд выносит вердикт
о СТАРОМ коде. Это хуже, чем не запускаться вовсе, и ловится обычно на
негативном контроле, когда исходник меняют туда-обратно (на нём и поймалось).
Полная пересборка графа стенда занимает около секунды.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 11:21:14 +03:00

3.8 KiB

Стенд CAT

Прогон:

test/cat/run.sh

Собирает cattest.pas и запускает его; код возврата ненулевой, если хоть одна проверка провалена. Внешних библиотек не требует и железа не касается: команды ходят по подставному радио (TFakeRadio), у которого есть настоящие геттеры и сеттеры, поэтому видно не только «команда ответила», но и что именно она изменила.

Зачем он такой

Команд в CATEngine.pas больше трёхсот, и проверять их по одной бессмысленно — список всё равно отстанет от кода. Поэтому стенд проверяет свойства всего набора сразу, а по командам ходит перебором AA..ZZ: незнакомый код движок отсеет сам («?;»), значит новая команда попадает под проверку без правки стенда.

  • A. Круговой прогон. То, что команда отдала на опрос, она обязана принять обратно. Так ловится классическое расхождение ширин: ZZGT; отвечал ZZGT000;, а на установку принимал ровно один символ — клиент, который читает значение и пишет его назад (обычная идиома логгеров), получал ?;. Read-only статусы (IF, ID, ZZIF, ZZID) из прогона исключены списком.

  • B. Мусор в поле. Разбор не имеет права упасть ни на одном аргументе (сборка идёт с -Criot — проверки диапазонов, ввода-вывода, переполнения и приведения типов включены) и обязан отвечать либо ничем, либо ?;/E;, либо одним корректным кадром: лишняя ; внутри ответа для клиента означает две команды вместо одной, и дальше он читает мусор. Отдельным прогоном на чистом радио проверяется, что нечисловое поле ничего не перестроило: этот класс дефектов («StrToIntDef(s, 0)» → индекс 0) уводил станцию на нулевой диапазон, нулевой фильтр и нулевую громкость. Числовые формы в этот прогон не входят: ZZFA00000000000; — синтаксически законная команда, и решать её судьбу должен контроллер, а не разбор.

  • C. Точечные регрессии на дефекты, которые уже случались: заглушка, молча правившая радио (ZZVB копировал VFO A в VFO B прямо на опросе), ошибочные алиасы, ширины полей, кенвудовские двойники уже исправленных ZZ-команд (FW/SH/SL/AG/SQ/GT — про них однажды забыли).

Грабли сборки

Те же, что и у стенда TCI (см. test/tci/README.md): -Mobjfpc обязателен, а каталог .ppu — свой и по абсолютному пути, иначе компилятор подхватит units GUI-сборки из корня проекта.