Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
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
13 changes: 13 additions & 0 deletions cli/assets/generated/TestTemplate.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import "forge-std/Test.sol";
import "../src/{contract_name}.sol";
Comment thread
raxhvl marked this conversation as resolved.
Outdated

contract {contract_name}Test is Test {
{contract_name} public {instance_name};

function setUp() public {
{instance_name} = new {contract_name}();
Comment thread
mds1 marked this conversation as resolved.
}
}
70 changes: 70 additions & 0 deletions cli/src/cmd/forge/generate/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//! generate command

use clap::{Parser, Subcommand};
use std::fs;
use std::path::Path;

/// CLI arguments for `forge generate`.
#[derive(Debug, Parser)]
pub struct GenerateArgs {
#[clap(subcommand)]
pub sub: GenerateSubcommands,
}

#[derive(Debug, Subcommand)]
pub enum GenerateSubcommands {
/// Scaffolds test file for given contract.
Test(GenerateTestArgs),
}

#[derive(Debug, Parser)]
pub struct GenerateTestArgs {
/// Contract name for test generation.
#[clap(long, short, value_name = "CONTRACT_NAME")]
pub contract_name: String,
}

impl GenerateTestArgs {
pub fn run(self) -> eyre::Result<()> {
let contract_name = format_identifier(&self.contract_name, true);
let instance_name = format_identifier(&self.contract_name, false);

// Create the test file content.
let test_content = include_str!("../../../../assets/generated/TestTemplate.t.sol");
let test_content = test_content
.replace("{contract_name}", &contract_name)
.replace("{instance_name}", &instance_name);

// Create the test directory if it doesn't exist.
fs::create_dir_all("test").unwrap();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we avoid unwrap here? We can just use ? and maybe map_err as well to make it a tad more descriptive.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely! I looked at some other files and figured there is wrapper around fs foundry_common::fs so I have swapped the implementation.


// Define the test file path
let test_file_path = Path::new("test").join(format!("{}.t.sol", contract_name));

// Write the test content to the test file.
fs::write(&test_file_path, test_content).unwrap();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto on unwrap

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed too


println!("Test file generated: {}", test_file_path.to_str().unwrap());
Ok(())
}
}

/// Utility function to convert an identifier to pascal or camel case.
fn format_identifier(input: &str, is_pascal_case: bool) -> String {
let mut result = String::new();
let mut capitalize_next = is_pascal_case;

for word in input.split_whitespace() {
if !word.is_empty() {
let (first, rest) = word.split_at(1);
let formatted_word = if capitalize_next {
format!("{}{}", first.to_uppercase(), rest)
} else {
format!("{}{}", first.to_lowercase(), rest)
};
capitalize_next = true;
result.push_str(&formatted_word);
}
}
result
}
1 change: 1 addition & 0 deletions cli/src/cmd/forge/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub mod flatten;
pub mod fmt;
pub mod fourbyte;
pub mod geiger;
pub mod generate;
pub mod init;
pub mod inspect;
pub mod install;
Expand Down
5 changes: 4 additions & 1 deletion cli/src/forge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use clap::{CommandFactory, Parser};
use clap_complete::generate;
use foundry_cli::{
cmd::{
forge::{cache::CacheSubcommands, watch},
forge::{cache::CacheSubcommands, generate::GenerateSubcommands, watch},
Cmd,
},
handler,
Expand Down Expand Up @@ -97,5 +97,8 @@ fn main() -> eyre::Result<()> {
}
Subcommands::Doc(cmd) => cmd.run(),
Subcommands::Selectors { command } => utils::block_on(command.run()),
Subcommands::Generate(cmd) => match cmd.sub {
GenerateSubcommands::Test(cmd) => cmd.run(),
},
}
}
5 changes: 4 additions & 1 deletion cli/src/opts/forge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::cmd::forge::{
flatten,
fmt::FmtArgs,
fourbyte::UploadSelectorsArgs,
geiger,
geiger, generate,
init::InitArgs,
inspect,
install::InstallArgs,
Expand Down Expand Up @@ -163,6 +163,9 @@ pub enum Subcommands {
#[clap(subcommand)]
command: SelectorsSubcommands,
},

/// Generate scaffold files.
Generate(generate::GenerateArgs),
}

// A set of solc compiler settings that can be set via command line arguments, which are intended
Expand Down