use super::super::super::*;
#[test]
fn rewrite_switch_statements_flattens_else_blocks_with_nested_chains() {
let mut statements = vec![
"if loc0 == 0 {".to_string(),
" do0;".to_string(),
"}".to_string(),
"else {".to_string(),
" if loc0 == 1 {".to_string(),
" do1;".to_string(),
" }".to_string(),
" else {".to_string(),
" do2;".to_string(),
" }".to_string(),
"}".to_string(),
];
HighLevelEmitter::rewrite_switch_statements(&mut statements);
assert_eq!(statements[0], "switch loc0 {");
assert!(statements.iter().any(|line| line.trim() == "case 0 {"));
assert!(statements.iter().any(|line| line.trim() == "case 1 {"));
assert!(statements.iter().any(|line| line.trim() == "default {"));
}
#[test]
fn rewrite_switch_statements_skips_duplicate_cases() {
let mut statements = vec![
"if loc0 == 0 {".to_string(),
" do0;".to_string(),
"}".to_string(),
"else if loc0 == 0 {".to_string(),
" do1;".to_string(),
"}".to_string(),
"else {".to_string(),
" do2;".to_string(),
"}".to_string(),
];
HighLevelEmitter::rewrite_switch_statements(&mut statements);
assert_eq!(statements[0], "if loc0 == 0 {");
assert!(!statements
.iter()
.any(|line| line.trim_start().starts_with("switch ")));
}
#[test]
fn rewrite_switch_statements_skips_non_literal_cases() {
let mut statements = vec![
"if loc0 == loc1 {".to_string(),
" do0;".to_string(),
"}".to_string(),
"else if loc0 == 1 {".to_string(),
" do1;".to_string(),
"}".to_string(),
"else {".to_string(),
" do2;".to_string(),
"}".to_string(),
];
HighLevelEmitter::rewrite_switch_statements(&mut statements);
assert_eq!(statements[0], "if loc0 == loc1 {");
assert!(!statements
.iter()
.any(|line| line.trim_start().starts_with("switch ")));
}
#[test]
fn rewrite_switch_statements_collapses_consecutive_standalone_ifs() {
let mut statements = vec![
"if loc0 == 0 {".to_string(),
" do0;".to_string(),
"}".to_string(),
"if loc0 == 1 {".to_string(),
" do1;".to_string(),
"}".to_string(),
"if loc0 == 2 {".to_string(),
" do2;".to_string(),
"}".to_string(),
];
HighLevelEmitter::rewrite_switch_statements(&mut statements);
assert_eq!(statements[0], "switch loc0 {");
assert!(statements.iter().any(|line| line.trim() == "case 0 {"));
assert!(statements.iter().any(|line| line.trim() == "case 1 {"));
assert!(statements.iter().any(|line| line.trim() == "case 2 {"));
assert!(statements.iter().any(|line| line.trim() == "do0;"));
assert!(statements.iter().any(|line| line.trim() == "do1;"));
assert!(statements.iter().any(|line| line.trim() == "do2;"));
}
#[test]
fn rewrite_switch_statements_skips_two_consecutive_standalone_ifs() {
let mut statements = vec![
"if loc0 == 0 {".to_string(),
" do0;".to_string(),
"}".to_string(),
"if loc0 == 1 {".to_string(),
" do1;".to_string(),
"}".to_string(),
];
HighLevelEmitter::rewrite_switch_statements(&mut statements);
assert_eq!(statements[0], "if loc0 == 0 {");
assert!(!statements
.iter()
.any(|line| line.trim_start().starts_with("switch ")));
}
#[test]
fn rewrite_switch_statements_skips_consecutive_ifs_with_different_scrutinee() {
let mut statements = vec![
"if loc0 == 0 {".to_string(),
" do0;".to_string(),
"}".to_string(),
"if loc1 == 1 {".to_string(),
" do1;".to_string(),
"}".to_string(),
"if loc0 == 2 {".to_string(),
" do2;".to_string(),
"}".to_string(),
];
HighLevelEmitter::rewrite_switch_statements(&mut statements);
assert_eq!(statements[0], "if loc0 == 0 {");
assert!(!statements
.iter()
.any(|line| line.trim_start().starts_with("switch ")));
}
#[test]
fn rewrite_switch_keeps_if_chain_when_case_body_reassigns_scrutinee() {
let mut statements = vec![
"if loc0 == 0 {".to_string(),
" loc0 = 1;".to_string(),
" do0;".to_string(),
"}".to_string(),
"if loc0 == 1 {".to_string(),
" do1;".to_string(),
"}".to_string(),
"if loc0 == 2 {".to_string(),
" do2;".to_string(),
"}".to_string(),
];
let original = statements.clone();
HighLevelEmitter::rewrite_switch_statements(&mut statements);
assert_eq!(
statements, original,
"scrutinee-mutating if-chain must not be rewritten to a switch"
);
}
#[test]
fn rewrite_switch_folds_standalone_ifs_when_bodies_terminate() {
let mut statements = vec![
"if loc0 == 0 {".to_string(),
" return 0;".to_string(),
"}".to_string(),
"if loc0 == 1 {".to_string(),
" return 1;".to_string(),
"}".to_string(),
"if loc0 == 2 {".to_string(),
" return 2;".to_string(),
"}".to_string(),
];
HighLevelEmitter::rewrite_switch_statements(&mut statements);
assert!(
statements.iter().any(|line| line.trim() == "switch loc0 {"),
"terminator-ending standalone ifs should fold into a switch: {statements:?}"
);
}