Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: use TestFunctionExt for string #2586

Merged
merged 2 commits into from
Aug 3, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cli/src/cmd/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use ethers::{
Artifact, ProjectCompileOutput,
},
};
use foundry_common::TestFunctionExt;
use foundry_config::Chain as ConfigChain;
use foundry_utils::Retry;
use std::{collections::BTreeMap, path::PathBuf};
Expand Down Expand Up @@ -148,8 +149,7 @@ impl From<RetryArgs> for Retry {
}

pub fn needs_setup(abi: &Abi) -> bool {
let setup_fns: Vec<_> =
abi.functions().filter(|func| func.name.to_lowercase() == "setup").collect();
let setup_fns: Vec<_> = abi.functions().filter(|func| func.name.is_setup()).collect();

for setup_fn in setup_fns.iter() {
if setup_fn.name != "setUp" {
Expand Down
3 changes: 2 additions & 1 deletion cli/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use ethers::{
prelude::Graph,
solc::{report::NoReporter, Artifact, FileFilter, Project, ProjectCompileOutput},
};
use foundry_common::TestFunctionExt;
use std::{
collections::BTreeMap,
fmt::Display,
Expand Down Expand Up @@ -188,7 +189,7 @@ impl ProjectCompiler {
let dev_functions =
contract.abi.as_ref().unwrap().abi.functions().into_iter().filter(
|func| {
func.name.starts_with("test") ||
func.name.is_test() ||
func.name.eq("IS_TEST") ||
func.name.eq("IS_SCRIPT")
},
Expand Down
2 changes: 2 additions & 0 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ pub mod errors;
pub mod evm;
pub mod fmt;
pub mod fs;
pub mod traits;
pub use constants::*;
pub use traits::*;
80 changes: 80 additions & 0 deletions common/src/traits.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
//! Commonly used traits
mattsse marked this conversation as resolved.
Show resolved Hide resolved

use ethers_core::abi::Function;

/// Extension trait for matching tests
pub trait TestFilter: Send + Sync {
/// Returns whether the test should be included
fn matches_test(&self, test_name: impl AsRef<str>) -> bool;
/// Returns whether the contract should be included
fn matches_contract(&self, contract_name: impl AsRef<str>) -> bool;
/// Returns a contract with the given path should be included
fn matches_path(&self, path: impl AsRef<str>) -> bool;
}

/// Extension trait for `Function`
pub trait TestFunctionExt {
/// Whether this function should be executed as fuzz test
fn is_fuzz_test(&self) -> bool;
/// Whether this function is a test
fn is_test(&self) -> bool;
/// Whether this function is a test that should fail
fn is_test_fail(&self) -> bool;
/// Whether this function is a `setUp` function
fn is_setup(&self) -> bool;
}

impl TestFunctionExt for Function {
fn is_fuzz_test(&self) -> bool {
// test functions that have inputs are considered fuzz tests as those inputs will be fuzzed
!self.inputs.is_empty()
}

fn is_test(&self) -> bool {
self.name.is_test()
}

fn is_test_fail(&self) -> bool {
self.name.is_test_fail()
}

fn is_setup(&self) -> bool {
self.name.is_setup()
}
}

impl<'a> TestFunctionExt for &'a str {
fn is_fuzz_test(&self) -> bool {
self.contains("fuzz")
onbjerg marked this conversation as resolved.
Show resolved Hide resolved
}

fn is_test(&self) -> bool {
self.starts_with("test")
}

fn is_test_fail(&self) -> bool {
self.starts_with("testFail")
}

fn is_setup(&self) -> bool {
self.to_lowercase() == "setup"
}
}

impl TestFunctionExt for String {
fn is_fuzz_test(&self) -> bool {
self.as_str().is_fuzz_test()
}

fn is_test(&self) -> bool {
self.as_str().is_test()
}

fn is_test_fail(&self) -> bool {
self.as_str().is_test_fail()
}

fn is_setup(&self) -> bool {
self.as_str().is_setup()
}
}
3 changes: 2 additions & 1 deletion evm/src/coverage/analysis.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::{ContractId, CoverageItem, CoverageItemKind, SourceLocation};
use ethers::solc::artifacts::ast::{self, Ast, Node, NodeType};
use foundry_common::TestFunctionExt;
use semver::Version;
use std::collections::HashMap;
use tracing::warn;
Expand Down Expand Up @@ -482,7 +483,7 @@ impl SourceAnalyzer {
)?;
let is_test = items.iter().any(|item| {
if let CoverageItemKind::Function { name } = &item.kind {
name.starts_with("test")
name.is_test()
} else {
false
}
Expand Down
3 changes: 2 additions & 1 deletion forge/src/gas_report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::{
};
use comfy_table::{modifiers::UTF8_ROUND_CORNERS, presets::UTF8_FULL, *};
use ethers::types::U256;
use foundry_common::TestFunctionExt;
use serde::{Deserialize, Serialize};
use std::{collections::BTreeMap, fmt::Display};

Expand Down Expand Up @@ -70,7 +71,7 @@ impl GasReport {
}
// TODO: More robust test contract filtering
RawOrDecodedCall::Decoded(func, sig, _)
if !func.starts_with("test") && func != "setUp" =>
if !func.is_test() && !func.is_setup() =>
{
let function_report = contract_report
.functions
Expand Down
4 changes: 2 additions & 2 deletions forge/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ pub use runner::ContractRunner;
mod multi_runner;
pub use multi_runner::{MultiContractRunner, MultiContractRunnerBuilder};

mod traits;
pub use traits::*;
/// reexport
pub use foundry_common::traits::TestFilter;

pub mod result;

Expand Down
7 changes: 4 additions & 3 deletions forge/src/multi_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use ethers::{
types::{Address, Bytes, U256},
};
use eyre::Result;
use foundry_common::TestFunctionExt;
use foundry_evm::{
executor::{
backend::Backend, fork::CreateFork, inspector::CheatsConfig, opts::EvmOpts, Executor,
Expand Down Expand Up @@ -74,7 +75,7 @@ impl MultiContractRunner {
filter.matches_contract(&id.name)
})
.flat_map(|(_, (abi, _, _))| abi.functions().map(|func| func.name.clone()))
.filter(|sig| sig.starts_with("test"))
.filter(|sig| sig.is_test())
.collect()
}

Expand All @@ -95,7 +96,7 @@ impl MultiContractRunner {
let name = id.name.clone();
let tests = abi
.functions()
.filter(|func| func.name.starts_with("test"))
.filter(|func| func.name.is_test())
.filter(|func| filter.matches_test(func.signature()))
.map(|func| func.name.clone())
.collect::<Vec<_>>();
Expand Down Expand Up @@ -282,7 +283,7 @@ impl MultiContractRunnerBuilder {
let abi = contract.abi.expect("We should have an abi by now");
// if it's a test, add it to deployable contracts
if abi.constructor.as_ref().map(|c| c.inputs.is_empty()).unwrap_or(true) &&
abi.functions().any(|func| func.name.starts_with("test"))
abi.functions().any(|func| func.name.is_test())
{
deployable_contracts.insert(
id.clone(),
Expand Down
7 changes: 4 additions & 3 deletions forge/src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use ethers::{
types::{Address, Bytes, U256},
};
use eyre::Result;
use foundry_common::TestFunctionExt;
use foundry_evm::{
executor::{CallResult, DeployResult, EvmError, Executor},
fuzz::FuzzedExecutor,
Expand Down Expand Up @@ -182,7 +183,7 @@ impl<'a> ContractRunner<'a> {
let mut warnings = Vec::new();

let setup_fns: Vec<_> =
self.contract.functions().filter(|func| func.name.to_lowercase() == "setup").collect();
self.contract.functions().filter(|func| func.name.is_setup()).collect();

let needs_setup = setup_fns.len() == 1 && setup_fns[0].name == "setUp";

Expand Down Expand Up @@ -247,11 +248,11 @@ impl<'a> ContractRunner<'a> {
.functions()
.into_iter()
.filter(|func| {
func.name.starts_with("test") &&
func.name.is_test() &&
filter.matches_test(func.signature()) &&
(include_fuzz_tests || func.inputs.is_empty())
})
.map(|func| (func, func.name.starts_with("testFail")))
.map(|func| (func, func.name.is_test_fail()))
.collect();

let test_results = tests
Expand Down
39 changes: 0 additions & 39 deletions forge/src/traits.rs

This file was deleted.