bulloak

A simple, fast, and easy-to-use Solidity test generator based on the Branching Tree Technique.

Installation

bash cargo install bulloak

Usage

Say you have a foo.tree file with the following contents:

text FooTest └── When stuff called └── It should revert.

If you pass it to bulloak like so, you will get the skeleton of a test contract printed to stdout:

``` $ bulloak foo.tree pragma solidity 0.8.0;

contract FooTest { modifier whenStuffCalled() { _; }

function testRevertWhenStuffCalled() external whenStuffCalled { // It should revert. } } ```

Scaffold Multiple Trees

If you are working in a solidity project and you have multiple trees you want to scaffold, you can use the -w option.

$ bulloak -w ./**/*.tree

This will create solidity files with the same name as the .tree files with the result of scaffolding each tree.

If there exists a file with a title that matches the name at the root node of the .tree, then bulloak will skip writing that file. However, you may override this behaviour with the -f flag. This will write to the filesystem overwriting any files that exist.

$ bulloak -wf ./**/*.tree

Compiler Errors

Another feature of bulloak is reporting errors in your input trees.

For example, say you have a buggy foo.tree file, which is missing a character. Running bulloak foo.tree would report the error like this:

`` ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••• bulloak error: unexpectedwhen` keyword

── when the id references a null stream ^^^^

--- (line 2, column 4) --- file: foo.tree ```

CLI Options

``` Usage: bulloak [OPTIONS] [FILES]...

Arguments: [FILES]... .tree files to process

Options: -c Whether to print it branches as comments in the output code -i The indentation of the output code [default: 2] -w, --write-files Whether to write to files instead of stdout -f, --force-write When write_files is specified, use --force-write to overwrite the output files -s, --solidity-version Sets a solidity version for the test contracts [default: 0.8.0] -h, --help Print help (see more with '--help') -V, --version Print version ```

Trees

bulloak scaffolds solidity test files based on .tree specifications that follow the Branching Tree Technique.

Currently, there is on-going discussion on how to handle different edge-cases to better empower the solidity community. This section is a description of the current implementation of the compiler.

Terminology

Spec

Each tree file should describe a function under test. Trees follow these rules:

Take the following solidity function:

solidity function hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? hash(a, b) : hash(b, a); } A reasonable spec for the above function would be: HashPairTest ├── It should never revert. ├── When first arg is smaller than second arg │ └── It should match the result of `keccak256(abi.encodePacked(a,b))`. └── When first arg is bigger than second arg └── It should match the result of `keccak256(abi.encodePacked(b,a))`.

There is a top-level action which would generate a test to check the function invariant that it should never revert.

Then, we have the two possible preconditions: a < b and a >= b. Both branches end in an action that will make bulloak generate the respective test.

Note the following things:

Output

There are a few things to keep in mind about the scaffolded solidity test:

Contributing

Please refer to CONTRIBUTING.md.

License

This project is licensed under either of: