#![allow(clippy::expect_used)]
use super::ast::*;
use super::codegen::*;
#[test]
fn test_codegen_001_shebang_transformation() {
let ast = BashAst {
statements: vec![],
metadata: AstMetadata {
source_file: None,
line_count: 0,
parse_time_ms: 0,
},
};
let output = generate_purified_bash(&ast);
assert!(
output.starts_with("#!/bin/sh\n"),
"Should emit POSIX sh shebang"
);
}
#[test]
fn test_codegen_002_simple_command() {
let ast = BashAst {
statements: vec![BashStmt::Command {
name: "echo".to_string(),
args: vec![BashExpr::Literal("hello".to_string())],
redirects: vec![],
span: Span::new(1, 1, 1, 10),
}],
metadata: AstMetadata {
source_file: None,
line_count: 1,
parse_time_ms: 0,
},
};
let output = generate_purified_bash(&ast);
assert!(
output.contains("echo hello"),
"Should generate echo command"
);
assert!(output.starts_with("#!/bin/sh\n"), "Should have shebang");
}
#[test]
fn test_codegen_003_assignment_not_exported() {
let ast = BashAst {
statements: vec![BashStmt::Assignment {
name: "VAR".to_string(),
index: None,
value: BashExpr::Literal("value".to_string()),
exported: false,
span: Span::new(1, 1, 1, 10),
}],
metadata: AstMetadata {
source_file: None,
line_count: 1,
parse_time_ms: 0,
},
};
let output = generate_purified_bash(&ast);
assert!(output.contains("VAR=value"), "Should generate assignment");
assert!(!output.contains("export"), "Should not have export keyword");
}
#[test]
fn test_codegen_004_assignment_exported() {
let ast = BashAst {
statements: vec![BashStmt::Assignment {
name: "VAR".to_string(),
index: None,
value: BashExpr::Literal("value".to_string()),
exported: true,
span: Span::new(1, 1, 1, 10),
}],
metadata: AstMetadata {
source_file: None,
line_count: 1,
parse_time_ms: 0,
},
};
let output = generate_purified_bash(&ast);
assert!(
output.contains("export VAR=value"),
"Should generate exported assignment"
);
}
#[test]
fn test_codegen_005_comment_preserved() {
let ast = BashAst {
statements: vec![BashStmt::Comment {
text: "This is a comment".to_string(),
span: Span::new(1, 1, 1, 20),
}],
metadata: AstMetadata {
source_file: None,
line_count: 1,
parse_time_ms: 0,
},
};
let output = generate_purified_bash(&ast);
assert!(
output.contains("# This is a comment"),
"Should preserve comment"
);
}
#[test]
fn test_codegen_006_shebang_comment_skipped() {
let ast = BashAst {
statements: vec![BashStmt::Comment {
text: "!/bin/bash".to_string(),
span: Span::new(1, 1, 1, 12),
}],
metadata: AstMetadata {
source_file: None,
line_count: 1,
parse_time_ms: 0,
},
};
let output = generate_purified_bash(&ast);
assert_eq!(
output.lines().count(),
2,
"Should have shebang + empty line"
);
assert!(output.starts_with("#!/bin/sh\n"));
}
#[test]
include!("codegen_tests_tests_codegen_2.rs");