1
use conjure_cp_essence_parser::parse_essence;
2

            
3
#[test]
4
1
fn parses_function_domains_with_attributes() {
5
1
    let source = r#"
6
1
language Essence 1.4
7
1
find w : function int(1..3) --> int(1..3)
8
1
find x : function (total) bool --> int(13,17)
9
1
find y : function (minSize 1, maxSize 3) int(1..3) --> int(1..3)
10
1
find z : function (size 2, injective) int(1..3) --> int(1..3)
11
1
"#;
12
1
    let (model, _) = parse_essence(source).unwrap();
13
1
    let printed = model.to_string();
14
1
    assert!(printed.contains("function  int(1..3) --> int(1..3)"));
15
1
    assert!(printed.contains("function (total) bool --> int(13, 17)"));
16
1
    assert!(printed.contains("function (minSize 1, maxSize 3) int(1..3) --> int(1..3)"));
17
1
    assert!(printed.contains("function (size 2, injective) int(1..3) --> int(1..3)"));
18
1
}
19

            
20
#[test]
21
1
fn parses_function_domains_with_paren_wrapped_attribute_values() {
22
    // Conjure's own grammar allows the attribute value to be a parenthesised integer
23
    // expression as well as a bare one, e.g. `minSize(3)` alongside `minSize 3`.
24
1
    let source = r#"
25
1
language Essence 1.4
26
1
find x : function (minSize(1), maxSize(3), total) int(1..3) --> int(1..3)
27
1
find y : function (size(2), bijective) int(1..3) --> int(1..3)
28
1
"#;
29
1
    let (model, _) = parse_essence(source).unwrap();
30
1
    let printed = model.to_string();
31
1
    assert!(printed.contains("function (minSize 1, maxSize 3, total) int(1..3) --> int(1..3)"));
32
1
    assert!(printed.contains("function (size 2, bijective) int(1..3) --> int(1..3)"));
33
1
}
34

            
35
#[test]
36
1
fn parses_function_literals_empty_and_populated() {
37
1
    let source = r#"
38
1
language Essence 1.4
39
1
letting A be function()
40
1
letting B be function(1 --> true, 2 --> false)
41
1
"#;
42
1
    let (model, _) = parse_essence(source).unwrap();
43
1
    let printed = model.to_string();
44
1
    assert!(printed.contains("function()"));
45
1
    assert!(printed.contains("function(1 --> true,2 --> false)"));
46
1
}
47

            
48
#[test]
49
1
fn parses_defined_operator() {
50
1
    let source = r#"
51
1
language Essence 1.4
52
1
find x : function int(1..3) --> int(1..3)
53
1
such that (defined(x) = {1,2})
54
1
"#;
55
1
    let (model, _) = parse_essence(source).unwrap();
56
1
    let printed = model.to_string();
57
1
    assert!(printed.contains("defined(x)"));
58
1
}
59

            
60
#[test]
61
1
fn parses_image_operator() {
62
1
    let source = r#"
63
1
language Essence 1.4
64
1
find f : function bool --> int(0..5)
65
1
find b : bool
66
1
find i : int(0..5)
67
1
such that (image(f, b) = i)
68
1
"#;
69
1
    let (model, _) = parse_essence(source).unwrap();
70
1
    let printed = model.to_string();
71
1
    assert!(printed.contains("image(f,b)"));
72
1
}
73

            
74
#[test]
75
1
fn parses_preimage_operator() {
76
1
    let source = r#"
77
1
language Essence 1.4
78
1
find f : function int(1..3) --> int(1..3)
79
1
such that (preImage(f, 2) = {1,2})
80
1
"#;
81
1
    let (model, _) = parse_essence(source).unwrap();
82
1
    let printed = model.to_string();
83
1
    assert!(printed.contains("preImage(f,2)"));
84
1
}
85

            
86
#[test]
87
1
fn parses_remaining_function_operators() {
88
    // NB: this deliberately avoids declaring a `relation of (...)`-typed variable, since
89
    // relation domains have no native tree-sitter grammar support at all yet (a pre-existing
90
    // gap unrelated to this function work) -- toRelation is instead exercised via a
91
    // function-to-function equality so it stays within what's supported.
92
1
    let source = r#"
93
1
language Essence 1.4
94
1
find x, y : function int(1..3) --> int(1..3)
95
1
find s : set of int(1..3)
96
1
letting D be domain int(1..2)
97
1
such that (range(x) = s)
98
1
such that (imageSet(x, 2) = s)
99
1
such that (inverse(x, y))
100
1
find g : function int(0..4) --> int(0..4)
101
1
such that (g = restrict(x, D))
102
1
find m : mset (maxOccur 5) of (int(1..3), int(1..3))
103
1
such that (m = toMSet(x))
104
1
such that (toRelation(x) = toRelation(y))
105
1
find t : set of (int(1..3), int(1..3))
106
1
such that (t = toSet(x))
107
1
"#;
108
1
    let (model, _) = parse_essence(source).unwrap();
109
1
    let printed = model.to_string();
110
1
    assert!(printed.contains("range(x)"));
111
1
    assert!(printed.contains("imageSet(x,2)"));
112
1
    assert!(printed.contains("inverse(x,y)"));
113
1
    assert!(printed.contains("restrict(x,D)"));
114
1
    assert!(printed.contains("toMSet(x)"));
115
1
    assert!(printed.contains("toRelation(x)"));
116
1
    assert!(printed.contains("toSet(x)"));
117
1
}