1
use conjure_cp_essence_parser::diagnostics::error_detection::syntactic_errors::{
2
    check_diagnostic, detect_syntactic_errors,
3
};
4

            
5
#[test]
6
1
fn unexpected_closing_paren() {
7
1
    let source = "find x: int(1..3))";
8
1
    let diagnostics = detect_syntactic_errors(source);
9
1
    assert_eq!(diagnostics.len(), 1, "Expected exactly one diagnostic");
10
1
    let diag = &diagnostics[0];
11
1
    check_diagnostic(diag, 0, 17, 0, 18, "Unexpected )");
12
1
}
13

            
14
#[test]
15
1
fn unexpected_identifier_in_range() {
16
1
    let source = "find x: int(1..3x)";
17
1
    let diagnostics = detect_syntactic_errors(source);
18
1
    assert_eq!(diagnostics.len(), 1, "Expected exactly one diagnostic");
19
1
    let diag = &diagnostics[0];
20
1
    check_diagnostic(diag, 0, 16, 0, 17, "Unexpected x inside an Integer Domain");
21
1
}
22

            
23
#[test]
24
1
fn unexpected_semicolon() {
25
1
    let source = "\
26
1
find x: int(1..3)
27
1
such that x = 6;
28
1
        ";
29
1
    let diagnostics = detect_syntactic_errors(source);
30
1
    assert_eq!(diagnostics.len(), 1, "Expected exactly one diagnostic");
31
1
    let diag = &diagnostics[0];
32
1
    check_diagnostic(diag, 1, 15, 1, 16, "Unexpected ;");
33
1
}
34

            
35
#[test]
36
1
fn unexpected_extra_comma_in_find() {
37
1
    let source = "find x,, y: int(1..3)";
38
1
    let diagnostics = detect_syntactic_errors(source);
39
1
    assert_eq!(diagnostics.len(), 1, "Expected exactly one diagnostic");
40
1
    let diag = &diagnostics[0];
41
1
    check_diagnostic(diag, 0, 6, 0, 7, "Unexpected , inside a Variable List");
42
1
}
43

            
44
#[test]
45
1
fn unexpected_token_in_implication() {
46
1
    let source = "\
47
1
find x: int(1..3)
48
1
such that x -> %9
49
1
";
50
1
    let diagnostics = detect_syntactic_errors(source);
51
1
    assert_eq!(diagnostics.len(), 1, "Expected exactly one diagnostic");
52
1
    let diag = &diagnostics[0];
53
1
    check_diagnostic(diag, 1, 15, 1, 16, "Unexpected % inside an Implication");
54
1
}
55

            
56
#[test]
57
1
fn unexpected_token_in_matrix_domain() {
58
1
    let source = "find x: matrix indexed by [int, &] of int";
59
1
    let diagnostics = detect_syntactic_errors(source);
60
1
    assert_eq!(diagnostics.len(), 1, "Expected exactly one diagnostic");
61
1
    let diag = &diagnostics[0];
62
1
    check_diagnostic(diag, 0, 32, 0, 33, "Unexpected & inside a Matrix Domain");
63
1
}
64

            
65
#[test]
66
1
fn unexpected_token_in_set_literal() {
67
1
    let source = "find x: set of int\nsuch that x = {1, 2, @}";
68
1
    let diagnostics = detect_syntactic_errors(source);
69
1
    assert_eq!(diagnostics.len(), 1, "Expected exactly one diagnostic");
70
1
    let diag = &diagnostics[0];
71
1
    check_diagnostic(diag, 1, 21, 1, 22, "Unexpected @ inside a Set");
72
1
}
73

            
74
// Multiple unexpected tokens
75
// One at the end of a find statement, one inside a set
76
#[test]
77
1
fn multiple_unexpected_tokens() {
78
1
    let source = "\
79
1
find x: set of int;
80
1
such that x = {1, 2, @}";
81
1
    let diagnostics = detect_syntactic_errors(source);
82
1
    assert_eq!(diagnostics.len(), 2, "Expected exactly two diagnostics");
83

            
84
    // First unexpected token: ';' at the end of domain
85
1
    let diag1 = &diagnostics[0];
86
1
    check_diagnostic(diag1, 0, 18, 0, 19, "Unexpected ;");
87

            
88
    // Second unexpected token: '@' in set literal
89
1
    let diag2 = &diagnostics[1];
90
1
    check_diagnostic(diag2, 1, 21, 1, 22, "Unexpected @ inside a Set");
91
1
}
92

            
93
#[test]
94
1
fn unexpected_x_in_all_diff() {
95
1
    let source = "\
96
1
find a : bool 
97
1
such that a = allDiff([1,2,4,1]x)";
98
1
    let diagnostics = detect_syntactic_errors(source);
99
1
    assert_eq!(diagnostics.len(), 1, "Expected exactly one diagnostic");
100
1
    let diag = &diagnostics[0];
101

            
102
1
    check_diagnostic(
103
1
        diag,
104
        1,
105
        31,
106
        1,
107
        32,
108
1
        "Unexpected x inside a List Combining Expression Bool",
109
    );
110
1
}
111

            
112
#[test]
113
1
fn unexpected_int_at_the_end() {
114
1
    let source = "\
115
1
find a : bool 
116
1
such that a = allDiff([1,2,4,1])8";
117
1
    let diagnostics = detect_syntactic_errors(source);
118
1
    assert_eq!(diagnostics.len(), 1, "Expected exactly one diagnostic");
119
1
    let diag = &diagnostics[0];
120
1
    check_diagnostic(diag, 1, 32, 1, 33, "Unexpected 8");
121
1
}
122

            
123
#[test]
124
1
fn unexpected_operand_at_end() {
125
1
    let source = "\
126
1
find x, a, b: int(1..3)+
127
1
";
128
1
    let diags = detect_syntactic_errors(source);
129
1
    assert_eq!(diags.len(), 1, "Expected exactly one diagnostic");
130
1
    let diag = &diags[0];
131
1
    check_diagnostic(diag, 0, 23, 0, 24, "Unexpected +");
132
1
}
133

            
134
#[test]
135
1
fn unexpected_operand_middle_no_comma() {
136
1
    let source = "\
137
1
find x-, b: int(1..3)
138
1
";
139
1
    let diags = detect_syntactic_errors(source);
140
1
    assert_eq!(diags.len(), 1, "Expected exactly one diagnostic");
141
1
    let diag = &diags[0];
142
1
    check_diagnostic(diag, 0, 6, 0, 7, "Unexpected - inside a Variable List");
143
1
}
144

            
145
#[test]
146
1
fn unexpected_operand_middle_comma() {
147
1
    let source = "\
148
1
find x,-, b: int(1..3)
149
1
";
150
1
    let diags = detect_syntactic_errors(source);
151
1
    assert_eq!(diags.len(), 1, "Expected exactly one diagnostic");
152
1
    let diag = &diags[0];
153
1
    check_diagnostic(diag, 0, 6, 0, 8, "Unexpected ,- inside a Variable List");
154
1
}
155

            
156
#[test]
157
1
fn unexpected_token_in_identifier() {
158
1
    let source = "find v@lue: int(1..3)";
159
1
    let diagnostics = detect_syntactic_errors(source);
160
1
    assert_eq!(diagnostics.len(), 1, "Expected exactly one diagnostic");
161
1
    let diag = &diagnostics[0];
162
1
    check_diagnostic(diag, 0, 6, 0, 10, "Unexpected @lue inside a Find Statement");
163
1
}
164

            
165
// Temporary before better logic is developed
166
#[test]
167
1
fn missing_right_operand_in_and_expr() {
168
1
    let source = "\
169
1
find x: int
170
1
such that x /\\
171
1
";
172
1
    let diagnostics = detect_syntactic_errors(source);
173
1
    assert_eq!(diagnostics.len(), 1, "Expected exactly one diagnostic");
174
1
    let diag = &diagnostics[0];
175
1
    check_diagnostic(diag, 1, 12, 1, 14, "Unexpected /\\");
176
1
}
177

            
178
// Temporary before better logic is developed
179
#[test]
180
1
fn unexpected_token_in_comparison() {
181
1
    let source = "\
182
1
find x: int
183
1
such that 5 =
184
1
    ";
185
1
    let diagnostics = detect_syntactic_errors(source);
186
1
    assert_eq!(diagnostics.len(), 1, "Expected exactly one diagnostic");
187
1
    let diag = &diagnostics[0];
188
1
    check_diagnostic(diag, 1, 12, 1, 13, "Unexpected =");
189
1
}
190

            
191
#[test]
192
1
fn unexpected_token_in_domain() {
193
    // not indented because have to avoid leading spaces for accurate character count
194
1
    let source = "find a: int(1.3)";
195

            
196
1
    let diagnostics = detect_syntactic_errors(source);
197

            
198
    // Should be exactly one diagnostic
199
1
    assert_eq!(diagnostics.len(), 1, "Expected exactly one diagnostic");
200
1
    let diag = &diagnostics[0];
201

            
202
1
    check_diagnostic(diag, 0, 13, 0, 15, "Unexpected .3 inside an Integer Domain");
203
1
}