blob: 5144ca9dc2fafef28b526cfab831357a4aade7cc [file] [log] [blame]
David Brazdil2c27f2c2015-05-12 18:06:38 +01001# Copyright (C) 2014 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
David Brazdilc4de9432015-05-20 11:03:22 +010015from common.immutables import ImmutableDict
David Brazdil2c27f2c2015-05-12 18:06:38 +010016from common.testing import ToUnicode
17from file_format.c1visualizer.parser import ParseC1visualizerStream
18from file_format.c1visualizer.struct import C1visualizerFile, C1visualizerPass
19from file_format.checker.parser import ParseCheckerStream, ParseCheckerAssertion
David Brazdilb34c35e2015-08-20 11:46:04 +010020from file_format.checker.struct import CheckerFile, TestCase, TestAssertion
David Brazdil6423cf52015-05-20 14:57:54 +010021from match.file import MatchTestCase, MatchFailedException
David Brazdil2c27f2c2015-05-12 18:06:38 +010022from match.line import MatchLines
23
24import io
25import unittest
26
27CheckerException = SystemExit
28
29class MatchLines_Test(unittest.TestCase):
30
31 def createTestAssertion(self, checkerString):
32 checkerFile = CheckerFile("<checker-file>")
33 testCase = TestCase(checkerFile, "TestMethod TestPass", 0)
34 return ParseCheckerAssertion(testCase, checkerString, TestAssertion.Variant.InOrder, 0)
35
36 def tryMatch(self, checkerString, c1String, varState={}):
David Brazdilc4de9432015-05-20 11:03:22 +010037 return MatchLines(self.createTestAssertion(checkerString),
38 ToUnicode(c1String),
39 ImmutableDict(varState))
David Brazdil2c27f2c2015-05-12 18:06:38 +010040
David Brazdil6423cf52015-05-20 14:57:54 +010041 def assertMatches(self, checkerString, c1String, varState={}):
42 self.assertIsNotNone(self.tryMatch(checkerString, c1String, varState))
43
44 def assertDoesNotMatch(self, checkerString, c1String, varState={}):
45 self.assertIsNone(self.tryMatch(checkerString, c1String, varState))
David Brazdil2c27f2c2015-05-12 18:06:38 +010046
47 def test_TextAndWhitespace(self):
David Brazdil6423cf52015-05-20 14:57:54 +010048 self.assertMatches("foo", "foo")
49 self.assertMatches("foo", " foo ")
50 self.assertMatches("foo", "foo bar")
51 self.assertDoesNotMatch("foo", "XfooX")
52 self.assertDoesNotMatch("foo", "zoo")
David Brazdil2c27f2c2015-05-12 18:06:38 +010053
David Brazdil6423cf52015-05-20 14:57:54 +010054 self.assertMatches("foo bar", "foo bar")
55 self.assertMatches("foo bar", "abc foo bar def")
56 self.assertMatches("foo bar", "foo foo bar bar")
David Brazdil2c27f2c2015-05-12 18:06:38 +010057
David Brazdil6423cf52015-05-20 14:57:54 +010058 self.assertMatches("foo bar", "foo X bar")
59 self.assertDoesNotMatch("foo bar", "foo Xbar")
David Brazdil2c27f2c2015-05-12 18:06:38 +010060
61 def test_Pattern(self):
David Brazdil6423cf52015-05-20 14:57:54 +010062 self.assertMatches("foo{{A|B}}bar", "fooAbar")
63 self.assertMatches("foo{{A|B}}bar", "fooBbar")
64 self.assertDoesNotMatch("foo{{A|B}}bar", "fooCbar")
David Brazdil2c27f2c2015-05-12 18:06:38 +010065
66 def test_VariableReference(self):
David Brazdil6423cf52015-05-20 14:57:54 +010067 self.assertMatches("foo<<X>>bar", "foobar", {"X": ""})
68 self.assertMatches("foo<<X>>bar", "fooAbar", {"X": "A"})
69 self.assertMatches("foo<<X>>bar", "fooBbar", {"X": "B"})
70 self.assertDoesNotMatch("foo<<X>>bar", "foobar", {"X": "A"})
71 self.assertDoesNotMatch("foo<<X>>bar", "foo bar", {"X": "A"})
David Brazdil2c27f2c2015-05-12 18:06:38 +010072 with self.assertRaises(CheckerException):
David Brazdil6423cf52015-05-20 14:57:54 +010073 self.tryMatch("foo<<X>>bar", "foobar", {})
David Brazdil2c27f2c2015-05-12 18:06:38 +010074
75 def test_VariableDefinition(self):
David Brazdil6423cf52015-05-20 14:57:54 +010076 self.assertMatches("foo<<X:A|B>>bar", "fooAbar")
77 self.assertMatches("foo<<X:A|B>>bar", "fooBbar")
78 self.assertDoesNotMatch("foo<<X:A|B>>bar", "fooCbar")
David Brazdil2c27f2c2015-05-12 18:06:38 +010079
David Brazdilc2c48ff2015-05-15 14:24:31 +010080 env = self.tryMatch("foo<<X:A.*B>>bar", "fooABbar", {})
David Brazdil2c27f2c2015-05-12 18:06:38 +010081 self.assertEqual(env, {"X": "AB"})
David Brazdilc2c48ff2015-05-15 14:24:31 +010082 env = self.tryMatch("foo<<X:A.*B>>bar", "fooAxxBbar", {})
David Brazdil2c27f2c2015-05-12 18:06:38 +010083 self.assertEqual(env, {"X": "AxxB"})
84
David Brazdil6423cf52015-05-20 14:57:54 +010085 self.assertMatches("foo<<X:A|B>>bar<<X>>baz", "fooAbarAbaz")
86 self.assertMatches("foo<<X:A|B>>bar<<X>>baz", "fooBbarBbaz")
87 self.assertDoesNotMatch("foo<<X:A|B>>bar<<X>>baz", "fooAbarBbaz")
David Brazdil2c27f2c2015-05-12 18:06:38 +010088
89 def test_NoVariableRedefinition(self):
90 with self.assertRaises(CheckerException):
David Brazdil6423cf52015-05-20 14:57:54 +010091 self.tryMatch("<<X:...>><<X>><<X:...>><<X>>", "foofoobarbar")
David Brazdil2c27f2c2015-05-12 18:06:38 +010092
93 def test_EnvNotChangedOnPartialMatch(self):
94 env = {"Y": "foo"}
David Brazdil6423cf52015-05-20 14:57:54 +010095 self.assertDoesNotMatch("<<X:A>>bar", "Abaz", env)
David Brazdil2c27f2c2015-05-12 18:06:38 +010096 self.assertFalse("X" in env.keys())
97
98 def test_VariableContentEscaped(self):
David Brazdil6423cf52015-05-20 14:57:54 +010099 self.assertMatches("<<X:..>>foo<<X>>", ".*foo.*")
100 self.assertDoesNotMatch("<<X:..>>foo<<X>>", ".*fooAAAA")
David Brazdil2c27f2c2015-05-12 18:06:38 +0100101
102
103class MatchFiles_Test(unittest.TestCase):
104
David Brazdil6423cf52015-05-20 14:57:54 +0100105 def assertMatches(self, checkerString, c1String):
David Brazdil2c27f2c2015-05-12 18:06:38 +0100106 checkerString = \
107 """
David Brazdila06d66a2015-05-28 11:14:54 +0100108 /// CHECK-START: MyMethod MyPass
David Brazdil2c27f2c2015-05-12 18:06:38 +0100109 """ + checkerString
110 c1String = \
111 """
112 begin_compilation
113 name "MyMethod"
114 method "MyMethod"
115 date 1234
116 end_compilation
117 begin_cfg
118 name "MyPass"
119 """ + c1String + \
120 """
121 end_cfg
122 """
123 checkerFile = ParseCheckerStream("<test-file>", "CHECK", io.StringIO(ToUnicode(checkerString)))
124 c1File = ParseC1visualizerStream("<c1-file>", io.StringIO(ToUnicode(c1String)))
David Brazdil6423cf52015-05-20 14:57:54 +0100125 assert len(checkerFile.testCases) == 1
126 assert len(c1File.passes) == 1
127 MatchTestCase(checkerFile.testCases[0], c1File.passes[0])
128
129 def assertDoesNotMatch(self, checkerString, c1String):
130 with self.assertRaises(MatchFailedException):
131 self.assertMatches(checkerString, c1String)
David Brazdil2c27f2c2015-05-12 18:06:38 +0100132
133 def test_Text(self):
David Brazdila06d66a2015-05-28 11:14:54 +0100134 self.assertMatches("/// CHECK: foo bar", "foo bar")
135 self.assertDoesNotMatch("/// CHECK: foo bar", "abc def")
David Brazdil2c27f2c2015-05-12 18:06:38 +0100136
137 def test_Pattern(self):
David Brazdila06d66a2015-05-28 11:14:54 +0100138 self.assertMatches("/// CHECK: abc {{de.}}", "abc de#")
139 self.assertDoesNotMatch("/// CHECK: abc {{de.}}", "abc d#f")
David Brazdil2c27f2c2015-05-12 18:06:38 +0100140
141 def test_Variables(self):
David Brazdil6423cf52015-05-20 14:57:54 +0100142 self.assertMatches(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100143 """
David Brazdila06d66a2015-05-28 11:14:54 +0100144 /// CHECK: foo<<X:.>>bar
145 /// CHECK: abc<<X>>def
David Brazdil2c27f2c2015-05-12 18:06:38 +0100146 """,
147 """
David Brazdil4e9aac12015-05-18 17:45:17 +0100148 foo0bar
149 abc0def
David Brazdil6423cf52015-05-20 14:57:54 +0100150 """)
151 self.assertMatches(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100152 """
David Brazdila06d66a2015-05-28 11:14:54 +0100153 /// CHECK: foo<<X:([0-9]+)>>bar
154 /// CHECK: abc<<X>>def
155 /// CHECK: ### <<X>> ###
David Brazdil2c27f2c2015-05-12 18:06:38 +0100156 """,
157 """
158 foo1234bar
159 abc1234def
160 ### 1234 ###
David Brazdil6423cf52015-05-20 14:57:54 +0100161 """)
162 self.assertDoesNotMatch(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100163 """
David Brazdila06d66a2015-05-28 11:14:54 +0100164 /// CHECK: foo<<X:([0-9]+)>>bar
165 /// CHECK: abc<<X>>def
David Brazdil2c27f2c2015-05-12 18:06:38 +0100166 """,
167 """
168 foo1234bar
169 abc1235def
David Brazdil6423cf52015-05-20 14:57:54 +0100170 """)
David Brazdil2c27f2c2015-05-12 18:06:38 +0100171
David Brazdil4e9aac12015-05-18 17:45:17 +0100172 def test_WholeWordMustMatch(self):
David Brazdila06d66a2015-05-28 11:14:54 +0100173 self.assertMatches("/// CHECK: b{{.}}r", "abc bar def")
174 self.assertDoesNotMatch("/// CHECK: b{{.}}r", "abc Xbar def")
175 self.assertDoesNotMatch("/// CHECK: b{{.}}r", "abc barX def")
176 self.assertDoesNotMatch("/// CHECK: b{{.}}r", "abc b r def")
David Brazdil4e9aac12015-05-18 17:45:17 +0100177
David Brazdil2c27f2c2015-05-12 18:06:38 +0100178 def test_InOrderAssertions(self):
David Brazdil6423cf52015-05-20 14:57:54 +0100179 self.assertMatches(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100180 """
David Brazdila06d66a2015-05-28 11:14:54 +0100181 /// CHECK: foo
182 /// CHECK: bar
David Brazdil2c27f2c2015-05-12 18:06:38 +0100183 """,
184 """
185 foo
186 bar
David Brazdil6423cf52015-05-20 14:57:54 +0100187 """)
188 self.assertDoesNotMatch(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100189 """
David Brazdila06d66a2015-05-28 11:14:54 +0100190 /// CHECK: foo
191 /// CHECK: bar
David Brazdil2c27f2c2015-05-12 18:06:38 +0100192 """,
193 """
194 bar
195 foo
David Brazdil6423cf52015-05-20 14:57:54 +0100196 """)
David Brazdil2c27f2c2015-05-12 18:06:38 +0100197
David Brazdil71141192015-05-19 18:29:40 +0100198 def test_NextLineAssertions(self):
199 self.assertMatches(
200 """
David Brazdila06d66a2015-05-28 11:14:54 +0100201 /// CHECK: foo
202 /// CHECK-NEXT: bar
203 /// CHECK-NEXT: abc
204 /// CHECK: def
David Brazdil71141192015-05-19 18:29:40 +0100205 """,
206 """
207 foo
208 bar
209 abc
210 def
211 """)
212 self.assertMatches(
213 """
David Brazdila06d66a2015-05-28 11:14:54 +0100214 /// CHECK: foo
215 /// CHECK-NEXT: bar
216 /// CHECK: def
David Brazdil71141192015-05-19 18:29:40 +0100217 """,
218 """
219 foo
220 bar
221 abc
222 def
223 """)
224 self.assertDoesNotMatch(
225 """
David Brazdila06d66a2015-05-28 11:14:54 +0100226 /// CHECK: foo
227 /// CHECK-NEXT: bar
David Brazdil71141192015-05-19 18:29:40 +0100228 """,
229 """
230 foo
231 abc
232 bar
233 """)
234
235 self.assertDoesNotMatch(
236 """
David Brazdila06d66a2015-05-28 11:14:54 +0100237 /// CHECK: foo
238 /// CHECK-NEXT: bar
David Brazdil71141192015-05-19 18:29:40 +0100239 """,
240 """
241 bar
242 foo
243 abc
244 """)
245
David Brazdil2c27f2c2015-05-12 18:06:38 +0100246 def test_DagAssertions(self):
David Brazdil6423cf52015-05-20 14:57:54 +0100247 self.assertMatches(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100248 """
David Brazdila06d66a2015-05-28 11:14:54 +0100249 /// CHECK-DAG: foo
250 /// CHECK-DAG: bar
David Brazdil2c27f2c2015-05-12 18:06:38 +0100251 """,
252 """
253 foo
254 bar
David Brazdil6423cf52015-05-20 14:57:54 +0100255 """)
256 self.assertMatches(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100257 """
David Brazdila06d66a2015-05-28 11:14:54 +0100258 /// CHECK-DAG: foo
259 /// CHECK-DAG: bar
David Brazdil2c27f2c2015-05-12 18:06:38 +0100260 """,
261 """
262 bar
263 foo
David Brazdil6423cf52015-05-20 14:57:54 +0100264 """)
David Brazdil2c27f2c2015-05-12 18:06:38 +0100265
266 def test_DagAssertionsScope(self):
David Brazdil6423cf52015-05-20 14:57:54 +0100267 self.assertMatches(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100268 """
David Brazdila06d66a2015-05-28 11:14:54 +0100269 /// CHECK: foo
270 /// CHECK-DAG: abc
271 /// CHECK-DAG: def
272 /// CHECK: bar
David Brazdil2c27f2c2015-05-12 18:06:38 +0100273 """,
274 """
275 foo
276 def
277 abc
278 bar
David Brazdil6423cf52015-05-20 14:57:54 +0100279 """)
280 self.assertDoesNotMatch(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100281 """
David Brazdila06d66a2015-05-28 11:14:54 +0100282 /// CHECK: foo
283 /// CHECK-DAG: abc
284 /// CHECK-DAG: def
285 /// CHECK: bar
David Brazdil2c27f2c2015-05-12 18:06:38 +0100286 """,
287 """
288 foo
289 abc
290 bar
291 def
David Brazdil6423cf52015-05-20 14:57:54 +0100292 """)
293 self.assertDoesNotMatch(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100294 """
David Brazdila06d66a2015-05-28 11:14:54 +0100295 /// CHECK: foo
296 /// CHECK-DAG: abc
297 /// CHECK-DAG: def
298 /// CHECK: bar
David Brazdil2c27f2c2015-05-12 18:06:38 +0100299 """,
300 """
301 foo
302 def
303 bar
304 abc
David Brazdil6423cf52015-05-20 14:57:54 +0100305 """)
David Brazdil2c27f2c2015-05-12 18:06:38 +0100306
307 def test_NotAssertions(self):
David Brazdil6423cf52015-05-20 14:57:54 +0100308 self.assertMatches(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100309 """
David Brazdila06d66a2015-05-28 11:14:54 +0100310 /// CHECK-NOT: foo
David Brazdil2c27f2c2015-05-12 18:06:38 +0100311 """,
312 """
313 abc
314 def
David Brazdil6423cf52015-05-20 14:57:54 +0100315 """)
316 self.assertDoesNotMatch(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100317 """
David Brazdila06d66a2015-05-28 11:14:54 +0100318 /// CHECK-NOT: foo
David Brazdil2c27f2c2015-05-12 18:06:38 +0100319 """,
320 """
321 abc foo
322 def
David Brazdil6423cf52015-05-20 14:57:54 +0100323 """)
324 self.assertDoesNotMatch(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100325 """
David Brazdila06d66a2015-05-28 11:14:54 +0100326 /// CHECK-NOT: foo
327 /// CHECK-NOT: bar
David Brazdil2c27f2c2015-05-12 18:06:38 +0100328 """,
329 """
330 abc
331 def bar
David Brazdil6423cf52015-05-20 14:57:54 +0100332 """)
David Brazdil2c27f2c2015-05-12 18:06:38 +0100333
334 def test_NotAssertionsScope(self):
David Brazdil6423cf52015-05-20 14:57:54 +0100335 self.assertMatches(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100336 """
David Brazdila06d66a2015-05-28 11:14:54 +0100337 /// CHECK: abc
338 /// CHECK-NOT: foo
339 /// CHECK: def
David Brazdil2c27f2c2015-05-12 18:06:38 +0100340 """,
341 """
342 abc
343 def
David Brazdil6423cf52015-05-20 14:57:54 +0100344 """)
345 self.assertMatches(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100346 """
David Brazdila06d66a2015-05-28 11:14:54 +0100347 /// CHECK: abc
348 /// CHECK-NOT: foo
349 /// CHECK: def
David Brazdil2c27f2c2015-05-12 18:06:38 +0100350 """,
351 """
352 abc
353 def
354 foo
David Brazdil6423cf52015-05-20 14:57:54 +0100355 """)
356 self.assertDoesNotMatch(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100357 """
David Brazdila06d66a2015-05-28 11:14:54 +0100358 /// CHECK: abc
359 /// CHECK-NOT: foo
360 /// CHECK: def
David Brazdil2c27f2c2015-05-12 18:06:38 +0100361 """,
362 """
363 abc
364 foo
365 def
David Brazdil6423cf52015-05-20 14:57:54 +0100366 """)
David Brazdil2c27f2c2015-05-12 18:06:38 +0100367
368 def test_LineOnlyMatchesOnce(self):
David Brazdil6423cf52015-05-20 14:57:54 +0100369 self.assertMatches(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100370 """
David Brazdila06d66a2015-05-28 11:14:54 +0100371 /// CHECK-DAG: foo
372 /// CHECK-DAG: foo
David Brazdil2c27f2c2015-05-12 18:06:38 +0100373 """,
374 """
375 foo
376 abc
377 foo
David Brazdil6423cf52015-05-20 14:57:54 +0100378 """)
379 self.assertDoesNotMatch(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100380 """
David Brazdila06d66a2015-05-28 11:14:54 +0100381 /// CHECK-DAG: foo
382 /// CHECK-DAG: foo
David Brazdil2c27f2c2015-05-12 18:06:38 +0100383 """,
384 """
385 foo
386 abc
387 bar
David Brazdil6423cf52015-05-20 14:57:54 +0100388 """)
David Brazdilb34c35e2015-08-20 11:46:04 +0100389
390 def test_EvalAssertions(self):
391 self.assertMatches("/// CHECK-EVAL: True", "foo")
392 self.assertDoesNotMatch("/// CHECK-EVAL: False", "foo")
393
394 self.assertMatches("/// CHECK-EVAL: 1 + 2 == 3", "foo")
395 self.assertDoesNotMatch("/// CHECK-EVAL: 1 + 2 == 4", "foo")
396
397 twoVarTestCase = """
398 /// CHECK-DAG: <<X:\d+>> <<Y:\d+>>
399 /// CHECK-EVAL: <<X>> > <<Y>>
400 """
401 self.assertMatches(twoVarTestCase, "42 41");
402 self.assertDoesNotMatch(twoVarTestCase, "42 43")