use vb6parse::parsers::cst::ConcreteSyntaxTree;
const SNAPSHOT_PATH: &str = "../../snapshots/parsers/cst/invalid_syntax/missing_end";
#[test]
fn missing_end_sub() {
let source = r"
Sub TestSub()
Dim x As Integer
x = 10
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be present even with syntax errors");
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!("missing_end_sub_cst", tree);
insta::assert_yaml_snapshot!(
"missing_end_sub_failures",
failures
.iter()
.map(|f| format!("{f:?}"))
.collect::<Vec<_>>()
);
}
#[test]
fn missing_end_sub_before_next_sub() {
let source = r#"
Sub FirstSub()
Dim x As Integer
x = 10
Public Sub SecondSub()
MsgBox "ok"
End Sub
"#;
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be present even with syntax errors");
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!("missing_end_sub_before_next_sub_cst", tree);
insta::assert_yaml_snapshot!(
"missing_end_sub_before_next_sub_failures",
failures
.iter()
.map(|f| format!("{f:?}"))
.collect::<Vec<_>>()
);
}
#[test]
fn missing_end_function() {
let source = r"
Function Calculate(x As Integer) As Integer
Calculate = x * 2
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be present even with syntax errors");
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!("missing_end_function_cst", tree);
insta::assert_yaml_snapshot!(
"missing_end_function_failures",
failures
.iter()
.map(|f| format!("{f:?}"))
.collect::<Vec<_>>()
);
}
#[test]
fn missing_end_function_before_next_function() {
let source = r"
Function FirstFunction(x As Integer) As Integer
FirstFunction = x * 2
Public Function SecondFunction(y As Integer) As Integer
SecondFunction = y + 1
End Function
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be present even with syntax errors");
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!("missing_end_function_before_next_function_cst", tree);
insta::assert_yaml_snapshot!(
"missing_end_function_before_next_function_failures",
failures
.iter()
.map(|f| format!("{f:?}"))
.collect::<Vec<_>>()
);
}
#[test]
fn missing_end_property() {
let source = r"
Property Get Name() As String
Name = m_name
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be present even with syntax errors");
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!("missing_end_property_cst", tree);
insta::assert_yaml_snapshot!(
"missing_end_property_failures",
failures
.iter()
.map(|f| format!("{f:?}"))
.collect::<Vec<_>>()
);
}
#[test]
fn missing_end_property_before_next_property() {
let source = r"
Property Get Name() As String
Name = m_name
Property Let Name(ByVal value As String)
m_name = value
End Property
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be present even with syntax errors");
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!("missing_end_property_before_next_property_cst", tree);
insta::assert_yaml_snapshot!(
"missing_end_property_before_next_property_failures",
failures
.iter()
.map(|f| format!("{f:?}"))
.collect::<Vec<_>>()
);
}
#[test]
fn missing_end_if() {
let source = r"
Sub Test()
If x > 0 Then
Debug.Print x
End Sub
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be present even with syntax errors");
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!("missing_end_if_cst", tree);
insta::assert_yaml_snapshot!(
"missing_end_if_failures",
failures
.iter()
.map(|f| format!("{f:?}"))
.collect::<Vec<_>>()
);
}
#[test]
fn missing_end_type() {
let source = r"
Type Point
X As Long
Y As Long
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be present even with syntax errors");
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!("missing_end_type_cst", tree);
insta::assert_yaml_snapshot!(
"missing_end_type_failures",
failures
.iter()
.map(|f| format!("{f:?}"))
.collect::<Vec<_>>()
);
}
#[test]
fn missing_end_type_before_next_type() {
let source = r"
Type Point
X As Long
Y As Long
Type Size
Width As Long
Height As Long
End Type
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be present even with syntax errors");
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!("missing_end_type_before_next_type_cst", tree);
insta::assert_yaml_snapshot!(
"missing_end_type_before_next_type_failures",
failures
.iter()
.map(|f| format!("{f:?}"))
.collect::<Vec<_>>()
);
}
#[test]
fn missing_end_type_before_next_sub() {
let source = r"
Type Point
X As Long
Y As Long
Sub Test()
Debug.Print 1
End Sub
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be present even with syntax errors");
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!("missing_end_type_before_next_sub_cst", tree);
insta::assert_yaml_snapshot!(
"missing_end_type_before_next_sub_failures",
failures
.iter()
.map(|f| format!("{f:?}"))
.collect::<Vec<_>>()
);
}
#[test]
fn missing_end_type_before_next_function() {
let source = r"
Type Point
X As Long
Y As Long
Function GetValue() As Long
GetValue = 1
End Function
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be present even with syntax errors");
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!("missing_end_type_before_next_function_cst", tree);
insta::assert_yaml_snapshot!(
"missing_end_type_before_next_function_failures",
failures
.iter()
.map(|f| format!("{f:?}"))
.collect::<Vec<_>>()
);
}
#[test]
fn missing_end_sub_before_next_type() {
let source = r"
Sub Test()
Dim x As Long
x = 1
Type Point
X As Long
Y As Long
End Type
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be present even with syntax errors");
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!("missing_end_sub_before_next_type_cst", tree);
insta::assert_yaml_snapshot!(
"missing_end_sub_before_next_type_failures",
failures
.iter()
.map(|f| format!("{f:?}"))
.collect::<Vec<_>>()
);
}
#[test]
fn missing_end_function_before_next_type() {
let source = r"
Function GetValue() As Long
GetValue = 1
Type Point
X As Long
Y As Long
End Type
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be present even with syntax errors");
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!("missing_end_function_before_next_type_cst", tree);
insta::assert_yaml_snapshot!(
"missing_end_function_before_next_type_failures",
failures
.iter()
.map(|f| format!("{f:?}"))
.collect::<Vec<_>>()
);
}
#[test]
fn missing_end_select() {
let source = r#"
Sub Test()
Select Case x
Case 1
Debug.Print "One"
Case 2
Debug.Print "Two"
End Sub
"#;
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be present even with syntax errors");
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!("missing_end_select_cst", tree);
insta::assert_yaml_snapshot!(
"missing_end_select_failures",
failures
.iter()
.map(|f| format!("{f:?}"))
.collect::<Vec<_>>()
);
}
#[test]
fn nested_missing_ends() {
let source = r"
Sub Test()
If x > 0 Then
For i = 1 To 10
Debug.Print i
' Missing Next, End If, and End Sub
";
let (cst_opt, failures) = ConcreteSyntaxTree::from_text("test.bas", source).unpack();
let cst = cst_opt.expect("CST should be present even with syntax errors");
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!("nested_missing_ends_cst", tree);
insta::assert_yaml_snapshot!(
"nested_missing_ends_failures",
failures
.iter()
.map(|f| format!("{f:?}"))
.collect::<Vec<_>>()
);
}