#![allow(clippy::unwrap_used)]
#![allow(clippy::expect_used)]
#![allow(unused_imports)]
use super::super::ast::Redirect;
use super::super::lexer::Lexer;
use super::super::parser::BashParser;
use super::super::semantic::SemanticAnalyzer;
use super::super::*;
#[test]
fn test_ISSUE_060_002_standalone_brace_group() {
let script = r#"{ echo "hello"; echo "world"; }"#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"Parser MUST accept standalone brace group: {:?}",
result.err()
);
let ast = result.expect("Should parse");
assert!(
!ast.statements.is_empty(),
"Should have at least one statement"
);
match &ast.statements[0] {
BashStmt::BraceGroup { body, .. } => {
assert!(
body.len() >= 2,
"Brace group should have at least 2 statements, got: {}",
body.len()
);
}
other => panic!("Expected BraceGroup statement, got: {:?}", other),
}
}
#[test]
fn test_ISSUE_060_003_brace_group_after_and() {
let script = r#"test -f file && { echo "exists"; cat file; }"#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"Parser MUST accept brace group after &&: {:?}",
result.err()
);
}
#[test]
fn test_ISSUE_062_001_extended_test_file_exists() {
let script = r#"if [[ -f /tmp/test.txt ]]; then echo exists; fi"#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"Parser MUST accept [[ ]] extended test: {:?}",
result.err()
);
}
#[test]
fn test_ISSUE_062_002_extended_test_negation() {
let script = r#"if [[ ! -s /tmp/file.txt ]]; then echo "File is empty"; exit 1; fi"#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"Parser MUST accept [[ ! ... ]] negated test: {:?}",
result.err()
);
}
#[test]
fn test_ISSUE_062_003_extended_test_string_comparison() {
let script = r#"if [[ "$total" -eq 0 ]]; then echo "No data"; exit 1; fi"#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"Parser MUST accept [[ ]] string comparison: {:?}",
result.err()
);
}
#[test]
fn test_ISSUE_062_004_extended_test_standalone() {
let script = r#"[[ -d /tmp ]] && echo "directory exists""#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"Parser MUST accept standalone [[ ]] test: {:?}",
result.err()
);
}
#[test]
fn test_ISSUE_061_001_herestring_basic() {
let script = r#"data="hello world"
read line <<< "$data"
echo "$line""#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"Parser MUST accept here-string <<<: {:?}",
result.err()
);
}
#[test]
fn test_ISSUE_061_002_herestring_literal() {
let script = r#"cat <<< "hello world""#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"Parser MUST accept here-string with literal: {:?}",
result.err()
);
}
#[test]
fn test_ISSUE_061_003_herestring_unquoted() {
let script = r#"read word <<< hello"#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"Parser MUST accept here-string with unquoted word: {:?}",
result.err()
);
}
#[test]
fn test_ISSUE_061_004_herestring_pipeline() {
let script = r#"cat <<< "test" | grep t"#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"Parser MUST accept here-string in pipeline: {:?}",
result.err()
);
}
#[test]
fn test_F001_inline_if_then_else_fi() {
let script = r#"if grep -q "pattern" "$FILE"; then echo "found"; else echo "not found"; fi"#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"F001 FALSIFIED: Parser MUST handle inline if/then/else/fi. Error: {:?}",
result.err()
);
let ast = result.unwrap();
assert_eq!(
ast.statements.len(),
1,
"F001 FALSIFIED: Should produce exactly one If statement"
);
match &ast.statements[0] {
BashStmt::If {
then_block,
else_block,
..
} => {
assert!(
!then_block.is_empty(),
"F001 FALSIFIED: then_block should not be empty"
);
assert!(
else_block.is_some(),
"F001 FALSIFIED: else_block should be present"
);
}
other => panic!("F001 FALSIFIED: Expected If statement, got {:?}", other),
}
}
#[test]
fn test_F001_issue93_exact_reproduction() {
let script =
r#"if grep -q "MAX_QUEUE_DEPTH.*=.*3" "$BRIDGE"; then pass "1"; else fail "2"; fi"#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"F001 FALSIFIED: Issue #93 exact case must parse. Error: {:?}",
result.err()
);
}
#[test]
fn test_F002_empty_array_initialization() {
let script = r#"local arr=()"#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"F002 FALSIFIED: Parser MUST handle empty array initialization. Error: {:?}",
result.err()
);
}
#[test]
fn test_F003_array_append_operator() {
let script = r#"arr+=("item")"#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"F003 FALSIFIED: Parser MUST handle array append operator. Error: {:?}",
result.err()
);
}
#[test]
fn test_F004_stderr_redirect_shorthand() {
let script = r#"echo "error" >&2"#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"F004 FALSIFIED: Parser MUST handle stderr redirect shorthand >&2. Error: {:?}",
result.err()
);
}
#[test]
fn test_F005_combined_redirect() {
let script = r#"command &>/dev/null"#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"F005 FALSIFIED: Parser MUST handle combined redirect &>. Error: {:?}",
result.err()
);
}
#[test]
fn test_F006_heredoc_quoted_delimiter() {
let script = r#"cat << 'EOF'
target_bytes = $gb * 1024
chunks = []
EOF"#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"F006 FALSIFIED: Parser MUST handle heredoc with quoted delimiter. Error: {:?}",
result.err()
);
}
#[test]
fn test_F007_line_continuation() {
let script = "echo \"line1 \\\nline2\"";
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"F007 FALSIFIED: Parser MUST handle line continuation. Error: {:?}",
result.err()
);
}
#[test]
fn test_F008_case_all_branches_assign() {
let script = r#"
case "$SHELL" in
*/zsh) shell_rc="$HOME/.zshrc" ;;
*/bash) shell_rc="$HOME/.bashrc" ;;
*) shell_rc="$HOME/.profile" ;;
esac
echo "$shell_rc"
"#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"F008 FALSIFIED: Parser MUST handle case with all branches. Error: {:?}",
result.err()
);
let ast = result.unwrap();
assert!(
ast.statements.len() >= 2,
"F008 FALSIFIED: Should have case and echo statements"
);
}
#[test]
fn test_F009_nested_command_substitution() {
let script = r#"echo "$(dirname "$(pwd)")""#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"F009 FALSIFIED: Parser MUST handle nested command substitution. Error: {:?}",
result.err()
);
}
#[test]
fn test_F010_process_substitution() {
let script = r#"diff <(ls dir1) <(ls dir2)"#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"F010 FALSIFIED: Parser MUST handle process substitution. Error: {:?}",
result.err()
);
}
#[test]
fn test_F011_brace_vs_parameter_expansion() {
let script = r#"VAR=${VAR:-default}"#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"F011 FALSIFIED: Parser MUST handle parameter expansion with default. Error: {:?}",
result.err()
);
}
#[test]
fn test_F012_arithmetic_expansion() {
let script = r#"result=$((x + y * 2))"#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"F012 FALSIFIED: Parser MUST handle arithmetic expansion. Error: {:?}",
result.err()
);
}
#[test]
fn test_F013_parameter_expansion_modifiers() {
let script = r#"
echo "${var:+set}"
echo "${var:?error message}"
echo "${var:-default}"
echo "${var:=assign}"
"#;
let mut parser = BashParser::new(script).expect("Lexer should succeed");
let result = parser.parse();
assert!(
result.is_ok(),
"F013 FALSIFIED: Parser MUST handle parameter expansion modifiers. Error: {:?}",
result.err()
);
}