-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLimitResultsTest.ql
More file actions
146 lines (134 loc) · 5.08 KB
/
LimitResultsTest.ql
File metadata and controls
146 lines (134 loc) · 5.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import qtil.results.LimitResults
import qtil.testing.Qnit
import Bugs
module TestConfig implements LimitResultsConfigSig<Bug, BugField> {
predicate problem(Bug bug, BugField field) { field.getBug() = bug }
bindingset[remaining]
string message(Bug bug, BugField field, string remaining) {
result = bug.getName() + " has field " + field.getFieldName() + remaining
}
}
module Results = LimitResults<Bug, BugField, TestConfig>;
/** BugA has 1 field (X), which is fewer than maxResults=3 (default), so all results are shown. */
class TestBugAResultCount extends Test, Case {
override predicate run(Qnit test) {
if count(BugField f, string msg | Results::hasLimitedResult(any(Bug b | b = TBugA()), f, msg)) =
1
then test.pass("BugA: 1 result shown (fewer than maxResults)")
else test.fail("BugA: wrong result count")
}
}
/** BugA shows field X with no suffix since total <= maxResults. */
class TestBugANoSuffix extends Test, Case {
override predicate run(Qnit test) {
if
exists(BugField f, string msg |
Results::hasLimitedResult(any(Bug b | b = TBugA()), f, msg) and
f.getFieldName() = "X" and
msg = "BugA has field X"
)
then test.pass("BugA: correct message with no suffix")
else test.fail("BugA: message incorrect")
}
}
/** BugB has 3 fields (A, B, C), exactly maxResults=3 (default), so all results are shown. */
class TestBugBResultCount extends Test, Case {
override predicate run(Qnit test) {
if count(BugField f, string msg | Results::hasLimitedResult(any(Bug b | b = TBugB()), f, msg)) =
3
then test.pass("BugB: 3 results shown (exactly maxResults)")
else test.fail("BugB: wrong result count")
}
}
/** BugB shows all 3 fields with no suffix since total <= maxResults. */
class TestBugBNoSuffix extends Test, Case {
override predicate run(Qnit test) {
if
forall(string fieldName |
fieldName = ["A", "B", "C"] and
exists(BugField f |
f.getFieldName() = fieldName and
f.getBugName() = "BugB"
)
|
exists(BugField f, string msg |
Results::hasLimitedResult(any(Bug b | b = TBugB()), f, msg) and
f.getFieldName() = fieldName and
msg = "BugB has field " + fieldName
)
)
then test.pass("BugB: all 3 results shown with no suffix")
else test.fail("BugB: some results have wrong message or are missing")
}
}
/** BugC has 5 fields (A, B, C, D, E), which exceeds maxResults=3 (default), so only 3 are shown. */
class TestBugCResultCount extends Test, Case {
override predicate run(Qnit test) {
if count(BugField f, string msg | Results::hasLimitedResult(any(Bug b | b = TBugC()), f, msg)) =
3
then test.pass("BugC: 3 results shown (capped at maxResults)")
else test.fail("BugC: wrong result count")
}
}
/**
* BugC shows only the first 3 fields alphabetically (A, B, C), not D or E, using the default
* placeholderString ordering (toString() = "BugC.A", "BugC.B", ...).
*/
class TestBugCTopRanked extends Test, Case {
override predicate run(Qnit test) {
if
forall(string fieldName | fieldName = ["A", "B", "C"] |
exists(BugField f |
Results::hasLimitedResult(any(Bug b | b = TBugC()), f, _) and
f.getFieldName() = fieldName and
f.getBugName() = "BugC"
)
) and
not exists(BugField f |
Results::hasLimitedResult(any(Bug b | b = TBugC()), f, _) and
f.getFieldName() = ["D", "E"] and
f.getBugName() = "BugC"
)
then test.pass("BugC: top 3 alphabetical fields shown, D and E omitted")
else test.fail("BugC: wrong fields shown")
}
}
/** BugC shows a suffix " (and 2 more)" since 5 - 3 = 2 entities are omitted. */
class TestBugCSuffix extends Test, Case {
override predicate run(Qnit test) {
if
forall(BugField f, string msg |
Results::hasLimitedResult(any(Bug b | b = TBugC()), f, msg)
|
msg.matches("% (and 2 more)")
)
then test.pass("BugC: all shown results have ' (and 2 more)' suffix")
else test.fail("BugC: some results have wrong suffix")
}
}
/**
* The `problems` query predicate returns (finding, msg, entity, entityStr) tuples, where
* entityStr is the default placeholderString (toString()).
*/
class TestProblemsQueryPredicate extends Test, Case {
override predicate run(Qnit test) {
if
// BugC: 3 problems shown, each entityStr = BugField.toString() = "BugC.<field>"
count(Bug b, string msg, BugField f, string fstr |
Results::problems(b, msg, f, fstr) and b = TBugC()
) = 3 and
forall(Bug b, string msg, BugField f, string fstr |
Results::problems(b, msg, f, fstr) and b = TBugC()
|
fstr = "BugC." + f.getFieldName()
) and
// BugA: 1 problem, entityStr = "BugA.X"
exists(Bug b, string msg, BugField f, string fstr |
Results::problems(b, msg, f, fstr) and
b = TBugA() and
fstr = "BugA.X"
)
then test.pass("problems query predicate returns correct results with entityStr = toString()")
else test.fail("problems query predicate returned unexpected results")
}
}