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

mdbook test extern crate functionality #394

Open
frankmcsherry opened this issue Aug 6, 2017 · 17 comments
Open

mdbook test extern crate functionality #394

frankmcsherry opened this issue Aug 6, 2017 · 17 comments

Comments

@frankmcsherry
Copy link

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

@azerupi
Copy link
Contributor

azerupi commented Aug 6, 2017

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.

@frankmcsherry
Copy link
Author

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.

@budziq
Copy link
Contributor

budziq commented Aug 6, 2017

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 😞 (on my defense skeptic integrates well with cargo test)

@frankmcsherry
Copy link
Author

frankmcsherry commented Aug 6, 2017

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.

@budziq
Copy link
Contributor

budziq commented Aug 6, 2017

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

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

@budziq budziq closed this as completed Aug 6, 2017
@andrewdavidmackenzie
Copy link
Contributor

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

@elmarco
Copy link

elmarco commented Jun 21, 2020

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

@andrewdavidmackenzie
Copy link
Contributor

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.

@alice-i-cecile
Copy link

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

@andrewdavidmackenzie
Copy link
Contributor

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

@mgeisler
Copy link
Contributor

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
Copy link
Contributor

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

@Dylan-DPC
Copy link
Member

Reöpening this

@Dylan-DPC Dylan-DPC reopened this Sep 23, 2022
@ehuss
Copy link
Contributor

ehuss commented Sep 23, 2022

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.

@mgeisler
Copy link
Contributor

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.

@tfpk
Copy link

tfpk commented Oct 9, 2022

@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.

@chriskrycho
Copy link

One note on @ehuss’s suggestion of making this work by using full-on crates: that does indeed work, and you must still use extern crate regardless of what the crate’s edition specifies, at least as of right now, and you may also still have to pass -L/--library-path for the dependencies of that crate. (We are building a small support crate for some new materials The Rust Programming Language book, and I am trying to get the book repo tests working with that, and it is… an interesting challenge.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests