Extracting docstrings from tests

Hi everyone :wave:

I have a codebase where some information about the test cases is included in the doc strings, like so:

/// This describes the add function
pub fn add(left: usize, right: usize) -> usize {
    left + right
}

#[cfg(test)]
mod tests {
    use super::*;

    /// This describes the test
    #[test]
    fn it_works() {
        let result = add(2, 2);
        assert_eq!(result, 4);
    }

    /// This function resides inside the `tests` module, but it is not a test itself
    fn some_helper_function() {}
}

I want to use rustdoc to extract the doc strings, but unfortunately I could not manage to get rustdoc to output anything about functions annotated with the #[test] macro :confused:
I am using cargo rustdoc -- --document-private-items --cfg test , which adds the tests module and tests.some_helper_function to the output, but tests.it_works is not present.

On Stack Overflow, someone suggested swapping out #[test] for #[cfg_attr(not(doc), test)] a couple of years ago, I would like to avoid modifying the source code though. Do you have any idea how to do this?

according to the reference, items annotated with #[test] don't get compiled unless --test is passed to rustc.

it doesn't even show up in the HIR, as you can see in this playground example (click the leftmost ... button, then click HIR, then "Show HIR")

you could try passing --test to rustdoc, although that's supposed to be the flag for running doctests.

you might have more luck with using the syn crate, or maybe tree-sitter-rust (tree-sitter is nice because it actually has its own query language)

1 Like

This. OP will need a fully-fledged Rust parser for this, no ifs or buts about it.

i mean, rustdoc calls into a rust parser, so it's not unreasonable to think it might be able to do something like this. unfortunatly it seems it's not so.

1 Like

here's a tree-sitter query to extract all the doc comments from a rust file, to get you started.

(line_comment
  doc: (doc_comment) @doc @text)
(block_comment
  doc: (doc_comment) @doc @text)
1 Like

Hi @binarycat, thanks for your answers. That was really helpful!

I tried setting RUSTFLAGS to --test, but that seems to fail in another place :confused:

error: output of --print=file-names missing when learning about target-specific information from rustc

Oh thanks, I didn't know tree-sitter until now. I did not know it until now, but I took some time to check it out today. I think I understand the basic principle - still, I don't understand one thing: When using the playground, I was not able to produce a tree with any doc_comment element, not even with an example from the test suite:

Do you know whether I am missing anything here?

might be a playground bug, try using the actual tree_sitter_rust crate.