use crate::spec::{expect_parse_failure, expect_parse_success, expect_success};
mod missing_keywords {
use super::*;
#[test]
fn mls_2_3_3_keyword_elsewhen() {
expect_parse_failure("model Test Real elsewhen; end Test;");
}
#[test]
fn mls_2_3_3_keyword_expandable() {
expect_parse_failure("model Test Real expandable; end Test;");
}
#[test]
fn mls_2_3_3_elsewhen_valid_usage() {
expect_success(
r#"
model Test
Real x(start = 0);
discrete Integer state(start = 0);
equation
der(x) = 1;
when x > 1 then
state = 1;
elsewhen x > 2 then
state = 2;
end when;
end Test;
"#,
"Test",
);
}
#[test]
fn mls_2_3_3_keyword_operator_used() {
expect_parse_failure("model Test Real operator; end Test;");
}
}
mod qident_escapes {
use super::*;
#[test]
#[ignore = "Q-IDENT backslash escape not yet supported"]
fn mls_2_3_1_qident_backslash() {
expect_parse_success("model Test Real 'path\\\\file'; end Test;");
}
#[test]
#[ignore = "Q-IDENT single quote escape not yet supported"]
fn mls_2_3_1_qident_single_quote_escape() {
expect_parse_success("model Test Real 'it\\'s'; end Test;");
}
#[test]
#[ignore = "Q-IDENT newline escape not yet supported"]
fn mls_2_3_1_qident_newline_escape() {
expect_parse_success("model Test Real 'line1\\nline2'; end Test;");
}
#[test]
fn mls_2_3_1_qident_special_chars() {
expect_parse_success("model Test Real 'a.b.c'; end Test;");
}
#[test]
fn mls_2_3_1_qident_digit_start() {
expect_parse_success("model Test Real '123var'; end Test;");
}
#[test]
fn mls_2_3_1_qident_spaces() {
expect_parse_success("model Test Real 'my variable name'; end Test;");
}
#[test]
fn mls_2_3_1_qident_keyword_inside() {
expect_parse_success("model Test Real 'model value'; end Test;");
}
}
mod string_escapes {
use super::*;
#[test]
fn mls_2_4_4_string_escape_alert() {
expect_success(
r#"model Test constant String s = "bell\a"; end Test;"#,
"Test",
);
}
#[test]
fn mls_2_4_4_string_escape_backspace() {
expect_success(
r#"model Test constant String s = "back\bspace"; end Test;"#,
"Test",
);
}
#[test]
fn mls_2_4_4_string_escape_formfeed() {
expect_success(
r#"model Test constant String s = "form\ffeed"; end Test;"#,
"Test",
);
}
#[test]
fn mls_2_4_4_string_escape_vtab() {
expect_success(
r#"model Test constant String s = "vertical\vtab"; end Test;"#,
"Test",
);
}
#[test]
fn mls_2_4_4_string_escape_question() {
expect_success(
r#"model Test constant String s = "what\?"; end Test;"#,
"Test",
);
}
#[test]
fn mls_2_4_4_string_escape_hex() {
expect_success(
r#"model Test constant String s = "hex\x41"; end Test;"#,
"Test",
);
}
#[test]
fn mls_2_4_4_string_escape_octal() {
expect_success(
r#"model Test constant String s = "octal\101"; end Test;"#,
"Test",
);
}
#[test]
fn mls_2_4_4_string_escape_common() {
expect_success(
r#"model Test
constant String s1 = "line1\nline2";
constant String s2 = "tab\there";
constant String s3 = "quote\"here";
constant String s4 = "back\\slash";
end Test;"#,
"Test",
);
}
}
mod unicode_handling {
use super::*;
#[test]
#[ignore = "Unicode identifiers not yet supported"]
fn mls_2_1_unicode_identifier() {
expect_parse_success("model Test Real α; end Test;");
}
#[test]
fn mls_2_1_unicode_in_string() {
expect_success(
r#"model Test constant String s = "Temperature: 25°C"; end Test;"#,
"Test",
);
}
#[test]
#[ignore = "Unicode Greek letter identifiers not yet supported"]
fn mls_2_1_unicode_greek() {
expect_parse_success("model Test Real Δx; Real θ; end Test;");
}
#[test]
#[ignore = "Unicode subscript/superscript identifiers not yet supported"]
fn mls_2_1_unicode_subscript() {
expect_parse_success("model Test Real x₁; Real x₂; end Test;");
}
}
mod comment_handling {
use super::*;
#[test]
fn mls_2_2_nested_comment_rejected() {
expect_parse_failure(
r#"
model Test
/* outer /* inner */ still in comment */
Real x;
end Test;
"#,
);
}
#[test]
fn mls_2_2_comment_text_with_slashes() {
expect_parse_success(
r#"
model Test
// URL: http://example.com
Real x;
end Test;
"#,
);
}
#[test]
fn mls_2_2_multiline_with_stars() {
expect_parse_success(
r#"
model Test
/*********************
* Documentation block
*********************/
Real x;
end Test;
"#,
);
}
}
mod literal_edge_cases {
use super::*;
#[test]
fn mls_2_4_large_integer() {
expect_success(
"model Test constant Integer n = 9223372036854775807; end Test;",
"Test",
);
}
#[test]
fn mls_2_4_very_small_real() {
expect_success("model Test constant Real x = 1e-308; end Test;", "Test");
}
#[test]
fn mls_2_4_very_large_real() {
expect_success("model Test constant Real x = 1e308; end Test;", "Test");
}
#[test]
fn mls_2_4_real_dot_start() {
expect_success("model Test constant Real x = .5; end Test;", "Test");
}
#[test]
fn mls_2_4_real_dot_end() {
expect_success("model Test constant Real x = 5.; end Test;", "Test");
}
#[test]
fn mls_2_4_integer_leading_zeros() {
expect_success("model Test constant Integer n = 007; end Test;", "Test");
}
#[test]
fn mls_2_4_empty_string() {
expect_success(r#"model Test constant String s = ""; end Test;"#, "Test");
}
#[test]
fn mls_2_4_whitespace_string() {
expect_success(r#"model Test constant String s = " "; end Test;"#, "Test");
}
}