use std::fs;
use std::path::PathBuf;
use claude_code_status_line::app::{parse_claude_input, render_statusline_with_width};
use claude_code_status_line::config::Config;
fn fixture_path(name: &str) -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests")
.join("fixtures")
.join("statusline")
.join(name)
}
fn load_fixture(name: &str) -> String {
fs::read_to_string(fixture_path(name)).expect("fixture should be readable")
}
fn test_config() -> Config {
let mut config = Config::default();
config.sections.git.enabled = false;
config.sections.quota.enabled = false;
config.sections.cost.enabled = false;
config.sections.model.show_thinking_mode = false;
config.display.show_background = false;
config.display.multiline = false;
config
}
fn strip_ansi(input: &str) -> String {
let mut result = String::new();
let mut chars = input.chars().peekable();
while let Some(ch) = chars.next() {
if ch == '\x1b' {
if chars.peek() == Some(&'[') {
chars.next();
for next in chars.by_ref() {
if ('@'..='~').contains(&next) {
break;
}
}
}
} else {
result.push(ch);
}
}
result
}
fn render_fixture(name: &str, config: &Config) -> String {
let input = parse_claude_input(&load_fixture(name)).expect("fixture should parse");
let lines = render_statusline_with_width(&input, config, 200);
strip_ansi(&lines.join("\n"))
}
#[test]
fn renders_legacy_workspace_only_fixture() {
let output = render_fixture("legacy-workspace-only.json", &test_config());
assert!(output.contains("legacy-repo"));
assert!(output.contains("Sonnet 4.5"));
assert!(output.contains("ctx: ~7%"));
assert!(output.contains("200k"));
}
#[test]
fn renders_direct_percentages_without_estimate_marker() {
let output = render_fixture("direct-percentages.json", &test_config());
assert!(output.contains("ctx: 8%"));
assert!(!output.contains("ctx: ~8%"));
}
#[test]
fn renders_workspace_added_dirs_as_compact_scope_detail() {
let output = render_fixture("workspace-added-dirs.json", &test_config());
assert!(output.contains("project"));
assert!(output.contains("+2 dirs"));
}
#[test]
fn renders_worktree_detail_when_git_section_is_unavailable() {
let output = render_fixture("worktree-session.json", &test_config());
assert!(output.contains("wt: feature-a"));
}
#[test]
fn renders_one_million_context_totals_without_fallback_to_200k() {
let output = render_fixture("context-1m.json", &test_config());
assert!(output.contains("ctx: 12.5%") || output.contains("ctx: 12%"));
assert!(output.contains("1000k"));
assert!(!output.contains("200k"));
}
#[test]
fn renders_direct_percentage_without_fake_totals_when_size_missing() {
let output = render_fixture("context-missing-size.json", &test_config());
assert!(output.contains("ctx: 12%"));
assert!(!output.contains("k/"));
}
#[test]
fn renders_model_without_empty_output_style_details() {
let mut config = test_config();
config.sections.model.show_output_style = true;
let output = render_fixture("model-no-output-style.json", &config);
assert!(output.contains("Opus 4.6"));
assert!(!output.contains("()"));
}