官术网_书友最值得收藏!

  • Rust Programming Cookbook
  • Claus Matzinger
  • 631字
  • 2021-06-24 12:27:45

How to do it...

Here are the steps for this recipe:

  1. Find a function or struct (or module) to add a documentation string, for example, the new_empty() function of List<T>:
    ///
/// Creates a new empty list.
///
///
pub fn new_empty() -> List<T> {
...
  1. Use the special (H1) section # Example to provide a cue for the compiler to run any snippet contained in that section:
    ///
/// Creates a new empty list.
///
///
/// # Example
  1. Now let's add a code example. Since doctests are considered black box tests, we import the struct (only if it's public, of course) and show what we want to show:
    ///
/// Creates a new empty list.
///
///
/// # Example
///
/// ```
/// use testing::List;
///
/// let mut list: List<i32> = List::new_empty();
/// ```
///
  1. With that ready, let's see whether the tests work: run cargo +nightly test in the project's root directory. You can see that we cheated a little bit and added tests to the other functions as well:
$ cargo +nightly test
Compiling testing v0.1.0 (Rust-Cookbook/Chapter01/testing)
Finished dev [unoptimized + debuginfo] target(s) in 0.86s
Running target/debug/deps/testing-a0355a7fb781369f

running 6 tests
[...]
Doc-tests testing

running 4 tests
test src/lib.rs - List (line 44) ... ok
test src/lib.rs - List<T>::new_empty (line 70) ... ok
test src/lib.rs - List<T>::append (line 94) ... ok
test src/lib.rs - List<T>::pop (line 121) ... ok

test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
  1. The code obviously has been augmented with several examples that have been run in this case—is that always what we want? Sometimes, it's all about the output, and adding all of the required imports for the test to successfully run is a pain. Hence, there are options to add to the fenced area (``` inside the fence ```), and ignore will neither compile nor run the code:
/// 
/// A singly-linked list, with nodes allocated on the heap using `Rc`s and `RefCell`s. Here's an image illustrating a linked list:
///
///
/// ![](https://upload.wikimedia.org/wikipedia/commons/6/6d/Singly-linked-list.svg)
///
/// *Found on https://en.wikipedia.org/wiki/Linked_list*
///
/// # Example
///
/// ```ignore
///
/// let list = List::new_empty();
/// ```
///
#[derive(Clone)]
pub struct List<T> where T: Sized + Clone {
[...]

  1. By running cargo test again, we see the changes reflected in the output:
$ cargo test
[...]
Doc-tests testing

running 4 tests
test src/lib.rs - List (line 46) ... ignored
test src/lib.rs - List<T>::append (line 94) ... ok
test src/lib.rs - List<T>::new_empty (line 70) ... ok
test src/lib.rs - List<T>::pop (line 121) ... ok

test result: ok. 3 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out
  1. Let's check the HTML output as well: run cargo doc to generate a target/doc/ directory containing all of the CSS/HTML/JavaScript/... required to show the documentation in a local browser. Open target/doc/testing/index.html with your favorite browser:
Note: Replace  testing  with the name of your project.
  1. Let's remove the ugly use statement at the top of the snippet. At that point, it doubles the lines displayed without adding anything—and rustdoc provides a simple way to do that, too. Add # in front of the offending line:
    ///
/// Creates a new empty list.
///
///
/// # Example
///
/// ```
/// # use testing::List;
/// let list: List<i32> = List::new_empty();
/// ```
///
pub fn new_empty() -> List<T> {
[...]
  1. Lastly, there are additional ways to configure the testing behavior of doctests. In this case, let's change warnings to errors by denying the warning while ignoring (allowing) unused variables:  
#![doc(html_logo_url = "https://blog.x5ff.xyz/img/main/logo.png",
test(no_crate_inject, attr(allow(unused_variables),
deny(warnings))))]
  1. One last time, let's check whether the output is what we expect and run cargo doc:

Now, let's see whether we can find out more about how the code works.

主站蜘蛛池模板: 阜康市| 维西| 德安县| 西贡区| 怀远县| 林周县| 新民市| 麦盖提县| 西昌市| 新昌县| 河曲县| 莱州市| 吴桥县| 马边| 张家界市| 偏关县| 普兰店市| 泗洪县| 潮安县| 特克斯县| 青岛市| 措美县| 靖西县| 汝州市| 沈丘县| 城市| 沅陵县| 南漳县| 彰化县| 西城区| 都兰县| 调兵山市| 全椒县| 土默特左旗| 东乡| 重庆市| 德保县| 扎兰屯市| 桂东县| 毕节市| 平塘县|