Documentation Testing

Comprehensive documentation testing for the Armature framework.

Overview

All code examples in documentation are tested automatically using Rust's built-in doc test feature. This ensures that all examples compile correctly and run as expected.

Documentation Test Coverage

Total Documentation Tests: 25

Package Doc Tests Status
armature-jwt 5 โœ… Pass
armature-cache 5 โœ… Pass
armature-config 3 โœ… Pass
armature-validation 3 โœ… Pass
armature-cron 3 โœ… Pass
armature-queue 2 โœ… Pass
armature-core 1 โœ… Pass
armature-security 1 โœ… Pass
armature-openapi 1 โœ… Pass
armature-opentelemetry 1 โœ… Pass

Ignored Tests: 4

Some tests use ignore attribute for:

  • Examples requiring external dependencies
  • Examples with complex setup requirements
  • HTTPS examples requiring certificates

Running Documentation Tests

Test All Documentation

cargo test --doc --all

Test Specific Package

cargo test --doc --package armature-jwt
cargo test --doc --package armature-config
cargo test --doc --package armature-validation

Show Documentation Test Output

cargo test --doc --all -- --nocapture

Documentation Examples by Module

JWT Authentication (armature-jwt)

5 doc tests

Examples cover:

  • Basic JWT token creation and verification
  • Custom claims with user data
  • Token signing and verification
  • Standard claims usage
  • JwtManager API methods
use armature_jwt::{JwtConfig, JwtManager, StandardClaims};

let config = JwtConfig::new("secret".to_string());
let manager = JwtManager::new(config)?;

let claims = StandardClaims::new()
    .with_subject("user123".to_string())
    .with_expiration(3600);

let token = manager.sign(&claims)?;
let decoded: StandardClaims = manager.verify(&token)?;

Configuration Management (armature-config)

3 doc tests

Examples cover:

  • Basic configuration management
  • Environment variable loading
  • Type conversions (string, int, float, bool)
  • Nested configuration keys
use armature_config::ConfigManager;

let manager = ConfigManager::new();
manager.set("app.name", "MyApp")?;
manager.set("app.port", 3000i64)?;

let name: String = manager.get("app.name")?;
let port: i64 = manager.get("app.port")?;

Validation Framework (armature-validation)

3 doc tests

Examples cover:

  • Basic validation with built-in validators
  • Validation rules builder pattern
  • Number validation (min, max, range, positive)
  • String validation (email, length, format)
use armature_validation::{Validate, ValidationError, NotEmpty, IsEmail};

impl Validate for UserInput {
    fn validate(&self) -> Result<(), Vec<ValidationError>> {
        let mut errors = Vec::new();
        if let Err(e) = NotEmpty::validate(&self.name, "name") {
            errors.push(e);
        }
        if let Err(e) = IsEmail::validate(&self.email, "email") {
            errors.push(e);
        }
        if errors.is_empty() { Ok(()) } else { Err(errors) }
    }
}

Cache Management (armature-cache)

5 doc tests

Examples cover:

  • Redis cache initialization
  • Basic get/set operations
  • TTL management
  • Namespaced caching
  • Cache manager usage

Cron Scheduling (armature-cron)

3 doc tests

Examples cover:

  • Cron expression parsing
  • Job scheduling
  • Scheduler management

Queue System (armature-queue)

2 doc tests

Examples cover:

  • Job queue creation
  • Job enqueuing
  • Worker management

Security Middleware (armature-security)

1 doc test

Example covers:

  • SecurityMiddleware configuration
  • HSTS, CSP, and other security headers
  • Default vs. custom security settings

Documentation Quality Standards

All documentation examples must:

โœ… Compile Successfully

  • All examples must compile without errors
  • Use proper imports and type annotations
  • Include necessary error handling

โœ… Be Self-Contained

  • Include all necessary imports
  • Provide complete, runnable code
  • Use # fn main() -> Result<(), Box<dyn std::error::Error>> for error handling

โœ… Demonstrate Real Usage

  • Show realistic use cases
  • Include proper error handling
  • Demonstrate best practices

โœ… Be Tested Automatically

  • Run as part of CI/CD pipeline
  • Fail build if examples don't compile
  • Verified on every commit

Doc Test Attributes

no_run

For examples that compile but shouldn't execute:

/// ```no_run
/// use armature_framework::prelude::*;
/// let app = Application::create::<AppModule>().await;
/// app.listen(3000).await.unwrap();
/// ```

ignore

For examples that should be excluded from testing:

/// ```ignore
/// // This example requires external setup
/// ```

should_panic

For examples demonstrating error conditions:

/// ```should_panic
/// panic!("This should fail");
/// ```

Module-Level Documentation

Format

//! # Module Name
//!
//! Brief module description.
//!
//! # Examples
//!
//! ```
//! use module_name::Feature;
//!
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let feature = Feature::new();
//! feature.do_something()?;
//! # Ok(())
//! # }
//! ```

Best Practices

  1. Start with //! for module docs
  2. Include at least one working example
  3. Show the most common use case
  4. Keep examples concise but complete
  5. Test examples automatically

Method-Level Documentation

Format

/// Brief description of what this method does.
///
/// # Arguments
///
/// * `arg1` - Description of arg1
/// * `arg2` - Description of arg2
///
/// # Returns
///
/// Description of return value.
///
/// # Errors
///
/// Description of possible errors.
///
/// # Examples
///
/// ```
/// use module_name::Type;
///
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// let instance = Type::new();
/// instance.method(arg1, arg2)?;
/// # Ok(())
/// # }
/// ```
pub fn method(&self, arg1: Type1, arg2: Type2) -> Result<ReturnType, Error> {
    // Implementation
}

Testing Strategy

Local Testing

Before committing:

# Test all documentation
cargo test --doc --all

# Test specific module
cargo test --doc --package armature-jwt

# Show all test output
cargo test --doc --all -- --nocapture

CI/CD Integration

Documentation tests run as part of the CI pipeline:

- name: Test Documentation
  run: cargo test --doc --all

Pre-commit Hook

Add to .git/hooks/pre-commit:

#!/bin/sh
cargo test --doc --all || exit 1

Continuous Improvement

Goals

  • โœ… 100% of public APIs have doc comments
  • โœ… All modules have at least one code example
  • โœ… All code examples compile and run
  • โœ… Examples demonstrate real-world usage
  • โณ Expand examples to cover edge cases
  • โณ Add more advanced usage examples
  • โณ Include troubleshooting examples

Metrics

Metric Current Goal
Doc test count 25 50+
Modules with examples 10 20
Example pass rate 100% 100%
Public API coverage ~80% 100%

Common Patterns

Error Handling in Examples

/// # Examples
///
/// ```
/// use module::Type;
///
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// let result = Type::try_new()?;
/// # Ok(())
/// # }
/// ```

Hidden Setup Code

Use # to hide setup code:

/// ```
/// # use module::Type;
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// let value = Type::new();
/// // User sees this
/// value.do_something()?;
/// # Ok(())
/// # }
/// ```

Testing Private Items

Private items aren't tested by default:

#[cfg(test)]
mod tests {
    /// This will be tested
    /// ```
    /// assert!(true);
    /// ```
    fn private_function() {}
}

Troubleshooting

Example Doesn't Compile

  1. Check imports are correct
  2. Verify types match
  3. Add error handling if needed
  4. Use # fn main() -> Result<...> wrapper

Example Compiles But Fails

  1. Check assertion logic
  2. Verify example data is valid
  3. Ensure dependencies are available
  4. Consider using no_run if appropriate

Example Takes Too Long

  1. Use no_run for long-running examples
  2. Simplify the example
  3. Mock expensive operations
  4. Use timeouts if necessary

Summary

Documentation testing ensures that all code examples in the Armature framework:

  • โœ… Compile correctly - No broken examples
  • โœ… Run successfully - Examples actually work
  • โœ… Stay up-to-date - Tests fail when APIs change
  • โœ… Serve as integration tests - Real usage verification
  • โœ… Provide confidence - Users can trust the documentation

Total: 25 passing documentation tests across 10 packages ๐ŸŽ‰