use super::*;
use crate::linter::{Diagnostic, Fix, Span};
#[test]
fn test_REPL_006_001_lint_finds_issues() {
let input = "cat file.txt | grep pattern";
let result = lint_bash(input);
assert!(result.is_ok(), "Should lint successfully: {:?}", result);
let lint_result = result.unwrap();
let _ = lint_result.diagnostics.len();
}
#[test]
fn test_REPL_006_001_lint_categorizes_severity() {
let input = "echo test";
let result = lint_bash(input);
assert!(result.is_ok(), "Should lint successfully");
let lint_result = result.unwrap();
let errors = lint_result
.diagnostics
.iter()
.filter(|d| d.severity == Severity::Error)
.count();
let warnings = lint_result
.diagnostics
.iter()
.filter(|d| d.severity == Severity::Warning)
.count();
assert!(
errors + warnings <= lint_result.diagnostics.len(),
"Error and warning counts should not exceed total diagnostics"
);
}
#[test]
fn test_REPL_006_001_format_lint_results() {
let input = "echo hello";
let result = lint_bash(input).unwrap();
let formatted = format_lint_results(&result);
assert!(!formatted.is_empty(), "Should format results");
assert!(
formatted.contains("issue") || formatted.contains("No issues"),
"Should show issue count or success message"
);
}
#[test]
fn test_REPL_006_001_lint_empty_input() {
let input = "";
let result = lint_bash(input);
assert!(result.is_ok(), "Should handle empty input");
}
#[test]
fn test_REPL_014_003_format_single_violation() {
let source = "echo hello\necho $RANDOM\necho world\n";
let diagnostic = Diagnostic {
code: "DET001".to_string(),
severity: Severity::Error,
message: "Non-deterministic $RANDOM".to_string(),
span: Span::new(2, 6, 2, 13),
fix: None,
};
let lint_result = LintResult {
diagnostics: vec![diagnostic],
};
let formatted = format_violations_with_context(&lint_result, source);
assert!(
formatted.contains("1 | echo hello"),
"Output: {}",
formatted
);
assert!(
formatted.contains(">") && formatted.contains("2 | echo $RANDOM"),
"Output: {}",
formatted
);
assert!(formatted.contains("3 | echo world"));
assert!(formatted.contains("^^^^^^^")); assert!(formatted.contains("error [DET001]")); assert!(formatted.contains("Non-deterministic $RANDOM"));
}
#[test]
fn test_REPL_014_003_format_with_fix() {
let source = "mkdir /app\n";
let diagnostic = Diagnostic {
code: "IDEM001".to_string(),
severity: Severity::Error,
message: "mkdir without -p".to_string(),
span: Span::new(1, 1, 1, 11),
fix: Some(Fix::new("mkdir -p /app")),
};
let lint_result = LintResult {
diagnostics: vec![diagnostic],
};
let formatted = format_violations_with_context(&lint_result, source);
assert!(formatted.contains(">") && formatted.contains("1 | mkdir /app"));
assert!(formatted.contains("IDEM001"));
assert!(formatted.contains("Suggested fix:"));
assert!(formatted.contains("mkdir -p /app"));
}
#[test]
fn test_REPL_014_003_multiple_violations() {
let source = "echo $RANDOM\nmkdir /app\nrm /tmp/file\n";
let diagnostics = vec![
Diagnostic {
code: "DET001".to_string(),
severity: Severity::Error,
message: "Non-deterministic $RANDOM".to_string(),
span: Span::new(1, 6, 1, 13),
fix: None,
},
Diagnostic {
code: "IDEM001".to_string(),
severity: Severity::Error,
message: "mkdir without -p".to_string(),
span: Span::new(2, 1, 2, 11),
fix: Some(Fix::new("mkdir -p /app")),
},
];
let lint_result = LintResult { diagnostics };
let formatted = format_violations_with_context(&lint_result, source);
assert!(formatted.contains("DET001"));
assert!(formatted.contains("IDEM001"));
assert!(formatted.contains("echo $RANDOM"));
assert!(formatted.contains("mkdir /app"));
}
#[test]
fn test_REPL_014_003_no_violations() {
let source = "echo hello\n";
let lint_result = LintResult {
diagnostics: vec![],
};
let formatted = format_violations_with_context(&lint_result, source);
assert!(formatted.contains("✓ No violations"));
}
#[test]
fn test_REPL_014_003_edge_of_file() {
let source1 = "echo $RANDOM\n";
let diagnostic1 = Diagnostic {
code: "DET001".to_string(),
severity: Severity::Error,
message: "Non-deterministic $RANDOM".to_string(),
span: Span::new(1, 6, 1, 13),
fix: None,
};
let formatted1 = format_violations_with_context(
&LintResult {
diagnostics: vec![diagnostic1],
},
source1,
);
assert!(formatted1.contains(">") && formatted1.contains("1 | echo $RANDOM"));
let source2 = "echo hello\necho world\necho $RANDOM\n";
let diagnostic2 = Diagnostic {
code: "DET001".to_string(),
severity: Severity::Error,
message: "Non-deterministic $RANDOM".to_string(),
span: Span::new(3, 6, 3, 13),
fix: None,
};
let formatted2 = format_violations_with_context(
&LintResult {
diagnostics: vec![diagnostic2],
},
source2,
);
assert!(formatted2.contains("1 | echo hello"));
assert!(formatted2.contains("2 | echo world"));
assert!(formatted2.contains(">") && formatted2.contains("3 | echo $RANDOM"));
}