Mastering Rust Doc Tests: Testing Your Documentation
Rust's documentation comments (/// and //!) are powerful not only for explaining your code but also for ensuring its correctness. Doc tests allow you to embed runnable Rust code directly within your documentation, guaranteeing that your examples and explanations remain accurate as your codebase evolves. This challenge will guide you in creating effective doc tests for a simple Rust function.
Problem Description
Your task is to write a Rust function that calculates the factorial of a non-negative integer. More importantly, you need to implement comprehensive doc tests for this function. These doc tests should cover various scenarios, including the base case, a typical positive input, and a larger input to demonstrate its functionality.
Requirements:
- Implement
factorial(n: u32) -> u32: Create a function namedfactorialthat accepts au32(unsigned 32-bit integer) as input and returns its factorial as au32. - Handle the base case (0!): The factorial of 0 is 1.
- Implement doc tests: Write at least three doc tests within the function's documentation comments:
- A test for the base case (input
0). - A test for a small positive integer (e.g., input
5). - A test for a larger positive integer to ensure the function can handle slightly more complex calculations within the
u32range (e.g., input10).
- A test for the base case (input
- Ensure doc tests pass: All implemented doc tests must pass when
cargo testis run.
Expected Behavior:
The factorial function should return the correct mathematical factorial for any non-negative u32 input. The doc tests should execute successfully, validating the function's behavior for the specified inputs.
Examples
Example 1: Base Case
/// Calculates the factorial of a non-negative integer.
///
/// # Examples
///
/// ```
/// assert_eq!(my_module::factorial(0), 1);
/// ```
///
/// /// ```
/// // ... rest of function and other tests
/// ```
pub fn factorial(n: u32) -> u32 {
// ... implementation ...
}
Input: n = 0
Output: 1
Explanation: The factorial of 0 is defined as 1.
Example 2: Small Positive Integer
/// Calculates the factorial of a non-negative integer.
///
/// # Examples
///
/// /// ```
/// // ... base case test ...
/// /// ```
///
/// ```
/// assert_eq!(my_module::factorial(5), 120);
/// ```
///
/// /// ```
/// // ... rest of function and other tests
/// /// ```
pub fn factorial(n: u32) -> u32 {
// ... implementation ...
}
Input: n = 5
Output: 120 (since 5 * 4 * 3 * 2 * 1 = 120)
Explanation: This tests a typical positive integer input.
Example 3: Larger Positive Integer
/// Calculates the factorial of a non-negative integer.
///
/// # Examples
///
/// /// ```
/// // ... base case test ...
/// /// ```
/// /// ```
/// // ... small positive integer test ...
/// /// ```
///
/// ```
/// assert_eq!(my_module::factorial(10), 3628800);
/// ```
pub fn factorial(n: u32) -> u32 {
// ... implementation ...
}
Input: n = 10
Output: 3628800 (since 10! = 3,628,800)
Explanation: This tests a larger input to ensure the calculation holds up.
Constraints
- The input
nwill be au32. - The output factorial will also be a
u32. Be mindful that factorials grow very quickly; the maximum factorial that can be represented byu32is 12! (479,001,600). Inputs larger than this will cause overflow if not handled, but for this challenge, we assume inputs will result in outputs withinu32's limits for the provided test cases. - The implementation of the
factorialfunction itself should be efficient and correct. - All doc tests must be runnable using
cargo test.
Notes
- Remember that code within
```rustblocks inside documentation comments is treated as a runnable Rust example. - The
assert_eq!macro is your friend for verifying that the actual output matches the expected output. - When writing doc tests, you often need to qualify function names if they are not in the current scope (e.g.,
crate_name::function_name). For a simple module,super::or the module name might be appropriate. For this challenge, assume your function is in a public module and can be called directly or viacrate_name::. - Consider the potential for integer overflow if you were to extend this function to handle larger inputs, though it's not a primary focus for this doc test challenge.
Good luck crafting robust and accurate documentation tests!