const SNAPSHOT_PATH: &str = "../../../snapshots/parsers/cst/library/financial/rate";
use vb6parse::ConcreteSyntaxTree;
#[test]
fn rate_basic() {
let source = r"
Dim interestRate As Double
interestRate = Rate(60, -200, 10000)
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_with_all_parameters() {
let source = r"
Dim rate As Double
rate = Rate(48, -250, 10000, 0, 0, 0.08)
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_if_statement() {
let source = r#"
If Rate(nper, pmt, pv) > 0.06 Then
MsgBox "Rate is above 6%"
End If
"#;
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_function_return() {
let source = r"
Function CalculateAPR(loan As Double, payment As Double) As Double
Dim monthlyRate As Double
monthlyRate = Rate(60, -payment, loan)
CalculateAPR = monthlyRate * 12
End Function
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_variable_assignment() {
let source = r"
Dim monthlyRate As Double
monthlyRate = Rate(months, payment, principal)
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_msgbox() {
let source = r#"
MsgBox "APR: " & Format(Rate(60, -500, 20000) * 12 * 100, "0.00") & "%"
"#;
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_debug_print() {
let source = r#"
Debug.Print "Monthly Rate: " & Rate(n, p, pv)
"#;
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_select_case() {
let source = r#"
Dim apr As Double
apr = Rate(months, -payment, loan) * 12
Select Case apr
Case Is > 0.1
category = "High"
Case Is > 0.05
category = "Medium"
Case Else
category = "Low"
End Select
"#;
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_class_usage() {
let source = r"
Private m_rate As Double
Public Sub Calculate()
m_rate = Rate(m_nper, m_pmt, m_pv)
End Sub
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_with_statement() {
let source = r"
With loanCalc
.InterestRate = Rate(.NumPayments, .Payment, .Principal)
End With
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_elseif() {
let source = r"
If amount > 100000 Then
r = 0.05
ElseIf Rate(60, -pmt, loan) > 0.08 Then
r = 0.06
End If
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_for_loop() {
let source = r"
For payment = 100 To 500 Step 50
r = Rate(60, -payment, 10000)
Debug.Print payment, r * 12
Next payment
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_do_while() {
let source = r"
Do While Rate(nper, -pmt, pv) < targetRate
pmt = pmt + 10
Loop
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_do_until() {
let source = r"
Do Until Rate(n, -p, amount) >= minRate
amount = amount - 100
Loop
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_while_wend() {
let source = r"
While Rate(periods, payment, principal) > 0
principal = principal + 1000
Wend
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_parentheses() {
let source = r"
Dim result As Double
result = (Rate(nper, pmt, pv))
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_iif() {
let source = r"
Dim annualRate As Double
annualRate = IIf(useGuess, Rate(n, p, pv, fv, t, g), Rate(n, p, pv))
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_comparison() {
let source = r#"
If Rate(60, -200, 10000) > Rate(48, -250, 10000) Then
MsgBox "First loan has higher rate"
End If
"#;
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_array_assignment() {
let source = r"
Dim rates(10) As Double
rates(i) = Rate(periods(i), payments(i), principals(i))
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_property_assignment() {
let source = r"
Set obj = New LoanAnalyzer
obj.InterestRate = Rate(obj.Term, obj.Payment, obj.Principal)
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_function_argument() {
let source = r"
Call AnalyzeLoan(Rate(60, -payment, principal) * 12, loanAmount)
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_arithmetic() {
let source = r"
Dim apr As Double
apr = Rate(months, -pmt, pv) * 12 * 100
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_concatenation() {
let source = r#"
Dim msg As String
msg = "APR is: " & Format(Rate(n, p, pv) * 12, "0.00%")
"#;
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_format_function() {
let source = r#"
Dim display As String
display = Format(Rate(60, -500, 20000) * 12 * 100, "0.00")
"#;
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_error_handling() {
let source = r#"
On Error Resume Next
interestRate = Rate(nper, pmt, pv, fv, type, guess)
If Err.Number <> 0 Then
MsgBox "Error calculating rate"
End If
On Error GoTo 0
"#;
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}
#[test]
fn rate_on_error_goto() {
let source = r#"
Sub CalculateRate()
On Error GoTo ErrorHandler
Dim r As Double
r = Rate(numMonths, monthlyPayment, loanAmount)
Exit Sub
ErrorHandler:
MsgBox "Error in rate calculation"
End Sub
"#;
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
assert_eq!(failures.len(), 0, "Expected no parse failures.");
let cst = cst_opt.expect("CST should be parsed");
let tree = cst.to_serializable();
let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path(SNAPSHOT_PATH);
settings.set_prepend_module_to_snapshot(false);
let _guard = settings.bind_to_scope();
insta::assert_yaml_snapshot!(tree);
}