use crate::spec::{expect_failure, expect_parse_success, expect_success};
mod operator_record_syntax {
use super::*;
#[test]
fn mls_14_1_operator_record_basic() {
expect_parse_success(
r#"
operator record Complex
Real re;
Real im;
end Complex;
"#,
);
}
#[test]
fn mls_14_1_operator_record_constructor() {
expect_parse_success(
r#"
operator record Complex
Real re;
Real im;
encapsulated operator 'constructor'
function fromReal
input Real re;
input Real im = 0;
output Complex result;
algorithm
result.re := re;
result.im := im;
end fromReal;
end 'constructor';
end Complex;
"#,
);
}
#[test]
fn mls_14_1_regular_record() {
expect_success(
r#"
record Point
Real x;
Real y;
end Point;
model Test
Point p(x = 1, y = 2);
equation
end Test;
"#,
"Test",
);
}
}
mod operator_definitions {
use super::*;
#[test]
fn mls_14_2_operator_add() {
expect_parse_success(
r#"
operator record Complex
Real re;
Real im;
encapsulated operator '+'
function add
input Complex c1;
input Complex c2;
output Complex result;
algorithm
result.re := c1.re + c2.re;
result.im := c1.im + c2.im;
end add;
end '+';
end Complex;
"#,
);
}
#[test]
fn mls_14_2_operator_unary_minus() {
expect_parse_success(
r#"
operator record Complex
Real re;
Real im;
encapsulated operator '-'
function negate
input Complex c;
output Complex result;
algorithm
result.re := -c.re;
result.im := -c.im;
end negate;
end '-';
end Complex;
"#,
);
}
#[test]
fn mls_14_2_operator_multiply() {
expect_parse_success(
r#"
operator record Complex
Real re;
Real im;
encapsulated operator '*'
function multiply
input Complex c1;
input Complex c2;
output Complex result;
algorithm
result.re := c1.re * c2.re - c1.im * c2.im;
result.im := c1.re * c2.im + c1.im * c2.re;
end multiply;
end '*';
end Complex;
"#,
);
}
#[test]
fn mls_14_2_operator_zero() {
expect_parse_success(
r#"
operator record Complex
Real re;
Real im;
encapsulated operator '0'
function zero
output Complex result;
algorithm
result.re := 0;
result.im := 0;
end zero;
end '0';
end Complex;
"#,
);
}
#[test]
fn mls_14_2_operator_string() {
expect_parse_success(
r#"
operator record Complex
Real re;
Real im;
encapsulated operator 'String'
function toString
input Complex c;
output String s;
algorithm
s := String(c.re) + " + " + String(c.im) + "i";
end toString;
end 'String';
end Complex;
"#,
);
}
}
mod operator_restrictions {
use super::*;
#[test]
fn mls_14_3_operator_must_be_encapsulated() {
expect_failure(
r#"
operator record Complex
Real re;
Real im;
operator '+'
function add
input Complex c1;
input Complex c2;
output Complex result;
algorithm
result.re := c1.re + c2.re;
result.im := c1.im + c2.im;
end add;
end '+';
end Complex;
"#,
"Complex",
);
}
#[test]
#[ignore = "operator record extends restriction not yet implemented"]
fn mls_14_3_operator_record_no_extends() {
expect_failure(
r#"
operator record Base
Real x;
end Base;
operator record Derived
extends Base;
Real y;
end Derived;
"#,
"Derived",
);
}
#[test]
#[ignore = "operator record partial restriction not yet implemented"]
fn mls_14_3_operator_record_no_partial() {
expect_failure(
r#"
partial operator record BadComplex
Real re;
Real im;
end BadComplex;
"#,
"BadComplex",
);
}
}
mod relational_operators {
use super::*;
#[test]
fn mls_14_5_operator_equal() {
expect_parse_success(
r#"
operator record Complex
Real re;
Real im;
encapsulated operator '=='
function isEqual
input Complex c1;
input Complex c2;
output Boolean result;
algorithm
result := c1.re == c2.re and c1.im == c2.im;
end isEqual;
end '==';
end Complex;
"#,
);
}
#[test]
fn mls_14_5_operator_not_equal() {
expect_parse_success(
r#"
operator record Complex
Real re;
Real im;
encapsulated operator '<>'
function isNotEqual
input Complex c1;
input Complex c2;
output Boolean result;
algorithm
result := c1.re <> c2.re or c1.im <> c2.im;
end isNotEqual;
end '<>';
end Complex;
"#,
);
}
}
mod numeric_operations {
use super::*;
#[test]
fn mls_14_4_operator_divide() {
expect_parse_success(
r#"
operator record Complex
Real re;
Real im;
encapsulated operator '/'
function divide
input Complex c1;
input Complex c2;
output Complex result;
protected
Real denom;
algorithm
denom := c2.re^2 + c2.im^2;
result.re := (c1.re*c2.re + c1.im*c2.im) / denom;
result.im := (c1.im*c2.re - c1.re*c2.im) / denom;
end divide;
end '/';
end Complex;
"#,
);
}
#[test]
fn mls_14_4_operator_power() {
expect_parse_success(
r#"
operator record Complex
Real re;
Real im;
encapsulated operator '^'
function power
input Complex c;
input Integer n;
output Complex result;
algorithm
result.re := c.re;
result.im := c.im;
end power;
end '^';
end Complex;
"#,
);
}
}