This file is a short practical guide for running universalmutator on TON projects.
The focus here is on real commands and a basic workflow:
Tolkfor.tolk->ton_common.rules + tolk.rulesTactfor.tact->ton_common.rules + tact.rulesFunCfor.fcand.func->ton_common.rules + func.rules
npm i -g @tact-lang/compiler
npm i -g @ton/tolk-js
npm i -g @ton-community/func-jsIf you need --comby:
python -m pip install combyFor --comby, you need not only the Python package but also an installed external comby binary.
There are two ways to specify your compile-check command:
--cmd "<command>"for a singlemutaterun onlyUM_TACT_CMD,UM_TOLK_CMD,UM_FUNC_CMDas defaults for the current shell session
The minimal scenario is almost always this:
mutate <sourcefile> <tact|tolk|func> --mutantDir mutants
analyze_mutants <sourcefile> "<test command>" --mutantDir mutants --prefix run
show_mutants run.notkilled.txt --mutantDir mutants --sourceDir <source_dir> --conciseIf there are many mutants, the next commands are:
prioritize_mutantsprune_mutantsintersect_mutants
mutate contracts/src/Contract.tolk tolk --cmd "acton build" --mutantDir mutants
analyze_mutants contracts/src/Contract.tolk "acton test" \
--mutantDir mutants \
--prefix tolkmutate contracts/contract.tolk tolk --mutantDir mutants
analyze_mutants contracts/contract.tolk "npx blueprint test" \
--mutantDir mutants \
--prefix tolk
show_mutants tolk.notkilled.txt \
--mutantDir mutants \
--sourceDir contracts \
--conciseIf the project is built through build, it is better to override the compile-check:
mutate contracts/contract.tact tact \
--cmd "npx blueprint build --all" \
--mutantDir mutantsIf you need a full build and test run:
analyze_mutants contracts/contract.tact "npx blueprint test" \
--mutantDir mutants \
--prefix tactgit clone https://github.com/tact-lang/jetton
cd jetton
yarn
mutate src/contracts/base/jetton-minter.tact tact \
--cmd "tact --config ./tact.config.json --project Jetton" \
--mutantDir mutantsgit clone https://github.com/ton-blockchain/tolk-bench.git
cd tolk-bench
npm install
mutate contracts_FunC/01_jetton/jetton-minter-discoverable.fc func \
--cmd 'npx func-js -C "contracts_FunC/01_jetton" params.fc op-codes.fc discovery-params.fc jetton-utils.fc jetton-minter-discoverable.fc' \
--mutantDir mutantsIf you are mutating not the entrypoint but an imported .fc file, this exact --cmd pattern is what you need: the build must go through the same target set the project actually uses.
After analyze_mutants, you will usually get:
killed.txtor<prefix>.killed.txtnotkilled.txtor<prefix>.notkilled.txt
These files contain mutant names, and you can already use them with all post-processing commands.
Shows exactly what changed in surviving mutants.
show_mutants func-minter.notkilled.txt \
--mutantDir mutants \
--sourceDir contracts_FunC/01_jetton \
--conciseThis command is useful if:
- there are too many surviving mutants
- tests are expensive
- you want to run the most diverse and informative mutations first
Basic example:
prioritize_mutants func-minter.notkilled.txt prioritized.txt 50 \
--mutantDir mutants \
--sourceDir contracts_FunC/01_jettonWhat it does:
- takes the list of surviving mutants
- ranks them by difference
- keeps the top 50 in
prioritized.txt
Then you can run:
show_mutants prioritized.txt \
--mutantDir mutants \
--sourceDir contracts_FunC/01_jetton \
--conciseOr re-test only this subset:
analyze_mutants contracts_FunC/01_jetton/jetton-minter-discoverable.fc \
"npx jest --runInBand tests/01_jetton/JettonWallet.spec.ts" \
--mutantDir mutants \
--fromFile prioritized.txt \
--prefix prioritized-run