blob: e4dd7844752bdbe38c729a6de9c4e93ba34d9876 [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
20from file_format.checker.struct import CheckerFile, TestCase, TestAssertion, RegexExpression
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 """
108 // CHECK-START: MyMethod MyPass
109 """ + 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 Brazdil6423cf52015-05-20 14:57: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 Brazdil6423cf52015-05-20 14:57: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 Brazdilc2c48ff2015-05-15 14:24:31 +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 Brazdilc2c48ff2015-05-15 14:24:31 +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 Brazdilc2c48ff2015-05-15 14:24:31 +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 Brazdil6423cf52015-05-20 14:57: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 """
181 // CHECK: foo
182 // CHECK: bar
183 """,
184 """
185 foo
186 bar
David Brazdil6423cf52015-05-20 14:57:54 +0100187 """)
188 self.assertDoesNotMatch(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100189 """
190 // CHECK: foo
191 // CHECK: bar
192 """,
193 """
194 bar
195 foo
David Brazdil6423cf52015-05-20 14:57:54 +0100196 """)
David Brazdil2c27f2c2015-05-12 18:06:38 +0100197
198 def test_DagAssertions(self):
David Brazdil6423cf52015-05-20 14:57:54 +0100199 self.assertMatches(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100200 """
201 // CHECK-DAG: foo
202 // CHECK-DAG: bar
203 """,
204 """
205 foo
206 bar
David Brazdil6423cf52015-05-20 14:57:54 +0100207 """)
208 self.assertMatches(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100209 """
210 // CHECK-DAG: foo
211 // CHECK-DAG: bar
212 """,
213 """
214 bar
215 foo
David Brazdil6423cf52015-05-20 14:57:54 +0100216 """)
David Brazdil2c27f2c2015-05-12 18:06:38 +0100217
218 def test_DagAssertionsScope(self):
David Brazdil6423cf52015-05-20 14:57:54 +0100219 self.assertMatches(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100220 """
221 // CHECK: foo
222 // CHECK-DAG: abc
223 // CHECK-DAG: def
224 // CHECK: bar
225 """,
226 """
227 foo
228 def
229 abc
230 bar
David Brazdil6423cf52015-05-20 14:57:54 +0100231 """)
232 self.assertDoesNotMatch(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100233 """
234 // CHECK: foo
235 // CHECK-DAG: abc
236 // CHECK-DAG: def
237 // CHECK: bar
238 """,
239 """
240 foo
241 abc
242 bar
243 def
David Brazdil6423cf52015-05-20 14:57:54 +0100244 """)
245 self.assertDoesNotMatch(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100246 """
247 // CHECK: foo
248 // CHECK-DAG: abc
249 // CHECK-DAG: def
250 // CHECK: bar
251 """,
252 """
253 foo
254 def
255 bar
256 abc
David Brazdil6423cf52015-05-20 14:57:54 +0100257 """)
David Brazdil2c27f2c2015-05-12 18:06:38 +0100258
259 def test_NotAssertions(self):
David Brazdil6423cf52015-05-20 14:57:54 +0100260 self.assertMatches(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100261 """
262 // CHECK-NOT: foo
263 """,
264 """
265 abc
266 def
David Brazdil6423cf52015-05-20 14:57:54 +0100267 """)
268 self.assertDoesNotMatch(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100269 """
270 // CHECK-NOT: foo
271 """,
272 """
273 abc foo
274 def
David Brazdil6423cf52015-05-20 14:57:54 +0100275 """)
276 self.assertDoesNotMatch(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100277 """
278 // CHECK-NOT: foo
279 // CHECK-NOT: bar
280 """,
281 """
282 abc
283 def bar
David Brazdil6423cf52015-05-20 14:57:54 +0100284 """)
David Brazdil2c27f2c2015-05-12 18:06:38 +0100285
286 def test_NotAssertionsScope(self):
David Brazdil6423cf52015-05-20 14:57:54 +0100287 self.assertMatches(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100288 """
289 // CHECK: abc
290 // CHECK-NOT: foo
291 // CHECK: def
292 """,
293 """
294 abc
295 def
David Brazdil6423cf52015-05-20 14:57:54 +0100296 """)
297 self.assertMatches(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100298 """
299 // CHECK: abc
300 // CHECK-NOT: foo
301 // CHECK: def
302 """,
303 """
304 abc
305 def
306 foo
David Brazdil6423cf52015-05-20 14:57:54 +0100307 """)
308 self.assertDoesNotMatch(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100309 """
310 // CHECK: abc
311 // CHECK-NOT: foo
312 // CHECK: def
313 """,
314 """
315 abc
316 foo
317 def
David Brazdil6423cf52015-05-20 14:57:54 +0100318 """)
David Brazdil2c27f2c2015-05-12 18:06:38 +0100319
320 def test_LineOnlyMatchesOnce(self):
David Brazdil6423cf52015-05-20 14:57:54 +0100321 self.assertMatches(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100322 """
323 // CHECK-DAG: foo
324 // CHECK-DAG: foo
325 """,
326 """
327 foo
328 abc
329 foo
David Brazdil6423cf52015-05-20 14:57:54 +0100330 """)
331 self.assertDoesNotMatch(
David Brazdil2c27f2c2015-05-12 18:06:38 +0100332 """
333 // CHECK-DAG: foo
334 // CHECK-DAG: foo
335 """,
336 """
337 foo
338 abc
339 bar
David Brazdil6423cf52015-05-20 14:57:54 +0100340 """)