#![allow(deprecated)]
use crate::fake_claude_lib::ScenarioBuilder;
use crate::fixtures::WorkspaceBuilder;
use assert_cmd::Command;
fn rslph_with_fake_claude(
scenario: &crate::fake_claude_lib::FakeClaudeHandle,
) -> assert_cmd::Command {
let mut cmd = Command::cargo_bin("rslph").expect("rslph binary should exist");
for (key, value) in scenario.env_vars() {
cmd.env(key, value);
}
cmd
}
#[test]
fn test_fake_claude_with_custom_tokens() {
let scenario = ScenarioBuilder::new()
.with_token_usage(5000, 1500, 2000, 1000)
.respond_with_text("Task completed with custom tokens.")
.build();
let output = std::process::Command::new(&scenario.executable_path)
.env("FAKE_CLAUDE_CONFIG", &scenario.config_path)
.output()
.expect("Failed to run fake claude");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout.contains("5000") || stdout.contains("\"input_tokens\":5000"),
"Expected input_tokens: 5000 in output, got: {}",
stdout
);
assert!(
stdout.contains("1500") || stdout.contains("\"output_tokens\":1500"),
"Expected output_tokens: 1500 in output, got: {}",
stdout
);
assert!(
stdout.contains("2000") || stdout.contains("\"cache_creation_input_tokens\":2000"),
"Expected cache_creation_input_tokens: 2000 in output, got: {}",
stdout
);
assert!(
stdout.contains("1000") || stdout.contains("\"cache_read_input_tokens\":1000"),
"Expected cache_read_input_tokens: 1000 in output, got: {}",
stdout
);
}
#[test]
fn test_fake_claude_multi_invocation_tokens() {
let scenario = ScenarioBuilder::new()
.with_token_usage(5000, 1500, 2000, 1000)
.respond_with_text("First invocation")
.next_invocation()
.with_token_usage(3000, 1000, 500, 2500)
.respond_with_text("Second invocation")
.build();
let output1 = std::process::Command::new(&scenario.executable_path)
.env("FAKE_CLAUDE_CONFIG", &scenario.config_path)
.output()
.expect("Failed to run fake claude");
let stdout1 = String::from_utf8_lossy(&output1.stdout);
assert!(
stdout1.contains("5000"),
"First invocation should have input_tokens: 5000, got: {}",
stdout1
);
let output2 = std::process::Command::new(&scenario.executable_path)
.env("FAKE_CLAUDE_CONFIG", &scenario.config_path)
.output()
.expect("Failed to run fake claude");
let stdout2 = String::from_utf8_lossy(&output2.stdout);
assert!(
stdout2.contains("3000"),
"Second invocation should have input_tokens: 3000, got: {}",
stdout2
);
}
#[test]
fn test_rslph_build_with_token_tracking() {
let scenario = ScenarioBuilder::new()
.with_token_usage(5000, 1500, 2000, 1000)
.respond_with_text("I'll work on Task 1. The task has been completed.")
.build();
let workspace = WorkspaceBuilder::new()
.with_progress_file("# Progress\n\n- [ ] Task 1\n")
.build();
let mut cmd = rslph_with_fake_claude(&scenario);
cmd.arg("build")
.arg("PROGRESS.md")
.arg("--max-iterations")
.arg("1")
.arg("--no-tui")
.current_dir(workspace.path());
let output = cmd.output().expect("Failed to run rslph");
assert!(
scenario.invocation_count() >= 1,
"Expected at least 1 invocation, got {}",
scenario.invocation_count()
);
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
let combined = format!("{}{}", stdout, stderr);
assert!(
output.status.success() || combined.contains("iteration"),
"Build should complete (may exit non-zero if task not marked done)"
);
}
#[test]
fn test_fake_claude_tool_use_with_tokens() {
let scenario = ScenarioBuilder::new()
.with_token_usage(10000, 5000, 3000, 2000)
.uses_read("/test/file.txt")
.build();
let output = std::process::Command::new(&scenario.executable_path)
.env("FAKE_CLAUDE_CONFIG", &scenario.config_path)
.output()
.expect("Failed to run fake claude");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout.contains("tool_use"),
"Expected tool_use in output, got: {}",
stdout
);
assert!(
stdout.contains("10000"),
"Expected input_tokens: 10000 in tool_use output, got: {}",
stdout
);
}