mod common;
use std::process::Command;
use common::test_fixtures_dir;
fn normalize_output(output: &str, fixture_dir: &str) -> String {
output.replace(fixture_dir, "<fixtures>")
}
#[test]
fn test_snapshot_check_clean_file_text() {
let rledger = require_rledger!();
let fixture = test_fixtures_dir().join("valid-ledger.beancount");
let output = Command::new(&rledger)
.args(["check", "--no-cache"])
.arg(&fixture)
.output()
.expect("failed to run rledger check");
assert!(
output.status.success(),
"rledger check should succeed on valid file: {}",
String::from_utf8_lossy(&output.stderr)
);
let stdout = String::from_utf8_lossy(&output.stdout);
let normalized = normalize_output(&stdout, &test_fixtures_dir().display().to_string());
insta::assert_snapshot!("check_clean_text", normalized.trim());
}
#[test]
fn test_snapshot_check_parse_errors_text() {
let rledger = require_rledger!();
let fixture = test_fixtures_dir().join("parse-errors.beancount");
let output = Command::new(&rledger)
.args(["check", "--no-cache"])
.arg(&fixture)
.output()
.expect("failed to run rledger check");
assert!(
!output.status.success(),
"rledger check should fail on file with parse errors"
);
let stdout = String::from_utf8_lossy(&output.stdout);
let normalized = normalize_output(&stdout, &test_fixtures_dir().display().to_string());
insta::assert_snapshot!("check_parse_errors_text", normalized.trim());
}
#[test]
fn test_snapshot_check_validation_errors_text() {
let rledger = require_rledger!();
let fixture = test_fixtures_dir().join("validation-errors.beancount");
let output = Command::new(&rledger)
.args(["check", "--no-cache"])
.arg(&fixture)
.output()
.expect("failed to run rledger check");
assert!(
!output.status.success(),
"rledger check should fail on file with validation errors"
);
let stdout = String::from_utf8_lossy(&output.stdout);
let normalized = normalize_output(&stdout, &test_fixtures_dir().display().to_string());
insta::assert_snapshot!("check_validation_errors_text", normalized.trim());
}
#[test]
fn test_snapshot_check_clean_file_json() {
let rledger = require_rledger!();
let fixture = test_fixtures_dir().join("valid-ledger.beancount");
let output = Command::new(&rledger)
.args(["check", "--format", "json", "--no-cache"])
.arg(&fixture)
.output()
.expect("failed to run rledger check");
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
if stderr.contains("--format") {
eprintln!("Skipping: --format json not supported");
return;
}
}
let stdout = String::from_utf8_lossy(&output.stdout);
let json: serde_json::Value = serde_json::from_str(&stdout).expect("should produce valid JSON");
let normalized_json = normalize_json_paths(&json, &test_fixtures_dir().display().to_string());
let pretty = serde_json::to_string_pretty(&normalized_json).unwrap();
insta::assert_snapshot!("check_clean_json", pretty);
}
#[test]
fn test_snapshot_check_validation_errors_json() {
let rledger = require_rledger!();
let fixture = test_fixtures_dir().join("validation-errors.beancount");
let output = Command::new(&rledger)
.args(["check", "--format", "json", "--no-cache"])
.arg(&fixture)
.output()
.expect("failed to run rledger check");
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
if stderr.contains("--format") {
eprintln!("Skipping: --format json not supported");
return;
}
}
let stdout = String::from_utf8_lossy(&output.stdout);
let json: serde_json::Value = serde_json::from_str(&stdout).expect("should produce valid JSON");
let normalized_json = normalize_json_paths(&json, &test_fixtures_dir().display().to_string());
let pretty = serde_json::to_string_pretty(&normalized_json).unwrap();
insta::assert_snapshot!("check_validation_errors_json", pretty);
}
#[test]
fn test_snapshot_query_table_output() {
let rledger = require_rledger!();
let fixture = test_fixtures_dir().join("query-test.beancount");
let output = Command::new(&rledger)
.args(["query", "-q"])
.arg(&fixture)
.arg("SELECT date, narration, account, position WHERE account ~ 'Expenses' ORDER BY date")
.output()
.expect("failed to run rledger query");
assert!(
output.status.success(),
"rledger query failed: {}",
String::from_utf8_lossy(&output.stderr)
);
let stdout = String::from_utf8_lossy(&output.stdout);
insta::assert_snapshot!("query_table_output", stdout.trim());
}
#[test]
fn test_snapshot_query_aggregate_output() {
let rledger = require_rledger!();
let fixture = test_fixtures_dir().join("query-test.beancount");
let output = Command::new(&rledger)
.args(["query", "-q"])
.arg(&fixture)
.arg("SELECT account, SUM(position) GROUP BY account ORDER BY account")
.output()
.expect("failed to run rledger query");
assert!(
output.status.success(),
"rledger query failed: {}",
String::from_utf8_lossy(&output.stderr)
);
let stdout = String::from_utf8_lossy(&output.stdout);
insta::assert_snapshot!("query_aggregate_output", stdout.trim());
}
fn normalize_json_paths(value: &serde_json::Value, fixture_dir: &str) -> serde_json::Value {
match value {
serde_json::Value::String(s) => {
serde_json::Value::String(s.replace(fixture_dir, "<fixtures>"))
}
serde_json::Value::Array(arr) => serde_json::Value::Array(
arr.iter()
.map(|v| normalize_json_paths(v, fixture_dir))
.collect(),
),
serde_json::Value::Object(obj) => serde_json::Value::Object(
obj.iter()
.map(|(k, v)| (k.clone(), normalize_json_paths(v, fixture_dir)))
.collect(),
),
other => other.clone(),
}
}