From 9502e71af04b684b50b70e4e687c9921f6ebe99e Mon Sep 17 00:00:00 2001 From: Arpad Borsos Date: Fri, 2 Jun 2023 10:26:29 +0200 Subject: [PATCH] Enable `doctest-in-workspace` by default This stabilizes and enables the `-Z doctest-in-workspace` flag by default. Also adds another testcase to make sure that the `include!()` and `file!()` macros interact well together. --- src/cargo/core/features.rs | 6 +- src/cargo/ops/cargo_test.rs | 11 +--- src/doc/man/cargo-test.md | 7 +++ src/doc/src/reference/unstable.md | 21 ++++++- tests/testsuite/doc.rs | 101 ++++++++++++++++++++++++++++-- 5 files changed, 131 insertions(+), 15 deletions(-) diff --git a/src/cargo/core/features.rs b/src/cargo/core/features.rs index 524a01725daa..c7bf8e12da9d 100644 --- a/src/cargo/core/features.rs +++ b/src/cargo/core/features.rs @@ -730,7 +730,6 @@ unstable_cli_options!( config_include: bool = ("Enable the `include` key in config files"), credential_process: bool = ("Add a config setting to fetch registry authentication tokens by calling an external process"), direct_minimal_versions: bool = ("Resolve minimal dependency versions instead of maximum (direct dependencies only)"), - doctest_in_workspace: bool = ("Compile doctests with paths relative to the workspace root"), doctest_xcompile: bool = ("Compile and run doctests for non-host target using runner config"), dual_proc_macros: bool = ("Build proc-macros for both the host and the target"), features: Option> = (HIDDEN), @@ -800,6 +799,9 @@ const STABILIZED_NAMED_PROFILES: &str = "The named-profiles feature is now alway See https://doc.rust-lang.org/nightly/cargo/reference/profiles.html#custom-profiles \ for more information"; +const STABILIZED_DOCTEST_IN_WORKSPACE: &str = + "The doctest-in-workspace feature is now always enabled."; + const STABILIZED_FUTURE_INCOMPAT_REPORT: &str = "The future-incompat-report feature is now always enabled."; @@ -1080,6 +1082,7 @@ impl CliUnstable { "multitarget" => stabilized_warn(k, "1.64", STABILISED_MULTITARGET), "sparse-registry" => stabilized_warn(k, "1.68", STABILISED_SPARSE_REGISTRY), "terminal-width" => stabilized_warn(k, "1.68", STABILIZED_TERMINAL_WIDTH), + "doctest-in-workspace" => stabilized_warn(k, "1.72", STABILIZED_DOCTEST_IN_WORKSPACE), // Unstable features // Sorted alphabetically: @@ -1098,7 +1101,6 @@ impl CliUnstable { "config-include" => self.config_include = parse_empty(k, v)?, "credential-process" => self.credential_process = parse_empty(k, v)?, "direct-minimal-versions" => self.direct_minimal_versions = parse_empty(k, v)?, - "doctest-in-workspace" => self.doctest_in_workspace = parse_empty(k, v)?, "doctest-xcompile" => self.doctest_xcompile = parse_empty(k, v)?, "dual-proc-macros" => self.dual_proc_macros = parse_empty(k, v)?, "gitoxide" => { diff --git a/src/cargo/ops/cargo_test.rs b/src/cargo/ops/cargo_test.rs index 4a86349ae9a0..1ddf7755fc57 100644 --- a/src/cargo/ops/cargo_test.rs +++ b/src/cargo/ops/cargo_test.rs @@ -172,7 +172,6 @@ fn run_doc_tests( let config = ws.config(); let mut errors = Vec::new(); let doctest_xcompile = config.cli_unstable().doctest_xcompile; - let doctest_in_workspace = config.cli_unstable().doctest_in_workspace; for doctest_info in &compilation.to_doc_test { let Doctest { @@ -215,13 +214,9 @@ fn run_doc_tests( p.arg("--crate-name").arg(&unit.target.crate_name()); p.arg("--test"); - if doctest_in_workspace { - add_path_args(ws, unit, &mut p); - p.arg("--test-run-directory") - .arg(unit.pkg.root().to_path_buf()); - } else { - p.arg(unit.target.src_path().path().unwrap()); - } + add_path_args(ws, unit, &mut p); + p.arg("--test-run-directory") + .arg(unit.pkg.root().to_path_buf()); if let CompileKind::Target(target) = unit.kind { // use `rustc_target()` to properly handle JSON target paths diff --git a/src/doc/man/cargo-test.md b/src/doc/man/cargo-test.md index 49792d6bec22..39796d3ef228 100644 --- a/src/doc/man/cargo-test.md +++ b/src/doc/man/cargo-test.md @@ -65,6 +65,13 @@ Setting the working directory of tests to the package's root directory makes it possible for tests to reliably access the package's files using relative paths, regardless from where `cargo test` was executed from. +For documentation tests, the working directory when invoking `rustdoc` is set to +the workspace root directory, and is also the directory `rustdoc` uses as the +compilation directory of each documentation test. +The corking directory when running each documentation test is set to the root +directory of the package the test belongs to, and is controlled via `rustdoc`s +`--test-run-directory` option. + ## OPTIONS ### Test Options diff --git a/src/doc/src/reference/unstable.md b/src/doc/src/reference/unstable.md index 50dfdd082b82..3d03c4bff89e 100644 --- a/src/doc/src/reference/unstable.md +++ b/src/doc/src/reference/unstable.md @@ -85,7 +85,6 @@ Each new feature described below should explain how to use it. * [host-config](#host-config) --- Allows setting `[target]`-like configuration settings for host build targets. * [target-applies-to-host](#target-applies-to-host) --- Alters whether certain flags will be passed to host build targets. * rustdoc - * [`doctest-in-workspace`](#doctest-in-workspace) --- Fixes workspace-relative paths when running doctests. * [rustdoc-map](#rustdoc-map) --- Provides mappings for documentation to link to external sites like [docs.rs](https://docs.rs/). * [scrape-examples](#scrape-examples) --- Shows examples within documentation. * `Cargo.toml` extensions @@ -1793,3 +1792,23 @@ See [Registry Protocols](registries.md#registry-protocols) for more information. The [`cargo logout`] command has been stabilized in the 1.70 release. [target triple]: ../appendix/glossary.md#target '"target" (glossary)' + + +### `doctest-in-workspace` + +The `-Z doctest-in-workspace` option for `cargo test` has been stabilized and +enabled by default in the 1.72 release. + +This changes the behavior of the current working +directory used when running doctests. Historically, Cargo has run `rustdoc +--test` relative to the root of the package, with paths relative from that +root. However, this is inconsistent with how `rustc` and `rustdoc` are +normally run in a workspace, where they are run relative to the workspace +root. This inconsistency causes problems in various ways, such as when passing +RUSTDOCFLAGS with relative paths, or dealing with diagnostic output. + +Cargo is now running `rustdoc` +from the root of the workspace. It also passes the `--test-run-directory` to +`rustdoc` so that when *running* the tests, they are run from the root of the +package. This preserves backwards compatibility and is consistent with how +normal unittests are run. diff --git a/tests/testsuite/doc.rs b/tests/testsuite/doc.rs index 739bcf3765ca..3bb617994397 100644 --- a/tests/testsuite/doc.rs +++ b/tests/testsuite/doc.rs @@ -2041,7 +2041,7 @@ fn crate_versions_flag_is_overridden() { asserts(output_documentation()); } -#[cargo_test(nightly, reason = "-Zdoctest-in-workspace is unstable")] +#[cargo_test] fn doc_test_in_workspace() { let p = project() .file( @@ -2087,8 +2087,7 @@ fn doc_test_in_workspace() { ", ) .build(); - p.cargo("test -Zdoctest-in-workspace --doc -vv") - .masquerade_as_nightly_cargo(&["doctest-in-workspace"]) + p.cargo("test --doc -vv") .with_stderr_contains("[DOCTEST] crate-a") .with_stdout_contains( " @@ -2096,7 +2095,6 @@ running 1 test test crate-a/src/lib.rs - (line 1) ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out[..] - ", ) .with_stderr_contains("[DOCTEST] crate-b") @@ -2106,7 +2104,102 @@ running 1 test test crate-b/src/lib.rs - (line 1) ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out[..] +", + ) + .run(); +} + +/// This is a test for . +/// The `file!()` macro inside of an `include!()` should output +/// workspace-relative paths, just like it does in other cases. +#[cargo_test] +fn doc_test_include_file() { + let p = project() + .file( + "Cargo.toml", + r#" + [workspace] + members = [ + "child", + ] + [package] + name = "root" + version = "0.1.0" + "#, + ) + .file( + "src/lib.rs", + r#" + /// ``` + /// assert_eq!("src/lib.rs", file!().replace("\\", "/")) + /// ``` + pub mod included { + include!(concat!("../", file!(), ".included.rs")); + } + "#, + ) + .file( + "src/lib.rs.included.rs", + r#" + /// ``` + /// assert_eq!(1, 1) + /// ``` + pub fn foo() {} + "#, + ) + .file( + "child/Cargo.toml", + r#" + [package] + name = "child" + version = "0.1.0" + "#, + ) + .file( + "child/src/lib.rs", + r#" + /// ``` + /// assert_eq!("child/src/lib.rs", file!().replace("\\", "/")) + /// ``` + pub mod included { + include!(concat!("../../", file!(), ".included.rs")); + } + "#, + ) + .file( + "child/src/lib.rs.included.rs", + r#" + /// ``` + /// assert_eq!(1, 1) + /// ``` + pub fn foo() {} + "#, + ) + .build(); + + p.cargo("test -p child --doc -vv -- --test-threads=1") + //.env("RUSTDOCFLAGS", "--test-args=--threads=1") + .with_stderr_contains("[DOCTEST] child") + .with_stdout_contains( + " +running 2 tests +test child/src/../../child/src/lib.rs.included.rs - included::foo (line 2) ... ok +test child/src/lib.rs - included (line 2) ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out[..] +", + ) + .run(); + + p.cargo("test -p root --doc -vv -- --test-threads=1") + .with_stderr_contains("[DOCTEST] root") + .with_stdout_contains( + " +running 2 tests +test src/../src/lib.rs.included.rs - included::foo (line 2) ... ok +test src/lib.rs - included (line 2) ... ok +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out[..] ", ) .run();