Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit af9d90c

Browse files
author
Dave Bartolomeo
committed
C++: New test framework that allows expected results as comments in source code
1 parent d12b140 commit af9d90c

1 file changed

Lines changed: 168 additions & 0 deletions

File tree

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
import cpp
2+
3+
abstract class InlineExpectationsTest extends string {
4+
bindingset[this]
5+
InlineExpectationsTest() { any() }
6+
7+
abstract string getARelevantTag();
8+
9+
abstract predicate hasActualResult(Location location, string element, string tag, string value);
10+
11+
final predicate hasFailureMessage(FailureLocatable element, string message) {
12+
exists(ActualResult actualResult |
13+
actualResult.getTest() = this and
14+
element = actualResult and
15+
(
16+
exists(FalseNegativeExpectation falseNegative |
17+
falseNegative.matchesActualResult(actualResult) and
18+
message = "Fixed false negative:" + falseNegative.getExpectationText()
19+
)
20+
or
21+
not exists(ValidExpectation expectation | expectation.matchesActualResult(actualResult)) and
22+
message = "Unexpected result: " + actualResult.getExpectationText()
23+
)
24+
)
25+
or
26+
exists(ValidExpectation expectation |
27+
not exists(ActualResult actualResult | expectation.matchesActualResult(actualResult)) and
28+
expectation.getTag() = getARelevantTag() and
29+
element = expectation and
30+
(
31+
expectation instanceof GoodExpectation and
32+
message = "Missing result:" + expectation.getExpectationText()
33+
or
34+
expectation instanceof FalsePositiveExpectation and
35+
message = "Fixed false positive:" + expectation.getExpectationText()
36+
)
37+
)
38+
or
39+
exists(InvalidExpectation expectation |
40+
element = expectation and
41+
message = "Invalid expectation syntax: " + expectation.getExpectation()
42+
)
43+
}
44+
}
45+
46+
private string expectationCommentPattern() { result = "//\\s*(\\$(?:[^/]|/[^/])*)(?://.*)?" }
47+
48+
private string expectationPattern() {
49+
result = "(?:(f(?:\\+|-)):)?((?:[A-Za-z-_]+)(?:\\s*,\\s*[A-Za-z-_]+)*)(?:=(.*))?"
50+
}
51+
52+
private string getAnExpectation(CppStyleComment comment) {
53+
result = comment.getContents().regexpCapture(expectationCommentPattern(), 1).splitAt("$").trim() and
54+
result != ""
55+
}
56+
57+
private newtype TFailureLocatable =
58+
TActualResult(
59+
InlineExpectationsTest test, Location location, string element, string tag, string value
60+
) {
61+
test.hasActualResult(location, element, tag, value)
62+
} or
63+
TValidExpectation(CppStyleComment comment, string tag, string value, string knownFailure) {
64+
exists(string expectation |
65+
expectation = getAnExpectation(comment) and
66+
expectation.regexpMatch(expectationPattern()) and
67+
tag = expectation.regexpCapture(expectationPattern(), 2).splitAt(",").trim() and
68+
(
69+
if exists(expectation.regexpCapture(expectationPattern(), 3))
70+
then value = expectation.regexpCapture(expectationPattern(), 3)
71+
else value = ""
72+
) and
73+
(
74+
if exists(expectation.regexpCapture(expectationPattern(), 1))
75+
then knownFailure = expectation.regexpCapture(expectationPattern(), 1)
76+
else knownFailure = ""
77+
)
78+
)
79+
} or
80+
TInvalidExpectation(CppStyleComment comment, string expectation) {
81+
expectation = getAnExpectation(comment) and
82+
not expectation.regexpMatch(expectationPattern())
83+
}
84+
85+
class FailureLocatable extends TFailureLocatable {
86+
string toString() { none() }
87+
88+
Location getLocation() { none() }
89+
90+
final string getExpectationText() { result = getTag() + "=" + getValue() }
91+
92+
string getTag() { none() }
93+
94+
string getValue() { none() }
95+
}
96+
97+
class ActualResult extends FailureLocatable, TActualResult {
98+
InlineExpectationsTest test;
99+
Location location;
100+
string element;
101+
string tag;
102+
string value;
103+
104+
ActualResult() { this = TActualResult(test, location, element, tag, value) }
105+
106+
override string toString() { result = element }
107+
108+
override Location getLocation() { result = location }
109+
110+
InlineExpectationsTest getTest() { result = test }
111+
112+
override string getTag() { result = tag }
113+
114+
override string getValue() { result = value }
115+
}
116+
117+
abstract private class Expectation extends FailureLocatable {
118+
CppStyleComment comment;
119+
120+
override string toString() { result = comment.toString() }
121+
122+
override Location getLocation() { result = comment.getLocation() }
123+
}
124+
125+
private class ValidExpectation extends Expectation, TValidExpectation {
126+
string tag;
127+
string value;
128+
string knownFailure;
129+
130+
ValidExpectation() { this = TValidExpectation(comment, tag, value, knownFailure) }
131+
132+
override string getTag() { result = tag }
133+
134+
override string getValue() { result = value }
135+
136+
string getKnownFailure() { result = knownFailure }
137+
138+
predicate matchesActualResult(ActualResult actualResult) {
139+
getLocation().getStartLine() = actualResult.getLocation().getStartLine() and
140+
getLocation().getFile() = actualResult.getLocation().getFile() and
141+
getTag() = actualResult.getTag() and
142+
getValue() = actualResult.getValue()
143+
}
144+
}
145+
146+
class GoodExpectation extends ValidExpectation {
147+
GoodExpectation() { getKnownFailure() = "" }
148+
}
149+
150+
class FalsePositiveExpectation extends ValidExpectation {
151+
FalsePositiveExpectation() { getKnownFailure() = "f+" }
152+
}
153+
154+
class FalseNegativeExpectation extends ValidExpectation {
155+
FalseNegativeExpectation() { getKnownFailure() = "f-" }
156+
}
157+
158+
class InvalidExpectation extends Expectation, TInvalidExpectation {
159+
string expectation;
160+
161+
InvalidExpectation() { this = TInvalidExpectation(comment, expectation) }
162+
163+
string getExpectation() { result = expectation }
164+
}
165+
166+
query predicate failures(FailureLocatable element, string message) {
167+
exists(InlineExpectationsTest test | test.hasFailureMessage(element, message))
168+
}

0 commit comments

Comments
 (0)