#![allow(missing_docs)]
use ruchy::frontend::parser::Parser;
fn parse_code(code: &str) -> anyhow::Result<()> {
let mut parser = Parser::new(code);
parser.parse()?;
Ok(())
}
#[test]
fn test_enum_variant_ok_alone_in_function() {
let code = r"
fn main() {
enum HttpStatus {
Ok = 200
}
}
";
let result = parse_code(code);
assert!(
result.is_ok(),
"Should parse enum alone in function, but got: {:?}",
result.err()
);
}
#[test]
fn test_enum_variant_ok_with_enum_reference() {
let code = r"
fn main() {
enum HttpStatus {
Ok = 200
}
let x = HttpStatus::Ok
}
";
let result = parse_code(code);
assert!(
result.is_ok(),
"Should parse enum with variant reference, but got: {:?}",
result.err()
);
}
#[test]
fn test_enum_normal_variant_with_reference() {
let code = r"
fn main() {
enum Test {
A = 1
}
let x = Test::A
}
";
let result = parse_code(code);
assert!(
result.is_ok(),
"Should parse enum with normal variant reference, but got: {:?}",
result.err()
);
}
#[test]
fn test_enum_variant_ok_with_statement_before() {
let code = r"
fn main() {
let x = 1
enum HttpStatus {
Ok = 200
}
}
";
let result = parse_code(code);
assert!(
result.is_ok(),
"Should parse enum with statement before, but got: {:?}",
result.err()
);
}
#[test]
fn test_enum_variant_err_inside_function() {
let code = r"
fn main() {
enum Status {
Err = 500
}
let x = Status::Err
}
";
let result = parse_code(code);
assert!(
result.is_ok(),
"Should parse enum with 'Err' variant inside function, but got: {:?}",
result.err()
);
}
#[test]
fn test_enum_variant_some_inside_function() {
let code = r"
fn main() {
enum Optional {
Some = 1,
None = 0
}
let x = Optional::Some
}
";
let result = parse_code(code);
assert!(
result.is_ok(),
"Should parse enum with 'Some'/'None' variants inside function, but got: {:?}",
result.err()
);
}
#[test]
fn test_enum_all_reserved_variants() {
let code = r"
fn main() {
enum AllReserved {
Ok = 1,
Err = 2,
Some = 3,
None = 4
}
let a = AllReserved::Ok
let b = AllReserved::Err
let c = AllReserved::Some
let d = AllReserved::None
}
";
let result = parse_code(code);
assert!(
result.is_ok(),
"Should parse enum with all reserved keywords as variants, but got: {:?}",
result.err()
);
}
#[test]
fn test_example_file_04_enum_discriminants() {
let code = std::fs::read_to_string("examples/lang_comp/15-enums/04_enum_discriminants.ruchy")
.expect("Failed to read example file");
let result = parse_code(&code);
assert!(
result.is_ok(),
"Should parse 04_enum_discriminants.ruchy, but got: {:?}",
result.err()
);
}
#[cfg(test)]
mod property_tests {
use super::*;
use proptest::prelude::*;
const RESERVED_KEYWORDS: &[&str] = &["Ok", "Err", "Some", "None"];
proptest! {
#![proptest_config(ProptestConfig::with_cases(10000))]
#[test]
fn prop_reserved_keywords_as_variants_never_panic(
keyword_idx in 0..RESERVED_KEYWORDS.len(),
discriminant in 1i64..1000i64
) {
let keyword = RESERVED_KEYWORDS[keyword_idx];
let code = format!(
"fn main() {{\n enum Test {{\n {keyword} = {discriminant}\n }}\n let x = Test::{keyword}\n}}"
);
let _ = parse_code(&code);
}
#[test]
fn prop_enum_inside_function_parses(
keyword_idx in 0..RESERVED_KEYWORDS.len()
) {
let keyword = RESERVED_KEYWORDS[keyword_idx];
let code = format!(
"fn main() {{\n enum Status {{\n {keyword}\n }}\n let x = Status::{keyword}\n}}"
);
let result = parse_code(&code);
prop_assert!(
result.is_ok(),
"Reserved keyword '{}' should parse as variant, got: {:?}",
keyword,
result.err()
);
}
#[test]
fn prop_multiple_reserved_keywords_in_enum(
count in 1..=4usize
) {
let keywords: Vec<&str> = RESERVED_KEYWORDS.iter().take(count).copied().collect();
let variants: Vec<String> = keywords
.iter()
.enumerate()
.map(|(i, kw)| format!("{} = {}", kw, i + 1))
.collect();
let code = format!(
"fn main() {{\n enum Test {{\n {}\n }}\n let x = Test::{}\n}}",
variants.join(",\n "),
keywords[0]
);
let result = parse_code(&code);
prop_assert!(
result.is_ok(),
"Enum with {} reserved keywords should parse, got: {:?}",
count,
result.err()
);
}
}
}