Merge pull request #1880 from ehuss/test
Update `test` to use the attribute template
diff --git a/src/attributes/testing.md b/src/attributes/testing.md
index 93e26a8..e6aae79 100644
--- a/src/attributes/testing.md
+++ b/src/attributes/testing.md
@@ -10,21 +10,44 @@
## The `test` attribute
r[attributes.testing.test.intro]
-The *`test` attribute* marks a function to be executed as a test.
+The *`test` [attribute][attributes]* marks a function to be executed as a test.
+
+> [!EXAMPLE]
+> ```rust
+> # pub fn add(left: u64, right: u64) -> u64 { left + right }
+>
+> #[test]
+> fn it_works() {
+> let result = add(2, 2);
+> assert_eq!(result, 4);
+> }
+> ```
+
+r[attributes.testing.test.syntax]
+The `test` attribute uses the [MetaWord] syntax and thus does not take any inputs.
+
+r[attributes.testing.test.allowed-positions]
+The `test` attribute may only be applied to [free functions] that are monomorphic, that take no arguments, and where the return type implements the [`Termination`] trait.
+
+> [!NOTE]
+> Some of types that implement the [`Termination`] trait include:
+> * `()`
+> * `Result<T, E> where T: Termination, E: Debug`
+
+r[attributes.testing.test.duplicates]
+Only the first instance of `test` on a function is honored.
+
+> [!NOTE]
+> Subsequent `test` attributes are currently ignored and `rustc` warns about these.
+
+<!-- TODO: This is a minor lie. Currently rustc warns that duplicates are ignored, but it then generates multiple test entries with the same name. I would vote for rejecting this in the future. -->
+
+r[attributes.testing.test.stdlib]
+The `test` attribute is exported from the standard library prelude as [`std::prelude::v1::test`].
r[attributes.testing.test.enabled]
These functions are only compiled when in test mode.
-r[attributes.testing.test.allowed-positions]
-Test functions must be free, monomorphic functions that take no arguments, and the return type must implement the [`Termination`] trait, for example:
-
-* `()`
-* `Result<T, E> where T: Termination, E: Debug`
-* `!`
-
-<!-- If the previous section needs updating (from "must take no arguments"
- onwards, also update it in the crates-and-source-files.md file -->
-
> [!NOTE]
> The test mode is enabled by passing the `--test` argument to `rustc` or using `cargo test`.
@@ -36,17 +59,18 @@
* Tests that return `ExitCode::SUCCESS` pass, and tests that return `ExitCode::FAILURE` fail.
* Tests that do not terminate neither pass nor fail.
-```rust
-# use std::io;
-# fn setup_the_thing() -> io::Result<i32> { Ok(1) }
-# fn do_the_thing(s: &i32) -> io::Result<()> { Ok(()) }
-#[test]
-fn test_the_thing() -> io::Result<()> {
- let state = setup_the_thing()?; // expected to succeed
- do_the_thing(&state)?; // expected to succeed
- Ok(())
-}
-```
+> [!EXAMPLE]
+> ```rust
+> # use std::io;
+> # fn setup_the_thing() -> io::Result<i32> { Ok(1) }
+> # fn do_the_thing(s: &i32) -> io::Result<()> { Ok(()) }
+> #[test]
+> fn test_the_thing() -> io::Result<()> {
+> let state = setup_the_thing()?; // expected to succeed
+> do_the_thing(&state)?; // expected to succeed
+> Ok(())
+> }
+> ```
r[attributes.testing.ignore]
## The `ignore` attribute
@@ -102,3 +126,4 @@
[`test` conditional compilation option]: ../conditional-compilation.md#test
[attributes]: ../attributes.md
[`ExitCode`]: std::process::ExitCode
+[free functions]: ../glossary.md#free-item