# Стенд CAT

Прогон:

```sh
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-сборки из корня проекта.
