From a40d23a251e339dc93205dd8ee2a1f5b52b153fb Mon Sep 17 00:00:00 2001 From: ddoktorski <45050160+ddoktorski@users.noreply.github.com> Date: Tue, 19 Nov 2024 15:28:58 +0100 Subject: [PATCH 01/23] Add scheduled workflow to test against different Scarb versions (#2662) Closes #2578 ## Introduced changes - Added a scheduled workflow to run all unit, integration and e2e tests for `sncast` and `snforge` for different Scarb versions, every Wednesday and Sunday at 0:00 UTC ## Checklist - [X] Linked relevant issue - [X] Updated relevant documentation - [X] Added relevant tests - [X] Performed self-review of the code - [X] Added changes to `CHANGELOG.md` --- .github/workflows/scheduled.yml | 125 ++++++++++++++++++++++++++++++++ scripts/get_scarb_versions.sh | 29 ++++++++ 2 files changed, 154 insertions(+) create mode 100644 .github/workflows/scheduled.yml create mode 100755 scripts/get_scarb_versions.sh diff --git a/.github/workflows/scheduled.yml b/.github/workflows/scheduled.yml new file mode 100644 index 0000000000..08d1eb1ea8 --- /dev/null +++ b/.github/workflows/scheduled.yml @@ -0,0 +1,125 @@ +name: Scheduled + +on: + pull_request: + paths: + - scripts/get_scarb_versions.sh + - .github/workflows/scheduled.yml + schedule: + - cron: '0 0 * * 3,0' + +jobs: + get-scarb-versions: + name: Get Scarb versions + outputs: + versions: ${{ steps.get_versions.outputs.versions }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: asdf-vm/actions/install@05e0d2ed97b598bfce82fd30daf324ae0c4570e6 + with: + tool_versions: | + scarb latest + + - name: Get versions + id: get_versions + run: | + scarb_versions=$(./scripts/get_scarb_versions.sh) + echo ${scarb_versions[@]} + echo "versions=[${scarb_versions[@]}]" >> "$GITHUB_OUTPUT" + + test-forge-unit-and-integration: + runs-on: ubuntu-latest + needs: get-scarb-versions + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.get-scarb-versions.outputs.versions) }} + + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab + - uses: software-mansion/setup-scarb@v1 + with: + scarb-version: ${{ matrix.version }} + - uses: software-mansion/setup-universal-sierra-compiler@v1 + + - run: cargo test --release --lib -p forge + - run: cargo test --release -p forge integration + + test-forge-e2e: + runs-on: ubuntu-latest + needs: get-scarb-versions + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.get-scarb-versions.outputs.versions) }} + + steps: + - name: Extract branch name + if: github.event_name != 'pull_request' + run: echo "BRANCH_NAME=$(echo ${GITHUB_REF#refs/heads/})" >> $GITHUB_ENV + + - name: Extract branch name on pull request + if: github.event_name == 'pull_request' + run: echo "BRANCH_NAME=$(echo $GITHUB_HEAD_REF)" >> $GITHUB_ENV + + - name: Extract repo name and owner + if: github.event_name != 'pull_request' + run: echo "REPO_NAME=$(echo ${{ github.repository }}.git)" >> $GITHUB_ENV + + - name: Extract repo name and owner on pull request + if: github.event_name == 'pull_request' + run: echo "REPO_NAME=$(echo ${{ github.event.pull_request.head.repo.full_name }}.git)" >> $GITHUB_ENV + + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab + - uses: software-mansion/setup-scarb@v1 + with: + scarb-version: ${{ matrix.version }} + - uses: software-mansion/setup-universal-sierra-compiler@v1 + - name: Install cairo-profiler + run: | + curl -L https://raw.githubusercontent.com/software-mansion/cairo-profiler/main/scripts/install.sh | sh + - uses: taiki-e/install-action@nextest + + - run: cargo test --release -p forge e2e + + test-cast: + runs-on: ubuntu-latest + needs: get-scarb-versions + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.get-scarb-versions.outputs.versions) }} + + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab + - uses: software-mansion/setup-scarb@v1 + with: + scarb-version: ${{ matrix.version }} + - uses: software-mansion/setup-universal-sierra-compiler@v1 + + - name: Install starknet-devnet-rs + run: ./scripts/install_devnet.sh + + - run: cargo test --release -p sncast + + notify_if_failed: + runs-on: ubuntu-latest + if: always() && contains(needs.*.result, 'failure') && github.event_name == 'schedule' + needs: [ test-forge-unit-and-integration, test-forge-e2e, test-cast ] + steps: + - name: Notify that the workflow has failed + uses: slackapi/slack-github-action@v1.27.0 + env: + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_SCHEDULED_TESTS_FAILURE_WEBHOOK_URL }} + with: + payload: | + { + "url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" + } diff --git a/scripts/get_scarb_versions.sh b/scripts/get_scarb_versions.sh new file mode 100755 index 0000000000..887d479236 --- /dev/null +++ b/scripts/get_scarb_versions.sh @@ -0,0 +1,29 @@ +#!/bin/bash +set -e + +# This script is used to find the following Scarb versions: +# The current major.minor version along with all its patch versions +# The latest patch versions for the two versions preceding the current one + +function get_all_patch_versions() { + # Omit version 2.8.0 as it has a bug when using the `assert_macros` package + asdf list all scarb "$1" | grep -v "rc" | grep -v "2.8.0" +} + +function get_latest_patch_version() { + get_all_patch_versions "$1" | sort -uV | tail -1 +} + +major_minor_versions=($(get_all_patch_versions | cut -d . -f 1,2 | sort -uV | tail -3)) + +declare -a scarb_versions + +if [[ ${major_minor_versions[0]} != "2.6" ]]; then + scarb_versions+=($(get_latest_patch_version "${major_minor_versions[0]}")) +fi + +scarb_versions+=($(get_latest_patch_version "${major_minor_versions[1]}")) + +scarb_versions+=($(get_all_patch_versions "${major_minor_versions[2]}")) + +printf '"%s", ' "${scarb_versions[@]}" | sed 's/, $/\n/' From 78c9d31877cb25d3a2235d7d47456c468dd5cd81 Mon Sep 17 00:00:00 2001 From: Franciszek Job <54181625+franciszekjob@users.noreply.github.com> Date: Tue, 19 Nov 2024 16:26:53 +0100 Subject: [PATCH 02/23] Automatic docs shell snippets syntax validation (#2660) Closes #2479 ## Introduced changes - Validate snforge and sncast shell snippets syntax in the docs - Fix docs snippets which are invalid/outdated ## Checklist - [x] Linked relevant issue - [x] Updated relevant documentation - [x] Added relevant tests - [x] Performed self-review of the code - [x] Added changes to `CHANGELOG.md` --- Cargo.lock | 17 +++ Cargo.toml | 2 + crates/docs/Cargo.toml | 14 +++ crates/docs/src/lib.rs | 2 + crates/docs/src/validation.rs | 115 ++++++++++++++++++ crates/forge/Cargo.toml | 1 + crates/forge/src/lib.rs | 2 +- .../tests/e2e/docs_snippets_validation.rs | 43 +++++++ crates/forge/tests/e2e/mod.rs | 1 + crates/sncast/Cargo.toml | 1 + crates/sncast/README.md | 7 +- crates/sncast/tests/docs_snippets/mod.rs | 1 + .../sncast/tests/docs_snippets/validation.rs | 70 +++++++++++ crates/sncast/tests/main.rs | 1 + docs/README.md | 4 +- docs/src/getting-started/first-steps.md | 1 + .../conditional-compilation.md | 4 +- docs/src/starknet/account.md | 4 +- 18 files changed, 280 insertions(+), 10 deletions(-) create mode 100644 crates/docs/Cargo.toml create mode 100644 crates/docs/src/lib.rs create mode 100644 crates/docs/src/validation.rs create mode 100644 crates/forge/tests/e2e/docs_snippets_validation.rs create mode 100644 crates/sncast/tests/docs_snippets/mod.rs create mode 100644 crates/sncast/tests/docs_snippets/validation.rs diff --git a/Cargo.lock b/Cargo.lock index 2701a0f44f..bb7c4f1f20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1889,6 +1889,15 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" +[[package]] +name = "docs" +version = "0.33.0" +dependencies = [ + "regex", + "shell-words", + "walkdir", +] + [[package]] name = "dyn-clone" version = "1.0.17" @@ -2157,6 +2166,7 @@ dependencies = [ "configuration", "console", "conversions", + "docs", "flatten-serde-json", "forge_runner", "fs_extra", @@ -4779,6 +4789,12 @@ dependencies = [ "url", ] +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + [[package]] name = "shellexpand" version = "3.1.0" @@ -4897,6 +4913,7 @@ dependencies = [ "conversions", "ctor", "data-transformer", + "docs", "fs_extra", "indoc", "itertools 0.12.1", diff --git a/Cargo.toml b/Cargo.toml index 9403ef2a2e..8a4aed0c14 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ members = [ "crates/configuration", "crates/universal-sierra-compiler-api", "crates/snforge-scarb-plugin", + "crates/docs", ] [workspace.package] @@ -82,6 +83,7 @@ project-root = "0.2.2" which = "5.0.0" conversions = { path = "./crates/conversions" } shared = { path = "./crates/shared" } +docs = { path = "./crates/docs" } test-case = "3.1.0" scarb-metadata = "1.13.0" flatten-serde-json = "0.1.0" diff --git a/crates/docs/Cargo.toml b/crates/docs/Cargo.toml new file mode 100644 index 0000000000..a6a11af985 --- /dev/null +++ b/crates/docs/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "docs" +version.workspace = true +edition.workspace = true +repository.workspace = true +license.workspace = true + +[dependencies] +regex = "1.11.1" +shell-words = "1.1.0" +walkdir.workspace = true + +[features] +testing = [] diff --git a/crates/docs/src/lib.rs b/crates/docs/src/lib.rs new file mode 100644 index 0000000000..1506b851ef --- /dev/null +++ b/crates/docs/src/lib.rs @@ -0,0 +1,2 @@ +#[cfg(feature = "testing")] +pub mod validation; diff --git a/crates/docs/src/validation.rs b/crates/docs/src/validation.rs new file mode 100644 index 0000000000..ea801187d9 --- /dev/null +++ b/crates/docs/src/validation.rs @@ -0,0 +1,115 @@ +use regex::Regex; +use std::{ + env, fs, io, + path::{Path, PathBuf}, +}; + +const EXTENSION: Option<&str> = Some("md"); + +pub struct Snippet { + pub command: String, + pub file_path: String, + pub line_start: usize, +} + +impl Snippet { + pub fn to_command_args(&self) -> Vec { + let cleaned_command = self + .command + .lines() + .map(str::trim_end) + .collect::>() + .join(" ") + .replace(" \\", ""); + + shell_words::split(&cleaned_command) + .expect("Failed to parse snippet string") + .into_iter() + .map(|arg| arg.trim().to_string()) + .collect() + } +} + +pub fn extract_snippets_from_file(file_path: &Path, re: &Regex) -> io::Result> { + let content = fs::read_to_string(file_path)?; + let file_path_str = file_path + .to_str() + .expect("Failed to get file path") + .to_string(); + + let snippets = re + .captures_iter(&content) + .filter_map(|caps| { + let command_match = caps.get(1)?; + let match_start = caps.get(0)?.start(); + + Some(Snippet { + command: command_match.as_str().to_string(), + file_path: file_path_str.clone(), + line_start: content[..match_start].lines().count() + 1, + }) + }) + .collect(); + + Ok(snippets) +} + +pub fn extract_snippets_from_directory(dir_path: &Path, re: &Regex) -> io::Result> { + let mut all_snippets = Vec::new(); + + let files = walkdir::WalkDir::new(dir_path) + .into_iter() + .map(|entry| entry.expect("Failed to read directory")) + .filter(|entry| entry.path().is_file()); + + for file in files { + let path = file.path(); + + if EXTENSION.map_or(true, |ext| { + path.extension().and_then(|path_ext| path_ext.to_str()) == Some(ext) + }) { + let snippets = extract_snippets_from_file(path, re)?; + all_snippets.extend(snippets); + } + } + + Ok(all_snippets) +} + +#[must_use] +pub fn get_parent_dir(levels_up: usize) -> PathBuf { + let mut dir = env::current_dir().expect("Failed to get the current directory"); + + for _ in 0..levels_up { + dir = dir + .parent() + .expect("Failed to navigate to parent directory") + .to_owned(); + } + + dir +} + +pub fn assert_valid_snippet( + condition: bool, + snippet: &Snippet, + tool_name: &str, + err_message: &str, +) { + assert!( + condition, + "Found invalid {} snippet in the docs in file: {} at line {}\n{}", + tool_name, snippet.file_path, snippet.line_start, err_message + ); +} + +pub fn print_success_message(snippets_len: usize, tool_name: &str) { + println!("Successfully validated {snippets_len} {tool_name} docs snippets"); +} + +pub fn print_skipped_snippet_message(snippet: &Snippet, tool_name: &str) { + println!( + "Skipped validation of {} snippet in the docs in file: {} at line {}", + tool_name, snippet.file_path, snippet.line_start + ); +} diff --git a/crates/forge/Cargo.toml b/crates/forge/Cargo.toml index f33a2dc258..3c8d119141 100644 --- a/crates/forge/Cargo.toml +++ b/crates/forge/Cargo.toml @@ -83,3 +83,4 @@ tempfile.workspace = true cairo-lang-starknet-classes.workspace = true walkdir.workspace = true test-case.workspace = true +docs = { workspace = true, features = ["testing"] } diff --git a/crates/forge/src/lib.rs b/crates/forge/src/lib.rs index 6753def0f8..13eb286806 100644 --- a/crates/forge/src/lib.rs +++ b/crates/forge/src/lib.rs @@ -53,7 +53,7 @@ Report bugs: https://github.com/foundry-rs/starknet-foundry/issues/new/choose\ )] #[command(about = "snforge - a testing tool for Starknet contracts", long_about = None)] #[clap(name = "snforge")] -struct Cli { +pub struct Cli { #[command(subcommand)] subcommand: ForgeSubcommand, } diff --git a/crates/forge/tests/e2e/docs_snippets_validation.rs b/crates/forge/tests/e2e/docs_snippets_validation.rs new file mode 100644 index 0000000000..d69b5adf46 --- /dev/null +++ b/crates/forge/tests/e2e/docs_snippets_validation.rs @@ -0,0 +1,43 @@ +use clap::Parser; +use docs::validation::{ + assert_valid_snippet, extract_snippets_from_directory, get_parent_dir, + print_skipped_snippet_message, print_success_message, +}; +use forge::Cli; +use regex::Regex; +#[test] +fn test_docs_snippets() { + let root_dir = get_parent_dir(2); + let docs_dir = root_dir.join("docs/src"); + + let re = Regex::new(r"(?ms)```shell\n\$ (snforge .+?)\n```").expect("Invalid regex pattern"); + + let snippets = extract_snippets_from_directory(&docs_dir, &re) + .expect("Failed to extract snforge command snippets"); + + // TODO(#2684) + let skipped_args = [ + // for some reason `try_parse_from` fails on `--version` flag + vec!["snforge", "--version"], + ]; + + for snippet in &snippets { + let args = snippet.to_command_args(); + let args: Vec<&str> = args.iter().map(String::as_str).collect(); + + if skipped_args.contains(&args) { + print_skipped_snippet_message(snippet, "snforge"); + continue; + } + + let parse_result = Cli::try_parse_from(args); + let err_message = if let Err(err) = &parse_result { + err.to_string() + } else { + String::new() + }; + assert_valid_snippet(parse_result.is_ok(), snippet, "snforge", &err_message); + } + + print_success_message(snippets.len(), "snforge"); +} diff --git a/crates/forge/tests/e2e/mod.rs b/crates/forge/tests/e2e/mod.rs index f67f9a7544..9e8d060115 100644 --- a/crates/forge/tests/e2e/mod.rs +++ b/crates/forge/tests/e2e/mod.rs @@ -7,6 +7,7 @@ mod color; mod components; mod contract_artifacts; mod coverage; +mod docs_snippets_validation; mod env; mod features; mod fork_warning; diff --git a/crates/sncast/Cargo.toml b/crates/sncast/Cargo.toml index 142234b81a..ce661ff32c 100644 --- a/crates/sncast/Cargo.toml +++ b/crates/sncast/Cargo.toml @@ -66,6 +66,7 @@ tempfile.workspace = true test-case.workspace = true fs_extra.workspace = true wiremock.workspace = true +docs = { workspace = true, features = ["testing"] } [[bin]] name = "sncast" diff --git a/crates/sncast/README.md b/crates/sncast/README.md index 67cae4aaf2..906bcc6c88 100644 --- a/crates/sncast/README.md +++ b/crates/sncast/README.md @@ -33,7 +33,6 @@ All subcommand usages are shown for two scenarios - when all necessary arguments ```shell $ sncast --account myuser \ - --url http://127.0.0.1:5050/rpc \ declare \ --contract-name SimpleBalance ``` @@ -72,8 +71,8 @@ transaction_hash: 0x7ad0d6e449e33b6581a4bb8df866c0fce3919a5ee05a30840ba521dafee2 ```shell $ sncast --account myuser \ + deploy --class-hash 0x8448a68b5ea1affc45e3fd4b8b480ea36a51dc34e337a16d2567d32d0c6f8a \ --url http://127.0.0.1:5050/rpc \ - deploy --class-hash 0x8448a68b5ea1affc45e3fd4b8b480ea36a51dc34e337a16d2567d32d0c6f8a ```
@@ -108,7 +107,7 @@ transaction_hash: 0x64a62a000240e034d1862c2bbfa154aac6a8195b4b2e570f38bf4fd47a5a ### Invoke a contract ```shell -$ sncast --url http://127.0.0.1:5050 \ +$ sncast \ --account example_user \ invoke \ --contract-address 0x4a739ab73aa3cac01f9da5d55f49fb67baee4919224454a2e3f85b16462a911 \ @@ -149,7 +148,7 @@ transaction_hash: 0x7ad0d6e449e33b6581a4bb8df866c0fce3919a5ee05a30840ba521dafee2 ### Call a contract ```shell -$ sncast --url http://127.0.0.1:5050 \ +$ sncast \ call \ --contract-address 0x4a739ab73aa3cac01f9da5d55f49fb67baee4919224454a2e3f85b16462a911 \ --function "some_function" \ diff --git a/crates/sncast/tests/docs_snippets/mod.rs b/crates/sncast/tests/docs_snippets/mod.rs new file mode 100644 index 0000000000..8695201df0 --- /dev/null +++ b/crates/sncast/tests/docs_snippets/mod.rs @@ -0,0 +1 @@ +pub mod validation; diff --git a/crates/sncast/tests/docs_snippets/validation.rs b/crates/sncast/tests/docs_snippets/validation.rs new file mode 100644 index 0000000000..2d649b86d0 --- /dev/null +++ b/crates/sncast/tests/docs_snippets/validation.rs @@ -0,0 +1,70 @@ +use docs::validation::{ + assert_valid_snippet, extract_snippets_from_directory, extract_snippets_from_file, + get_parent_dir, print_skipped_snippet_message, print_success_message, Snippet, +}; +use regex::Regex; +use tempfile::tempdir; + +use crate::helpers::runner::runner; + +#[test] +fn test_docs_snippets() { + let tempdir = tempdir().expect("Unable to create a temporary directory"); + + let root_dir_path = get_parent_dir(2); + let docs_dir_path = root_dir_path.join("docs/src"); + let sncast_readme_path = root_dir_path.join("crates/sncast/README.md"); + + let re = Regex::new(r"(?ms)```shell\n\$ sncast(.+?)\n```").expect("Invalid regex pattern"); + + let docs_snippets = extract_snippets_from_directory(&docs_dir_path, &re) + .expect("Failed to extract sncast command snippets"); + + let readme_snippets = extract_snippets_from_file(&sncast_readme_path, &re) + .expect("Failed to extract sncast command snippets"); + + let snippets = docs_snippets + .into_iter() + .chain(readme_snippets) + .collect::>(); + + // TODO(#2684) + let skipped_args = [ + // snippet "$ sncast " + vec![""], + // snippet with interactive account import example + vec![ + "account", + "import", + "--url", + "http://127.0.0.1:5050", + "--name", + "account_123", + "--address", + "0x1", + "--type", + "oz", + ], + ]; + + for snippet in &snippets { + let args = snippet.to_command_args(); + let args: Vec<&str> = args.iter().map(String::as_str).collect(); + + if skipped_args.contains(&args) { + print_skipped_snippet_message(snippet, "sncast"); + continue; + } + + // TODO(#2678) + + let snapbox = runner(&args).current_dir(tempdir.path()); + let output = snapbox.output().expect("Failed to execute the command"); + let exit_code = output.status.code().unwrap_or_default(); + let stderr = String::from_utf8_lossy(&output.stderr); + + assert_valid_snippet(exit_code != 2, snippet, "sncast", &stderr); + } + + print_success_message(snippets.len(), "sncast"); +} diff --git a/crates/sncast/tests/main.rs b/crates/sncast/tests/main.rs index 5465fce9b8..255cc634cd 100644 --- a/crates/sncast/tests/main.rs +++ b/crates/sncast/tests/main.rs @@ -1,3 +1,4 @@ +mod docs_snippets; mod e2e; pub mod helpers; mod integration; diff --git a/docs/README.md b/docs/README.md index 39b0255d33..f70abc808f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -11,11 +11,11 @@ $ cargo install mdbook ## Building ```shell -mdbook build +$ mdbook build ``` ## Open preview and reload on every change ```shell -mdbook serve +$ mdbook serve ``` \ No newline at end of file diff --git a/docs/src/getting-started/first-steps.md b/docs/src/getting-started/first-steps.md index c59dcbfd29..08833008cf 100644 --- a/docs/src/getting-started/first-steps.md +++ b/docs/src/getting-started/first-steps.md @@ -23,6 +23,7 @@ $ tree . -L 1 . ├── Scarb.lock ├── Scarb.toml +├── snfoundry.toml ├── src └── tests diff --git a/docs/src/snforge-advanced-features/conditional-compilation.md b/docs/src/snforge-advanced-features/conditional-compilation.md index 28cdc2ba7f..1120cf4f79 100644 --- a/docs/src/snforge-advanced-features/conditional-compilation.md +++ b/docs/src/snforge-advanced-features/conditional-compilation.md @@ -39,8 +39,8 @@ enable_for_tests = [] Then, to use the contract in tests `snforge test` must be provided with a flag defined above: -``` -snforge test --features enable_for_tests +```shell +$ snforge test --features enable_for_tests ``` Also, we can specify which features are going to be enabled by default: diff --git a/docs/src/starknet/account.md b/docs/src/starknet/account.md index 79fbf962a9..517e30e62a 100644 --- a/docs/src/starknet/account.md +++ b/docs/src/starknet/account.md @@ -61,11 +61,12 @@ You can do it both by sending tokens from another starknet account or by bridgin ```shell $ sncast \ - account deploy \ + account deploy \ --url http://127.0.0.1:5050 \ --name some-name \ --fee-token strk \ --max-fee 9999999999999 +```
Output: @@ -150,6 +151,7 @@ $ sncast \ --name some-name \ --url http://127.0.0.1:5050 \ --class-hash 0x00e2eb8f5672af4e6a4e8a8f1b44989685e668489b0a25437733756c5a34a1d6 + --type oz ``` #### [`account create`](../appendix/sncast/account/create.md) With Salt Argument From 5bbfa804a1d7aac97a9df9d35b1fde3f2c08cc6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Artur=20Micha=C5=82ek?= <52135326+cptartur@users.noreply.github.com> Date: Tue, 19 Nov 2024 16:50:03 +0100 Subject: [PATCH 03/23] Update test and contract collection docs (#2656) Closes #2627 Closes #2465 ## Introduced changes - Split contract collection docs into two parts: one showing new mechanism and one showing old - Moved current (old) contract collection docs to subpage - Added new contract collection docs subpage - Added information that Scarb handles test collection and linked relevant sections in Scarb docs - Reworked test collection docs ## Checklist - [x] Linked relevant issue - [x] Updated relevant documentation - [x] Added relevant tests - [x] Performed self-review of the code - [x] Added changes to `CHANGELOG.md` --------- Co-authored-by: Franciszek Job <54181625+franciszekjob@users.noreply.github.com> Co-authored-by: ddoktorski <45050160+ddoktorski@users.noreply.github.com> --- docs/src/SUMMARY.md | 2 + .../contract-collection/new-mechanism.md | 39 ++++ .../contract-collection/old-mechanism.md | 32 ++++ docs/src/testing/contracts-collection.md | 41 ++--- docs/src/testing/test-collection.md | 168 ++++++++++-------- 5 files changed, 186 insertions(+), 96 deletions(-) create mode 100644 docs/src/testing/contract-collection/new-mechanism.md create mode 100644 docs/src/testing/contract-collection/old-mechanism.md diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 9ed93f8e27..375a3c70b5 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -24,6 +24,8 @@ * [Testing Workspaces](testing/testing-workspaces.md) * [Test Collection](testing/test-collection.md) * [Contract Collection](testing/contracts-collection.md) + * [Optimized Mechanism](testing/contract-collection/new-mechanism.md) + * [Old Mechanism](testing/contract-collection/old-mechanism.md) * [Gas and VM Resources Estimation](testing/gas-and-resource-estimation.md) * [Coverage](testing/coverage.md) diff --git a/docs/src/testing/contract-collection/new-mechanism.md b/docs/src/testing/contract-collection/new-mechanism.md new file mode 100644 index 0000000000..350ddeae58 --- /dev/null +++ b/docs/src/testing/contract-collection/new-mechanism.md @@ -0,0 +1,39 @@ +# How Contracts Are Collected + +For the [`declare`](../../appendix/snforge-library/declare.md) to work, snforge must collect and call build on +contracts in the package. By default, if using Scarb version >= 2.8.3, snforge will combine test +collection and contract collection steps. + +When running `snforge test`, snforge will, under the hood, call the `scarb build --test` command. This command builds +all the test and contracts along them. Snforge collects these contracts and makes them available for declaring in tests. + +Contracts are collected from both `src` and `tests` directory, including modules marked with `#[cfg(test)]`. +Internally, snforge collects contracts from all `[[test]]` targets compiled by Scarb. +You can read more about that in [test collection](../test-collection.md) documentation. + +## Collection Order + +When multiple `[[test]]` targets are present, snforge will first try to collect contracts from `integration` `test-type` +target. If `integration` is not present, snforge will first collect contracts from the first encountered `[[test]]` +target. + +After collecting from initial `[[test]]` target, snforge will collect contracts from any other encountered targets. +No specific order of collection is guaranteed. + +> 📝 **Note** +> +> If multiple contracts with the same name are present, snforge will use the first encountered implementation and will +> not collect others. + +## Using External Contracts in Tests + +To use contract from dependencies in tests, `Scarb.toml` must be updated to include these contracts under +`[[target.starknet-contract]]`. + +```toml +[[target.starknet-contract]] +build-external-contracts = ["path::to::Contract1", "other::path::to::Contract2"] +``` + +For more information about `build-external-contracts`, +see [Scarb documentation](https://docs.swmansion.com/scarb/docs/extensions/starknet/contract-target.html#compiling-external-contracts). diff --git a/docs/src/testing/contract-collection/old-mechanism.md b/docs/src/testing/contract-collection/old-mechanism.md new file mode 100644 index 0000000000..af5725bcde --- /dev/null +++ b/docs/src/testing/contract-collection/old-mechanism.md @@ -0,0 +1,32 @@ +# How Contracts Are Collected + +When you call `snforge test`, one of the things that `snforge` does is that it calls Scarb, particularly `scarb build`. +It makes Scarb build all contracts from your package and save them to the `target/{current_profile}` directory +(read more on [Scarb website](https://docs.swmansion.com/scarb/docs/extensions/starknet/contract-target.html)). + +Then, `snforge` loads compiled contracts from the package your tests are located, allowing you to declare the contracts +in +tests. + +Only contracts from `src/` directory are loaded. Contracts from `/tests` and modules marked with `#[cfg(test)]` are not +build or collected. To create contracts to be specifically used in tests +see [conditional compilation](../../snforge-advanced-features/conditional-compilation.md). + +> ⚠️ **Warning** +> +> Make sure to define `[[target.starknet-contract]]` section in your `Scarb.toml`, otherwise Scarb won't build your +> contracts. + +## Using External Contracts In Tests + +If you wish to use contracts from your dependencies inside your tests (e.g. an ERC20 token, an account contract), +you must first make Scarb build them. You can do that by using `build-external-contracts` key in `Scarb.toml`, +e.g.: + +```toml +[[target.starknet-contract]] +build-external-contracts = ["openzeppelin::account::account::Account"] +``` + +For more information about `build-external-contracts`, +see [Scarb documentation](https://docs.swmansion.com/scarb/docs/extensions/starknet/contract-target.html#compiling-external-contracts). diff --git a/docs/src/testing/contracts-collection.md b/docs/src/testing/contracts-collection.md index 30477bea85..811af548c6 100644 --- a/docs/src/testing/contracts-collection.md +++ b/docs/src/testing/contracts-collection.md @@ -1,24 +1,25 @@ -## How Contracts Are Collected +# How Contracts Are Collected -When you call `snforge test`, one of the things that `snforge` does is that it calls Scarb, particularly `scarb build`. -It makes Scarb build all contracts from your package and save them to the `target/{current_profile}` directory -(read more on [Scarb website](https://docs.swmansion.com/scarb/docs/extensions/starknet/contract-target.html)). +`snforge` supports two mechanisms for collecting contracts used in tests. +The default one depends on Scarb version used and can be controlled with `--no-optimization` flag. -Then, `snforge` loads compiled contracts from the package your tests are in, allowing you to declare the contracts in tests. +- If using Scarb version >= 2.8.3, [optimized collection mechanism](contract-collection/new-mechanism.md) is used by + default. +- If using Scarb version < 2.8.3 or running `snforge test` with `--no-optimization` flag, + the [old collection mechanism](contract-collection/old-mechanism.md) is used. -> ⚠️ **Warning** +> 📝 **Note** > -> Make sure to define `[[target.starknet-contract]]` section in your `Scarb.toml`, otherwise Scarb won't build your contracts. - - -## Using External Contracts In Tests - -If you wish to use contracts from your dependencies inside your tests (e.g. an ERC20 token, an account contract), -you must first make Scarb build them. You can do that by using `build-external-contracts` property in `Scarb.toml`, e.g.: - -```toml -[[target.starknet-contract]] -build-external-contracts = ["openzeppelin::account::account::Account"] -``` - -For more information about `build-external-contracts`, see [Scarb documentation](https://docs.swmansion.com/scarb/docs/extensions/starknet/contract-target.html#compiling-external-contracts). +> Enabling new mechanism **requires** Scarb version >= 2.8.3. + +## Differences Between Collection Mechanisms + +| Feature | Old Mechanism | Optimised Mechanism | +|---------------------------------------------------------|---------------|---------------------| +| Using contracts from `/src` | ✅ | ✅ | +| Using contracts from `/tests` | ❌ | ✅ | +| Using contracts from modules marked with `#[cfg(test)]` | ❌ | ✅ | +| Using contracts from dependencies | ✅ | ✅ | +| Contracts more closely resemble ones from real network | ✅ | ❌ | +| Less compilation steps required (faster compilation) | ❌ | ✅ | +| Additional compilation step required (`scarb build`) | ✅ | ❌ | diff --git a/docs/src/testing/test-collection.md b/docs/src/testing/test-collection.md index c8535dfa17..f084eb1069 100644 --- a/docs/src/testing/test-collection.md +++ b/docs/src/testing/test-collection.md @@ -1,111 +1,127 @@ -## Test Collection +# How Tests Are Collected -`snforge` considers all functions in your project marked with `#[test]` attribute as tests. -By default, test functions run without any arguments. -However, adding any arguments to function signature will enable [fuzz testing](../snforge-advanced-features/fuzz-testing.md) for this -test case. +Snforge executes tests, but it does not compile them directly. +Instead, it compiles tests by internally running `scarb build --test` command. -`snforge` will collect tests only from these places: +The `snforge_scarb_plugin` dependency, which is included with `snforge_std` dependency makes all functions +marked with `#[test]` executable and indicates to Scarb they should be compiled. +Without the plugin, no snforge tests can be compiled, that's why `snforge_std` dependency is always required in all +snforge projects. -- any files reachable from the package root (declared as `mod` in `lib.cairo` or its children) - -these have to be in a module annotated with `#[cfg(test)]` -- files inside the [`tests`](#the-tests-directory) directory +Thanks to that, Scarb collects all functions marked with `#[test]` +from [valid locations](https://docs.swmansion.com/scarb/docs/extensions/testing.html#tests-organization) and compiles +them into tests that are executed by snforge. -## The `tests` Directory +## `[[test]]` Target -`snforge` collects tests from `tests` directory. -Depending on the presence of `tests/lib.cairo` file, the behavior of the test collector will be different. +Under the hood, Scarb utilizes the `[[test]]` target mechanism to compile the tests. More information about the +`[[test]]` target is available in +the [Scarb documentation](https://docs.swmansion.com/scarb/docs/reference/targets.html#test-targets). -### With `tests/lib.cairo` +By default, `[[test]]]` target is implicitly configured and user does not have to define it. +See [Scarb documentation](https://docs.swmansion.com/scarb/docs/reference/targets.html#auto-detection-of-test-targets) +for more details about the mechanism. -If there is a `lib.cairo` file in `tests` folder, -then it is treated as an entrypoint to the `tests` package from which tests are collected. +## Tests Organization -For example, for a package structured this way: +Test can be placed in both `src` and `test` directories. When adding tests to files in `src` you must wrap them in tests +module. -```shell -$ tree . -``` +You can read more about tests organization +in [Scarb documentation](https://docs.swmansion.com/scarb/docs/extensions/testing.html#tests-organization). -
-Output: +### Unit Tests -```shell -. -├── Scarb.toml -├── tests/ -│ ├── lib.cairo -│ ├── common/ -│ │ └── utils.cairo -│ ├── common.cairo -│ ├── test_contract.cairo -│ └── not_included.cairo -└── src/ - └── lib.cairo -``` -
-
- -with `tests/lib.cairo` content: +Test placed in `src` directory are often called unit tests. +For these test to function in snforge, they must be wrapped in a module marked with `#[cfg(test)]` attribute. ```rust -mod common; -mod test_contract; +// src/example.rs +// ... + +// This test is not in module marked with `#[cfg(test)]` so it won't work +#[test] +fn my_invalid_test() { + // ... +} + +#[cfg(test)] +mod tests { + // This test is in module marked with `#[cfg(test)]` so it will work + #[test] + fn my_test() { + // .. + } +} ``` -and `tests/common.cairo` content: +### Integration Tests + +Integration tests are placed in `tests` directory. +This directory is a special directory in Scarb. +Tests do not have to be wrapped in `#[cfg(test)]` and each file is treated as a separate module. ```rust -mod utils; +// tests/example.rs +// ... + +// This test is in `tests` directory +// so it works without being in module with `#[cfg(test)]` +#[test] +fn my_test_1() { + // .. +} ``` -tests from `tests/lib.cairo`, `tests/test_contract.cairo`, `tests/common.cairo` -and `tests/common/utils.cairo` will be collected. - -### Without `tests/lib.cairo` +#### Modules and `lib.cairo` -When there is no `lib.cairo` present in `tests` folder, -all test files **directly** in `tests` directory (i.e., not in its subdirectories) -are treated as modules and added to a single virtual `lib.cairo`. -Then this virtual `lib.cairo` is treated as an entrypoint to the `tests` package from which tests are collected. - -For example, for a package structured this way: +As written above, each file in `tests` directory is treated as a separate module ```shell -$ tree . +$ tree ``` -
+
Output: ```shell -. -├── Scarb.toml -├── tests/ -│ ├── common/ -│ │ └── utils.cairo -│ ├── common.cairo -│ ├── test_contract.cairo -│ └── not_included/ -│ └── ignored.cairo -└── src/ - └── lib.cairo +tests/ +├── module1.cairo <-- is collected +├── module2.cairo <-- is collected +└── module3.cairo <-- is collected ``` +
-
-and `tests/common.cairo` content: +Scarb will collect each file and compile it as a +separate [test target](https://docs.swmansion.com/scarb/docs/reference/targets.html#test-targets). +Each of these targets will be run separately by `snforge`. -```rust -mod utils; +However, it is also possible to define `lib.cairo` file in `tests`. +This stops files in `tests` from being treated as separate modules. +Instead, Scarb will only create a single test target for that `lib.cairo` file. +Only tests that are reachable from this file will be collected and compiled. + +```shell +$ tree ``` -tests from `tests/test_contract.cairo`, `tests/common.cairo` and `tests/common/utils.cairo` will be collected. +
+Output: -### Sharing Code Between Tests +```shell +tests/ +├── lib.cairo +├── module1.cairo <-- is collected +├── module2.cairo <-- is collected +└── module3.cairo <-- is not collected +``` -Sometimes you may want a share some code between tests to organize them. -The package structure of tests makes it easy! -In both of the above examples, you can -make the functions from `tests/common/utils.cairo` available in `tests/test_contract.cairo` -by using a relative import: `use super::common::utils;`. +
+ +```rust +// tests/lib.cairo + +mod module1; +mod module2; +``` From 2027d71012817f138df7de0f9df48e33a80548fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Artur=20Micha=C5=82ek?= <52135326+cptartur@users.noreply.github.com> Date: Fri, 22 Nov 2024 14:24:45 +0100 Subject: [PATCH 04/23] Generate sitemap for docs (#2693) Closes # ## Introduced changes - Added generation of sitemap for documentation Tested on a fork https://github.com/cptartur/starknet-foundry/commit/2a2bc47dd8c1022138584f85a3cadb4853a08b54 and it seems to deploy correctly there https://cptartur.github.io/starknet-foundry/sitemap.xml ## Checklist - [x] Linked relevant issue - [x] Updated relevant documentation - [x] Added relevant tests - [x] Performed self-review of the code - [x] Added changes to `CHANGELOG.md` --- .github/workflows/docs.yml | 8 ++++++++ docs/src/SUMMARY.md | 2 +- docs/src/starknet/{index.md => sncast-overview.md} | 0 3 files changed, 9 insertions(+), 1 deletion(-) rename docs/src/starknet/{index.md => sncast-overview.md} (100%) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 887b79de6a..9deb4d0e58 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -37,6 +37,10 @@ jobs: toolchain: stable - uses: Swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + - name: Install sitemap CLI + run: | + npm i -g static-sitemap-cli - name: Install mdBook run: | cargo install --version ${MDBOOK_VERSION} mdbook @@ -78,6 +82,10 @@ jobs: curl -o highlight.js https://raw.githubusercontent.com/software-mansion/scarb/main/extensions/scarb-doc/theme/highlight.js cp highlight.js ./docs/book/html/sncast_std/highlight.js cp highlight.js ./docs/book/html/snforge_std/highlight.js + - name: Generate sitemap + run: | + sscli --base https://foundry-rs.github.io/starknet-foundry + working-directory: ./docs/book/html - name: Upload artifact uses: actions/upload-pages-artifact@v3 with: diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 375a3c70b5..8bdcece5ad 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -41,7 +41,7 @@ # `sncast` Overview -* [Outline](starknet/index.md) +* [Outline](starknet/sncast-overview.md) * [Creating And Deploying Accounts](starknet/account.md) * [Importing Accounts](starknet/account-import.md) * [Declaring New Contracts](starknet/declare.md) diff --git a/docs/src/starknet/index.md b/docs/src/starknet/sncast-overview.md similarity index 100% rename from docs/src/starknet/index.md rename to docs/src/starknet/sncast-overview.md From a6b9785dd519b60a9ad53b0ac46bd98a516c4c52 Mon Sep 17 00:00:00 2001 From: Wojciech Szymczyk Date: Fri, 22 Nov 2024 18:11:05 +0100 Subject: [PATCH 05/23] Add upload to registry workflow for foundry_std (#2461) Closes https://github.com/foundry-rs/starknet-foundry/issues/2344 Closes #2463 This PR is a part of the stack: -- Add missing info recommended for package uploads (https://github.com/foundry-rs/starknet-foundry/pull/2460) --> Add github action workflow for automatic registry uploads during release (This PR) ## Introduced changes - Updates github workflow to also upload std libraries to scarbs registry during release - Sets snforge_scarb_plugin to specific version downloadable from the registry, as required by scarb ## Checklist - [X] Linked relevant issue - [X] Updated relevant documentation - [X] Added relevant tests - [X] Performed self-review of the code - [X] Added changes to `CHANGELOG.md` --------- Co-authored-by: kkawula <57270771+kkawula@users.noreply.github.com> --- .github/workflows/publish_plugin.yml | 37 ++++++++++++++++++++++++++++ .github/workflows/release.yml | 32 ++++++++++++++++++++++++ scripts/set_plugin_version.sh | 10 ++++++++ 3 files changed, 79 insertions(+) create mode 100644 .github/workflows/publish_plugin.yml create mode 100755 scripts/set_plugin_version.sh diff --git a/.github/workflows/publish_plugin.yml b/.github/workflows/publish_plugin.yml new file mode 100644 index 0000000000..bc8ac8c364 --- /dev/null +++ b/.github/workflows/publish_plugin.yml @@ -0,0 +1,37 @@ +name: Publish snforge_scarb_plugin + +on: + workflow_call: + workflow_dispatch: + +jobs: + upload-to-registry: + name: Upload plugin to the registry + runs-on: ubuntu-latest + env: + SCARB_REGISTRY_AUTH_TOKEN: ${{ secrets.SCARB_REGISTRY_AUTH_TOKEN }} + steps: + - uses: actions/checkout@v4 + + - name: Check version + id: check-version + if: ${{ github.event_name != 'workflow_dispatch' }} + run: | + set -exo pipefail + + snforge_scarb_plugin_version=$(grep version crates/snforge-scarb-plugin/Scarb.toml | cut -d '"' -f 2) + snforge_scarb_plugin_uploaded=$(curl -s https://scarbs.xyz/api/v1/index/sn/fo/snforge_scarb_plugin.json | jq --arg version "$snforge_scarb_plugin_version" '[.[] | select(.v == $version)] | length > 0') + echo "snforge_scarb_plugin_uploaded=$snforge_scarb_plugin_uploaded" >> $GITHUB_OUTPUT + + - uses: dtolnay/rust-toolchain@7b1c307e0dcbda6122208f10795a713336a9b35a + with: + toolchain: stable + + - uses: software-mansion/setup-scarb@v1 + with: + scarb-version: "2.8.5" + + - name: Publish snforge_scarb_plugin + if: ${{ steps.check-version.outputs.snforge_scarb_plugin_uploaded == 'false' || github.event_name == 'workflow_dispatch' }} + working-directory: crates/snforge-scarb-plugin + run: scarb publish diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6ee84895f9..1ccf3a013d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -249,3 +249,35 @@ jobs: env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAG: ${{ steps.create-release.outputs.computed-prefix }}${{ steps.create-release.outputs.version }} + + publish-snforge-scarb-plugin: + name: Publish snforge_scarb_plugin + uses: ./.github/workflows/publish_plugin.yml + secrets: inherit + + publish-to-registry: + name: Publish packages to the registry + runs-on: ubuntu-latest + needs: [ create-release, publish-snforge-scarb-plugin ] + env: + SCARB_REGISTRY_AUTH_TOKEN: ${{ secrets.SCARB_REGISTRY_AUTH_TOKEN }} + steps: + - uses: actions/checkout@v4 + + - uses: dtolnay/rust-toolchain@7b1c307e0dcbda6122208f10795a713336a9b35a + with: + toolchain: stable + + - uses: software-mansion/setup-scarb@v1 + with: + scarb-version: "2.8.5" + + - name: Publish sncast_std + working-directory: sncast_std + run: scarb publish --allow-dirty + + - name: Publish snforge_std + working-directory: snforge_std + run: | + ../scripts/set_plugin_version.sh + scarb publish --allow-dirty diff --git a/scripts/set_plugin_version.sh b/scripts/set_plugin_version.sh new file mode 100755 index 0000000000..2e397f57f5 --- /dev/null +++ b/scripts/set_plugin_version.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +PLUGIN_FILE_PATH="../crates/snforge-scarb-plugin/Scarb.toml" +SNFORGE_STD_PATH="../snforge_std/Scarb.toml" + +VERSION=$(grep version "$PLUGIN_FILE_PATH" | cut -d '"' -f 2) + +sed -i.bak "/snforge_scarb_plugin/ s/\(snforge_scarb_plugin = \).*/\1\"^${VERSION}\"/" $SNFORGE_STD_PATH + +rm ${SNFORGE_STD_PATH}.bak 2> /dev/null From ed614495ec404f9003e4325009cdd9ca08d13157 Mon Sep 17 00:00:00 2001 From: kkawula <57270771+kkawula@users.noreply.github.com> Date: Mon, 25 Nov 2024 12:46:55 +0100 Subject: [PATCH 06/23] Add data transformer examples to docs (#2682) Closes #2557 ## Introduced changes - ## Checklist - [x] Linked relevant issue - [x] Updated relevant documentation - [x] Added relevant tests - [x] Performed self-review of the code - [x] Added changes to `CHANGELOG.md` --- crates/sncast/README.md | 10 ++++---- docs/src/projects/configuration.md | 4 ++-- docs/src/starknet/call.md | 19 ++++++++-------- docs/src/starknet/invoke.md | 15 +++++++----- docs/src/starknet/sncast-overview.md | 34 +++++++++++++++++----------- 5 files changed, 47 insertions(+), 35 deletions(-) diff --git a/crates/sncast/README.md b/crates/sncast/README.md index 906bcc6c88..d7dda0a8cc 100644 --- a/crates/sncast/README.md +++ b/crates/sncast/README.md @@ -112,7 +112,7 @@ $ sncast \ invoke \ --contract-address 0x4a739ab73aa3cac01f9da5d55f49fb67baee4919224454a2e3f85b16462a911 \ --function "some_function" \ - --calldata 1 2 3 + --arguments '1, 2, 3' ```
@@ -132,7 +132,7 @@ With arguments taken from `snfoundry.toml` file (default profile name): $ sncast invoke \ --contract-address 0x4a739ab73aa3cac01f9da5d55f49fb67baee4919224454a2e3f85b16462a911 \ --function "some_function" \ - --calldata 1 2 3 + --arguments '1, 2, 3' ```
@@ -152,7 +152,7 @@ $ sncast \ call \ --contract-address 0x4a739ab73aa3cac01f9da5d55f49fb67baee4919224454a2e3f85b16462a911 \ --function "some_function" \ - --calldata 1 2 3 + --arguments '1, 2, 3' ```
@@ -171,8 +171,8 @@ With arguments taken from `snfoundry.toml` file (default profile name): ```shell $ sncast call \ --contract-address 0x4a739ab73aa3cac01f9da5d55f49fb67baee4919224454a2e3f85b16462a911 \ - --function some_function \ - --calldata 1 2 3 + --function "some_function" \ + --arguments '1, 2, 3' ```
diff --git a/docs/src/projects/configuration.md b/docs/src/projects/configuration.md index 45638a5e62..8794cc1cd5 100644 --- a/docs/src/projects/configuration.md +++ b/docs/src/projects/configuration.md @@ -54,7 +54,7 @@ $ sncast --profile myprofile \ call \ --contract-address 0x38b7b9507ccf73d79cb42c2cc4e58cf3af1248f342112879bfdf5aa4f606cc9 \ --function get \ - --calldata 0x0 \ + --arguments '0' \ --block-id latest ``` @@ -91,7 +91,7 @@ With this, there's no need to include the `--profile` argument when using `sncas $ sncast call \ --contract-address 0x38b7b9507ccf73d79cb42c2cc4e58cf3af1248f342112879bfdf5aa4f606cc9 \ --function get \ - --calldata 0x0 \ + --arguments '0' \ --block-id latest ``` diff --git a/docs/src/starknet/call.md b/docs/src/starknet/call.md index 17d1cb3c82..541c297f5e 100644 --- a/docs/src/starknet/call.md +++ b/docs/src/starknet/call.md @@ -20,9 +20,9 @@ For a detailed CLI description, see the [call command reference](../appendix/snc $ sncast \ call \ --url http://127.0.0.1:5050 \ - --contract-address 0x4a739ab73aa3cac01f9da5d55f49fb67baee4919224454a2e3f85b16462a911 \ - --function "some_function" \ - --calldata 1 2 3 + --contract-address 0x522dc7cbe288037382a02569af5a4169531053d284193623948eac8dd051716 \ + --function "balance_of" \ + --arguments '0x0554d15a839f0241ba465bb176d231730c01cf89cdcb95fe896c51d4a6f4bb8f' ```
@@ -30,7 +30,7 @@ $ sncast \ ```shell command: call -response: [0x1, 0x23, 0x4] +response: [0x1, 0x0] ```

@@ -44,10 +44,11 @@ You can call a contract at the specific block by passing `--block-id` argument. ```shell $ sncast call \ - --contract-address 0x4a739ab73aa3cac01f9da5d55f49fb67baee4919224454a2e3f85b16462a911 \ - --function "some_function" \ - --calldata 1 2 3 \ - --block-id 1234 + --url http://127.0.0.1:5050 \ + --contract-address 0x522dc7cbe288037382a02569af5a4169531053d284193623948eac8dd051716 \ + --function "balance_of" \ + --arguments '0x0554d15a839f0241ba465bb176d231730c01cf89cdcb95fe896c51d4a6f4bb8f' \ + --block-id 77864 ```
@@ -55,6 +56,6 @@ $ sncast call \ ```shell command: call -response: [0x1, 0x23] +response: [0x0, 0x0] ```
diff --git a/docs/src/starknet/invoke.md b/docs/src/starknet/invoke.md index d7a642018d..370e4ef1e3 100644 --- a/docs/src/starknet/invoke.md +++ b/docs/src/starknet/invoke.md @@ -21,10 +21,13 @@ $ sncast \ --account example_user \ invoke \ --url http://127.0.0.1:5050 \ - --fee-token strk \ - --contract-address 0x4a739ab73aa3cac01f9da5d55f49fb67baee4919224454a2e3f85b16462a911 \ - --function "some_function" \ - --calldata 1 2 0x1e + --contract-address 0x522dc7cbe288037382a02569af5a4169531053d284193623948eac8dd051716 \ + --function "add" \ + --fee-token eth \ + --arguments 'pokemons::model::PokemonData {'\ +'name: "Magmar",'\ +'element: pokemons::model::Element::Fire'\ +'}' ```
@@ -32,10 +35,10 @@ $ sncast \ ```shell command: invoke -transaction_hash: 0x7ad0d6e449e33b6581a4bb8df866c0fce3919a5ee05a30840ba521dafee217f +transaction_hash: 0x504f830428d0fcf462b4b814e2f67e12dfbcf3dc7847c1e36ba39d3eb7ac313 To see invocation details, visit: -transaction: https://starkscan.co/tx/0x7ad0d6e449... +transaction: https://sepolia.starkscan.co/tx/0x504f830428d0fcf462b4b814e2f67e12dfbcf3dc7847c1e36ba39d3eb7ac313 ```

diff --git a/docs/src/starknet/sncast-overview.md b/docs/src/starknet/sncast-overview.md index 32f98b060a..c0b4231da1 100644 --- a/docs/src/starknet/sncast-overview.md +++ b/docs/src/starknet/sncast-overview.md @@ -28,12 +28,11 @@ You can, however, overwrite their values by supplying them as flags directly to Let's use `sncast` to call a contract's function: ```shell -$ sncast --account myuser \ - call \ +$ sncast call \ --url http://127.0.0.1:5050 \ - --contract-address 0x38b7b9507ccf73d79cb42c2cc4e58cf3af1248f342112879bfdf5aa4f606cc9 \ - --function get \ - --calldata 0x0 \ + --contract-address 0x522dc7cbe288037382a02569af5a4169531053d284193623948eac8dd051716 \ + --function "pokemon" \ + --arguments '"Charizard"' \ --block-id latest ``` @@ -42,7 +41,7 @@ $ sncast --account myuser \ ```shell command: call -response: [0x0] +response: [0x0, 0x0, 0x43686172697a617264, 0x9, 0x0, 0x0, 0x41a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf] ```

@@ -51,21 +50,30 @@ response: [0x0] > In the above example we supply `sncast` with `--account` and `--url` flags. If `snfoundry.toml` is present, and have these properties set, values provided using these flags will override values from `snfoundry.toml`. Learn more about `snfoundry.toml` configuration [here](../projects/configuration.md#sncast). -### Calldata - -Some `sncast` commands (namely `call`, `deploy` and `invoke`) allow passing *calldata* - a series of arguments to perform an action with on blockchain. +### Arguments -In the example above we called a function with an argument: `0x0`, passed using `--calldata` flag. +Some `sncast` commands (namely `call`, `deploy` and `invoke`) allow passing arguments to perform an action with on the blockchain. -Please note the notation of the argument. The default way of passing calldata is a list of hexadecimally encoded field elements - the *serialized* calldata. -To obtain the serialized form of the wished data, one must write a Cairo program calling `Serde::serialize` on subsequent arguments and displaying the results. +Under the hood cast always send request with serialized form of arguments, but it can be passed in +human-readable form thanks to the [calldata transformation](./calldata-transformation.md) feature present in Cast. -It is also possible to pass calldata in more friendly, human readable form thanks to the [calldata transformation](./calldata-transformation.md) feature present in Cast. +In the example above we called a function with a deserialized argument: `'"Charizard"'`, passed using `--arguments` flag. > ⚠️ **Warning** > Cast will not verify the serialized calldata. Any errors caused by passing improper calldata in a serialized form will originate from the network. > Basic static analysis is possible only when passing expressions - see [calldata transformation](./calldata-transformation.md). + +### Using Serialized Calldata + +The same result can be achieved by passing serialized calldata, which is a list of hexadecimal-encoded field elements. + +For example, this is equivalent to using the --calldata option with the following value: 0x0 0x43686172697a617264 0x9. + +To obtain the serialized form of the wished data, you can write a Cairo program that calls `Serde::serialize` on subsequent arguments and displays the results. + +Read more about it in the [Cairo documentation](https://book.cairo-lang.org/appendix-03-derivable-traits.html?highlight=seri#serializing-with-serde). + ### How to Use `--wait` Flag Let's invoke a transaction and wait for it to be `ACCEPTED_ON_L2`. From 28e4d8b8e06a778e6b6a8602d148372292d51076 Mon Sep 17 00:00:00 2001 From: kkawula <57270771+kkawula@users.noreply.github.com> Date: Mon, 25 Nov 2024 16:45:55 +0100 Subject: [PATCH 07/23] Update docs styling (#2704) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes # ## Introduced changes - Imo it wasn't readable ## Checklist - [x] Linked relevant issue - [x] Updated relevant documentation - [x] Added relevant tests - [x] Performed self-review of the code - [x] Added changes to `CHANGELOG.md` --------- Co-authored-by: Artur Michałek <52135326+cptartur@users.noreply.github.com> --- docs/src/testing/testing.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/testing/testing.md b/docs/src/testing/testing.md index bdff23bcc6..80e1c8a4a8 100644 --- a/docs/src/testing/testing.md +++ b/docs/src/testing/testing.md @@ -141,11 +141,11 @@ To run all tests regardless of the `#[ignore]` attribute use `snforge test --inc ## Writing Assertions and `assert_macros` Package > ⚠️ **Recommended only for development** ️⚠️ > ->***Assert macros package provides a set of macros that can be used to write assertions such as `assert_eq!`. +> Assert macros package provides a set of macros that can be used to write assertions such as `assert_eq!`. In order to use it, your project must have the `assert_macros` dependency added to the `Scarb.toml` file. These macros are very expensive to run on Starknet, as they result a huge amount of steps and are not recommended for production use. They are only meant to be used in tests. -For snforge `v0.31.0` and later, this dependency is added automatically when creating a project using `snforge init`. But for earlier versions, you need to add it manually.*** +For snforge `v0.31.0` and later, this dependency is added automatically when creating a project using `snforge init`. But for earlier versions, you need to add it manually. ```toml [dev-dependencies] From 6578e288e264d67a4b513c346658118444db5af0 Mon Sep 17 00:00:00 2001 From: ddoktorski <45050160+ddoktorski@users.noreply.github.com> Date: Mon, 25 Nov 2024 17:33:53 +0100 Subject: [PATCH 08/23] Make rpc url optional for `show-config` command (#2701) Closes #2644 ## Introduced changes - Do not require rpc url for `show-config` command to work - Added missing `show_explorer_links` field to the `ShowConfigResponse` ## Checklist - [X] Linked relevant issue - [X] Updated relevant documentation - [X] Added relevant tests - [X] Performed self-review of the code - [X] Added changes to `CHANGELOG.md` --- CHANGELOG.md | 1 + crates/sncast/src/main.rs | 2 +- crates/sncast/src/response/print.rs | 1 + crates/sncast/src/response/structs.rs | 3 ++- .../src/starknet_commands/show_config.rs | 12 +++++++--- .../tests/data/files/correct_snfoundry.toml | 6 +++++ crates/sncast/tests/e2e/show_config.rs | 23 +++++++++++++++++++ 7 files changed, 43 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56f1be4062..2a734a9c6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 #### Changed - Changed return type of `declare` in Cairo Deployment Scripts so it can handle already declared contracts without failing +- Allow using `show-config` command without providing rpc url ## [0.33.0] - 2024-11-04 diff --git a/crates/sncast/src/main.rs b/crates/sncast/src/main.rs index 84cd3d4c37..d5b7d012b2 100644 --- a/crates/sncast/src/main.rs +++ b/crates/sncast/src/main.rs @@ -586,7 +586,7 @@ async fn run_async_command( }, Commands::ShowConfig(show) => { - let provider = show.rpc.get_provider(&config).await?; + let provider = show.rpc.get_provider(&config).await.ok(); let result = starknet_commands::show_config::show_config(&show, &provider, config, cli.profile) diff --git a/crates/sncast/src/response/print.rs b/crates/sncast/src/response/print.rs index 8128c8a6e4..6b4e49655a 100644 --- a/crates/sncast/src/response/print.rs +++ b/crates/sncast/src/response/print.rs @@ -75,6 +75,7 @@ impl From for OutputValue { .collect(), ), Value::String(s) => OutputValue::String(s.to_string()), + Value::Bool(b) => OutputValue::String(b.to_string()), s => panic!("{s:?} cannot be auto-serialized to output"), } } diff --git a/crates/sncast/src/response/structs.rs b/crates/sncast/src/response/structs.rs index affec75d54..cd28b0020c 100644 --- a/crates/sncast/src/response/structs.rs +++ b/crates/sncast/src/response/structs.rs @@ -107,13 +107,14 @@ impl CommandResponse for MulticallNewResponse {} #[derive(Serialize)] pub struct ShowConfigResponse { pub profile: Option, - pub chain_id: String, + pub chain_id: Option, pub rpc_url: Option, pub account: Option, pub accounts_file_path: Option, pub keystore: Option, pub wait_timeout: Option, pub wait_retry_interval: Option, + pub show_explorer_links: bool, } impl CommandResponse for ShowConfigResponse {} diff --git a/crates/sncast/src/starknet_commands/show_config.rs b/crates/sncast/src/starknet_commands/show_config.rs index ba61c7dc8e..4d54ca6291 100644 --- a/crates/sncast/src/starknet_commands/show_config.rs +++ b/crates/sncast/src/starknet_commands/show_config.rs @@ -18,12 +18,17 @@ pub struct ShowConfig { #[allow(clippy::ptr_arg)] pub async fn show_config( show: &ShowConfig, - provider: &JsonRpcClient, + provider: &Option>, cast_config: CastConfig, profile: Option, ) -> Result { - let chain_id_field = get_chain_id(provider).await?; - let chain_id = chain_id_to_network_name(chain_id_field); + let chain_id = if let Some(provider) = provider { + let chain_id_field = get_chain_id(provider).await?; + Some(chain_id_to_network_name(chain_id_field)) + } else { + None + }; + let rpc_url = Some(show.rpc.url.clone().unwrap_or(cast_config.url)).filter(|p| !p.is_empty()); let account = Some(cast_config.account).filter(|p| !p.is_empty()); let mut accounts_file_path = @@ -44,5 +49,6 @@ pub async fn show_config( keystore, wait_timeout: wait_timeout.map(|x| Decimal(u64::from(x))), wait_retry_interval: wait_retry_interval.map(|x| Decimal(u64::from(x))), + show_explorer_links: cast_config.show_explorer_links, }) } diff --git a/crates/sncast/tests/data/files/correct_snfoundry.toml b/crates/sncast/tests/data/files/correct_snfoundry.toml index 83a09dbf38..0baa551e1b 100644 --- a/crates/sncast/tests/data/files/correct_snfoundry.toml +++ b/crates/sncast/tests/data/files/correct_snfoundry.toml @@ -25,3 +25,9 @@ account = "user3" [sncast.profile5] url = "http://127.0.0.1:5055/rpc" account = "user8" + +[sncast.profile6] +accounts-file = "/path/to/account.json" +account = "user1" +wait-params = { timeout = 500, retry-interval = 10 } +show-explorer-links = false diff --git a/crates/sncast/tests/e2e/show_config.rs b/crates/sncast/tests/e2e/show_config.rs index 57f35cb569..ae1dd14629 100644 --- a/crates/sncast/tests/e2e/show_config.rs +++ b/crates/sncast/tests/e2e/show_config.rs @@ -15,6 +15,7 @@ async fn test_show_config_from_snfoundry_toml() { accounts_file_path: ../account-file chain_id: alpha-sepolia rpc_url: {} + show_explorer_links: true wait_retry_interval: 5 wait_timeout: 300 ", URL}); @@ -44,6 +45,7 @@ async fn test_show_config_from_cli() { chain_id: alpha-sepolia keystore: ../keystore rpc_url: {} + show_explorer_links: true wait_retry_interval: 1 wait_timeout: 2 ", URL}); @@ -63,6 +65,7 @@ async fn test_show_config_from_cli_and_snfoundry_toml() { chain_id: alpha-sepolia profile: profile2 rpc_url: {} + show_explorer_links: true wait_retry_interval: 5 wait_timeout: 300 ", URL}); @@ -82,6 +85,7 @@ async fn test_show_config_when_no_keystore() { chain_id: alpha-sepolia profile: profile4 rpc_url: {} + show_explorer_links: true wait_retry_interval: 5 wait_timeout: 300 ", URL}); @@ -101,7 +105,26 @@ async fn test_show_config_when_keystore() { keystore: ../keystore profile: profile3 rpc_url: {} + show_explorer_links: true wait_retry_interval: 5 wait_timeout: 300 ", URL}); } + +#[tokio::test] +async fn test_show_config_no_url() { + let tempdir = copy_config_to_tempdir("tests/data/files/correct_snfoundry.toml", None).unwrap(); + let args = vec!["--profile", "profile6", "show-config"]; + + let snapbox = runner(&args).current_dir(tempdir.path()); + + snapbox.assert().success().stdout_eq(formatdoc! {r" + command: show-config + account: user1 + accounts_file_path: /path/to/account.json + profile: profile6 + show_explorer_links: false + wait_retry_interval: 10 + wait_timeout: 500 + "}); +} From 2afd2127479f5518272d8ce138db21faf4bb390a Mon Sep 17 00:00:00 2001 From: ksew1 <95349104+ksew1@users.noreply.github.com> Date: Tue, 26 Nov 2024 09:58:58 +0000 Subject: [PATCH 09/23] Add backtrace to forge (#2679) Closes https://github.com/foundry-rs/starknet-foundry/issues/2468 ## Introduced changes - Forge will display backtrace for contracts in format similar to rust ## Checklist - [x] Linked relevant issue - [x] Updated relevant documentation - [x] Added relevant tests - [x] Performed self-review of the code - [x] Added changes to `CHANGELOG.md` --- .github/workflows/ci.yml | 5 +- Cargo.lock | 1 + .../execution/cairo1_execution.rs | 22 +- .../execution/deprecated/cairo0_execution.rs | 15 +- .../execution/entry_point.rs | 78 +++++- crates/cheatnet/src/state.rs | 8 + crates/forge-runner/Cargo.toml | 1 + crates/forge-runner/src/backtrace.rs | 226 ++++++++++++++++++ crates/forge-runner/src/lib.rs | 1 + crates/forge-runner/src/running.rs | 25 +- crates/forge-runner/src/test_case_summary.rs | 7 +- .../tests/data/backtrace_panic/Scarb.toml | 22 ++ .../tests/data/backtrace_panic/src/lib.cairo | 61 +++++ .../tests/data/backtrace_vm_error/Scarb.toml | 22 ++ .../data/backtrace_vm_error/src/lib.cairo | 68 ++++++ crates/forge/tests/e2e/backtrace.rs | 126 ++++++++++ crates/forge/tests/e2e/mod.rs | 1 + 17 files changed, 664 insertions(+), 25 deletions(-) create mode 100644 crates/forge-runner/src/backtrace.rs create mode 100644 crates/forge/tests/data/backtrace_panic/Scarb.toml create mode 100644 crates/forge/tests/data/backtrace_panic/src/lib.cairo create mode 100644 crates/forge/tests/data/backtrace_vm_error/Scarb.toml create mode 100644 crates/forge/tests/data/backtrace_vm_error/src/lib.cairo create mode 100644 crates/forge/tests/e2e/backtrace.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1605611422..9d10c834bc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -88,8 +88,8 @@ jobs: - name: nextest partition ${{ matrix.partition }}/8 run: cargo nextest run --partition 'count:${{ matrix.partition }}/8' --archive-file 'nextest-archive.tar.zst' e2e - test-coverage: - name: Test coverage + test-scarb-2-8-3: + name: Test scarb 2.8.3 runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -105,6 +105,7 @@ jobs: curl -L https://raw.githubusercontent.com/software-mansion/cairo-coverage/main/scripts/install.sh | sh - run: cargo test --package forge --features scarb_2_8_3 --test main e2e::coverage + - run: cargo test --package forge --features scarb_2_8_3 --test main e2e::backtrace test-coverage-error: name: Test coverage error diff --git a/Cargo.lock b/Cargo.lock index bb7c4f1f20..2a6dd09c6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2226,6 +2226,7 @@ dependencies = [ "cairo-lang-sierra-to-casm", "cairo-lang-sierra-type-size", "cairo-lang-starknet", + "cairo-lang-starknet-classes", "cairo-lang-test-plugin", "cairo-lang-utils", "cairo-vm", diff --git a/crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/execution/cairo1_execution.rs b/crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/execution/cairo1_execution.rs index 22e656fc02..4b63a11d48 100644 --- a/crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/execution/cairo1_execution.rs +++ b/crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/execution/cairo1_execution.rs @@ -1,22 +1,23 @@ +use crate::runtime_extensions::call_to_blockifier_runtime_extension::execution::entry_point::{ + ContractClassEntryPointExecutionResult, EntryPointExecutionErrorWithLastPc, GetLastPc, + OnErrorLastPc, +}; use crate::runtime_extensions::call_to_blockifier_runtime_extension::CheatnetState; use crate::runtime_extensions::cheatable_starknet_runtime_extension::CheatableStarknetRuntimeExtension; use crate::runtime_extensions::common::get_relocated_vm_trace; -use blockifier::execution::call_info::CallInfo; -use blockifier::execution::deprecated_syscalls::hint_processor::SyscallCounter; use blockifier::execution::entry_point_execution::{ finalize_execution, initialize_execution_context, prepare_call_arguments, VmExecutionContext, }; use blockifier::{ execution::{ contract_class::{ContractClassV1, EntryPointV1}, - entry_point::{CallEntryPoint, EntryPointExecutionContext, EntryPointExecutionResult}, + entry_point::{CallEntryPoint, EntryPointExecutionContext}, errors::EntryPointExecutionError, execution_utils::Args, }, state::state_api::State, }; use cairo_vm::vm::errors::cairo_run_errors::CairoRunError; -use cairo_vm::vm::trace::trace_entry::RelocatedTraceEntry; use cairo_vm::{ hint_processor::hint_processor_definition::HintProcessor, vm::runners::cairo_runner::{CairoArg, CairoRunner, ExecutionResources}, @@ -31,7 +32,7 @@ pub fn execute_entry_point_call_cairo1( cheatnet_state: &mut CheatnetState, // Added parameter resources: &mut ExecutionResources, context: &mut EntryPointExecutionContext, -) -> EntryPointExecutionResult<(CallInfo, SyscallCounter, Option>)> { +) -> ContractClassEntryPointExecutionResult { let VmExecutionContext { mut runner, mut syscall_handler, @@ -68,7 +69,8 @@ pub fn execute_entry_point_call_cairo1( &entry_point, &args, program_extra_data_length, - )?; + ) + .on_error_get_last_pc(&mut runner)?; let vm_trace = if cheatable_runtime .extension @@ -86,6 +88,7 @@ pub fn execute_entry_point_call_cairo1( .syscall_counter .clone(); + let last_pc = runner.get_last_pc(); let call_info = finalize_execution( runner, cheatable_runtime.extended_runtime.hint_handler, @@ -94,8 +97,11 @@ pub fn execute_entry_point_call_cairo1( program_extra_data_length, )?; if call_info.execution.failed { - return Err(EntryPointExecutionError::ExecutionFailed { - error_data: call_info.execution.retdata.0, + return Err(EntryPointExecutionErrorWithLastPc { + source: EntryPointExecutionError::ExecutionFailed { + error_data: call_info.execution.retdata.0, + }, + last_pc, }); } diff --git a/crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/execution/deprecated/cairo0_execution.rs b/crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/execution/deprecated/cairo0_execution.rs index 35c139c502..8a1e89cbcf 100644 --- a/crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/execution/deprecated/cairo0_execution.rs +++ b/crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/execution/deprecated/cairo0_execution.rs @@ -1,23 +1,21 @@ +use crate::runtime_extensions::call_to_blockifier_runtime_extension::execution::entry_point::{ + ContractClassEntryPointExecutionResult, OnErrorLastPc, +}; use crate::runtime_extensions::call_to_blockifier_runtime_extension::CheatnetState; use crate::runtime_extensions::deprecated_cheatable_starknet_extension::runtime::{ DeprecatedExtendedRuntime, DeprecatedStarknetRuntime, }; use crate::runtime_extensions::deprecated_cheatable_starknet_extension::DeprecatedCheatableStarknetRuntimeExtension; -use blockifier::execution::call_info::CallInfo; use blockifier::execution::contract_class::ContractClassV0; use blockifier::execution::deprecated_entry_point_execution::{ finalize_execution, initialize_execution_context, prepare_call_arguments, VmExecutionContext, }; -use blockifier::execution::entry_point::{ - CallEntryPoint, EntryPointExecutionContext, EntryPointExecutionResult, -}; +use blockifier::execution::entry_point::{CallEntryPoint, EntryPointExecutionContext}; use blockifier::execution::errors::EntryPointExecutionError; use blockifier::execution::execution_utils::Args; -use blockifier::execution::syscalls::hint_processor::SyscallCounter; use blockifier::state::state_api::State; use cairo_vm::hint_processor::hint_processor_definition::HintProcessor; use cairo_vm::vm::runners::cairo_runner::{CairoArg, CairoRunner, ExecutionResources}; -use cairo_vm::vm::trace::trace_entry::RelocatedTraceEntry; // blockifier/src/execution/deprecated_execution.rs:36 (execute_entry_point_call) pub fn execute_entry_point_call_cairo0( @@ -27,7 +25,7 @@ pub fn execute_entry_point_call_cairo0( cheatnet_state: &mut CheatnetState, resources: &mut ExecutionResources, context: &mut EntryPointExecutionContext, -) -> EntryPointExecutionResult<(CallInfo, SyscallCounter, Option>)> { +) -> ContractClassEntryPointExecutionResult { let VmExecutionContext { mut runner, mut syscall_handler, @@ -61,7 +59,8 @@ pub fn execute_entry_point_call_cairo0( &mut cheatable_syscall_handler, entry_point_pc, &args, - )?; + ) + .on_error_get_last_pc(&mut runner)?; let syscall_counter = cheatable_syscall_handler .extended_runtime diff --git a/crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/execution/entry_point.rs b/crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/execution/entry_point.rs index 87f494dd6d..5aeed3dcb6 100644 --- a/crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/execution/entry_point.rs +++ b/crates/cheatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/execution/entry_point.rs @@ -2,7 +2,7 @@ use std::cell::RefCell; use super::cairo1_execution::execute_entry_point_call_cairo1; use crate::runtime_extensions::call_to_blockifier_runtime_extension::execution::deprecated::cairo0_execution::execute_entry_point_call_cairo0; use crate::runtime_extensions::call_to_blockifier_runtime_extension::CheatnetState; -use crate::state::{CallTrace, CallTraceNode, CheatStatus}; +use crate::state::{CallTrace, CallTraceNode, CheatStatus, EncounteredError}; use blockifier::execution::call_info::{CallExecution, Retdata}; use blockifier::{ execution::{ @@ -17,7 +17,7 @@ use blockifier::{ }, state::state_api::State, }; -use cairo_vm::vm::runners::cairo_runner::ExecutionResources; +use cairo_vm::vm::runners::cairo_runner::{CairoRunner, ExecutionResources}; use starknet_api::{ core::ClassHash, deprecated_contract_class::EntryPointType, @@ -28,11 +28,17 @@ use std::rc::Rc; use blockifier::execution::deprecated_syscalls::hint_processor::SyscallCounter; use starknet_types_core::felt::Felt; use cairo_vm::vm::trace::trace_entry::RelocatedTraceEntry; +use thiserror::Error; use conversions::FromConv; use crate::runtime_extensions::call_to_blockifier_runtime_extension::rpc::{AddressOrClassHash, CallResult}; use crate::runtime_extensions::common::sum_syscall_counters; use conversions::string::TryFromHexStr; +pub(crate) type ContractClassEntryPointExecutionResult = Result< + (CallInfo, SyscallCounter, Option>), + EntryPointExecutionErrorWithLastPc, +>; + // blockifier/src/execution/entry_point.rs:180 (CallEntryPoint::execute) #[allow(clippy::too_many_lines)] pub fn execute_call_entry_point( @@ -151,7 +157,15 @@ pub fn execute_call_entry_point( ); Ok(call_info) } - Err(err) => { + Err(EntryPointExecutionErrorWithLastPc { + source: err, + last_pc: pc, + }) => { + if let Some(pc) = pc { + cheatnet_state + .encountered_errors + .push(EncounteredError { pc, class_hash }); + } exit_error_call(&err, cheatnet_state, resources, entry_point); Err(err) } @@ -297,3 +311,61 @@ fn aggregate_syscall_counters(trace: &Rc>) -> SyscallCounter } result } + +#[derive(Debug, Error)] +#[error("{}", source)] +pub struct EntryPointExecutionErrorWithLastPc { + pub source: EntryPointExecutionError, + pub last_pc: Option, +} + +impl From for EntryPointExecutionErrorWithLastPc +where + T: Into, +{ + fn from(value: T) -> Self { + Self { + source: value.into(), + last_pc: None, + } + } +} + +pub(crate) trait OnErrorLastPc: Sized { + fn on_error_get_last_pc( + self, + runner: &mut CairoRunner, + ) -> Result; +} + +impl OnErrorLastPc for Result { + fn on_error_get_last_pc( + self, + runner: &mut CairoRunner, + ) -> Result { + match self { + Err(source) => { + let last_pc = runner.get_last_pc(); + + Err(EntryPointExecutionErrorWithLastPc { source, last_pc }) + } + Ok(value) => Ok(value), + } + } +} + +pub trait GetLastPc { + fn get_last_pc(&mut self) -> Option; +} + +impl GetLastPc for CairoRunner { + fn get_last_pc(&mut self) -> Option { + if self.relocated_trace.is_none() { + self.relocate(true).ok()?; + } + self.relocated_trace + .as_ref() + .and_then(|trace| trace.last()) + .map(|entry| entry.pc) + } +} diff --git a/crates/cheatnet/src/state.rs b/crates/cheatnet/src/state.rs index a557ecd694..5b0fbf7189 100644 --- a/crates/cheatnet/src/state.rs +++ b/crates/cheatnet/src/state.rs @@ -320,6 +320,12 @@ pub struct TraceData { pub is_vm_trace_needed: bool, } +#[derive(Clone)] +pub struct EncounteredError { + pub pc: usize, + pub class_hash: ClassHash, +} + pub struct CheatnetState { pub cheated_execution_info_contracts: HashMap, pub global_cheated_execution_info: ExecutionInfoMock, @@ -332,6 +338,7 @@ pub struct CheatnetState { pub deploy_salt_base: u32, pub block_info: BlockInfo, pub trace_data: TraceData, + pub encountered_errors: Vec, } impl Default for CheatnetState { @@ -357,6 +364,7 @@ impl Default for CheatnetState { current_call_stack: NotEmptyCallStack::from(test_call), is_vm_trace_needed: false, }, + encountered_errors: vec![], } } } diff --git a/crates/forge-runner/Cargo.toml b/crates/forge-runner/Cargo.toml index 929c0f720f..a9e35b7012 100644 --- a/crates/forge-runner/Cargo.toml +++ b/crates/forge-runner/Cargo.toml @@ -19,6 +19,7 @@ cairo-lang-sierra-type-size.workspace = true cairo-lang-sierra-gas.workspace = true cairo-lang-sierra-ap-change.workspace = true cairo-lang-test-plugin.workspace = true +cairo-lang-starknet-classes.workspace = true cairo-annotations.workspace = true starknet-types-core.workspace = true starknet_api.workspace = true diff --git a/crates/forge-runner/src/backtrace.rs b/crates/forge-runner/src/backtrace.rs new file mode 100644 index 0000000000..7afad162bb --- /dev/null +++ b/crates/forge-runner/src/backtrace.rs @@ -0,0 +1,226 @@ +use anyhow::{Context, Result}; +use cairo_annotations::annotations::coverage::{ + CodeLocation, ColumnNumber, CoverageAnnotationsV1, LineNumber, VersionedCoverageAnnotations, +}; +use cairo_annotations::annotations::profiler::{ + FunctionName, ProfilerAnnotationsV1, VersionedProfilerAnnotations, +}; +use cairo_annotations::annotations::TryFromDebugInfo; +use cairo_lang_sierra::program::StatementIdx; +use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; +use cairo_lang_starknet_classes::contract_class::ContractClass; +use cheatnet::runtime_extensions::forge_runtime_extension::contracts_data::ContractsData; +use cheatnet::state::EncounteredError; +use indoc::indoc; +use itertools::Itertools; +use rayon::prelude::*; +use starknet_api::core::ClassHash; +use std::collections::HashMap; +use std::fmt::Display; +use std::{env, fmt}; + +const BACKTRACE_ENV: &str = "SNFORGE_BACKTRACE"; + +pub fn add_backtrace_footer( + message: String, + contracts_data: &ContractsData, + encountered_errors: &[EncounteredError], +) -> String { + if encountered_errors.is_empty() { + return message; + } + + let is_backtrace_enabled = env::var(BACKTRACE_ENV).is_ok_and(|value| value == "1"); + if !is_backtrace_enabled { + return format!( + "{message}\nnote: run with `{BACKTRACE_ENV}=1` environment variable to display a backtrace", + ); + } + + BacktraceContractRepository::new(contracts_data, encountered_errors) + .map(|repository| { + encountered_errors + .iter() + .filter_map(|error| repository.get_backtrace(error.pc, error.class_hash)) + .map(|backtrace| backtrace.to_string()) + .collect::>() + .join("\n") + }) + .map_or_else( + |err| format!("{message}\nfailed to create backtrace: {err}"), + |backtraces| format!("{message}\n{backtraces}"), + ) +} + +struct ContractBacktraceData { + contract_name: String, + casm_debug_info_start_offsets: Vec, + coverage_annotations: CoverageAnnotationsV1, + profiler_annotations: ProfilerAnnotationsV1, +} + +impl ContractBacktraceData { + fn new(class_hash: &ClassHash, contracts_data: &ContractsData) -> Result { + let contract_name = contracts_data + .get_contract_name(class_hash) + .context(format!( + "failed to get contract name for class hash: {class_hash}" + ))? + .clone(); + + let contract_artifacts = contracts_data + .get_artifacts(&contract_name) + .context(format!( + "failed to get artifacts for contract name: {contract_name}" + ))?; + + let contract_class = serde_json::from_str::(&contract_artifacts.sierra)?; + + let sierra_debug_info = contract_class + .sierra_program_debug_info + .as_ref() + .context("debug info not found")?; + + let VersionedCoverageAnnotations::V1(coverage_annotations) = + VersionedCoverageAnnotations::try_from_debug_info(sierra_debug_info).context(indoc! { + "perhaps the contract was compiled without the following entry in Scarb.toml under [profile.dev.cairo]: + unstable-add-statements-code-locations-debug-info = true + + or scarb version is less than 2.8.0 + " + })?; + + let VersionedProfilerAnnotations::V1(profiler_annotations) = + VersionedProfilerAnnotations::try_from_debug_info(sierra_debug_info).context(indoc! { + "perhaps the contract was compiled without the following entry in Scarb.toml under [profile.dev.cairo]: + unstable-add-statements-functions-debug-info = true + + or scarb version is less than 2.8.0 + " + })?; + + // Not optimal, but USC doesn't produce debug info for the contract class + let (_, debug_info) = CasmContractClass::from_contract_class_with_debug_info( + contract_class, + true, + usize::MAX, + )?; + + let casm_debug_info_start_offsets = debug_info + .sierra_statement_info + .iter() + .map(|statement_debug_info| statement_debug_info.start_offset) + .collect(); + + Ok(Self { + contract_name, + casm_debug_info_start_offsets, + coverage_annotations, + profiler_annotations, + }) + } + + fn backtrace_from(&self, pc: usize) -> Option { + let sierra_statement_idx = StatementIdx( + self.casm_debug_info_start_offsets + .partition_point(|start_offset| *start_offset < pc - 1) + .saturating_sub(1), + ); + + let code_locations = self + .coverage_annotations + .statements_code_locations + .get(&sierra_statement_idx)?; + + let function_names = self + .profiler_annotations + .statements_functions + .get(&sierra_statement_idx)?; + + let stack = code_locations + .iter() + .zip(function_names) + .map(|(code_location, function_name)| Backtrace { + code_location, + function_name, + }) + .collect(); + + Some(BacktraceStack { + pc, + contract_name: &self.contract_name, + stack, + }) + } +} + +struct BacktraceContractRepository(HashMap); + +impl BacktraceContractRepository { + fn new( + contracts_data: &ContractsData, + encountered_errors: &[EncounteredError], + ) -> Result { + Ok(Self( + encountered_errors + .iter() + .map(|error| error.class_hash) + .unique() + .collect::>() + .par_iter() + .map(|class_hash| { + ContractBacktraceData::new(class_hash, contracts_data) + .map(|contract_data| (*class_hash, contract_data)) + }) + .collect::>()?, + )) + } + + fn get_backtrace(&self, pc: usize, class_hash: ClassHash) -> Option { + self.0.get(&class_hash)?.backtrace_from(pc) + } +} + +struct Backtrace<'a> { + code_location: &'a CodeLocation, + function_name: &'a FunctionName, +} + +struct BacktraceStack<'a> { + pc: usize, + contract_name: &'a str, + stack: Vec>, +} + +impl Display for Backtrace<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let function_name = &self.function_name.0; + let path = truncate_at_char(&self.code_location.0 .0, '['); + let line = self.code_location.1.start.line + LineNumber(1); // most editors start line numbers from 1 + let col = self.code_location.1.start.col + ColumnNumber(1); // most editors start column numbers from 1 + + write!(f, "{function_name}\n at {path}:{line}:{col}",) + } +} + +impl Display for BacktraceStack<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + writeln!( + f, + "error occurred in contract '{}' at pc: '{}'", + self.contract_name, self.pc + )?; + writeln!(f, "stack backtrace:")?; + for (i, backtrace) in self.stack.iter().enumerate() { + writeln!(f, " {i}: {backtrace}")?; + } + Ok(()) + } +} + +fn truncate_at_char(input: &str, delimiter: char) -> &str { + match input.find(delimiter) { + Some(index) => &input[..index], + None => input, + } +} diff --git a/crates/forge-runner/src/lib.rs b/crates/forge-runner/src/lib.rs index 1c231eea19..8608f685e6 100644 --- a/crates/forge-runner/src/lib.rs +++ b/crates/forge-runner/src/lib.rs @@ -33,6 +33,7 @@ pub mod profiler_api; pub mod test_case_summary; pub mod test_target_summary; +mod backtrace; mod fuzzer; mod gas; pub mod printing; diff --git a/crates/forge-runner/src/running.rs b/crates/forge-runner/src/running.rs index d286a70bf3..21081c16c5 100644 --- a/crates/forge-runner/src/running.rs +++ b/crates/forge-runner/src/running.rs @@ -1,3 +1,4 @@ +use crate::backtrace::add_backtrace_footer; use crate::build_trace_data::test_sierra_program_path::VersionedProgramPath; use crate::forge_config::{RuntimeConfig, TestRunnerConfig}; use crate::gas::calculate_used_gas; @@ -21,7 +22,9 @@ use cheatnet::runtime_extensions::forge_runtime_extension::{ get_all_used_resources, update_top_call_execution_resources, update_top_call_l1_resources, update_top_call_vm_trace, ForgeExtension, ForgeRuntime, }; -use cheatnet::state::{BlockInfoReader, CallTrace, CheatnetState, ExtendedStateReader}; +use cheatnet::state::{ + BlockInfoReader, CallTrace, CheatnetState, EncounteredError, ExtendedStateReader, +}; use entry_code::create_entry_code; use hints::{hints_by_representation, hints_to_params}; use runtime::starknet::context::{build_context, set_max_steps}; @@ -129,6 +132,7 @@ pub struct RunResultWithInfo { pub(crate) call_trace: Rc>, pub(crate) gas_used: u128, pub(crate) used_resources: UsedResources, + pub(crate) encountered_errors: Vec, } #[allow(clippy::too_many_lines)] @@ -246,6 +250,14 @@ pub fn run_test_case( Err(err) => Err(err), }; + let encountered_errors = forge_runtime + .extended_runtime + .extended_runtime + .extension + .cheatnet_state + .encountered_errors + .clone(); + let call_trace_ref = get_call_trace_ref(&mut forge_runtime); update_top_call_execution_resources(&mut forge_runtime); @@ -269,6 +281,7 @@ pub fn run_test_case( gas_used: gas, used_resources, call_trace: call_trace_ref, + encountered_errors, }) } @@ -289,6 +302,7 @@ fn extract_test_case_summary( result_with_info.gas_used, result_with_info.used_resources, &result_with_info.call_trace, + &result_with_info.encountered_errors, contracts_data, maybe_versioned_program_path, ), @@ -298,7 +312,14 @@ fn extract_test_case_summary( msg: Some(format!( "\n {}\n", error.to_string().replace(" Custom Hint Error: ", "\n ") - )), + )) + .map(|msg| { + add_backtrace_footer( + msg, + contracts_data, + &result_with_info.encountered_errors, + ) + }), arguments: args, test_statistics: (), }, diff --git a/crates/forge-runner/src/test_case_summary.rs b/crates/forge-runner/src/test_case_summary.rs index 78340772c9..7e13bc4cc8 100644 --- a/crates/forge-runner/src/test_case_summary.rs +++ b/crates/forge-runner/src/test_case_summary.rs @@ -1,3 +1,4 @@ +use crate::backtrace::add_backtrace_footer; use crate::build_trace_data::build_profiler_call_trace; use crate::build_trace_data::test_sierra_program_path::VersionedProgramPath; use crate::expected_result::{ExpectedPanicValue, ExpectedTestResult}; @@ -8,7 +9,7 @@ use cairo_lang_runner::short_string::as_cairo_short_string; use cairo_lang_runner::{RunResult, RunResultValue}; use cheatnet::runtime_extensions::call_to_blockifier_runtime_extension::rpc::UsedResources; use cheatnet::runtime_extensions::forge_runtime_extension::contracts_data::ContractsData; -use cheatnet::state::CallTrace as InternalCallTrace; +use cheatnet::state::{CallTrace as InternalCallTrace, EncounteredError}; use conversions::byte_array::ByteArray; use num_traits::Pow; use shared::utils::build_readable_text; @@ -216,11 +217,13 @@ impl TestCaseSummary { gas: u128, used_resources: UsedResources, call_trace: &Rc>, + encountered_errors: &[EncounteredError], contracts_data: &ContractsData, maybe_versioned_program_path: &Option, ) -> Self { let name = test_case.name.clone(); - let msg = extract_result_data(&run_result, &test_case.config.expected_result); + let msg = extract_result_data(&run_result, &test_case.config.expected_result) + .map(|msg| add_backtrace_footer(msg, contracts_data, encountered_errors)); match run_result.value { RunResultValue::Success(_) => match &test_case.config.expected_result { ExpectedTestResult::Success => { diff --git a/crates/forge/tests/data/backtrace_panic/Scarb.toml b/crates/forge/tests/data/backtrace_panic/Scarb.toml new file mode 100644 index 0000000000..db687cf174 --- /dev/null +++ b/crates/forge/tests/data/backtrace_panic/Scarb.toml @@ -0,0 +1,22 @@ +[package] +name = "backtrace_panic" +version = "0.1.0" +edition = "2023_11" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] +starknet = "2.7.0" + +[dev-dependencies] +snforge_std = { path = "../../../../../snforge_std" } + +[[target.starknet-contract]] +sierra = true + +[scripts] +test = "snforge test" + +[profile.dev.cairo] +unstable-add-statements-functions-debug-info = true +unstable-add-statements-code-locations-debug-info = true diff --git a/crates/forge/tests/data/backtrace_panic/src/lib.cairo b/crates/forge/tests/data/backtrace_panic/src/lib.cairo new file mode 100644 index 0000000000..5517a8fd35 --- /dev/null +++ b/crates/forge/tests/data/backtrace_panic/src/lib.cairo @@ -0,0 +1,61 @@ +#[starknet::interface] +pub trait IOuterContract { + fn outer(self: @TState, contract_address: starknet::ContractAddress); +} + +#[starknet::contract] +pub mod OuterContract { + use super::{IInnerContractDispatcher, IInnerContractDispatcherTrait}; + + #[storage] + pub struct Storage {} + + #[abi(embed_v0)] + impl OuterContract of super::IOuterContract { + fn outer(self: @ContractState, contract_address: starknet::ContractAddress) { + let dispatcher = IInnerContractDispatcher { contract_address }; + dispatcher.inner(); + } + } +} + +#[starknet::interface] +pub trait IInnerContract { + fn inner(self: @TState); +} + +#[starknet::contract] +pub mod InnerContract { + #[storage] + pub struct Storage {} + + #[abi(embed_v0)] + impl InnerContract of super::IInnerContract { + fn inner(self: @ContractState) { + inner_call() + } + } + + fn inner_call() { + assert(1 != 1, 'aaaa'); + } +} + +#[cfg(test)] +mod Test { + use snforge_std::cheatcodes::contract_class::DeclareResultTrait; + use snforge_std::{ContractClassTrait, declare}; + use super::{IOuterContractDispatcher, IOuterContractDispatcherTrait}; + + #[test] + fn test_unwrapped_call_contract_syscall() { + let contract_inner = declare("InnerContract").unwrap().contract_class(); + let (contract_address_inner, _) = contract_inner.deploy(@array![]).unwrap(); + + let contract_outer = declare("OuterContract").unwrap().contract_class(); + let (contract_address_outer, _) = contract_outer.deploy(@array![]).unwrap(); + + let dispatcher = IOuterContractDispatcher { contract_address: contract_address_outer }; + dispatcher.outer(contract_address_inner); + } +} diff --git a/crates/forge/tests/data/backtrace_vm_error/Scarb.toml b/crates/forge/tests/data/backtrace_vm_error/Scarb.toml new file mode 100644 index 0000000000..942939e25e --- /dev/null +++ b/crates/forge/tests/data/backtrace_vm_error/Scarb.toml @@ -0,0 +1,22 @@ +[package] +name = "backtrace_vm_error" +version = "0.1.0" +edition = "2023_11" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] +starknet = "2.7.0" + +[dev-dependencies] +snforge_std = { path = "../../../../../snforge_std" } + +[[target.starknet-contract]] +sierra = true + +[scripts] +test = "snforge test" + +[profile.dev.cairo] +unstable-add-statements-functions-debug-info = true +unstable-add-statements-code-locations-debug-info = true diff --git a/crates/forge/tests/data/backtrace_vm_error/src/lib.cairo b/crates/forge/tests/data/backtrace_vm_error/src/lib.cairo new file mode 100644 index 0000000000..ec8559e832 --- /dev/null +++ b/crates/forge/tests/data/backtrace_vm_error/src/lib.cairo @@ -0,0 +1,68 @@ +#[starknet::interface] +pub trait IOuterContract { + fn outer(self: @TState, contract_address: starknet::ContractAddress); +} + +#[starknet::contract] +pub mod OuterContract { + use super::{IInnerContractDispatcher, IInnerContractDispatcherTrait}; + + #[storage] + pub struct Storage {} + + #[abi(embed_v0)] + impl OuterContract of super::IOuterContract { + fn outer(self: @ContractState, contract_address: starknet::ContractAddress) { + let dispatcher = IInnerContractDispatcher { contract_address }; + dispatcher.inner(); + } + } +} + +#[starknet::interface] +pub trait IInnerContract { + fn inner(self: @TState); +} + +#[starknet::contract] +pub mod InnerContract { + use starknet::SyscallResultTrait; + use starknet::syscalls::call_contract_syscall; + + #[storage] + pub struct Storage {} + + #[abi(embed_v0)] + impl InnerContract of super::IInnerContract { + fn inner(self: @ContractState) { + inner_call() + } + } + + fn inner_call() { + let this = starknet::get_contract_address(); + let selector = selector!("nonexistent"); + let calldata = array![].span(); + + call_contract_syscall(this, selector, calldata).unwrap_syscall(); + } +} + +#[cfg(test)] +mod Test { + use snforge_std::cheatcodes::contract_class::DeclareResultTrait; + use snforge_std::{ContractClassTrait, declare}; + use super::{IOuterContractDispatcher, IOuterContractDispatcherTrait}; + + #[test] + fn test_unwrapped_call_contract_syscall() { + let contract_inner = declare("InnerContract").unwrap().contract_class(); + let (contract_address_inner, _) = contract_inner.deploy(@array![]).unwrap(); + + let contract_outer = declare("OuterContract").unwrap().contract_class(); + let (contract_address_outer, _) = contract_outer.deploy(@array![]).unwrap(); + + let dispatcher = IOuterContractDispatcher { contract_address: contract_address_outer }; + dispatcher.outer(contract_address_inner); + } +} diff --git a/crates/forge/tests/e2e/backtrace.rs b/crates/forge/tests/e2e/backtrace.rs new file mode 100644 index 0000000000..f591ea383d --- /dev/null +++ b/crates/forge/tests/e2e/backtrace.rs @@ -0,0 +1,126 @@ +use super::common::runner::{setup_package, test_runner}; +use assert_fs::fixture::{FileWriteStr, PathChild}; +use indoc::indoc; +use shared::test_utils::output_assert::assert_stdout_contains; +use std::fs; +use toml_edit::{value, DocumentMut}; + +#[test] +#[cfg_attr(not(feature = "scarb_2_8_3"), ignore)] +fn test_backtrace_missing_env() { + let temp = setup_package("backtrace_vm_error"); + + let output = test_runner(&temp).assert().failure(); + + assert_stdout_contains( + output, + indoc! { + "Failure data: + (0x454e545259504f494e545f4e4f545f464f554e44 ('ENTRYPOINT_NOT_FOUND'), 0x454e545259504f494e545f4641494c4544 ('ENTRYPOINT_FAILED')) + note: run with `SNFORGE_BACKTRACE=1` environment variable to display a backtrace" + }, + ); +} + +#[test] +#[cfg_attr(not(feature = "scarb_2_8_3"), ignore)] +fn test_backtrace() { + let temp = setup_package("backtrace_vm_error"); + + let output = test_runner(&temp) + .env("SNFORGE_BACKTRACE", "1") + .assert() + .failure(); + + assert_stdout_contains( + output, + indoc! { + "Failure data: + (0x454e545259504f494e545f4e4f545f464f554e44 ('ENTRYPOINT_NOT_FOUND'), 0x454e545259504f494e545f4641494c4544 ('ENTRYPOINT_FAILED')) + error occurred in contract 'InnerContract' at pc: '72' + stack backtrace: + 0: backtrace_vm_error::InnerContract::inner_call + at [..]/src/lib.cairo:47:9 + 1: backtrace_vm_error::InnerContract::InnerContract::inner + at [..]/src/lib.cairo:38:13 + 2: backtrace_vm_error::InnerContract::__wrapper__InnerContract__inner + at [..]/src/lib.cairo:37:9 + + error occurred in contract 'OuterContract' at pc: '107' + stack backtrace: + 0: backtrace_vm_error::IInnerContractDispatcherImpl::inner + at [..]/src/lib.cairo:22:1 + 1: backtrace_vm_error::OuterContract::OuterContract::outer + at [..]/src/lib.cairo:17:13 + 2: backtrace_vm_error::OuterContract::__wrapper__OuterContract__outer + at [..]/src/lib.cairo:15:9" + }, + ); +} + +#[test] +#[cfg_attr(not(feature = "scarb_2_8_3"), ignore)] +fn test_wrong_scarb_toml_configuration() { + let temp = setup_package("backtrace_vm_error"); + + let manifest_path = temp.child("Scarb.toml"); + + let mut scarb_toml = fs::read_to_string(&manifest_path) + .unwrap() + .parse::() + .unwrap(); + + scarb_toml["profile"]["dev"]["cairo"]["unstable-add-statements-code-locations-debug-info"] = + value(false); + + manifest_path.write_str(&scarb_toml.to_string()).unwrap(); + + let output = test_runner(&temp) + .env("SNFORGE_BACKTRACE", "1") + .assert() + .failure(); + + assert_stdout_contains( + output, + indoc! { + "Failure data: + (0x454e545259504f494e545f4e4f545f464f554e44 ('ENTRYPOINT_NOT_FOUND'), 0x454e545259504f494e545f4641494c4544 ('ENTRYPOINT_FAILED')) + failed to create backtrace: perhaps the contract was compiled without the following entry in Scarb.toml under [profile.dev.cairo]: + unstable-add-statements-code-locations-debug-info = true + + or scarb version is less than 2.8.0" + }, + ); +} + +#[test] +#[cfg_attr(not(feature = "scarb_2_8_3"), ignore)] +fn test_backtrace_panic() { + let temp = setup_package("backtrace_panic"); + + let output = test_runner(&temp) + .env("SNFORGE_BACKTRACE", "1") + .assert() + .failure(); + + assert_stdout_contains( + output, + indoc! { + "Failure data: + 0x61616161 ('aaaa') + error occurred in contract 'InnerContract' at pc: '70' + stack backtrace: + 0: backtrace_panic::InnerContract::__wrapper__InnerContract__inner + at [..]/src/lib.cairo:34:9 + + error occurred in contract 'OuterContract' at pc: '107' + stack backtrace: + 0: backtrace_panic::IInnerContractDispatcherImpl::inner + at [..]/src/lib.cairo:22:1 + 1: backtrace_panic::OuterContract::OuterContract::outer + at [..]/src/lib.cairo:17:13 + 2: backtrace_panic::OuterContract::__wrapper__OuterContract__outer + at [..]/src/lib.cairo:15:9" + }, + ); +} diff --git a/crates/forge/tests/e2e/mod.rs b/crates/forge/tests/e2e/mod.rs index 9e8d060115..9fbf0d711c 100644 --- a/crates/forge/tests/e2e/mod.rs +++ b/crates/forge/tests/e2e/mod.rs @@ -1,5 +1,6 @@ pub(crate) mod common; +mod backtrace; mod build_profile; mod build_trace_data; mod collection; From ff8d40154c4fccd53a52d32ccd1c15ff1b97fa9a Mon Sep 17 00:00:00 2001 From: kkawula <57270771+kkawula@users.noreply.github.com> Date: Tue, 26 Nov 2024 11:20:10 +0100 Subject: [PATCH 10/23] Global cast configuration (#2689) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #2221 ## Introduced changes - Added global config implementation - Update `show-config` command - Update `snfoundry.toml` docs ## Checklist - [x] Linked relevant issue - [x] Updated relevant documentation - [x] Added relevant tests - [x] Performed self-review of the code - [x] Added changes to `CHANGELOG.md` --------- Co-authored-by: Artur Michałek <52135326+cptartur@users.noreply.github.com> Co-authored-by: ddoktorski <45050160+ddoktorski@users.noreply.github.com> --- CHANGELOG.md | 2 + Cargo.lock | 1 + Cargo.toml | 1 + crates/configuration/src/lib.rs | 20 +-- crates/forge/src/init.rs | 24 ++-- crates/shared/src/consts.rs | 1 + crates/sncast/Cargo.toml | 1 + crates/sncast/src/helpers/config.rs | 115 ++++++++++++++++++ crates/sncast/src/helpers/configuration.rs | 12 +- crates/sncast/src/helpers/mod.rs | 1 + crates/sncast/src/main.rs | 38 ++++-- crates/sncast/src/response/structs.rs | 2 + .../src/starknet_commands/account/mod.rs | 4 +- .../src/starknet_commands/show_config.rs | 2 + crates/sncast/tests/e2e/main_tests.rs | 23 ---- docs/src/appendix/sncast/account/create.md | 2 +- docs/src/appendix/sncast/account/import.md | 2 +- docs/src/appendix/snfoundry-toml.md | 35 ++++-- docs/src/projects/configuration.md | 57 ++++++++- 19 files changed, 263 insertions(+), 80 deletions(-) create mode 100644 crates/sncast/src/helpers/config.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a734a9c6e..5658544768 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - You can skip `--name` flag when using `account import` - a default name will be generated. - Addresses outputted when calling `sncast account create`, `sncast deploy` and `sncast declare` are now padded to 64 characters length and prefixed with `0x0` +- Globally available configuration to store profiles to share between projects. +- Missing fields in `show-config` command, `block_explorer` and `show_explorer_links`. #### Changed diff --git a/Cargo.lock b/Cargo.lock index 2a6dd09c6a..7c4db0a47a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4914,6 +4914,7 @@ dependencies = [ "conversions", "ctor", "data-transformer", + "dirs", "docs", "fs_extra", "indoc", diff --git a/Cargo.toml b/Cargo.toml index 8a4aed0c14..680ec6dcab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,6 +53,7 @@ cairo-lang-parser = "2.7.0" cairo-lang-macro = "0.1.0" cairo-vm = "1.0.0-rc3" cairo-annotations = "0.1.0" +dirs = "5.0.1" starknet-types-core = { version = "0.1.7", features = ["hash", "prime-bigint"] } anyhow = "1.0.92" assert_fs = "1.1.2" diff --git a/crates/configuration/src/lib.rs b/crates/configuration/src/lib.rs index 78ee92e1c7..91a65cb036 100644 --- a/crates/configuration/src/lib.rs +++ b/crates/configuration/src/lib.rs @@ -10,7 +10,7 @@ pub const CONFIG_FILENAME: &str = "snfoundry.toml"; /// Defined in snfoundry.toml /// Configuration not associated with any specific package -pub trait GlobalConfig { +pub trait Config { #[must_use] fn tool_name() -> &'static str; @@ -53,7 +53,7 @@ pub fn get_profile( } } -pub fn load_global_config( +pub fn load_config( path: &Option, profile: &Option, ) -> Result { @@ -243,7 +243,7 @@ mod tests { #[serde(default)] pub account: String, } - impl GlobalConfig for StubConfig { + impl Config for StubConfig { fn tool_name() -> &'static str { "stubtool" } @@ -255,7 +255,7 @@ mod tests { #[test] fn load_config_happy_case_with_profile() { let tempdir = copy_config_to_tempdir("tests/data/stubtool_snfoundry.toml", None).unwrap(); - let config = load_global_config::( + let config = load_config::( &Some(Utf8PathBuf::try_from(tempdir.path().to_path_buf()).unwrap()), &Some(String::from("profile1")), ) @@ -267,7 +267,7 @@ mod tests { #[test] fn load_config_happy_case_default_profile() { let tempdir = copy_config_to_tempdir("tests/data/stubtool_snfoundry.toml", None).unwrap(); - let config = load_global_config::( + let config = load_config::( &Some(Utf8PathBuf::try_from(tempdir.path().to_path_buf()).unwrap()), &None, ) @@ -279,7 +279,7 @@ mod tests { #[test] fn load_config_not_found() { let tempdir = tempdir().expect("Failed to create a temporary directory"); - let config = load_global_config::( + let config = load_config::( &Some(Utf8PathBuf::try_from(tempdir.path().to_path_buf()).unwrap()), &None, ) @@ -310,7 +310,7 @@ mod tests { url_nested: f32, } - impl GlobalConfig for StubComplexConfig { + impl Config for StubComplexConfig { fn tool_name() -> &'static str { "stubtool" } @@ -325,7 +325,7 @@ mod tests { let temp_dir = tempdir().expect("Failed to create a temporary directory"); File::create(temp_dir.path().join(CONFIG_FILENAME)).unwrap(); - load_global_config::( + load_config::( &Some(Utf8PathBuf::try_from(temp_dir.path().to_path_buf()).unwrap()), &None, ) @@ -344,7 +344,7 @@ mod tests { ) .expect("Failed to copy config file to temp dir"); // missing env variables - if load_global_config::( + if load_config::( &Some(Utf8PathBuf::try_from(tempdir.path().to_path_buf()).unwrap()), &Some(String::from("with-envs")), ) @@ -359,7 +359,7 @@ mod tests { env::set_var("VALUE_FLOAT123132", "321.312"); env::set_var("VALUE_BOOL1231321", "true"); env::set_var("VALUE_BOOL1231322", "false"); - let config = load_global_config::( + let config = load_config::( &Some(Utf8PathBuf::try_from(tempdir.path().to_path_buf()).unwrap()), &Some(String::from("with-envs")), ) diff --git a/crates/forge/src/init.rs b/crates/forge/src/init.rs index c427d8c29e..b36154c726 100644 --- a/crates/forge/src/init.rs +++ b/crates/forge/src/init.rs @@ -5,6 +5,7 @@ use include_dir::{include_dir, Dir}; use indoc::formatdoc; use scarb_api::ScarbCommand; use semver::Version; +use shared::consts::FREE_RPC_PROVIDER_URL; use std::env; use std::fs::{self, OpenOptions}; use std::io::Write; @@ -20,16 +21,19 @@ fn create_snfoundry_manifest(path: &PathBuf) -> Result<()> { fs::write( path, formatdoc! {r#" - # Visit https://foundry-rs.github.io/starknet-foundry/appendix/snfoundry-toml.html for more information - - # [sncast.myprofile1] # Define a profile name - # url = "http://127.0.0.1:5050/" # Url of the RPC provider - # accounts_file = "../account-file" # Path to the file with the account data - # account = "mainuser" # Account from `accounts_file` or default account file that will be used for the transactions - # keystore = "~/keystore" # Path to the keystore file - # wait_params = {{ timeout = 500, retry_interval = 10 }} # Wait for submitted transaction parameters - # block_explorer = "StarkScan" # Block explorer service used to display links to transaction details - "# + # Visit https://foundry-rs.github.io/starknet-foundry/appendix/snfoundry-toml.html + # and https://foundry-rs.github.io/starknet-foundry/projects/configuration.html for more information + + # [sncast.default] # Define a profile name + # url = "{default_rpc_url}" # Url of the RPC provider + # accounts-file = "../account-file" # Path to the file with the account data + # account = "mainuser" # Account from `accounts_file` or default account file that will be used for the transactions + # keystore = "~/keystore" # Path to the keystore file + # wait-params = {{ timeout = 300, retry-interval = 10 }} # Wait for submitted transaction parameters + # block-explorer = "StarkScan" # Block explorer service used to display links to transaction details + # show-explorer-links = true # Print links pointing to pages with transaction details in the chosen block explorer + "#, + default_rpc_url = FREE_RPC_PROVIDER_URL, }, )?; diff --git a/crates/shared/src/consts.rs b/crates/shared/src/consts.rs index d94812861f..b39af175b0 100644 --- a/crates/shared/src/consts.rs +++ b/crates/shared/src/consts.rs @@ -1,3 +1,4 @@ pub const EXPECTED_RPC_VERSION: &str = "0.7.0"; pub const RPC_URL_VERSION: &str = "v0_7"; pub const SNFORGE_TEST_FILTER: &str = "SNFORGE_TEST_FILTER"; +pub const FREE_RPC_PROVIDER_URL: &str = "https://free-rpc.nethermind.io/sepolia-juno/v0_7"; diff --git a/crates/sncast/Cargo.toml b/crates/sncast/Cargo.toml index ce661ff32c..3319c1a9ae 100644 --- a/crates/sncast/Cargo.toml +++ b/crates/sncast/Cargo.toml @@ -56,6 +56,7 @@ serde_path_to_error.workspace = true walkdir.workspace = true const-hex.workspace = true regex.workspace = true +dirs.workspace = true [dev-dependencies] ctor.workspace = true diff --git a/crates/sncast/src/helpers/config.rs b/crates/sncast/src/helpers/config.rs new file mode 100644 index 0000000000..0ef8e9392a --- /dev/null +++ b/crates/sncast/src/helpers/config.rs @@ -0,0 +1,115 @@ +use crate::helpers::configuration::{show_explorer_links_default, CastConfig}; +use crate::helpers::constants::DEFAULT_ACCOUNTS_FILE; +use crate::ValidatedWaitParams; +use anyhow::Result; +use camino::Utf8PathBuf; +use indoc::formatdoc; +use shared::consts::FREE_RPC_PROVIDER_URL; +use std::fs; +use std::fs::File; +use std::io::Write; + +pub fn get_global_config_path() -> Result { + let global_config_dir = { + if cfg!(target_os = "windows") { + dirs::config_dir() + .ok_or_else(|| anyhow::anyhow!("Could not determine config directory"))? + .join("starknet-foundry") + } else { + dirs::home_dir() + .ok_or_else(|| anyhow::anyhow!("Could not determine home directory"))? + .join(".config/starknet-foundry") + } + }; + + if !global_config_dir.exists() { + fs::create_dir_all(&global_config_dir)?; + } + + let global_config_path = Utf8PathBuf::from_path_buf(global_config_dir.join("snfoundry.toml")) + .expect("Failed to convert PathBuf to Utf8PathBuf for global configuration"); + + if !global_config_path.exists() { + create_global_config(global_config_path.clone())?; + } + + Ok(global_config_path) +} + +fn build_default_manifest() -> String { + let default_wait_params = ValidatedWaitParams::default(); + + formatdoc! {r#" + # Visit https://foundry-rs.github.io/starknet-foundry/appendix/snfoundry-toml.html + # and https://foundry-rs.github.io/starknet-foundry/projects/configuration.html for more information + + # [sncast.default] + # url = "{default_url}" + # block-explorer = "{default_block_explorer}" + # wait-params = {{ timeout = {default_wait_timeout}, retry-interval = {default_wait_retry_interval} }} + # show-explorer-links = {default_show_explorer_links} + # accounts-file = "{default_accounts_file}" + # account = "{default_account}" + # keystore = "{default_keystore}" + "#, + default_url = FREE_RPC_PROVIDER_URL, + default_accounts_file = DEFAULT_ACCOUNTS_FILE, + default_wait_timeout = default_wait_params.timeout, + default_wait_retry_interval = default_wait_params.retry_interval, + default_block_explorer = "StarkScan", + default_show_explorer_links = show_explorer_links_default(), + default_account = "default", + default_keystore = "" + } +} + +fn create_global_config(global_config_path: Utf8PathBuf) -> Result<()> { + let mut file = File::create(global_config_path)?; + file.write_all(build_default_manifest().as_bytes())?; + + Ok(()) +} +macro_rules! clone_field { + ($global_config:expr, $local_config:expr, $default_config:expr, $field:ident) => { + if $local_config.$field != $default_config.$field { + $local_config.$field.clone() + } else { + $global_config.$field.clone() + } + }; +} + +#[must_use] +pub fn combine_cast_configs(global_config: &CastConfig, local_config: &CastConfig) -> CastConfig { + let default_cast_config = CastConfig::default(); + + CastConfig { + url: clone_field!(global_config, local_config, default_cast_config, url), + account: clone_field!(global_config, local_config, default_cast_config, account), + accounts_file: clone_field!( + global_config, + local_config, + default_cast_config, + accounts_file + ), + keystore: clone_field!(global_config, local_config, default_cast_config, keystore), + wait_params: clone_field!( + global_config, + local_config, + default_cast_config, + wait_params + ), + block_explorer: clone_field!( + global_config, + local_config, + default_cast_config, + block_explorer + ), + show_explorer_links: clone_field!( + global_config, + local_config, + default_cast_config, + show_explorer_links + ), + } +} diff --git a/crates/sncast/src/helpers/configuration.rs b/crates/sncast/src/helpers/configuration.rs index c2603233bc..43d694b473 100644 --- a/crates/sncast/src/helpers/configuration.rs +++ b/crates/sncast/src/helpers/configuration.rs @@ -1,12 +1,12 @@ +use super::block_explorer; use crate::ValidatedWaitParams; use anyhow::Result; use camino::Utf8PathBuf; -use configuration::GlobalConfig; +use configuration::Config; use serde::{Deserialize, Serialize}; -use super::block_explorer; - -const fn show_explorer_links_default() -> bool { +#[must_use] +pub const fn show_explorer_links_default() -> bool { true } @@ -57,12 +57,12 @@ impl Default for CastConfig { keystore: None, wait_params: ValidatedWaitParams::default(), block_explorer: Some(block_explorer::Service::default()), - show_explorer_links: true, + show_explorer_links: show_explorer_links_default(), } } } -impl GlobalConfig for CastConfig { +impl Config for CastConfig { #[must_use] fn tool_name() -> &'static str { "sncast" diff --git a/crates/sncast/src/helpers/mod.rs b/crates/sncast/src/helpers/mod.rs index b9ac734f9e..c88c105765 100644 --- a/crates/sncast/src/helpers/mod.rs +++ b/crates/sncast/src/helpers/mod.rs @@ -1,5 +1,6 @@ pub mod block_explorer; pub mod braavos; +pub mod config; pub mod configuration; pub mod constants; pub mod error; diff --git a/crates/sncast/src/main.rs b/crates/sncast/src/main.rs index d5b7d012b2..8effdafb05 100644 --- a/crates/sncast/src/main.rs +++ b/crates/sncast/src/main.rs @@ -1,11 +1,8 @@ -use crate::starknet_commands::account::Account; -use crate::starknet_commands::show_config::ShowConfig; use crate::starknet_commands::{ - account, call::Call, declare::Declare, deploy::Deploy, invoke::Invoke, multicall::Multicall, - script::Script, tx_status::TxStatus, + account, account::Account, call::Call, declare::Declare, deploy::Deploy, invoke::Invoke, + multicall::Multicall, script::Script, show_config::ShowConfig, tx_status::TxStatus, }; use anyhow::{Context, Result}; -use configuration::load_global_config; use data_transformer::Calldata; use sncast::response::explorer_link::print_block_explorer_link_if_allowed; use sncast::response::print::{print_command_result, OutputFormat}; @@ -13,6 +10,8 @@ use sncast::response::print::{print_command_result, OutputFormat}; use crate::starknet_commands::deploy::DeployArguments; use camino::Utf8PathBuf; use clap::{Parser, Subcommand}; +use configuration::load_config; +use sncast::helpers::config::{combine_cast_configs, get_global_config_path}; use sncast::helpers::configuration::CastConfig; use sncast::helpers::constants::{DEFAULT_ACCOUNTS_FILE, DEFAULT_MULTICALL_CONTENTS}; use sncast::helpers::fee::PayableTransaction; @@ -209,8 +208,7 @@ fn main() -> Result<()> { if let Commands::Script(script) = &cli.command { run_script_command(&cli, runtime, script, numbers_format, output_format) } else { - let mut config = load_global_config::(&None, &cli.profile)?; - update_cast_config(&mut config, &cli); + let config = get_cast_config(&cli)?; runtime.block_on(run_async_command( cli, @@ -657,11 +655,8 @@ fn run_script_command( let manifest_path = assert_manifest_path_exists()?; let package_metadata = get_package_metadata(&manifest_path, &run.package)?; - let mut config = load_global_config::( - &Some(package_metadata.root.clone()), - &cli.profile, - )?; - update_cast_config(&mut config, cli); + let config = get_cast_config(cli)?; + let provider = runtime.block_on(run.rpc.get_provider(&config))?; let mut artifacts = build_and_load_artifacts( @@ -715,7 +710,7 @@ fn run_script_command( Ok(()) } -fn update_cast_config(config: &mut CastConfig, cli: &Cli) { +fn config_with_cli(config: &mut CastConfig, cli: &Cli) { macro_rules! clone_or_else { ($field:expr, $config_field:expr) => { $field.clone().unwrap_or_else(|| $config_field.clone()) @@ -740,3 +735,20 @@ fn update_cast_config(config: &mut CastConfig, cli: &Cli) { clone_or_else!(cli.wait_timeout, config.wait_params.get_timeout()), ); } + +fn get_cast_config(cli: &Cli) -> Result { + let global_config_path = get_global_config_path().unwrap_or_else(|err| { + eprintln!("Error getting global config path: {err}"); + Utf8PathBuf::new() + }); + + let global_config = load_config::(&Some(global_config_path.clone()), &cli.profile) + .unwrap_or_else(|_| load_config::(&Some(global_config_path), &None).unwrap()); + + let local_config = load_config::(&None, &cli.profile)?; + + let mut combined_config = combine_cast_configs(&global_config, &local_config); + + config_with_cli(&mut combined_config, cli); + Ok(combined_config) +} diff --git a/crates/sncast/src/response/structs.rs b/crates/sncast/src/response/structs.rs index cd28b0020c..33c4e15d52 100644 --- a/crates/sncast/src/response/structs.rs +++ b/crates/sncast/src/response/structs.rs @@ -1,4 +1,5 @@ use super::explorer_link::OutputLink; +use crate::helpers::block_explorer; use crate::helpers::block_explorer::LinkProvider; use camino::Utf8PathBuf; use conversions::padded_felt::PaddedFelt; @@ -115,6 +116,7 @@ pub struct ShowConfigResponse { pub wait_timeout: Option, pub wait_retry_interval: Option, pub show_explorer_links: bool, + pub block_explorer: Option, } impl CommandResponse for ShowConfigResponse {} diff --git a/crates/sncast/src/starknet_commands/account/mod.rs b/crates/sncast/src/starknet_commands/account/mod.rs index d507a39317..dc32f53a87 100644 --- a/crates/sncast/src/starknet_commands/account/mod.rs +++ b/crates/sncast/src/starknet_commands/account/mod.rs @@ -7,7 +7,7 @@ use anyhow::{anyhow, bail, Context, Result}; use camino::Utf8PathBuf; use clap::{Args, Subcommand, ValueEnum}; use configuration::{ - find_config_file, load_global_config, search_config_upwards_relative_to, CONFIG_FILENAME, + find_config_file, load_config, search_config_upwards_relative_to, CONFIG_FILENAME, }; use serde_json::json; use sncast::{chain_id_to_network_name, decode_chain_id, helpers::configuration::CastConfig}; @@ -128,7 +128,7 @@ pub fn add_created_profile_to_configuration( cast_config: &CastConfig, path: &Option, ) -> Result<()> { - if !load_global_config::(path, profile) + if !load_config::(path, profile) .unwrap_or_default() .account .is_empty() diff --git a/crates/sncast/src/starknet_commands/show_config.rs b/crates/sncast/src/starknet_commands/show_config.rs index 4d54ca6291..fafbe6b59a 100644 --- a/crates/sncast/src/starknet_commands/show_config.rs +++ b/crates/sncast/src/starknet_commands/show_config.rs @@ -39,6 +39,7 @@ pub async fn show_config( } let wait_timeout = Some(cast_config.wait_params.get_timeout()); let wait_retry_interval = Some(cast_config.wait_params.get_retry_interval()); + let block_explorer = cast_config.block_explorer; Ok(ShowConfigResponse { profile, @@ -50,5 +51,6 @@ pub async fn show_config( wait_timeout: wait_timeout.map(|x| Decimal(u64::from(x))), wait_retry_interval: wait_retry_interval.map(|x| Decimal(u64::from(x))), show_explorer_links: cast_config.show_explorer_links, + block_explorer, }) } diff --git a/crates/sncast/tests/e2e/main_tests.rs b/crates/sncast/tests/e2e/main_tests.rs index 960bac8a63..c52510cb1d 100644 --- a/crates/sncast/tests/e2e/main_tests.rs +++ b/crates/sncast/tests/e2e/main_tests.rs @@ -169,29 +169,6 @@ async fn test_missing_account_flag() { ); } -#[tokio::test] -async fn test_missing_url() { - let args = vec![ - "--accounts-file", - ACCOUNT_FILE_PATH, - "--account", - ACCOUNT, - "declare", - "--contract-name", - "whatever", - "--fee-token", - "eth", - ]; - - let snapbox = runner(&args); - let output = snapbox.assert().failure(); - - assert_stderr_contains( - output, - "Error: RPC url not passed nor found in snfoundry.toml", - ); -} - #[tokio::test] async fn test_inexistent_keystore() { let args = vec![ diff --git a/docs/src/appendix/sncast/account/create.md b/docs/src/appendix/sncast/account/create.md index 01d1b895a1..f102c2424a 100644 --- a/docs/src/appendix/sncast/account/create.md +++ b/docs/src/appendix/sncast/account/create.md @@ -37,7 +37,7 @@ Salt for the account address. If omitted random one will be generated. ## `--add-profile ` Optional. -If passed, a profile with corresponding name will be added to snfoundry.toml. +If passed, a profile with corresponding name will be added to the local snfoundry.toml. ## `--class-hash, -c` Optional. diff --git a/docs/src/appendix/sncast/account/import.md b/docs/src/appendix/sncast/account/import.md index aa990f74de..e1ad3c0715 100644 --- a/docs/src/appendix/sncast/account/import.md +++ b/docs/src/appendix/sncast/account/import.md @@ -49,4 +49,4 @@ Salt for the account address. ## `--add-profile ` Optional. -If passed, a profile with corresponding name will be added to snfoundry.toml. +If passed, a profile with corresponding name will be added to the local snfoundry.toml. diff --git a/docs/src/appendix/snfoundry-toml.md b/docs/src/appendix/snfoundry-toml.md index 9f0847f90b..296c0f3aed 100644 --- a/docs/src/appendix/snfoundry-toml.md +++ b/docs/src/appendix/snfoundry-toml.md @@ -25,19 +25,19 @@ The `url` field specifies the address of RPC provider. url = "http://example.com" ``` -#### `accounts_file` +#### `accounts-file` -The `accounts_file` field specifies the path to a file containing account information. +The `accounts-file` field specifies the path to a file containing account information. If not provided, the default path is `~/.starknet_accounts/starknet_open_zeppelin_accounts.json`. ```toml [sncast.myprofile] -accounts_file = "path/to/accounts.json" +accounts-file = "path/to/accounts.json" ``` #### `account` -The `account` field specifies which account from the `accounts_file` to use for transactions. +The `account` field specifies which account from the `accounts-file` to use for transactions. ```toml [sncast.myprofile] @@ -53,19 +53,27 @@ The `keystore` field specifies the path to the keystore file. keystore = "path/to/keystore" ``` -#### `wait_params` +#### `wait-params` -The `wait_params` field defines the waiting parameters for transactions. By default, timeout (in seconds) is set to `300` and retry_interval (in seconds) to `5`. +The `wait-params` field defines the waiting parameters for transactions. By default, timeout (in seconds) is set to `300` and retry-interval (in seconds) to `5`. This means transactions will be checked every `5 seconds`, with a total of `60 attempts` before timing out. ```toml [sncast.myprofile] -wait_params = { timeout = 300, retry-interval = 5 } +wait-params = { timeout = 300, retry-interval = 5 } ``` -#### `block_explorer` +#### `show-explorer-links` +Enable printing links pointing to pages with transaction details in the chosen block explorer -The `block_explorer` field specifies the block explorer service used to display links to transaction details. +```toml +[sncast.myprofile] +show-explorer-links = true +``` + +#### `block-explorer` + +The `block-explorer` field specifies the block explorer service used to display links to transaction details. | Value | URL | |-----------|----------------------------------------| @@ -77,7 +85,7 @@ The `block_explorer` field specifies the block explorer service used to display ```toml [sncast.myprofile] -block_explorer = "StarkScan" +block-explorer = "StarkScan" ``` #### Complete Example of `snfoundry.toml` File @@ -85,11 +93,12 @@ block_explorer = "StarkScan" ```toml [sncast.myprofile1] url = "http://127.0.0.1:5050/" -accounts_file = "../account-file" +accounts-file = "../account-file" account = "mainuser" keystore = "~/keystore" -wait_params = { timeout = 500, retry_interval = 10 } -block_explorer = "StarkScan" +wait-params = { timeout = 500, retry-interval = 10 } +block-explorer = "StarkScan" +show-explorer-links = true [sncast.dev] url = "http://127.0.0.1:5056/rpc" diff --git a/docs/src/projects/configuration.md b/docs/src/projects/configuration.md index 8794cc1cd5..cf857d4840 100644 --- a/docs/src/projects/configuration.md +++ b/docs/src/projects/configuration.md @@ -105,7 +105,62 @@ response: [0x1, 0x23, 0x4]

-## Environmental variables +### Global Configuration + +Global configuration file is a [`snfoundry.toml`](https://foundry-rs.github.io/starknet-foundry/appendix/snfoundry-toml.html), +which is a common storage for configurations to apply to multiple projects across various directories. +This file is stored in a predefined location and is used to store profiles that can be used from any location on your computer. + +#### Interaction Between Local and Global Profiles + +Global config can be overridden by a local config. + +If both local and global profiles with the same name are present, local profile will be combined with global profile. For any setting defined in both profiles, the local setting will take precedence. For settings not defined in the local profile, values from the corresponding global profile will be used, or if not defined, values from the global default profile will be used instead. + +This same behavior applies for [default profiles](#default-profile) as well. A local default profile will override a global default profile. + +> 📝 **Note** +> Remember that arguments passed in the CLI have the highest priority and will always override the configuration file settings. + + +#### Global Configuration File Location +The global configuration is stored in a specific location depending on the operating system: + +- macOS/Linux : The global configuration file is located at `$HOME/.config/starknet-foundry/snfoundry.toml` +- Windows : The file can be found at `C:\Users\\AppData\Roaming\starknet-foundry\snfoundry.toml` + +> 📝 **Note** +> If missing, global configuration file will be created automatically on running any `sncast` command for the first time. + +### Config Interaction Example + +``` +root/ +├── .config/ +│ └── starknet-foundry/ +│ └── snfoundry.toml -> A +└── /../../ + └── projects/ + ├── snfoundry.toml -> B + └── cairo-projects/ + └── opus-magnum/ +``` + +**Glossary:** + +- **A:** Global configuration file containing the profiles [`default`](#default-profile) and [`testnet`](#defining-profiles-in-snfoundrytoml). +- **B:** Local configuration file containing the profiles `default` and `mainnet`. + +In any directory in the file system, a user can run the `sncast` command using the `default` and `testnet` profiles, +because they are defined in global config (file A). + +If no profiles are explicitly specified, the `default` profile from the global configuration file will be used. + +When running `sncast` from the `opus-magnum` directory, there is a configuration file in the parent directory (file B). +This setup allows for the use of the following profiles: `default`, `testnet`, and `mainnet`. If the `mainnet` profile is specified, +the configuration from the local file will be used to override the global `default` profile, as the `mainnet` profile does not exist in the global configuration. + +## Environmental Variables Programmers can use environmental variables in both `Scarb.toml::tool::snforge` and in `snfoundry.toml`. To use an environmental variable as a value, use its name prefixed with `$`. This might be useful, for example, to hide node urls in the public repositories. From 76ac22ebc84ef6757040c750dd8fb011af2865af Mon Sep 17 00:00:00 2001 From: ksew1 <95349104+ksew1@users.noreply.github.com> Date: Tue, 26 Nov 2024 11:06:25 +0000 Subject: [PATCH 11/23] Add backtrace docs (#2699) Related https://github.com/foundry-rs/starknet-foundry/issues/2468 ## Introduced changes - Added backtrace docs ## Checklist - [x] Linked relevant issue - [x] Updated relevant documentation - [x] Added relevant tests - [x] Performed self-review of the code - [x] Added changes to `CHANGELOG.md` --- docs/src/SUMMARY.md | 1 + .../snforge-advanced-features/backtrace.md | 89 +++++++++++++++++++ docs/src/testing/testing.md | 2 + 3 files changed, 92 insertions(+) create mode 100644 docs/src/snforge-advanced-features/backtrace.md diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 8bdcece5ad..aa294b1189 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -36,6 +36,7 @@ * [Conditional Compilation](snforge-advanced-features/conditional-compilation.md) * [Direct Storage Access](snforge-advanced-features/storage-cheatcodes.md) * [Profiling](snforge-advanced-features/profiling.md) +* [Backtrace](snforge-advanced-features/backtrace.md) --- diff --git a/docs/src/snforge-advanced-features/backtrace.md b/docs/src/snforge-advanced-features/backtrace.md new file mode 100644 index 0000000000..4819dbc227 --- /dev/null +++ b/docs/src/snforge-advanced-features/backtrace.md @@ -0,0 +1,89 @@ +# Backtrace + +## Prerequisites + +Backtrace feature relies on debug information provided by Scarb. To generate the necessary debug information, you need +to have: + +1. [Scarb](https://github.com/software-mansion/scarb) version `2.8.0` or higher +2. `Scarb.toml` file with the following Cairo compiler configuration: + +```toml +[profile.dev.cairo] +unstable-add-statements-code-locations-debug-info = true +unstable-add-statements-functions-debug-info = true +``` + +## Usage + +> 📝 **Note** +> Currently, only the last line of failure in each contract is guaranteed to appear in the backtrace. The complete call +> tree is not fully supported yet; however, in most cases, it will be available. It internally relies on the inlining +> behavior of the compiler, and a full backtrace is available if all functions are inlined. To obtain a more detailed +> backtrace, ensure that +> your [inlining strategy](https://docs.swmansion.com/scarb/docs/reference/manifest.html#inlining-strategy) in +`Scarb.toml` is set to `default`. + +When a contract call fails, the error message alone may not always provide enough information to identify the root cause +of the issue. To aid in debugging, `snforge` offers a feature that can generate a backtrace of the execution. + +If your contract fails and a backtrace can be generated, `snforge` will prompt you to run the operation again with the +`SNFORGE_BACKTRACE=1` environment variable (if it’s not already configured). For example, you may see failure data like +this: + + + + + +```shell +$ snforge test +``` +
+Output: + +```shell +Failure data: + (0x454e545259504f494e545f4e4f545f464f554e44 ('ENTRYPOINT_NOT_FOUND'), 0x454e545259504f494e545f4641494c4544 ('ENTRYPOINT_FAILED')) +note: run with `SNFORGE_BACKTRACE=1` environment variable to display a backtrace +``` +
+
+ + +To enable backtraces, simply set the `SNFORGE_BACKTRACE=1` environment variable and rerun the operation. + +When enabled, the backtrace will display the call tree of the execution, including the specific line numbers in the +contracts where the errors occurred. Here's an example of what you might see: + + +```shell +$ SNFORGE_BACKTRACE=1 snforge test +``` +
+Output: + +```shell +Failure data: + (0x454e545259504f494e545f4e4f545f464f554e44 ('ENTRYPOINT_NOT_FOUND'), 0x454e545259504f494e545f4641494c4544 ('ENTRYPOINT_FAILED')) + +Error occurred in contract 'InnerContract' at pc: '72' +Stack backtrace: + 0: backtrace_vm_error::InnerContract::inner_call + at [..]/src/lib.cairo:47:9 + 1: backtrace_vm_error::InnerContract::InnerContract::inner + at [..]/src/lib.cairo:38:13 + 2: backtrace_vm_error::InnerContract::__wrapper__InnerContract__inner + at [..]/src/lib.cairo:37:9 + +Error occurred in contract 'OuterContract' at pc: '107' +Stack backtrace: + 0: backtrace_vm_error::IInnerContractDispatcherImpl::inner + at [..]/src/lib.cairo:22:1 + 1: backtrace_vm_error::OuterContract::OuterContract::outer + at [..]/src/lib.cairo:17:13 + 2: backtrace_vm_error::OuterContract::__wrapper__OuterContract__outer + at [..]/src/lib.cairo:15:9 +``` +
+
+ diff --git a/docs/src/testing/testing.md b/docs/src/testing/testing.md index 80e1c8a4a8..bfc6a953ee 100644 --- a/docs/src/testing/testing.md +++ b/docs/src/testing/testing.md @@ -66,6 +66,8 @@ Failures:

+When contract fails, you can get backtrace information by setting the `SNFORGE_BACKTRACE=1` environment variable. Read more about it [here](../snforge-advanced-features/backtrace.md). + ## Expected Failures Sometimes you want to mark a test as expected to fail. This is useful when you want to verify that an action fails as From 63447bbde8c9ad647ab3f8086968347a30519892 Mon Sep 17 00:00:00 2001 From: Franciszek Job <54181625+franciszekjob@users.noreply.github.com> Date: Tue, 26 Nov 2024 12:30:08 +0100 Subject: [PATCH 12/23] Add example for `storage_address_from_base` usage (#2705) Closes #2439 ## Introduced changes Update example for `storage_address_from_base` usage in storage cheatcodes docs ## Checklist - [x] Linked relevant issue - [x] Updated relevant documentation - [x] Added relevant tests - [x] Performed self-review of the code - [x] Added changes to `CHANGELOG.md` --- .../src/felts_only.cairo | 11 +++++-- .../direct_storage_access/tests/lib.cairo | 1 + .../using_storage_address_from_base.cairo | 31 +++++++++++++++++++ .../storage-cheatcodes.md | 7 +++++ 4 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 docs/listings/snforge_advanced_features/crates/direct_storage_access/tests/using_storage_address_from_base.cairo diff --git a/docs/listings/snforge_advanced_features/crates/direct_storage_access/src/felts_only.cairo b/docs/listings/snforge_advanced_features/crates/direct_storage_access/src/felts_only.cairo index 82ad3d9511..9d0104e863 100644 --- a/docs/listings/snforge_advanced_features/crates/direct_storage_access/src/felts_only.cairo +++ b/docs/listings/snforge_advanced_features/crates/direct_storage_access/src/felts_only.cairo @@ -1,8 +1,10 @@ #[starknet::interface] -pub trait ISimpleStorageContract {} +pub trait ISimpleStorageContract { + fn get_value(self: @TState, key: felt252) -> felt252; +} #[starknet::contract] -mod SimpleStorageContract { +pub mod SimpleStorageContract { use starknet::storage::Map; #[storage] @@ -16,4 +18,9 @@ mod SimpleStorageContract { self.plain_felt.write(0x2137_felt252); self.mapping.write('some_key', 'some_value'); } + + #[external(v0)] + pub fn get_value(self: @ContractState, key: felt252) -> felt252 { + self.mapping.read(key) + } } diff --git a/docs/listings/snforge_advanced_features/crates/direct_storage_access/tests/lib.cairo b/docs/listings/snforge_advanced_features/crates/direct_storage_access/tests/lib.cairo index 628d3a5239..f667aaf500 100644 --- a/docs/listings/snforge_advanced_features/crates/direct_storage_access/tests/lib.cairo +++ b/docs/listings/snforge_advanced_features/crates/direct_storage_access/tests/lib.cairo @@ -1,3 +1,4 @@ pub mod felts_only; pub mod complex_structures; pub mod storage_address; +pub mod using_storage_address_from_base; diff --git a/docs/listings/snforge_advanced_features/crates/direct_storage_access/tests/using_storage_address_from_base.cairo b/docs/listings/snforge_advanced_features/crates/direct_storage_access/tests/using_storage_address_from_base.cairo new file mode 100644 index 0000000000..8d8e26576b --- /dev/null +++ b/docs/listings/snforge_advanced_features/crates/direct_storage_access/tests/using_storage_address_from_base.cairo @@ -0,0 +1,31 @@ +use starknet::storage::StorageAsPointer; +use starknet::storage::StoragePathEntry; + +use snforge_std::{declare, ContractClassTrait, DeclareResultTrait, store, load}; +use starknet::storage_access::{storage_address_from_base}; + +use direct_storage_access::felts_only::{ + SimpleStorageContract, ISimpleStorageContractDispatcher, ISimpleStorageContractDispatcherTrait +}; + +#[test] +fn update_mapping() { + let key = 0; + let data = 100; + let (contract_address, _) = declare("SimpleStorageContract") + .unwrap() + .contract_class() + .deploy(@array![]) + .unwrap(); + let dispatcher = ISimpleStorageContractDispatcher { contract_address }; + let mut state = SimpleStorageContract::contract_state_for_testing(); + + let storage_address = storage_address_from_base( + state.mapping.entry(key).as_ptr().__storage_pointer_address__.into() + ); + let storage_value: Span = array![data.into()].span(); + store(contract_address, storage_address.into(), storage_value); + + let read_data = dispatcher.get_value(key.into()); + assert_eq!(read_data, data, "Storage update failed") +} diff --git a/docs/src/snforge-advanced-features/storage-cheatcodes.md b/docs/src/snforge-advanced-features/storage-cheatcodes.md index 7127d92dd3..37c2e509f8 100644 --- a/docs/src/snforge-advanced-features/storage-cheatcodes.md +++ b/docs/src/snforge-advanced-features/storage-cheatcodes.md @@ -49,3 +49,10 @@ And perform a test checking `load` and `store` behavior in context of those stru > 📝 **Note** > > The `load` cheatcode will return zeros for memory you haven't written into yet (it is a default storage value for Starknet contracts' storage). + +## Example with `storage_address_from_base` +This example uses `storage_address_from_base` with entry's of the storage variable. + +```rust +{{#include ../../listings/snforge_advanced_features/crates/direct_storage_access/tests/using_storage_address_from_base.cairo}} +``` \ No newline at end of file From d6976d4635cbe69bd199fd502788c469d408ed2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Artur=20Micha=C5=82ek?= <52135326+cptartur@users.noreply.github.com> Date: Tue, 26 Nov 2024 16:22:32 +0100 Subject: [PATCH 13/23] Release 0.34.0 (#2715) Closes # ## Introduced changes - ## Checklist - [ ] Linked relevant issue - [ ] Updated relevant documentation - [ ] Added relevant tests - [ ] Performed self-review of the code - [ ] Added changes to `CHANGELOG.md` --- CHANGELOG.md | 3 ++- Cargo.lock | 10 +++++----- Cargo.toml | 2 +- crates/sncast/tests/e2e/script/general.rs | 2 +- crates/snforge-scarb-plugin/Scarb.toml | 2 +- sncast_std/Scarb.lock | 2 +- sncast_std/Scarb.toml | 2 +- snforge_std/Scarb.lock | 4 ++-- snforge_std/Scarb.toml | 2 +- 9 files changed, 15 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5658544768..acef01e233 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.34.0] - 2024-11-26 + ### Forge #### Added @@ -25,7 +27,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - You can skip `--name` flag when using `account import` - a default name will be generated. - Addresses outputted when calling `sncast account create`, `sncast deploy` and `sncast declare` are now padded to 64 characters length and prefixed with `0x0` - Globally available configuration to store profiles to share between projects. -- Missing fields in `show-config` command, `block_explorer` and `show_explorer_links`. #### Changed diff --git a/Cargo.lock b/Cargo.lock index 7c4db0a47a..b1141f08e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1891,7 +1891,7 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "docs" -version = "0.33.0" +version = "0.34.0" dependencies = [ "regex", "shell-words", @@ -2138,7 +2138,7 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "forge" -version = "0.33.0" +version = "0.34.0" dependencies = [ "anyhow", "ark-ff", @@ -2210,7 +2210,7 @@ dependencies = [ [[package]] name = "forge_runner" -version = "0.33.0" +version = "0.34.0" dependencies = [ "anyhow", "bimap", @@ -4890,7 +4890,7 @@ dependencies = [ [[package]] name = "sncast" -version = "0.33.0" +version = "0.34.0" dependencies = [ "anyhow", "async-trait", @@ -4955,7 +4955,7 @@ dependencies = [ [[package]] name = "snforge_scarb_plugin" -version = "0.33.0" +version = "0.34.0" dependencies = [ "cairo-lang-diagnostics", "cairo-lang-filesystem", diff --git a/Cargo.toml b/Cargo.toml index 680ec6dcab..694ea4aaae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ members = [ ] [workspace.package] -version = "0.33.0" +version = "0.34.0" edition = "2021" repository = "https://github.com/foundry-rs/starknet-foundry" license = "MIT" diff --git a/crates/sncast/tests/e2e/script/general.rs b/crates/sncast/tests/e2e/script/general.rs index 5b3f0727d0..5b82923645 100644 --- a/crates/sncast/tests/e2e/script/general.rs +++ b/crates/sncast/tests/e2e/script/general.rs @@ -135,7 +135,7 @@ async fn test_incompatible_sncast_std_version() { snapbox.assert().success().stdout_matches(indoc! {r" ... - [WARNING] Package sncast_std version does not meet the recommended version requirement =0.33.0, it might result in unexpected behaviour + [WARNING] Package sncast_std version does not meet the recommended version requirement =0.34.0, it might result in unexpected behaviour ... "}); } diff --git a/crates/snforge-scarb-plugin/Scarb.toml b/crates/snforge-scarb-plugin/Scarb.toml index 3fceabef79..64519161c6 100644 --- a/crates/snforge-scarb-plugin/Scarb.toml +++ b/crates/snforge-scarb-plugin/Scarb.toml @@ -1,6 +1,6 @@ [package] name = "snforge_scarb_plugin" -version = "0.33.1" +version = "0.34.0" edition = "2024_07" [cairo-plugin] diff --git a/sncast_std/Scarb.lock b/sncast_std/Scarb.lock index 8f3a361385..0cf0672dbc 100644 --- a/sncast_std/Scarb.lock +++ b/sncast_std/Scarb.lock @@ -3,4 +3,4 @@ version = 1 [[package]] name = "sncast_std" -version = "0.33.0" +version = "0.34.0" diff --git a/sncast_std/Scarb.toml b/sncast_std/Scarb.toml index 2a5f3baf24..c78e7e2b71 100644 --- a/sncast_std/Scarb.toml +++ b/sncast_std/Scarb.toml @@ -1,6 +1,6 @@ [package] name = "sncast_std" -version = "0.33.0" +version = "0.34.0" edition = "2023_11" description = "Library used for writing deployment scripts in Cairo" homepage = "https://foundry-rs.github.io/starknet-foundry/starknet/script.html" diff --git a/snforge_std/Scarb.lock b/snforge_std/Scarb.lock index d7f0c48a44..1d45c2d1b6 100644 --- a/snforge_std/Scarb.lock +++ b/snforge_std/Scarb.lock @@ -3,11 +3,11 @@ version = 1 [[package]] name = "snforge_scarb_plugin" -version = "0.33.0" +version = "0.34.0" [[package]] name = "snforge_std" -version = "0.33.0" +version = "0.34.0" dependencies = [ "snforge_scarb_plugin", ] diff --git a/snforge_std/Scarb.toml b/snforge_std/Scarb.toml index bf2f21a52e..188602ef5d 100644 --- a/snforge_std/Scarb.toml +++ b/snforge_std/Scarb.toml @@ -1,6 +1,6 @@ [package] name = "snforge_std" -version = "0.33.0" +version = "0.34.0" edition = "2023_10" description = "Cairo testing library" documentation = "https://foundry-rs.github.io/starknet-foundry/appendix/snforge-library.html" From 7c632c2c70af171ca4861dd93b93ade48a5db3cd Mon Sep 17 00:00:00 2001 From: Franciszek Job <54181625+franciszekjob@users.noreply.github.com> Date: Tue, 26 Nov 2024 17:50:58 +0100 Subject: [PATCH 14/23] Use trace mode in `verify_cairo_listings.sh` (#2717) Closes # ## Introduced changes Allow trace mode while checking packages in `verify_cairo_listings.sh` ## Checklist - [x] Linked relevant issue - [x] Updated relevant documentation - [x] Added relevant tests - [x] Performed self-review of the code - [x] Added changes to `CHANGELOG.md` --- scripts/verify_cairo_listings.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/verify_cairo_listings.sh b/scripts/verify_cairo_listings.sh index 6f5f4245c3..87d31a3f72 100755 --- a/scripts/verify_cairo_listings.sh +++ b/scripts/verify_cairo_listings.sh @@ -1,4 +1,4 @@ #!/bin/bash -set -e +set -xe for d in ./docs/listings/*; do (cd "$d" && scarb test); done From 43a1ad114a275c23663b1900c59afc4cf68d1a6d Mon Sep 17 00:00:00 2001 From: Franciszek Job <54181625+franciszekjob@users.noreply.github.com> Date: Wed, 27 Nov 2024 12:13:30 +0100 Subject: [PATCH 15/23] Validate forge command outputs in docs (#2687) Relates #2479 Closes #2684 ## Introduced changes - Automatically run snforge commands which are present in the docc; if the output of respective output is present in the docs too, it's compared with the actual output from executed command - Allow ignoring commands (so they will not be executed) ## Checklist - [x] Linked relevant issue - [x] Updated relevant documentation - [x] Added relevant tests - [x] Performed self-review of the code - [x] Added changes to `CHANGELOG.md` --------- Co-authored-by: ddoktorski <45050160+ddoktorski@users.noreply.github.com> --- Cargo.lock | 2 + crates/docs/Cargo.toml | 2 + crates/docs/src/lib.rs | 5 + crates/docs/src/snippet.rs | 89 ++++++++++++++++ crates/docs/src/utils.rs | 41 +++++++ crates/docs/src/validation.rs | 100 +++++------------- crates/forge/tests/e2e/common/runner.rs | 47 ++++++-- .../tests/e2e/docs_snippets_validation.rs | 56 ++++++---- .../sncast/tests/docs_snippets/validation.rs | 54 ++++------ .../scripts => }/basic_example/Scarb.toml | 6 +- .../basic_example/src/basic_example.cairo | 0 .../scripts => }/basic_example/src/lib.cairo | 0 .../scripts => }/call/Scarb.toml | 5 +- .../scripts => }/call/src/lib.cairo | 0 .../conditional_compilation/Scarb.toml | 8 +- .../src/contract.cairo | 0 .../src/function.cairo | 0 .../conditional_compilation/src/lib.cairo | 0 .../conditional_compilation/tests/test.cairo | 0 .../{sncast_overview => declare}/Scarb.toml | 12 +-- .../scripts => }/declare/src/lib.cairo | 0 .../scripts => }/deploy/Scarb.toml | 7 +- .../scripts => }/deploy/src/lib.cairo | 0 .../detailed_resources_example/Scarb.toml | 18 ++++ .../detailed_resources_example/src/lib.cairo | 25 +++++ .../tests/test_contract.cairo | 15 +++ .../direct_storage_access/Scarb.toml | 8 +- .../src/complex_structures.cairo | 0 .../src/felts_only.cairo | 0 .../direct_storage_access/src/lib.cairo | 0 .../tests/complex_structures.cairo | 0 .../tests/felts_only.cairo | 0 .../tests/felts_only/field.cairo | 0 .../tests/felts_only/map_entry.cairo | 0 .../direct_storage_access/tests/lib.cairo | 0 .../tests/storage_address.cairo | 0 .../using_storage_address_from_base.cairo | 0 .../scripts => }/error_handling/Scarb.toml | 8 +- .../error_handling/src/error_handling.cairo | 0 .../scripts => }/error_handling/src/lib.cairo | 0 docs/listings/failing_example/Scarb.toml | 18 ++++ docs/listings/failing_example/src/lib.cairo | 25 +++++ docs/listings/failing_example/tests/lib.cairo | 15 +++ .../scripts/declare => first_test}/Scarb.toml | 11 +- .../src/lib.cairo} | 0 .../crates => }/fork_testing/Scarb.toml | 8 +- .../crates => }/fork_testing/src/lib.cairo | 0 .../fork_testing/tests/explicit.cairo | 0 .../tests/explicit/block_hash.cairo | 0 .../tests/explicit/block_number.cairo | 0 .../tests/explicit/block_tag.cairo | 0 .../crates => }/fork_testing/tests/lib.cairo | 0 .../crates => }/fork_testing/tests/name.cairo | 0 .../fork_testing/tests/overridden_name.cairo | 0 .../scripts => }/full_example/Scarb.toml | 6 +- .../full_example/src/full_example.cairo | 0 .../scripts => }/full_example/src/lib.cairo | 0 .../crates => }/fuzz_testing/Scarb.toml | 7 +- .../fuzz_testing/src/basic_example.cairo | 0 .../crates => }/fuzz_testing/src/lib.cairo | 0 .../fuzz_testing/src/with_parameters.cairo | 0 .../scripts => }/get_nonce/Scarb.toml | 6 +- .../scripts => }/get_nonce/src/lib.cairo | 0 docs/listings/hello_snforge/Scarb.toml | 18 ++++ docs/listings/hello_snforge/src/lib.cairo | 25 +++++ .../hello_snforge/tests/test_contract.cairo | 14 +++ docs/listings/hello_starknet/Scarb.toml | 18 ++++ docs/listings/hello_starknet/src/lib.cairo | 25 +++++ .../hello_starknet/tests/test_contract.cairo | 47 ++++++++ docs/listings/hello_workspaces/Scarb.toml | 34 ++++++ .../crates/addition/Scarb.toml | 15 +++ .../crates/addition/src/lib.cairo | 33 ++++++ .../crates/addition/tests/nested.cairo | 17 +++ .../addition/tests/nested/test_nested.cairo | 12 +++ .../crates/fibonacci/Scarb.toml | 23 ++++ .../crates/fibonacci/src/lib.cairo | 39 +++++++ .../crates/fibonacci/tests/abc.cairo | 10 ++ .../crates/fibonacci/tests/abc/efg.cairo | 9 ++ .../crates/fibonacci/tests/lib.cairo | 6 ++ .../fibonacci/tests/not_collected.cairo | 6 ++ docs/listings/hello_workspaces/src/lib.cairo | 28 +++++ .../hello_workspaces/tests/test_failing.cairo | 9 ++ docs/listings/ignoring_example/Scarb.toml | 16 +++ docs/listings/ignoring_example/src/lib.cairo | 8 ++ .../{sncast_library => invoke}/Scarb.toml | 8 +- .../scripts => }/invoke/src/lib.cairo | 0 .../crates => }/map3/Scarb.toml | 4 +- .../{sncast_overview => map3}/snfoundry.toml | 0 .../crates => }/map3/src/lib.cairo | 0 docs/listings/panicking_test/Scarb.toml | 16 +++ .../src/lib.cairo} | 9 +- docs/listings/should_panic_example/Scarb.toml | 16 +++ .../should_panic_example/src/lib.cairo | 45 ++++++++ .../sncast_library/scripts/invoke/Scarb.toml | 15 --- docs/listings/sncast_overview/.gitignore | 1 - .../crates/testing_smart_contracts/Scarb.toml | 14 --- .../testing_smart_contracts/src/lib.cairo | 2 - .../crates/using_cheatcodes/Scarb.toml | 15 --- .../tests/caller_address.cairo | 5 - .../crates/writing_tests/Scarb.toml | 14 --- .../crates/writing_tests/src/lib.cairo | 2 - .../tests/expected_failures.cairo | 44 -------- .../crates/writing_tests/tests/ignoring.cairo | 4 - .../testing_contract_internals/Scarb.toml | 6 +- .../src/basic_example.cairo | 0 .../testing_contract_internals/src/lib.cairo | 0 .../src/spying_for_events.cairo | 0 .../src/using_library_calls.cairo | 0 .../tests/lib.cairo | 0 .../tests/mocking_the_context_info.cairo | 0 .../tests/spying_for_events.cairo | 0 .../spying_for_events/syscall_tests.cairo | 0 .../tests/spying_for_events/tests.cairo | 0 .../tests/using_library_calls.cairo | 0 .../crates => }/testing_events/Scarb.toml | 6 +- .../testing_events/src/contract.cairo | 0 .../crates => }/testing_events/src/lib.cairo | 0 .../testing_events/src/syscall.cairo | 0 .../testing_events/src/syscall_dummy.cairo | 0 .../testing_events/tests/assert_emitted.cairo | 0 .../tests/assert_manually.cairo | 0 .../testing_events/tests/filter.cairo | 0 .../testing_events/tests/syscall.cairo | 0 .../testing_messages_to_l1/Scarb.toml | 6 +- .../testing_messages_to_l1/src/lib.cairo | 0 .../tests/detailed.cairo | 0 .../testing_messages_to_l1/tests/lib.cairo | 0 .../testing_messages_to_l1/tests/simple.cairo | 0 .../Scarb.toml | 16 +++ .../src/lib.cairo} | 0 .../tests/handle_panic.cairo | 2 +- .../tests/panic.cairo | 3 +- .../Scarb.toml | 16 +++ .../src/lib.cairo | 26 +++++ .../tests/safe_dispatcher.cairo | 2 +- .../Scarb.toml | 16 +++ .../src/lib.cairo} | 0 .../tests/simple_contract.cairo | 2 +- .../scripts => }/tx_status/Scarb.toml | 6 +- .../scripts => }/tx_status/src/lib.cairo | 0 .../Scarb.toml | 12 ++- .../using_cheatcodes/src/lib.cairo | 0 .../tests/lib.cairo} | 7 -- .../Scarb.toml | 17 +++ .../src/lib.cairo | 55 ++++++++++ .../tests/lib.cairo} | 11 +- .../using_cheatcodes_cheat_address/Scarb.toml | 17 +++ .../src/lib.cairo | 55 ++++++++++ .../tests/lib.cairo} | 2 +- .../Scarb.toml | 10 +- .../using_cheatcodes_others/src/lib.cairo | 55 ++++++++++ .../tests/caller_address.cairo | 2 + .../caller_address/proper_use_global.cairo | 2 +- .../tests/caller_address/span.cairo | 4 +- .../tests/cheat_constructor.cairo | 2 +- .../tests/lib.cairo | 0 docs/src/appendix/sncast-library/call.md | 2 +- docs/src/appendix/sncast-library/declare.md | 2 +- docs/src/appendix/sncast-library/deploy.md | 2 +- docs/src/appendix/sncast-library/get_nonce.md | 2 +- docs/src/appendix/sncast-library/invoke.md | 2 +- docs/src/appendix/sncast-library/tx_status.md | 2 +- docs/src/getting-started/first-steps.md | 18 ++-- .../snforge-advanced-features/backtrace.md | 6 +- .../conditional-compilation.md | 6 +- .../snforge-advanced-features/fork-testing.md | 12 +-- .../snforge-advanced-features/fuzz-testing.md | 14 +-- .../storage-cheatcodes.md | 8 +- docs/src/starknet/account-import.md | 1 + docs/src/starknet/invoke.md | 4 +- docs/src/starknet/script.md | 8 +- docs/src/starknet/sncast-overview.md | 2 + docs/src/testing/contracts.md | 47 ++++---- .../testing/gas-and-resource-estimation.md | 23 ++-- docs/src/testing/running-tests.md | 72 +++++++------ .../src/testing/testing-contract-internals.md | 14 +-- docs/src/testing/testing-events.md | 12 +-- docs/src/testing/testing-messages-to-l1.md | 4 +- docs/src/testing/testing-workspaces.md | 89 ++++++++++++---- docs/src/testing/testing.md | 45 ++++---- docs/src/testing/using-cheatcodes.md | 39 ++++--- scripts/verify_cairo_listings.sh | 3 +- 182 files changed, 1503 insertions(+), 524 deletions(-) create mode 100644 crates/docs/src/snippet.rs create mode 100644 crates/docs/src/utils.rs rename docs/listings/{sncast_overview/scripts => }/basic_example/Scarb.toml (69%) rename docs/listings/{sncast_overview/scripts => }/basic_example/src/basic_example.cairo (100%) rename docs/listings/{sncast_overview/scripts => }/basic_example/src/lib.cairo (100%) rename docs/listings/{sncast_library/scripts => }/call/Scarb.toml (55%) rename docs/listings/{sncast_library/scripts => }/call/src/lib.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/conditional_compilation/Scarb.toml (68%) rename docs/listings/{snforge_advanced_features/crates => }/conditional_compilation/src/contract.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/conditional_compilation/src/function.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/conditional_compilation/src/lib.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/conditional_compilation/tests/test.cairo (100%) rename docs/listings/{sncast_overview => declare}/Scarb.toml (66%) rename docs/listings/{sncast_library/scripts => }/declare/src/lib.cairo (100%) rename docs/listings/{sncast_library/scripts => }/deploy/Scarb.toml (51%) rename docs/listings/{sncast_library/scripts => }/deploy/src/lib.cairo (100%) create mode 100644 docs/listings/detailed_resources_example/Scarb.toml create mode 100644 docs/listings/detailed_resources_example/src/lib.cairo create mode 100644 docs/listings/detailed_resources_example/tests/test_contract.cairo rename docs/listings/{snforge_advanced_features/crates => }/direct_storage_access/Scarb.toml (60%) rename docs/listings/{snforge_advanced_features/crates => }/direct_storage_access/src/complex_structures.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/direct_storage_access/src/felts_only.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/direct_storage_access/src/lib.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/direct_storage_access/tests/complex_structures.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/direct_storage_access/tests/felts_only.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/direct_storage_access/tests/felts_only/field.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/direct_storage_access/tests/felts_only/map_entry.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/direct_storage_access/tests/lib.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/direct_storage_access/tests/storage_address.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/direct_storage_access/tests/using_storage_address_from_base.cairo (100%) rename docs/listings/{sncast_overview/scripts => }/error_handling/Scarb.toml (65%) rename docs/listings/{sncast_overview/scripts => }/error_handling/src/error_handling.cairo (100%) rename docs/listings/{sncast_overview/scripts => }/error_handling/src/lib.cairo (100%) create mode 100644 docs/listings/failing_example/Scarb.toml create mode 100644 docs/listings/failing_example/src/lib.cairo create mode 100644 docs/listings/failing_example/tests/lib.cairo rename docs/listings/{sncast_library/scripts/declare => first_test}/Scarb.toml (57%) rename docs/listings/{snforge_overview/crates/writing_tests/src/first_test.cairo => first_test/src/lib.cairo} (100%) rename docs/listings/{snforge_advanced_features/crates => }/fork_testing/Scarb.toml (72%) rename docs/listings/{snforge_advanced_features/crates => }/fork_testing/src/lib.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/fork_testing/tests/explicit.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/fork_testing/tests/explicit/block_hash.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/fork_testing/tests/explicit/block_number.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/fork_testing/tests/explicit/block_tag.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/fork_testing/tests/lib.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/fork_testing/tests/name.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/fork_testing/tests/overridden_name.cairo (100%) rename docs/listings/{sncast_overview/scripts => }/full_example/Scarb.toml (73%) rename docs/listings/{sncast_overview/scripts => }/full_example/src/full_example.cairo (100%) rename docs/listings/{sncast_overview/scripts => }/full_example/src/lib.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/fuzz_testing/Scarb.toml (57%) rename docs/listings/{snforge_advanced_features/crates => }/fuzz_testing/src/basic_example.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/fuzz_testing/src/lib.cairo (100%) rename docs/listings/{snforge_advanced_features/crates => }/fuzz_testing/src/with_parameters.cairo (100%) rename docs/listings/{sncast_library/scripts => }/get_nonce/Scarb.toml (58%) rename docs/listings/{sncast_library/scripts => }/get_nonce/src/lib.cairo (100%) create mode 100644 docs/listings/hello_snforge/Scarb.toml create mode 100644 docs/listings/hello_snforge/src/lib.cairo create mode 100644 docs/listings/hello_snforge/tests/test_contract.cairo create mode 100644 docs/listings/hello_starknet/Scarb.toml create mode 100644 docs/listings/hello_starknet/src/lib.cairo create mode 100644 docs/listings/hello_starknet/tests/test_contract.cairo create mode 100644 docs/listings/hello_workspaces/Scarb.toml create mode 100644 docs/listings/hello_workspaces/crates/addition/Scarb.toml create mode 100644 docs/listings/hello_workspaces/crates/addition/src/lib.cairo create mode 100644 docs/listings/hello_workspaces/crates/addition/tests/nested.cairo create mode 100644 docs/listings/hello_workspaces/crates/addition/tests/nested/test_nested.cairo create mode 100644 docs/listings/hello_workspaces/crates/fibonacci/Scarb.toml create mode 100644 docs/listings/hello_workspaces/crates/fibonacci/src/lib.cairo create mode 100644 docs/listings/hello_workspaces/crates/fibonacci/tests/abc.cairo create mode 100644 docs/listings/hello_workspaces/crates/fibonacci/tests/abc/efg.cairo create mode 100644 docs/listings/hello_workspaces/crates/fibonacci/tests/lib.cairo create mode 100644 docs/listings/hello_workspaces/crates/fibonacci/tests/not_collected.cairo create mode 100644 docs/listings/hello_workspaces/src/lib.cairo create mode 100644 docs/listings/hello_workspaces/tests/test_failing.cairo create mode 100644 docs/listings/ignoring_example/Scarb.toml create mode 100644 docs/listings/ignoring_example/src/lib.cairo rename docs/listings/{sncast_library => invoke}/Scarb.toml (70%) rename docs/listings/{sncast_library/scripts => }/invoke/src/lib.cairo (100%) rename docs/listings/{sncast_overview/crates => }/map3/Scarb.toml (73%) rename docs/listings/{sncast_overview => map3}/snfoundry.toml (100%) rename docs/listings/{sncast_overview/crates => }/map3/src/lib.cairo (100%) create mode 100644 docs/listings/panicking_test/Scarb.toml rename docs/listings/{snforge_overview/crates/writing_tests/src/panicking_tests.cairo => panicking_test/src/lib.cairo} (54%) create mode 100644 docs/listings/should_panic_example/Scarb.toml create mode 100644 docs/listings/should_panic_example/src/lib.cairo delete mode 100644 docs/listings/sncast_library/scripts/invoke/Scarb.toml delete mode 100644 docs/listings/sncast_overview/.gitignore delete mode 100644 docs/listings/snforge_overview/crates/testing_smart_contracts/Scarb.toml delete mode 100644 docs/listings/snforge_overview/crates/testing_smart_contracts/src/lib.cairo delete mode 100644 docs/listings/snforge_overview/crates/using_cheatcodes/Scarb.toml delete mode 100644 docs/listings/snforge_overview/crates/using_cheatcodes/tests/caller_address.cairo delete mode 100644 docs/listings/snforge_overview/crates/writing_tests/Scarb.toml delete mode 100644 docs/listings/snforge_overview/crates/writing_tests/src/lib.cairo delete mode 100644 docs/listings/snforge_overview/crates/writing_tests/tests/expected_failures.cairo delete mode 100644 docs/listings/snforge_overview/crates/writing_tests/tests/ignoring.cairo rename docs/listings/{snforge_overview/crates => }/testing_contract_internals/Scarb.toml (67%) rename docs/listings/{snforge_overview/crates => }/testing_contract_internals/src/basic_example.cairo (100%) rename docs/listings/{snforge_overview/crates => }/testing_contract_internals/src/lib.cairo (100%) rename docs/listings/{snforge_overview/crates => }/testing_contract_internals/src/spying_for_events.cairo (100%) rename docs/listings/{snforge_overview/crates => }/testing_contract_internals/src/using_library_calls.cairo (100%) rename docs/listings/{snforge_overview/crates => }/testing_contract_internals/tests/lib.cairo (100%) rename docs/listings/{snforge_overview/crates => }/testing_contract_internals/tests/mocking_the_context_info.cairo (100%) rename docs/listings/{snforge_overview/crates => }/testing_contract_internals/tests/spying_for_events.cairo (100%) rename docs/listings/{snforge_overview/crates => }/testing_contract_internals/tests/spying_for_events/syscall_tests.cairo (100%) rename docs/listings/{snforge_overview/crates => }/testing_contract_internals/tests/spying_for_events/tests.cairo (100%) rename docs/listings/{snforge_overview/crates => }/testing_contract_internals/tests/using_library_calls.cairo (100%) rename docs/listings/{snforge_overview/crates => }/testing_events/Scarb.toml (65%) rename docs/listings/{snforge_overview/crates => }/testing_events/src/contract.cairo (100%) rename docs/listings/{snforge_overview/crates => }/testing_events/src/lib.cairo (100%) rename docs/listings/{snforge_overview/crates => }/testing_events/src/syscall.cairo (100%) rename docs/listings/{snforge_overview/crates => }/testing_events/src/syscall_dummy.cairo (100%) rename docs/listings/{snforge_overview/crates => }/testing_events/tests/assert_emitted.cairo (100%) rename docs/listings/{snforge_overview/crates => }/testing_events/tests/assert_manually.cairo (100%) rename docs/listings/{snforge_overview/crates => }/testing_events/tests/filter.cairo (100%) rename docs/listings/{snforge_overview/crates => }/testing_events/tests/syscall.cairo (100%) rename docs/listings/{snforge_overview/crates => }/testing_messages_to_l1/Scarb.toml (66%) rename docs/listings/{snforge_overview/crates => }/testing_messages_to_l1/src/lib.cairo (100%) rename docs/listings/{snforge_overview/crates => }/testing_messages_to_l1/tests/detailed.cairo (100%) rename docs/listings/{snforge_overview/crates => }/testing_messages_to_l1/tests/lib.cairo (100%) rename docs/listings/{snforge_overview/crates => }/testing_messages_to_l1/tests/simple.cairo (100%) create mode 100644 docs/listings/testing_smart_contracts_handling_errors/Scarb.toml rename docs/listings/{snforge_overview/crates/testing_smart_contracts/src/handling_errors.cairo => testing_smart_contracts_handling_errors/src/lib.cairo} (100%) rename docs/listings/{snforge_overview/crates/testing_smart_contracts => testing_smart_contracts_handling_errors}/tests/handle_panic.cairo (95%) rename docs/listings/{snforge_overview/crates/testing_smart_contracts => testing_smart_contracts_handling_errors}/tests/panic.cairo (84%) create mode 100644 docs/listings/testing_smart_contracts_safe_dispatcher/Scarb.toml create mode 100644 docs/listings/testing_smart_contracts_safe_dispatcher/src/lib.cairo rename docs/listings/{snforge_overview/crates/testing_smart_contracts => testing_smart_contracts_safe_dispatcher}/tests/safe_dispatcher.cairo (93%) create mode 100644 docs/listings/testing_smart_contracts_writing_tests/Scarb.toml rename docs/listings/{snforge_overview/crates/testing_smart_contracts/src/simple_contract.cairo => testing_smart_contracts_writing_tests/src/lib.cairo} (100%) rename docs/listings/{snforge_overview/crates/testing_smart_contracts => testing_smart_contracts_writing_tests}/tests/simple_contract.cairo (95%) rename docs/listings/{sncast_library/scripts => }/tx_status/Scarb.toml (58%) rename docs/listings/{sncast_library/scripts => }/tx_status/src/lib.cairo (100%) rename docs/listings/{snforge_overview => using_cheatcodes}/Scarb.toml (60%) rename docs/listings/{snforge_overview/crates => }/using_cheatcodes/src/lib.cairo (100%) rename docs/listings/{snforge_overview/crates/using_cheatcodes/tests/caller_address/failing.cairo => using_cheatcodes/tests/lib.cairo} (77%) create mode 100644 docs/listings/using_cheatcodes_cancelling_cheat/Scarb.toml create mode 100644 docs/listings/using_cheatcodes_cancelling_cheat/src/lib.cairo rename docs/listings/{snforge_overview/crates/using_cheatcodes/tests/caller_address/cancel.cairo => using_cheatcodes_cancelling_cheat/tests/lib.cairo} (80%) create mode 100644 docs/listings/using_cheatcodes_cheat_address/Scarb.toml create mode 100644 docs/listings/using_cheatcodes_cheat_address/src/lib.cairo rename docs/listings/{snforge_overview/crates/using_cheatcodes/tests/caller_address/proper_use.cairo => using_cheatcodes_cheat_address/tests/lib.cairo} (87%) rename docs/listings/{snforge_advanced_features => using_cheatcodes_others}/Scarb.toml (59%) create mode 100644 docs/listings/using_cheatcodes_others/src/lib.cairo create mode 100644 docs/listings/using_cheatcodes_others/tests/caller_address.cairo rename docs/listings/{snforge_overview/crates/using_cheatcodes => using_cheatcodes_others}/tests/caller_address/proper_use_global.cairo (93%) rename docs/listings/{snforge_overview/crates/using_cheatcodes => using_cheatcodes_others}/tests/caller_address/span.cairo (93%) rename docs/listings/{snforge_overview/crates/using_cheatcodes => using_cheatcodes_others}/tests/cheat_constructor.cairo (91%) rename docs/listings/{snforge_overview/crates/using_cheatcodes => using_cheatcodes_others}/tests/lib.cairo (100%) diff --git a/Cargo.lock b/Cargo.lock index b1141f08e2..63cec86a7f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1894,6 +1894,8 @@ name = "docs" version = "0.34.0" dependencies = [ "regex", + "serde", + "serde_json", "shell-words", "walkdir", ] diff --git a/crates/docs/Cargo.toml b/crates/docs/Cargo.toml index a6a11af985..41e8b672b1 100644 --- a/crates/docs/Cargo.toml +++ b/crates/docs/Cargo.toml @@ -9,6 +9,8 @@ license.workspace = true regex = "1.11.1" shell-words = "1.1.0" walkdir.workspace = true +serde.workspace = true +serde_json.workspace = true [features] testing = [] diff --git a/crates/docs/src/lib.rs b/crates/docs/src/lib.rs index 1506b851ef..684d3b527e 100644 --- a/crates/docs/src/lib.rs +++ b/crates/docs/src/lib.rs @@ -1,2 +1,7 @@ #[cfg(feature = "testing")] +pub mod snippet; +#[cfg(feature = "testing")] pub mod validation; + +#[cfg(feature = "testing")] +pub mod utils; diff --git a/crates/docs/src/snippet.rs b/crates/docs/src/snippet.rs new file mode 100644 index 0000000000..2b03f74534 --- /dev/null +++ b/crates/docs/src/snippet.rs @@ -0,0 +1,89 @@ +use regex::Regex; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug)] +pub struct SnippetType(String); + +impl SnippetType { + #[must_use] + pub fn forge() -> Self { + SnippetType("snforge".to_string()) + } + + #[must_use] + pub fn sncast() -> Self { + SnippetType("sncast".to_string()) + } + + #[must_use] + pub fn as_str(&self) -> &str { + &self.0 + } + + #[must_use] + pub fn get_re(&self) -> Regex { + // The regex pattern is used to match the snippet, its config and the output. Example: + // + // ```shell + // $ snforge or sncast command with args... + // ``` + //
+ // Output: + // ```shell + // Output of the command... + // ``` + //
+ + let escaped_command = regex::escape(self.as_str()); + let pattern = format!( + r"(?ms)^(?:\n)?```shell\n\$ (?P{escaped_command} .+?)\n```(?:\s*
\nOutput:<\/summary>\n\n```shell\n(?P[\s\S]+?)\n```[\s]*<\/details>)?" + ); + + Regex::new(&pattern).unwrap() + } +} + +#[derive(Debug, Deserialize, Serialize, Default)] +pub struct SnippetConfig { + pub ignored: Option, + pub package_name: Option, +} + +#[derive(Debug)] +pub struct Snippet { + pub command: String, + pub output: Option, + pub file_path: String, + pub line_start: usize, + pub snippet_type: SnippetType, + pub config: SnippetConfig, +} + +impl Snippet { + #[must_use] + pub fn to_command_args(&self) -> Vec { + let cleaned_command = self + .command + .lines() + .collect::>() + .join(" ") + .replace(" \\", ""); + + shell_words::split(&cleaned_command) + .expect("Failed to parse snippet string") + .into_iter() + .map(|arg| arg.trim().to_string()) + .collect() + } + + #[must_use] + pub fn capture_package_from_output(&self) -> Option { + let re = + Regex::new(r"Collected \d+ test\(s\) from ([a-zA-Z_][a-zA-Z0-9_]*) package").unwrap(); + + re.captures_iter(self.output.as_ref()?) + .filter_map(|caps| caps.get(1)) + .last() + .map(|m| m.as_str().to_string()) + } +} diff --git a/crates/docs/src/utils.rs b/crates/docs/src/utils.rs new file mode 100644 index 0000000000..9b5b3bcfaa --- /dev/null +++ b/crates/docs/src/utils.rs @@ -0,0 +1,41 @@ +use std::{env, path::PathBuf}; + +use crate::snippet::Snippet; + +#[must_use] +pub fn get_nth_ancestor(levels_up: usize) -> PathBuf { + let mut dir = env::current_dir().expect("Failed to get the current directory"); + + for _ in 0..levels_up { + dir = dir + .parent() + .expect("Failed to navigate to parent directory") + .to_owned(); + } + + dir +} + +pub fn assert_valid_snippet(condition: bool, snippet: &Snippet, err_message: &str) { + assert!( + condition, + "Found invalid {} snippet in the docs at {}:{}:1\n{}", + snippet.snippet_type.as_str(), + snippet.file_path, + snippet.line_start, + err_message + ); +} + +pub fn print_success_message(snippets_len: usize, tool_name: &str) { + println!("Successfully validated {snippets_len} {tool_name} docs snippets"); +} + +pub fn print_skipped_snippet_message(snippet: &Snippet) { + println!( + "Skipped validation of {} snippet in the docs in file: {} at line {}", + snippet.snippet_type.as_str(), + snippet.file_path, + snippet.line_start, + ); +} diff --git a/crates/docs/src/validation.rs b/crates/docs/src/validation.rs index ea801187d9..70605570a6 100644 --- a/crates/docs/src/validation.rs +++ b/crates/docs/src/validation.rs @@ -1,52 +1,43 @@ -use regex::Regex; -use std::{ - env, fs, io, - path::{Path, PathBuf}, -}; +use std::{fs, io, path::Path}; -const EXTENSION: Option<&str> = Some("md"); - -pub struct Snippet { - pub command: String, - pub file_path: String, - pub line_start: usize, -} +use crate::snippet::{Snippet, SnippetConfig, SnippetType}; -impl Snippet { - pub fn to_command_args(&self) -> Vec { - let cleaned_command = self - .command - .lines() - .map(str::trim_end) - .collect::>() - .join(" ") - .replace(" \\", ""); - - shell_words::split(&cleaned_command) - .expect("Failed to parse snippet string") - .into_iter() - .map(|arg| arg.trim().to_string()) - .collect() - } -} +const EXTENSION: Option<&str> = Some("md"); -pub fn extract_snippets_from_file(file_path: &Path, re: &Regex) -> io::Result> { +pub fn extract_snippets_from_file( + file_path: &Path, + snippet_type: &SnippetType, +) -> io::Result> { let content = fs::read_to_string(file_path)?; let file_path_str = file_path .to_str() .expect("Failed to get file path") .to_string(); - let snippets = re + let snippets = snippet_type + .get_re() .captures_iter(&content) .filter_map(|caps| { - let command_match = caps.get(1)?; let match_start = caps.get(0)?.start(); + let config_str = caps + .name("config") + .map_or_else(String::new, |m| m.as_str().to_string()); + let command_match = caps.name("command")?; + let output = caps.name("output").map(|m| m.as_str().to_string()); + + let config = if config_str.is_empty() { + SnippetConfig::default() + } else { + serde_json::from_str(&config_str).expect("Failed to parse snippet config") + }; Some(Snippet { command: command_match.as_str().to_string(), + output, file_path: file_path_str.clone(), line_start: content[..match_start].lines().count() + 1, + snippet_type: snippet_type.clone(), + config, }) }) .collect(); @@ -54,7 +45,10 @@ pub fn extract_snippets_from_file(file_path: &Path, re: &Regex) -> io::Result io::Result> { +pub fn extract_snippets_from_directory( + dir_path: &Path, + snippet_type: &SnippetType, +) -> io::Result> { let mut all_snippets = Vec::new(); let files = walkdir::WalkDir::new(dir_path) @@ -68,48 +62,10 @@ pub fn extract_snippets_from_directory(dir_path: &Path, re: &Regex) -> io::Resul if EXTENSION.map_or(true, |ext| { path.extension().and_then(|path_ext| path_ext.to_str()) == Some(ext) }) { - let snippets = extract_snippets_from_file(path, re)?; + let snippets = extract_snippets_from_file(path, snippet_type)?; all_snippets.extend(snippets); } } Ok(all_snippets) } - -#[must_use] -pub fn get_parent_dir(levels_up: usize) -> PathBuf { - let mut dir = env::current_dir().expect("Failed to get the current directory"); - - for _ in 0..levels_up { - dir = dir - .parent() - .expect("Failed to navigate to parent directory") - .to_owned(); - } - - dir -} - -pub fn assert_valid_snippet( - condition: bool, - snippet: &Snippet, - tool_name: &str, - err_message: &str, -) { - assert!( - condition, - "Found invalid {} snippet in the docs in file: {} at line {}\n{}", - tool_name, snippet.file_path, snippet.line_start, err_message - ); -} - -pub fn print_success_message(snippets_len: usize, tool_name: &str) { - println!("Successfully validated {snippets_len} {tool_name} docs snippets"); -} - -pub fn print_skipped_snippet_message(snippet: &Snippet, tool_name: &str) { - println!( - "Skipped validation of {} snippet in the docs in file: {} at line {}", - tool_name, snippet.file_path, snippet.line_start - ); -} diff --git a/crates/forge/tests/e2e/common/runner.rs b/crates/forge/tests/e2e/common/runner.rs index 9a8d05e789..bc248916b1 100644 --- a/crates/forge/tests/e2e/common/runner.rs +++ b/crates/forge/tests/e2e/common/runner.rs @@ -33,13 +33,33 @@ pub(crate) fn test_runner(temp_dir: &TempDir) -> SnapboxCommand { pub(crate) static BASE_FILE_PATTERNS: &[&str] = &["**/*.cairo", "**/*.toml"]; +fn is_package_from_docs_listings(package: &str) -> bool { + let package_path = Path::new("../../docs/listings").join(package); + fs::canonicalize(&package_path).is_ok() +} + pub(crate) fn setup_package_with_file_patterns( package_name: &str, file_patterns: &[&str], ) -> TempDir { let temp = tempdir_with_tool_versions().unwrap(); - temp.copy_from(format!("tests/data/{package_name}"), file_patterns) - .unwrap(); + + let is_from_docs_listings = is_package_from_docs_listings(package_name); + + let package_path = if is_from_docs_listings { + format!("../../docs/listings/{package_name}",) + } else { + format!("tests/data/{package_name}",) + }; + + let package_path = Utf8PathBuf::from_str(&package_path) + .unwrap() + .canonicalize_utf8() + .unwrap() + .to_string() + .replace('\\', "/"); + + temp.copy_from(package_path, file_patterns).unwrap(); let snforge_std_path = Utf8PathBuf::from_str("../../snforge_std") .unwrap() @@ -54,12 +74,26 @@ pub(crate) fn setup_package_with_file_patterns( .unwrap() .parse::() .unwrap(); - scarb_toml["dev-dependencies"]["snforge_std"]["path"] = value(snforge_std_path); + + let is_workspace = scarb_toml.get("workspace").is_some(); + + if is_workspace { + scarb_toml["workspace"]["dependencies"]["snforge_std"]["path"] = value(snforge_std_path); + } else { + scarb_toml["dev-dependencies"]["snforge_std"]["path"] = value(snforge_std_path); + } + scarb_toml["dependencies"]["starknet"] = value("2.4.0"); scarb_toml["dependencies"]["assert_macros"] = value(get_assert_macros_version().unwrap().to_string()); scarb_toml["target.starknet-contract"]["sierra"] = value(true); + if is_from_docs_listings { + scarb_toml["dev-dependencies"]["snforge_std"] + .as_table_mut() + .and_then(|snforge_std| snforge_std.remove("workspace")); + } + manifest_path.write_str(&scarb_toml.to_string()).unwrap(); // TODO (#2074): do that on .cairo.template files only @@ -209,12 +243,7 @@ pub(crate) fn get_remote_url() -> String { .output_checked() .unwrap(); - String::from_utf8(output.stdout) - .unwrap() - .trim() - .strip_prefix("git@github.com:") - .unwrap() - .to_string() + String::from_utf8(output.stdout).unwrap().trim().to_string() } } diff --git a/crates/forge/tests/e2e/docs_snippets_validation.rs b/crates/forge/tests/e2e/docs_snippets_validation.rs index d69b5adf46..a385d1c06a 100644 --- a/crates/forge/tests/e2e/docs_snippets_validation.rs +++ b/crates/forge/tests/e2e/docs_snippets_validation.rs @@ -1,43 +1,59 @@ use clap::Parser; -use docs::validation::{ - assert_valid_snippet, extract_snippets_from_directory, get_parent_dir, - print_skipped_snippet_message, print_success_message, +use docs::snippet::SnippetType; +use docs::utils::{ + assert_valid_snippet, get_nth_ancestor, print_skipped_snippet_message, print_success_message, }; +use docs::validation::extract_snippets_from_directory; use forge::Cli; -use regex::Regex; +use shared::test_utils::output_assert::assert_stdout_contains; + +use super::common::runner::{runner, setup_package}; + #[test] fn test_docs_snippets() { - let root_dir = get_parent_dir(2); + let root_dir = get_nth_ancestor(2); let docs_dir = root_dir.join("docs/src"); - let re = Regex::new(r"(?ms)```shell\n\$ (snforge .+?)\n```").expect("Invalid regex pattern"); - - let snippets = extract_snippets_from_directory(&docs_dir, &re) - .expect("Failed to extract snforge command snippets"); + let snippet_type = SnippetType::forge(); - // TODO(#2684) - let skipped_args = [ - // for some reason `try_parse_from` fails on `--version` flag - vec!["snforge", "--version"], - ]; + let snippets = extract_snippets_from_directory(&docs_dir, &snippet_type) + .expect("Failed to extract command snippets"); for snippet in &snippets { let args = snippet.to_command_args(); - let args: Vec<&str> = args.iter().map(String::as_str).collect(); + let mut args: Vec<&str> = args.iter().map(String::as_str).collect(); - if skipped_args.contains(&args) { - print_skipped_snippet_message(snippet, "snforge"); + if snippet.config.ignored.unwrap_or(false) { + print_skipped_snippet_message(snippet); continue; } - let parse_result = Cli::try_parse_from(args); + let parse_result = Cli::try_parse_from(args.clone()); let err_message = if let Err(err) = &parse_result { err.to_string() } else { String::new() }; - assert_valid_snippet(parse_result.is_ok(), snippet, "snforge", &err_message); + + assert_valid_snippet(parse_result.is_ok(), snippet, &err_message); + + // Remove "snforge" from the args + args.remove(0); + + if let Some(snippet_output) = &snippet.output { + let package_name = snippet + .config + .package_name + .clone() + .or_else(|| snippet.capture_package_from_output()) + .expect("Cannot find package name in command output or snippet config"); + + let temp = setup_package(&package_name); + let output = runner(&temp).args(args).assert(); + + assert_stdout_contains(output, snippet_output); + } } - print_success_message(snippets.len(), "snforge"); + print_success_message(snippets.len(), snippet_type.as_str()); } diff --git a/crates/sncast/tests/docs_snippets/validation.rs b/crates/sncast/tests/docs_snippets/validation.rs index 2d649b86d0..362cd07e7e 100644 --- a/crates/sncast/tests/docs_snippets/validation.rs +++ b/crates/sncast/tests/docs_snippets/validation.rs @@ -1,8 +1,8 @@ -use docs::validation::{ - assert_valid_snippet, extract_snippets_from_directory, extract_snippets_from_file, - get_parent_dir, print_skipped_snippet_message, print_success_message, Snippet, +use docs::snippet::{Snippet, SnippetType}; +use docs::utils::{ + assert_valid_snippet, get_nth_ancestor, print_skipped_snippet_message, print_success_message, }; -use regex::Regex; +use docs::validation::{extract_snippets_from_directory, extract_snippets_from_file}; use tempfile::tempdir; use crate::helpers::runner::runner; @@ -11,60 +11,42 @@ use crate::helpers::runner::runner; fn test_docs_snippets() { let tempdir = tempdir().expect("Unable to create a temporary directory"); - let root_dir_path = get_parent_dir(2); + let root_dir_path = get_nth_ancestor(2); let docs_dir_path = root_dir_path.join("docs/src"); let sncast_readme_path = root_dir_path.join("crates/sncast/README.md"); - let re = Regex::new(r"(?ms)```shell\n\$ sncast(.+?)\n```").expect("Invalid regex pattern"); + let snippet_type = SnippetType::sncast(); - let docs_snippets = extract_snippets_from_directory(&docs_dir_path, &re) - .expect("Failed to extract sncast command snippets"); + let docs_snippets = extract_snippets_from_directory(&docs_dir_path, &snippet_type) + .expect("Failed to extract command snippets"); - let readme_snippets = extract_snippets_from_file(&sncast_readme_path, &re) - .expect("Failed to extract sncast command snippets"); + let readme_snippets = extract_snippets_from_file(&sncast_readme_path, &snippet_type) + .expect("Failed to extract command snippets"); let snippets = docs_snippets .into_iter() .chain(readme_snippets) .collect::>(); - // TODO(#2684) - let skipped_args = [ - // snippet "$ sncast " - vec![""], - // snippet with interactive account import example - vec![ - "account", - "import", - "--url", - "http://127.0.0.1:5050", - "--name", - "account_123", - "--address", - "0x1", - "--type", - "oz", - ], - ]; - for snippet in &snippets { let args = snippet.to_command_args(); - let args: Vec<&str> = args.iter().map(String::as_str).collect(); + let mut args: Vec<&str> = args.iter().map(String::as_str).collect(); + + // remove "sncast" from the args + args.remove(0); - if skipped_args.contains(&args) { - print_skipped_snippet_message(snippet, "sncast"); + if snippet.config.ignored.unwrap_or(false) { + print_skipped_snippet_message(snippet); continue; } - // TODO(#2678) - let snapbox = runner(&args).current_dir(tempdir.path()); let output = snapbox.output().expect("Failed to execute the command"); let exit_code = output.status.code().unwrap_or_default(); let stderr = String::from_utf8_lossy(&output.stderr); - assert_valid_snippet(exit_code != 2, snippet, "sncast", &stderr); + assert_valid_snippet(exit_code != 2, snippet, &stderr); } - print_success_message(snippets.len(), "sncast"); + print_success_message(snippets.len(), snippet_type.as_str()); } diff --git a/docs/listings/sncast_overview/scripts/basic_example/Scarb.toml b/docs/listings/basic_example/Scarb.toml similarity index 69% rename from docs/listings/sncast_overview/scripts/basic_example/Scarb.toml rename to docs/listings/basic_example/Scarb.toml index b425f3ed72..c637765bb1 100644 --- a/docs/listings/sncast_overview/scripts/basic_example/Scarb.toml +++ b/docs/listings/basic_example/Scarb.toml @@ -6,9 +6,9 @@ edition = "2024_07" # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html [dependencies] -snforge_std.workspace = true -sncast_std.workspace = true -starknet.workspace = true +starknet = "2.7.0" +snforge_std = { path = "../../../snforge_std" } +sncast_std = { path = "../../../sncast_std" } [[target.lib]] sierra = true diff --git a/docs/listings/sncast_overview/scripts/basic_example/src/basic_example.cairo b/docs/listings/basic_example/src/basic_example.cairo similarity index 100% rename from docs/listings/sncast_overview/scripts/basic_example/src/basic_example.cairo rename to docs/listings/basic_example/src/basic_example.cairo diff --git a/docs/listings/sncast_overview/scripts/basic_example/src/lib.cairo b/docs/listings/basic_example/src/lib.cairo similarity index 100% rename from docs/listings/sncast_overview/scripts/basic_example/src/lib.cairo rename to docs/listings/basic_example/src/lib.cairo diff --git a/docs/listings/sncast_library/scripts/call/Scarb.toml b/docs/listings/call/Scarb.toml similarity index 55% rename from docs/listings/sncast_library/scripts/call/Scarb.toml rename to docs/listings/call/Scarb.toml index 445f83833b..d3a1355702 100644 --- a/docs/listings/sncast_library/scripts/call/Scarb.toml +++ b/docs/listings/call/Scarb.toml @@ -4,8 +4,9 @@ version = "0.1.0" edition = "2023_11" [dependencies] -starknet.workspace = true -sncast_std.workspace = true +starknet = "2.7.0" +sncast_std = { path = "../../../sncast_std" } +snforge_std = { path = "../../../snforge_std" } [[target.lib]] sierra = true diff --git a/docs/listings/sncast_library/scripts/call/src/lib.cairo b/docs/listings/call/src/lib.cairo similarity index 100% rename from docs/listings/sncast_library/scripts/call/src/lib.cairo rename to docs/listings/call/src/lib.cairo diff --git a/docs/listings/snforge_advanced_features/crates/conditional_compilation/Scarb.toml b/docs/listings/conditional_compilation/Scarb.toml similarity index 68% rename from docs/listings/snforge_advanced_features/crates/conditional_compilation/Scarb.toml rename to docs/listings/conditional_compilation/Scarb.toml index 598a980be5..136ac8da96 100644 --- a/docs/listings/snforge_advanced_features/crates/conditional_compilation/Scarb.toml +++ b/docs/listings/conditional_compilation/Scarb.toml @@ -8,9 +8,11 @@ default = ["enable_for_tests"] enable_for_tests = [] [dependencies] -starknet.workspace = true -snforge_std.workspace = true -assert_macros.workspace = true +starknet = "2.7.0" +assert_macros = "0.1.0" + +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } [[target.starknet-contract]] sierra = true diff --git a/docs/listings/snforge_advanced_features/crates/conditional_compilation/src/contract.cairo b/docs/listings/conditional_compilation/src/contract.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/conditional_compilation/src/contract.cairo rename to docs/listings/conditional_compilation/src/contract.cairo diff --git a/docs/listings/snforge_advanced_features/crates/conditional_compilation/src/function.cairo b/docs/listings/conditional_compilation/src/function.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/conditional_compilation/src/function.cairo rename to docs/listings/conditional_compilation/src/function.cairo diff --git a/docs/listings/snforge_advanced_features/crates/conditional_compilation/src/lib.cairo b/docs/listings/conditional_compilation/src/lib.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/conditional_compilation/src/lib.cairo rename to docs/listings/conditional_compilation/src/lib.cairo diff --git a/docs/listings/snforge_advanced_features/crates/conditional_compilation/tests/test.cairo b/docs/listings/conditional_compilation/tests/test.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/conditional_compilation/tests/test.cairo rename to docs/listings/conditional_compilation/tests/test.cairo diff --git a/docs/listings/sncast_overview/Scarb.toml b/docs/listings/declare/Scarb.toml similarity index 66% rename from docs/listings/sncast_overview/Scarb.toml rename to docs/listings/declare/Scarb.toml index 4e682fa59d..caba58eb23 100644 --- a/docs/listings/sncast_overview/Scarb.toml +++ b/docs/listings/declare/Scarb.toml @@ -1,18 +1,18 @@ -[workspace] -members = ["scripts/*", "crates/*"] +[package] +name = "declare" +version = "0.1.0" +edition = "2023_11" -[workspace.dependencies] +[dependencies] starknet = "2.7.0" -snforge_std = { path = "../../../snforge_std" } sncast_std = { path = "../../../sncast_std" } -assert_macros = "0.1.0" +snforge_std = { path = "../../../snforge_std" } [[target.starknet-contract]] sierra = true [[target.lib]] sierra = true -casm = true [scripts] test = "snforge test" diff --git a/docs/listings/sncast_library/scripts/declare/src/lib.cairo b/docs/listings/declare/src/lib.cairo similarity index 100% rename from docs/listings/sncast_library/scripts/declare/src/lib.cairo rename to docs/listings/declare/src/lib.cairo diff --git a/docs/listings/sncast_library/scripts/deploy/Scarb.toml b/docs/listings/deploy/Scarb.toml similarity index 51% rename from docs/listings/sncast_library/scripts/deploy/Scarb.toml rename to docs/listings/deploy/Scarb.toml index 1ae2f99497..0a87b3ab07 100644 --- a/docs/listings/sncast_library/scripts/deploy/Scarb.toml +++ b/docs/listings/deploy/Scarb.toml @@ -4,8 +4,11 @@ version = "0.1.0" edition = "2023_11" [dependencies] -starknet.workspace = true -sncast_std.workspace = true +starknet = "2.7.0" +sncast_std = { path = "../../../sncast_std" } + +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } [[target.lib]] sierra = true diff --git a/docs/listings/sncast_library/scripts/deploy/src/lib.cairo b/docs/listings/deploy/src/lib.cairo similarity index 100% rename from docs/listings/sncast_library/scripts/deploy/src/lib.cairo rename to docs/listings/deploy/src/lib.cairo diff --git a/docs/listings/detailed_resources_example/Scarb.toml b/docs/listings/detailed_resources_example/Scarb.toml new file mode 100644 index 0000000000..788a68ee9d --- /dev/null +++ b/docs/listings/detailed_resources_example/Scarb.toml @@ -0,0 +1,18 @@ +[package] +name = "detailed_resources_example" +version = "0.1.0" +edition = "2023_11" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] +starknet = "2.7.0" + +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } + +[[target.starknet-contract]] +sierra = true + +[scripts] +test = "snforge test" diff --git a/docs/listings/detailed_resources_example/src/lib.cairo b/docs/listings/detailed_resources_example/src/lib.cairo new file mode 100644 index 0000000000..4955786578 --- /dev/null +++ b/docs/listings/detailed_resources_example/src/lib.cairo @@ -0,0 +1,25 @@ +#[starknet::interface] +pub trait IHelloStarknet { + fn increase_balance(ref self: TContractState, amount: felt252); + fn get_balance(self: @TContractState) -> felt252; +} + +#[starknet::contract] +mod HelloStarknet { + #[storage] + struct Storage { + balance: felt252, + } + + #[abi(embed_v0)] + impl HelloStarknetImpl of super::IHelloStarknet { + fn increase_balance(ref self: ContractState, amount: felt252) { + assert(amount != 0, 'Amount cannot be 0'); + self.balance.write(self.balance.read() + amount); + } + + fn get_balance(self: @ContractState) -> felt252 { + self.balance.read() + } + } +} diff --git a/docs/listings/detailed_resources_example/tests/test_contract.cairo b/docs/listings/detailed_resources_example/tests/test_contract.cairo new file mode 100644 index 0000000000..42968bcd13 --- /dev/null +++ b/docs/listings/detailed_resources_example/tests/test_contract.cairo @@ -0,0 +1,15 @@ +#[test] +fn test_abc() { + assert(1 == 1, 1); +} + +#[test] +fn test_failing() { + assert(1 == 2, 'failing check'); +} + +#[test] +fn test_xyz() { + assert(1 == 1, 1); +} + diff --git a/docs/listings/snforge_advanced_features/crates/direct_storage_access/Scarb.toml b/docs/listings/direct_storage_access/Scarb.toml similarity index 60% rename from docs/listings/snforge_advanced_features/crates/direct_storage_access/Scarb.toml rename to docs/listings/direct_storage_access/Scarb.toml index 118608e7cb..b1f73067fa 100644 --- a/docs/listings/snforge_advanced_features/crates/direct_storage_access/Scarb.toml +++ b/docs/listings/direct_storage_access/Scarb.toml @@ -4,9 +4,11 @@ version = "0.1.0" edition = "2023_11" [dependencies] -starknet.workspace = true -snforge_std.workspace = true -assert_macros.workspace = true +starknet = "2.7.0" +assert_macros = "0.1.0" + +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } [[target.starknet-contract]] sierra = true diff --git a/docs/listings/snforge_advanced_features/crates/direct_storage_access/src/complex_structures.cairo b/docs/listings/direct_storage_access/src/complex_structures.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/direct_storage_access/src/complex_structures.cairo rename to docs/listings/direct_storage_access/src/complex_structures.cairo diff --git a/docs/listings/snforge_advanced_features/crates/direct_storage_access/src/felts_only.cairo b/docs/listings/direct_storage_access/src/felts_only.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/direct_storage_access/src/felts_only.cairo rename to docs/listings/direct_storage_access/src/felts_only.cairo diff --git a/docs/listings/snforge_advanced_features/crates/direct_storage_access/src/lib.cairo b/docs/listings/direct_storage_access/src/lib.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/direct_storage_access/src/lib.cairo rename to docs/listings/direct_storage_access/src/lib.cairo diff --git a/docs/listings/snforge_advanced_features/crates/direct_storage_access/tests/complex_structures.cairo b/docs/listings/direct_storage_access/tests/complex_structures.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/direct_storage_access/tests/complex_structures.cairo rename to docs/listings/direct_storage_access/tests/complex_structures.cairo diff --git a/docs/listings/snforge_advanced_features/crates/direct_storage_access/tests/felts_only.cairo b/docs/listings/direct_storage_access/tests/felts_only.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/direct_storage_access/tests/felts_only.cairo rename to docs/listings/direct_storage_access/tests/felts_only.cairo diff --git a/docs/listings/snforge_advanced_features/crates/direct_storage_access/tests/felts_only/field.cairo b/docs/listings/direct_storage_access/tests/felts_only/field.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/direct_storage_access/tests/felts_only/field.cairo rename to docs/listings/direct_storage_access/tests/felts_only/field.cairo diff --git a/docs/listings/snforge_advanced_features/crates/direct_storage_access/tests/felts_only/map_entry.cairo b/docs/listings/direct_storage_access/tests/felts_only/map_entry.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/direct_storage_access/tests/felts_only/map_entry.cairo rename to docs/listings/direct_storage_access/tests/felts_only/map_entry.cairo diff --git a/docs/listings/snforge_advanced_features/crates/direct_storage_access/tests/lib.cairo b/docs/listings/direct_storage_access/tests/lib.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/direct_storage_access/tests/lib.cairo rename to docs/listings/direct_storage_access/tests/lib.cairo diff --git a/docs/listings/snforge_advanced_features/crates/direct_storage_access/tests/storage_address.cairo b/docs/listings/direct_storage_access/tests/storage_address.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/direct_storage_access/tests/storage_address.cairo rename to docs/listings/direct_storage_access/tests/storage_address.cairo diff --git a/docs/listings/snforge_advanced_features/crates/direct_storage_access/tests/using_storage_address_from_base.cairo b/docs/listings/direct_storage_access/tests/using_storage_address_from_base.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/direct_storage_access/tests/using_storage_address_from_base.cairo rename to docs/listings/direct_storage_access/tests/using_storage_address_from_base.cairo diff --git a/docs/listings/sncast_overview/scripts/error_handling/Scarb.toml b/docs/listings/error_handling/Scarb.toml similarity index 65% rename from docs/listings/sncast_overview/scripts/error_handling/Scarb.toml rename to docs/listings/error_handling/Scarb.toml index b52b5904ba..5ef420704b 100644 --- a/docs/listings/sncast_overview/scripts/error_handling/Scarb.toml +++ b/docs/listings/error_handling/Scarb.toml @@ -6,10 +6,10 @@ edition = "2024_07" # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html [dependencies] -snforge_std.workspace = true -sncast_std.workspace = true -starknet.workspace = true -assert_macros.workspace = true +snforge_std = { path = "../../../snforge_std" } +sncast_std = { path = "../../../sncast_std" } +starknet = "2.7.0" +assert_macros = "0.1.0" [[target.lib]] sierra = true diff --git a/docs/listings/sncast_overview/scripts/error_handling/src/error_handling.cairo b/docs/listings/error_handling/src/error_handling.cairo similarity index 100% rename from docs/listings/sncast_overview/scripts/error_handling/src/error_handling.cairo rename to docs/listings/error_handling/src/error_handling.cairo diff --git a/docs/listings/sncast_overview/scripts/error_handling/src/lib.cairo b/docs/listings/error_handling/src/lib.cairo similarity index 100% rename from docs/listings/sncast_overview/scripts/error_handling/src/lib.cairo rename to docs/listings/error_handling/src/lib.cairo diff --git a/docs/listings/failing_example/Scarb.toml b/docs/listings/failing_example/Scarb.toml new file mode 100644 index 0000000000..890df4147f --- /dev/null +++ b/docs/listings/failing_example/Scarb.toml @@ -0,0 +1,18 @@ +[package] +name = "failing_example" +version = "0.1.0" +edition = "2023_11" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] +starknet = "2.7.0" + +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } + +[[target.starknet-contract]] +sierra = true + +[scripts] +test = "snforge test" diff --git a/docs/listings/failing_example/src/lib.cairo b/docs/listings/failing_example/src/lib.cairo new file mode 100644 index 0000000000..4955786578 --- /dev/null +++ b/docs/listings/failing_example/src/lib.cairo @@ -0,0 +1,25 @@ +#[starknet::interface] +pub trait IHelloStarknet { + fn increase_balance(ref self: TContractState, amount: felt252); + fn get_balance(self: @TContractState) -> felt252; +} + +#[starknet::contract] +mod HelloStarknet { + #[storage] + struct Storage { + balance: felt252, + } + + #[abi(embed_v0)] + impl HelloStarknetImpl of super::IHelloStarknet { + fn increase_balance(ref self: ContractState, amount: felt252) { + assert(amount != 0, 'Amount cannot be 0'); + self.balance.write(self.balance.read() + amount); + } + + fn get_balance(self: @ContractState) -> felt252 { + self.balance.read() + } + } +} diff --git a/docs/listings/failing_example/tests/lib.cairo b/docs/listings/failing_example/tests/lib.cairo new file mode 100644 index 0000000000..42968bcd13 --- /dev/null +++ b/docs/listings/failing_example/tests/lib.cairo @@ -0,0 +1,15 @@ +#[test] +fn test_abc() { + assert(1 == 1, 1); +} + +#[test] +fn test_failing() { + assert(1 == 2, 'failing check'); +} + +#[test] +fn test_xyz() { + assert(1 == 1, 1); +} + diff --git a/docs/listings/sncast_library/scripts/declare/Scarb.toml b/docs/listings/first_test/Scarb.toml similarity index 57% rename from docs/listings/sncast_library/scripts/declare/Scarb.toml rename to docs/listings/first_test/Scarb.toml index b7fbb9f0e9..1b14dabb57 100644 --- a/docs/listings/sncast_library/scripts/declare/Scarb.toml +++ b/docs/listings/first_test/Scarb.toml @@ -1,16 +1,15 @@ [package] -name = "declare" +name = "first_test" version = "0.1.0" edition = "2023_11" [dependencies] -starknet.workspace = true -sncast_std.workspace = true +starknet = "2.7.0" -[[target.starknet-contract]] -sierra = true +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } -[[target.lib]] +[[target.starknet-contract]] sierra = true [scripts] diff --git a/docs/listings/snforge_overview/crates/writing_tests/src/first_test.cairo b/docs/listings/first_test/src/lib.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/writing_tests/src/first_test.cairo rename to docs/listings/first_test/src/lib.cairo diff --git a/docs/listings/snforge_advanced_features/crates/fork_testing/Scarb.toml b/docs/listings/fork_testing/Scarb.toml similarity index 72% rename from docs/listings/snforge_advanced_features/crates/fork_testing/Scarb.toml rename to docs/listings/fork_testing/Scarb.toml index ba8e0d5257..7bc4b5d822 100644 --- a/docs/listings/snforge_advanced_features/crates/fork_testing/Scarb.toml +++ b/docs/listings/fork_testing/Scarb.toml @@ -4,9 +4,11 @@ version = "0.1.0" edition = "2023_11" [dependencies] -starknet.workspace = true -snforge_std.workspace = true -assert_macros.workspace = true +starknet = "2.7.0" +assert_macros = "0.1.0" + +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } [[target.starknet-contract]] sierra = true diff --git a/docs/listings/snforge_advanced_features/crates/fork_testing/src/lib.cairo b/docs/listings/fork_testing/src/lib.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/fork_testing/src/lib.cairo rename to docs/listings/fork_testing/src/lib.cairo diff --git a/docs/listings/snforge_advanced_features/crates/fork_testing/tests/explicit.cairo b/docs/listings/fork_testing/tests/explicit.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/fork_testing/tests/explicit.cairo rename to docs/listings/fork_testing/tests/explicit.cairo diff --git a/docs/listings/snforge_advanced_features/crates/fork_testing/tests/explicit/block_hash.cairo b/docs/listings/fork_testing/tests/explicit/block_hash.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/fork_testing/tests/explicit/block_hash.cairo rename to docs/listings/fork_testing/tests/explicit/block_hash.cairo diff --git a/docs/listings/snforge_advanced_features/crates/fork_testing/tests/explicit/block_number.cairo b/docs/listings/fork_testing/tests/explicit/block_number.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/fork_testing/tests/explicit/block_number.cairo rename to docs/listings/fork_testing/tests/explicit/block_number.cairo diff --git a/docs/listings/snforge_advanced_features/crates/fork_testing/tests/explicit/block_tag.cairo b/docs/listings/fork_testing/tests/explicit/block_tag.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/fork_testing/tests/explicit/block_tag.cairo rename to docs/listings/fork_testing/tests/explicit/block_tag.cairo diff --git a/docs/listings/snforge_advanced_features/crates/fork_testing/tests/lib.cairo b/docs/listings/fork_testing/tests/lib.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/fork_testing/tests/lib.cairo rename to docs/listings/fork_testing/tests/lib.cairo diff --git a/docs/listings/snforge_advanced_features/crates/fork_testing/tests/name.cairo b/docs/listings/fork_testing/tests/name.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/fork_testing/tests/name.cairo rename to docs/listings/fork_testing/tests/name.cairo diff --git a/docs/listings/snforge_advanced_features/crates/fork_testing/tests/overridden_name.cairo b/docs/listings/fork_testing/tests/overridden_name.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/fork_testing/tests/overridden_name.cairo rename to docs/listings/fork_testing/tests/overridden_name.cairo diff --git a/docs/listings/sncast_overview/scripts/full_example/Scarb.toml b/docs/listings/full_example/Scarb.toml similarity index 73% rename from docs/listings/sncast_overview/scripts/full_example/Scarb.toml rename to docs/listings/full_example/Scarb.toml index e4e6c65dee..5f8e8a5da7 100644 --- a/docs/listings/sncast_overview/scripts/full_example/Scarb.toml +++ b/docs/listings/full_example/Scarb.toml @@ -6,9 +6,9 @@ edition = "2024_07" # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html [dependencies] -snforge_std.workspace = true -sncast_std.workspace = true -map3 = { path = "../../crates/map3" } +snforge_std = { path = "../../../snforge_std" } +sncast_std = { path = "../../../sncast_std" } +map3 = { path = "../map3" } [[target.starknet-contract]] build-external-contracts = ["map3::MapContract"] diff --git a/docs/listings/sncast_overview/scripts/full_example/src/full_example.cairo b/docs/listings/full_example/src/full_example.cairo similarity index 100% rename from docs/listings/sncast_overview/scripts/full_example/src/full_example.cairo rename to docs/listings/full_example/src/full_example.cairo diff --git a/docs/listings/sncast_overview/scripts/full_example/src/lib.cairo b/docs/listings/full_example/src/lib.cairo similarity index 100% rename from docs/listings/sncast_overview/scripts/full_example/src/lib.cairo rename to docs/listings/full_example/src/lib.cairo diff --git a/docs/listings/snforge_advanced_features/crates/fuzz_testing/Scarb.toml b/docs/listings/fuzz_testing/Scarb.toml similarity index 57% rename from docs/listings/snforge_advanced_features/crates/fuzz_testing/Scarb.toml rename to docs/listings/fuzz_testing/Scarb.toml index 147edffe81..a0a0076d75 100644 --- a/docs/listings/snforge_advanced_features/crates/fuzz_testing/Scarb.toml +++ b/docs/listings/fuzz_testing/Scarb.toml @@ -4,8 +4,11 @@ version = "0.1.0" edition = "2023_11" [dependencies] -snforge_std.workspace = true -assert_macros.workspace = true +starknet = "2.7.0" +assert_macros = "0.1.0" + +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } [[target.lib]] sierra = true diff --git a/docs/listings/snforge_advanced_features/crates/fuzz_testing/src/basic_example.cairo b/docs/listings/fuzz_testing/src/basic_example.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/fuzz_testing/src/basic_example.cairo rename to docs/listings/fuzz_testing/src/basic_example.cairo diff --git a/docs/listings/snforge_advanced_features/crates/fuzz_testing/src/lib.cairo b/docs/listings/fuzz_testing/src/lib.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/fuzz_testing/src/lib.cairo rename to docs/listings/fuzz_testing/src/lib.cairo diff --git a/docs/listings/snforge_advanced_features/crates/fuzz_testing/src/with_parameters.cairo b/docs/listings/fuzz_testing/src/with_parameters.cairo similarity index 100% rename from docs/listings/snforge_advanced_features/crates/fuzz_testing/src/with_parameters.cairo rename to docs/listings/fuzz_testing/src/with_parameters.cairo diff --git a/docs/listings/sncast_library/scripts/get_nonce/Scarb.toml b/docs/listings/get_nonce/Scarb.toml similarity index 58% rename from docs/listings/sncast_library/scripts/get_nonce/Scarb.toml rename to docs/listings/get_nonce/Scarb.toml index d908abfca9..3050533742 100644 --- a/docs/listings/sncast_library/scripts/get_nonce/Scarb.toml +++ b/docs/listings/get_nonce/Scarb.toml @@ -4,9 +4,9 @@ version = "0.1.0" edition = "2023_11" [dependencies] -starknet.workspace = true -snforge_std.workspace = true -sncast_std.workspace = true +starknet = "2.7.0" +snforge_std = { path = "../../../snforge_std" } +sncast_std = { path = "../../../sncast_std" } [[target.starknet-contract]] sierra = true diff --git a/docs/listings/sncast_library/scripts/get_nonce/src/lib.cairo b/docs/listings/get_nonce/src/lib.cairo similarity index 100% rename from docs/listings/sncast_library/scripts/get_nonce/src/lib.cairo rename to docs/listings/get_nonce/src/lib.cairo diff --git a/docs/listings/hello_snforge/Scarb.toml b/docs/listings/hello_snforge/Scarb.toml new file mode 100644 index 0000000000..364c9066d0 --- /dev/null +++ b/docs/listings/hello_snforge/Scarb.toml @@ -0,0 +1,18 @@ +[package] +name = "hello_snforge" +version = "0.1.0" +edition = "2023_11" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] +starknet = "2.7.0" + +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } + +[[target.starknet-contract]] +sierra = true + +[scripts] +test = "snforge test" diff --git a/docs/listings/hello_snforge/src/lib.cairo b/docs/listings/hello_snforge/src/lib.cairo new file mode 100644 index 0000000000..4955786578 --- /dev/null +++ b/docs/listings/hello_snforge/src/lib.cairo @@ -0,0 +1,25 @@ +#[starknet::interface] +pub trait IHelloStarknet { + fn increase_balance(ref self: TContractState, amount: felt252); + fn get_balance(self: @TContractState) -> felt252; +} + +#[starknet::contract] +mod HelloStarknet { + #[storage] + struct Storage { + balance: felt252, + } + + #[abi(embed_v0)] + impl HelloStarknetImpl of super::IHelloStarknet { + fn increase_balance(ref self: ContractState, amount: felt252) { + assert(amount != 0, 'Amount cannot be 0'); + self.balance.write(self.balance.read() + amount); + } + + fn get_balance(self: @ContractState) -> felt252 { + self.balance.read() + } + } +} diff --git a/docs/listings/hello_snforge/tests/test_contract.cairo b/docs/listings/hello_snforge/tests/test_contract.cairo new file mode 100644 index 0000000000..a747a94cd9 --- /dev/null +++ b/docs/listings/hello_snforge/tests/test_contract.cairo @@ -0,0 +1,14 @@ +#[test] +fn test_executing() { + assert(1 == 1, 1); +} + +#[test] +fn test_calling() { + assert(2 == 2, 2); +} + +#[test] +fn test_calling_another() { + assert(3 == 3, 3); +} diff --git a/docs/listings/hello_starknet/Scarb.toml b/docs/listings/hello_starknet/Scarb.toml new file mode 100644 index 0000000000..717985204b --- /dev/null +++ b/docs/listings/hello_starknet/Scarb.toml @@ -0,0 +1,18 @@ +[package] +name = "hello_starknet" +version = "0.1.0" +edition = "2023_11" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] +starknet = "2.7.0" + +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } + +[[target.starknet-contract]] +sierra = true + +[scripts] +test = "snforge test" diff --git a/docs/listings/hello_starknet/src/lib.cairo b/docs/listings/hello_starknet/src/lib.cairo new file mode 100644 index 0000000000..4955786578 --- /dev/null +++ b/docs/listings/hello_starknet/src/lib.cairo @@ -0,0 +1,25 @@ +#[starknet::interface] +pub trait IHelloStarknet { + fn increase_balance(ref self: TContractState, amount: felt252); + fn get_balance(self: @TContractState) -> felt252; +} + +#[starknet::contract] +mod HelloStarknet { + #[storage] + struct Storage { + balance: felt252, + } + + #[abi(embed_v0)] + impl HelloStarknetImpl of super::IHelloStarknet { + fn increase_balance(ref self: ContractState, amount: felt252) { + assert(amount != 0, 'Amount cannot be 0'); + self.balance.write(self.balance.read() + amount); + } + + fn get_balance(self: @ContractState) -> felt252 { + self.balance.read() + } + } +} diff --git a/docs/listings/hello_starknet/tests/test_contract.cairo b/docs/listings/hello_starknet/tests/test_contract.cairo new file mode 100644 index 0000000000..b1f395afc1 --- /dev/null +++ b/docs/listings/hello_starknet/tests/test_contract.cairo @@ -0,0 +1,47 @@ +use starknet::ContractAddress; + +use snforge_std::{declare, ContractClassTrait, DeclareResultTrait}; + +use hello_starknet::IHelloStarknetSafeDispatcher; +use hello_starknet::IHelloStarknetSafeDispatcherTrait; +use hello_starknet::IHelloStarknetDispatcher; +use hello_starknet::IHelloStarknetDispatcherTrait; + +fn deploy_contract(name: ByteArray) -> ContractAddress { + let contract = declare(name).unwrap().contract_class(); + let (contract_address, _) = contract.deploy(@ArrayTrait::new()).unwrap(); + contract_address +} + +#[test] +fn test_increase_balance() { + let contract_address = deploy_contract("HelloStarknet"); + + let dispatcher = IHelloStarknetDispatcher { contract_address }; + + let balance_before = dispatcher.get_balance(); + assert(balance_before == 0, 'Invalid balance'); + + dispatcher.increase_balance(42); + + let balance_after = dispatcher.get_balance(); + assert(balance_after == 42, 'Invalid balance'); +} + +#[test] +#[feature("safe_dispatcher")] +fn test_cannot_increase_balance_with_zero_value() { + let contract_address = deploy_contract("HelloStarknet"); + + let safe_dispatcher = IHelloStarknetSafeDispatcher { contract_address }; + + let balance_before = safe_dispatcher.get_balance().unwrap(); + assert(balance_before == 0, 'Invalid balance'); + + match safe_dispatcher.increase_balance(0) { + Result::Ok(_) => core::panic_with_felt252('Should have panicked'), + Result::Err(panic_data) => { + assert(*panic_data.at(0) == 'Amount cannot be 0', *panic_data.at(0)); + } + }; +} diff --git a/docs/listings/hello_workspaces/Scarb.toml b/docs/listings/hello_workspaces/Scarb.toml new file mode 100644 index 0000000000..8e47bbc6f5 --- /dev/null +++ b/docs/listings/hello_workspaces/Scarb.toml @@ -0,0 +1,34 @@ +[workspace] +members = [ + "crates/*", +] + +[workspace.scripts] +test = "snforge" + +[workspace.tool.snforge] + +[workspace.package] +version = "0.1.0" + +[package] +name = "hello_workspaces" +version.workspace = true +edition = "2023_10" + +[scripts] +test.workspace = true + +[tool] +snforge.workspace = true + +[dependencies] +fibonacci = { path = "crates/fibonacci" } +addition = { path = "crates/addition" } +starknet = "2.7.0" + +[workspace.dependencies] +snforge_std = { path = "../../../snforge_std" } + +[[target.starknet-contract]] +sierra = true diff --git a/docs/listings/hello_workspaces/crates/addition/Scarb.toml b/docs/listings/hello_workspaces/crates/addition/Scarb.toml new file mode 100644 index 0000000000..d67f97584f --- /dev/null +++ b/docs/listings/hello_workspaces/crates/addition/Scarb.toml @@ -0,0 +1,15 @@ +[package] +name = "addition" +version.workspace = true +edition = "2023_10" + +[dependencies] +starknet = "2.7.0" + +[dev-dependencies] +snforge_std.workspace = true + +[[target.starknet-contract]] +sierra = true + +[lib] diff --git a/docs/listings/hello_workspaces/crates/addition/src/lib.cairo b/docs/listings/hello_workspaces/crates/addition/src/lib.cairo new file mode 100644 index 0000000000..f53d0a379c --- /dev/null +++ b/docs/listings/hello_workspaces/crates/addition/src/lib.cairo @@ -0,0 +1,33 @@ +fn add(a: felt252, b: felt252) -> felt252 { + a + b +} + +#[starknet::interface] +trait IAdditionContract { + fn answer(ref self: TContractState) -> felt252; +} + +#[starknet::contract] +mod AdditionContract { + use addition::add; + + #[storage] + struct Storage {} + + #[abi(embed_v0)] + impl AdditionContractImpl of super::IAdditionContract { + fn answer(ref self: ContractState) -> felt252 { + add(10, 20) + } + } +} + +#[cfg(test)] +mod tests { + use super::add; + + #[test] + fn it_works() { + assert(add(2, 3) == 5, 'it works!'); + } +} diff --git a/docs/listings/hello_workspaces/crates/addition/tests/nested.cairo b/docs/listings/hello_workspaces/crates/addition/tests/nested.cairo new file mode 100644 index 0000000000..1ee9db3963 --- /dev/null +++ b/docs/listings/hello_workspaces/crates/addition/tests/nested.cairo @@ -0,0 +1,17 @@ +use snforge_std::declare; + +mod test_nested; + +fn foo() -> u8 { + 2 +} + +#[test] +fn simple_case() { + assert(1 == 1, 'simple check'); +} + +#[test] +fn contract_test() { + declare("AdditionContract").unwrap(); +} diff --git a/docs/listings/hello_workspaces/crates/addition/tests/nested/test_nested.cairo b/docs/listings/hello_workspaces/crates/addition/tests/nested/test_nested.cairo new file mode 100644 index 0000000000..5aa19b8adf --- /dev/null +++ b/docs/listings/hello_workspaces/crates/addition/tests/nested/test_nested.cairo @@ -0,0 +1,12 @@ +use super::foo; + +#[test] +fn test_two() { + assert(foo() == 2, 'foo() == 2'); +} + +#[test] +fn test_two_and_two() { + assert(2 == 2, '2 == 2'); + assert(2 == 2, '2 == 2'); +} diff --git a/docs/listings/hello_workspaces/crates/fibonacci/Scarb.toml b/docs/listings/hello_workspaces/crates/fibonacci/Scarb.toml new file mode 100644 index 0000000000..45378edf34 --- /dev/null +++ b/docs/listings/hello_workspaces/crates/fibonacci/Scarb.toml @@ -0,0 +1,23 @@ +[package] +name = "fibonacci" +version.workspace = true +edition = "2023_10" + +[scripts] +test.workspace = true + +[tool] +snforge.workspace = true + +[dependencies] +addition = { path = "../addition" } +starknet = "2.7.0" + +[dev-dependencies] +snforge_std.workspace = true + +[[target.starknet-contract]] +sierra = true +build-external-contracts = ["addition::AdditionContract"] + +[lib] diff --git a/docs/listings/hello_workspaces/crates/fibonacci/src/lib.cairo b/docs/listings/hello_workspaces/crates/fibonacci/src/lib.cairo new file mode 100644 index 0000000000..005d6453f2 --- /dev/null +++ b/docs/listings/hello_workspaces/crates/fibonacci/src/lib.cairo @@ -0,0 +1,39 @@ +use addition::add; + +fn fib(a: felt252, b: felt252, n: felt252) -> felt252 { + match n { + 0 => a, + _ => fib(b, add(a, b), n - 1), + } +} + +#[starknet::contract] +mod FibonacciContract { + use addition::add; + use fibonacci::fib; + + #[storage] + struct Storage {} + + #[abi(embed_v0)] + fn answer(ref self: ContractState) -> felt252 { + add(fib(0, 1, 16), fib(0, 1, 8)) + } +} + +#[cfg(test)] +mod tests { + use super::fib; + use snforge_std::declare; + + #[test] + fn it_works() { + assert(fib(0, 1, 16) == 987, 'it works!'); + } + + #[test] + fn contract_test() { + declare("FibonacciContract").unwrap(); + declare("AdditionContract").unwrap(); + } +} diff --git a/docs/listings/hello_workspaces/crates/fibonacci/tests/abc.cairo b/docs/listings/hello_workspaces/crates/fibonacci/tests/abc.cairo new file mode 100644 index 0000000000..8fbad19666 --- /dev/null +++ b/docs/listings/hello_workspaces/crates/fibonacci/tests/abc.cairo @@ -0,0 +1,10 @@ +mod efg; + +#[test] +fn abc_test() { + assert(foo() == 1, ''); +} + +fn foo() -> u8 { + 1 +} diff --git a/docs/listings/hello_workspaces/crates/fibonacci/tests/abc/efg.cairo b/docs/listings/hello_workspaces/crates/fibonacci/tests/abc/efg.cairo new file mode 100644 index 0000000000..b0c8f2a8b8 --- /dev/null +++ b/docs/listings/hello_workspaces/crates/fibonacci/tests/abc/efg.cairo @@ -0,0 +1,9 @@ +#[test] +fn efg_test() { + assert(super::foo() == 1, ''); +} + +#[test] +fn failing_test() { + assert(1 == 2, ''); +} diff --git a/docs/listings/hello_workspaces/crates/fibonacci/tests/lib.cairo b/docs/listings/hello_workspaces/crates/fibonacci/tests/lib.cairo new file mode 100644 index 0000000000..582c1efab6 --- /dev/null +++ b/docs/listings/hello_workspaces/crates/fibonacci/tests/lib.cairo @@ -0,0 +1,6 @@ +mod abc; + +#[test] +fn lib_test() { + assert(abc::foo() == 1, ''); +} diff --git a/docs/listings/hello_workspaces/crates/fibonacci/tests/not_collected.cairo b/docs/listings/hello_workspaces/crates/fibonacci/tests/not_collected.cairo new file mode 100644 index 0000000000..a4c1b8d76b --- /dev/null +++ b/docs/listings/hello_workspaces/crates/fibonacci/tests/not_collected.cairo @@ -0,0 +1,6 @@ +// should not be collected + +#[test] +fn not_collected() { + assert(1 == 1, ''); +} diff --git a/docs/listings/hello_workspaces/src/lib.cairo b/docs/listings/hello_workspaces/src/lib.cairo new file mode 100644 index 0000000000..a93dc5d461 --- /dev/null +++ b/docs/listings/hello_workspaces/src/lib.cairo @@ -0,0 +1,28 @@ +#[starknet::interface] +trait IFibContract { + fn answer(ref self: TContractState) -> felt252; +} + +#[starknet::contract] +mod FibContract { + use addition::add; + use fibonacci::fib; + + #[storage] + struct Storage {} + + #[abi(embed_v0)] + impl FibContractImpl of super::IFibContract { + fn answer(ref self: ContractState) -> felt252 { + add(fib(0, 1, 16), fib(0, 1, 8)) + } + } +} + +#[cfg(test)] +mod tests { + #[test] + fn test_simple() { + assert(1 == 1, 1); + } +} diff --git a/docs/listings/hello_workspaces/tests/test_failing.cairo b/docs/listings/hello_workspaces/tests/test_failing.cairo new file mode 100644 index 0000000000..864786023b --- /dev/null +++ b/docs/listings/hello_workspaces/tests/test_failing.cairo @@ -0,0 +1,9 @@ +#[test] +fn test_failing() { + assert(1 == 2, 'failing check'); +} + +#[test] +fn test_another_failing() { + assert(2 == 3, 'failing check'); +} diff --git a/docs/listings/ignoring_example/Scarb.toml b/docs/listings/ignoring_example/Scarb.toml new file mode 100644 index 0000000000..6ce2d88b2d --- /dev/null +++ b/docs/listings/ignoring_example/Scarb.toml @@ -0,0 +1,16 @@ +[package] +name = "ignoring_example" +version = "0.1.0" +edition = "2023_11" + +[dependencies] +starknet = "2.7.0" + +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } + +[[target.starknet-contract]] +sierra = true + +[scripts] +test = "snforge test" diff --git a/docs/listings/ignoring_example/src/lib.cairo b/docs/listings/ignoring_example/src/lib.cairo new file mode 100644 index 0000000000..f76a6eede4 --- /dev/null +++ b/docs/listings/ignoring_example/src/lib.cairo @@ -0,0 +1,8 @@ +#[cfg(test)] +mod tests { + #[test] + #[ignore] + fn ignored_test() { // test code + } +} + diff --git a/docs/listings/sncast_library/Scarb.toml b/docs/listings/invoke/Scarb.toml similarity index 70% rename from docs/listings/sncast_library/Scarb.toml rename to docs/listings/invoke/Scarb.toml index 660b958f63..55ed304196 100644 --- a/docs/listings/sncast_library/Scarb.toml +++ b/docs/listings/invoke/Scarb.toml @@ -1,7 +1,9 @@ -[workspace] -members = ["scripts/*"] +[package] +name = "invoke" +version = "0.1.0" +edition = "2023_11" -[workspace.dependencies] +[dependencies] starknet = "2.7.0" snforge_std = { path = "../../../snforge_std" } sncast_std = { path = "../../../sncast_std" } diff --git a/docs/listings/sncast_library/scripts/invoke/src/lib.cairo b/docs/listings/invoke/src/lib.cairo similarity index 100% rename from docs/listings/sncast_library/scripts/invoke/src/lib.cairo rename to docs/listings/invoke/src/lib.cairo diff --git a/docs/listings/sncast_overview/crates/map3/Scarb.toml b/docs/listings/map3/Scarb.toml similarity index 73% rename from docs/listings/sncast_overview/crates/map3/Scarb.toml rename to docs/listings/map3/Scarb.toml index 4dec1caab6..0e4e7d558a 100644 --- a/docs/listings/sncast_overview/crates/map3/Scarb.toml +++ b/docs/listings/map3/Scarb.toml @@ -10,8 +10,8 @@ sierra = true sierra = false [dependencies] -snforge_std.workspace = true -starknet.workspace = true +snforge_std = { path = "../../../snforge_std" } +starknet = "2.7.0" [scripts] test = "snforge test" diff --git a/docs/listings/sncast_overview/snfoundry.toml b/docs/listings/map3/snfoundry.toml similarity index 100% rename from docs/listings/sncast_overview/snfoundry.toml rename to docs/listings/map3/snfoundry.toml diff --git a/docs/listings/sncast_overview/crates/map3/src/lib.cairo b/docs/listings/map3/src/lib.cairo similarity index 100% rename from docs/listings/sncast_overview/crates/map3/src/lib.cairo rename to docs/listings/map3/src/lib.cairo diff --git a/docs/listings/panicking_test/Scarb.toml b/docs/listings/panicking_test/Scarb.toml new file mode 100644 index 0000000000..ef03e9c5e4 --- /dev/null +++ b/docs/listings/panicking_test/Scarb.toml @@ -0,0 +1,16 @@ +[package] +name = "panicking_test" +version = "0.1.0" +edition = "2023_11" + +[dependencies] +starknet = "2.7.0" + +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } + +[[target.starknet-contract]] +sierra = true + +[scripts] +test = "snforge test" diff --git a/docs/listings/snforge_overview/crates/writing_tests/src/panicking_tests.cairo b/docs/listings/panicking_test/src/lib.cairo similarity index 54% rename from docs/listings/snforge_overview/crates/writing_tests/src/panicking_tests.cairo rename to docs/listings/panicking_test/src/lib.cairo index f9701e34dd..eea1bbbdfe 100644 --- a/docs/listings/snforge_overview/crates/writing_tests/src/panicking_tests.cairo +++ b/docs/listings/panicking_test/src/lib.cairo @@ -1,7 +1,6 @@ -//ANCHOR:first_half fn panicking_function() { let mut data = array![]; - data.append('aaa'); + data.append('panic message'); panic(data) } @@ -10,14 +9,8 @@ mod tests { use super::panicking_function; #[test] - //ANCHOR_END:first_half - #[should_panic(expected: 'aaa')] - //ANCHOR:second_half fn failing() { panicking_function(); assert(2 == 2, '2 == 2'); } } -//ANCHOR_END:second_half - -mod dummy {} // trick `scarb fmt --check` diff --git a/docs/listings/should_panic_example/Scarb.toml b/docs/listings/should_panic_example/Scarb.toml new file mode 100644 index 0000000000..7980eeca8d --- /dev/null +++ b/docs/listings/should_panic_example/Scarb.toml @@ -0,0 +1,16 @@ +[package] +name = "should_panic_example" +version = "0.1.0" +edition = "2023_11" + +[dependencies] +starknet = "2.7.0" + +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } + +[[target.starknet-contract]] +sierra = true + +[scripts] +test = "snforge test" diff --git a/docs/listings/should_panic_example/src/lib.cairo b/docs/listings/should_panic_example/src/lib.cairo new file mode 100644 index 0000000000..fc59c2ac77 --- /dev/null +++ b/docs/listings/should_panic_example/src/lib.cairo @@ -0,0 +1,45 @@ +#[cfg(test)] +mod tests { + //ANCHOR:byte_array + #[test] + #[should_panic(expected: "This will panic")] + fn should_panic_exact() { + panic!("This will panic"); + } + + // here the expected message is a substring of the actual message + #[test] + #[should_panic(expected: "will panic")] + fn should_panic_expected_is_substring() { + panic!("This will panic"); + } + //ANCHOR_END:byte_array + + //ANCHOR:felt + #[test] + #[should_panic(expected: 'panic message')] + fn should_panic_felt_matching() { + assert(1 != 1, 'panic message'); + } + //ANCHOR_END:felt + + //ANCHOR:tuple + use core::panic_with_felt252; + + #[test] + #[should_panic(expected: ('panic message',))] + fn should_panic_check_data() { + panic_with_felt252('panic message'); + } + + // works for multiple messages + #[test] + #[should_panic(expected: ('panic message', 'second message',))] + fn should_panic_multiple_messages() { + let mut arr = ArrayTrait::new(); + arr.append('panic message'); + arr.append('second message'); + panic(arr); + } + //ANCHOR_END:tuple +} diff --git a/docs/listings/sncast_library/scripts/invoke/Scarb.toml b/docs/listings/sncast_library/scripts/invoke/Scarb.toml deleted file mode 100644 index 1936363e8c..0000000000 --- a/docs/listings/sncast_library/scripts/invoke/Scarb.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "invoke" -version = "0.1.0" -edition = "2023_11" - -[dependencies] -starknet.workspace = true -snforge_std.workspace = true -sncast_std.workspace = true - -[[target.starknet-contract]] -sierra = true - -[scripts] -test = "snforge test" diff --git a/docs/listings/sncast_overview/.gitignore b/docs/listings/sncast_overview/.gitignore deleted file mode 100644 index a1d8daa50d..0000000000 --- a/docs/listings/sncast_overview/.gitignore +++ /dev/null @@ -1 +0,0 @@ -scripts/**/*state.json diff --git a/docs/listings/snforge_overview/crates/testing_smart_contracts/Scarb.toml b/docs/listings/snforge_overview/crates/testing_smart_contracts/Scarb.toml deleted file mode 100644 index 2a22bc631a..0000000000 --- a/docs/listings/snforge_overview/crates/testing_smart_contracts/Scarb.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "testing_smart_contracts" -version = "0.1.0" -edition = "2023_11" - -[dependencies] -starknet.workspace = true -snforge_std.workspace = true - -[[target.starknet-contract]] -sierra = true - -[scripts] -test = "snforge test" diff --git a/docs/listings/snforge_overview/crates/testing_smart_contracts/src/lib.cairo b/docs/listings/snforge_overview/crates/testing_smart_contracts/src/lib.cairo deleted file mode 100644 index 7a2182058d..0000000000 --- a/docs/listings/snforge_overview/crates/testing_smart_contracts/src/lib.cairo +++ /dev/null @@ -1,2 +0,0 @@ -pub mod simple_contract; -pub mod handling_errors; diff --git a/docs/listings/snforge_overview/crates/using_cheatcodes/Scarb.toml b/docs/listings/snforge_overview/crates/using_cheatcodes/Scarb.toml deleted file mode 100644 index 537128dcfb..0000000000 --- a/docs/listings/snforge_overview/crates/using_cheatcodes/Scarb.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "using_cheatcodes" -version = "0.1.0" -edition = "2023_11" - -[dependencies] -starknet.workspace = true -snforge_std.workspace = true -assert_macros.workspace = true - -[[target.starknet-contract]] -sierra = true - -[scripts] -test = "snforge test" diff --git a/docs/listings/snforge_overview/crates/using_cheatcodes/tests/caller_address.cairo b/docs/listings/snforge_overview/crates/using_cheatcodes/tests/caller_address.cairo deleted file mode 100644 index 5d6f615f9c..0000000000 --- a/docs/listings/snforge_overview/crates/using_cheatcodes/tests/caller_address.cairo +++ /dev/null @@ -1,5 +0,0 @@ -pub mod failing; -pub mod proper_use; -pub mod proper_use_global; -pub mod cancel; -pub mod span; diff --git a/docs/listings/snforge_overview/crates/writing_tests/Scarb.toml b/docs/listings/snforge_overview/crates/writing_tests/Scarb.toml deleted file mode 100644 index f3f793dab6..0000000000 --- a/docs/listings/snforge_overview/crates/writing_tests/Scarb.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "writing_tests" -version = "0.1.0" -edition = "2023_11" - -[dependencies] -starknet.workspace = true -snforge_std.workspace = true - -[[target.starknet-contract]] -sierra = true - -[scripts] -test = "snforge test" diff --git a/docs/listings/snforge_overview/crates/writing_tests/src/lib.cairo b/docs/listings/snforge_overview/crates/writing_tests/src/lib.cairo deleted file mode 100644 index dd518b4752..0000000000 --- a/docs/listings/snforge_overview/crates/writing_tests/src/lib.cairo +++ /dev/null @@ -1,2 +0,0 @@ -pub mod first_test; -pub mod panicking_tests; diff --git a/docs/listings/snforge_overview/crates/writing_tests/tests/expected_failures.cairo b/docs/listings/snforge_overview/crates/writing_tests/tests/expected_failures.cairo deleted file mode 100644 index da698c1a57..0000000000 --- a/docs/listings/snforge_overview/crates/writing_tests/tests/expected_failures.cairo +++ /dev/null @@ -1,44 +0,0 @@ -//ANCHOR:byte_array -#[test] -#[should_panic(expected: "This will panic")] -fn should_panic_exact() { - panic!("This will panic"); -} - -// here the expected message is a substring of the actual message -#[test] -#[should_panic(expected: "will panic")] -fn should_panic_expected_is_substring() { - panic!("This will panic"); -} -//ANCHOR_END:byte_array - -//ANCHOR:felt -#[test] -#[should_panic(expected: 'panic message')] -fn should_panic_felt_matching() { - assert(1 != 1, 'panic message'); -} -//ANCHOR_END:felt - -//ANCHOR:tuple -use core::panic_with_felt252; - -#[test] -#[should_panic(expected: ('panic message',))] -fn should_panic_check_data() { - panic_with_felt252('panic message'); -} - -// works for multiple messages -#[test] -#[should_panic(expected: ('panic message', 'second message',))] -fn should_panic_multiple_messages() { - let mut arr = ArrayTrait::new(); - arr.append('panic message'); - arr.append('second message'); - panic(arr); -} -//ANCHOR_END:tuple - -mod dummy {} // trick `scarb fmt -c` diff --git a/docs/listings/snforge_overview/crates/writing_tests/tests/ignoring.cairo b/docs/listings/snforge_overview/crates/writing_tests/tests/ignoring.cairo deleted file mode 100644 index e9d1988135..0000000000 --- a/docs/listings/snforge_overview/crates/writing_tests/tests/ignoring.cairo +++ /dev/null @@ -1,4 +0,0 @@ -#[test] -#[ignore] -fn ignored_test() { // test code -} diff --git a/docs/listings/snforge_overview/crates/testing_contract_internals/Scarb.toml b/docs/listings/testing_contract_internals/Scarb.toml similarity index 67% rename from docs/listings/snforge_overview/crates/testing_contract_internals/Scarb.toml rename to docs/listings/testing_contract_internals/Scarb.toml index fd0ff87b5c..05aab81c8a 100644 --- a/docs/listings/snforge_overview/crates/testing_contract_internals/Scarb.toml +++ b/docs/listings/testing_contract_internals/Scarb.toml @@ -4,8 +4,10 @@ version = "0.1.0" edition = "2023_11" [dependencies] -starknet.workspace = true -snforge_std.workspace = true +starknet = "2.7.0" + +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } [[target.starknet-contract]] sierra = true diff --git a/docs/listings/snforge_overview/crates/testing_contract_internals/src/basic_example.cairo b/docs/listings/testing_contract_internals/src/basic_example.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_contract_internals/src/basic_example.cairo rename to docs/listings/testing_contract_internals/src/basic_example.cairo diff --git a/docs/listings/snforge_overview/crates/testing_contract_internals/src/lib.cairo b/docs/listings/testing_contract_internals/src/lib.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_contract_internals/src/lib.cairo rename to docs/listings/testing_contract_internals/src/lib.cairo diff --git a/docs/listings/snforge_overview/crates/testing_contract_internals/src/spying_for_events.cairo b/docs/listings/testing_contract_internals/src/spying_for_events.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_contract_internals/src/spying_for_events.cairo rename to docs/listings/testing_contract_internals/src/spying_for_events.cairo diff --git a/docs/listings/snforge_overview/crates/testing_contract_internals/src/using_library_calls.cairo b/docs/listings/testing_contract_internals/src/using_library_calls.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_contract_internals/src/using_library_calls.cairo rename to docs/listings/testing_contract_internals/src/using_library_calls.cairo diff --git a/docs/listings/snforge_overview/crates/testing_contract_internals/tests/lib.cairo b/docs/listings/testing_contract_internals/tests/lib.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_contract_internals/tests/lib.cairo rename to docs/listings/testing_contract_internals/tests/lib.cairo diff --git a/docs/listings/snforge_overview/crates/testing_contract_internals/tests/mocking_the_context_info.cairo b/docs/listings/testing_contract_internals/tests/mocking_the_context_info.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_contract_internals/tests/mocking_the_context_info.cairo rename to docs/listings/testing_contract_internals/tests/mocking_the_context_info.cairo diff --git a/docs/listings/snforge_overview/crates/testing_contract_internals/tests/spying_for_events.cairo b/docs/listings/testing_contract_internals/tests/spying_for_events.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_contract_internals/tests/spying_for_events.cairo rename to docs/listings/testing_contract_internals/tests/spying_for_events.cairo diff --git a/docs/listings/snforge_overview/crates/testing_contract_internals/tests/spying_for_events/syscall_tests.cairo b/docs/listings/testing_contract_internals/tests/spying_for_events/syscall_tests.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_contract_internals/tests/spying_for_events/syscall_tests.cairo rename to docs/listings/testing_contract_internals/tests/spying_for_events/syscall_tests.cairo diff --git a/docs/listings/snforge_overview/crates/testing_contract_internals/tests/spying_for_events/tests.cairo b/docs/listings/testing_contract_internals/tests/spying_for_events/tests.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_contract_internals/tests/spying_for_events/tests.cairo rename to docs/listings/testing_contract_internals/tests/spying_for_events/tests.cairo diff --git a/docs/listings/snforge_overview/crates/testing_contract_internals/tests/using_library_calls.cairo b/docs/listings/testing_contract_internals/tests/using_library_calls.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_contract_internals/tests/using_library_calls.cairo rename to docs/listings/testing_contract_internals/tests/using_library_calls.cairo diff --git a/docs/listings/snforge_overview/crates/testing_events/Scarb.toml b/docs/listings/testing_events/Scarb.toml similarity index 65% rename from docs/listings/snforge_overview/crates/testing_events/Scarb.toml rename to docs/listings/testing_events/Scarb.toml index b712ac493f..bb14cc408c 100644 --- a/docs/listings/snforge_overview/crates/testing_events/Scarb.toml +++ b/docs/listings/testing_events/Scarb.toml @@ -4,8 +4,10 @@ version = "0.1.0" edition = "2023_11" [dependencies] -starknet.workspace = true -snforge_std.workspace = true +starknet = "2.7.0" + +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } [[target.starknet-contract]] sierra = true diff --git a/docs/listings/snforge_overview/crates/testing_events/src/contract.cairo b/docs/listings/testing_events/src/contract.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_events/src/contract.cairo rename to docs/listings/testing_events/src/contract.cairo diff --git a/docs/listings/snforge_overview/crates/testing_events/src/lib.cairo b/docs/listings/testing_events/src/lib.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_events/src/lib.cairo rename to docs/listings/testing_events/src/lib.cairo diff --git a/docs/listings/snforge_overview/crates/testing_events/src/syscall.cairo b/docs/listings/testing_events/src/syscall.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_events/src/syscall.cairo rename to docs/listings/testing_events/src/syscall.cairo diff --git a/docs/listings/snforge_overview/crates/testing_events/src/syscall_dummy.cairo b/docs/listings/testing_events/src/syscall_dummy.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_events/src/syscall_dummy.cairo rename to docs/listings/testing_events/src/syscall_dummy.cairo diff --git a/docs/listings/snforge_overview/crates/testing_events/tests/assert_emitted.cairo b/docs/listings/testing_events/tests/assert_emitted.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_events/tests/assert_emitted.cairo rename to docs/listings/testing_events/tests/assert_emitted.cairo diff --git a/docs/listings/snforge_overview/crates/testing_events/tests/assert_manually.cairo b/docs/listings/testing_events/tests/assert_manually.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_events/tests/assert_manually.cairo rename to docs/listings/testing_events/tests/assert_manually.cairo diff --git a/docs/listings/snforge_overview/crates/testing_events/tests/filter.cairo b/docs/listings/testing_events/tests/filter.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_events/tests/filter.cairo rename to docs/listings/testing_events/tests/filter.cairo diff --git a/docs/listings/snforge_overview/crates/testing_events/tests/syscall.cairo b/docs/listings/testing_events/tests/syscall.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_events/tests/syscall.cairo rename to docs/listings/testing_events/tests/syscall.cairo diff --git a/docs/listings/snforge_overview/crates/testing_messages_to_l1/Scarb.toml b/docs/listings/testing_messages_to_l1/Scarb.toml similarity index 66% rename from docs/listings/snforge_overview/crates/testing_messages_to_l1/Scarb.toml rename to docs/listings/testing_messages_to_l1/Scarb.toml index bee7f589eb..892751fe9f 100644 --- a/docs/listings/snforge_overview/crates/testing_messages_to_l1/Scarb.toml +++ b/docs/listings/testing_messages_to_l1/Scarb.toml @@ -4,8 +4,10 @@ version = "0.1.0" edition = "2023_11" [dependencies] -starknet.workspace = true -snforge_std.workspace = true +starknet = "2.7.0" + +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } [[target.starknet-contract]] sierra = true diff --git a/docs/listings/snforge_overview/crates/testing_messages_to_l1/src/lib.cairo b/docs/listings/testing_messages_to_l1/src/lib.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_messages_to_l1/src/lib.cairo rename to docs/listings/testing_messages_to_l1/src/lib.cairo diff --git a/docs/listings/snforge_overview/crates/testing_messages_to_l1/tests/detailed.cairo b/docs/listings/testing_messages_to_l1/tests/detailed.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_messages_to_l1/tests/detailed.cairo rename to docs/listings/testing_messages_to_l1/tests/detailed.cairo diff --git a/docs/listings/snforge_overview/crates/testing_messages_to_l1/tests/lib.cairo b/docs/listings/testing_messages_to_l1/tests/lib.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_messages_to_l1/tests/lib.cairo rename to docs/listings/testing_messages_to_l1/tests/lib.cairo diff --git a/docs/listings/snforge_overview/crates/testing_messages_to_l1/tests/simple.cairo b/docs/listings/testing_messages_to_l1/tests/simple.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_messages_to_l1/tests/simple.cairo rename to docs/listings/testing_messages_to_l1/tests/simple.cairo diff --git a/docs/listings/testing_smart_contracts_handling_errors/Scarb.toml b/docs/listings/testing_smart_contracts_handling_errors/Scarb.toml new file mode 100644 index 0000000000..90c0ebf9ad --- /dev/null +++ b/docs/listings/testing_smart_contracts_handling_errors/Scarb.toml @@ -0,0 +1,16 @@ +[package] +name = "testing_smart_contracts_handling_errors" +version = "0.1.0" +edition = "2023_11" + +[dependencies] +starknet = "2.7.0" + +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } + +[[target.starknet-contract]] +sierra = true + +[scripts] +test = "snforge test" diff --git a/docs/listings/snforge_overview/crates/testing_smart_contracts/src/handling_errors.cairo b/docs/listings/testing_smart_contracts_handling_errors/src/lib.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_smart_contracts/src/handling_errors.cairo rename to docs/listings/testing_smart_contracts_handling_errors/src/lib.cairo diff --git a/docs/listings/snforge_overview/crates/testing_smart_contracts/tests/handle_panic.cairo b/docs/listings/testing_smart_contracts_handling_errors/tests/handle_panic.cairo similarity index 95% rename from docs/listings/snforge_overview/crates/testing_smart_contracts/tests/handle_panic.cairo rename to docs/listings/testing_smart_contracts_handling_errors/tests/handle_panic.cairo index ec8d8b2537..ea182b9100 100644 --- a/docs/listings/snforge_overview/crates/testing_smart_contracts/tests/handle_panic.cairo +++ b/docs/listings/testing_smart_contracts_handling_errors/tests/handle_panic.cairo @@ -2,7 +2,7 @@ use snforge_std::byte_array::try_deserialize_bytearray_error; use snforge_std::{declare, ContractClassTrait, DeclareResultTrait}; -use testing_smart_contracts::handling_errors::{ +use testing_smart_contracts_handling_errors::{ IPanicContractSafeDispatcher, IPanicContractSafeDispatcherTrait }; diff --git a/docs/listings/snforge_overview/crates/testing_smart_contracts/tests/panic.cairo b/docs/listings/testing_smart_contracts_handling_errors/tests/panic.cairo similarity index 84% rename from docs/listings/snforge_overview/crates/testing_smart_contracts/tests/panic.cairo rename to docs/listings/testing_smart_contracts_handling_errors/tests/panic.cairo index d42ec2108d..5bdd7006fd 100644 --- a/docs/listings/snforge_overview/crates/testing_smart_contracts/tests/panic.cairo +++ b/docs/listings/testing_smart_contracts_handling_errors/tests/panic.cairo @@ -1,13 +1,12 @@ //ANCHOR:first_half use snforge_std::{declare, ContractClassTrait, DeclareResultTrait}; -use testing_smart_contracts::handling_errors::{ +use testing_smart_contracts_handling_errors::{ IPanicContractDispatcher, IPanicContractDispatcherTrait }; #[test] //ANCHOR_END:first_half -#[should_panic(expected: ('PANIC', 'DAYTAH'))] //ANCHOR:second_half fn failing() { let contract = declare("PanicContract").unwrap().contract_class(); diff --git a/docs/listings/testing_smart_contracts_safe_dispatcher/Scarb.toml b/docs/listings/testing_smart_contracts_safe_dispatcher/Scarb.toml new file mode 100644 index 0000000000..571443a88d --- /dev/null +++ b/docs/listings/testing_smart_contracts_safe_dispatcher/Scarb.toml @@ -0,0 +1,16 @@ +[package] +name = "testing_smart_contracts_safe_dispatcher" +version = "0.1.0" +edition = "2023_11" + +[dependencies] +starknet = "2.7.0" + +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } + +[[target.starknet-contract]] +sierra = true + +[scripts] +test = "snforge test" diff --git a/docs/listings/testing_smart_contracts_safe_dispatcher/src/lib.cairo b/docs/listings/testing_smart_contracts_safe_dispatcher/src/lib.cairo new file mode 100644 index 0000000000..be964fec2a --- /dev/null +++ b/docs/listings/testing_smart_contracts_safe_dispatcher/src/lib.cairo @@ -0,0 +1,26 @@ +#[starknet::interface] +pub trait IPanicContract { + fn do_a_panic(self: @TContractState); + fn do_a_string_panic(self: @TContractState); +} + +#[starknet::contract] +pub mod PanicContract { + use core::array::ArrayTrait; + + #[storage] + struct Storage {} + + #[abi(embed_v0)] + pub impl PanicContractImpl of super::IPanicContract { + // Panics + fn do_a_panic(self: @ContractState) { + panic(array!['PANIC', 'DAYTAH']); + } + + fn do_a_string_panic(self: @ContractState) { + // A macro which allows panicking with a ByteArray (string) instance + panic!("This is panicking with a string, which can be longer than 31 characters"); + } + } +} diff --git a/docs/listings/snforge_overview/crates/testing_smart_contracts/tests/safe_dispatcher.cairo b/docs/listings/testing_smart_contracts_safe_dispatcher/tests/safe_dispatcher.cairo similarity index 93% rename from docs/listings/snforge_overview/crates/testing_smart_contracts/tests/safe_dispatcher.cairo rename to docs/listings/testing_smart_contracts_safe_dispatcher/tests/safe_dispatcher.cairo index 779c9c6ab2..56ca89580a 100644 --- a/docs/listings/snforge_overview/crates/testing_smart_contracts/tests/safe_dispatcher.cairo +++ b/docs/listings/testing_smart_contracts_safe_dispatcher/tests/safe_dispatcher.cairo @@ -1,6 +1,6 @@ use snforge_std::{declare, ContractClassTrait, DeclareResultTrait}; -use testing_smart_contracts::handling_errors::{ +use testing_smart_contracts_safe_dispatcher::{ IPanicContractSafeDispatcher, IPanicContractSafeDispatcherTrait }; diff --git a/docs/listings/testing_smart_contracts_writing_tests/Scarb.toml b/docs/listings/testing_smart_contracts_writing_tests/Scarb.toml new file mode 100644 index 0000000000..234185fba5 --- /dev/null +++ b/docs/listings/testing_smart_contracts_writing_tests/Scarb.toml @@ -0,0 +1,16 @@ +[package] +name = "testing_smart_contracts_writing_tests" +version = "0.1.0" +edition = "2023_11" + +[dependencies] +starknet = "2.7.0" + +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } + +[[target.starknet-contract]] +sierra = true + +[scripts] +test = "snforge test" diff --git a/docs/listings/snforge_overview/crates/testing_smart_contracts/src/simple_contract.cairo b/docs/listings/testing_smart_contracts_writing_tests/src/lib.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/testing_smart_contracts/src/simple_contract.cairo rename to docs/listings/testing_smart_contracts_writing_tests/src/lib.cairo diff --git a/docs/listings/snforge_overview/crates/testing_smart_contracts/tests/simple_contract.cairo b/docs/listings/testing_smart_contracts_writing_tests/tests/simple_contract.cairo similarity index 95% rename from docs/listings/snforge_overview/crates/testing_smart_contracts/tests/simple_contract.cairo rename to docs/listings/testing_smart_contracts_writing_tests/tests/simple_contract.cairo index 11a6a32451..c47b4ed808 100644 --- a/docs/listings/snforge_overview/crates/testing_smart_contracts/tests/simple_contract.cairo +++ b/docs/listings/testing_smart_contracts_writing_tests/tests/simple_contract.cairo @@ -1,6 +1,6 @@ use snforge_std::{declare, ContractClassTrait, DeclareResultTrait}; -use testing_smart_contracts::simple_contract::{ +use testing_smart_contracts_writing_tests::{ ISimpleContractDispatcher, ISimpleContractDispatcherTrait }; diff --git a/docs/listings/sncast_library/scripts/tx_status/Scarb.toml b/docs/listings/tx_status/Scarb.toml similarity index 58% rename from docs/listings/sncast_library/scripts/tx_status/Scarb.toml rename to docs/listings/tx_status/Scarb.toml index 5a3a2a08ae..1b98344e94 100644 --- a/docs/listings/sncast_library/scripts/tx_status/Scarb.toml +++ b/docs/listings/tx_status/Scarb.toml @@ -4,9 +4,9 @@ version = "0.1.0" edition = "2023_11" [dependencies] -starknet.workspace = true -snforge_std.workspace = true -sncast_std.workspace = true +starknet = "2.7.0" +snforge_std = { path = "../../../snforge_std" } +sncast_std = { path = "../../../sncast_std" } [[target.starknet-contract]] sierra = true diff --git a/docs/listings/sncast_library/scripts/tx_status/src/lib.cairo b/docs/listings/tx_status/src/lib.cairo similarity index 100% rename from docs/listings/sncast_library/scripts/tx_status/src/lib.cairo rename to docs/listings/tx_status/src/lib.cairo diff --git a/docs/listings/snforge_overview/Scarb.toml b/docs/listings/using_cheatcodes/Scarb.toml similarity index 60% rename from docs/listings/snforge_overview/Scarb.toml rename to docs/listings/using_cheatcodes/Scarb.toml index 437d4c716e..70ab8ea626 100644 --- a/docs/listings/snforge_overview/Scarb.toml +++ b/docs/listings/using_cheatcodes/Scarb.toml @@ -1,11 +1,15 @@ -[workspace] -members = ["crates/*"] +[package] +name = "using_cheatcodes" +version = "0.1.0" +edition = "2023_11" -[workspace.dependencies] +[dependencies] starknet = "2.7.0" -snforge_std = { path = "../../../snforge_std" } assert_macros = "0.1.0" +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } + [[target.starknet-contract]] sierra = true diff --git a/docs/listings/snforge_overview/crates/using_cheatcodes/src/lib.cairo b/docs/listings/using_cheatcodes/src/lib.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/using_cheatcodes/src/lib.cairo rename to docs/listings/using_cheatcodes/src/lib.cairo diff --git a/docs/listings/snforge_overview/crates/using_cheatcodes/tests/caller_address/failing.cairo b/docs/listings/using_cheatcodes/tests/lib.cairo similarity index 77% rename from docs/listings/snforge_overview/crates/using_cheatcodes/tests/caller_address/failing.cairo rename to docs/listings/using_cheatcodes/tests/lib.cairo index a44eac2e7e..646dfdf4ea 100644 --- a/docs/listings/snforge_overview/crates/using_cheatcodes/tests/caller_address/failing.cairo +++ b/docs/listings/using_cheatcodes/tests/lib.cairo @@ -1,11 +1,7 @@ -//ANCHOR:first_half use snforge_std::{declare, ContractClassTrait, DeclareResultTrait}; use using_cheatcodes::{ICheatcodeCheckerDispatcher, ICheatcodeCheckerDispatcherTrait}; #[test] -//ANCHOR_END:first_half -#[should_panic(expected: 'user is not allowed')] -//ANCHOR:second_half fn call_and_invoke() { let contract = declare("CheatcodeChecker").unwrap().contract_class(); let (contract_address, _) = contract.deploy(@array![]).unwrap(); @@ -19,6 +15,3 @@ fn call_and_invoke() { let balance = dispatcher.get_balance(); assert(balance == 100, 'balance == 100'); } -//ANCHOR_END:second_half - -mod dummy {} // trick `scarb fmt -c` diff --git a/docs/listings/using_cheatcodes_cancelling_cheat/Scarb.toml b/docs/listings/using_cheatcodes_cancelling_cheat/Scarb.toml new file mode 100644 index 0000000000..ec3efea5ea --- /dev/null +++ b/docs/listings/using_cheatcodes_cancelling_cheat/Scarb.toml @@ -0,0 +1,17 @@ +[package] +name = "using_cheatcodes_cancelling_cheat" +version = "0.1.0" +edition = "2023_11" + +[dependencies] +starknet = "2.7.0" +assert_macros = "0.1.0" + +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } + +[[target.starknet-contract]] +sierra = true + +[scripts] +test = "snforge test" diff --git a/docs/listings/using_cheatcodes_cancelling_cheat/src/lib.cairo b/docs/listings/using_cheatcodes_cancelling_cheat/src/lib.cairo new file mode 100644 index 0000000000..b6c20ffcad --- /dev/null +++ b/docs/listings/using_cheatcodes_cancelling_cheat/src/lib.cairo @@ -0,0 +1,55 @@ +#[starknet::interface] +pub trait ICheatcodeChecker { + fn increase_balance(ref self: TContractState, amount: felt252); + fn get_balance(self: @TContractState) -> felt252; + fn get_block_number_at_construction(self: @TContractState) -> u64; + fn get_block_timestamp_at_construction(self: @TContractState) -> u64; +} + +#[starknet::contract] +pub mod CheatcodeChecker { + use core::box::BoxTrait; + use starknet::get_caller_address; + + #[storage] + struct Storage { + balance: felt252, + blk_nb: u64, + blk_timestamp: u64, + } + + #[constructor] + fn constructor(ref self: ContractState) { + // store the current block number + self.blk_nb.write(starknet::get_block_info().unbox().block_number); + // store the current block timestamp + self.blk_timestamp.write(starknet::get_block_info().unbox().block_timestamp); + } + + #[abi(embed_v0)] + impl ICheatcodeCheckerImpl of super::ICheatcodeChecker { + // Increases the balance by the given amount + fn increase_balance(ref self: ContractState, amount: felt252) { + assert_is_allowed_user(); + self.balance.write(self.balance.read() + amount); + } + // Gets the balance. + fn get_balance(self: @ContractState) -> felt252 { + self.balance.read() + } + // Gets the block number + fn get_block_number_at_construction(self: @ContractState) -> u64 { + self.blk_nb.read() + } + // Gets the block timestamp + fn get_block_timestamp_at_construction(self: @ContractState) -> u64 { + self.blk_timestamp.read() + } + } + + fn assert_is_allowed_user() { + // checks if caller is '123' + let address = get_caller_address(); + assert(address.into() == 123, 'user is not allowed'); + } +} diff --git a/docs/listings/snforge_overview/crates/using_cheatcodes/tests/caller_address/cancel.cairo b/docs/listings/using_cheatcodes_cancelling_cheat/tests/lib.cairo similarity index 80% rename from docs/listings/snforge_overview/crates/using_cheatcodes/tests/caller_address/cancel.cairo rename to docs/listings/using_cheatcodes_cancelling_cheat/tests/lib.cairo index 2b550e0068..3024c98a43 100644 --- a/docs/listings/snforge_overview/crates/using_cheatcodes/tests/caller_address/cancel.cairo +++ b/docs/listings/using_cheatcodes_cancelling_cheat/tests/lib.cairo @@ -1,15 +1,13 @@ -//ANCHOR:first_half use snforge_std::{ declare, ContractClassTrait, DeclareResultTrait, start_cheat_caller_address, stop_cheat_caller_address }; -use using_cheatcodes::{ICheatcodeCheckerSafeDispatcher, ICheatcodeCheckerSafeDispatcherTrait}; +use using_cheatcodes_cancelling_cheat::{ + ICheatcodeCheckerSafeDispatcher, ICheatcodeCheckerSafeDispatcherTrait +}; #[test] -//ANCHOR_END:first_half -#[should_panic(expected: 'Second call failed!')] -//ANCHOR:second_half #[feature("safe_dispatcher")] fn call_and_invoke() { let contract = declare("CheatcodeChecker").unwrap().contract_class(); @@ -37,6 +35,3 @@ fn call_and_invoke() { let balance = dispatcher.get_balance(); assert_eq!(balance, Result::Ok(100)); } -//ANCHOR_END:second_half - -mod dummy {} // trick `scarb fmt -c` diff --git a/docs/listings/using_cheatcodes_cheat_address/Scarb.toml b/docs/listings/using_cheatcodes_cheat_address/Scarb.toml new file mode 100644 index 0000000000..b75776b9b3 --- /dev/null +++ b/docs/listings/using_cheatcodes_cheat_address/Scarb.toml @@ -0,0 +1,17 @@ +[package] +name = "using_cheatcodes_cheat_address" +version = "0.1.0" +edition = "2023_11" + +[dependencies] +starknet = "2.7.0" +assert_macros = "0.1.0" + +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } + +[[target.starknet-contract]] +sierra = true + +[scripts] +test = "snforge test" diff --git a/docs/listings/using_cheatcodes_cheat_address/src/lib.cairo b/docs/listings/using_cheatcodes_cheat_address/src/lib.cairo new file mode 100644 index 0000000000..b6c20ffcad --- /dev/null +++ b/docs/listings/using_cheatcodes_cheat_address/src/lib.cairo @@ -0,0 +1,55 @@ +#[starknet::interface] +pub trait ICheatcodeChecker { + fn increase_balance(ref self: TContractState, amount: felt252); + fn get_balance(self: @TContractState) -> felt252; + fn get_block_number_at_construction(self: @TContractState) -> u64; + fn get_block_timestamp_at_construction(self: @TContractState) -> u64; +} + +#[starknet::contract] +pub mod CheatcodeChecker { + use core::box::BoxTrait; + use starknet::get_caller_address; + + #[storage] + struct Storage { + balance: felt252, + blk_nb: u64, + blk_timestamp: u64, + } + + #[constructor] + fn constructor(ref self: ContractState) { + // store the current block number + self.blk_nb.write(starknet::get_block_info().unbox().block_number); + // store the current block timestamp + self.blk_timestamp.write(starknet::get_block_info().unbox().block_timestamp); + } + + #[abi(embed_v0)] + impl ICheatcodeCheckerImpl of super::ICheatcodeChecker { + // Increases the balance by the given amount + fn increase_balance(ref self: ContractState, amount: felt252) { + assert_is_allowed_user(); + self.balance.write(self.balance.read() + amount); + } + // Gets the balance. + fn get_balance(self: @ContractState) -> felt252 { + self.balance.read() + } + // Gets the block number + fn get_block_number_at_construction(self: @ContractState) -> u64 { + self.blk_nb.read() + } + // Gets the block timestamp + fn get_block_timestamp_at_construction(self: @ContractState) -> u64 { + self.blk_timestamp.read() + } + } + + fn assert_is_allowed_user() { + // checks if caller is '123' + let address = get_caller_address(); + assert(address.into() == 123, 'user is not allowed'); + } +} diff --git a/docs/listings/snforge_overview/crates/using_cheatcodes/tests/caller_address/proper_use.cairo b/docs/listings/using_cheatcodes_cheat_address/tests/lib.cairo similarity index 87% rename from docs/listings/snforge_overview/crates/using_cheatcodes/tests/caller_address/proper_use.cairo rename to docs/listings/using_cheatcodes_cheat_address/tests/lib.cairo index cd4b71f24b..5c29b4d211 100644 --- a/docs/listings/snforge_overview/crates/using_cheatcodes/tests/caller_address/proper_use.cairo +++ b/docs/listings/using_cheatcodes_cheat_address/tests/lib.cairo @@ -1,5 +1,5 @@ use snforge_std::{declare, ContractClassTrait, DeclareResultTrait, start_cheat_caller_address}; -use using_cheatcodes::{ICheatcodeCheckerDispatcher, ICheatcodeCheckerDispatcherTrait}; +use using_cheatcodes_cheat_address::{ICheatcodeCheckerDispatcher, ICheatcodeCheckerDispatcherTrait}; #[test] fn call_and_invoke() { diff --git a/docs/listings/snforge_advanced_features/Scarb.toml b/docs/listings/using_cheatcodes_others/Scarb.toml similarity index 59% rename from docs/listings/snforge_advanced_features/Scarb.toml rename to docs/listings/using_cheatcodes_others/Scarb.toml index ec83246478..f9049e22b8 100644 --- a/docs/listings/snforge_advanced_features/Scarb.toml +++ b/docs/listings/using_cheatcodes_others/Scarb.toml @@ -1,9 +1,13 @@ -[workspace] -members = ["crates/*"] +[package] +name = "using_cheatcodes_others" +version = "0.1.0" +edition = "2023_11" -[workspace.dependencies] +[dependencies] starknet = "2.7.0" assert_macros = "0.1.0" + +[dev-dependencies] snforge_std = { path = "../../../snforge_std" } [[target.starknet-contract]] diff --git a/docs/listings/using_cheatcodes_others/src/lib.cairo b/docs/listings/using_cheatcodes_others/src/lib.cairo new file mode 100644 index 0000000000..b6c20ffcad --- /dev/null +++ b/docs/listings/using_cheatcodes_others/src/lib.cairo @@ -0,0 +1,55 @@ +#[starknet::interface] +pub trait ICheatcodeChecker { + fn increase_balance(ref self: TContractState, amount: felt252); + fn get_balance(self: @TContractState) -> felt252; + fn get_block_number_at_construction(self: @TContractState) -> u64; + fn get_block_timestamp_at_construction(self: @TContractState) -> u64; +} + +#[starknet::contract] +pub mod CheatcodeChecker { + use core::box::BoxTrait; + use starknet::get_caller_address; + + #[storage] + struct Storage { + balance: felt252, + blk_nb: u64, + blk_timestamp: u64, + } + + #[constructor] + fn constructor(ref self: ContractState) { + // store the current block number + self.blk_nb.write(starknet::get_block_info().unbox().block_number); + // store the current block timestamp + self.blk_timestamp.write(starknet::get_block_info().unbox().block_timestamp); + } + + #[abi(embed_v0)] + impl ICheatcodeCheckerImpl of super::ICheatcodeChecker { + // Increases the balance by the given amount + fn increase_balance(ref self: ContractState, amount: felt252) { + assert_is_allowed_user(); + self.balance.write(self.balance.read() + amount); + } + // Gets the balance. + fn get_balance(self: @ContractState) -> felt252 { + self.balance.read() + } + // Gets the block number + fn get_block_number_at_construction(self: @ContractState) -> u64 { + self.blk_nb.read() + } + // Gets the block timestamp + fn get_block_timestamp_at_construction(self: @ContractState) -> u64 { + self.blk_timestamp.read() + } + } + + fn assert_is_allowed_user() { + // checks if caller is '123' + let address = get_caller_address(); + assert(address.into() == 123, 'user is not allowed'); + } +} diff --git a/docs/listings/using_cheatcodes_others/tests/caller_address.cairo b/docs/listings/using_cheatcodes_others/tests/caller_address.cairo new file mode 100644 index 0000000000..e8df5dd455 --- /dev/null +++ b/docs/listings/using_cheatcodes_others/tests/caller_address.cairo @@ -0,0 +1,2 @@ +pub mod proper_use_global; +pub mod span; diff --git a/docs/listings/snforge_overview/crates/using_cheatcodes/tests/caller_address/proper_use_global.cairo b/docs/listings/using_cheatcodes_others/tests/caller_address/proper_use_global.cairo similarity index 93% rename from docs/listings/snforge_overview/crates/using_cheatcodes/tests/caller_address/proper_use_global.cairo rename to docs/listings/using_cheatcodes_others/tests/caller_address/proper_use_global.cairo index b810ded3f0..e8f4262be1 100644 --- a/docs/listings/snforge_overview/crates/using_cheatcodes/tests/caller_address/proper_use_global.cairo +++ b/docs/listings/using_cheatcodes_others/tests/caller_address/proper_use_global.cairo @@ -2,7 +2,7 @@ use snforge_std::{ declare, ContractClassTrait, DeclareResultTrait, start_cheat_caller_address_global, stop_cheat_caller_address_global }; -use using_cheatcodes::{ICheatcodeCheckerDispatcher, ICheatcodeCheckerDispatcherTrait}; +use using_cheatcodes_others::{ICheatcodeCheckerDispatcher, ICheatcodeCheckerDispatcherTrait}; #[test] fn call_and_invoke_global() { diff --git a/docs/listings/snforge_overview/crates/using_cheatcodes/tests/caller_address/span.cairo b/docs/listings/using_cheatcodes_others/tests/caller_address/span.cairo similarity index 93% rename from docs/listings/snforge_overview/crates/using_cheatcodes/tests/caller_address/span.cairo rename to docs/listings/using_cheatcodes_others/tests/caller_address/span.cairo index 0b05f181bf..eec19b9e60 100644 --- a/docs/listings/snforge_overview/crates/using_cheatcodes/tests/caller_address/span.cairo +++ b/docs/listings/using_cheatcodes_others/tests/caller_address/span.cairo @@ -1,7 +1,9 @@ use snforge_std::{declare, ContractClassTrait, DeclareResultTrait, cheat_caller_address, CheatSpan}; use starknet::ContractAddress; -use using_cheatcodes::{ICheatcodeCheckerSafeDispatcher, ICheatcodeCheckerSafeDispatcherTrait}; +use using_cheatcodes_others::{ + ICheatcodeCheckerSafeDispatcher, ICheatcodeCheckerSafeDispatcherTrait +}; #[test] #[feature("safe_dispatcher")] diff --git a/docs/listings/snforge_overview/crates/using_cheatcodes/tests/cheat_constructor.cairo b/docs/listings/using_cheatcodes_others/tests/cheat_constructor.cairo similarity index 91% rename from docs/listings/snforge_overview/crates/using_cheatcodes/tests/cheat_constructor.cairo rename to docs/listings/using_cheatcodes_others/tests/cheat_constructor.cairo index 829d269a35..fa39e238fb 100644 --- a/docs/listings/snforge_overview/crates/using_cheatcodes/tests/cheat_constructor.cairo +++ b/docs/listings/using_cheatcodes_others/tests/cheat_constructor.cairo @@ -3,7 +3,7 @@ use snforge_std::{ start_cheat_block_timestamp }; -use using_cheatcodes::{ICheatcodeCheckerDispatcher, ICheatcodeCheckerDispatcherTrait}; +use using_cheatcodes_others::{ICheatcodeCheckerDispatcher, ICheatcodeCheckerDispatcherTrait}; #[test] fn call_and_invoke() { diff --git a/docs/listings/snforge_overview/crates/using_cheatcodes/tests/lib.cairo b/docs/listings/using_cheatcodes_others/tests/lib.cairo similarity index 100% rename from docs/listings/snforge_overview/crates/using_cheatcodes/tests/lib.cairo rename to docs/listings/using_cheatcodes_others/tests/lib.cairo diff --git a/docs/src/appendix/sncast-library/call.md b/docs/src/appendix/sncast-library/call.md index f943e458da..3e76894fe3 100644 --- a/docs/src/appendix/sncast-library/call.md +++ b/docs/src/appendix/sncast-library/call.md @@ -11,7 +11,7 @@ Calls a contract and returns `CallResult`. - `calldata` - inputs to the function to be called. ```rust -{{#include ../../../listings/sncast_library/scripts/call/src/lib.cairo}} +{{#include ../../../listings/call/src/lib.cairo}} ``` Structure used by the command: diff --git a/docs/src/appendix/sncast-library/declare.md b/docs/src/appendix/sncast-library/declare.md index 8165a69b2d..f75510507d 100644 --- a/docs/src/appendix/sncast-library/declare.md +++ b/docs/src/appendix/sncast-library/declare.md @@ -9,7 +9,7 @@ Declares a contract and returns `DeclareResult`. - `nonce` - nonce for declare transaction. If not provided, nonce will be set automatically. ```rust -{{#include ../../../listings/sncast_library/scripts/declare/src/lib.cairo}} +{{#include ../../../listings/declare/src/lib.cairo}} ``` ## Returned Type diff --git a/docs/src/appendix/sncast-library/deploy.md b/docs/src/appendix/sncast-library/deploy.md index 326d7de9fd..e503218118 100644 --- a/docs/src/appendix/sncast-library/deploy.md +++ b/docs/src/appendix/sncast-library/deploy.md @@ -46,5 +46,5 @@ pub struct StrkFeeSettings { - `nonce` - nonce for declare transaction. If not provided, nonce will be set automatically. ```rust -{{#include ../../../listings/sncast_library/scripts/deploy/src/lib.cairo}} +{{#include ../../../listings/deploy/src/lib.cairo}} ``` diff --git a/docs/src/appendix/sncast-library/get_nonce.md b/docs/src/appendix/sncast-library/get_nonce.md index 3261250bca..2ad4b84559 100644 --- a/docs/src/appendix/sncast-library/get_nonce.md +++ b/docs/src/appendix/sncast-library/get_nonce.md @@ -7,5 +7,5 @@ Gets nonce of an account for a given block tag (`pending` or `latest`) and retur - `block_tag` - block tag name, one of `pending` or `latest`. ```rust -{{#include ../../../listings/sncast_library/scripts/get_nonce/src/lib.cairo}} +{{#include ../../../listings/get_nonce/src/lib.cairo}} ``` diff --git a/docs/src/appendix/sncast-library/invoke.md b/docs/src/appendix/sncast-library/invoke.md index 8cd5c0a121..db964a11a0 100644 --- a/docs/src/appendix/sncast-library/invoke.md +++ b/docs/src/appendix/sncast-library/invoke.md @@ -17,7 +17,7 @@ Invokes a contract and returns `InvokeResult`. - `nonce` - nonce for declare transaction. If not provided, nonce will be set automatically. ```rust -{{#include ../../../listings/sncast_library/scripts/invoke/src/lib.cairo}} +{{#include ../../../listings/invoke/src/lib.cairo}} ``` Structures used by the command: diff --git a/docs/src/appendix/sncast-library/tx_status.md b/docs/src/appendix/sncast-library/tx_status.md index f00842679b..83536455b1 100644 --- a/docs/src/appendix/sncast-library/tx_status.md +++ b/docs/src/appendix/sncast-library/tx_status.md @@ -7,7 +7,7 @@ Gets the status of a transaction using its hash and returns `TxStatusResult`. - `transaction_hash` - hash of the transaction ```rust -{{#include ../../../listings/sncast_library/scripts/tx_status/src/lib.cairo}} +{{#include ../../../listings/tx_status/src/lib.cairo}} ``` Structures used by the command: diff --git a/docs/src/getting-started/first-steps.md b/docs/src/getting-started/first-steps.md index 08833008cf..8aa0231c48 100644 --- a/docs/src/getting-started/first-steps.md +++ b/docs/src/getting-started/first-steps.md @@ -6,13 +6,13 @@ We demonstrate how to create a new project, compile, and test it. To start a new project with Starknet Foundry, run `snforge init` ```shell -$ snforge init project_name +$ snforge init hello_starknet ``` Let's check out the project structure ```shell -$ cd project_name +$ cd hello_starknet $ tree . -L 1 ``` @@ -27,7 +27,7 @@ $ tree . -L 1 ├── src └── tests -2 directories, 2 files +2 directories, 3 files ```

@@ -47,15 +47,12 @@ $ snforge test Output: ```shell - Compiling project_name v0.1.0 (project_name/Scarb.toml) - Finished release target(s) in 1 second - -Collected 2 test(s) from project_name package +Collected 2 test(s) from hello_starknet package Running 0 test(s) from src/ Running 2 test(s) from tests/ -[PASS] tests::test_contract::test_increase_balance (gas: ~170) -[PASS] tests::test_contract::test_cannot_increase_balance_with_zero_value (gas: ~104) -Tests: 2 passed, 0 failed, 0 skipped, 0 ignored +[PASS] hello_starknet_integrationtest::test_contract::test_cannot_increase_balance_with_zero_value (gas: ~105) +[PASS] hello_starknet_integrationtest::test_contract::test_increase_balance (gas: ~172) +Tests: 2 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out ```

@@ -76,6 +73,7 @@ snforge_std = "0.33.0" Make sure that the above version matches the installed `snforge` version. You can check the currently installed version with + ```shell $ snforge --version ``` diff --git a/docs/src/snforge-advanced-features/backtrace.md b/docs/src/snforge-advanced-features/backtrace.md index 4819dbc227..6075567d94 100644 --- a/docs/src/snforge-advanced-features/backtrace.md +++ b/docs/src/snforge-advanced-features/backtrace.md @@ -34,7 +34,7 @@ this: - + ```shell $ snforge test ``` @@ -55,7 +55,9 @@ To enable backtraces, simply set the `SNFORGE_BACKTRACE=1` environment variable When enabled, the backtrace will display the call tree of the execution, including the specific line numbers in the contracts where the errors occurred. Here's an example of what you might see: - + + + ```shell $ SNFORGE_BACKTRACE=1 snforge test ``` diff --git a/docs/src/snforge-advanced-features/conditional-compilation.md b/docs/src/snforge-advanced-features/conditional-compilation.md index 1120cf4f79..459298b1e5 100644 --- a/docs/src/snforge-advanced-features/conditional-compilation.md +++ b/docs/src/snforge-advanced-features/conditional-compilation.md @@ -16,7 +16,7 @@ Additionally, for utilizing features the `snforge test` command exposes the foll Firstly, define a contract in the `src` directory with a `#[cfg(feature: '')]` attribute: ```rust -{{#include ../../listings/snforge_advanced_features/crates/conditional_compilation/src/lib.cairo}} +{{#include ../../listings/conditional_compilation/src/lib.cairo}} ``` > 📝 **Note** @@ -27,7 +27,7 @@ Firstly, define a contract in the `src` directory with a `#[cfg(feature: 'Output: ```shell -Collected 1 test(s) from fuzz_testing package -Running 1 test(s) from src/ -Running 0 test(s) from tests/ -[PASS] fuzz_testing::basic_example::test_sum (runs: 256, gas: {max: ~1, min: ~1, mean: ~1.00, std deviation: ~0.00}) -Tests: 1 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out +Collected 2 test(s) from fuzz_testing package +Running 2 test(s) from src/ +[PASS] fuzz_testing::with_parameters::tests::test_sum (runs: 22, gas: {max: ~1, min: ~1, mean: ~1.00, std deviation: ~0.00}) +[PASS] fuzz_testing::basic_example::tests::test_sum (runs: 256, gas: {max: ~1, min: ~1, mean: ~1.00, std deviation: ~0.00}) +Tests: 2 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out Fuzzer seed: [..] ```
@@ -59,7 +59,7 @@ Trying to use arguments of different type in test definition will result in an e It is possible to configure the number of runs of the random fuzzer as well as its seed for a specific test case: ```rust -{{#include ../../listings/snforge_advanced_features/crates/fuzz_testing/src/with_parameters.cairo}} +{{#include ../../listings/fuzz_testing/src/with_parameters.cairo}} ``` It can also be configured globally, via command line arguments: diff --git a/docs/src/snforge-advanced-features/storage-cheatcodes.md b/docs/src/snforge-advanced-features/storage-cheatcodes.md index 37c2e509f8..d82a2d9e41 100644 --- a/docs/src/snforge-advanced-features/storage-cheatcodes.md +++ b/docs/src/snforge-advanced-features/storage-cheatcodes.md @@ -15,13 +15,13 @@ This example uses only felts for simplicity. 1. Exact storage fields ```rust -{{#include ../../listings/snforge_advanced_features/crates/direct_storage_access/tests/felts_only/field.cairo}} +{{#include ../../listings/direct_storage_access/tests/felts_only/field.cairo}} ``` 2. Map entries ```rust -{{#include ../../listings/snforge_advanced_features/crates/direct_storage_access/tests/felts_only/map_entry.cairo}} +{{#include ../../listings/direct_storage_access/tests/felts_only/map_entry.cairo}} ``` ## Example: Complex structures in storage @@ -30,13 +30,13 @@ This example uses a complex key and value, with default derived serialization me We use a contract along with helper structs: ```rust -{{#include ../../listings/snforge_advanced_features/crates/direct_storage_access/src/complex_structures.cairo}} +{{#include ../../listings/direct_storage_access/src/complex_structures.cairo}} ``` And perform a test checking `load` and `store` behavior in context of those structs: ```rust -{{#include ../../listings/snforge_advanced_features/crates/direct_storage_access/tests/complex_structures.cairo}} +{{#include ../../listings/direct_storage_access/tests/complex_structures.cairo}} ``` > ⚠️ **Warning** diff --git a/docs/src/starknet/account-import.md b/docs/src/starknet/account-import.md index 1451365abb..31039fe0ae 100644 --- a/docs/src/starknet/account-import.md +++ b/docs/src/starknet/account-import.md @@ -87,6 +87,7 @@ $ sncast \ If you don't want to pass the private key in the command (because of safety aspect), you can skip `--private-key` flag. You will be prompted to enter the private key in interactive mode. + ```shell $ sncast \ account import \ diff --git a/docs/src/starknet/invoke.md b/docs/src/starknet/invoke.md index 370e4ef1e3..10bd551526 100644 --- a/docs/src/starknet/invoke.md +++ b/docs/src/starknet/invoke.md @@ -24,9 +24,9 @@ $ sncast \ --contract-address 0x522dc7cbe288037382a02569af5a4169531053d284193623948eac8dd051716 \ --function "add" \ --fee-token eth \ - --arguments 'pokemons::model::PokemonData {'\ + --arguments 'pokemons::model::PokemonData {'\ 'name: "Magmar",'\ -'element: pokemons::model::Element::Fire'\ +'element: pokemons::model::Element::Fire'\ '}' ``` diff --git a/docs/src/starknet/script.md b/docs/src/starknet/script.md index fecce2ed10..d822d4dda0 100644 --- a/docs/src/starknet/script.md +++ b/docs/src/starknet/script.md @@ -221,7 +221,7 @@ For more details, see [init command](../appendix/sncast/script/init.md). This example shows how to call an already deployed contract. Please find full example with contract deployment [here](#full-example-with-contract-deployment). ```rust -{{#include ../../listings/sncast_overview/scripts/basic_example/src/basic_example.cairo}} +{{#include ../../listings/basic_example/src/basic_example.cairo}} ``` The script should be included in a Scarb package. The directory structure and config for this example looks like this: @@ -276,13 +276,13 @@ status: success This example script declares, deploys and interacts with an example `MapContract`: ```rust -{{#include ../../listings/sncast_overview/crates/map3/src/lib.cairo}} +{{#include ../../listings/map3/src/lib.cairo}} ``` We prepare a script: ```rust -{{#include ../../listings/sncast_overview/scripts/full_example/src/full_example.cairo}} +{{#include ../../listings/full_example/src/full_example.cairo}} ``` The script should be included in a Scarb package. The directory structure and config for this example looks like this: @@ -414,7 +414,7 @@ Script errors implement `Debug` trait, allowing the error to be printed to stdou ### Minimal example with `assert!` and `println!` ```rust -{{#include ../../listings/sncast_overview/scripts/error_handling/src/error_handling.cairo}} +{{#include ../../listings/error_handling/src/error_handling.cairo}} ``` More on deployment scripts errors [here](../appendix/sncast-library/errors.md). diff --git a/docs/src/starknet/sncast-overview.md b/docs/src/starknet/sncast-overview.md index c0b4231da1..95602ff2ca 100644 --- a/docs/src/starknet/sncast-overview.md +++ b/docs/src/starknet/sncast-overview.md @@ -11,6 +11,8 @@ Starknet Foundry `sncast` is a command line tool for performing Starknet RPC cal ## How to Use `sncast` To use `sncast`, run the `sncast` command followed by a subcommand (see [available commands](../appendix/sncast.md)): + + ```shell $ sncast ``` diff --git a/docs/src/testing/contracts.md b/docs/src/testing/contracts.md index 08e600fb4f..5b3433cc8b 100644 --- a/docs/src/testing/contracts.md +++ b/docs/src/testing/contracts.md @@ -19,7 +19,7 @@ writing smart contracts, you often want to test their interactions with the bloc Let's consider a simple smart contract with two methods. ```rust -{{#include ../../listings/snforge_overview/crates/testing_smart_contracts/src/simple_contract.cairo}} +{{#include ../../listings/testing_smart_contracts_writing_tests/src/lib.cairo}} ``` Note that the name after `mod` will be used as the contract name for testing purposes. @@ -29,7 +29,7 @@ Note that the name after `mod` will be used as the contract name for testing pur Let's write a test that will deploy the `HelloStarknet` contract and call some functions. ```rust -{{#include ../../listings/snforge_overview/crates/testing_smart_contracts/tests/simple_contract.cairo}} +{{#include ../../listings/testing_smart_contracts_writing_tests/tests/simple_contract.cairo}} ``` > 📝 **Note** @@ -46,11 +46,19 @@ $ snforge test Output: ```shell -Collected 1 test(s) from testing_smart_contracts package +Collected 2 test(s) from testing_smart_contracts_handling_errors package +Running 2 test(s) from tests/ +[FAIL] testing_smart_contracts_handling_errors_integrationtest::panic::failing + +Failure data: + (0x50414e4943 ('PANIC'), 0x444159544148 ('DAYTAH')) + +[PASS] testing_smart_contracts_handling_errors_integrationtest::handle_panic::handling_string_errors (gas: ~103) Running 0 test(s) from src/ -Running 1 test(s) from tests/ -[PASS] tests::call_and_invoke -Tests: 1 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out +Tests: 1 passed, 1 failed, 0 skipped, 0 ignored, 0 filtered out + +Failures: + testing_smart_contracts_handling_errors_integrationtest::panic::failing ```

@@ -64,14 +72,14 @@ panicking. First, let's add a new, panicking function to our contract. ```rust -{{#include ../../listings/snforge_overview/crates/testing_smart_contracts/src/handling_errors.cairo}} +{{#include ../../listings/testing_smart_contracts_handling_errors/src/lib.cairo}} ``` If we called this function in a test, it would result in a failure. ```rust -{{#include ../../listings/snforge_overview/crates/testing_smart_contracts/tests/panic.cairo:first_half}} -{{#include ../../listings/snforge_overview/crates/testing_smart_contracts/tests/panic.cairo:second_half}} +{{#include ../../listings/testing_smart_contracts_handling_errors/tests/panic.cairo:first_half}} +{{#include ../../listings/testing_smart_contracts_handling_errors/tests/panic.cairo:second_half}} ``` ```shell @@ -82,18 +90,19 @@ $ snforge test Output: ```shell -Collected 1 test(s) from testing_smart_contracts package -Running 0 test(s) from src/ -Running 1 test(s) from tests/ -[FAIL] tests::failing +Collected 2 test(s) from testing_smart_contracts_handling_errors package +Running 2 test(s) from tests/ +[FAIL] testing_smart_contracts_handling_errors_integrationtest::panic::failing Failure data: (0x50414e4943 ('PANIC'), 0x444159544148 ('DAYTAH')) -Tests: 0 passed, 1 failed, 0 skipped, 0 ignored, 0 filtered out +[PASS] testing_smart_contracts_handling_errors_integrationtest::handle_panic::handling_string_errors (gas: ~103) +Running 0 test(s) from src/ +Tests: 1 passed, 1 failed, 0 skipped, 0 ignored, 0 filtered out Failures: - tests::failing + testing_smart_contracts_handling_errors_integrationtest::panic::failing ```

@@ -107,7 +116,7 @@ but are available for testing purposes. They allow using the contract without automatically unwrapping the result, which allows to catch the error like shown below. ```rust -{{#include ../../listings/snforge_overview/crates/testing_smart_contracts/tests/safe_dispatcher.cairo}} +{{#include ../../listings/testing_smart_contracts_safe_dispatcher/tests/safe_dispatcher.cairo}} ``` Now the test passes as expected. @@ -120,10 +129,10 @@ $ snforge test Output: ```shell -Collected 1 test(s) from package_name package +Collected 1 test(s) from testing_smart_contracts_safe_dispatcher package Running 0 test(s) from src/ Running 1 test(s) from tests/ -[PASS] tests::handling_errors +[PASS] testing_smart_contracts_safe_dispatcher_integrationtest::safe_dispatcher::handling_errors (gas: ~103) Tests: 1 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out ``` @@ -132,7 +141,7 @@ Tests: 1 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out Similarly, you can handle the panics which use `ByteArray` as an argument (like an `assert!` or `panic!` macro) ```rust -{{#include ../../listings/snforge_overview/crates/testing_smart_contracts/tests/handle_panic.cairo}} +{{#include ../../listings/testing_smart_contracts_handling_errors/tests/handle_panic.cairo}} ``` You also could skip the de-serialization of the `panic_data`, and not use `try_deserialize_bytearray_error`, but this way you can actually use assertions on the `ByteArray` that was used to panic. diff --git a/docs/src/testing/gas-and-resource-estimation.md b/docs/src/testing/gas-and-resource-estimation.md index 0529400270..c91cb15782 100644 --- a/docs/src/testing/gas-and-resource-estimation.md +++ b/docs/src/testing/gas-and-resource-estimation.md @@ -44,13 +44,22 @@ $ snforge test --detailed-resources Output: ```shell -... -[PASS] package_name::tests::resources (gas: ~2213) - steps: 881 - memory holes: 36 - builtins: ("range_check_builtin": 32) - syscalls: (StorageWrite: 1, StorageRead: 1, CallContract: 1) -... +Collected 2 test(s) from hello_starknet package +Running 2 test(s) from tests/ +[PASS] hello_starknet_integrationtest::test_contract::test_cannot_increase_balance_with_zero_value (gas: ~105) + steps: 3405 + memory holes: 22 + builtins: ([..]) + syscalls: ([..]) + +[PASS] hello_starknet_integrationtest::test_contract::test_increase_balance (gas: ~172) + steps: 4535 + memory holes: 15 + builtins: ([..]) + syscalls: ([..]) + +Running 0 test(s) from src/ +Tests: 2 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out ```
diff --git a/docs/src/testing/running-tests.md b/docs/src/testing/running-tests.md index bf3382e80b..0138f8f88a 100644 --- a/docs/src/testing/running-tests.md +++ b/docs/src/testing/running-tests.md @@ -10,11 +10,12 @@ $ snforge test Output: ```shell -Collected 3 test(s) from package_name package -Running 3 test(s) from src/ -[PASS] package_name::tests::executing -[PASS] package_name::tests::calling -[PASS] package_name::tests::calling_another +Collected 3 test(s) from hello_snforge package +Running 0 test(s) from src/ +Running 3 test(s) from tests/ +[PASS] hello_snforge_integrationtest::test_contract::test_calling (gas: ~1) +[PASS] hello_snforge_integrationtest::test_contract::test_executing (gas: ~1) +[PASS] hello_snforge_integrationtest::test_contract::test_calling_another (gas: ~1) Tests: 3 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out ``` @@ -23,8 +24,7 @@ Tests: 3 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out ## Filtering Tests You can pass a filter string after the `snforge test` command to filter tests. -By default, any test with an [absolute module tree path](https://book.cairo-lang.org/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html#paths-for-referring-to-an-item-in-the-module-tree) - matching the filter will be run. +By default, any test with an [absolute module tree path](https://book.cairo-lang.org/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html#paths-for-referring-to-an-item-in-the-module-tree) matching the filter will be run. ```shell $ snforge test calling @@ -34,10 +34,11 @@ $ snforge test calling Output: ```shell -Collected 2 test(s) from package_name package -Running 2 test(s) from src/ -[PASS] package_name::tests::calling -[PASS] package_name::tests::calling_another +Collected 2 test(s) from hello_snforge package +Running 0 test(s) from src/ +Running 2 test(s) from tests/ +[PASS] hello_snforge_integrationtest::test_contract::test_calling_another (gas: ~1) +[PASS] hello_snforge_integrationtest::test_contract::test_calling (gas: ~1) Tests: 2 passed, 0 failed, 0 skipped, 0 ignored, 1 filtered out ``` @@ -54,16 +55,17 @@ Note, you have to use a fully qualified test name, including a module name. > ```shell -$ snforge test package_name::tests::calling --exact +$ snforge test hello_snforge_integrationtest::test_contract::test_calling --exact ```
Output: ```shell -Collected 1 test(s) from package_name package -Running 1 test(s) from src/ -[PASS] package_name::tests::calling +Collected 1 test(s) from hello_snforge package +Running 1 test(s) from tests/ +[PASS] hello_snforge_integrationtest::test_contract::test_calling (gas: ~1) +Running 0 test(s) from src/ Tests: 1 passed, 0 failed, 0 skipped, 0 ignored, other filtered out ```
@@ -73,6 +75,7 @@ Tests: 1 passed, 0 failed, 0 skipped, 0 ignored, other filtered out To stop the test execution after first failed test, you can pass an `--exit-first` flag along with `snforge test` command. + ```shell $ snforge test --exit-first ``` @@ -81,20 +84,18 @@ $ snforge test --exit-first Output: ```shell -Collected 6 test(s) from package_name package -Running 6 test(s) from src/ -[PASS] package_name::tests::executing -[PASS] package_name::tests::calling -[PASS] package_name::tests::calling_another -[FAIL] package_name::tests::failing +Collected 3 test(s) from failing_example package +Running 3 test(s) from tests/ +[FAIL] failing_example_tests::test_failing Failure data: 0x6661696c696e6720636865636b ('failing check') -Tests: 3 passed, 1 failed, 2 skipped, 0 ignored, 0 filtered out Failures: - package_name::tests::failing + failing_example_tests::test_failing + +Tests: 0 passed, 1 failed, 2 skipped, 0 ignored, 0 filtered out ```
@@ -111,15 +112,22 @@ $ snforge test --detailed-resources Output: ```shell -Collected 1 test(s) from package_name package -Running 1 test(s) from src/ -[PASS] package_name::tests::resources (gas: ~2213) - steps: 881 - memory holes: 36 - builtins: ("range_check_builtin": 32) - syscalls: (StorageWrite: 1, StorageRead: 1, CallContract: 1) - -Tests: 1 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out +Collected 2 test(s) from hello_starknet package +Running 2 test(s) from tests/ +[PASS] hello_starknet_integrationtest::test_contract::test_cannot_increase_balance_with_zero_value (gas: ~105) + steps: 3405 + memory holes: 22 + builtins: ([..]) + syscalls: ([..]) + +[PASS] hello_starknet_integrationtest::test_contract::test_increase_balance (gas: ~172) + steps: 4535 + memory holes: 15 + builtins: ([..]) + syscalls: ([..]) + +Running 0 test(s) from src/ +Tests: 2 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out ```
diff --git a/docs/src/testing/testing-contract-internals.md b/docs/src/testing/testing-contract-internals.md index 8bf3aff494..f653f49cf2 100644 --- a/docs/src/testing/testing-contract-internals.md +++ b/docs/src/testing/testing-contract-internals.md @@ -18,7 +18,7 @@ This is a function generated by the `#[starknet::contract]` macro. It can be used to test some functions which accept the state as an argument, see the example below: ```rust -{{#include ../../listings/snforge_overview/crates/testing_contract_internals/src/basic_example.cairo}} +{{#include ../../listings/testing_contract_internals/src/basic_example.cairo}} ``` This code contains some caveats: @@ -38,7 +38,7 @@ Example usages: Example for `cheat_block_number`, same can be implemented for `cheat_caller_address`/`cheat_block_timestamp`/`elect` etc. ```rust -{{#include ../../listings/snforge_overview/crates/testing_contract_internals/tests/mocking_the_context_info.cairo}} +{{#include ../../listings/testing_contract_internals/tests/mocking_the_context_info.cairo}} ``` #### 2. Spying for events You can use both `starknet::emit_event_syscall`, and the spies will capture the events, @@ -47,17 +47,17 @@ emitted in a `#[test]` function, if you pass the `test_address()` as a spy param Given the emitting contract implementation: ```rust -{{#include ../../listings/snforge_overview/crates/testing_contract_internals/src/spying_for_events.cairo}} +{{#include ../../listings/testing_contract_internals/src/spying_for_events.cairo}} ``` You can implement this test: ```rust -{{#include ../../listings/snforge_overview/crates/testing_contract_internals/tests/spying_for_events/tests.cairo}} +{{#include ../../listings/testing_contract_internals/tests/spying_for_events/tests.cairo}} ``` You can also use the `starknet::emit_event_syscall` directly in the tests: ```rust -{{#include ../../listings/snforge_overview/crates/testing_contract_internals/tests/spying_for_events/syscall_tests.cairo}} +{{#include ../../listings/testing_contract_internals/tests/spying_for_events/syscall_tests.cairo}} ``` ## Using Library Calls With the Test State Context @@ -67,11 +67,11 @@ Using the above utilities, you can avoid deploying a mock contract, to test a `l For contract implementation: ```rust -{{#include ../../listings/snforge_overview/crates/testing_contract_internals/src/using_library_calls.cairo}} +{{#include ../../listings/testing_contract_internals/src/using_library_calls.cairo}} ``` We use the `SafeLibraryDispatcher` like this: ```rust -{{#include ../../listings/snforge_overview/crates/testing_contract_internals/tests/using_library_calls.cairo}} +{{#include ../../listings/testing_contract_internals/tests/using_library_calls.cairo}} ``` > ⚠️ **Warning** > diff --git a/docs/src/testing/testing-events.md b/docs/src/testing/testing-events.md index 31342fc6ca..37cf58dbcd 100644 --- a/docs/src/testing/testing-events.md +++ b/docs/src/testing/testing-events.md @@ -2,7 +2,7 @@ Examples are based on the following `SpyEventsChecker` contract implementation: ```rust -{{#include ../../listings/snforge_overview/crates/testing_events/src/contract.cairo}} +{{#include ../../listings/testing_events/src/contract.cairo}} ``` ## Asserting emission with `assert_emitted` method @@ -11,7 +11,7 @@ This is the simpler way, in which you don't have to fetch the events explicitly. See the below code for reference: ```rust -{{#include ../../listings/snforge_overview/crates/testing_events/tests/assert_emitted.cairo}} +{{#include ../../listings/testing_events/tests/assert_emitted.cairo}} ``` Let's go through the code: @@ -52,7 +52,7 @@ Simply call `get_events()` on your `EventSpy` and access `events` field on the Then, you can access the events and assert data by yourself. ```rust -{{#include ../../listings/snforge_overview/crates/testing_events/tests/assert_manually.cairo}} +{{#include ../../listings/testing_events/tests/assert_manually.cairo}} ``` Let's go through important parts of the provided code: @@ -75,7 +75,7 @@ Sometimes, when you assert the events manually, you might not want to get all th a particular address. You can address that by using the method `emitted_by` on the `Events` structure. ```rust -{{#include ../../listings/snforge_overview/crates/testing_events/tests/filter.cairo}} +{{#include ../../listings/testing_events/tests/filter.cairo}} ``` `events_from_first_address` has events emitted by the first contract only. @@ -89,13 +89,13 @@ They can also be asserted with `spy.assert_emitted` method. Let's extend our `SpyEventsChecker` with `emit_event_with_syscall` method: ```rust -{{#include ../../listings/snforge_overview/crates/testing_events/src/syscall_dummy.cairo}} +{{#include ../../listings/testing_events/src/syscall_dummy.cairo}} ``` And add a test for it: ```rust -{{#include ../../listings/snforge_overview/crates/testing_events/tests/syscall.cairo}} +{{#include ../../listings/testing_events/tests/syscall.cairo}} ``` Using `Event` struct from the `snforge_std` library we can easily assert nonstandard events. diff --git a/docs/src/testing/testing-messages-to-l1.md b/docs/src/testing/testing-messages-to-l1.md index fe0c490bbb..74902deafb 100644 --- a/docs/src/testing/testing-messages-to-l1.md +++ b/docs/src/testing/testing-messages-to-l1.md @@ -34,11 +34,11 @@ With the spy ready to use, you can execute some code, and make the assertions: 1. Either with the spy directly by using `assert_sent`/`assert_not_sent` methods from `MessageToL1SpyAssertionsTrait` trait: ```rust -{{#include ../../listings/snforge_overview/crates/testing_messages_to_l1/tests/simple.cairo}} +{{#include ../../listings/testing_messages_to_l1/tests/simple.cairo}} ``` 2. Or use the messages' contents directly via `get_messages()` method of the `MessageToL1SpyTrait`: ```rust -{{#include ../../listings/snforge_overview/crates/testing_messages_to_l1/tests/detailed.cairo}} +{{#include ../../listings/testing_messages_to_l1/tests/detailed.cairo}} ``` diff --git a/docs/src/testing/testing-workspaces.md b/docs/src/testing/testing-workspaces.md index a959874cf4..63eefb8459 100644 --- a/docs/src/testing/testing-workspaces.md +++ b/docs/src/testing/testing-workspaces.md @@ -46,10 +46,25 @@ $ snforge test Output: ```shell -Collected 1 test(s) from hello_workspaces package +Collected 3 test(s) from hello_workspaces package Running 1 test(s) from src/ -[PASS] hello_workspaces::tests::test_simple -Tests: 1 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out +[PASS] hello_workspaces::tests::test_simple (gas: ~1) +Running 2 test(s) from tests/ +[FAIL] hello_workspaces_integrationtest::test_failing::test_failing + +Failure data: + 0x6661696c696e6720636865636b ('failing check') + +[FAIL] hello_workspaces_integrationtest::test_failing::test_another_failing + +Failure data: + 0x6661696c696e6720636865636b ('failing check') + +Tests: 1 passed, 2 failed, 0 skipped, 0 ignored, 0 filtered out + +Failures: + hello_workspaces_integrationtest::test_failing::test_failing + hello_workspaces_integrationtest::test_failing::test_another_failing ```
@@ -57,7 +72,7 @@ Tests: 1 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out To select the specific package to test, pass a `--package package_name` (or `-p package_name` for short) flag. You can also run `snforge test` from the package directory to achieve the same effect. - + ```shell $ snforge test --package addition ``` @@ -66,12 +81,15 @@ $ snforge test --package addition Output: ```shell -Collected 2 test(s) from addition package +Collected 5 test(s) from addition package +Running 4 test(s) from tests/ +[PASS] addition_integrationtest::nested::test_nested::test_two (gas: ~1) +[PASS] addition_integrationtest::nested::test_nested::test_two_and_two (gas: ~1) +[PASS] addition_integrationtest::nested::simple_case (gas: ~1) +[PASS] addition_integrationtest::nested::contract_test (gas: ~1) Running 1 test(s) from src/ -[PASS] addition::tests::it_works -Running 1 test(s) from tests/ -[PASS] tests::test_simple::simple_case -Tests: 2 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out +[PASS] addition::tests::it_works (gas: ~1) +Tests: 5 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out ```
@@ -86,24 +104,53 @@ $ snforge test --workspace Output: ```shell -Collected 2 test(s) from addition package +Collected 5 test(s) from addition package +Running 4 test(s) from tests/ +[PASS] addition_integrationtest::nested::test_nested::test_two (gas: ~1) +[PASS] addition_integrationtest::nested::simple_case (gas: ~1) +[PASS] addition_integrationtest::nested::test_nested::test_two_and_two (gas: ~1) +[PASS] addition_integrationtest::nested::contract_test (gas: ~1) Running 1 test(s) from src/ -[PASS] addition::tests::it_works -Running 1 test(s) from tests/ -[PASS] tests::test_simple::simple_case -Tests: 2 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out +[PASS] addition::tests::it_works (gas: ~1) +Tests: 5 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out -Collected 1 test(s) from fibonacci package -Running 1 test(s) from src/ -[PASS] fibonacci::tests::it_works -Tests: 1 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out +Collected 6 test(s) from fibonacci package +Running 2 test(s) from src/ +[PASS] fibonacci::tests::it_works (gas: ~1) +[PASS] fibonacci::tests::contract_test (gas: ~1) +Running 4 test(s) from tests/ +[FAIL] fibonacci_tests::abc::efg::failing_test + +Failure data: + 0x0 ('') +[PASS] fibonacci_tests::abc::efg::efg_test (gas: ~1) +[PASS] fibonacci_tests::lib_test (gas: ~1) +[PASS] fibonacci_tests::abc::abc_test (gas: ~1) +Tests: 5 passed, 1 failed, 0 skipped, 0 ignored, 0 filtered out -Collected 1 test(s) from hello_workspaces package + +Collected 3 test(s) from hello_workspaces package Running 1 test(s) from src/ -[PASS] hello_workspaces::tests::test_simple -Tests: 1 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out +[PASS] hello_workspaces::tests::test_simple (gas: ~1) +Running 2 test(s) from tests/ +[FAIL] hello_workspaces_integrationtest::test_failing::test_another_failing + +Failure data: + 0x6661696c696e6720636865636b ('failing check') + +[FAIL] hello_workspaces_integrationtest::test_failing::test_failing + +Failure data: + 0x6661696c696e6720636865636b ('failing check') + +Tests: 1 passed, 2 failed, 0 skipped, 0 ignored, 0 filtered out + +Failures: + fibonacci_tests::abc::efg::failing_test + hello_workspaces_integrationtest::test_failing::test_another_failing + hello_workspaces_integrationtest::test_failing::test_failing ```
diff --git a/docs/src/testing/testing.md b/docs/src/testing/testing.md index bfc6a953ee..229fdb718d 100644 --- a/docs/src/testing/testing.md +++ b/docs/src/testing/testing.md @@ -8,7 +8,7 @@ should write as many unit tests as possible as these are faster than integration First, add the following code to the `src/lib.cairo` file: ```rust -{{#include ../../listings/snforge_overview/crates/writing_tests/src/first_test.cairo}} +{{#include ../../listings/first_test/src/lib.cairo}} ``` It is a common practice to keep your unit tests in the same file as the tested code. @@ -26,9 +26,9 @@ $ snforge test Output: ```shell -Collected 1 test(s) from writing_tests package +Collected 1 test(s) from first_test package Running 1 test(s) from src/ -[PASS] writing::first_test::tests::test_sum +[PASS] first_test::tests::test_sum (gas: ~1) Tests: 1 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out ``` @@ -39,8 +39,7 @@ Tests: 1 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out If your code panics, the test is considered failed. Here's an example of a failing test. ```rust -{{#include ../../listings/snforge_overview/crates/writing_tests/src/panicking_tests.cairo:first_half}} -{{#include ../../listings/snforge_overview/crates/writing_tests/src/panicking_tests.cairo:second_half}} +{{#include ../../listings/panicking_test/src/lib.cairo}} ``` ```shell @@ -51,17 +50,17 @@ $ snforge test Output: ```shell -Collected 1 test(s) from writing_tests package +Collected 1 test(s) from panicking_test package Running 1 test(s) from src/ -[FAIL] writing_tests::panicking_tests::tests::failing +[FAIL] panicking_test::tests::failing Failure data: - 0x616161 ('aaa') + 0x70616e6963206d657373616765 ('panic message') Tests: 0 passed, 1 failed, 0 skipped, 0 ignored, 0 filtered out Failures: - writing_tests::panicking_tests::tests::failing + panicking_test::tests::failing ```
@@ -79,18 +78,18 @@ You can specify the expected failure message in three ways: 1. **With ByteArray**: ```rust -{{#include ../../listings/snforge_overview/crates/writing_tests/tests/expected_failures.cairo:byte_array}} +{{#include ../../listings/should_panic_example/src/lib.cairo:byte_array}} ``` With this format, the expected error message needs to be a substring of the actual error message. This is particularly useful when the error message includes dynamic data such as a hash or address. 2. **With felt** ```rust -{{#include ../../listings/snforge_overview/crates/writing_tests/tests/expected_failures.cairo:felt}} +{{#include ../../listings/should_panic_example/src/lib.cairo:felt}} ``` 3. **With tuple of felts**: ```rust -{{#include ../../listings/snforge_overview/crates/writing_tests/tests/expected_failures.cairo:tuple}} +{{#include ../../listings/should_panic_example/src/lib.cairo:tuple}} ``` @@ -102,11 +101,14 @@ $ snforge test Output: ```shell -Collected 1 test(s) from writing_tests package -Running 0 test(s) from src/ -Running 1 test(s) from tests/ -[PASS] snforge_overview_integrationtest::should_panic_check_data -Tests: 1 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out +Collected 5 test(s) from should_panic_example package +Running 5 test(s) from src/ +[PASS] should_panic_example::tests::should_panic_felt_matching (gas: ~1) +[PASS] should_panic_example::tests::should_panic_multiple_messages (gas: ~1) +[PASS] should_panic_example::tests::should_panic_exact (gas: ~1) +[PASS] should_panic_example::tests::should_panic_expected_is_substring (gas: ~1) +[PASS] should_panic_example::tests::should_panic_check_data (gas: ~1) +Tests: 5 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out ```
@@ -117,7 +119,7 @@ Sometimes you may have tests that you want to exclude during most runs of `snfor You can achieve it using `#[ignore]` - tests marked with this attribute will be skipped by default. ```rust -{{#include ../../listings/snforge_overview/crates/writing_tests/tests/ignoring.cairo}} +{{#include ../../listings/ignoring_example/src/lib.cairo}} ``` ```shell @@ -128,10 +130,9 @@ $ snforge test Output: ```shell -Collected 1 test(s) from writing_tests package -Running 0 test(s) from src/ -Running 1 test(s) from tests/ -[IGNORE] writing_tests_integrationtest::ignoring::ignored_test +Collected 1 test(s) from ignoring_example package +Running 1 test(s) from src/ +[IGNORE] ignoring_example::tests::ignored_test Tests: 0 passed, 0 failed, 0 skipped, 1 ignored, 0 filtered out ``` diff --git a/docs/src/testing/using-cheatcodes.md b/docs/src/testing/using-cheatcodes.md index eb8d0e6202..1ce48ad934 100644 --- a/docs/src/testing/using-cheatcodes.md +++ b/docs/src/testing/using-cheatcodes.md @@ -23,7 +23,7 @@ using [cheatcodes](../appendix/cheatcodes.md). In this tutorial, we will be using the following Starknet contract: ```rust -{{#include ../../listings/snforge_overview/crates/using_cheatcodes/src/lib.cairo}} +{{#include ../../listings/using_cheatcodes/src/lib.cairo}} ``` ## Writing Tests @@ -31,8 +31,7 @@ In this tutorial, we will be using the following Starknet contract: We can try to create a test that will increase and verify the balance. ```rust -{{#include ../../listings/snforge_overview/crates/using_cheatcodes/tests/caller_address/failing.cairo:first_half}} -{{#include ../../listings/snforge_overview/crates/using_cheatcodes/tests/caller_address/failing.cairo:second_half}} +{{#include ../../listings/using_cheatcodes/tests/lib.cairo}} ``` This test fails, which means that `increase_balance` method panics as we expected. @@ -46,13 +45,17 @@ $ snforge test ```shell Collected 1 test(s) from using_cheatcodes package +Running 0 test(s) from src/ Running 1 test(s) from tests/ -[FAIL] using_cheatcodes_tests::caller_address::failing::call_and_invoke +[FAIL] using_cheatcodes_tests::call_and_invoke Failure data: 0x75736572206973206e6f7420616c6c6f776564 ('user is not allowed') Tests: 0 passed, 1 failed, 0 skipped, 0 ignored, 0 filtered out + +Failures: + using_cheatcodes_tests::call_and_invoke ```
@@ -68,7 +71,7 @@ address, so it passes our validation. ### Cheating an Address ```rust -{{#include ../../listings/snforge_overview/crates/using_cheatcodes/tests/caller_address/proper_use.cairo}} +{{#include ../../listings/using_cheatcodes_cheat_address/tests/lib.cairo}} ``` The test will now pass without an error @@ -81,16 +84,16 @@ $ snforge test Output: ```shell -Collected 1 test(s) from using_cheatcodes package +Collected 1 test(s) from using_cheatcodes_cheat_address package Running 0 test(s) from src/ Running 1 test(s) from tests/ -[PASS] using_cheatcodes_integrationtest::caller_address::proper_use::call_and_invoke (gas: ~239) +[PASS] using_cheatcodes_cheat_address_tests::call_and_invoke (gas: ~239) Tests: 1 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out ```
-### Canceling the Cheat +### Cancelling the Cheat Most cheatcodes come with corresponding `start_` and `stop_` functions that can be used to start and stop the state change. @@ -99,8 +102,7 @@ using [`stop_cheat_caller_address`](../appendix/cheatcodes/caller_address.md#sto We will demonstrate its behavior using `SafeDispatcher` to show when exactly the fail occurs: ```rust -{{#include ../../listings/snforge_overview/crates/using_cheatcodes/tests/caller_address/cancel.cairo:first_half}} -{{#include ../../listings/snforge_overview/crates/using_cheatcodes/tests/caller_address/cancel.cairo:second_half}} +{{#include ../../listings/using_cheatcodes_cancelling_cheat/tests/lib.cairo}} ``` ```shell @@ -111,15 +113,18 @@ $ snforge test Output: ```shell -Collected 1 test(s) from using_cheatcodes package -Running 0 test(s) from src/ +Collected 1 test(s) from using_cheatcodes_cancelling_cheat package Running 1 test(s) from tests/ -[FAIL] using_cheatcodes_tests::caller_address::cancel::call_and_invoke +[FAIL] using_cheatcodes_cancelling_cheat_tests::call_and_invoke Failure data: 0x5365636f6e642063616c6c206661696c656421 ('Second call failed!') -Tests: 0 passed, 1 failed, 0 skipped, 0 ignored, 4 filtered out +Running 0 test(s) from src/ +Tests: 0 passed, 1 failed, 0 skipped, 0 ignored, 0 filtered out + +Failures: + using_cheatcodes_cancelling_cheat_tests::call_and_invoke ```
@@ -132,7 +137,7 @@ In case you want to cheat the caller address for all contracts, you can use the For more see [Cheating Globally](../appendix/cheatcodes/global.md). ```rust -{{#include ../../listings/snforge_overview/crates/using_cheatcodes/tests/caller_address/proper_use_global.cairo}} +{{#include ../../listings/using_cheatcodes_others/tests/caller_address/proper_use_global.cairo}} ``` ### Cheating the Constructor @@ -144,7 +149,7 @@ Let's say, that you have a contract that saves the caller address (deployer) in To `cheat_caller_address` the constructor, you need to `start_cheat_caller_address` before it is invoked, with the right address. To achieve this, you need to precalculate the address of the contract by using the `precalculate_address` function of `ContractClassTrait` on the declared contract, and then use it in `start_cheat_caller_address` as an argument: ```rust -{{#include ../../listings/snforge_overview/crates/using_cheatcodes/tests/cheat_constructor.cairo}} +{{#include ../../listings/using_cheatcodes_others/tests/cheat_constructor.cairo}} ``` ### Setting Cheatcode Span @@ -178,5 +183,5 @@ Of course the cheatcode can still be canceled before its `CheatSpan` goes down t To better understand the functionality of `CheatSpan`, here's a full example: ```rust -{{#include ../../listings/snforge_overview/crates/using_cheatcodes/tests/caller_address/span.cairo}} +{{#include ../../listings/using_cheatcodes_others/tests/caller_address/span.cairo}} ``` diff --git a/scripts/verify_cairo_listings.sh b/scripts/verify_cairo_listings.sh index 87d31a3f72..a49c86a437 100755 --- a/scripts/verify_cairo_listings.sh +++ b/scripts/verify_cairo_listings.sh @@ -1,4 +1,5 @@ #!/bin/bash set -xe -for d in ./docs/listings/*; do (cd "$d" && scarb test); done +# TODO(#2718) +for d in ./docs/listings/*; do (cd "$d" && scarb build); done From 33f4156e105d1cdabf9c6459e804c47c729aeb68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Artur=20Micha=C5=82ek?= <52135326+cptartur@users.noreply.github.com> Date: Fri, 29 Nov 2024 17:08:50 +0100 Subject: [PATCH 16/23] Fix 1.83.0 lints (#2731) Closes # ## Introduced changes - Fixed lints introduced in clippy in rust 1.83.0 ## Checklist - [x] Linked relevant issue - [x] Updated relevant documentation - [x] Added relevant tests - [x] Performed self-review of the code - [x] Added changes to `CHANGELOG.md` --- .../mod.rs | 2 +- .../runtime.rs | 6 ++-- crates/configuration/src/lib.rs | 34 +++++++++---------- crates/conversions/src/serde/deserialize.rs | 2 +- crates/forge-runner/src/build_trace_data.rs | 11 +++--- crates/forge-runner/src/gas.rs | 2 +- crates/forge-runner/src/package_tests/raw.rs | 1 - crates/forge-runner/src/running.rs | 10 +++--- crates/forge-runner/src/test_case_summary.rs | 4 +-- crates/runtime/src/lib.rs | 8 ++--- crates/sncast/src/main.rs | 19 +++++++---- .../src/starknet_commands/account/create.rs | 2 +- .../src/starknet_commands/account/import.rs | 2 +- .../src/starknet_commands/account/list.rs | 20 +++++------ .../src/starknet_commands/account/mod.rs | 18 +++++----- .../src/starknet_commands/script/run.rs | 2 +- .../src/starknet_commands/show_config.rs | 2 +- crates/sncast/tests/helpers/devnet.rs | 2 ++ 18 files changed, 76 insertions(+), 71 deletions(-) diff --git a/crates/cheatnet/src/runtime_extensions/deprecated_cheatable_starknet_extension/mod.rs b/crates/cheatnet/src/runtime_extensions/deprecated_cheatable_starknet_extension/mod.rs index 0fff9cf90c..3380d88413 100644 --- a/crates/cheatnet/src/runtime_extensions/deprecated_cheatable_starknet_extension/mod.rs +++ b/crates/cheatnet/src/runtime_extensions/deprecated_cheatable_starknet_extension/mod.rs @@ -201,7 +201,7 @@ impl<'a> DeprecatedExtensionLogic for DeprecatedCheatableStarknetRuntimeExtensio } } -impl<'a> DeprecatedCheatableStarknetRuntimeExtension<'a> { +impl DeprecatedCheatableStarknetRuntimeExtension<'_> { // crates/blockifier/src/execution/deprecated_syscalls/hint_processor.rs:233 fn execute_syscall( &mut self, diff --git a/crates/cheatnet/src/runtime_extensions/deprecated_cheatable_starknet_extension/runtime.rs b/crates/cheatnet/src/runtime_extensions/deprecated_cheatable_starknet_extension/runtime.rs index b5fe05a40b..d9830038df 100644 --- a/crates/cheatnet/src/runtime_extensions/deprecated_cheatable_starknet_extension/runtime.rs +++ b/crates/cheatnet/src/runtime_extensions/deprecated_cheatable_starknet_extension/runtime.rs @@ -30,7 +30,7 @@ pub struct DeprecatedStarknetRuntime<'a> { pub hint_handler: DeprecatedSyscallHintProcessor<'a>, } -impl<'a> SyscallPtrAccess for DeprecatedStarknetRuntime<'a> { +impl SyscallPtrAccess for DeprecatedStarknetRuntime<'_> { fn get_mut_syscall_ptr(&mut self) -> &mut Relocatable { &mut self.hint_handler.syscall_ptr } @@ -46,7 +46,7 @@ impl<'a> SyscallPtrAccess for DeprecatedStarknetRuntime<'a> { } } -impl<'a> ResourceTracker for DeprecatedStarknetRuntime<'a> { +impl ResourceTracker for DeprecatedStarknetRuntime<'_> { fn consumed(&self) -> bool { self.hint_handler.context.vm_run_resources.consumed() } @@ -64,7 +64,7 @@ impl<'a> ResourceTracker for DeprecatedStarknetRuntime<'a> { } } -impl<'a> HintProcessorLogic for DeprecatedStarknetRuntime<'a> { +impl HintProcessorLogic for DeprecatedStarknetRuntime<'_> { fn execute_hint( &mut self, vm: &mut VirtualMachine, diff --git a/crates/configuration/src/lib.rs b/crates/configuration/src/lib.rs index 91a65cb036..3b163d3593 100644 --- a/crates/configuration/src/lib.rs +++ b/crates/configuration/src/lib.rs @@ -40,9 +40,9 @@ fn get_with_ownership(config: serde_json::Value, key: &str) -> Option, + profile: Option<&str>, ) -> Result { - let profile_name = profile.as_deref().unwrap_or("default"); + let profile_name = profile.unwrap_or("default"); let tool_config = get_with_ownership(raw_config, tool) .unwrap_or(serde_json::Value::Object(serde_json::Map::new())); @@ -54,8 +54,8 @@ pub fn get_profile( } pub fn load_config( - path: &Option, - profile: &Option, + path: Option<&Utf8PathBuf>, + profile: Option<&str>, ) -> Result { let config_path = path .as_ref() @@ -146,7 +146,7 @@ pub fn search_config_upwards_relative_to(current_dir: &Utf8PathBuf) -> Result Result { search_config_upwards_relative_to(&Utf8PathBuf::try_from( - std::env::current_dir().expect("Failed to get current directory"), + env::current_dir().expect("Failed to get current directory"), )?) } @@ -256,8 +256,8 @@ mod tests { fn load_config_happy_case_with_profile() { let tempdir = copy_config_to_tempdir("tests/data/stubtool_snfoundry.toml", None).unwrap(); let config = load_config::( - &Some(Utf8PathBuf::try_from(tempdir.path().to_path_buf()).unwrap()), - &Some(String::from("profile1")), + Some(&Utf8PathBuf::try_from(tempdir.path().to_path_buf()).unwrap()), + Some(&String::from("profile1")), ) .unwrap(); assert_eq!(config.account, String::from("user3")); @@ -268,8 +268,8 @@ mod tests { fn load_config_happy_case_default_profile() { let tempdir = copy_config_to_tempdir("tests/data/stubtool_snfoundry.toml", None).unwrap(); let config = load_config::( - &Some(Utf8PathBuf::try_from(tempdir.path().to_path_buf()).unwrap()), - &None, + Some(&Utf8PathBuf::try_from(tempdir.path().to_path_buf()).unwrap()), + None, ) .unwrap(); assert_eq!(config.account, String::from("user1")); @@ -280,8 +280,8 @@ mod tests { fn load_config_not_found() { let tempdir = tempdir().expect("Failed to create a temporary directory"); let config = load_config::( - &Some(Utf8PathBuf::try_from(tempdir.path().to_path_buf()).unwrap()), - &None, + Some(&Utf8PathBuf::try_from(tempdir.path().to_path_buf()).unwrap()), + None, ) .unwrap(); @@ -326,8 +326,8 @@ mod tests { File::create(temp_dir.path().join(CONFIG_FILENAME)).unwrap(); load_config::( - &Some(Utf8PathBuf::try_from(temp_dir.path().to_path_buf()).unwrap()), - &None, + Some(&Utf8PathBuf::try_from(temp_dir.path().to_path_buf()).unwrap()), + None, ) .unwrap(); } @@ -345,8 +345,8 @@ mod tests { .expect("Failed to copy config file to temp dir"); // missing env variables if load_config::( - &Some(Utf8PathBuf::try_from(tempdir.path().to_path_buf()).unwrap()), - &Some(String::from("with-envs")), + Some(&Utf8PathBuf::try_from(tempdir.path().to_path_buf()).unwrap()), + Some(&String::from("with-envs")), ) .is_ok() { @@ -360,8 +360,8 @@ mod tests { env::set_var("VALUE_BOOL1231321", "true"); env::set_var("VALUE_BOOL1231322", "false"); let config = load_config::( - &Some(Utf8PathBuf::try_from(tempdir.path().to_path_buf()).unwrap()), - &Some(String::from("with-envs")), + Some(&Utf8PathBuf::try_from(tempdir.path().to_path_buf()).unwrap()), + Some(&String::from("with-envs")), ) .unwrap(); assert_eq!(config.url, String::from("nfsaufbnsailfbsbksdabfnkl")); diff --git a/crates/conversions/src/serde/deserialize.rs b/crates/conversions/src/serde/deserialize.rs index 108a1dbb48..8576efcf0b 100644 --- a/crates/conversions/src/serde/deserialize.rs +++ b/crates/conversions/src/serde/deserialize.rs @@ -24,7 +24,7 @@ pub trait CairoDeserialize: Sized { fn deserialize(reader: &mut BufferReader<'_>) -> BufferReadResult; } -impl<'b> BufferReader<'b> { +impl BufferReader<'_> { #[must_use] pub fn new<'a>(buffer: &'a [Felt]) -> BufferReader<'a> { BufferReader::<'a> { buffer, idx: 0 } diff --git a/crates/forge-runner/src/build_trace_data.rs b/crates/forge-runner/src/build_trace_data.rs index bb4541795a..845775c234 100644 --- a/crates/forge-runner/src/build_trace_data.rs +++ b/crates/forge-runner/src/build_trace_data.rs @@ -40,7 +40,7 @@ pub const TEST_CODE_FUNCTION_NAME: &str = "SNFORGE_TEST_CODE_FUNCTION"; pub fn build_profiler_call_trace( value: &Rc>, contracts_data: &ContractsData, - maybe_versioned_program_path: &Option, + maybe_versioned_program_path: Option<&VersionedProgramPath>, ) -> ProfilerCallTrace { let value = value.borrow(); @@ -79,7 +79,7 @@ fn build_cairo_execution_info( entry_point: &CallEntryPoint, vm_trace: Option>, contracts_data: &ContractsData, - maybe_test_sierra_program_path: &Option, + maybe_test_sierra_program_path: Option<&VersionedProgramPath>, run_with_call_header: bool, ) -> Option { let contract_name = get_contract_name(entry_point.class_hash, contracts_data); @@ -104,13 +104,12 @@ fn build_cairo_execution_info( fn get_source_sierra_path( contract_name: &str, contracts_data: &ContractsData, - maybe_versioned_program_path: &Option, + maybe_versioned_program_path: Option<&VersionedProgramPath>, ) -> Option { if contract_name == TEST_CODE_CONTRACT_NAME { Some( maybe_versioned_program_path - .clone() - .map_or_else(Utf8PathBuf::new, Into::into), + .map_or_else(Utf8PathBuf::new, |v| Utf8PathBuf::from(v.clone())), ) } else { contracts_data @@ -122,7 +121,7 @@ fn get_source_sierra_path( fn build_profiler_call_trace_node( value: &CallTraceNode, contracts_data: &ContractsData, - maybe_versioned_program_path: &Option, + maybe_versioned_program_path: Option<&VersionedProgramPath>, ) -> ProfilerCallTraceNode { match value { CallTraceNode::EntryPointCall(trace) => ProfilerCallTraceNode::EntryPointCall( diff --git a/crates/forge-runner/src/gas.rs b/crates/forge-runner/src/gas.rs index 46d58383ee..99997d9c78 100644 --- a/crates/forge-runner/src/gas.rs +++ b/crates/forge-runner/src/gas.rs @@ -146,7 +146,7 @@ fn get_l1_data_cost( } pub fn check_available_gas( - available_gas: &Option, + available_gas: Option, summary: TestCaseSummary, ) -> TestCaseSummary { match summary { diff --git a/crates/forge-runner/src/package_tests/raw.rs b/crates/forge-runner/src/package_tests/raw.rs index d2854465f9..b669d1eec8 100644 --- a/crates/forge-runner/src/package_tests/raw.rs +++ b/crates/forge-runner/src/package_tests/raw.rs @@ -3,7 +3,6 @@ use cairo_lang_sierra::program::ProgramArtifact; use camino::Utf8PathBuf; /// these structs are representation of scarb output for `scarb build --test` - /// produced by scarb pub struct TestTargetRaw { pub sierra_file_path: Utf8PathBuf, diff --git a/crates/forge-runner/src/running.rs b/crates/forge-runner/src/running.rs index 21081c16c5..8899e3b722 100644 --- a/crates/forge-runner/src/running.rs +++ b/crates/forge-runner/src/running.rs @@ -81,7 +81,7 @@ pub fn run_test( &case, vec![], &test_runner_config.contracts_data, - &maybe_versioned_program_path, + maybe_versioned_program_path.as_ref().as_ref(), ) }) } @@ -122,7 +122,7 @@ pub(crate) fn run_fuzz_test( &case, args, &test_runner_config.contracts_data, - &maybe_versioned_program_path, + maybe_versioned_program_path.as_ref().as_ref(), ) }) } @@ -158,7 +158,7 @@ pub fn run_test_case( dict_state_reader: cheatnet_constants::build_testing_state(), fork_state_reader: get_fork_state_reader( runtime_config.cache_dir, - &case.config.fork_config, + case.config.fork_config.as_ref(), )?, }; let block_info = state_reader.get_block_info()?; @@ -290,7 +290,7 @@ fn extract_test_case_summary( case: &TestCaseWithResolvedConfig, args: Vec, contracts_data: &ContractsData, - maybe_versioned_program_path: &Option, + maybe_versioned_program_path: Option<&VersionedProgramPath>, ) -> TestCaseSummary { match run_result { Ok(result_with_info) => { @@ -338,7 +338,7 @@ fn extract_test_case_summary( fn get_fork_state_reader( cache_dir: &Utf8Path, - fork_config: &Option, + fork_config: Option<&ResolvedForkConfig>, ) -> Result> { fork_config .as_ref() diff --git a/crates/forge-runner/src/test_case_summary.rs b/crates/forge-runner/src/test_case_summary.rs index 7e13bc4cc8..5d37a7b140 100644 --- a/crates/forge-runner/src/test_case_summary.rs +++ b/crates/forge-runner/src/test_case_summary.rs @@ -219,7 +219,7 @@ impl TestCaseSummary { call_trace: &Rc>, encountered_errors: &[EncounteredError], contracts_data: &ContractsData, - maybe_versioned_program_path: &Option, + maybe_versioned_program_path: Option<&VersionedProgramPath>, ) -> Self { let name = test_case.name.clone(); let msg = extract_result_data(&run_result, &test_case.config.expected_result) @@ -240,7 +240,7 @@ impl TestCaseSummary { maybe_versioned_program_path, )), }; - check_available_gas(&test_case.config.available_gas, summary) + check_available_gas(test_case.config.available_gas, summary) } ExpectedTestResult::Panics(_) => TestCaseSummary::Failed { name, diff --git a/crates/runtime/src/lib.rs b/crates/runtime/src/lib.rs index e884df8b3a..639d6439c4 100644 --- a/crates/runtime/src/lib.rs +++ b/crates/runtime/src/lib.rs @@ -63,7 +63,7 @@ pub struct StarknetRuntime<'a> { pub hint_handler: SyscallHintProcessor<'a>, } -impl<'a> SyscallPtrAccess for StarknetRuntime<'a> { +impl SyscallPtrAccess for StarknetRuntime<'_> { fn get_mut_syscall_ptr(&mut self) -> &mut Relocatable { &mut self.hint_handler.syscall_ptr } @@ -73,7 +73,7 @@ impl<'a> SyscallPtrAccess for StarknetRuntime<'a> { } } -impl<'a> ResourceTracker for StarknetRuntime<'a> { +impl ResourceTracker for StarknetRuntime<'_> { fn consumed(&self) -> bool { self.hint_handler.context.vm_run_resources.consumed() } @@ -91,7 +91,7 @@ impl<'a> ResourceTracker for StarknetRuntime<'a> { } } -impl<'a> SignalPropagator for StarknetRuntime<'a> { +impl SignalPropagator for StarknetRuntime<'_> { fn propagate_system_call_signal( &mut self, _selector: DeprecatedSyscallSelector, @@ -121,7 +121,7 @@ fn fetch_cheatcode_input( Ok(inputs) } -impl<'a> HintProcessorLogic for StarknetRuntime<'a> { +impl HintProcessorLogic for StarknetRuntime<'_> { fn execute_hint( &mut self, vm: &mut VirtualMachine, diff --git a/crates/sncast/src/main.rs b/crates/sncast/src/main.rs index 8effdafb05..710f2a97bb 100644 --- a/crates/sncast/src/main.rs +++ b/crates/sncast/src/main.rs @@ -586,9 +586,13 @@ async fn run_async_command( Commands::ShowConfig(show) => { let provider = show.rpc.get_provider(&config).await.ok(); - let result = - starknet_commands::show_config::show_config(&show, &provider, config, cli.profile) - .await; + let result = starknet_commands::show_config::show_config( + &show, + provider.as_ref(), + config, + cli.profile, + ) + .await; print_command_result("show-config", &result, numbers_format, output_format)?; @@ -742,10 +746,13 @@ fn get_cast_config(cli: &Cli) -> Result { Utf8PathBuf::new() }); - let global_config = load_config::(&Some(global_config_path.clone()), &cli.profile) - .unwrap_or_else(|_| load_config::(&Some(global_config_path), &None).unwrap()); + let global_config = + load_config::(Some(&global_config_path.clone()), cli.profile.as_deref()) + .unwrap_or_else(|_| { + load_config::(Some(&global_config_path), None).unwrap() + }); - let local_config = load_config::(&None, &cli.profile)?; + let local_config = load_config::(None, cli.profile.as_deref())?; let mut combined_config = combine_cast_configs(&global_config, &local_config); diff --git a/crates/sncast/src/starknet_commands/account/create.rs b/crates/sncast/src/starknet_commands/account/create.rs index 286ff21e4b..27d444e85f 100644 --- a/crates/sncast/src/starknet_commands/account/create.rs +++ b/crates/sncast/src/starknet_commands/account/create.rs @@ -116,7 +116,7 @@ pub async fn create( keystore, ..Default::default() }; - add_created_profile_to_configuration(&create.add_profile, &config, &None)?; + add_created_profile_to_configuration(create.add_profile.as_deref(), &config, None)?; } Ok(AccountCreateResponse { diff --git a/crates/sncast/src/starknet_commands/account/import.rs b/crates/sncast/src/starknet_commands/account/import.rs index 96d350055a..bd756b72d6 100644 --- a/crates/sncast/src/starknet_commands/account/import.rs +++ b/crates/sncast/src/starknet_commands/account/import.rs @@ -158,7 +158,7 @@ pub async fn import( accounts_file: accounts_file.into(), ..Default::default() }; - add_created_profile_to_configuration(&import.add_profile, &config, &None)?; + add_created_profile_to_configuration(import.add_profile.as_deref(), &config, None)?; } Ok(AccountImportResponse { diff --git a/crates/sncast/src/starknet_commands/account/list.rs b/crates/sncast/src/starknet_commands/account/list.rs index 0403064164..1e52c668ca 100644 --- a/crates/sncast/src/starknet_commands/account/list.rs +++ b/crates/sncast/src/starknet_commands/account/list.rs @@ -115,23 +115,23 @@ fn print_as_json(networks: &HashMap) -> anyho Ok(()) } -fn print_if_some(title: &str, item: &Option) { - if let Some(ref item) = item { +fn print_if_some(title: &str, item: Option<&T>) { + if let Some(item) = item { println!(" {title}: {item}"); } } fn print_pretty(data: &AccountDataRepresentation, name: &str) { println!("- {name}:"); - print_if_some("network", &data.network); - print_if_some("private key", &data.private_key); + print_if_some("network", data.network.as_ref()); + print_if_some("private key", data.private_key.as_ref()); println!(" public key: {}", data.public_key); - print_if_some("address", &data.address); - print_if_some("salt", &data.salt); - print_if_some("class hash", &data.class_hash); - print_if_some("deployed", &data.deployed); - print_if_some("legacy", &data.legacy); - print_if_some("type", &data.account_type); + print_if_some("address", data.address.as_ref()); + print_if_some("salt", data.salt.as_ref()); + print_if_some("class hash", data.class_hash.as_ref()); + print_if_some("deployed", data.deployed.as_ref()); + print_if_some("legacy", data.legacy.as_ref()); + print_if_some("type", data.account_type.as_ref()); println!(); } diff --git a/crates/sncast/src/starknet_commands/account/mod.rs b/crates/sncast/src/starknet_commands/account/mod.rs index dc32f53a87..b636757aa4 100644 --- a/crates/sncast/src/starknet_commands/account/mod.rs +++ b/crates/sncast/src/starknet_commands/account/mod.rs @@ -124,9 +124,9 @@ pub fn write_account_to_accounts_file( } pub fn add_created_profile_to_configuration( - profile: &Option, + profile: Option<&str>, cast_config: &CastConfig, - path: &Option, + path: Option<&Utf8PathBuf>, ) -> Result<()> { if !load_config::(path, profile) .unwrap_or_default() @@ -135,7 +135,7 @@ pub fn add_created_profile_to_configuration( { bail!( "Failed to add profile = {} to the snfoundry.toml. Profile already exists", - profile.as_ref().unwrap_or(&"default".to_string()) + profile.unwrap_or("default") ); } @@ -157,9 +157,7 @@ pub fn add_created_profile_to_configuration( } let mut profile_config = toml::value::Table::new(); profile_config.insert( - profile - .clone() - .unwrap_or_else(|| cast_config.account.clone()), + profile.map_or_else(|| cast_config.account.clone(), ToString::to_string), Value::Table(new_profile), ); @@ -208,9 +206,9 @@ mod tests { ..Default::default() }; let res = add_created_profile_to_configuration( - &Some(String::from("some-name")), + Some(&String::from("some-name")), &config, - &Some(path.clone()), + Some(&path.clone()), ); assert!(res.is_ok()); @@ -233,9 +231,9 @@ mod tests { ..Default::default() }; let res = add_created_profile_to_configuration( - &Some(String::from("default")), + Some(&String::from("default")), &config, - &Some(Utf8PathBuf::try_from(tempdir.path().to_path_buf()).unwrap()), + Some(&Utf8PathBuf::try_from(tempdir.path().to_path_buf()).unwrap()), ); assert!(res.is_err()); } diff --git a/crates/sncast/src/starknet_commands/script/run.rs b/crates/sncast/src/starknet_commands/script/run.rs index 03e3617203..64de368a37 100644 --- a/crates/sncast/src/starknet_commands/script/run.rs +++ b/crates/sncast/src/starknet_commands/script/run.rs @@ -81,7 +81,7 @@ pub struct CastScriptExtension<'a> { pub state: StateManager, } -impl<'a> CastScriptExtension<'a> { +impl CastScriptExtension<'_> { pub fn account( &self, ) -> Result<&SingleOwnerAccount<&JsonRpcClient, LocalWallet>> { diff --git a/crates/sncast/src/starknet_commands/show_config.rs b/crates/sncast/src/starknet_commands/show_config.rs index fafbe6b59a..4cfbbcaf2e 100644 --- a/crates/sncast/src/starknet_commands/show_config.rs +++ b/crates/sncast/src/starknet_commands/show_config.rs @@ -18,7 +18,7 @@ pub struct ShowConfig { #[allow(clippy::ptr_arg)] pub async fn show_config( show: &ShowConfig, - provider: &Option>, + provider: Option<&JsonRpcClient>, cast_config: CastConfig, profile: Option, ) -> Result { diff --git a/crates/sncast/tests/helpers/devnet.rs b/crates/sncast/tests/helpers/devnet.rs index 5dc6cc7ab3..491f0634fb 100644 --- a/crates/sncast/tests/helpers/devnet.rs +++ b/crates/sncast/tests/helpers/devnet.rs @@ -11,6 +11,7 @@ use std::time::{Duration, Instant}; use tokio::runtime::Runtime; use url::Url; +#[allow(clippy::zombie_processes)] #[cfg(test)] #[ctor] fn start_devnet() { @@ -75,6 +76,7 @@ fn start_devnet() { rt.block_on(deploy_braavos_account()); } +#[allow(clippy::zombie_processes)] #[cfg(test)] #[dtor] fn stop_devnet() { From 4e4058835dcf6e470ef4368069ed1b94a9dd7937 Mon Sep 17 00:00:00 2001 From: Franciszek Job <54181625+franciszekjob@users.noreply.github.com> Date: Fri, 29 Nov 2024 20:39:49 +0100 Subject: [PATCH 17/23] Add backtrace in changelog (#2728) Closes # ## Introduced changes - ## Checklist - [x] Linked relevant issue - [x] Updated relevant documentation - [x] Added relevant tests - [x] Performed self-review of the code - [x] Added changes to `CHANGELOG.md` --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index acef01e233..a38295a70b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `generate_random_felt()` for generating (pseudo) random felt value. - Printing information about compiling Sierra using `universal-sierra-compiler` +- Displaying backtrace when contract call fails #### Changed From b52c9cf7b07fd0a34d44f5dab5c6952d3754f908 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 12:09:44 +0100 Subject: [PATCH 18/23] Bump the prod-deps group with 14 updates (#2739) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the prod-deps group with 14 updates: | Package | From | To | | --- | --- | --- | | [anyhow](https://github.com/dtolnay/anyhow) | `1.0.92` | `1.0.93` | | [clap](https://github.com/clap-rs/clap) | `4.5.20` | `4.5.21` | | [serde](https://github.com/serde-rs/serde) | `1.0.214` | `1.0.215` | | [serde_json](https://github.com/serde-rs/json) | `1.0.132` | `1.0.133` | | [tempfile](https://github.com/Stebalien/tempfile) | `3.13.0` | `3.14.0` | | [thiserror](https://github.com/dtolnay/thiserror) | `1.0.67` | `1.0.69` | | [ctor](https://github.com/mmastrac/rust-ctor) | `0.2.8` | `0.2.9` | | [url](https://github.com/servo/rust-url) | `2.5.3` | `2.5.4` | | [tokio](https://github.com/tokio-rs/tokio) | `1.41.0` | `1.41.1` | | [axum](https://github.com/tokio-rs/axum) | `0.7.7` | `0.7.9` | | [flate2](https://github.com/rust-lang/flate2-rs) | `1.0.34` | `1.0.35` | | [const-hex](https://github.com/danipopes/const-hex) | `1.13.1` | `1.14.0` | | [indicatif](https://github.com/console-rs/indicatif) | `0.17.8` | `0.17.9` | | [proc-macro2](https://github.com/dtolnay/proc-macro2) | `1.0.89` | `1.0.92` | Updates `anyhow` from 1.0.92 to 1.0.93
Release notes

Sourced from anyhow's releases.

1.0.93

  • Update dev-dependencies to thiserror v2
Commits
  • 713bda9 Release 1.0.93
  • f91c247 Merge pull request #391 from dtolnay/thiserror
  • 2a3901c Isolate old rustc version tests from needing anyhow dev-dependencies in lockfile
  • 3ca2cdd Update dev-dependencies to thiserror v2
  • See full diff in compare view

Updates `clap` from 4.5.20 to 4.5.21
Release notes

Sourced from clap's releases.

v4.5.21

[4.5.21] - 2024-11-13

Fixes

  • (parser) Ensure defaults are filled in on error with ignore_errors(true)
Changelog

Sourced from clap's changelog.

[4.5.21] - 2024-11-13

Fixes

  • (parser) Ensure defaults are filled in on error with ignore_errors(true)
Commits
  • 03d7226 chore: Release
  • 3df70fb docs: Update changelog
  • 3266c36 Merge pull request #5691 from epage/custom
  • 951762d feat(complete): Allow any OsString-compatible type to be a CompletionCandidate
  • bb6493e feat(complete): Offer - as a path option
  • 27b348d refactor(complete): Simplify ArgValueCandidates code
  • 49b8108 feat(complete): Add PathCompleter
  • 82a360a feat(complete): Add ArgValueCompleter
  • 47aedc6 fix(complete): Ensure paths are sorted
  • 431e2bc test(complete): Ensure ArgValueCandidates get filtered
  • Additional commits viewable in compare view

Updates `serde` from 1.0.214 to 1.0.215
Release notes

Sourced from serde's releases.

v1.0.215

  • Produce warning when multiple fields or variants have the same deserialization name (#2855, #2856, #2857)
Commits
  • 8939af4 Release 1.0.215
  • fa5d58c Use ui test syntax that does not interfere with rustfmt
  • 1a3cf4b Update PR 2562 ui tests
  • 7d96352 Merge pull request #2857 from dtolnay/collide
  • 111ecc5 Update ui tests for warning on colliding aliases
  • edd6fe9 Revert "Add checks for conflicts for aliases"
  • a20e924 Revert "pacify clippy"
  • b1353a9 Merge pull request #2856 from dtolnay/dename
  • c59e876 Produce a separate warning for every colliding name
  • 7f1e697 Merge pull request #2855 from dtolnay/namespan
  • Additional commits viewable in compare view

Updates `serde_json` from 1.0.132 to 1.0.133
Release notes

Sourced from serde_json's releases.

v1.0.133

  • Implement From<[T; N]> for serde_json::Value (#1215)
Commits
  • 0903de4 Release 1.0.133
  • 2b65ca0 Merge pull request #1215 from dtolnay/fromarray
  • 4e5f985 Implement From<[T; N]> for Value
  • 2ccb5b6 Disable question_mark clippy lint in lexical test
  • a11f5f2 Resolve unnecessary_map_or clippy lints
  • 07f280a Wrap PR 1213 to 80 columns
  • 75ed447 Merge pull request #1213 from djmitche/safety-comment
  • 73011c0 Add a safety comment to unsafe block
  • be2198a Prevent upload-artifact step from causing CI failure
  • 7cce517 Raise minimum version for preserve_order feature to Rust 1.65
  • Additional commits viewable in compare view

Updates `tempfile` from 3.13.0 to 3.14.0
Changelog

Sourced from tempfile's changelog.

3.14.0

  • Make the wasip2 target work (requires tempfile's "nightly" feature to be enabled). #305.
  • Allow older windows-sys versions #304.
Commits

Updates `thiserror` from 1.0.67 to 1.0.69
Release notes

Sourced from thiserror's releases.

1.0.69

1.0.68

  • Handle incomplete expressions more robustly in format arguments, such as while code is being typed (#341, #344)
Commits
  • 41938bd Release 1.0.69
  • 9d6506e Merge pull request #382 from dtolnay/hang
  • 591a44d Fix fallback fmt expression parser hang
  • 5b36e37 Add ui test of invalid expression syntax in display attribute
  • 8d06fb5 Release 1.0.68
  • 372fd8a Merge pull request #344 from dtolnay/binop
  • 08f8992 Disregard equality binop in fallback parser
  • d2a823d Merge pull request #343 from dtolnay/unnamed
  • b3bf7a6 Add logic to determine whether unnamed fmt arguments are present
  • 490f9c0 Merge pull request #342 from dtolnay/synfull
  • Additional commits viewable in compare view

Updates `ctor` from 0.2.8 to 0.2.9
Commits

Updates `url` from 2.5.3 to 2.5.4
Release notes

Sourced from url's releases.

v2.5.4

What's Changed

  • Revert "Normalize URL paths: convert /.//p, /..//p, and //p to p (#943)" by @​valenting in servo/rust-url#999
  • Updates the MSRV to 1.63 required though the libc v0.2.164 dependency

Full Changelog: https://github.com/servo/rust-url/compare/v2.5.3...v2.5.4

Commits

Updates `tokio` from 1.41.0 to 1.41.1
Release notes

Sourced from tokio's releases.

Tokio v1.41.1

1.41.1 (Nov 7th, 2024)

Fixed

  • metrics: fix bug with wrong number of buckets for the histogram (#6957)
  • net: display net requirement for net::UdpSocket in docs (#6938)
  • net: fix typo in TcpStream internal comment (#6944)

#6957: tokio-rs/tokio#6957 #6938: tokio-rs/tokio#6938 #6944: tokio-rs/tokio#6944

Commits
  • bb7ca75 chore: prepare Tokio v1.41.1 (#6959)
  • 4a34b77 metrics: fix bug with wrong number of buckets for the histogram (#6957)
  • 8897885 docs: fix mismatched backticks in CONTRIBUTING.md (#6951)
  • 0dbdd19 ci: update cargo-check-external-types to 0.1.13 (#6949)
  • 94e55c0 net: fix typo in TcpStream internal comment (#6944)
  • 4468f27 metrics: fixed flaky worker_steal_count test (#6932)
  • 070a825 metrics: removed race condition from global_queue_depth_multi_thread test (#6...
  • 946401c net: display net requirement for net::UdpSocket in docs (#6938)
  • 0c01fd2 ci: use patched version of cargo-check-external-types to fix CI failure (#6937)
  • ebe2416 ci: use cargo deny (#6931)
  • See full diff in compare view

Updates `axum` from 0.7.7 to 0.7.9
Release notes

Sourced from axum's releases.

axum - v0.7.9

  • fixed: Avoid setting content-length before middleware (#3031)

#3031:tokio-rs/axum#3031

axum - v0.7.8

  • fixed: Skip SSE incompatible chars of serde_json::RawValue in Event::json_data (#2992)
  • added: Add method_not_allowed_fallback to set a fallback when a path matches but there is no handler for the given HTTP method (#2903)
  • added: Add MethodFilter::CONNECT, routing::connect[_service] and MethodRouter::connect[_service] (#2961)
  • added: Add NoContent as a self-described shortcut for StatusCode::NO_CONTENT (#2978)

#2903: tokio-rs/axum#2903 #2961: tokio-rs/axum#2961 #2978: tokio-rs/axum#2978 #2992: tokio-rs/axum#2992

Commits

Updates `flate2` from 1.0.34 to 1.0.35
Release notes

Sourced from flate2's releases.

1.0.35 - security update to zlib-rs

What's Changed

New Contributors

Full Changelog: https://github.com/rust-lang/flate2-rs/compare/1.0.34...1.0.35

Commits

Updates `const-hex` from 1.13.1 to 1.14.0
Commits
  • 624ea07 chore: Release const-hex version 1.14.0
  • 3e38e09 feat: add 'core-error' feature (#19)
  • 7b43bc0 chore: Release const-hex version 1.13.2
  • aa535d6 fix: require target_feature = "simd128" on wasm32 (#18)
  • ce406b5 chore: update benchmark results
  • a7d9991 chore: add encode/decode bench for rustc-hex (#15)
  • See full diff in compare view

Updates `indicatif` from 0.17.8 to 0.17.9
Release notes

Sourced from indicatif's releases.

0.17.9

What's Changed

Commits
  • e84863a feat: allow constructing and setting the progress bar len to None (#664)
  • 90a1f3b Bump version to 0.17.9
  • 83da31e Bump EmbarkStudios/cargo-deny-action from 1 to 2
  • 884ddfb Replace instant with web-time
  • 5396704 Update unicode-width requirement from 0.1 to 0.2
  • fde06b7 Update deny config for cargo-deny 0.15 release
  • 6c01758 bump MSRV to 1.70 for Tokio 1.39.2
  • ffd3cda ProgressBar::new: update doc string to reflect correct default refresh rate
  • d323a96 Fix 'lazy continuation' lint errors in docs
  • 5295317 Fix AtomicPosition::reset storing wrong value (#650)
  • Additional commits viewable in compare view

Updates `proc-macro2` from 1.0.89 to 1.0.92
Release notes

Sourced from proc-macro2's releases.

1.0.92

  • Improve compiler/fallback mismatch panic message (#487)

1.0.91

  • Fix panic "compiler/fallback mismatch 949" when using TokenStream::from_str from inside a proc macro to parse a string containing doc comment (#484)

1.0.90

  • Improve error recovery in TokenStream's and Literal's FromStr implementations to work around rust-lang/rust#58736 such that rustc does not poison compilation on codepaths that should be recoverable errors (#477, #478, #479, #480, #481, #482)
Commits
  • acc7d36 Release 1.0.92
  • 0cb443d Merge pull request #487 from dtolnay/mismatchline
  • ae478ed Change mismatch panic message to avoid github linkifying
  • 5046761 Release 1.0.91
  • 27c5494 Merge pull request #486 from dtolnay/compilerlex
  • a9146d6 Ensure that compiler tokenstream parsing only produces a compiler lexerror
  • 1ce5f04 Merge pull request #485 from dtolnay/fallbackident
  • 75d0818 Make parser's fallback Ident symmetric with Group and Literal
  • 56c3e31 Merge pull request #484 from dtolnay/fbliteral
  • d2c0e61 Fix spanned fallback literal construction
  • Additional commits viewable in compare view

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 100 ++++++++++-------- Cargo.toml | 26 ++--- .../conversions/cairo-serde-macros/Cargo.toml | 2 +- 3 files changed, 72 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 63cec86a7f..b9fa0b1262 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -121,9 +121,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.92" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f37166d7d48a0284b99dd824694c26119c700b53bf0d1540cdb147dbdaaf13" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" [[package]] name = "ark-ec" @@ -335,9 +335,9 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "axum" -version = "0.7.7" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" dependencies = [ "async-trait", "axum-core", @@ -1320,9 +1320,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.20" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" dependencies = [ "clap_builder", "clap_derive", @@ -1330,9 +1330,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.20" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" dependencies = [ "anstream", "anstyle", @@ -1407,7 +1407,7 @@ dependencies = [ "encode_unicode", "lazy_static", "libc", - "unicode-width", + "unicode-width 0.1.13", "windows-sys 0.52.0", ] @@ -1419,9 +1419,9 @@ checksum = "32b13ea120a812beba79e34316b3942a857c86ec1593cb34f27bb28272ce2cca" [[package]] name = "const-hex" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0121754e84117e65f9d90648ee6aa4882a6e63110307ab73967a4c5e7e69e586" +checksum = "4b0485bab839b018a8f1723fc5391819fea5f8f0f32288ef8a735fd096b6160c" dependencies = [ "cfg-if", "cpufeatures", @@ -1593,9 +1593,9 @@ dependencies = [ [[package]] name = "ctor" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" +checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" dependencies = [ "quote", "syn 2.0.87", @@ -2100,9 +2100,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.34" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", "miniz_oxide", @@ -3038,15 +3038,15 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.17.8" +version = "0.17.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" +checksum = "cbf675b85ed934d3c67b5c5469701eec7db22689d0a2139d856e0925fa28b281" dependencies = [ "console", - "instant", "number_prefix", "portable-atomic", - "unicode-width", + "unicode-width 0.2.0", + "web-time", ] [[package]] @@ -3224,9 +3224,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.158" +version = "0.2.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" [[package]] name = "libm" @@ -3981,9 +3981,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.89" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -4353,9 +4353,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ "bitflags 2.6.0", "errno", @@ -4420,7 +4420,7 @@ dependencies = [ "scopeguard", "smallvec", "unicode-segmentation", - "unicode-width", + "unicode-width 0.1.13", "utf8parse", "winapi", ] @@ -4622,18 +4622,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", @@ -4653,9 +4653,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", @@ -5403,9 +5403,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", @@ -5500,18 +5500,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.67" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3c6efbfc763e64eb85c11c25320f0737cb7364c4b6336db90aa9ebe27a0bbd" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.67" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b607164372e89797d78b8e23a6d67d5d1038c1c65efd52e1389ef8b77caba2a6" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", @@ -5590,9 +5590,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.41.0" +version = "1.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" dependencies = [ "backtrace", "bytes", @@ -5827,6 +5827,12 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + [[package]] name = "unicode-xid" version = "0.2.5" @@ -5858,9 +5864,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.3" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", @@ -6016,6 +6022,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "webpki" version = "0.22.4" diff --git a/Cargo.toml b/Cargo.toml index 694ea4aaae..d17dd84fb9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,10 +55,10 @@ cairo-vm = "1.0.0-rc3" cairo-annotations = "0.1.0" dirs = "5.0.1" starknet-types-core = { version = "0.1.7", features = ["hash", "prime-bigint"] } -anyhow = "1.0.92" +anyhow = "1.0.93" assert_fs = "1.1.2" camino = { version = "1.1.9", features = ["serde1"] } -clap = { version = "4.5.20", features = ["derive"] } +clap = { version = "4.5.21", features = ["derive"] } console = "0.15.8" include_dir = "0.7.4" indoc = "2" @@ -66,15 +66,15 @@ itertools = "0.12.1" num-traits = "0.2.19" rayon = "1.10" regex = "1.11.1" -serde = { version = "1.0.214", features = ["derive"] } -serde_json = "1.0.132" +serde = { version = "1.0.215", features = ["derive"] } +serde_json = "1.0.133" starknet = { git = "https://github.com/xJonathanLEI/starknet-rs", rev = "660a732" } starknet-crypto = { git = "https://github.com/xJonathanLEI/starknet-rs", rev = "660a732" } -tempfile = "3.13.0" -thiserror = "1.0.67" -ctor = "0.2.8" -url = { "version" = "2.5.3", "features" = ["serde"] } -tokio = { version = "1.41.0", features = ["full"] } +tempfile = "3.14.0" +thiserror = "1.0.69" +ctor = "0.2.9" +url = { "version" = "2.5.4", "features" = ["serde"] } +tokio = { version = "1.41.1", features = ["full"] } tokio-util = "0.7.11" futures = "0.3.31" num-bigint = { version = "0.4.6", features = ["rand"] } @@ -109,10 +109,10 @@ ark-secp256k1 = "0.4.0" ark-secp256r1 = "0.4.0" openssl = { version = "0.10", features = ["vendored"] } toml_edit = "0.22.22" -axum = "0.7.7" +axum = "0.7.9" lazy_static = "1.5.0" fs2 = "0.4.3" -flate2 = "1.0.34" +flate2 = "1.0.35" k256 = { version = "0.13.4", features = ["sha256", "ecdsa", "serde"] } p256 = { version = "0.13.2", features = ["sha256", "ecdsa", "serde"] } glob = "0.3.1" @@ -122,5 +122,5 @@ fs4 = "0.7" async-trait = "0.1.83" serde_path_to_error = "0.1.16" wiremock = "0.6.0" -const-hex = "1.13.1" -indicatif = "0.17.8" +const-hex = "1.14.0" +indicatif = "0.17.9" diff --git a/crates/conversions/cairo-serde-macros/Cargo.toml b/crates/conversions/cairo-serde-macros/Cargo.toml index 4da7e3d161..8fdba8a168 100644 --- a/crates/conversions/cairo-serde-macros/Cargo.toml +++ b/crates/conversions/cairo-serde-macros/Cargo.toml @@ -9,4 +9,4 @@ proc-macro = true [dependencies] syn = "2.0.79" quote = "1.0.37" -proc-macro2 = "1.0.89" +proc-macro2 = "1.0.92" From 1a42d6d0e942157ecc7f6e199b3798a072285aa7 Mon Sep 17 00:00:00 2001 From: ddoktorski <45050160+ddoktorski@users.noreply.github.com> Date: Mon, 2 Dec 2024 12:52:42 +0100 Subject: [PATCH 19/23] Catch non provider errors in sncast commands (#2724) Closes #2536 ## Introduced changes - Catch errors that can occur before sending the transaction. They are very unlikely to happen, but if they do occur they will be displayed with relevant information instead of printing `Unknown RPC error` - Slight formatting improvement ## Checklist - [X] Linked relevant issue - [X] Updated relevant documentation - [X] Added relevant tests - [X] Performed self-review of the code - [X] Added changes to `CHANGELOG.md` --- crates/sncast/src/response/errors.rs | 11 +++++------ crates/sncast/src/starknet_commands/declare.rs | 2 +- crates/sncast/src/starknet_commands/deploy.rs | 2 +- crates/sncast/src/starknet_commands/invoke.rs | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/crates/sncast/src/response/errors.rs b/crates/sncast/src/response/errors.rs index 5f40a35a95..8d62e8dfa3 100644 --- a/crates/sncast/src/response/errors.rs +++ b/crates/sncast/src/response/errors.rs @@ -4,9 +4,6 @@ use conversions::serde::serialize::CairoSerialize; use conversions::byte_array::ByteArray; -use starknet::core::types::StarknetError::{ - ContractError, TransactionExecutionError, ValidationFailure, -}; use starknet::core::types::{ContractErrorData, StarknetError, TransactionExecutionErrorData}; use starknet::providers::ProviderError; use thiserror::Error; @@ -111,15 +108,17 @@ impl From for SNCastStarknetError { StarknetError::InvalidTransactionIndex => SNCastStarknetError::InvalidTransactionIndex, StarknetError::ClassHashNotFound => SNCastStarknetError::ClassHashNotFound, StarknetError::TransactionHashNotFound => SNCastStarknetError::TransactionHashNotFound, - ContractError(err) => SNCastStarknetError::ContractError(err), - TransactionExecutionError(err) => SNCastStarknetError::TransactionExecutionError(err), + StarknetError::ContractError(err) => SNCastStarknetError::ContractError(err), + StarknetError::TransactionExecutionError(err) => { + SNCastStarknetError::TransactionExecutionError(err) + } StarknetError::ClassAlreadyDeclared => SNCastStarknetError::ClassAlreadyDeclared, StarknetError::InvalidTransactionNonce => SNCastStarknetError::InvalidTransactionNonce, StarknetError::InsufficientMaxFee => SNCastStarknetError::InsufficientMaxFee, StarknetError::InsufficientAccountBalance => { SNCastStarknetError::InsufficientAccountBalance } - ValidationFailure(err) => { + StarknetError::ValidationFailure(err) => { SNCastStarknetError::ValidationFailure(ByteArray::from(err.as_str())) } StarknetError::CompilationFailed => SNCastStarknetError::CompilationFailed, diff --git a/crates/sncast/src/starknet_commands/declare.rs b/crates/sncast/src/starknet_commands/declare.rs index 0dffb9ed76..6cdbe8a406 100644 --- a/crates/sncast/src/starknet_commands/declare.rs +++ b/crates/sncast/src/starknet_commands/declare.rs @@ -150,6 +150,6 @@ pub async fn declare( })) } Err(Provider(error)) => Err(StarknetCommandError::ProviderError(error.into())), - _ => Err(anyhow!("Unknown RPC error").into()), + Err(error) => Err(anyhow!(format!("Unexpected error occurred: {error}")).into()), } } diff --git a/crates/sncast/src/starknet_commands/deploy.rs b/crates/sncast/src/starknet_commands/deploy.rs index 2cbf89db28..8b3bcb4e29 100644 --- a/crates/sncast/src/starknet_commands/deploy.rs +++ b/crates/sncast/src/starknet_commands/deploy.rs @@ -140,6 +140,6 @@ pub async fn deploy( .await .map_err(StarknetCommandError::from), Err(Provider(error)) => Err(StarknetCommandError::ProviderError(error.into())), - _ => Err(anyhow!("Unknown RPC error").into()), + Err(error) => Err(anyhow!(format!("Unexpected error occurred: {error}")).into()), } } diff --git a/crates/sncast/src/starknet_commands/invoke.rs b/crates/sncast/src/starknet_commands/invoke.rs index 636f68941d..8d481d6cf8 100644 --- a/crates/sncast/src/starknet_commands/invoke.rs +++ b/crates/sncast/src/starknet_commands/invoke.rs @@ -118,6 +118,6 @@ pub async fn execute_calls( .await .map_err(StarknetCommandError::from), Err(Provider(error)) => Err(StarknetCommandError::ProviderError(error.into())), - _ => Err(anyhow!("Unknown RPC error").into()), + Err(error) => Err(anyhow!(format!("Unexpected error occurred: {error}")).into()), } } From 334f7699125bf6bb68ef4e334908191f010aef02 Mon Sep 17 00:00:00 2001 From: Szymon Sadowski <50834734+Nemezjusz@users.noreply.github.com> Date: Mon, 2 Dec 2024 12:54:27 +0100 Subject: [PATCH 20/23] Extend plugin diagnostics with warnings (#2702) Resolves #2358 Hi, I think I finished this issue, but let me know if I should change anything! --- CHANGELOG.md | 6 ++++++ crates/snforge-scarb-plugin/src/args/unnamed.rs | 2 +- crates/snforge-scarb-plugin/src/common.rs | 8 ++++---- .../integration/single_attributes/available_gas.rs | 8 +++++--- .../tests/integration/single_attributes/fork.rs | 13 +++++++------ 5 files changed, 23 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a38295a70b..8d65aae31f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### `snforge_scarb_plugin` + +#### Changed + + - `snforge_scarb_plugin` will now also emit warnings when errors occur + ## [0.34.0] - 2024-11-26 ### Forge diff --git a/crates/snforge-scarb-plugin/src/args/unnamed.rs b/crates/snforge-scarb-plugin/src/args/unnamed.rs index 26dbdc2f44..79d6ef69d5 100644 --- a/crates/snforge-scarb-plugin/src/args/unnamed.rs +++ b/crates/snforge-scarb-plugin/src/args/unnamed.rs @@ -31,6 +31,6 @@ impl<'a> UnnamedArgs<'a> { ) -> Result<&[(usize, &'a Expr); N], Diagnostic> { self.as_slice() .try_into() - .map_err(|_| T::error(format!("expected {} arguments, got: {}", N, self.len()))) + .map_err(|_| T::error(format!("expected arguments: {}, got: {}", N, self.len()))) } } diff --git a/crates/snforge-scarb-plugin/src/common.rs b/crates/snforge-scarb-plugin/src/common.rs index 54c05dc53d..1f295d6985 100644 --- a/crates/snforge-scarb-plugin/src/common.rs +++ b/crates/snforge-scarb-plugin/src/common.rs @@ -18,10 +18,10 @@ pub fn into_proc_macro_result( match handler(&args, &item, &mut warns) { Ok(item) => ProcMacroResult::new(TokenStream::new(item)).with_diagnostics(warns.into()), - Err(diagnostics) => ProcMacroResult::new(item).with_diagnostics( - //TODO(#2358) extend with warns - diagnostics, - ), + Err(mut diagnostics) => { + diagnostics.extend(warns); + ProcMacroResult::new(item).with_diagnostics(diagnostics) + } } } diff --git a/crates/snforge-scarb-plugin/tests/integration/single_attributes/available_gas.rs b/crates/snforge-scarb-plugin/tests/integration/single_attributes/available_gas.rs index 8f2c978de0..890758c69c 100644 --- a/crates/snforge-scarb-plugin/tests/integration/single_attributes/available_gas.rs +++ b/crates/snforge-scarb-plugin/tests/integration/single_attributes/available_gas.rs @@ -12,8 +12,10 @@ fn fails_with_empty() { assert_diagnostics( &result, - &[Diagnostic::error( - "#[available_gas] expected 1 arguments, got: 0", + &[ + Diagnostic::warn("#[available_gas] used with empty argument list. Either remove () or specify some arguments"), + Diagnostic::error( + "#[available_gas] expected arguments: 1, got: 0", )], ); } @@ -28,7 +30,7 @@ fn fails_with_more_than_one() { assert_diagnostics( &result, &[Diagnostic::error( - "#[available_gas] expected 1 arguments, got: 3", + "#[available_gas] expected arguments: 1, got: 3", )], ); } diff --git a/crates/snforge-scarb-plugin/tests/integration/single_attributes/fork.rs b/crates/snforge-scarb-plugin/tests/integration/single_attributes/fork.rs index a92a4a02b4..efdf280d54 100644 --- a/crates/snforge-scarb-plugin/tests/integration/single_attributes/fork.rs +++ b/crates/snforge-scarb-plugin/tests/integration/single_attributes/fork.rs @@ -17,7 +17,7 @@ fn fails_without_block() { " All options failed - variant: exactly one of | | should be specified, got 0 - - variant: #[fork] expected 1 arguments, got: 0 + - variant: #[fork] expected arguments: 1, got: 0 - variant: #[fork] can be used with unnamed attributes only Resolve at least one of them " @@ -39,7 +39,7 @@ fn fails_without_url() { " All options failed - variant: argument is missing - - variant: #[fork] expected 1 arguments, got: 0 + - variant: #[fork] expected arguments: 1, got: 0 - variant: #[fork] can be used with unnamed attributes only Resolve at least one of them " @@ -56,12 +56,13 @@ fn fails_without_args() { assert_diagnostics( &result, - &[Diagnostic::error(formatdoc!( + &[Diagnostic::warn("#[fork] used with empty argument list. Either remove () or specify some arguments"), + Diagnostic::error(formatdoc!( " All options failed - variant: exactly one of | | should be specified, got 0 - - variant: #[fork] expected 1 arguments, got: 0 - - variant: #[fork] expected 1 arguments, got: 0 + - variant: #[fork] expected arguments: 1, got: 0 + - variant: #[fork] expected arguments: 1, got: 0 Resolve at least one of them " ))], @@ -81,7 +82,7 @@ fn fails_with_invalid_url() { " All options failed - variant: #[fork] is not a valid url - - variant: #[fork] expected 1 arguments, got: 0 + - variant: #[fork] expected arguments: 1, got: 0 - variant: #[fork] can be used with unnamed attributes only Resolve at least one of them " From d513efd8968ca7340db847c98bdcd3f0c5ce5188 Mon Sep 17 00:00:00 2001 From: Jagadeesh B Date: Mon, 2 Dec 2024 19:55:16 +0530 Subject: [PATCH 21/23] fix(docs): Correct contract name from "HelloStarknet" to "SimpleContract" (#2735) #2734 Closes # ## Introduced changes The documentation incorrectly refers to the "HelloStarknet" contract in the test example. Updated it to the correct contract name "SimpleContract" for clarity and accuracy. --- docs/src/testing/contracts.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/testing/contracts.md b/docs/src/testing/contracts.md index 5b3433cc8b..d47f0f2fb0 100644 --- a/docs/src/testing/contracts.md +++ b/docs/src/testing/contracts.md @@ -26,7 +26,7 @@ Note that the name after `mod` will be used as the contract name for testing pur ## Writing Tests -Let's write a test that will deploy the `HelloStarknet` contract and call some functions. +Let's write a test that will deploy the `SimpleContract` contract and call some functions. ```rust {{#include ../../listings/testing_smart_contracts_writing_tests/tests/simple_contract.cairo}} @@ -36,7 +36,7 @@ Let's write a test that will deploy the `HelloStarknet` contract and call some f > > Notice that the arguments to the contract's constructor (the `deploy`'s `calldata` argument) need to be serialized with `Serde`. > -> `HelloStarknet` contract has no constructor, so the calldata remains empty in the example above. +> `SimpleContract` contract has no constructor, so the calldata remains empty in the example above. ```shell $ snforge test From 771cf1d711fea9ca43ebf5a8a73e3248297aebd4 Mon Sep 17 00:00:00 2001 From: ddoktorski <45050160+ddoktorski@users.noreply.github.com> Date: Tue, 3 Dec 2024 15:56:15 +0100 Subject: [PATCH 22/23] Fix docs snippets test for Scarb >=2.8.1 (#2742) ## Introduced changes - Fix `e2e::docs_snippets_validation::test_docs_snippets` which failed in the [last scheduled run](https://github.com/foundry-rs/starknet-foundry/actions/runs/12100509808/job/33739201518) - Replace changeable values: gas and execution resources with wildcard `[..]` in outputs validation --------- Co-authored-by: Franciszek Job <54181625+franciszekjob@users.noreply.github.com> --- crates/docs/src/validation.rs | 18 +++++++++++++++--- crates/forge/tests/e2e/common/runner.rs | 6 ------ docs/listings/hello_workspaces/Scarb.toml | 3 +++ .../src/testing/gas-and-resource-estimation.md | 8 ++++---- docs/src/testing/running-tests.md | 8 ++++---- 5 files changed, 26 insertions(+), 17 deletions(-) diff --git a/crates/docs/src/validation.rs b/crates/docs/src/validation.rs index 70605570a6..bf141b0e41 100644 --- a/crates/docs/src/validation.rs +++ b/crates/docs/src/validation.rs @@ -1,6 +1,7 @@ -use std::{fs, io, path::Path}; - use crate::snippet::{Snippet, SnippetConfig, SnippetType}; +use regex::Regex; +use std::sync::LazyLock; +use std::{fs, io, path::Path}; const EXTENSION: Option<&str> = Some("md"); @@ -23,7 +24,18 @@ pub fn extract_snippets_from_file( .name("config") .map_or_else(String::new, |m| m.as_str().to_string()); let command_match = caps.name("command")?; - let output = caps.name("output").map(|m| m.as_str().to_string()); + let output = caps.name("output").map(|m| { + static GAS_RE: LazyLock = + LazyLock::new(|| Regex::new(r"gas: ~\d+").unwrap()); + static EXECUTION_RESOURCES_RE: LazyLock = LazyLock::new(|| { + Regex::new(r"(steps|memory holes|builtins|syscalls): (\d+|\(.+\))").unwrap() + }); + + let output = GAS_RE.replace_all(m.as_str(), "gas: ~[..]").to_string(); + EXECUTION_RESOURCES_RE + .replace_all(output.as_str(), "${1}: [..]") + .to_string() + }); let config = if config_str.is_empty() { SnippetConfig::default() diff --git a/crates/forge/tests/e2e/common/runner.rs b/crates/forge/tests/e2e/common/runner.rs index bc248916b1..72a76cd405 100644 --- a/crates/forge/tests/e2e/common/runner.rs +++ b/crates/forge/tests/e2e/common/runner.rs @@ -88,12 +88,6 @@ pub(crate) fn setup_package_with_file_patterns( value(get_assert_macros_version().unwrap().to_string()); scarb_toml["target.starknet-contract"]["sierra"] = value(true); - if is_from_docs_listings { - scarb_toml["dev-dependencies"]["snforge_std"] - .as_table_mut() - .and_then(|snforge_std| snforge_std.remove("workspace")); - } - manifest_path.write_str(&scarb_toml.to_string()).unwrap(); // TODO (#2074): do that on .cairo.template files only diff --git a/docs/listings/hello_workspaces/Scarb.toml b/docs/listings/hello_workspaces/Scarb.toml index 8e47bbc6f5..20fec0edce 100644 --- a/docs/listings/hello_workspaces/Scarb.toml +++ b/docs/listings/hello_workspaces/Scarb.toml @@ -27,6 +27,9 @@ fibonacci = { path = "crates/fibonacci" } addition = { path = "crates/addition" } starknet = "2.7.0" +[dev-dependencies] +snforge_std.workspace = true + [workspace.dependencies] snforge_std = { path = "../../../snforge_std" } diff --git a/docs/src/testing/gas-and-resource-estimation.md b/docs/src/testing/gas-and-resource-estimation.md index c91cb15782..af5a4d6111 100644 --- a/docs/src/testing/gas-and-resource-estimation.md +++ b/docs/src/testing/gas-and-resource-estimation.md @@ -49,14 +49,14 @@ Running 2 test(s) from tests/ [PASS] hello_starknet_integrationtest::test_contract::test_cannot_increase_balance_with_zero_value (gas: ~105) steps: 3405 memory holes: 22 - builtins: ([..]) - syscalls: ([..]) + builtins: (range_check: 77, pedersen: 7) + syscalls: (CallContract: 2, StorageRead: 1, Deploy: 1) [PASS] hello_starknet_integrationtest::test_contract::test_increase_balance (gas: ~172) steps: 4535 memory holes: 15 - builtins: ([..]) - syscalls: ([..]) + builtins: (range_check: 95, pedersen: 7) + syscalls: (CallContract: 3, StorageRead: 3, Deploy: 1, StorageWrite: 1) Running 0 test(s) from src/ Tests: 2 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out diff --git a/docs/src/testing/running-tests.md b/docs/src/testing/running-tests.md index 0138f8f88a..63f4aa7419 100644 --- a/docs/src/testing/running-tests.md +++ b/docs/src/testing/running-tests.md @@ -117,14 +117,14 @@ Running 2 test(s) from tests/ [PASS] hello_starknet_integrationtest::test_contract::test_cannot_increase_balance_with_zero_value (gas: ~105) steps: 3405 memory holes: 22 - builtins: ([..]) - syscalls: ([..]) + builtins: (range_check: 77, pedersen: 7) + syscalls: (CallContract: 2, StorageRead: 1, Deploy: 1) [PASS] hello_starknet_integrationtest::test_contract::test_increase_balance (gas: ~172) steps: 4535 memory holes: 15 - builtins: ([..]) - syscalls: ([..]) + builtins: (range_check: 95, pedersen: 7) + syscalls: (CallContract: 3, StorageRead: 3, Deploy: 1, StorageWrite: 1) Running 0 test(s) from src/ Tests: 2 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out From c5fa6235d4535125c457706a809d6996c036c7ed Mon Sep 17 00:00:00 2001 From: tserg <8017125+tserg@users.noreply.github.com> Date: Tue, 3 Dec 2024 23:47:22 +0800 Subject: [PATCH 23/23] docs: improve configuration.md (#2745) Minor improvement for docs. --- docs/src/projects/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/projects/configuration.md b/docs/src/projects/configuration.md index cf857d4840..51b6580bfe 100644 --- a/docs/src/projects/configuration.md +++ b/docs/src/projects/configuration.md @@ -175,4 +175,4 @@ url = "$NODE_URL" # ... ``` -Variable value are automatically resolved to numbers and booleans (strings `true`, `false`) if it is possible. +Variable values are automatically resolved to numbers and booleans (strings `true`, `false`) where possible.