-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: add test runner * feat: finish test runner & add test isolation checks * ci: install solc * chore: rename Greet to Greeter and break into 2 contracts * feat: add multi-contract runner * feat: add gas consumption per test we subtract 21k gas and the associated calldata costs of calling the function * chore: fix clippy lints * feat: add dapp cli
- Loading branch information
Showing
6 changed files
with
635 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.6; | ||
|
||
contract Greeter { | ||
string public greeting; | ||
|
||
function greet(string memory _greeting) public { | ||
greeting = _greeting; | ||
} | ||
|
||
function gm() public { | ||
greeting = "gm"; | ||
} | ||
} | ||
|
||
contract GreeterTestSetup { | ||
Greeter greeter; | ||
|
||
function greeting() public view returns (string memory) { | ||
return greeter.greeting(); | ||
} | ||
|
||
function setUp() public { | ||
greeter = new Greeter(); | ||
} | ||
} | ||
|
||
contract GreeterTest is GreeterTestSetup { | ||
function greet(string memory greeting) public { | ||
greeter.greet(greeting); | ||
} | ||
|
||
// check the positive case | ||
function testGreeting() public { | ||
greeter.greet("yo"); | ||
require(keccak256(abi.encodePacked(greeter.greeting())) == keccak256(abi.encodePacked("yo")), "not equal"); | ||
} | ||
|
||
// check the unhappy case | ||
function testFailGreeting() public { | ||
greeter.greet("yo"); | ||
require(keccak256(abi.encodePacked(greeter.greeting())) == keccak256(abi.encodePacked("hi")), "not equal to `hi`"); | ||
} | ||
|
||
function testIsolation() public { | ||
require(bytes(greeter.greeting()).length == 0); | ||
} | ||
} | ||
|
||
contract GmTest is GreeterTestSetup { | ||
function testGm() public { | ||
greeter.gm(); | ||
require(keccak256(abi.encodePacked(greeter.greeting())) == keccak256(abi.encodePacked("gm")), "not equal"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
use structopt::StructOpt; | ||
|
||
use dapptools::dapp::{Executor, MultiContractRunner}; | ||
use evm::Config; | ||
|
||
use ansi_term::Colour; | ||
|
||
#[derive(Debug, StructOpt)] | ||
pub struct Opts { | ||
#[structopt(subcommand)] | ||
pub sub: Subcommands, | ||
} | ||
|
||
#[derive(Debug, StructOpt)] | ||
#[structopt(about = "Perform Ethereum RPC calls from the comfort of your command line.")] | ||
pub enum Subcommands { | ||
Test { | ||
#[structopt( | ||
help = "glob path to your smart contracts", | ||
long, | ||
short, | ||
default_value = "./src/**/*.sol" | ||
)] | ||
contracts: String, | ||
// TODO: Add extra configuration options around blockchain context | ||
}, | ||
} | ||
|
||
fn main() -> eyre::Result<()> { | ||
let opts = Opts::from_args(); | ||
match opts.sub { | ||
Subcommands::Test { contracts } => { | ||
let cfg = Config::istanbul(); | ||
let gas_limit = 12_500_000; | ||
let env = Executor::new_vicinity(); | ||
|
||
let runner = MultiContractRunner::new(&contracts, &cfg, gas_limit, env).unwrap(); | ||
let results = runner.test().unwrap(); | ||
|
||
// TODO: Once we add traces in the VM, proceed to print them in a nice and structured | ||
// way | ||
for (contract_name, tests) in results { | ||
if !tests.is_empty() { | ||
println!("Running {} tests for {}", tests.len(), contract_name); | ||
} | ||
|
||
for (name, result) in tests { | ||
let status = if result.success { | ||
Colour::Green.paint("[PASS]") | ||
} else { | ||
Colour::Red.paint("[FAIL]") | ||
}; | ||
println!("{} {} (gas: {})", status, name, result.gas_used); | ||
} | ||
// skip a line | ||
println!(); | ||
} | ||
} | ||
} | ||
|
||
Ok(()) | ||
} |
Oops, something went wrong.