| Crates.io | poly_doctest |
| lib.rs | poly_doctest |
| version | 0.1.0 |
| created_at | 2025-09-23 20:34:32.873196+00 |
| updated_at | 2025-09-23 20:34:32.873196+00 |
| description | Polyglot documentation snippet test generator - extract code snippets from docs and generate tests |
| homepage | |
| repository | https://github.com/Indra-db/poly_doctest |
| max_upload_size | |
| id | 1852071 |
| size | 105,012 |
readme is a wip. initial release.
A polyglot documentation snippet test generator that extracts code snippets from markdown documentation and generates test files.
HIDE: prefix to exclude setup code from generated testsThis crate provides the core functionality for extracting documentation snippets and generating tests. Language-specific generators implement the LangGenerator trait to produce language-appropriate test files.
processor: Markdown parsing, code extraction, and HIDE line processingsource: Unified interface for local and remote documentation sourcesgenerator: Language generator trait and orchestration logiccli: Command-line interface with argument parsingmodel: Data structures for code snippets and source fileserror: Unified error handling across all modulesLangGenerator: Trait for implementing language-specific test generatorsDocsSource: Enum supporting local directories and remote Git repositoriesCodeSnippet: Processed code snippet with auto-generated test nameSourceFileSnippets: Collection of snippets from a single source fileCliArgs: Structured command-line arguments with validationThis crate is designed to be used by language-specific generator crates:
use poly_doctest::{LangGenerator, run_cli, Result, CodeSnippet, SourceFileSnippets};
use std::path::{Path, PathBuf};
#[derive(Default)]
pub struct MyLanguageGenerator;
impl LangGenerator for MyLanguageGenerator {
fn code_fence_languages(&self) -> &[&str] {
&["mylang", "ml"] // Language identifiers in markdown code fences
}
fn default_output(&self) -> PathBuf {
PathBuf::from("tests/docs")
}
fn generate(&self, source_files: &[SourceFileSnippets], output_path: &Path) -> Result<()> {
// Generate language-specific test files
for source_file in source_files {
for snippet in &source_file.snippets {
// Generate test file using snippet.name and snippet.code
println!("Test: {} -> {}", snippet.name, snippet.code);
}
}
Ok(())
}
}
fn main() -> anyhow::Result<()> {
let generator = MyLanguageGenerator::default();
poly_doctest::run_cli(generator)?;
Ok(())
}
The built-in CLI supports multiple source types and options:
# Local directory (recursive)
my-generator --local ./docs --recursive --output ./tests
# Remote GitHub repository
my-generator --remote https://github.com/owner/repo/tree/main/docs --output ./tests
# Custom hide prefix
my-generator --local ./docs --hide-prefix "SKIP:" --output ./tests
Documentation snippets must use the following format to be processed:
```language test
// Your code here
```
test keyword: Required to indicate this block should generate a testUse the HIDE: prefix (configurable) to remove the prefix but keep the content:
```rust test
HIDE:use std::collections::HashMap;
HIDE: // This comment will be kept
let mut map = HashMap::new();
map.insert("key", "value");
assert_eq!(map.get("key"), Some(&"value"));
```
The generated test will contain:
use std::collections::HashMap;
// This comment will be kept
let mut map = HashMap::new();
map.insert("key", "value");
assert_eq!(map.get("key"), Some(&"value"));
Test names are automatically generated using this hierarchy:
filename_01, filename_02, etc.Important: Headings accumulate as you traverse the document, and the counter is global across all snippets in a single document.
Example:
## Section A
```rust test
let x = 1; // Generated name: section_a_01
```
## Section B
### Subsection
```rust test
let y = 2; // Generated name: section_a_section_b_subsection_02
```
```rust test
let z = 3; // Generated name: section_a_section_b_subsection_03
```
This generates: section_a_01, section_a_section_b_subsection_02, section_a_section_b_subsection_03
Supports extracting documentation from remote Git repositories:
# Full repository
--remote https://github.com/owner/repo
# Specific branch and path
--remote https://github.com/owner/repo/tree/develop/documentation
# GitLab repositories (auto-detected from URL)
--remote https://gitlab.com/owner/repo/tree/main/docs
run_cli(generator): Run with command-line argument parsingrun_with_args(generator, args): Run with pre-parsed argumentsgenerate_docs_with_options(): Low-level generation with full controlSee the tests/rust_doctest/rustgen.rs for a complete Rust generator implementation that creates test modules with proper imports and test functions.
MIT OR Apache-2.0