Skip to content

Commit

Permalink
fix: merge main and fix Testenvironment error
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexD10S committed Apr 22, 2024
2 parents 479c525 + 40cc3ef commit 53c594c
Show file tree
Hide file tree
Showing 18 changed files with 292 additions and 146 deletions.
18 changes: 10 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ members = ["crates/*"]

[workspace.dependencies]
anyhow = "1.0"
thiserror = "1.0.58"
duct = "0.13"
git2 = "0.18"
tempfile = "3.8"
Expand Down
2 changes: 1 addition & 1 deletion crates/pop-cli/src/commands/new/pallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl NewPalletCommand {
&self.name,
))?;
set_theme(Theme);
let target = resolve_pallet_path(self.path.clone());
let target = resolve_pallet_path(self.path.clone())?;
let pallet_name = self.name.clone();
let pallet_path = target.join(pallet_name.clone());
if pallet_path.exists() {
Expand Down
1 change: 1 addition & 0 deletions crates/pop-contracts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ edition = "2021"

[dependencies]
anyhow.workspace = true
thiserror.workspace = true
duct.workspace = true
url.workspace = true
tokio.workspace = true
Expand Down
31 changes: 31 additions & 0 deletions crates/pop-contracts/src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use thiserror::Error;

#[derive(Error, Debug)]
pub enum Error {
#[error("Failed to create new contract project: {0}")]
NewContract(String),

#[error("IO error: {0}")]
IO(#[from] std::io::Error),

#[error("Failed to execute test command: {0}")]
TestCommand(String),

#[error("Failed to parse balance: {0}")]
BalanceParsing(String),

#[error("Failed to parse account address: {0}")]
AccountAddressParsing(String),

#[error("Failed to get manifest path: {0}")]
ManifestPath(String),

#[error("Failed to parse secret URI: {0}")]
ParseSecretURI(String),

#[error("Failed to create keypair from URI: {0}")]
KeyPairCreation(String),

#[error("Failed to parse hex encoded bytes: {0}")]
HexParsing(String),
}
1 change: 1 addition & 0 deletions crates/pop-contracts/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod build;
mod call;
mod errors;
mod new;
mod test;
mod up;
Expand Down
35 changes: 24 additions & 11 deletions crates/pop-contracts/src/new.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,43 @@
use crate::errors::Error;
use contract_build::new_contract_project;
use std::path::Path;

/// Create a new smart contract at `target`
pub fn create_smart_contract(name: String, target: &Path) -> anyhow::Result<()> {
// In this code, out_dir will automatically join `name` to `target`,
// which is created prior to the call to this function
// So we must pass `target.parent()`
new_contract_project(&name, target.canonicalize()?.parent())
pub fn create_smart_contract(name: String, target: &Path) -> Result<(), Error> {
// Canonicalize the target path to ensure consistency and resolve any symbolic links.
let canonicalized_path = target
.canonicalize()
// If an I/O error occurs during canonicalization, convert it into an Error enum variant.
.map_err(|e| Error::IO(e))?;

// Retrieve the parent directory of the canonicalized path.
let parent_path = canonicalized_path
.parent()
// If the parent directory cannot be retrieved (e.g., if the path has no parent),
// return a NewContract variant indicating the failure.
.ok_or(Error::NewContract("Failed to get parent directory".to_string()))?;

// Create a new contract project with the provided name in the parent directory.
new_contract_project(&name, Some(parent_path))
// If an error occurs during the creation of the contract project,
// convert it into a NewContract variant with a formatted error message.
.map_err(|e| Error::NewContract(format!("{}", e)))
}

#[cfg(test)]
mod tests {
use super::*;
use anyhow::{Error, Result};
use std::fs;
use tempfile;

fn setup_test_environment() -> Result<tempfile::TempDir, Error> {
let temp_dir = tempfile::tempdir().expect("Could not create temp dir");
let temp_dir = tempfile::tempdir()?;
let temp_contract_dir = temp_dir.path().join("test_contract");
fs::create_dir(&temp_contract_dir)?;
let result =
create_smart_contract("test_contract".to_string(), temp_contract_dir.as_path());
assert!(result.is_ok(), "Contract test environment setup failed");

create_smart_contract("test_contract".to_string(), temp_contract_dir.as_path())?;
Ok(temp_dir)
}

#[test]
fn test_create_smart_contract_success() -> Result<(), Error> {
let temp_dir = setup_test_environment()?;
Expand Down
46 changes: 31 additions & 15 deletions crates/pop-contracts/src/test.rs
Original file line number Diff line number Diff line change
@@ -1,46 +1,62 @@
use crate::errors::Error;
use duct::cmd;
use std::path::PathBuf;

pub fn test_smart_contract(path: &Option<PathBuf>) -> anyhow::Result<()> {
cmd("cargo", vec!["test"]).dir(path.clone().unwrap_or("./".into())).run()?;

pub fn test_smart_contract(path: &Option<PathBuf>) -> Result<(), Error> {
// Execute `cargo test` command in the specified directory.
cmd("cargo", vec!["test"])
.dir(path.clone().unwrap_or_else(|| PathBuf::from("./")))
.run()
.map_err(|e| Error::TestCommand(format!("Cargo test command failed: {}", e)))?;
Ok(())
}

pub fn test_e2e_smart_contract(path: &Option<PathBuf>) -> anyhow::Result<()> {
pub fn test_e2e_smart_contract(path: &Option<PathBuf>) -> Result<(), Error> {
// Execute `cargo test --features=e2e-tests` command in the specified directory.
cmd("cargo", vec!["test", "--features=e2e-tests"])
.dir(path.clone().unwrap_or("./".into()))
.run()?;

.dir(path.clone().unwrap_or_else(|| PathBuf::from("./")))
.run()
.map_err(|e| Error::TestCommand(format!("Cargo test command failed: {}", e)))?;
Ok(())
}

#[cfg(feature = "unit_contract")]
#[cfg(test)]
mod tests {
use super::*;
use anyhow::{Error, Result};
use std::fs;
use tempfile;
use thiserror::Error;

#[derive(Error, Debug)]
pub enum Error {
#[error("Error in test: {0}")]
TestEnvironmentError(String),
}

fn setup_test_environment() -> Result<tempfile::TempDir, Error> {
let temp_dir = tempfile::tempdir().expect("Could not create temp dir");
let temp_dir = tempfile::tempdir().map_err(|e| {
Error::TestEnvironmentError(format!("Failed to create temp dir: {}", e))
})?;
let temp_contract_dir = temp_dir.path().join("test_contract");
fs::create_dir(&temp_contract_dir)?;
fs::create_dir(&temp_contract_dir).map_err(|e| {
Error::TestEnvironmentError(format!("Failed to create test contract directory: {}", e))
})?;
let result =
crate::create_smart_contract("test_contract".to_string(), temp_contract_dir.as_path());
crate::create_smart_contract("test_contract".to_string(), temp_contract_dir.as_path())
.map_err(|e| {
Error::TestEnvironmentError(format!("Failed to create smart contract: {}", e))
});
assert!(result.is_ok(), "Contract test environment setup failed");

Ok(temp_dir)
}

#[test]
fn test_contract_test() -> Result<(), Error> {
let temp_contract_dir = setup_test_environment()?;

// Run unit tests for the smart contract in the temporary contract directory.
let result = test_smart_contract(&Some(temp_contract_dir.path().join("test_contract")));

assert!(result.is_ok(), "Result should be Ok");

Ok(())
}
}
29 changes: 13 additions & 16 deletions crates/pop-contracts/src/utils/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,30 @@
use anyhow::{anyhow, Result};
use crate::errors::Error;
use contract_build::ManifestPath;
use contract_extrinsics::BalanceVariant;
use ink_env::{DefaultEnvironment, Environment};
use std::{path::PathBuf, str::FromStr};
use subxt::{Config, PolkadotConfig as DefaultConfig};

// If the user specifies a path (which is not the current directory), it will have to manually
// add a Cargo.toml file. If not provided, pop-cli will ask the user for a specific path. or ask
// to the user the specific path (Like cargo-contract does)
pub fn get_manifest_path(path: &Option<PathBuf>) -> anyhow::Result<ManifestPath> {
if path.is_some() {
let full_path: PathBuf =
PathBuf::from(path.as_ref().unwrap().to_string_lossy().to_string() + "/Cargo.toml");

return ManifestPath::try_from(Some(full_path));
pub fn get_manifest_path(path: &Option<PathBuf>) -> Result<ManifestPath, Error> {
if let Some(path) = path {
let full_path = PathBuf::from(path.to_string_lossy().to_string() + "/Cargo.toml");
return ManifestPath::try_from(Some(full_path))
.map_err(|e| Error::ManifestPath(format!("Failed to get manifest path: {}", e)));
} else {
return ManifestPath::try_from(path.as_ref());
return ManifestPath::try_from(path.as_ref())
.map_err(|e| Error::ManifestPath(format!("Failed to get manifest path: {}", e)));
}
}

/// Parse a balance from string format
pub fn parse_balance(
balance: &str,
) -> Result<BalanceVariant<<DefaultEnvironment as Environment>::Balance>> {
BalanceVariant::from_str(balance).map_err(|e| anyhow!("Balance parsing failed: {e}"))
) -> Result<BalanceVariant<<DefaultEnvironment as Environment>::Balance>, Error> {
BalanceVariant::from_str(balance).map_err(|e| Error::BalanceParsing(format!("{}", e)))
}
pub fn parse_account(account: &str) -> Result<<DefaultConfig as Config>::AccountId> {

pub fn parse_account(account: &str) -> Result<<DefaultConfig as Config>::AccountId, Error> {
<DefaultConfig as Config>::AccountId::from_str(account)
.map_err(|e| anyhow::anyhow!("Account address parsing failed: {e}"))
.map_err(|e| Error::AccountAddressParsing(format!("{}", e)))
}

#[cfg(test)]
Expand Down
14 changes: 8 additions & 6 deletions crates/pop-contracts/src/utils/signer.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
use anyhow::Result;
use crate::errors::Error;
use contract_build::util::decode_hex;
use sp_core::Bytes;
use subxt_signer::{sr25519::Keypair, SecretUri};

/// Create a Signer from a secret URI.
pub(crate) fn create_signer(suri: &str) -> Result<Keypair> {
let uri = <SecretUri as std::str::FromStr>::from_str(suri)?;
let keypair = Keypair::from_uri(&uri)?;
pub(crate) fn create_signer(suri: &str) -> Result<Keypair, Error> {
let uri = <SecretUri as std::str::FromStr>::from_str(suri)
.map_err(|e| Error::ParseSecretURI(format!("{}", e)))?;
let keypair = Keypair::from_uri(&uri).map_err(|e| Error::KeyPairCreation(format!("{}", e)))?;
Ok(keypair)
}

/// Parse hex encoded bytes.
pub fn parse_hex_bytes(input: &str) -> Result<Bytes> {
let bytes = decode_hex(input)?;
pub fn parse_hex_bytes(input: &str) -> Result<Bytes, Error> {
let bytes = decode_hex(input).map_err(|e| Error::HexParsing(format!("{}", e)))?;
Ok(bytes.into())
}
1 change: 1 addition & 0 deletions crates/pop-parachains/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ edition = "2021"

[dependencies]
anyhow.workspace = true
thiserror.workspace = true
duct.workspace = true
git2.workspace = true
tempfile.workspace = true
Expand Down
Loading

0 comments on commit 53c594c

Please sign in to comment.