#![allow(clippy::unwrap_used)]
#![allow(clippy::expect_used)]
use crate::linter::output::{write_results, OutputFormat};
use crate::linter::rules::{lint_shell, lint_shell_with_path, LintProfile};
use crate::linter::{Diagnostic, Fix, LintResult, Severity, Span};
use std::path::Path;
#[test]
fn test_lint_shell_empty_source() {
let result = lint_shell("");
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_whitespace_only() {
let result = lint_shell(" \n\n \t\n");
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_comment_only() {
let result = lint_shell("# This is just a comment\n# Another comment\n");
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_shebang_only() {
let result = lint_shell("#!/bin/sh\n");
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_clean_script() {
let script = "#!/bin/sh\nprintf '%s\\n' 'hello'\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_backtick_usage() {
let script = "result=`echo hello`\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_arithmetic_expression() {
let script = "x=$((1 + 2))\necho $x\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_test_bracket_spacing() {
let script = "if [ -f /tmp/x ]; then echo yes; fi\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_heredoc() {
let script = "cat <<EOF\nhello world\nEOF\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_unicode_quotes() {
let script = "echo \u{201c}hello\u{201d}\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_missing_shebang() {
let script = "echo hello world\necho goodbye\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_dollar_single_quote() {
let script = "echo 'it\\'s'\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_trailing_backslash() {
let script = "echo \"hello\\\nworld\"\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_useless_cat() {
let script = "cat file.txt | grep pattern\n";
let result = lint_shell(script);
assert!(
result.diagnostics.iter().any(|d| d.code.starts_with("SC")),
"Should detect at least one issue"
);
}
#[test]
fn test_lint_shell_unquoted_glob() {
let script = "for f in *.txt; do echo $f; done\n";
let result = lint_shell(script);
assert!(
result.diagnostics.iter().any(|d| d.code == "SC2086"),
"Should detect unquoted $f"
);
}
#[test]
fn test_lint_shell_cd_without_check() {
let script = "cd /tmp\necho done\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_unused_variable() {
let script = "UNUSED_VAR=hello\necho done\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_double_bracket() {
let script = "if [[ -f /tmp/x ]]; then echo yes; fi\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_eval_usage() {
let script = "eval \"echo $VAR\"\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_array_usage() {
let script = "arr=(a b c)\necho ${arr[0]}\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_read_without_r() {
let script = "read name\necho $name\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_echo_with_flags() {
let script = "echo -e \"hello\\nworld\"\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_echo_backslash_n() {
let script = "echo \"hello\\nworld\"\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_useless_echo_cmd_subst() {
let script = "result=$(echo $(cat file.txt))\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_dollar_brace_expansion() {
let script = "if [[ $var == *.txt ]]; then echo yes; fi\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_printf_format_injection() {
let script = "printf $var\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_trap_timing() {
let script = "trap \"rm -f $TMPFILE\" EXIT\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_dangerous_rm() {
let script = "rm -rf $DIR/\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_ssh_in_loop() {
let script = "while read host; do ssh $host uptime; done < hosts.txt\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_same_file_redirect() {
let script = "sort file.txt > file.txt\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_subshell_variable_scope() {
let script = "x=1\n(x=2)\necho $x\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_constant_condition() {
let script = "if [ \"true\" = \"true\" ]; then echo yes; fi\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_grep_regex_literal() {
let script = "grep foo* file.txt\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_tilde_in_quotes() {
let script = "cd \"~/Documents\"\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_seq_vs_brace() {
let script = "for i in {1..10}; do echo $i; done\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_test_n_unquoted() {
let script = "if [ -n $var ]; then echo set; fi\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_redirect_stderr() {
let script = "cmd > /dev/null 2>&1\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_function_keyword() {
let script = "function myfunc() {\n echo hello\n}\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_numeric_comparison_in_test() {
let script = "if [ $a -gt $b ]; then echo bigger; fi\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
fn test_lint_shell_det_random() {
let script = "echo $RANDOM\n";
let result = lint_shell(script);
assert!(
result.diagnostics.iter().any(|d| d.code.starts_with("DET")),
"Should detect non-deterministic $RANDOM"
);
}
#[test]
fn test_lint_shell_det_date() {
let script = "date +%s > /tmp/timestamp\n";
let result = lint_shell(script);
let _count = result.diagnostics.len();
}
#[test]
include!("lint_shell_coverage_tests_tests_lint_2.rs");