diff --git a/src/build/contract.rs b/src/build/contract.rs index 94488156..6f76638f 100644 --- a/src/build/contract.rs +++ b/src/build/contract.rs @@ -212,14 +212,11 @@ impl Contract { "Refusing to overwrite an existing file {binary_file_path:?} (use --overwrite to force).", ); } - File::create(&binary_file_path) - .map_err(|error| { - anyhow::anyhow!("File {:?} creating error: {}", binary_file_path, error) - })? - .write_all(format!("0x{}", hex::encode(self.build.bytecode.as_slice())).as_bytes()) - .map_err(|error| { - anyhow::anyhow!("File {:?} writing error: {}", binary_file_path, error) - })?; + std::fs::write( + &binary_file_path, + format!("0x{}", hex::encode(self.build.bytecode.as_slice())).as_bytes(), + ) + .map_err(|error| anyhow::anyhow!("File {binary_file_path:?} writing error: {error}"))?; if selection.is_empty() { return Ok(()); diff --git a/src/lib.rs b/src/lib.rs index b15c0969..e1262c3d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -60,10 +60,6 @@ pub fn llvm_ir( suppressed_warnings: Vec, debug_config: Option, ) -> anyhow::Result { - if input_paths.is_empty() { - writeln!(std::io::stderr(), "No input sources provided").expect("Stderr writing error"); - } - let paths: Vec<&Path> = input_paths.iter().map(|path| path.as_path()).collect(); let project = Project::try_from_llvm_ir_paths(paths.as_slice(), output_selection)?; @@ -90,10 +86,6 @@ pub fn eravm_assembly( suppressed_warnings: Vec, debug_config: Option, ) -> anyhow::Result { - if input_paths.is_empty() { - writeln!(std::io::stderr(), "No input sources provided").expect("Stderr writing error"); - } - let paths: Vec<&Path> = input_paths.iter().map(|path| path.as_path()).collect(); let project = Project::try_from_eravm_assembly_paths(paths.as_slice(), output_selection)?; diff --git a/tests/cli/basic.rs b/tests/cli/basic.rs index 6b493cfb..c033d84f 100644 --- a/tests/cli/basic.rs +++ b/tests/cli/basic.rs @@ -23,6 +23,48 @@ fn default() -> anyhow::Result<()> { Ok(()) } +#[test] +fn with_proxy() -> anyhow::Result<()> { + let _ = common::setup(); + + let args = &[common::TEST_CREATE_MINIMAL_PROXY_TO_CONTRACT_PATH]; + + let result = common::execute_zkvyper(args)?; + let zkvyper_status = result + .success() + .stdout(predicate::str::contains("0x")) + .get_output() + .status + .code() + .expect("No exit code."); + + let vyper_result = common::execute_vyper(args)?; + vyper_result.code(zkvyper_status); + + Ok(()) +} + +#[test] +fn with_warnings() -> anyhow::Result<()> { + let _ = common::setup(); + + let args = &[common::TEST_TX_ORIGIN_CONTRACT_PATH]; + + let result = common::execute_zkvyper(args)?; + let zkvyper_status = result + .success() + .stdout(predicate::str::contains("0x")) + .get_output() + .status + .code() + .expect("No exit code."); + + let vyper_result = common::execute_vyper(args)?; + vyper_result.code(zkvyper_status); + + Ok(()) +} + #[test] fn without_input_files() -> anyhow::Result<()> { let _ = common::setup(); diff --git a/tests/cli/format.rs b/tests/cli/format.rs index 0520163b..a9547413 100644 --- a/tests/cli/format.rs +++ b/tests/cli/format.rs @@ -1,6 +1,8 @@ use predicates::prelude::*; use test_case::test_case; +use era_compiler_vyper::VyperSelection; + use crate::common; #[test_case("combined_json")] @@ -13,10 +15,38 @@ use crate::common; #[test_case("devdoc")] #[test_case("eravm_assembly")] #[test_case("project_metadata")] -fn default(selector: &str) -> anyhow::Result<()> { +fn default(format: &str) -> anyhow::Result<()> { + let _ = common::setup(); + + let args = &[common::TEST_GREETER_CONTRACT_PATH, "-f", format]; + + let result = common::execute_zkvyper(args)?; + result.success(); + + Ok(()) +} + +#[test] +fn all() -> anyhow::Result<()> { let _ = common::setup(); - let args = &[common::TEST_GREETER_CONTRACT_PATH, "-f", selector]; + let format = [ + VyperSelection::IRJson, + VyperSelection::AST, + VyperSelection::ABI, + VyperSelection::MethodIdentifiers, + VyperSelection::Layout, + VyperSelection::UserDocumentation, + VyperSelection::DeveloperDocumentation, + VyperSelection::EraVMAssembly, + VyperSelection::ProjectMetadata, + ] + .into_iter() + .map(|selection| selection.to_string()) + .collect::>() + .join(","); + + let args = &[common::TEST_GREETER_CONTRACT_PATH, "-f", format.as_str()]; let result = common::execute_zkvyper(args)?; result.success(); diff --git a/tests/cli/mod.rs b/tests/cli/mod.rs index 2208a7de..853b3686 100644 --- a/tests/cli/mod.rs +++ b/tests/cli/mod.rs @@ -20,7 +20,7 @@ mod output_dir; mod overwrite; mod recursive_process; mod search_paths; -mod suppress; +mod suppress_warnings; mod threads; mod version; mod vyper; diff --git a/tests/cli/output_dir.rs b/tests/cli/output_dir.rs index fc85a56d..987ef8fd 100644 --- a/tests/cli/output_dir.rs +++ b/tests/cli/output_dir.rs @@ -1,6 +1,8 @@ use predicates::prelude::*; use tempfile::TempDir; +use era_compiler_vyper::VyperSelection; + use crate::common; #[test] @@ -68,7 +70,7 @@ fn combined_json() -> anyhow::Result<()> { } #[test] -fn with_eravm_assembly() -> anyhow::Result<()> { +fn eravm_assembly_only() -> anyhow::Result<()> { let _ = common::setup(); let tmp_dir_zk_vyper = TempDir::new().expect("Failed to create temp dir"); @@ -110,3 +112,70 @@ fn with_eravm_assembly() -> anyhow::Result<()> { Ok(()) } + +#[test] +fn all_output() -> anyhow::Result<()> { + let _ = common::setup(); + + let tmp_dir_zk_vyper = TempDir::new().expect("Failed to create temp dir"); + let tmp_dir_path_zk_vyper = tmp_dir_zk_vyper.path().to_str().unwrap(); + + let format = [ + VyperSelection::IRJson, + VyperSelection::AST, + VyperSelection::ABI, + VyperSelection::MethodIdentifiers, + VyperSelection::Layout, + VyperSelection::UserDocumentation, + VyperSelection::DeveloperDocumentation, + VyperSelection::EraVMAssembly, + VyperSelection::ProjectMetadata, + ] + .into_iter() + .map(|selection| selection.to_string()) + .collect::>() + .join(","); + + // Check if output is empty and exit code + let args = &[ + common::TEST_GREETER_CONTRACT_PATH, + "-o", + tmp_dir_path_zk_vyper, + "-f", + format.as_str(), + ]; + + let result = common::execute_zkvyper(args)?; + result + .success() + .stderr(predicate::str::contains("Refusing to overwrite").not()) + .get_output() + .status + .code() + .expect("No exit code."); + + // Verify output directory and file creation + assert_eq!( + false, + common::is_file_empty(&format!( + "{tmp_dir_path_zk_vyper}/{}", + common::VYPER_BIN_OUTPUT_NAME + ))? + ); + assert_eq!( + false, + common::is_file_empty(&format!( + "{tmp_dir_path_zk_vyper}/{}", + common::VYPER_ASM_OUTPUT_NAME + ))? + ); + assert_eq!( + false, + common::is_file_empty(&format!( + "{tmp_dir_path_zk_vyper}/{}", + common::TEST_GREETER_CONTRACT_NAME + ))? + ); + + Ok(()) +} diff --git a/tests/cli/suppress.rs b/tests/cli/suppress_warnings.rs similarity index 62% rename from tests/cli/suppress.rs rename to tests/cli/suppress_warnings.rs index a1567441..e0d69b9c 100644 --- a/tests/cli/suppress.rs +++ b/tests/cli/suppress_warnings.rs @@ -24,3 +24,21 @@ fn default(warning_type: WarningType) -> anyhow::Result<()> { Ok(()) } + +#[test] +fn invalid_type() -> anyhow::Result<()> { + let _ = common::setup(); + + let args = &[ + common::TEST_TX_ORIGIN_CONTRACT_PATH, + "--suppress-warnings", + "unknown", + ]; + + let result = common::execute_zkvyper(args)?; + result + .failure() + .stderr(predicate::str::contains("invalid warning type: unknown")); + + Ok(()) +} diff --git a/tests/common/const.rs b/tests/common/const.rs index a9694c9d..9c1bfa1e 100644 --- a/tests/common/const.rs +++ b/tests/common/const.rs @@ -49,6 +49,10 @@ pub const TEST_SELFDESTRUCT_CONTRACT_PATH: &'static str = pub const TEST_CREATE_COPY_OF_CONTRACT_PATH: &'static str = "tests/data/contracts/vyper/create_copy_of.vy"; +/// A test input file. +pub const TEST_CREATE_MINIMAL_PROXY_TO_CONTRACT_PATH: &'static str = + "tests/data/contracts/vyper/create_minimal_proxy_to.vy"; + /// A test input file. pub const TEST_ERAVM_ASSEMBLY_CONTRACT_PATH: &'static str = "tests/data/contracts/eravm/default.zasm"; diff --git a/tests/data/contracts/vyper/create_minimal_proxy_to.vy b/tests/data/contracts/vyper/create_minimal_proxy_to.vy new file mode 100644 index 00000000..72487ddd --- /dev/null +++ b/tests/data/contracts/vyper/create_minimal_proxy_to.vy @@ -0,0 +1,4 @@ +@external +def f(): + result: address = create_minimal_proxy_to(convert(0x42, address)) + return \ No newline at end of file