tix-tracker 0.12.0

A terminal issue tracker: markdown + YAML frontmatter issues with a kanban TUI and CLI
Documentation
#[allow(clippy::wildcard_imports)]
use super::super::*;
#[allow(clippy::wildcard_imports)]
use super::helpers::*;

/// Throughput harness for tix #1518. Ignored by default (it is a benchmark,
/// not an assertion); run it against a release build:
///
/// ```text
/// cargo test --release -- --ignored --nocapture perf_startup_and_render
/// ```
///
/// It reports, per issue count, the time to construct an `App` (one tree walk
/// plus board/corpus/rollover build since #1518) and the time for one full
/// board frame. Both are printed; the test asserts nothing, so a regression is
/// visible in the numbers rather than as a flaky wall-clock bound.
#[test]
#[ignore = "throughput harness (tix #1518); run with --release --ignored --nocapture"]
fn perf_startup_and_render() {
    use std::time::Instant;
    for n in [10u32, 100, 1000, 5000] {
        let (_tmp, config) = perf_fixture(n);
        let iters: u32 = if n >= 1000 { 3 } else { 10 };
        // Warm the page cache, then measure `App::new`.
        let mut app = App::new(&config).unwrap();
        let start = Instant::now();
        for _ in 0..iters {
            app = App::new(&config).unwrap();
        }
        let startup = start.elapsed() / iters;
        // One full frame over the built board.
        let start = Instant::now();
        for _ in 0..iters {
            render_to_cells(&app, 120, 40).unwrap();
        }
        let frame = start.elapsed() / iters;
        println!("n={n:5}  startup={startup:>10?}  frame={frame:>10?}");
    }
}

/// Where startup time actually goes, per phase (tix #1518). Run:
///
/// ```text
/// cargo test --release -- --ignored --nocapture perf_startup_breakdown
/// ```
///
/// Prints, per issue count: the tree scan (`store.list`), the board build
/// (blocked/children/related over the whole set), corpus serialization, the
/// rollover plan, and one steady-state filesystem-watcher poll.
#[test]
#[ignore = "throughput harness (tix #1518); run with --release --ignored --nocapture"]
fn perf_startup_breakdown() {
    use std::time::Instant;
    for n in [1000u32, 5000] {
        let (_tmp, config) = perf_fixture(n);
        let store = Store::open(&config).unwrap();
        let board_config = config.default_config().clone();

        let start = Instant::now();
        let issues = store.list().unwrap();
        let scan = start.elapsed();

        let resolution = BoardState::resolution_for(&store, &board_config);
        let start = Instant::now();
        let _board = BoardState::build_from_issues(
            &issues,
            &board_config,
            &store.config,
            &resolution,
            false,
        );
        let board = start.elapsed();

        let start = Instant::now();
        let corpus = Corpus::from_issues(issues);
        let corpus_ser = start.elapsed();

        let planner = Planner::from_config(config.clone(), std::path::PathBuf::from("."));
        let start = Instant::now();
        let _plan = planner.rollover_plan_from(&corpus.issues, &today());
        let rollover = start.elapsed();

        let mut watcher = crate::watcher::FsWatcher::new(store.issues_dir.clone());
        let _ = watcher.poll();
        let start = Instant::now();
        for _ in 0..5 {
            let _ = watcher.poll();
        }
        let watch = start.elapsed() / 5;

        println!(
            "n={n:5} scan={scan:>10?} board={board:>10?} corpus_ser={corpus_ser:>10?} \
                 rollover={rollover:>10?} watch_poll={watch:>10?}"
        );
    }
}