Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(test): Expand documentation of cargo-test-support #14272

Merged
merged 28 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
742defb
docs(contrib): Update functional/ui comparison
epage Jul 15, 2024
ba94d70
docs(contrib): Update functional example
epage Jul 15, 2024
f05eba0
docs(test): Migrate cargo_test docs from contrib to API reference
epage Jul 12, 2024
83d1c14
docs(test): Point to docs, rather than source
epage Jul 22, 2024
8e524ae
docs(test): Link to two different docs builds
epage Jul 15, 2024
ad6abb5
docs(test): Verify they work
epage Jul 15, 2024
ca9fc47
docs(test): Add high level example
epage Jul 15, 2024
86945a2
docs(test): Document t!
epage Jul 15, 2024
504d377
docs(test): Document cargo_process
epage Jul 15, 2024
fa0e66e
docs(test): Document git_process
epage Jul 15, 2024
7762d1f
docs(test): Document cargo_exe
epage Jul 15, 2024
f42ae4c
docs(test): Pull RawOutput from API
epage Jul 15, 2024
4674f2b
docs(test): Organize docs for Execs
epage Jul 15, 2024
1fe8ae6
docs(test): Document Execs
epage Jul 16, 2024
b4b56d4
docs(test): Document basic_*manifest functions
epage Jul 18, 2024
1707566
docs(test): Document 'process'
epage Jul 18, 2024
c9dddd2
docs(test): Document main_file function
epage Jul 18, 2024
e53f2af
docs(test): Document panic_error function
epage Jul 18, 2024
3dff0ec
docs(test): Document project* functions
epage Jul 18, 2024
45f61cc
docs(test): Expand docs for Project
epage Jul 19, 2024
cb52840
docs(test): Expand docs for ProjectBuilder
epage Jul 19, 2024
8f88a8a
docs(test): Expand 'compare' documentation
epage Jul 19, 2024
97ccb65
docs(test): Expose `git` documentation
epage Jul 19, 2024
64a62ff
docs(test): Expand 'git' documentation
epage Jul 19, 2024
062652c
docs(test): Expand 'install' documentation
epage Jul 19, 2024
6d0eea0
refactor(test): Document 'paths' mod
epage Jul 19, 2024
b931d98
refactor(test): Document 'publish' mod
epage Jul 19, 2024
83cbca0
refactor(test): Document 'registry' mod
epage Jul 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions crates/cargo-test-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,49 @@ use std::path::Path;
use std::process::Command;
use std::sync::Once;

/// Replacement for `#[test]`
///
/// The `#[cargo_test]` attribute extends `#[test]` with some setup before starting the test.
/// It will create a filesystem "sandbox" under the "cargo integration test" directory for each test, such as `/path/to/cargo/target/tmp/cit/t123/`.
/// The sandbox will contain a `home` directory that will be used instead of your normal home directory.
///
/// The `#[cargo_test]` attribute takes several options that will affect how the test is generated.
/// They are listed in parentheses separated with commas, such as:
///
/// ```rust,ignore
/// #[cargo_test(nightly, reason = "-Zfoo is unstable")]
/// ```
///
/// The options it supports are:
///
/// * `>=1.64` --- This indicates that the test will only run with the given version of `rustc` or newer.
/// This can be used when a new `rustc` feature has been stabilized that the test depends on.
/// If this is specified, a `reason` is required to explain why it is being checked.
/// * `nightly` --- This will cause the test to be ignored if not running on the nightly toolchain.
/// This is useful for tests that use unstable options in `rustc` or `rustdoc`.
/// These tests are run in Cargo's CI, but are disabled in rust-lang/rust's CI due to the difficulty of updating both repos simultaneously.
/// A `reason` field is required to explain why it is nightly-only.
/// * `requires_<cmd>` --- This indicates a command that is required to be installed to be run.
/// For example, `requires_rustfmt` means the test will only run if the executable `rustfmt` is installed.
/// These tests are *always* run on CI.
/// This is mainly used to avoid requiring contributors from having every dependency installed.
/// * `build_std_real` --- This is a "real" `-Zbuild-std` test (in the `build_std` integration test).
/// This only runs on nightly, and only if the environment variable `CARGO_RUN_BUILD_STD_TESTS` is set (these tests on run on Linux).
/// * `build_std_mock` --- This is a "mock" `-Zbuild-std` test (which uses a mock standard library).
/// This only runs on nightly, and is disabled for windows-gnu.
/// * `public_network_test` --- This tests contacts the public internet.
/// These tests are disabled unless the `CARGO_PUBLIC_NETWORK_TESTS` environment variable is set.
/// Use of this should be *extremely rare*, please avoid using it if possible.
/// The hosts it contacts should have a relatively high confidence that they are reliable and stable (such as github.com), especially in CI.
/// The tests should be carefully considered for developer security and privacy as well.
/// * `container_test` --- This indicates that it is a test that uses Docker.
/// These tests are disabled unless the `CARGO_CONTAINER_TESTS` environment variable is set.
/// This requires that you have Docker installed.
/// The SSH tests also assume that you have OpenSSH installed.
/// These should work on Linux, macOS, and Windows where possible.
/// Unfortunately these tests are not run in CI for macOS or Windows (no Docker on macOS, and Windows does not support Linux images).
/// See [`cargo-test-support::containers`](https://doc.rust-lang.org/nightly/nightly-rustc/cargo_test_support/containers) for more on writing these tests.
/// * `ignore_windows="reason"` --- Indicates that the test should be ignored on windows for the given reason.
#[proc_macro_attribute]
pub fn cargo_test(attr: TokenStream, item: TokenStream) -> TokenStream {
// Ideally these options would be embedded in the test itself. However, I
Expand Down
3 changes: 0 additions & 3 deletions crates/cargo-test-support/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ homepage.workspace = true
repository.workspace = true
description = "Testing framework for Cargo's testsuite."

[lib]
doctest = false

[dependencies]
anstream.workspace = true
anstyle.workspace = true
Expand Down
34 changes: 32 additions & 2 deletions crates/cargo-test-support/src/compare.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
//! Routines for comparing and diffing output.
//!
//! # Patterns
//! # Deprecated comparisons
//!
//! Cargo's tests are in transition from internal-only pattern and normalization routines used in
//! asserts like [`crate::Execs::with_stdout`] to [`assert_e2e`] and [`assert_ui`].
//!
//! ## Patterns
//!
//! Many of these functions support special markup to assist with comparing
//! text that may vary or is otherwise uninteresting for the test at hand. The
Expand All @@ -22,7 +27,7 @@
//! can use this to avoid duplicating the `with_stderr` call like:
//! `if cfg!(target_env = "msvc") {e.with_stderr("...[DIRTY]...");} else {e.with_stderr("...");}`.
//!
//! # Normalization
//! ## Normalization
//!
//! In addition to the patterns described above, the strings are normalized
//! in such a way to avoid unwanted differences. The normalizations are:
Expand Down Expand Up @@ -86,6 +91,19 @@ macro_rules! regex {
/// Other heuristics are applied to try to ensure Windows-style paths aren't
/// a problem.
/// - Carriage returns are removed, which can help when running on Windows.
///
/// # Example
///
/// ```no_run
/// # use cargo_test_support::compare::assert_e2e;
/// # use cargo_test_support::file;
/// # let p = cargo_test_support::project().build();
/// # let stdout = "";
/// assert_e2e().eq(stdout, file!["stderr.term.svg"]);
/// ```
/// ```console
/// $ SNAPSHOTS=overwrite cargo test
/// ```
pub fn assert_ui() -> snapbox::Assert {
let mut subs = snapbox::Redactions::new();
subs.extend(MIN_LITERAL_REDACTIONS.into_iter().cloned())
Expand Down Expand Up @@ -129,6 +147,18 @@ pub fn assert_ui() -> snapbox::Assert {
/// Other heuristics are applied to try to ensure Windows-style paths aren't
/// a problem.
/// - Carriage returns are removed, which can help when running on Windows.
///
/// # Example
///
/// ```no_run
/// # use cargo_test_support::compare::assert_e2e;
/// # use cargo_test_support::str;
/// # let p = cargo_test_support::project().build();
/// assert_e2e().eq(p.read_lockfile(), str![]);
/// ```
/// ```console
/// $ SNAPSHOTS=overwrite cargo test
/// ```
pub fn assert_e2e() -> snapbox::Assert {
let mut subs = snapbox::Redactions::new();
subs.extend(MIN_LITERAL_REDACTIONS.into_iter().cloned())
Expand Down
103 changes: 54 additions & 49 deletions crates/cargo-test-support/src/git.rs
Original file line number Diff line number Diff line change
@@ -1,60 +1,66 @@
/*
# Git Testing Support

## Creating a git dependency
`git::new()` is an easy way to create a new git repository containing a
project that you can then use as a dependency. It will automatically add all
the files you specify in the project and commit them to the repository.
Example:

```
let git_project = git::new("dep1", |project| {
project
.file("Cargo.toml", &basic_manifest("dep1", "1.0.0"))
.file("src/lib.rs", r#"pub fn f() { println!("hi!"); } "#)
});

// Use the `url()` method to get the file url to the new repository.
let p = project()
.file("Cargo.toml", &format!(r#"
[package]
name = "a"
version = "1.0.0"

[dependencies]
dep1 = {{ git = '{}' }}
"#, git_project.url()))
.file("src/lib.rs", "extern crate dep1;")
.build();
```

## Manually creating repositories
`git::repo()` can be used to create a `RepoBuilder` which provides a way of
adding files to a blank repository and committing them.

If you want to then manipulate the repository (such as adding new files or
tags), you can use `git2::Repository::open()` to open the repository and then
use some of the helper functions in this file to interact with the repository.

*/
//! # Git Testing Support
//!
//! ## Creating a git dependency
//! [`new()`] is an easy way to create a new git repository containing a
//! project that you can then use as a dependency. It will automatically add all
//! the files you specify in the project and commit them to the repository.
//!
//! ### Example:
//!
//! ```no_run
//! # use cargo_test_support::project;
//! # use cargo_test_support::basic_manifest;
//! # use cargo_test_support::git;
//! let git_project = git::new("dep1", |project| {
//! project
//! .file("Cargo.toml", &basic_manifest("dep1", "1.0.0"))
//! .file("src/lib.rs", r#"pub fn f() { println!("hi!"); } "#)
//! });
//!
//! // Use the `url()` method to get the file url to the new repository.
//! let p = project()
//! .file("Cargo.toml", &format!(r#"
//! [package]
//! name = "a"
//! version = "1.0.0"
//!
//! [dependencies]
//! dep1 = {{ git = '{}' }}
//! "#, git_project.url()))
//! .file("src/lib.rs", "extern crate dep1;")
//! .build();
//! ```
//!
//! ## Manually creating repositories
//!
//! [`repo()`] can be used to create a [`RepoBuilder`] which provides a way of
//! adding files to a blank repository and committing them.
//!
//! If you want to then manipulate the repository (such as adding new files or
//! tags), you can use `git2::Repository::open()` to open the repository and then
//! use some of the helper functions in this file to interact with the repository.

use crate::{paths::CargoPathExt, project, Project, ProjectBuilder, SymlinkBuilder};
use std::fs;
use std::path::{Path, PathBuf};
use std::sync::Once;
use url::Url;

/// Manually construct a [`Repository`]
///
/// See also [`new`], [`repo`]
#[must_use]
pub struct RepoBuilder {
repo: git2::Repository,
files: Vec<PathBuf>,
}

/// See [`new`]
pub struct Repository(git2::Repository);

/// Create a `RepoBuilder` to build a new git repository.
/// Create a [`RepoBuilder`] to build a new git repository.
///
/// Call `build()` to finalize and create the repository.
/// Call [`RepoBuilder::build()`] to finalize and create the repository.
pub fn repo(p: &Path) -> RepoBuilder {
RepoBuilder::init(p)
}
Expand Down Expand Up @@ -130,7 +136,7 @@ impl Repository {
}
}

/// Initialize a new repository at the given path.
/// *(`git2`)* Initialize a new repository at the given path.
pub fn init(path: &Path) -> git2::Repository {
default_search_path();
let repo = t!(git2::Repository::init(path));
Expand Down Expand Up @@ -158,16 +164,15 @@ fn default_repo_cfg(repo: &git2::Repository) {
t!(cfg.set_str("user.name", "Foo Bar"));
}

/// Create a new git repository with a project.
/// Create a new [`Project`] in a git [`Repository`]
pub fn new<F>(name: &str, callback: F) -> Project
where
F: FnOnce(ProjectBuilder) -> ProjectBuilder,
{
new_repo(name, callback).0
}

/// Create a new git repository with a project.
/// Returns both the Project and the git Repository.
/// Create a new [`Project`] with access to the [`Repository`]
pub fn new_repo<F>(name: &str, callback: F) -> (Project, git2::Repository)
where
F: FnOnce(ProjectBuilder) -> ProjectBuilder,
Expand All @@ -182,14 +187,14 @@ where
(git_project, repo)
}

/// Add all files in the working directory to the git index.
/// *(`git2`)* Add all files in the working directory to the git index
pub fn add(repo: &git2::Repository) {
let mut index = t!(repo.index());
t!(index.add_all(["*"].iter(), git2::IndexAddOption::DEFAULT, None));
t!(index.write());
}

/// Add a git submodule to the repository.
/// *(`git2`)* Add a git submodule to the repository
pub fn add_submodule<'a>(
repo: &'a git2::Repository,
url: &str,
Expand All @@ -207,7 +212,7 @@ pub fn add_submodule<'a>(
s
}

/// Commit changes to the git repository.
/// *(`git2`)* Commit changes to the git repository
pub fn commit(repo: &git2::Repository) -> git2::Oid {
let tree_id = t!(t!(repo.index()).write_tree());
let sig = t!(repo.signature());
Expand All @@ -226,7 +231,7 @@ pub fn commit(repo: &git2::Repository) -> git2::Oid {
))
}

/// Create a new tag in the git repository.
/// *(`git2`)* Create a new tag in the git repository
pub fn tag(repo: &git2::Repository, name: &str) {
let head = repo.head().unwrap().target().unwrap();
t!(repo.tag(
Expand Down
3 changes: 3 additions & 0 deletions crates/cargo-test-support/src/install.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Helpers for testing `cargo install`

use std::env::consts::EXE_SUFFIX;
use std::path::Path;

Expand All @@ -23,6 +25,7 @@ fn check_has_installed_exe<P: AsRef<Path>>(path: P, name: &'static str) -> bool
path.as_ref().join("bin").join(exe(name)).is_file()
}

/// `$name$EXE`
pub fn exe(name: &str) -> String {
format!("{}{}", name, EXE_SUFFIX)
}
Loading
Loading