blob: 0215f5023ff844bb6cde3037c2ea20a053020aac [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
15from common.testing import ToUnicode
16from file_format.c1visualizer.parser import ParseC1visualizerStream
17from file_format.c1visualizer.struct import C1visualizerFile, C1visualizerPass
18from file_format.checker.parser import ParseCheckerStream, ParseCheckerAssertion
19from file_format.checker.struct import CheckerFile, TestCase, TestAssertion, RegexExpression
20from match.file import MatchFiles
21from match.line import MatchLines
22
23import io
24import unittest
25
26CheckerException = SystemExit
27
28class MatchLines_Test(unittest.TestCase):
29
30 def createTestAssertion(self, checkerString):
31 checkerFile = CheckerFile("<checker-file>")
32 testCase = TestCase(checkerFile, "TestMethod TestPass", 0)
33 return ParseCheckerAssertion(testCase, checkerString, TestAssertion.Variant.InOrder, 0)
34
35 def tryMatch(self, checkerString, c1String, varState={}):
36 return MatchLines(self.createTestAssertion(checkerString), ToUnicode(c1String), varState)
37
38 def matches(self, checkerString, c1String, varState={}):
39 return self.tryMatch(checkerString, c1String, varState) is not None
40
41 def test_TextAndWhitespace(self):
42 self.assertTrue(self.matches("foo", "foo"))
43 self.assertTrue(self.matches("foo", " foo "))
44 self.assertTrue(self.matches("foo", "foo bar"))
45 self.assertFalse(self.matches("foo", "XfooX"))
46 self.assertFalse(self.matches("foo", "zoo"))
47
48 self.assertTrue(self.matches("foo bar", "foo bar"))
49 self.assertTrue(self.matches("foo bar", "abc foo bar def"))
50 self.assertTrue(self.matches("foo bar", "foo foo bar bar"))
51
52 self.assertTrue(self.matches("foo bar", "foo X bar"))
53 self.assertFalse(self.matches("foo bar", "foo Xbar"))
54
55 def test_Pattern(self):
56 self.assertTrue(self.matches("foo{{A|B}}bar", "fooAbar"))
57 self.assertTrue(self.matches("foo{{A|B}}bar", "fooBbar"))
58 self.assertFalse(self.matches("foo{{A|B}}bar", "fooCbar"))
59
60 def test_VariableReference(self):
David Brazdilc2c48ff2015-05-15 14:24:31 +010061 self.assertTrue(self.matches("foo<<X>>bar", "foobar", {"X": ""}))
62 self.assertTrue(self.matches("foo<<X>>bar", "fooAbar", {"X": "A"}))
63 self.assertTrue(self.matches("foo<<X>>bar", "fooBbar", {"X": "B"}))
64 self.assertFalse(self.matches("foo<<X>>bar", "foobar", {"X": "A"}))
65 self.assertFalse(self.matches("foo<<X>>bar", "foo bar", {"X": "A"}))
David Brazdil2c27f2c2015-05-12 18:06:38 +010066 with self.assertRaises(CheckerException):
David Brazdilc2c48ff2015-05-15 14:24:31 +010067 self.assertTrue(self.matches("foo<<X>>bar", "foobar", {}))
David Brazdil2c27f2c2015-05-12 18:06:38 +010068
69 def test_VariableDefinition(self):
David Brazdilc2c48ff2015-05-15 14:24:31 +010070 self.assertTrue(self.matches("foo<<X:A|B>>bar", "fooAbar"))
71 self.assertTrue(self.matches("foo<<X:A|B>>bar", "fooBbar"))
72 self.assertFalse(self.matches("foo<<X:A|B>>bar", "fooCbar"))
David Brazdil2c27f2c2015-05-12 18:06:38 +010073
David Brazdilc2c48ff2015-05-15 14:24:31 +010074 env = self.tryMatch("foo<<X:A.*B>>bar", "fooABbar", {})
David Brazdil2c27f2c2015-05-12 18:06:38 +010075 self.assertEqual(env, {"X": "AB"})
David Brazdilc2c48ff2015-05-15 14:24:31 +010076 env = self.tryMatch("foo<<X:A.*B>>bar", "fooAxxBbar", {})
David Brazdil2c27f2c2015-05-12 18:06:38 +010077 self.assertEqual(env, {"X": "AxxB"})
78
David Brazdilc2c48ff2015-05-15 14:24:31 +010079 self.assertTrue(self.matches("foo<<X:A|B>>bar<<X>>baz", "fooAbarAbaz"))
80 self.assertTrue(self.matches("foo<<X:A|B>>bar<<X>>baz", "fooBbarBbaz"))
81 self.assertFalse(self.matches("foo<<X:A|B>>bar<<X>>baz", "fooAbarBbaz"))
David Brazdil2c27f2c2015-05-12 18:06:38 +010082
83 def test_NoVariableRedefinition(self):
84 with self.assertRaises(CheckerException):
David Brazdilc2c48ff2015-05-15 14:24:31 +010085 self.matches("<<X:...>><<X>><<X:...>><<X>>", "foofoobarbar")
David Brazdil2c27f2c2015-05-12 18:06:38 +010086
87 def test_EnvNotChangedOnPartialMatch(self):
88 env = {"Y": "foo"}
David Brazdilc2c48ff2015-05-15 14:24:31 +010089 self.assertFalse(self.matches("<<X:A>>bar", "Abaz", env))
David Brazdil2c27f2c2015-05-12 18:06:38 +010090 self.assertFalse("X" in env.keys())
91
92 def test_VariableContentEscaped(self):
David Brazdilc2c48ff2015-05-15 14:24:31 +010093 self.assertTrue(self.matches("<<X:..>>foo<<X>>", ".*foo.*"))
94 self.assertFalse(self.matches("<<X:..>>foo<<X>>", ".*fooAAAA"))
David Brazdil2c27f2c2015-05-12 18:06:38 +010095
96
97class MatchFiles_Test(unittest.TestCase):
98
99 def matches(self, checkerString, c1String):
100 checkerString = \
101 """
102 // CHECK-START: MyMethod MyPass
103 """ + checkerString
104 c1String = \
105 """
106 begin_compilation
107 name "MyMethod"
108 method "MyMethod"
109 date 1234
110 end_compilation
111 begin_cfg
112 name "MyPass"
113 """ + c1String + \
114 """
115 end_cfg
116 """
117 checkerFile = ParseCheckerStream("<test-file>", "CHECK", io.StringIO(ToUnicode(checkerString)))
118 c1File = ParseC1visualizerStream("<c1-file>", io.StringIO(ToUnicode(c1String)))
119 try:
120 MatchFiles(checkerFile, c1File)
121 return True
122 except CheckerException:
123 return False
124
125 def test_Text(self):
126 self.assertTrue(self.matches( "// CHECK: foo bar", "foo bar"))
127 self.assertFalse(self.matches("// CHECK: foo bar", "abc def"))
128
129 def test_Pattern(self):
130 self.assertTrue(self.matches( "// CHECK: abc {{de.}}", "abc de#"))
131 self.assertFalse(self.matches("// CHECK: abc {{de.}}", "abc d#f"))
132
133 def test_Variables(self):
134 self.assertTrue(self.matches(
135 """
David Brazdilc2c48ff2015-05-15 14:24:31 +0100136 // CHECK: foo<<X:.>>bar
137 // CHECK: abc<<X>>def
David Brazdil2c27f2c2015-05-12 18:06:38 +0100138 """,
139 """
David Brazdil4e9aac12015-05-18 17:45:17 +0100140 foo0bar
141 abc0def
David Brazdil2c27f2c2015-05-12 18:06:38 +0100142 """))
143 self.assertTrue(self.matches(
144 """
David Brazdilc2c48ff2015-05-15 14:24:31 +0100145 // CHECK: foo<<X:([0-9]+)>>bar
146 // CHECK: abc<<X>>def
147 // CHECK: ### <<X>> ###
David Brazdil2c27f2c2015-05-12 18:06:38 +0100148 """,
149 """
150 foo1234bar
151 abc1234def
152 ### 1234 ###
153 """))
154 self.assertFalse(self.matches(
155 """
David Brazdilc2c48ff2015-05-15 14:24:31 +0100156 // CHECK: foo<<X:([0-9]+)>>bar
157 // CHECK: abc<<X>>def
David Brazdil2c27f2c2015-05-12 18:06:38 +0100158 """,
159 """
160 foo1234bar
161 abc1235def
162 """))
163
David Brazdil4e9aac12015-05-18 17:45:17 +0100164 def test_WholeWordMustMatch(self):
165 self.assertTrue(self.matches( "// CHECK: b{{.}}r", "abc bar def"))
166 self.assertFalse(self.matches( "// CHECK: b{{.}}r", "abc Xbar def"))
167 self.assertFalse(self.matches( "// CHECK: b{{.}}r", "abc barX def"))
168 self.assertFalse(self.matches( "// CHECK: b{{.}}r", "abc b r def"))
169
David Brazdil2c27f2c2015-05-12 18:06:38 +0100170 def test_InOrderAssertions(self):
171 self.assertTrue(self.matches(
172 """
173 // CHECK: foo
174 // CHECK: bar
175 """,
176 """
177 foo
178 bar
179 """))
180 self.assertFalse(self.matches(
181 """
182 // CHECK: foo
183 // CHECK: bar
184 """,
185 """
186 bar
187 foo
188 """))
189
190 def test_DagAssertions(self):
191 self.assertTrue(self.matches(
192 """
193 // CHECK-DAG: foo
194 // CHECK-DAG: bar
195 """,
196 """
197 foo
198 bar
199 """))
200 self.assertTrue(self.matches(
201 """
202 // CHECK-DAG: foo
203 // CHECK-DAG: bar
204 """,
205 """
206 bar
207 foo
208 """))
209
210 def test_DagAssertionsScope(self):
211 self.assertTrue(self.matches(
212 """
213 // CHECK: foo
214 // CHECK-DAG: abc
215 // CHECK-DAG: def
216 // CHECK: bar
217 """,
218 """
219 foo
220 def
221 abc
222 bar
223 """))
224 self.assertFalse(self.matches(
225 """
226 // CHECK: foo
227 // CHECK-DAG: abc
228 // CHECK-DAG: def
229 // CHECK: bar
230 """,
231 """
232 foo
233 abc
234 bar
235 def
236 """))
237 self.assertFalse(self.matches(
238 """
239 // CHECK: foo
240 // CHECK-DAG: abc
241 // CHECK-DAG: def
242 // CHECK: bar
243 """,
244 """
245 foo
246 def
247 bar
248 abc
249 """))
250
251 def test_NotAssertions(self):
252 self.assertTrue(self.matches(
253 """
254 // CHECK-NOT: foo
255 """,
256 """
257 abc
258 def
259 """))
260 self.assertFalse(self.matches(
261 """
262 // CHECK-NOT: foo
263 """,
264 """
265 abc foo
266 def
267 """))
268 self.assertFalse(self.matches(
269 """
270 // CHECK-NOT: foo
271 // CHECK-NOT: bar
272 """,
273 """
274 abc
275 def bar
276 """))
277
278 def test_NotAssertionsScope(self):
279 self.assertTrue(self.matches(
280 """
281 // CHECK: abc
282 // CHECK-NOT: foo
283 // CHECK: def
284 """,
285 """
286 abc
287 def
288 """))
289 self.assertTrue(self.matches(
290 """
291 // CHECK: abc
292 // CHECK-NOT: foo
293 // CHECK: def
294 """,
295 """
296 abc
297 def
298 foo
299 """))
300 self.assertFalse(self.matches(
301 """
302 // CHECK: abc
303 // CHECK-NOT: foo
304 // CHECK: def
305 """,
306 """
307 abc
308 foo
309 def
310 """))
311
312 def test_LineOnlyMatchesOnce(self):
313 self.assertTrue(self.matches(
314 """
315 // CHECK-DAG: foo
316 // CHECK-DAG: foo
317 """,
318 """
319 foo
320 abc
321 foo
322 """))
323 self.assertFalse(self.matches(
324 """
325 // CHECK-DAG: foo
326 // CHECK-DAG: foo
327 """,
328 """
329 foo
330 abc
331 bar
332 """))