Skip to content

Commit d796559

Browse files
authored
Refactor parser tests into separate modules (#194)
Closes #190 Split parser tests into separate modules to reduce the module sizes.
1 parent 9c334e7 commit d796559

14 files changed

+1539
-1548
lines changed

src/parser/tests.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
use crate::ast::{SourceRange, Statement};
22

33
// Copyright (c) 2020 Ghaith Hachem and Mathias Rieder
4+
mod container_parser_tests;
45
mod control_parser_tests;
56
mod expressions_parser_tests;
7+
mod function_parser_tests;
8+
mod initializer_parser_tests;
9+
mod misc_parser_tests;
610
mod parse_errors;
7-
mod parser_tests;
11+
mod program_parser_tests;
12+
mod statement_parser_tests;
13+
mod type_parser_tests;
14+
mod variable_parser_tests;
815

916
pub fn lex(source: &str) -> crate::lexer::ParseSession {
1017
crate::lexer::lex(source)
+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
use crate::{
2+
parser::{parse, tests::lex},
3+
Diagnostic,
4+
};
5+
use pretty_assertions::*;
6+
7+
#[test]
8+
fn action_container_parsed() {
9+
let lexer = lex("ACTIONS foo ACTION bar END_ACTION END_ACTIONS");
10+
let result = parse(lexer).unwrap().0;
11+
12+
let prg = &result.implementations[0];
13+
assert_eq!(prg.name, "foo.bar");
14+
assert_eq!(prg.type_name, "foo");
15+
}
16+
17+
#[test]
18+
fn two_action_containers_parsed() {
19+
let lexer = lex("ACTIONS foo ACTION bar END_ACTION ACTION buz END_ACTION END_ACTIONS");
20+
let result = parse(lexer).unwrap().0;
21+
22+
let prg = &result.implementations[0];
23+
assert_eq!(prg.name, "foo.bar");
24+
assert_eq!(prg.type_name, "foo");
25+
26+
let prg2 = &result.implementations[1];
27+
assert_eq!(prg2.name, "foo.buz");
28+
assert_eq!(prg2.type_name, "foo");
29+
}
30+
31+
#[test]
32+
fn mixed_action_types_parsed() {
33+
let lexer = lex("PROGRAM foo END_PROGRAM ACTIONS foo ACTION bar END_ACTION END_ACTIONS ACTION foo.buz END_ACTION");
34+
let result = parse(lexer).unwrap().0;
35+
36+
let prg = &result.implementations[1];
37+
assert_eq!(prg.name, "foo.bar");
38+
assert_eq!(prg.type_name, "foo");
39+
40+
let prg2 = &result.implementations[2];
41+
assert_eq!(prg2.name, "foo.buz");
42+
assert_eq!(prg2.type_name, "foo");
43+
}
44+
45+
#[test]
46+
fn actions_with_no_container_error() {
47+
let lexer = lex("ACTIONS ACTION bar END_ACTION ACTION buz END_ACTION END_ACTIONS");
48+
let err = parse(lexer).expect_err("Expecting parser failure");
49+
assert_eq!(
50+
err,
51+
Diagnostic::unexpected_token_found("Identifier".into(), "ACTION".into(), (8..14).into())
52+
);
53+
}
54+
55+
#[test]
56+
fn two_programs_can_be_parsed() {
57+
let lexer = lex("PROGRAM foo END_PROGRAM PROGRAM bar END_PROGRAM");
58+
let result = parse(lexer).unwrap().0;
59+
60+
let prg = &result.units[0];
61+
assert_eq!(prg.name, "foo");
62+
let prg2 = &result.units[1];
63+
assert_eq!(prg2.name, "bar");
64+
}
65+
66+
#[test]
67+
fn simple_program_with_varblock_can_be_parsed() {
68+
let lexer = lex("PROGRAM buz VAR END_VAR END_PROGRAM");
69+
let result = parse(lexer).unwrap().0;
70+
71+
let prg = &result.units[0];
72+
73+
assert_eq!(prg.variable_blocks.len(), 1);
74+
}
75+
76+
#[test]
77+
fn simple_program_with_two_varblocks_can_be_parsed() {
78+
let lexer = lex("PROGRAM buz VAR END_VAR VAR END_VAR END_PROGRAM");
79+
let result = parse(lexer).unwrap().0;
80+
81+
let prg = &result.units[0];
82+
83+
assert_eq!(prg.variable_blocks.len(), 2);
84+
}
85+
86+
#[test]
87+
fn single_action_parsed() {
88+
let lexer = lex("ACTION foo.bar END_ACTION");
89+
let result = parse(lexer).unwrap().0;
90+
91+
let prg = &result.implementations[0];
92+
assert_eq!(prg.name, "foo.bar");
93+
assert_eq!(prg.type_name, "foo");
94+
}
95+
96+
#[test]
97+
fn two_actions_parsed() {
98+
let lexer = lex("ACTION foo.bar END_ACTION ACTION fuz.bar END_ACTION");
99+
let result = parse(lexer).unwrap().0;
100+
101+
let prg = &result.implementations[0];
102+
assert_eq!(prg.name, "foo.bar");
103+
assert_eq!(prg.type_name, "foo");
104+
105+
let prg2 = &result.implementations[1];
106+
assert_eq!(prg2.name, "fuz.bar");
107+
assert_eq!(prg2.type_name, "fuz");
108+
}
+155
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
use crate::{
2+
ast::*,
3+
parser::{parse, tests::lex},
4+
Diagnostic,
5+
};
6+
use pretty_assertions::*;
7+
8+
#[test]
9+
fn simple_foo_function_can_be_parsed() {
10+
let lexer = lex("FUNCTION foo : INT END_FUNCTION");
11+
let result = parse(lexer).unwrap().0;
12+
13+
let prg = &result.units[0];
14+
assert_eq!(prg.pou_type, PouType::Function);
15+
assert_eq!(prg.name, "foo");
16+
assert_eq!(
17+
prg.return_type.as_ref().unwrap(),
18+
&DataTypeDeclaration::DataTypeReference {
19+
referenced_type: "INT".to_string()
20+
}
21+
);
22+
}
23+
24+
#[test]
25+
fn simple_foo_function_block_can_be_parsed() {
26+
let lexer = lex("FUNCTION_BLOCK foo END_FUNCTION_BLOCK");
27+
let result = parse(lexer).unwrap().0;
28+
29+
let prg = &result.units[0];
30+
assert_eq!(prg.pou_type, PouType::FunctionBlock);
31+
assert_eq!(prg.name, "foo");
32+
assert!(prg.return_type.is_none());
33+
}
34+
35+
#[test]
36+
fn a_function_with_varargs_can_be_parsed() {
37+
let lexer = lex("FUNCTION foo : INT VAR_INPUT x : INT; y : ...; END_VAR END_FUNCTION");
38+
let result = parse(lexer).unwrap().0;
39+
40+
let prg = &result.units[0];
41+
let variable_block = &prg.variable_blocks[0];
42+
let ast_string = format!("{:#?}", variable_block);
43+
let expected_ast = r#"VariableBlock {
44+
variables: [
45+
Variable {
46+
name: "x",
47+
data_type: DataTypeReference {
48+
referenced_type: "INT",
49+
},
50+
},
51+
Variable {
52+
name: "y",
53+
data_type: DataTypeDefinition {
54+
data_type: VarArgs {
55+
referenced_type: None,
56+
},
57+
},
58+
},
59+
],
60+
variable_block_type: Input,
61+
}"#;
62+
assert_eq!(ast_string, expected_ast);
63+
}
64+
65+
#[test]
66+
fn a_function_with_typed_varargs_can_be_parsed() {
67+
let lexer = lex("FUNCTION foo : INT VAR_INPUT x : INT; y : INT...; END_VAR END_FUNCTION");
68+
let result = parse(lexer).unwrap().0;
69+
70+
let prg = &result.units[0];
71+
let variable_block = &prg.variable_blocks[0];
72+
let ast_string = format!("{:#?}", variable_block);
73+
let expected_ast = r#"VariableBlock {
74+
variables: [
75+
Variable {
76+
name: "x",
77+
data_type: DataTypeReference {
78+
referenced_type: "INT",
79+
},
80+
},
81+
Variable {
82+
name: "y",
83+
data_type: DataTypeDefinition {
84+
data_type: VarArgs {
85+
referenced_type: Some(
86+
DataTypeReference {
87+
referenced_type: "INT",
88+
},
89+
),
90+
},
91+
},
92+
},
93+
],
94+
variable_block_type: Input,
95+
}"#;
96+
assert_eq!(ast_string, expected_ast);
97+
}
98+
99+
#[test]
100+
fn varargs_parameters_can_be_parsed() {
101+
let lexer = lex("
102+
FUNCTION foo : DINT
103+
VAR_INPUT
104+
args1 : ...;
105+
args2 : INT...;
106+
END_VAR
107+
END_FUNCTION
108+
");
109+
let (parse_result, diagnostics) = parse(lexer).unwrap();
110+
111+
assert_eq!(
112+
format!("{:#?}", diagnostics),
113+
format!("{:#?}", Vec::<Diagnostic>::new()).as_str()
114+
);
115+
116+
let x = &parse_result.units[0];
117+
let expected = Pou {
118+
name: "foo".into(),
119+
pou_type: PouType::Function,
120+
return_type: Some(DataTypeDeclaration::DataTypeReference {
121+
referenced_type: "DINT".into(),
122+
}),
123+
variable_blocks: vec![VariableBlock {
124+
variable_block_type: VariableBlockType::Input,
125+
variables: vec![
126+
Variable {
127+
name: "args1".into(),
128+
data_type: DataTypeDeclaration::DataTypeDefinition {
129+
data_type: DataType::VarArgs {
130+
referenced_type: None,
131+
},
132+
},
133+
initializer: None,
134+
location: SourceRange::undefined(),
135+
},
136+
Variable {
137+
name: "args2".into(),
138+
data_type: DataTypeDeclaration::DataTypeDefinition {
139+
data_type: DataType::VarArgs {
140+
referenced_type: Some(Box::new(
141+
DataTypeDeclaration::DataTypeReference {
142+
referenced_type: "INT".into(),
143+
},
144+
)),
145+
},
146+
},
147+
initializer: None,
148+
location: SourceRange::undefined(),
149+
},
150+
],
151+
}],
152+
location: SourceRange::undefined(),
153+
};
154+
assert_eq!(format!("{:#?}", expected), format!("{:#?}", x).as_str());
155+
}

0 commit comments

Comments
 (0)