#![cfg(any(
not(any(
feature = "parser_tests",
feature = "analyzer_tests",
feature = "codegen_tests",
feature = "interpreter_tests",
feature = "conformance_tests",
feature = "integration_tests",
)),
feature = "analyzer_tests",
))]
#[path = "common/test_utils.rs"]
mod test_utils;
use anyhow::Result;
use std::fs;
use std::process::Command;
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_match_true_false_becomes_matches() -> Result<()> {
let timestamp = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos();
let _tmp = tempfile::tempdir().unwrap();
let temp_dir = _tmp.path().join(format!("wj_matches_test_{}", timestamp));
fs::create_dir_all(&temp_dir)?;
let src_dir = temp_dir.join("src");
fs::create_dir_all(&src_dir)?;
fs::write(
src_dir.join("main.wj"),
r#"
fn is_some(value: Option<i32>) -> bool {
match value {
Some(_) => true,
None => false,
}
}
fn main() {
let opt = Some(42)
let result = is_some(opt)
}
"#,
)?;
fs::write(
temp_dir.join("wj.toml"),
r#"
[package]
name = "matches-test"
version = "0.1.0"
[dependencies]
"#,
)?;
let output_dir = temp_dir.join("src");
let output = Command::new(test_utils::wj_binary())
.args(["build", "--no-cargo"])
.arg(src_dir.to_str().unwrap())
.arg("--output")
.arg(output_dir.to_str().unwrap())
.output()?;
let stderr = String::from_utf8_lossy(&output.stderr);
let stdout = String::from_utf8_lossy(&output.stdout);
let generated = fs::read_to_string(output_dir.join("main.rs")).unwrap_or_else(|_| {
panic!(
"Failed to read generated main.rs\nstdout: {}\nstderr: {}",
stdout, stderr
)
});
assert!(
generated.contains("matches!("),
"Match returning bool should be optimized to matches! macro\nGenerated:\n{}",
generated
);
assert!(
generated.contains("Some(_)"),
"matches! macro should contain the pattern\nGenerated:\n{}",
generated
);
let match_count = generated.matches("match value").count();
let matches_count = generated.matches("matches!(value").count();
assert!(
matches_count > 0 || match_count == 0,
"Simple boolean match should use matches! macro\nGenerated:\n{}",
generated
);
Ok(())
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_match_false_true_becomes_not_matches() -> Result<()> {
let timestamp = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos();
let _tmp2 = tempfile::tempdir().unwrap();
let temp_dir = _tmp2
.path()
.join(format!("wj_not_matches_test_{}", timestamp));
fs::create_dir_all(&temp_dir)?;
let src_dir = temp_dir.join("src");
fs::create_dir_all(&src_dir)?;
fs::write(
src_dir.join("main.wj"),
r#"
fn is_none(value: Option<i32>) -> bool {
match value {
Some(_) => false,
None => true,
}
}
fn main() {
let opt = Some(42)
let result = is_none(opt)
}
"#,
)?;
fs::write(
temp_dir.join("wj.toml"),
r#"
[package]
name = "not-matches-test"
version = "0.1.0"
[dependencies]
"#,
)?;
let output_dir = temp_dir.join("src");
let output = Command::new(test_utils::wj_binary())
.args(["build", "--no-cargo"])
.arg(src_dir.to_str().unwrap())
.arg("--output")
.arg(output_dir.to_str().unwrap())
.output()?;
let stderr = String::from_utf8_lossy(&output.stderr);
let stdout = String::from_utf8_lossy(&output.stdout);
let generated = fs::read_to_string(output_dir.join("main.rs")).unwrap_or_else(|_| {
panic!(
"Failed to read generated main.rs\nstdout: {}\nstderr: {}",
stdout, stderr
)
});
assert!(
(generated.contains("!matches!(") || generated.contains("! matches!("))
&& generated.contains("Some(_)"),
"Inverted match should be optimized to !matches! macro\nGenerated:\n{}",
generated
);
Ok(())
}
#[test]
#[cfg_attr(tarpaulin, ignore)]
fn test_complex_match_not_optimized() -> Result<()> {
let timestamp = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_nanos();
let _tmp3 = tempfile::tempdir().unwrap();
let temp_dir = _tmp3
.path()
.join(format!("wj_complex_match_test_{}", timestamp));
fs::create_dir_all(&temp_dir)?;
let src_dir = temp_dir.join("src");
fs::create_dir_all(&src_dir)?;
fs::write(
src_dir.join("main.wj"),
r#"
fn get_value(opt: Option<i32>) -> i32 {
match opt {
Some(x) => x * 2,
None => 0,
}
}
fn main() {
let opt = Some(42)
let result = get_value(opt)
}
"#,
)?;
fs::write(
temp_dir.join("wj.toml"),
r#"
[package]
name = "complex-match-test"
version = "0.1.0"
[dependencies]
"#,
)?;
let output_dir = temp_dir.join("src");
let output = Command::new(test_utils::wj_binary())
.args(["build", "--no-cargo"])
.arg(src_dir.to_str().unwrap())
.arg("--output")
.arg(output_dir.to_str().unwrap())
.output()?;
let stderr = String::from_utf8_lossy(&output.stderr);
let stdout = String::from_utf8_lossy(&output.stdout);
let generated = fs::read_to_string(output_dir.join("main.rs")).unwrap_or_else(|_| {
panic!(
"Failed to read generated main.rs\nstdout: {}\nstderr: {}",
stdout, stderr
)
});
assert!(
generated.contains("match opt"),
"Complex match should remain as match expression\nGenerated:\n{}",
generated
);
assert!(
!generated.contains("matches!(opt"),
"matches! should only be used for boolean results\nGenerated:\n{}",
generated
);
Ok(())
}