Rust By Example 21.2 ; Confused by doccomments example

Hello

I am terribly confused by the example here: Documentation testing - Rust By Example

...
/// and `extern crate <cratename>`. Assume we're testing `doccomments` crate:
///
/// ```
/// let result = doccomments::add(2, 3);
/// assert_eq!(result, 5);
/// ```
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

My assumption is that the example likes to comment on pub fn add(a: i32, b: i32) -> i32 and provide an example on how to use it. Cargo test will then check if the provided example actually works. This concept is new to me.

This is how my test project looks like after some trial, error, online search assumptions to fill in the gabs:

_21_Testing
├── Cargo.lock
├── Cargo.toml
├── src
│   ├── doccomments.rs
│   └── main.rs
└── target
...

Cargo.toml:

[package]
name = "_21_Testing"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

[lib]
path = "src/doccomments.rs"

src/doccomments.rs:

/// First line is a short summary describing function.
///
/// The next lines present detailed documentation. Code blocks start with
/// triple backquotes and have implicit `fn main()` inside
/// and `extern crate <cratename>`. Assume we're testing `doccomments` crate:
///
/// ```
/// let result = add(2, 3);
/// assert_eq!(result, 5);
/// ```
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

Runing cargo test includes this output:

...
   Doc-tests _21_Testing

running 1 test
test src/doccomments.rs - add (line 7) ... FAILED

failures:

---- src/doccomments.rs - add (line 7) stdout ----
error[E0433]: failed to resolve: use of undeclared crate or module `doccomments`
 --> src/doccomments.rs:8:14
  |
3 | let result = doccomments::add(2, 3);
  |              ^^^^^^^^^^^ use of undeclared crate or module `doccomments`

error: aborting due to previous error
...

Simple, i thought to myself as I removed doccomments:: and rerun cargo test:

...
   Doc-tests _21_Testing

running 1 test
test src/doccomments.rs - add (line 7) ... FAILED

failures:

---- src/doccomments.rs - add (line 7) stdout ----
error[E0425]: cannot find function `add` in this scope
 --> src/doccomments.rs:8:14
  |
3 | let result = add(2, 3);
  |              ^^^ not found in this scope
  |
help: consider importing this function
  |
2 | use _21_Testing::add;
  |

error: aborting due to previous error
...

At this point, I turned to the search function in this forum and some more online searching, without much luck as I am not sure what to search for. I think I am confused about the environment the documentation code is placed in, and/or how to create a library correctly. Maybe it is something completely different. I am at a loss on how to approach this.

The reason doccomments::add didn't work is your crate has a different name _21_Testing

If you change the crate name in your Cargo.toml to "doccomments" I believe that original example should work.

1 Like

Thank you @semicoleon

I allowed myself to be anoying and change doccomments:: to _21_Testing:: and it works:

   Doc-tests _21_Testing

running 1 test
test src/doccomments.rs - add (line 7) ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.12s

Also tried this to improve my understanding of the situation:

  • Removed _21_Testing::
  • Added line /// use _21_Testing::*;
...
// and `extern crate <cratename>`. Assume we're testing `doccomments` crate:
///
/// ```
/// use _21_Testing::*;
/// let result = add(2, 3);
/// assert_eq!(result, 5);
/// ```
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}
...

And it worked as well.

I understood:

  • Documentation testing places the code example in a virtual test environment outside the file it was written in.
  • Since only one [lib] entry is allowed in Cargo.toml, the package name always acts as the "root" to the lib file, no matter what the lib source file is called.

On this second point, I changed the example back to its original form (with doccomments:: and no use entry), but added the name option to the [lib] section in Cargo.toml:

[package]
name = "_21_Testing"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

[lib]
name = "doccomments"
path = "src/doccomments.rs"

This worked as well, keeping the package name intact and making the Rust by example exaples compatible with my crate :slight_smile:
$ cargo test:

...
   Doc-tests doccomments

running 1 test
test src/doccomments.rs - add (line 9) ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.12s
...

Thanks again, simple solution but tremendous help, as i had no clue what was going on and the influence form C made it worse. I would not have guessed the role of the name entries in Cargo.toml

1 Like

You could have a look at Ch 7 of the Rust book, and The Cargo Book for more detail. Both are also available locally via rustup doc if you have the tools installed.

Of course you might favour the empirical approach - just pointing out that the docs are there if you want/need them.

1 Like