t27.aiEnglish

От спецификации к боту

Вы узнаете

Почему бот начинается с таблицы команд и ответов и как три проверки ловят плохую таблицу ещё до того, как бот существует.

Бота не пишут, его описывают. spec_to_bot.t27 перечисляет 3 команды и ответ каждой как данные. Прежде чем что-то сгенерируется, над описанием запускаются 3 проверки: у каждой команды есть ответ, у двух команд нет общего ответа, а число маршрутов равно числу команд. Описание, не прошедшее проверку, дало бы неверного бота, поэтому сначала чинят таблицу, а бота генерируют потом. Сотрите ответ в виджете и посмотрите, какая проверка станет красной.

Попробуйте

Сотрите один ответ и назовите проверку, которая станет красной. В кадре со спецификацией найдите тест, который ломает пропавший ответ, и одну строку, которую вы изменили бы, чтобы подложить эту ошибку.

Открыть интерактивный урок →

From a spec to a bot: break the table, watch a check go red ↗

A bot written down as a table of commands and replies. Blank a reply or repeat one and the checks turn red before any bot exists. Nothing is sent.

specs/vibecoding/spec_to_bot.t27

// SPDX-License-Identifier: Apache-2.0
; specs/vibecoding/spec_to_bot.t27 -- lesson "From a spec to a bot" of the course Vibecoding from zero
; The one idea: you do not write the bot, you write down what it should do, as data, and check the
; description before anything is generated from it. This spec lists three commands and the reply
; each one gets; its tests are the checks a description must pass: every command has a reply, no
; two commands share a reply, and the count of routes equals the count of commands.
; Command ids: 1 start, 2 help, 3 about. Reply ids: 10, 20, 30; a reply id of 0 means "missing".
; ASCII only (L3), English only (LANG-EN).
; phi^2 + 1/phi^2 = 3 | TRINITY

module vc_spec_to_bot;

pub const BOT_NAME : str = "first-bot";
pub const COMMAND_COUNT : u8 = 3;
pub const COMMAND_IDS : [3]u8 = [1, 2, 3];
; The reply for the command in the same position of COMMAND_IDS.
pub const REPLY_IDS : [3]u8 = [10, 20, 30];
pub const ROUTE_COUNT : u8 = 3;

; A route is complete when it has a reply.
pub fn has_reply(reply: u8) -> bool {
    return reply != 0;
}

test every_command_has_a_reply {
    assert REPLY_IDS[0] != 0;
    assert REPLY_IDS[1] != 0;
    assert REPLY_IDS[2] != 0;
}

; Negative control: a description that forgets one reply (REPLY_IDS = [10, 0, 30]) turns this red.
test no_reply_is_shared_by_two_commands {
    assert REPLY_IDS[0] != REPLY_IDS[1];
    assert REPLY_IDS[0] != REPLY_IDS[2];
    assert REPLY_IDS[1] != REPLY_IDS[2];
}

test no_command_is_listed_twice {
    assert COMMAND_IDS[0] != COMMAND_IDS[1];
    assert COMMAND_IDS[0] != COMMAND_IDS[2];
    assert COMMAND_IDS[1] != COMMAND_IDS[2];
}

test the_routes_match_the_commands {
    assert ROUTE_COUNT == COMMAND_COUNT;
    assert COMMAND_IDS[COMMAND_COUNT - 1] == 3;
    assert REPLY_IDS[ROUTE_COUNT - 1] == 30;
}

Открыть спеку урока в плеере ↗

Все уроки