diff --git a/forc-util/src/lib.rs b/forc-util/src/lib.rs index efeb8c5cec1..56f1efb76eb 100644 --- a/forc-util/src/lib.rs +++ b/forc-util/src/lib.rs @@ -41,10 +41,6 @@ pub fn find_parent_dir_with_file(starter_path: &Path, file_name: &str) -> Option pub fn find_manifest_dir(starter_path: &Path) -> Option { find_parent_dir_with_file(starter_path, constants::MANIFEST_FILE_NAME) } -/// Continually go up in the file tree until a Cargo manifest file is found. -pub fn find_cargo_manifest_dir(starter_path: &Path) -> Option { - find_parent_dir_with_file(starter_path, constants::TEST_MANIFEST_FILE_NAME) -} pub fn is_sway_file(file: &Path) -> bool { let res = file.extension(); diff --git a/forc/src/cli/commands/clean.rs b/forc/src/cli/commands/clean.rs index cfd5909298f..5490eeee4e3 100644 --- a/forc/src/cli/commands/clean.rs +++ b/forc/src/cli/commands/clean.rs @@ -2,9 +2,7 @@ use crate::ops::forc_clean; use anyhow::Result; use clap::Parser; -/// Removes the default forc compiler output artifact directory, i.e. `/out`. Also -/// calls `cargo clean` which removes the `target` directory generated by `cargo` when running -/// tests. +/// Removes the default forc compiler output artifact directory, i.e. `/out`. #[derive(Debug, Parser)] pub struct Command { /// Path to the project, if not specified, current working directory will be used. diff --git a/forc/src/cli/commands/test.rs b/forc/src/cli/commands/test.rs index abc3bcfe0c8..7be1758e966 100644 --- a/forc/src/cli/commands/test.rs +++ b/forc/src/cli/commands/test.rs @@ -1,104 +1,41 @@ -use crate::ops::forc_build; use anyhow::{bail, Result}; use clap::Parser; -use std::io::{BufRead, BufReader}; -use std::process; -use std::thread; -use tracing::{error, info}; -/// Run Rust-based tests on current project. -/// As of now, `forc test` is a simple wrapper on -/// `cargo test`; `forc new` also creates a rust -/// package under your project, named `tests`. -/// You can opt to either run these Rust tests by -/// using `forc test` or going inside the package -/// and using `cargo test`. +/// Run the Sway unit tests for the current project. +/// +/// NOTE: This feature is not yet implemented. Track progress at the following link: +/// https://github.com/FuelLabs/sway/issues/1832 +/// +/// NOTE: Previously this command was used to support Rust integration testing, however the +/// provided behaviour served no benefit over running `cargo test` directly. The proposal to change +/// the behaviour to support unit testing can be found at the following link: +/// https://github.com/FuelLabs/sway/issues/1833 +/// +/// Sway unit tests are functions decorated with the `#[test_script]` attribute. Each test is +/// compiled as an independent `script` program and has access to the namespace of the module in +/// which it is declared. Unit tests declared within `contract` projects may also call directly +/// into their associated contract's ABI. +/// +/// Upon successful compilation, test scripts are executed to their completion. A test is +/// considered a failure in the case that a revert (`rvrt`) instruction is encountered during +/// execution. Otherwise, it is considered a success. #[derive(Debug, Parser)] pub(crate) struct Command { - /// If specified, only run tests containing this string in their names - pub test_name: Option, - /// Options passed through to the `cargo test` invocation. - /// - /// E.g. Given the following: - /// - /// `forc test --cargo-test-opts="--color always"` - /// - /// The `--color always` option is forwarded to `cargo test` like so: - /// - /// `cargo test --color always` - #[clap(long)] - pub cargo_test_opts: Option, - /// All trailing arguments following `--` are collected within this argument. - /// - /// E.g. Given the following: - /// - /// `forc test -- foo bar baz` - /// - /// The arguments `foo`, `bar` and `baz` are forwarded on to `cargo test` like so: - /// - /// `cargo test -- foo bar baz` - #[clap(raw = true)] - pub cargo_test_args: Vec, + /// When specified, only tests containing the given string will be executed. + pub filter: Option, } -pub(crate) fn exec(command: Command) -> Result<()> { - // Ensure the project builds before running tests. - forc_build::build(Default::default())?; +pub(crate) fn exec(_command: Command) -> Result<()> { + bail!(r#" +Sway unit testing is not yet implemented. Track progress at the following link: - let mut cmd = process::Command::new("cargo"); - cmd.arg("test"); +https://github.com/FuelLabs/sway/issues/1832 - // Pass through cargo test options. - let mut user_specified_color_opt = false; - if let Some(opts) = command.cargo_test_opts { - user_specified_color_opt = opts.contains("--color"); - for opt in opts.split_whitespace() { - cmd.arg(&opt); - } - } +NOTE: Previously this command was used to support Rust integration testing, +however the provided behaviour served no benefit over runnin `cargo test` +directly. The proposal to change the behaviour to support unit testing can be +found at the following link: - // If the coloring option wasn't specified by the user, enable it ourselves. This is useful as - // `cargo test`'s coloring is disabled by default when run as a child process. - if !user_specified_color_opt { - cmd.args(&["--color", "always"]); - } - - // Pass through test name. - if let Some(ref name) = command.test_name { - cmd.arg(name); - } - - // Pass through cargo test args. - if !command.cargo_test_args.is_empty() { - cmd.arg("--"); - cmd.args(&command.cargo_test_args); - } - - let mut child = cmd - .stdout(process::Stdio::piped()) - .stderr(process::Stdio::piped()) - .spawn() - .unwrap(); - - let out = BufReader::new(child.stdout.take().unwrap()); - let err = BufReader::new(child.stderr.take().unwrap()); - - // Reading stderr on a separate thread so we keep things non-blocking - let thread = thread::spawn(move || { - err.lines().for_each(|line| error!("{}", line.unwrap())); - }); - - out.lines().for_each(|line| info!("{}", line.unwrap())); - thread.join().unwrap(); - - let child_success = match child.try_wait() { - Ok(Some(returned_status)) => returned_status.success(), - Ok(None) => child.wait().unwrap().success(), - Err(_) => false, - }; - - match child_success { - true => Ok(()), - false => bail!("child test process failed"), - } +https://github.com/FuelLabs/sway/issues/1833 + "#); } diff --git a/forc/src/ops/forc_clean.rs b/forc/src/ops/forc_clean.rs index 01b4e20d733..fabeef1c6fa 100644 --- a/forc/src/ops/forc_clean.rs +++ b/forc/src/ops/forc_clean.rs @@ -1,7 +1,7 @@ use crate::cli::CleanCommand; use anyhow::{anyhow, bail, Result}; -use forc_util::{default_output_directory, find_cargo_manifest_dir, find_manifest_dir}; -use std::{path::PathBuf, process}; +use forc_util::{default_output_directory, find_manifest_dir}; +use std::path::PathBuf; use sway_utils::MANIFEST_FILE_NAME; pub fn clean(command: CleanCommand) -> Result<()> { @@ -29,15 +29,5 @@ pub fn clean(command: CleanCommand) -> Result<()> { let out_dir = default_output_directory(&manifest_dir); let _ = std::fs::remove_dir_all(out_dir); - // Run `cargo clean`, forwarding stdout and stderr (`cargo clean` doesn't appear to output - // anything as of writing this). - if find_cargo_manifest_dir(&this_dir).is_some() { - process::Command::new("cargo") - .arg("clean") - .stderr(process::Stdio::inherit()) - .stdout(process::Stdio::inherit()) - .output()?; - } - Ok(()) } diff --git a/forc/src/ops/forc_init.rs b/forc/src/ops/forc_init.rs index 51947a2ef9c..760546f0ef5 100644 --- a/forc/src/ops/forc_init.rs +++ b/forc/src/ops/forc_init.rs @@ -91,9 +91,6 @@ pub fn init(command: InitCommand) -> Result<()> { // Make a new directory for the project fs::create_dir_all(Path::new(&project_dir).join("src"))?; - // Make directory for tests - fs::create_dir_all(Path::new(&project_dir).join("tests"))?; - // Insert default manifest file match program_type { Library => fs::write( @@ -106,12 +103,6 @@ pub fn init(command: InitCommand) -> Result<()> { )?, } - // Insert default test manifest file - fs::write( - Path::new(&project_dir).join(constants::TEST_MANIFEST_FILE_NAME), - defaults::default_tests_manifest(&project_name), - )?; - match program_type { Contract => fs::write( Path::new(&project_dir) @@ -139,17 +130,6 @@ pub fn init(command: InitCommand) -> Result<()> { )?, } - // Insert default test function - let harness_path = Path::new(&project_dir).join("tests").join("harness.rs"); - fs::write(&harness_path, defaults::default_test_program(&project_name))?; - - if command.verbose { - info!( - "\nCreated test harness at {}", - harness_path.canonicalize()?.display() - ); - } - // Ignore default `out` and `target` directories created by forc and cargo. let gitignore_path = Path::new(&project_dir).join(".gitignore"); // Append to existing gitignore if it exists otherwise create a new one. diff --git a/forc/src/ops/forc_template.rs b/forc/src/ops/forc_template.rs index 1898460bd36..2eb579fafa3 100644 --- a/forc/src/ops/forc_template.rs +++ b/forc/src/ops/forc_template.rs @@ -1,5 +1,4 @@ use crate::cli::TemplateCommand; -use crate::utils::defaults; use anyhow::{anyhow, Context, Result}; use forc_pkg::{ fetch_git, fetch_id, find_dir_within, git_commit_path, pin_git, Manifest, SourceGit, @@ -9,7 +8,7 @@ use fs_extra::dir::{copy, CopyOptions}; use std::fs::File; use std::io::{Read, Write}; use std::path::{Path, PathBuf}; -use std::{env, fs}; +use std::env; use sway_utils::constants; use tracing::info; use url::Url; @@ -73,19 +72,6 @@ pub fn init(command: TemplateCommand) -> Result<()> { edit_forc_toml(&target_dir, &command.project_name, &whoami::realname())?; if target_dir.join("test").exists() { edit_cargo_toml(&target_dir, &command.project_name, &whoami::realname())?; - } else { - // Create the tests directory, harness.rs and Cargo.toml file - fs::create_dir_all(target_dir.join("tests"))?; - - fs::write( - target_dir.join("tests").join("harness.rs"), - defaults::default_test_program(&command.project_name), - )?; - - fs::write( - target_dir.join("Cargo.toml"), - defaults::default_tests_manifest(&command.project_name), - )?; } Ok(()) } diff --git a/forc/src/utils/defaults.rs b/forc/src/utils/defaults.rs index d2cc72f0975..01a7031c7c4 100644 --- a/forc/src/utils/defaults.rs +++ b/forc/src/utils/defaults.rs @@ -15,32 +15,6 @@ name = "{project_name}" ) } -/// Creates a default Cargo manifest for the Rust-based tests. -/// It includes necessary packages to make the Rust-based -/// tests work. -pub(crate) fn default_tests_manifest(project_name: &str) -> String { - let author = get_author(); - - format!( - r#"[project] -name = "{project_name}" -version = "0.1.0" -authors = ["{author}"] -edition = "2021" -license = "Apache-2.0" - -[dependencies] -fuels = {{ version = "0.20", features = ["fuel-core-lib"] }} -tokio = {{ version = "1.12", features = ["rt", "macros"] }} - -[[test]] -harness = true -name = "integration_tests" -path = "tests/harness.rs" -"# - ) -} - pub(crate) fn default_contract() -> String { r#"contract; @@ -86,61 +60,6 @@ fn main() -> bool { .into() } -// TODO Ideally after (instance, id) it should link to the The Fuels-rs Book -// to provide further information for writing tests/working with sway -pub(crate) fn default_test_program(project_name: &str) -> String { - format!( - "{}{}{}{}{}{}{}", - r#"use fuels::{prelude::*, tx::ContractId}; - -// Load abi from json -abigen!(MyContract, "out/debug/"#, - project_name, - r#"-abi.json"); - -async fn get_contract_instance() -> (MyContract, ContractId) { - // Launch a local network and deploy the contract - let mut wallets = launch_custom_provider_and_get_wallets( - WalletsConfig::new( - Some(1), /* Single wallet */ - Some(1), /* Single coin (UTXO) */ - Some(1_000_000_000), /* Amount per coin */ - ), - None, - ) - .await; - let wallet = wallets.pop().unwrap(); - - let id = Contract::deploy( - "./out/debug/"#, - project_name, - r#".bin", - &wallet, - TxParameters::default(), - StorageConfiguration::with_storage_path(Some( - "./out/debug/"#, - project_name, - r#"-storage_slots.json".to_string(), - )), - ) - .await - .unwrap(); - - let instance = MyContractBuilder::new(id.to_string(), wallet).build(); - - (instance, id.into()) -} - -#[tokio::test] -async fn can_get_contract_id() { - let (_instance, _id) = get_contract_instance().await; - - // Now you have an instance of your contract you can use to test each function -} -"# - ) -} - pub(crate) fn default_gitignore() -> String { r#"out target @@ -161,10 +80,4 @@ fn parse_default_manifest() { ) } -#[test] -fn parse_default_tests_manifest() { - tracing::info!( - "{:#?}", - toml::from_str::(&default_tests_manifest("test_proj")).unwrap() - ) -} +pub const NODE_URL: &str = "http://127.0.0.1:4000";