blob: 62e8e000e8b2463d55e4990dfb3df325d32fed07 [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):
61 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"}))
66 with self.assertRaises(CheckerException):
67 self.assertTrue(self.matches("foo[[X]]bar", "foobar", {}))
68
69 def test_VariableDefinition(self):
70 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"))
73
74 env = self.tryMatch("foo[[X:A.*B]]bar", "fooABbar", {})
75 self.assertEqual(env, {"X": "AB"})
76 env = self.tryMatch("foo[[X:A.*B]]bar", "fooAxxBbar", {})
77 self.assertEqual(env, {"X": "AxxB"})
78
79 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"))
82
83 def test_NoVariableRedefinition(self):
84 with self.assertRaises(CheckerException):
85 self.matches("[[X:...]][[X]][[X:...]][[X]]", "foofoobarbar")
86
87 def test_EnvNotChangedOnPartialMatch(self):
88 env = {"Y": "foo"}
89 self.assertFalse(self.matches("[[X:A]]bar", "Abaz", env))
90 self.assertFalse("X" in env.keys())
91
92 def test_VariableContentEscaped(self):
93 self.assertTrue(self.matches("[[X:..]]foo[[X]]", ".*foo.*"))
94 self.assertFalse(self.matches("[[X:..]]foo[[X]]", ".*fooAAAA"))
95
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 """
136 // CHECK: foo[[X:.]]bar
137 // CHECK: abc[[X]]def
138 """,
139 """
140 foo bar
141 abc def
142 """))
143 self.assertTrue(self.matches(
144 """
145 // CHECK: foo[[X:([0-9]+)]]bar
146 // CHECK: abc[[X]]def
147 // CHECK: ### [[X]] ###
148 """,
149 """
150 foo1234bar
151 abc1234def
152 ### 1234 ###
153 """))
154 self.assertFalse(self.matches(
155 """
156 // CHECK: foo[[X:([0-9]+)]]bar
157 // CHECK: abc[[X]]def
158 """,
159 """
160 foo1234bar
161 abc1235def
162 """))
163
164 def test_InOrderAssertions(self):
165 self.assertTrue(self.matches(
166 """
167 // CHECK: foo
168 // CHECK: bar
169 """,
170 """
171 foo
172 bar
173 """))
174 self.assertFalse(self.matches(
175 """
176 // CHECK: foo
177 // CHECK: bar
178 """,
179 """
180 bar
181 foo
182 """))
183
184 def test_DagAssertions(self):
185 self.assertTrue(self.matches(
186 """
187 // CHECK-DAG: foo
188 // CHECK-DAG: bar
189 """,
190 """
191 foo
192 bar
193 """))
194 self.assertTrue(self.matches(
195 """
196 // CHECK-DAG: foo
197 // CHECK-DAG: bar
198 """,
199 """
200 bar
201 foo
202 """))
203
204 def test_DagAssertionsScope(self):
205 self.assertTrue(self.matches(
206 """
207 // CHECK: foo
208 // CHECK-DAG: abc
209 // CHECK-DAG: def
210 // CHECK: bar
211 """,
212 """
213 foo
214 def
215 abc
216 bar
217 """))
218 self.assertFalse(self.matches(
219 """
220 // CHECK: foo
221 // CHECK-DAG: abc
222 // CHECK-DAG: def
223 // CHECK: bar
224 """,
225 """
226 foo
227 abc
228 bar
229 def
230 """))
231 self.assertFalse(self.matches(
232 """
233 // CHECK: foo
234 // CHECK-DAG: abc
235 // CHECK-DAG: def
236 // CHECK: bar
237 """,
238 """
239 foo
240 def
241 bar
242 abc
243 """))
244
245 def test_NotAssertions(self):
246 self.assertTrue(self.matches(
247 """
248 // CHECK-NOT: foo
249 """,
250 """
251 abc
252 def
253 """))
254 self.assertFalse(self.matches(
255 """
256 // CHECK-NOT: foo
257 """,
258 """
259 abc foo
260 def
261 """))
262 self.assertFalse(self.matches(
263 """
264 // CHECK-NOT: foo
265 // CHECK-NOT: bar
266 """,
267 """
268 abc
269 def bar
270 """))
271
272 def test_NotAssertionsScope(self):
273 self.assertTrue(self.matches(
274 """
275 // CHECK: abc
276 // CHECK-NOT: foo
277 // CHECK: def
278 """,
279 """
280 abc
281 def
282 """))
283 self.assertTrue(self.matches(
284 """
285 // CHECK: abc
286 // CHECK-NOT: foo
287 // CHECK: def
288 """,
289 """
290 abc
291 def
292 foo
293 """))
294 self.assertFalse(self.matches(
295 """
296 // CHECK: abc
297 // CHECK-NOT: foo
298 // CHECK: def
299 """,
300 """
301 abc
302 foo
303 def
304 """))
305
306 def test_LineOnlyMatchesOnce(self):
307 self.assertTrue(self.matches(
308 """
309 // CHECK-DAG: foo
310 // CHECK-DAG: foo
311 """,
312 """
313 foo
314 abc
315 foo
316 """))
317 self.assertFalse(self.matches(
318 """
319 // CHECK-DAG: foo
320 // CHECK-DAG: foo
321 """,
322 """
323 foo
324 abc
325 bar
326 """))