📚Чтение Заметок
Как я уже упоминал ранее, написание тестов будет очень солидной частью вашего времени на программирование контрактов FunC. Давайте подведем итоги наших тестов, созданных на предыдущем уроке:
Стоит отметить, что если мы запустим тест пряжи сейчас, он не сработает, потому что наш код значительно изменился. Что нам нужно сделать, чтобы исправить это, так это:
- Нам нужно предоставить надлежащие данные о начальном состоянии, поэтому в нашем хранилище c4 есть некоторые предварительно заполненные данные.
- Мы собираемся предоставить 0 в качестве значения счетчика и zeroAddress в качестве адреса отправителя с наибольшим количеством отправленных (в соответствии с новой логикой нашего контракта).
Нам нужно передать конкретную команду операции внутри тела сообщения, которое мы отправляем в контракт.
Давайте разберемся с исходными данными. Как вы помните, мы используем метод createFromConfig для инициализации нашего контракта, и мы устанавливаем начальные данные состояния нашего контракта как простую пустую ячейку следующим образом:
static createFromConfig(config: any, code: Cell, workchain = 0) {
const data = beginCell().endCell();
const init = { code, data };
const address = contractAddress(workchain, init);
return new MainContract(address, init);
}
Затем createFromConfig вызывается в нашем main.spec.ts:
const myContract = blockchain.openContract(
await MainContract.createFromConfig({}, codeCell)
);
До сих пор мы передавали пустой объект в качестве конфигурации, но давайте теперь разрешим передачу значений, которые нам на самом деле понадобятся для инициализации соответствующих данных нашего контракта.
Давайте определим, как должна выглядеть наша конфигурация. Сразу после импорта в наших обертках /MainContract.ts мы определим новый тип под названием MainContractConfig.
// ... library imports
export type MainContractConfig = {
number: number;
address: Address;
};
Еще одна классная функция помощи, которую мы собираемся реализовать в том же файле обертки, будет mainContractConfigToCell. Он получит объект типа MainContractConfig, правильно упакует эти параметры в ячейку и вернет ее. Нам это нужно, потому что, как вы помните, хранилище c4 - это ячейка памяти:
// ... library imports
// ... MainContractConfig type
export function mainContractConfigToCell(config: MainContractConfig): Cell {
return beginCell().storeUint(config.number, 32).storeAddress(config.address).endCell();
}
Теперь давайте обновим createFromConfig в том же файле, но внутри класса MainContract. Теперь он должен использовать функцию mainContractConfigToCell для формирования ячейки данных начального состояния:
Теперь, когда наш метод createFromConfig готов, давайте обновим, как мы используем его в нашем файле tests/main.spec.ts:
Обратите внимание, как мы создали кошелек initAddress (казначейство) из начальной "initAddress", чтобы передать его адрес в метод createFromConfig нашего MainContract.
На данный момент мы успешно инициализируем наш контракт! Поздравляю :)
Поскольку теперь мы также собираемся отправить определенные данные внутри тела сообщения, давайте обновим метод sendInternalMessage в наших обертках /MainContract.ts.
Мы собираемся переименовать его в sendIncrement, и теперь он примет еще одно значение - increment_by. Это будет номер для укращения стоимости хранения текущего контракта.
Мы также имеем в виду, что это тот же орган, который разборирует наш контракт, чтобы получить код операции. Итак, давайте не забудем сначала сохранить 32-битное целое число (1 для приращения, как вы можете видеть в коде нашего контракта), а затем - 32-битное целое число для приращения значения:
Есть еще один метод, который нам нужно обновить в нашей обертке - getData. Как вы помните, мы переименовали метод getter, а также теперь он возвращает два значения. Давайте скорректируем наш метод обертки:
async getData(provider: ContractProvider) {
const { stack } = await provider.get("get_contract_storage_data", []);
return {
number: stack.readNumber(),
recent_sender: stack.readAddress(),
};
}
Обратите внимание, как мы читаем результирующий стек метода геттера. Мы читаем Number(), чтобы прочитать целое число текущего значения.
Теперь мы все готовы вернуться к нашим тестам /main.spec.ts и продолжить прохождение нашего теста. Вот обновленный код нашего теста:
Что мы здесь обновили?
- Теперь мы передаем число - 1 - в метод sendIncrement, поэтому наше результирующее значение должно быть увращено на 1.
- Мы установили ожидания для значений recent_sender и number.
Теперь мы можем запустить наш тест с помощью команды yarn test. Если вы все сделали правильно - в терминале вы увидите следующее:
PASS tests/main.spec.ts
main.fc contract tests
✓ should successfully increase counter in contract and get the proper most recent sender address (452 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 4.339 s, estimated 5 s
Вуаля, наш встречный контракт теперь должным образом протестирован. С нетерпением жду дополнительной логики на следующих уроках!