pddm_tests.py
Go to the documentation of this file.
1 #! /usr/bin/python
2 #
3 # Protocol Buffers - Google's data interchange format
4 # Copyright 2015 Google Inc. All rights reserved.
5 # https://developers.google.com/protocol-buffers/
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions are
9 # met:
10 #
11 # * Redistributions of source code must retain the above copyright
12 # notice, this list of conditions and the following disclaimer.
13 # * Redistributions in binary form must reproduce the above
14 # copyright notice, this list of conditions and the following disclaimer
15 # in the documentation and/or other materials provided with the
16 # distribution.
17 # * Neither the name of Google Inc. nor the names of its
18 # contributors may be used to endorse or promote products derived from
19 # this software without specific prior written permission.
20 #
21 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 
33 """Tests for pddm.py."""
34 
35 import io
36 import unittest
37 
38 import pddm
39 
40 
41 class TestParsingMacros(unittest.TestCase):
42 
43  def testParseEmpty(self):
44  f = io.StringIO(u'')
45  result = pddm.MacroCollection(f)
46  self.assertEqual(len(result._macros), 0)
47 
48  def testParseOne(self):
49  f = io.StringIO(u"""PDDM-DEFINE foo( )
50 body""")
51  result = pddm.MacroCollection(f)
52  self.assertEqual(len(result._macros), 1)
53  macro = result._macros.get('foo')
54  self.assertIsNotNone(macro)
55  self.assertEquals(macro.name, 'foo')
56  self.assertEquals(macro.args, tuple())
57  self.assertEquals(macro.body, 'body')
58 
59  def testParseGeneral(self):
60  # Tests multiple defines, spaces in all places, etc.
61  f = io.StringIO(u"""
62 PDDM-DEFINE noArgs( )
63 body1
64 body2
65 
66 PDDM-DEFINE-END
67 
68 PDDM-DEFINE oneArg(foo)
69 body3
70 PDDM-DEFINE twoArgs( bar_ , baz )
71 body4
72 body5""")
73  result = pddm.MacroCollection(f)
74  self.assertEqual(len(result._macros), 3)
75  macro = result._macros.get('noArgs')
76  self.assertIsNotNone(macro)
77  self.assertEquals(macro.name, 'noArgs')
78  self.assertEquals(macro.args, tuple())
79  self.assertEquals(macro.body, 'body1\nbody2\n')
80  macro = result._macros.get('oneArg')
81  self.assertIsNotNone(macro)
82  self.assertEquals(macro.name, 'oneArg')
83  self.assertEquals(macro.args, ('foo',))
84  self.assertEquals(macro.body, 'body3')
85  macro = result._macros.get('twoArgs')
86  self.assertIsNotNone(macro)
87  self.assertEquals(macro.name, 'twoArgs')
88  self.assertEquals(macro.args, ('bar_', 'baz'))
89  self.assertEquals(macro.body, 'body4\nbody5')
90  # Add into existing collection
91  f = io.StringIO(u"""
92 PDDM-DEFINE another(a,b,c)
93 body1
94 body2""")
95  result.ParseInput(f)
96  self.assertEqual(len(result._macros), 4)
97  macro = result._macros.get('another')
98  self.assertIsNotNone(macro)
99  self.assertEquals(macro.name, 'another')
100  self.assertEquals(macro.args, ('a', 'b', 'c'))
101  self.assertEquals(macro.body, 'body1\nbody2')
102 
104  test_list = [
105  # Unknown directive
106  (u'PDDM-DEFINE foo()\nbody\nPDDM-DEFINED foo\nbaz',
107  'Hit a line with an unknown directive: '),
108  # End without begin
109  (u'PDDM-DEFINE foo()\nbody\nPDDM-DEFINE-END\nPDDM-DEFINE-END\n',
110  'Got DEFINE-END directive without an active macro: '),
111  # Line not in macro block
112  (u'PDDM-DEFINE foo()\nbody\nPDDM-DEFINE-END\nmumble\n',
113  'Hit a line that wasn\'t a directive and no open macro definition: '),
114  # Redefine macro
115  (u'PDDM-DEFINE foo()\nbody\nPDDM-DEFINE foo(a)\nmumble\n',
116  'Attempt to redefine macro: '),
117  ]
118  for idx, (input_str, expected_prefix) in enumerate(test_list, 1):
119  f = io.StringIO(input_str)
120  try:
121  result = pddm.MacroCollection(f)
122  self.fail('Should throw exception, entry %d' % idx)
123  except pddm.PDDMError as e:
124  self.assertTrue(e.message.startswith(expected_prefix),
125  'Entry %d failed: %r' % (idx, e))
126 
128  test_list = [
129  # 1. No name
130  (u'PDDM-DEFINE\nmumble',
131  'Failed to parse macro definition: '),
132  # 2. No name (with spaces)
133  (u'PDDM-DEFINE \nmumble',
134  'Failed to parse macro definition: '),
135  # 3. No open paren
136  (u'PDDM-DEFINE foo\nmumble',
137  'Failed to parse macro definition: '),
138  # 4. No close paren
139  (u'PDDM-DEFINE foo(\nmumble',
140  'Failed to parse macro definition: '),
141  # 5. No close paren (with args)
142  (u'PDDM-DEFINE foo(a, b\nmumble',
143  'Failed to parse macro definition: '),
144  # 6. No name before args
145  (u'PDDM-DEFINE (a, b)\nmumble',
146  'Failed to parse macro definition: '),
147  # 7. No name before args
148  (u'PDDM-DEFINE foo bar(a, b)\nmumble',
149  'Failed to parse macro definition: '),
150  # 8. Empty arg name
151  (u'PDDM-DEFINE foo(a, ,b)\nmumble',
152  'Empty arg name in macro definition: '),
153  (u'PDDM-DEFINE foo(a,,b)\nmumble',
154  'Empty arg name in macro definition: '),
155  # 10. Duplicate name
156  (u'PDDM-DEFINE foo(a,b,a,c)\nmumble',
157  'Arg name "a" used more than once in macro definition: '),
158  # 11. Invalid arg name
159  (u'PDDM-DEFINE foo(a b,c)\nmumble',
160  'Invalid arg name "a b" in macro definition: '),
161  (u'PDDM-DEFINE foo(a.b,c)\nmumble',
162  'Invalid arg name "a.b" in macro definition: '),
163  (u'PDDM-DEFINE foo(a-b,c)\nmumble',
164  'Invalid arg name "a-b" in macro definition: '),
165  (u'PDDM-DEFINE foo(a,b,c.)\nmumble',
166  'Invalid arg name "c." in macro definition: '),
167  # 15. Extra stuff after the name
168  (u'PDDM-DEFINE foo(a,c) foo\nmumble',
169  'Failed to parse macro definition: '),
170  (u'PDDM-DEFINE foo(a,c) foo)\nmumble',
171  'Failed to parse macro definition: '),
172  ]
173  for idx, (input_str, expected_prefix) in enumerate(test_list, 1):
174  f = io.StringIO(input_str)
175  try:
176  result = pddm.MacroCollection(f)
177  self.fail('Should throw exception, entry %d' % idx)
178  except pddm.PDDMError as e:
179  self.assertTrue(e.message.startswith(expected_prefix),
180  'Entry %d failed: %r' % (idx, e))
181 
182 
183 class TestExpandingMacros(unittest.TestCase):
184 
185  def testExpandBasics(self):
186  f = io.StringIO(u"""
187 PDDM-DEFINE noArgs( )
188 body1
189 body2
190 
191 PDDM-DEFINE-END
192 
193 PDDM-DEFINE oneArg(a)
194 body3 a
195 
196 PDDM-DEFINE-END
197 
198 PDDM-DEFINE twoArgs(b,c)
199 body4 b c
200 body5
201 PDDM-DEFINE-END
202 
203 """)
204  mc = pddm.MacroCollection(f)
205  test_list = [
206  (u'noArgs()',
207  'body1\nbody2\n'),
208  (u'oneArg(wee)',
209  'body3 wee\n'),
210  (u'twoArgs(having some, fun)',
211  'body4 having some fun\nbody5'),
212  # One arg, pass empty.
213  (u'oneArg()',
214  'body3 \n'),
215  # Two args, gets empty in each slot.
216  (u'twoArgs(, empty)',
217  'body4 empty\nbody5'),
218  (u'twoArgs(empty, )',
219  'body4 empty \nbody5'),
220  (u'twoArgs(, )',
221  'body4 \nbody5'),
222  ]
223  for idx, (input_str, expected) in enumerate(test_list, 1):
224  result = mc.Expand(input_str)
225  self.assertEqual(result, expected,
226  'Entry %d --\n Result: %r\n Expected: %r' %
227  (idx, result, expected))
228 
230  f = io.StringIO(u"""
231 PDDM-DEFINE bar(a)
232 a-a$S-a$l-a$L-a$u-a$U
233 PDDM-DEFINE-END
234 """)
235  mc = pddm.MacroCollection(f)
236 
237  self.assertEqual(mc.Expand('bar(xYz)'), 'xYz- -xYz-xyz-XYz-XYZ')
238  self.assertEqual(mc.Expand('bar(MnoP)'), 'MnoP- -mnoP-mnop-MnoP-MNOP')
239  # Test empty
240  self.assertEqual(mc.Expand('bar()'), '-----')
241 
243  f = io.StringIO(u"""
244 PDDM-DEFINE foo(a, b)
245 <a-z>
246 PDDM-DEFINE baz(a)
247 a - a$z
248 """)
249  mc = pddm.MacroCollection(f)
250  test_list = [
251  # 1. Unknown macro
252  (u'bar()',
253  'No macro named "bar".'),
254  (u'bar(a)',
255  'No macro named "bar".'),
256  # 3. Arg mismatch
257  (u'foo()',
258  'Expected 2 args, got: "foo()".'),
259  (u'foo(a b)',
260  'Expected 2 args, got: "foo(a b)".'),
261  (u'foo(a,b,c)',
262  'Expected 2 args, got: "foo(a,b,c)".'),
263  # 6. Unknown option in expansion
264  (u'baz(mumble)',
265  'Unknown arg option "a$z" while expanding "baz(mumble)".'),
266  ]
267  for idx, (input_str, expected_err) in enumerate(test_list, 1):
268  try:
269  result = mc.Expand(input_str)
270  self.fail('Should throw exception, entry %d' % idx)
271  except pddm.PDDMError as e:
272  self.assertEqual(e.message, expected_err,
273  'Entry %d failed: %r' % (idx, e))
274 
276  f = io.StringIO(u"""
277 PDDM-DEFINE StartIt()
278 foo(abc, def)
279 foo(ghi, jkl)
280 PDDM-DEFINE foo(a, b)
281 bar(a, int)
282 bar(b, NSString *)
283 PDDM-DEFINE bar(n, t)
284 - (t)n;
285 - (void)set##n$u##:(t)value;
286 
287 """)
288  mc = pddm.MacroCollection(f)
289  expected = """- (int)abc;
290 - (void)setAbc:(int)value;
291 
292 - (NSString *)def;
293 - (void)setDef:(NSString *)value;
294 
295 - (int)ghi;
296 - (void)setGhi:(int)value;
297 
298 - (NSString *)jkl;
299 - (void)setJkl:(NSString *)value;
300 """
301  self.assertEqual(mc.Expand('StartIt()'), expected)
302 
304  f = io.StringIO(u"""
305 PDDM-DEFINE foo(a, b)
306 bar(1, a)
307 bar(2, b)
308 PDDM-DEFINE bar(x, y)
309 foo(x, y)
310 """)
311  mc = pddm.MacroCollection(f)
312  try:
313  result = mc.Expand('foo(A,B)')
314  self.fail('Should throw exception! Test failed to catch recursion.')
315  except pddm.PDDMError as e:
316  self.assertEqual(e.message,
317  'Found macro recusion, invoking "foo(1, A)":\n...while expanding "bar(1, A)".\n...while expanding "foo(A,B)".')
318 
319 
320 class TestParsingSource(unittest.TestCase):
321 
322  def testBasicParse(self):
323  test_list = [
324  # 1. no directives
325  (u'a\nb\nc',
326  (3,) ),
327  # 2. One define
328  (u'a\n//%PDDM-DEFINE foo()\n//%body\nc',
329  (1, 2, 1) ),
330  # 3. Two defines
331  (u'a\n//%PDDM-DEFINE foo()\n//%body\n//%PDDM-DEFINE bar()\n//%body2\nc',
332  (1, 4, 1) ),
333  # 4. Two defines with ends
334  (u'a\n//%PDDM-DEFINE foo()\n//%body\n//%PDDM-DEFINE-END\n'
335  u'//%PDDM-DEFINE bar()\n//%body2\n//%PDDM-DEFINE-END\nc',
336  (1, 6, 1) ),
337  # 5. One expand, one define (that runs to end of file)
338  (u'a\n//%PDDM-EXPAND foo()\nbody\n//%PDDM-EXPAND-END\n'
339  u'//%PDDM-DEFINE bar()\n//%body2\n',
340  (1, 1, 2) ),
341  # 6. One define ended with an expand.
342  (u'a\nb\n//%PDDM-DEFINE bar()\n//%body2\n'
343  u'//%PDDM-EXPAND bar()\nbody2\n//%PDDM-EXPAND-END\n',
344  (2, 2, 1) ),
345  # 7. Two expands (one end), one define.
346  (u'a\n//%PDDM-EXPAND foo(1)\nbody\n//%PDDM-EXPAND foo(2)\nbody2\n//%PDDM-EXPAND-END\n'
347  u'//%PDDM-DEFINE foo()\n//%body2\n',
348  (1, 2, 2) ),
349  ]
350  for idx, (input_str, line_counts) in enumerate(test_list, 1):
351  f = io.StringIO(input_str)
352  sf = pddm.SourceFile(f)
353  sf._ParseFile()
354  self.assertEqual(len(sf._sections), len(line_counts),
355  'Entry %d -- %d != %d' %
356  (idx, len(sf._sections), len(line_counts)))
357  for idx2, (sec, expected) in enumerate(zip(sf._sections, line_counts), 1):
358  self.assertEqual(sec.num_lines_captured, expected,
359  'Entry %d, section %d -- %d != %d' %
360  (idx, idx2, sec.num_lines_captured, expected))
361 
362  def testErrors(self):
363  test_list = [
364  # 1. Directive within expansion
365  (u'//%PDDM-EXPAND a()\n//%PDDM-BOGUS',
366  'Ran into directive ("//%PDDM-BOGUS", line 2) while in "//%PDDM-EXPAND a()".'),
367  (u'//%PDDM-EXPAND a()\n//%PDDM-DEFINE a()\n//%body\n',
368  'Ran into directive ("//%PDDM-DEFINE", line 2) while in "//%PDDM-EXPAND a()".'),
369  # 3. Expansion ran off end of file
370  (u'//%PDDM-EXPAND a()\na\nb\n',
371  'Hit the end of the file while in "//%PDDM-EXPAND a()".'),
372  # 4. Directive within define
373  (u'//%PDDM-DEFINE a()\n//%body\n//%PDDM-BOGUS',
374  'Ran into directive ("//%PDDM-BOGUS", line 3) while in "//%PDDM-DEFINE a()".'),
375  (u'//%PDDM-DEFINE a()\n//%body\n//%PDDM-EXPAND-END a()',
376  'Ran into directive ("//%PDDM-EXPAND-END", line 3) while in "//%PDDM-DEFINE a()".'),
377  # 6. Directives that shouldn't start sections
378  (u'a\n//%PDDM-DEFINE-END a()\n//a\n',
379  'Unexpected line 2: "//%PDDM-DEFINE-END a()".'),
380  (u'a\n//%PDDM-EXPAND-END a()\n//a\n',
381  'Unexpected line 2: "//%PDDM-EXPAND-END a()".'),
382  (u'//%PDDM-BOGUS\n//a\n',
383  'Unexpected line 1: "//%PDDM-BOGUS".'),
384  ]
385  for idx, (input_str, expected_err) in enumerate(test_list, 1):
386  f = io.StringIO(input_str)
387  try:
388  pddm.SourceFile(f)._ParseFile()
389  self.fail('Should throw exception, entry %d' % idx)
390  except pddm.PDDMError as e:
391  self.assertEqual(e.message, expected_err,
392  'Entry %d failed: %r' % (idx, e))
393 
394 class TestProcessingSource(unittest.TestCase):
395 
396  def testBasics(self):
397  input_str = u"""
398 //%PDDM-IMPORT-DEFINES ImportFile
399 foo
400 //%PDDM-EXPAND mumble(abc)
401 //%PDDM-EXPAND-END
402 bar
403 //%PDDM-EXPAND mumble(def)
404 //%PDDM-EXPAND mumble(ghi)
405 //%PDDM-EXPAND-END
406 baz
407 //%PDDM-DEFINE mumble(a_)
408 //%a_: getName(a_)
409 """
410  input_str2 = u"""
411 //%PDDM-DEFINE getName(x_)
412 //%do##x_$u##(int x_);
413 
414 """
415  expected = u"""
416 //%PDDM-IMPORT-DEFINES ImportFile
417 foo
418 //%PDDM-EXPAND mumble(abc)
419 // This block of code is generated, do not edit it directly.
420 
421 abc: doAbc(int abc);
422 //%PDDM-EXPAND-END mumble(abc)
423 bar
424 //%PDDM-EXPAND mumble(def)
425 // This block of code is generated, do not edit it directly.
426 
427 def: doDef(int def);
428 //%PDDM-EXPAND mumble(ghi)
429 // This block of code is generated, do not edit it directly.
430 
431 ghi: doGhi(int ghi);
432 //%PDDM-EXPAND-END (2 expansions)
433 baz
434 //%PDDM-DEFINE mumble(a_)
435 //%a_: getName(a_)
436 """
437  expected_stripped = u"""
438 //%PDDM-IMPORT-DEFINES ImportFile
439 foo
440 //%PDDM-EXPAND mumble(abc)
441 //%PDDM-EXPAND-END mumble(abc)
442 bar
443 //%PDDM-EXPAND mumble(def)
444 //%PDDM-EXPAND mumble(ghi)
445 //%PDDM-EXPAND-END (2 expansions)
446 baz
447 //%PDDM-DEFINE mumble(a_)
448 //%a_: getName(a_)
449 """
450  def _Resolver(name):
451  self.assertEqual(name, 'ImportFile')
452  return io.StringIO(input_str2)
453  f = io.StringIO(input_str)
454  sf = pddm.SourceFile(f, _Resolver)
455  sf.ProcessContent()
456  self.assertEqual(sf.processed_content, expected)
457  # Feed it through and nothing should change.
458  f2 = io.StringIO(sf.processed_content)
459  sf2 = pddm.SourceFile(f2, _Resolver)
460  sf2.ProcessContent()
461  self.assertEqual(sf2.processed_content, expected)
462  self.assertEqual(sf2.processed_content, sf.processed_content)
463  # Test stripping (with the original input and expanded version).
464  f2 = io.StringIO(input_str)
465  sf2 = pddm.SourceFile(f2)
466  sf2.ProcessContent(strip_expansion=True)
467  self.assertEqual(sf2.processed_content, expected_stripped)
468  f2 = io.StringIO(sf.processed_content)
469  sf2 = pddm.SourceFile(f2, _Resolver)
470  sf2.ProcessContent(strip_expansion=True)
471  self.assertEqual(sf2.processed_content, expected_stripped)
472 
474  input_str = u"""
475 foo
476 //%PDDM-DEFINE mumble(a_)
477 //%body
478 //%PDDM-DEFINE mumble(x_)
479 //%body2
480 
481 """
482  f = io.StringIO(input_str)
483  sf = pddm.SourceFile(f)
484  try:
485  sf.ProcessContent()
486  self.fail('Should throw exception! Test failed to catch macro parsing error.')
487  except pddm.PDDMError as e:
488  self.assertEqual(e.message,
489  'Attempt to redefine macro: "PDDM-DEFINE mumble(x_)"\n'
490  '...while parsing section that started:\n'
491  ' Line 3: //%PDDM-DEFINE mumble(a_)')
492 
494  input_str = u"""
495 foo
496 //%PDDM-DEFINE mumble(a_)
497 //%body
498 //%PDDM-EXPAND foobar(x_)
499 //%PDDM-EXPAND-END
500 
501 """
502  f = io.StringIO(input_str)
503  sf = pddm.SourceFile(f)
504  try:
505  sf.ProcessContent()
506  self.fail('Should throw exception! Test failed to catch expand error.')
507  except pddm.PDDMError as e:
508  self.assertEqual(e.message,
509  'No macro named "foobar".\n'
510  '...while expanding "foobar(x_)" from the section that'
511  ' started:\n Line 5: //%PDDM-EXPAND foobar(x_)')
512 
513 
514 if __name__ == '__main__':
515  unittest.main()
pddm_tests.TestParsingMacros.testParseDirectiveIssues
def testParseDirectiveIssues(self)
Definition: pddm_tests.py:103
pddm_tests.TestProcessingSource.testProcessFileWithMacroParseError
def testProcessFileWithMacroParseError(self)
Definition: pddm_tests.py:473
pddm_tests.TestExpandingMacros
Definition: pddm_tests.py:183
pddm_tests.TestExpandingMacros.testExpandBasics
def testExpandBasics(self)
Definition: pddm_tests.py:185
pddm_tests.TestParsingMacros.testParseGeneral
def testParseGeneral(self)
Definition: pddm_tests.py:59
pddm_tests.TestParsingMacros.testParseOne
def testParseOne(self)
Definition: pddm_tests.py:48
pddm_tests.TestParsingSource.testBasicParse
def testBasicParse(self)
Definition: pddm_tests.py:322
pddm_tests.TestExpandingMacros.testCatchRecursion
def testCatchRecursion(self)
Definition: pddm_tests.py:303
pddm_tests.TestProcessingSource
Definition: pddm_tests.py:394
pddm.MacroCollection
Definition: pddm.py:140
pddm.SourceFile
Definition: pddm.py:361
pddm.PDDMError
Definition: pddm.py:135
pddm_tests.TestProcessingSource.testProcessFileWithExpandError
def testProcessFileWithExpandError(self)
Definition: pddm_tests.py:493
pddm_tests.TestParsingSource
Definition: pddm_tests.py:320
len
int len
Definition: php/ext/google/protobuf/map.c:206
pddm_tests.TestExpandingMacros.testExpandReferences
def testExpandReferences(self)
Definition: pddm_tests.py:275
pddm_tests.TestExpandingMacros.testExpandArgOptions
def testExpandArgOptions(self)
Definition: pddm_tests.py:229
pddm_tests.TestParsingMacros.testParseBeginIssues
def testParseBeginIssues(self)
Definition: pddm_tests.py:127
pddm_tests.TestParsingMacros
Definition: pddm_tests.py:41
pddm_tests.TestParsingSource.testErrors
def testErrors(self)
Definition: pddm_tests.py:362
pddm_tests.TestProcessingSource.testBasics
def testBasics(self)
Definition: pddm_tests.py:396
pddm_tests.TestExpandingMacros.testExpandSimpleMacroErrors
def testExpandSimpleMacroErrors(self)
Definition: pddm_tests.py:242
pddm_tests.TestParsingMacros.testParseEmpty
def testParseEmpty(self)
Definition: pddm_tests.py:43


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:57