mdBook icon indicating copy to clipboard operation
mdBook copied to clipboard

`mdbook test` extern crate functionality

Open frankmcsherry opened this issue 6 years ago • 16 comments

I apologize if this isn't an "issue" per se, but I've not had much luck finding answers.

Is mdbook test intended to work for books containing references to crates (e.g. extern crate my_crate;)? I've tried the -L argument, which .. I couldn't get to do anything when pointed at the associated crate root.

I saw some language in other issues that perhaps test is mostly targeting the Rust book, and if that means no it isn't meant to work for other projects, that would be great to know. And, if I'm just doing it wrong and it should work, even better. :D

frankmcsherry avatar Aug 06 '17 19:08 frankmcsherry

I think the feature you are looking for has been merged in https://github.com/azerupi/mdBook/pull/340 but not yet released. Is that what you tested?

mdbook test is quite rudimentary at the moment. It was mostly added for the Rust book but I would like to see it grow to be more useful in general.

azerupi avatar Aug 06 '17 19:08 azerupi

I have tried this. I cloned the repo, and then from the root of the book directory did

~/Projects/mdbook/target/debug/mdbook test -L PATH_TO_CRATE_ROOT

which came back with

[*]: Testing file: "/Users/mcsherry/Projects/timely-dataflow/mdbook/src/./chapter_1.md"
[*]: Testing file: "/Users/mcsherry/Projects/timely-dataflow/mdbook/src/./chapter_1_1.md"
An error occured:
Rustdoc returned an error: 
running 1 test
test /Users/mcsherry/Projects/timely-dataflow/mdbook/src/./chapter_1_1.md - Dataflow_Programming (line 11) ... FAILED

failures:

---- /Users/mcsherry/Projects/timely-dataflow/mdbook/src/./chapter_1_1.md - Dataflow_Programming (line 11) stdout ----
    error[E0463]: can't find crate for `timely`
 --> <anon>:1:1
  |
1 | extern crate timely;
  | ^^^^^^^^^^^^^^^^^^^^ can't find crate

error: aborting due to previous error

It's totally possible I'm not understanding what -L expects; the only thing I could think of was a local crate root. If you have other tips (or perhaps, I should flip through the source to see what it does), they would be appreciated. :)

It would be great from my point of view if mdbook test worked for external crates. I was hoping to use it to write up documentation about a framework I'm building, but I don't see how to do that if I can't use the crate that I'm writing about.

frankmcsherry avatar Aug 06 '17 19:08 frankmcsherry

~As far as I know our current support for -L is not enough to test with extern crate. Looking at rustdoc documentation I think that we might also have to pass the --extern parameter to rustdoc in mdbook test (I'm prepared to by corrected here ;) ).~ Anyhow as @azerupi mentioned it is not yet released anyhow.

@frankmcsherry At the moment I would suggest using skeptic which is designed just for that purpose (testing with multiple extern crates). It is used to great success in rust-cookbook (another project using mdbook). If you have any question regarding the the integration I'll gladly help.

~In the mean time we'll look into this issue (mdbook test should also work with extern crates).~


edit:

And I'm corrected ;) rustdoc --test ./info.md -L ./target/debug/deps is enough so mdbook test -L ./target/debug/deps will work just as well. Sorry to misinform :disappointed: (on my defense skeptic integrates well with cargo test)

budziq avatar Aug 06 '17 19:08 budziq

Ah, thank you! This is helpful info, and skeptic looks like like it fits the bill for keeping examples correct. :D

Happy to close this as "understood", or leave it open if it is a longer-term goal to have the functionality. As you like.

frankmcsherry avatar Aug 06 '17 19:08 frankmcsherry

I'll close this as mdbook test -L ./target/debug/deps

works ok. We'll just need to update the docs

budziq avatar Aug 06 '17 20:08 budziq

I couldn't get either cases to work -L path to local crate, or -L ./target/debug/deps

is there some secret I'm not getting

andrewdavidmackenzie avatar Sep 14 '19 23:09 andrewdavidmackenzie

@andrewdavidmackenzie I am also struggling to get this work. Did you find a solution?

elmarco avatar Jun 21 '20 16:06 elmarco

No, I have forgotten what changed - but I think in recent versions of my book I was somehow (magically) able to just remove those extern crate statements and it all works. Sorry I can't help more.

andrewdavidmackenzie avatar Jul 09 '20 09:07 andrewdavidmackenzie

I wasn't able to get this to work either :( Should this issue be re-opened?

alice-i-cecile avatar Sep 26 '21 23:09 alice-i-cecile

To answer previous questions - no, I didn't find a solution to this, but haven't tried recently.

andrewdavidmackenzie avatar Sep 27 '21 08:09 andrewdavidmackenzie

Hi all,

I too was struggling with this today. I can almost get it to work, here are the steps I took. I wanted to test an example using Tokio. So to create the magic target/debug/deps/ directory, I created a Cargo.toml with

[dependencies]
tokio = { version = "1.21.1", features = ["full"] }

I created an examples/async.rs file with my code:

extern crate tokio;
use std::time::Duration;

async fn sleep_then_print(timer: i32) {
    println!("Start timer {}.", timer);
    tokio::time::sleep(Duration::from_millis(200)).await;
    println!("Timer {} done.", timer);
}

#[tokio::main]
async fn main() {
    println!("Creating futures");
    let f1 = sleep_then_print(1);
    let f2 = sleep_then_print(2);
    let f3 = sleep_then_print(3);

    println!("Joining futures");
    tokio::join!(f1, f2, f3);
}

I ran the example once with cargo run --example async. This creates some Tokio files in target/debug/deps/:

% ls target/debug/deps/libtokio*
target/debug/deps/libtokio-53487e49f22932e2.rlib
target/debug/deps/libtokio_macros-6700705ed016b494.so
target/debug/deps/libtokio-53487e49f22932e2.rmeta

With this setup, I can now include the Rust file in an async/example.md file:

# Example

```rust,edition2021
{{#include ../../examples/async.rs}}
```

Finally, I can run mdbook test:

% mdbook test -c 'Example' -L target/debug/deps
2022-09-23 16:54:30 [INFO] (mdbook::book): Testing chapter 'Example': "async/example.md"

Some things to note:

  • It does not work if I leave out the extern tokio; line — despite using the 2021 edition.

Worse, when the example changes, the workflow breaks. Something generates an additional crate file in the deps/ directory and I see:

 mdbook test -c 'Example' -L target/debug/deps
2022-09-23 16:57:55 [INFO] (mdbook::book): Testing chapter 'Example': "async/example.md"
2022-09-23 16:57:55 [ERROR] (mdbook::book): rustdoc returned an error:

--- stdout

running 1 test
test /tmp/mdbook-fUXdOO/async/example.md - Example (line 3) ... FAILED

failures:

---- /tmp/mdbook-fUXdOO/async/example.md - Example (line 3) stdout ----
error[E0464]: multiple matching crates for `tokio`
 --> /tmp/mdbook-fUXdOO/async/example.md:4:1
  |
2 | extern crate tokio;
  | ^^^^^^^^^^^^^^^^^^^
  |
  = note: candidates:
          crate `tokio`: .../target/debug/deps/libtokio-38e8b4ca412fced7.rmeta
          crate `tokio`: .../target/debug/deps/libtokio-53487e49f22932e2.rlib
          .../target/debug/deps/libtokio-53487e49f22932e2.rmeta

I do see the extra file in my target/debug/deps/ directory:

% ls target/debug/deps/libtokio*
target/debug/deps/libtokio-38e8b4ca412fced7.rmeta
target/debug/deps/libtokio-53487e49f22932e2.rmeta
target/debug/deps/libtokio-53487e49f22932e2.rlib
target/debug/deps/libtokio_macros-6700705ed016b494.so

I have rust-analyzer hooked up to my editor, so perhaps it's the process which generates an extra file there.

Have anybody found a more stable way to use this flag? The above seems like it could be made to work in a CI pipeline, but for daily editing of the files it's very brittle.

mgeisler avatar Sep 23 '22 15:09 mgeisler

@messense, you added the --library-path flag in #340 to address #339. Can you tell us more about how you use it?

mgeisler avatar Sep 23 '22 15:09 mgeisler

Reöpening this

Dylan-DPC avatar Sep 23 '22 15:09 Dylan-DPC

Using -L requires extern crate and is a rather crude system that won't handle multiple crates with the same name.

#706 is open to add more first-class support of external crates, I don't think this needs to be reopened.

For now, if you need external crates, I might suggest not using mdbook test, but instead just including source snippets from a real Cargo project. For example The Rust Book keeps all projects in this directory. You can then run your own tests against the projects in any way that you want. I realize that is more complicated and cumbersome.

ehuss avatar Sep 23 '22 15:09 ehuss

Thanks @ehuss, I have indeed used separate Rust files for some of my larger code snippets. I've found mdbook test super valuable: it tests what I actually show in the documentation, so it gives me a ton of safety. I've often included parts of files and this is where mdbook test shines since it let's me test both the snippets as well as the full code.

I'll subscribe to #706 and see how we can improve this.

mgeisler avatar Sep 28 '22 14:09 mgeisler

@ehuss @mgeisler -- posting here since I already posted in #706, I've now got an MVP of a crate that solves this issue. Would really appreciate feedback -- if it's useful enough, it might be something worth integrating back into mdbook.

tfpk avatar Oct 09 '22 09:10 tfpk