Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/test-fixture/src/lib.rs')
| -rw-r--r-- | crates/test-fixture/src/lib.rs | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/crates/test-fixture/src/lib.rs b/crates/test-fixture/src/lib.rs index d81f27d7c3..ca68edd88c 100644 --- a/crates/test-fixture/src/lib.rs +++ b/crates/test-fixture/src/lib.rs @@ -37,7 +37,110 @@ use triomphe::Arc; pub const WORKSPACE: base_db::SourceRootId = base_db::SourceRootId(0); +/// A trait for setting up test databases from fixture strings. +/// +/// Fixtures are strings containing Rust source code with optional metadata that describe +/// a project setup. This is the primary way to write tests for rust-analyzer without +/// having to depend on the entire sysroot. +/// +/// # Fixture Syntax +/// +/// ## Basic Structure +/// +/// A fixture without metadata is parsed into a single source file (`/main.rs`). +/// Metadata is added after a `//-` comment prefix. +/// +/// ```text +/// //- /main.rs +/// fn main() { +/// println!("Hello"); +/// } +/// ``` +/// +/// Note that the fixture syntax is optional and can be omitted if the test only requires +/// a simple single file. +/// +/// ## File Metadata +/// +/// Each file can have the following metadata after `//-`: +/// +/// - **Path** (required): Must start with `/`, e.g., `/main.rs`, `/lib.rs`, `/foo/bar.rs` +/// - **`crate:<name>`**: Defines a new crate with this file as its root +/// - Optional version: `crate:[email protected],https://example.com/repo.git` +/// - **`deps:<crate1>,<crate2>`**: Dependencies (requires `crate:`) +/// - **`extern-prelude:<crate1>,<crate2>`**: Limits extern prelude to specified crates +/// - **`edition:<year>`**: Rust edition (2015, 2018, 2021, 2024). Defaults to current. +/// - **`cfg:<key>=<value>,<flag>`**: Configuration options, e.g., `cfg:test,feature="foo"` +/// - **`env:<KEY>=<value>`**: Environment variables +/// - **`crate-attr:<attr>`**: Crate-level attributes, e.g., `crate-attr:no_std` +/// - **`new_source_root:local|library`**: Starts a new source root +/// - **`library`**: Marks crate as external library (not workspace member) +/// +/// ## Global Meta (must appear at the top, in order) +/// +/// - **`//- toolchain: nightly|stable`**: Sets the Rust toolchain (default: stable) +/// - **`//- target_data_layout: <layout>`**: LLVM data layout string +/// - **`//- target_arch: <arch>`**: Target architecture (default: x86_64) +/// - **`//- proc_macros: <name1>,<name2>`**: Enables predefined test proc macros +/// - **`//- minicore: <flag1>, <flag2>`**: Includes subset of libcore +/// +/// ## Cursor Markers +/// +/// Use `$0` to mark cursor position(s) in the fixture: +/// - Single `$0`: marks a position (use with [`with_position`](Self::with_position)) +/// - Two `$0` markers: marks a range (use with [`with_range`](Self::with_range)) +/// - Escape as `\$0` if you need a literal `$0` +/// +/// # Examples +/// +/// ## Single file with cursor position +/// ```text +/// r#" +/// fn main() { +/// let x$0 = 42; +/// } +/// "# +/// ``` +/// +/// ## Multiple crates with dependencies +/// ```text +/// r#" +/// //- /main.rs crate:main deps:helper +/// use helper::greet; +/// fn main() { greet(); } +/// +/// //- /lib.rs crate:helper +/// pub fn greet() {} +/// "# +/// ``` +/// +/// ## Using minicore for lang items +/// ```text +/// r#" +/// //- minicore: option, result, iterator +/// //- /main.rs +/// fn foo() -> Option<i32> { Some(42) } +/// "# +/// ``` +/// +/// The available minicore flags are listed at the top of crates\test-utils\src\minicore.rs. +/// +/// ## Using test proc macros +/// ```text +/// r#" +/// //- proc_macros: identity, mirror +/// //- /main.rs crate:main deps:proc_macros +/// use proc_macros::identity; +/// +/// #[identity] +/// fn foo() {} +/// "# +/// ``` +/// +/// Available proc macros: `identity` (attr), `DeriveIdentity` (derive), `input_replace` (attr), +/// `mirror` (bang), `shorten` (bang) pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { + /// See the trait documentation for more information on fixtures. #[track_caller] fn with_single_file( #[rust_analyzer::rust_fixture] ra_fixture: &str, @@ -50,6 +153,7 @@ pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { (db, file) } + /// See the trait documentation for more information on fixtures. #[track_caller] fn with_many_files( #[rust_analyzer::rust_fixture] ra_fixture: &str, @@ -66,6 +170,7 @@ pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { (db, files) } + /// See the trait documentation for more information on fixtures. #[track_caller] fn with_files(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> Self { let mut db = Self::default(); @@ -75,6 +180,7 @@ pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { db } + /// See the trait documentation for more information on fixtures. #[track_caller] fn with_files_extra_proc_macros( #[rust_analyzer::rust_fixture] ra_fixture: &str, @@ -88,6 +194,7 @@ pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { db } + /// See the trait documentation for more information on fixtures. #[track_caller] fn with_position(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (Self, FilePosition) { let (db, file_id, range_or_offset) = Self::with_range_or_offset(ra_fixture); @@ -95,6 +202,7 @@ pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { (db, FilePosition { file_id, offset }) } + /// See the trait documentation for more information on fixtures. #[track_caller] fn with_range(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (Self, FileRange) { let (db, file_id, range_or_offset) = Self::with_range_or_offset(ra_fixture); @@ -102,6 +210,7 @@ pub trait WithFixture: Default + ExpandDatabase + SourceDatabase + 'static { (db, FileRange { file_id, range }) } + /// See the trait documentation for more information on fixtures. #[track_caller] fn with_range_or_offset( #[rust_analyzer::rust_fixture] ra_fixture: &str, |