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

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

            
14
#[test]
15
fn unexpected_identifier_in_range() {
16
    let source = "find x: int(1..3x)";
17
    let diagnostics = detect_syntactic_errors(source);
18
    assert!(!diagnostics.is_empty(), "Expected at least one diagnostic");
19
    let diag = &diagnostics[0];
20
    check_diagnostic(diag, 0, 16, 0, 17, "Unexpected 'x' inside 'int_domain'");
21
}
22

            
23
#[test]
24
fn unexpected_semicolon() {
25
    let source = "\
26
find x: int(1..3)
27
such that x = 6;
28
        ";
29
    let diagnostics = detect_syntactic_errors(source);
30
    assert!(!diagnostics.is_empty(), "Expected at least one diagnostic");
31
    let diag = &diagnostics[0];
32
    check_diagnostic(
33
        diag,
34
        1,
35
        15,
36
        1,
37
        16,
38
        "Unexpected ';' at the end of 'such that'",
39
    );
40
}
41

            
42
#[test]
43
fn unexpected_extra_comma_in_find() {
44
    let source = "find x,, y: int(1..3)";
45
    let diagnostics = detect_syntactic_errors(source);
46
    assert!(!diagnostics.is_empty(), "Expected at least one diagnostic");
47
    let diag = &diagnostics[0];
48
    check_diagnostic(diag, 0, 6, 0, 7, "Unexpected ',' inside 'variable_list'");
49
}
50

            
51
#[test]
52
fn unexpected_token_in_implication() {
53
    let source = "\
54
find x: int(1..3)
55
such that x -> %9
56
";
57
    let diagnostics = detect_syntactic_errors(source);
58
    assert!(!diagnostics.is_empty());
59
    let diag = &diagnostics[0];
60
    check_diagnostic(diag, 1, 15, 1, 16, "Unexpected '%' inside 'implication'");
61
}
62

            
63
#[test]
64
fn unexpected_token_in_matrix_domain() {
65
    let source = "find x: matrix indexed by [int, &] of int";
66
    let diagnostics = detect_syntactic_errors(source);
67
    assert!(!diagnostics.is_empty());
68
    let diag = &diagnostics[0];
69
    check_diagnostic(diag, 0, 32, 0, 33, "Unexpected '&' inside 'matrix_domain'");
70
}
71

            
72
#[test]
73
fn unexpected_token_in_set_literal() {
74
    let source = "find x: set of int\nsuch that x = {1, 2, @}";
75
    let diagnostics = detect_syntactic_errors(source);
76
    assert!(!diagnostics.is_empty());
77
    let diag = &diagnostics[0];
78

            
79
    check_diagnostic(diag, 1, 21, 1, 22, "Unexpected '@' inside 'set_literal'");
80
}
81

            
82
// Multiple unexpected tokens
83
// One at the end of a find statement, one inside a set
84
#[test]
85
fn multiple_unexpected_tokens() {
86
    let source = "\
87
find x: set of int;
88
such that x = {1, 2, @}";
89
    let diagnostics = detect_syntactic_errors(source);
90
    assert!(diagnostics.len() >= 2, "Expected at least two diagnostics");
91

            
92
    // First unexpected token: ';' at the end of domain
93
    let diag1 = &diagnostics[0];
94
    check_diagnostic(diag1, 0, 18, 0, 19, "Unexpected ';' at the end of 'find'");
95

            
96
    // Second unexpected token: '@' in set literal
97
    let diag2 = &diagnostics[1];
98
    check_diagnostic(diag2, 1, 21, 1, 22, "Unexpected '@' inside 'set_literal'");
99
}
100

            
101
#[test]
102
fn unexpected_x_in_all_diff() {
103
    let source = "\
104
find a : bool 
105
such that a = allDiff([1,2,4,1]x)";
106
    let diagnostics = detect_syntactic_errors(source);
107
    assert!(!diagnostics.is_empty(), "Expected at least one diagnostic");
108
    let diag = &diagnostics[0];
109

            
110
    check_diagnostic(
111
        diag,
112
        1,
113
        31,
114
        1,
115
        32,
116
        "Unexpected 'x' inside 'list_combining_expr_bool'",
117
    );
118
}
119

            
120
#[test]
121
fn unexpected_int_at_the_end() {
122
    let source = "\
123
find a : bool 
124
such that a = allDiff([1,2,4,1])8";
125
    let diagnostics = detect_syntactic_errors(source);
126
    assert!(!diagnostics.is_empty(), "Expected at least one diagnostic");
127
    let diag = &diagnostics[0];
128

            
129
    check_diagnostic(
130
        diag,
131
        1,
132
        32,
133
        1,
134
        33,
135
        "Unexpected '8' at the end of 'such that'",
136
    );
137
}