1
use conjure_cp_essence_parser::diagnostics::error_detection::semantic_errors::detect_semantic_errors;
2
use conjure_cp_essence_parser::diagnostics::error_detection::syntactic_errors::check_diagnostic;
3

            
4
#[test]
5
1
fn detects_undefined_variable() {
6
1
    let source = "find x: int(1..10)\nsuch that x = y";
7
    // y is undefined
8
1
    let diagnostics = detect_semantic_errors(source);
9

            
10
1
    assert_eq!(
11
1
        diagnostics.len(),
12
        1,
13
        "Expected exactly one diagnostic for undefined variable"
14
    );
15

            
16
1
    let diag = &diagnostics[0];
17

            
18
1
    check_diagnostic(
19
1
        diag,
20
        1,
21
        14,
22
        1,
23
        15,
24
1
        "Semantic Error: Undefined variable: 'y'",
25
    );
26
1
}
27

            
28
#[test]
29
1
fn no_errors_for_valid_code() {
30
1
    let source = "find x, y: int(1..10)\nsuch that x + y = 10";
31
1
    let diagnostics = detect_semantic_errors(source);
32

            
33
    // should have no diagnostics
34
1
    assert_eq!(
35
1
        diagnostics.len(),
36
        0,
37
        "Expected no diagnostics for valid code, got: {:?}",
38
        diagnostics
39
    );
40
1
}
41

            
42
#[test]
43
1
fn range_points_to_error_location() {
44
1
    let source = "find x: int(1..10)\nsuch that x = undefined_var";
45
1
    let diagnostics = detect_semantic_errors(source);
46

            
47
1
    assert_eq!(
48
1
        diagnostics.len(),
49
        1,
50
        "Expected exactly one diagnostic for undefined variable"
51
    );
52

            
53
1
    let diag = &diagnostics[0];
54

            
55
1
    check_diagnostic(
56
1
        diag,
57
        1,
58
        14,
59
        1,
60
        27,
61
1
        "Semantic Error: Undefined variable: 'undefined_var'",
62
    );
63
1
}
64

            
65
// not enforced in conjure
66
#[ignore]
67
#[test]
68
fn domain_start_greater_than_end() {
69
    let source = "find x: int(10..1)";
70
    let diagnostics = detect_semantic_errors(source);
71

            
72
    assert_eq!(
73
        diagnostics.len(),
74
        1,
75
        "Expected exactly one diagnostic for undefined variable"
76
    );
77

            
78
    let diag = &diagnostics[0];
79

            
80
    check_diagnostic(
81
        diag,
82
        0,
83
        12,
84
        0,
85
        17,
86
        "Semantic Error: Start value greater than end value in 'domain'",
87
    );
88
}
89

            
90
#[ignore]
91
#[test]
92
fn incorrect_type_for_equation() {
93
    let source = "
94
    letting y be false\n
95
    find x: int(5..10)\n
96
    such that 5 + y = 6";
97
    let diagnostics = detect_semantic_errors(source);
98

            
99
    assert_eq!(
100
        diagnostics.len(),
101
        1,
102
        "Expected exactly one diagnostic for undefined variable"
103
    );
104

            
105
    let diag = &diagnostics[0];
106

            
107
    check_diagnostic(
108
        diag,
109
        2,
110
        14,
111
        2,
112
        15,
113
        "Semantic Error: Incorrect type 'bool' for variable 'y', expected 'int'",
114
    );
115
}
116

            
117
#[ignore]
118
#[test]
119
fn dividing_over_zero() {
120
    let source = "find x: int(5..10)\nsuch that x/0 = 3";
121
    let diagnostics = detect_semantic_errors(source);
122

            
123
    assert_eq!(
124
        diagnostics.len(),
125
        1,
126
        "Expected exactly one diagnostic for undefined variable"
127
    );
128

            
129
    let diag = &diagnostics[0];
130

            
131
    check_diagnostic(
132
        diag,
133
        1,
134
        10,
135
        1,
136
        13,
137
        "Semantic Error: Unsafe division attempted",
138
    );
139
}
140

            
141
#[ignore]
142
#[test]
143
fn invalid_index() {
144
    let source = "letting s be (0,1,1,0)
145
                \nletting t be (0,0,0,1)
146
                \nfind a : bool such that a = (s[5] = t[1])";
147
    let diagnostics = detect_semantic_errors(source);
148

            
149
    assert_eq!(
150
        diagnostics.len(),
151
        1,
152
        "Expected exactly one diagnostic for undefined variable"
153
    );
154

            
155
    let diag = &diagnostics[0];
156

            
157
    check_diagnostic(diag, 2, 31, 2, 32, "Semantic Error: Index out of bounds");
158
}
159

            
160
#[ignore]
161
#[test]
162
fn duplicate_declaration_of_variable() {
163
    let source = "find x: int(1..10)\nfind x: int(2..3)";
164
    let diagnostics = detect_semantic_errors(source);
165

            
166
    assert_eq!(
167
        diagnostics.len(),
168
        1,
169
        "Expected exactly one diagnostic for undefined variable"
170
    );
171

            
172
    let diag = &diagnostics[0];
173

            
174
    check_diagnostic(
175
        diag,
176
        1,
177
        5,
178
        1,
179
        6,
180
        "Semantic Error: Redeclaration of variable 'x' which was previously defined",
181
    );
182
}
183

            
184
#[ignore]
185
#[test]
186
fn extra_comma_in_variable_list() {
187
    let source = "find x,: int(1..10)";
188
    let diagnostics = detect_semantic_errors(source);
189

            
190
    assert_eq!(
191
        diagnostics.len(),
192
        1,
193
        "Expected exactly one diagnostic for undefined variable"
194
    );
195

            
196
    let diag = &diagnostics[0];
197

            
198
    check_diagnostic(
199
        diag,
200
        0,
201
        6,
202
        0,
203
        7,
204
        "Semantic Error: Extra ',' at the end of 'variable_list'",
205
    );
206
}